27.4 安装部署

Kubernetes安装包括两种模式,一种是使用自带的脚本,另一种是手动进行配置。

用Kubernetes本地手动部署多节点情况相对复杂,需要提前理解其基本原理和各个组件。

1.使用脚本安装

Kubernetes提供了自带的本地部署脚本(支持Ubuntu 14.04 LTS系统),其中包括三个节点:一个Master+Node,两个Node。通过Flannel方案作为后端网络实现。

(1)预配置

所有节点上需要安装Docker和bridge-utils,并且Master节点需要能访问到外网下载必要的软件包,Node节点需要有启动Pod所需要的Docker镜像。

下载kubernetes代码包,并切换到稳定版本,如release-1.2:


  1. $ git clone https://github.com/kubernetes/kubernetes.git --depth=1
  2. $ git checkout release-1.2
  3. $ cd kubernetes/cluster/ubuntu/

配置信息在config-default.sh文件中。

修改下面一行为你的本地节点的实际用户名和地址:


  1. export nodes=${nodes:-"vcap@10.10.103.250 vcap@10.10.103.162 vcap@10.10.103.223"}

这里分别更新为本地实际节点地址:


  1. export nodes=${nodes:-"ubuntu@192.168.122.22 ubuntu@192.168.122.177 ubuntu@192.
  2. 168.122.8"}

修改下面一行为你需要的配置角色,a代表Master,i代表Node,会对应到上面指定的服务器列表:


  1. role=${role:-"ai i i"}

用户可以自行配置服务使用的集群地址范围,默认为192.168.3.0/24:


  1. export SERVICE_CLUSTER_IP_RANGE=192.168.3.0/24

另外,还有flannel的数据网地址范围,默认为172.16.0.0/16:


  1. export FLANNEL_NET=172.16.0.0/16

(2)开始安装

配置完成后进入上层的kubernetes/cluster/目录,执行安装脚本kube-up.sh。

该脚本会自动下载flannel、etcd、kubernetes等的压缩包(下载过程可能比较慢,推荐提前下载好,具体参考ubuntu/download-release.sh脚本),然后对各个节点进行配置,最后对启动后的集群进行校验,确保安装成功:


  1. $ cd ..
  2. $ KUBERNETES_PROVIDER=ubuntu ./kube-up.sh
  3. ... Starting cluster using provider: ubuntu
  4. ... calling verify-prereqs
  5. Identity added: /home/ubuntu/.ssh/id_rsa (/home/ubuntu/.ssh/id_rsa)
  6. ... calling kube-up
  7. ~/kubernetes/cluster/ubuntu ~/kubernetes/cluster
  8. Prepare flannel 0.5.5 release ...
  9. Prepare etcd 2.2.1 release ...
  10. Prepare kubernetes 1.2.0 release ...
  11. ...
  12. Wrote config for ubuntu to /home/ubuntu/.kube/config
  13. ... calling validate-cluster
  14. Found 3 node(s).
  15. NAME LABELS STATUS AGE
  16. 192.168.122.177 kubernetes.io/hostname=192.168.122.177 Ready <invalid>
  17. 192.168.122.22 kubernetes.io/hostname=192.168.122.22 Ready <invalid>
  18. 192.168.122.8 kubernetes.io/hostname=192.168.122.8 Ready <invalid>
  19. Validate output:
  20. NAME STATUS MESSAGE ERROR
  21. controller-manager Healthy ok nil
  22. scheduler Healthy ok nil
  23. etcd-0 Healthy {"health": "true"} nil
  24. Cluster validation succeeded
  25. Done, listing cluster services:
  26. Kubernetes master is running at http://192.168.122.22:8080

由于我们指定了KUBERNETES_PROVIDER=ubuntu,该脚本实际上调用的是ubuntu目录下的脚本。

部署成功后,kubeconfig文件在用户目录下的.kube/config中,记录了集群的访问信息和认证信息,例如:


  1. apiVersion: v1
  2. clusters:
  3. - cluster:
  4. insecure-skip-tls-verify: true
  5. server: http://192.168.122.22:8080
  6. name: ubuntu
  7. contexts:
  8. - context:
  9. cluster: ubuntu
  10. user: ubuntu
  11. name: ubuntu
  12. current-context: ubuntu
  13. kind: Config
  14. preferences: {}
  15. users:
  16. - name: ubuntu
  17. user:
  18. password: EFMXyR1UurQuL4TB
  19. username: admin

此时,可以通过kubernetes/cluster/ubuntu/binaries目录下的kubectl客户端跟集群进行交互,例如:


  1. $ cd ubuntu/binaries
  2. $ ./kubectl version
  3. Client Version: version.Info{Major:"1", Minor:"2", GitVersion:"v1.2.0", GitCommit:
  4. "5cb86ee022267586db386f62781338b0483733b3", GitTreeState:"clean"}
  5. Server Version: version.Info{Major:"1", Minor:"2", GitVersion:"v1.2.0", GitCommit:
  6. "5cb86ee022267586db386f62781338b0483733b3", GitTreeState:"clean"}
  7. $ ./kubectl get nodes
  8. NAME STATUS AGE
  9. 192.168.122.177 Ready 26m
  10. 192.168.122.22 Ready 1h
  11. 192.168.122.8 Ready 25m
  12. $ ./kubectl get services
  13. NAME CLUSTER_IP EXTERNAL_IP PORT(S) SELECTOR AGE
  14. kubernetes 192.168.3.1 <none> 443/TCP <none> 1h

该目录下还包括集群各个节点上使用的二进制服务文件:


  1. $ tree .
  2. .├── kubectl├── master ├── etcd ├── etcdctl ├── flanneld ├── kube-apiserver ├── kube-controller-manager └── kube-scheduler└── minion
  3. ├── flanneld
  4. ├── kubelet
  5. └── kube-proxy

(3)Master节点服务

Master节点(同时也是Node节点)上服务包括kube-apiserver、kube-scheduler、kube-controller-manager、kubelet和kube-proxy:


  1. $ $ ps aux|grep kube
  2. root 29960 0.6 3.5 88080 72356 ? Ssl 14:56 0:13
  3. /opt/bin/kube-apiserver --insecure-bind-address=0.0.0.0 --insecure-port=8080
  4. --etcd-servers=http://127.0.0.1:4001 --logtostderr=true --service-cluster-ip-
  5. range=192.168.3.0/24 --admission-control=NamespaceLifecycle,LimitRanger,
  6. ServiceAccount,ResourceQuota,SecurityContextDeny --service-node-port-range=
  7. 30000-32767 --advertise-address=192.168.122.22 --client-ca-file=/srv/
  8. kubernetes/ca.crt --tls-cert-file=/srv/kubernetes/server.cert --tls-
  9. private-key-file=/srv/kubernetes/server.key
  10. root 29961 0.3 1.7 49276 34508 ? Ssl 14:56 0:07
  11. /opt/bin/kube-controller-manager --master=127.0.0.1:8080 --root-ca-file=
  12. /srv/kubernetes/ca.crt --service-account-private-key-file=/srv/kubernetes
  13. /server.key --logtostderr=true
  14. root 29962 0.0 1.1 34796 23484 ? Ssl 14:56 0:00
  15. /opt/bin/kube-scheduler --logtostderr=true --master=127.0.0.1:8080
  16. root 29978 0.4 2.0 459496 41172 ? Ssl 14:56 0:10
  17. /opt/bin/kubelet --hostname-override=192.168.122.22 --api-servers=
  18. http://192.168.122.22:8080 --logtostderr=true --cluster-dns=192.168.3.10
  19. --cluster-domain=cluster.local --config=
  20. root 29981 0.0 0.9 29232 19428 ? Ssl 14:56 0:00
  21. /opt/bin/kube-proxy --hostname-override=192.168.122.22 --master=
  22. http://192.168.122.22:8080 --logtostderr=true

(4)Node节点服务

Node节点上服务则简单的多,包括kubelet和kube-proxy:


  1. $ ps aux|grep kube
  2. root 11347 0.5 2.1 418548 43352 ? Ssl 14:57 0:11
  3. /opt/bin/kubelet --hostname-override=192.168.122.177 --api-servers=
  4. http://192.168.122.22:8080 --logtostderr=true --cluster-dns=192.168.3.10
  5. --cluster-domain=cluster.local --config=
  6. root 11348 0.0 0.9 29232 19644 ? Ssl 14:57 0:00
  7. /opt/bin/kube-proxy --hostname-override=192.168.122.177 --master=
  8. http://192.168.122.22:8080 --logtostderr=true

(5)管理脚本

kubernetes/cluster也提供了其他方面用户进行操作的管理脚本,主要包括:

·kube-up.sh部署一个kubernetes集群;

·kube-down.sh停止一个kubernetes集群;

·kubectl.sh通过kubectl命令来对集群发出指令;

·kube-push.sh升级一个已有的集群到指定版本;

·validate-cluster.sh执行一些校验操作,确保集群启动成功;

·get-kube-local.sh快速部署一个单节点的本地集群。

(6)配置DNS

DNS服务在Kubernetes中以addon形式存在,可以在集群启动后选择添加,以Pod形式运行在集群中。Kubernetes代码包中自带了若干addon,都在cluster/addons/目录下,包括了DNS、dashboard、负载均衡、监控等。

配置选项仍然在kubernetes/cluster/ubuntu/config-default.sh文件中,相关配置包括:


  1. # Optional: Install cluster DNS.
  2. ENABLE_CLUSTER_DNS="${KUBE_ENABLE_CLUSTER_DNS:-true}"
  3. # DNS_SERVER_IP must be a IP in SERVICE_CLUSTER_IP_RANGE
  4. DNS_SERVER_IP=${DNS_SERVER_IP:-"192.168.3.10"}
  5. DNS_DOMAIN=${DNS_DOMAIN:-"cluster.local"}
  6. DNS_REPLICAS=${DNS_REPLICAS:-1}

更新配置后,执行如下命令,会自动创建默认的kube-system命名空间,并启动一个skydns的Pod:


  1. $ cd cluster/ubuntu
  2. $ KUBERNETES_PROVIDER=ubuntu ./deployAddons.sh
  3. Creating kube-system namespace...
  4. namespace "kube-system" created
  5. The namespace 'kube-system' is successfully created.
  6. Deploying DNS on Kubernetes
  7. replicationcontroller "kube-dns-v11" created
  8. service "kube-dns" created
  9. Kube-dns rc and service is successfully deployed.
  10. Creating Kubernetes Dashboard replicationController
  11. replicationcontroller "kubernetes-dashboard-v1.0.0" created
  12. Creating Kubernetes Dashboard service
  13. service "kubernetes-dashboard" created

Node上实际需要依赖的Docker镜像包括gcr.io/google_containers/exechealthz:1.0、gcr.io/google_containers/kube2sky:1.14、gcr.io/google_containers/etcd-amd64:2.2.1、gcr.io/google_containers/pause:2.0。

27.4 安装部署 - 图1注意

第一次创建Pod的时候,如果本地没有gcr.io/google_containers/pause:2.0镜像,会自动下载。如果出现下载超时问题,可以自行搜索镜像tar包,通过docker load命令来添加到各个Node节点上。建议本地提前准备好gcr.io相关的镜像。

(7)配置Web UI

修改配置文件kubernetes/cluster/ubuntu/config-default.sh,相关配置包括:


  1. ENABLE_CLUSTER_UI="${KUBE_ENABLE_CLUSTER_UI:-true}"

同样,更新配置后,执行如下命令,会自动创建默认的kube-system命名空间,并启动一个kubernetes-dashboard的Pod:


  1. $ cd cluster/ubuntu
  2. $ KUBERNETES_PROVIDER=ubuntu ./deployAddons.sh

实际上是调用如下命令来启动服务:


  1. $ kubectl create -f cluster/addons/dashboard/dashboard-controller.yaml --namespace=
  2. kube-system
  3. $ kubectl create -f cluster/addons/dashboard/dashboard-service.yaml --namespace=
  4. kube-system

Node上依赖的Docker镜像包括gcr.io/google_containers/kubernetes-dashboard-amd64:v1.0.0、gcr.io/google_containers/pause:2.0。

dashboard服务提供了一个简单的Web管理界面,如图27-3所示。

27.4 安装部署 - 图2

图27-3 Kubernetes的Web管理界面

(8)查看相关信息

首先,查看集群的信息,显示API服务地址和启动服务的地址:


  1. $ ./kubectl cluster-info
  2. Kubernetes master is running at http://192.168.122.22:8080
  3. KubeDNS is running at http://192.168.122.22:8080/api/v1/proxy/namespaces/kube-
  4. system/services/kube-dns
  5. kubernetes-dashboard is running at http://192.168.122.22:8080/api/v1/proxy
  6. /namespaces/kube-system/services/kubernetes-dashboard

查看启动的服务列表,可见dns和dashboard服务分别被分配了一个虚拟的ClusterIP:192.168.3.10和192.168.3.231:


  1. $ ./kubectl get services --namespace=kube-system
  2. NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  3. kube-dns 192.168.3.10 <none> 53/UDP,53/TCP 3m
  4. kubernetes-dashboard 192.168.3.231 <none> 80/TCP 3m

可以进一步用如下命令获取各个Pod的详细信息:


  1. $ ./kubectl get pods --namespace=kube-system -o json

在Pod所在的Node节点上,可以查看iptables规则,查看访问对应服务的流量被映射到相应端口。例如访问dashboard服务的ClusterIP 192.168.3.231:80,最终被映射到了Pod地址172.16.72.2:9090:


  1. $ sudo iptables -nvL -t nat
  2. ...
  3. Chain KUBE-SEP-2NKLTCPMR5LPTJA4 (1 references)
  4. pkts bytes target prot opt in out source destination
  5. 0 0 KUBE-MARK-MASQ all -- * * 172.16.75.2 0.0.0.0/0 /* kube-system/kube-dns:dns-tcp */
  6. 0 0 DNAT tcp -- * * 0.0.0.0/0 0.0.0.0/0 /* kube-system/kube-dns:dns-tcp */ tcp to:172.16.75.2:53
  7. Chain KUBE-SEP-5TZPVMQGISGQSOMF (1 references)
  8. pkts bytes target prot opt in out source destination
  9. 0 0 KUBE-MARK-MASQ all -- * * 192.168.122.22 0.0.0.0/0 /* default/kubernetes:https */
  10. 0 0 DNAT tcp -- * * 0.0.0.0/0 0.0.0.0/0 /* default/kubernetes:https */ tcp to:192.168.122.22:6443
  11. Chain KUBE-SEP-OR5WFLXGZDSJPSIA (1 references)
  12. pkts bytes target prot opt in out source destination
  13. 0 0 KUBE-MARK-MASQ all -- * * 172.16.72.2 0.0.0.0/0 /* kube-system/kubernetes-dashboard: */
  14. 0 0 DNAT tcp -- * * 0.0.0.0/0 0.0.0.0/0 /* kube-system/kubernetes-dashboard: */ tcp to:172.16.72.2:9090
  15. Chain KUBE-SEP-RZ3OQFEV4V6Q3AN2 (1 references)
  16. pkts bytes target prot opt in out source destination
  17. 0 0 KUBE-MARK-MASQ all -- * * 172.16.75.2 0.0.0.0/0 /* kube-system/kube-dns:dns */
  18. 0 0 DNAT udp -- * * 0.0.0.0/0 0.0.0.0/0 /* kube-system/kube-dns:dns */ udp to:172.16.75.2:53
  19. Chain KUBE-SERVICES (2 references)
  20. pkts bytes target prot opt in out source destination
  21. 0 0 KUBE-SVC-NPX46M4PTMTKRN6Y tcp -- * * 0.0.0.0/0 192.168.3.1 /* default/kubernetes:https cluster IP */ tcp dpt:443
  22. 0 0 KUBE-SVC-TCOU7JCQXEZGVUNU udp -- * * 0.0.0.0/0 192.168.3.10 /* kube-system/kube-dns:dns cluster IP */ udp dpt:53
  23. 0 0 KUBE-SVC-ERIFXISQEP7F7OF4 tcp -- * * 0.0.0.0/0 192.168.3.10 /* kube-system/kube-dns:dns-tcp cluster IP */ tcp dpt:53
  24. 0 0 KUBE-SVC-XGLOHA7QRQ3V22RZ tcp -- * * 0.0.0.0/0 192.168.3.231 /* kube-system/kubernetes-dashboard: cluster IP */ tcp dpt:80
  25. 0 0 KUBE-NODEPORTS all -- * * 0.0.0.0/0 0.0.0.0/0 /* kubernetes service nodeports; NOTE: this must be the last rule in this chain */ AD
  26. DRTYPE match dst-type LOCAL
  27. Chain KUBE-SVC-ERIFXISQEP7F7OF4 (1 references)
  28. pkts bytes target prot opt in out source destination
  29. 0 0 KUBE-SEP-2NKLTCPMR5LPTJA4 all -- * * 0.0.0.0/0 0.0.0.0/0 /* kube-system/kube-dns:dns-tcp */
  30. Chain KUBE-SVC-NPX46M4PTMTKRN6Y (1 references)
  31. pkts bytes target prot opt in out source destination
  32. 0 0 KUBE-SEP-5TZPVMQGISGQSOMF all -- * * 0.0.0.0/0 0.0.0.0/0 /* default/kubernetes:https */
  33. Chain KUBE-SVC-TCOU7JCQXEZGVUNU (1 references)
  34. pkts bytes target prot opt in out source destination
  35. 0 0 KUBE-SEP-RZ3OQFEV4V6Q3AN2 all -- * * 0.0.0.0/0 0.0.0.0/0 /* kube-system/kube-dns:dns */
  36. Chain KUBE-SVC-XGLOHA7QRQ3V22RZ (1 references)
  37. pkts bytes target prot opt in out source destination
  38. 0 0 KUBE-SEP-OR5WFLXGZDSJPSIA all -- * * 0.0.0.0/0 0.0.0.0/0 /* kube-system/kubernetes-dashboard: */

2.手动本地配置

如果要在本地手动安装,需要对环境进行一系列自定义的配置。实践中不推荐大家自定安装,但通过了解这个过程可以加深对Kubernetes各个组件功能的理解。

(1)Node节点配置

首先,要取消Docker-Engine对本地的网络接管,删除默认的docker0网桥:


  1. $ sudo iptables -t nat -F
  2. $ ifconfig docker0 down
  3. $ brctl delbr docker0

另外,在Docker服务中修改默认的网桥信息,如果使用VXLAN这样的overlay方案,还需要修改MTU:


  1. DOCKER_OPTS=" -H tcp://127.0.0.1:4243 -H unix:///var/run/docker.sock --bip=
  2. 172.16.21.1/24 --mtu=1450"

(2)下载组件文件

Kubernetes也提供了Linux平台上预编译好的各个组件文件,方便搭建本地集群。

从github.com/kubernetes/kubernetes/releases/latest下载编译好的二进制执行包kubernetes.tar.gz,并解压。这里以1.2.0版本为例,其他版本需要替换地址中版本号为对应版本号。

对应操作如下:


  1. $ curl -L https://github.com/kubernetes/kubernetes/releases/download/v1.2.0/
  2. kubernetes.tar.gz > kubernetes.tar.gz
  3. $ tar xzvf kubernetes.tar.gz

解压后,进入kubernetes/server/子目录下,并解压kubernetes-server-linux-amd64.tar.gz文件,查看其子目录kubernetes/server/bin下的文件:


  1. $ cd kubernetes/server/ && tar xzvf kubernetes-server-linux-amd64.tar.gz
  2. $ ls kubernetes/server/bin
  3. hyperkube kube-apiserver.tar
  4. kube-controller-manager.tar kube-proxy kube-scheduler.tar
  5. kube-apiserver kube-controller-manager
  6. kubectl kube-scheduler linkcheck
  7. kube-apiserver.docker_tag kube-controller-manager.docker_tag
  8. kubelet kube-scheduler.docker_tag

可以看到,核心组件的执行文件都在这里了。其中,hyperkube将所有的组件打包在了一起,可以通过子命令来指定作为某个组件运行。例如


  1. $ hyperkube kubelet ...

等价于直接运行了kubelet组件。

(3)Master节点

首先来配置Master节点,主要包括etcd、kube-apiserver、kube-scheduler、kube-controller-manager等。用户也可以启动其他组件。

1)本地启动etcd服务,监听到默认的4001端口。读者可自行查阅前面的第22章。


  1. $ etcd

2)kube-apiserver配置,通过下面命令启动一个kube-apiserver,监听在本地的非安全端口10.0.100.88:8080。该命令没有启用安全端口,所以可能会有警告信息,这里暂时忽略:


  1. $ kube-apiserver --service-cluster-ip-range=10.0.0.1/24 --etcd-servers=
  2. http://127.0.0.1:4001 --insecure-bind-address=10.0.100.88

此时,从其他节点应该可以通过http://10.0.100.88:8080地址访问到API列表信息。

3)kube-scheduler配置,只需要指定Master的API监听地址:


  1. $ kube-scheduler --master=10.0.100.88:8080 --address=10.0.100.88

4)kube-controller-manager配置,只需要指定Master的API监听地址:


  1. $ kube-controller-manager --master=10.0.100.88:8080 --address=10.0.100.88

(4)Node节点

Node节点要简单得多,主要包括kubelet和kube-proxy两个组件。

用下面命令可以启动kubelet:


  1. $ sudo kubelet --address="0.0.0.0" --api-servers=http://10.0.100.88:8080 --
  2. configure-cbr0=true

此时,可以通过API查看到注册上来的Node节点了:


  1. $ kubectl -s 10.0.100.88:8080 get nodes
  2. NAME LABELS STATUS
  3. host-99 kubernetes.io/hostname=host-99 Ready

用下面命令可以启动kube-proxy:


  1. $ sudo kube-proxy --master=10.0.100.88:8080