今天来通过kubeadm在虚拟机环境部署一套kubernetes,1台master节点,3台node节点。本文的部署步骤是根据kubernetes官网的Using kubeadm to Create a Cluster来进行的,有兴趣的读者可以参考,链接为:
https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/
好了,废话不多说,开始部署:
一.通过 VirtualBox 准备四台虚拟机,一台master节点和三台node节点,都安装centos7的操作系统,并且这次部署k8s 1.10.3版本,列表如下:node3 192.168.58.6
首先咱们要做的是一些准备工作,包括如下工作:
1.4台节点的时钟同步(如果节点之间时钟不一致,会导致节点在加入集群的时候失败),这里就不详细介绍如何配置时钟同步了,需要了解的朋友自己百度啊。
2.更换默认的yum源(你肯定不想一直等待在电脑面前看着慢吞吞的下载安装进度条吧),这里使用阿里云的yum源,kubernetes也同样使用阿里云的yum安装源,这里贴一下kubernetes的安装源:
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
3.修改hostname,配置host文件,设置master节点hostname为master,其余节点分别为:node1-node3
4.关闭selinux,防火墙,设置不使用swap 分区
[root@localhost ~]# setenforce 0
[root@localhost ~]# swapoff -a
5.在每台节点上安装docker,本文安装的是1.13.1,同时不要忘了还要做一个镜像加速,我这里使用的是阿里云的镜像加速,具体设置方法这里不详细介绍,可以百度。
[root@master yum.repos.d]# docker -v
Docker version 1.13.1, build 94f4240/1.13.1
如果上面你的准备工作你都做好了,咱们就继续吧
二.在每个节点上安装kubelet,kubeadm和kubectl,kubectl会在安装kubeadm的时候被安装上
yum install kubelet
yum install kubeadm
安装完成kubelet后,记得通过systemctl enable kubelet,不然后面kubeadm init的时候,不能过通过check
此时如果通过 systemctl start kubelet的话,会发现kubelet无法启动,那是因为目前还没有初始化kubernetes集群以及安装网络插件。
为什么master节点也需要安装kubelet呢?因为kubeadm会以容器的方式安装master节点需要的服务,如apiserver,etcd
三.接下来就是执行kubeadm init了,但是这里因为国内网络的原因,我们无法到kubeadm制定的镜像源获取到启动服务需要的镜像,那么怎么跨过这个坑呢,有两个办法,第一个是VPN,第二个是国内的镜像仓库找到需要的镜像,通过docker pull的方式拉到本地,然后通过docker tag的方式修改镜像的标签,来符合kubeadm要求的镜像,所需要哪些镜像呢,我们通过官网可以茶看到:
https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm-init/
Image Name v1.8 release branch version v1.9 release branch version
k8s.gcr.io/kube-apiserver-${ARCH} v1.8.x v1.9.x
k8s.gcr.io/kube-controller-manager-${ARCH} v1.8.x v1.9.x
k8s.gcr.io/kube-scheduler-${ARCH} v1.8.x v1.9.x
k8s.gcr.io/kube-proxy-${ARCH} v1.8.x v1.9.x
k8s.gcr.io/etcd-${ARCH} 3.0.17 3.1.10
k8s.gcr.io/pause-${ARCH} 3.0 3.0
k8s.gcr.io/k8s-dns-sidecar-${ARCH} 1.14.5 1.14.7
k8s.gcr.io/k8s-dns-kube-dns-${ARCH} 1.14.5 1.14.7
k8s.gcr.io/k8s-dns-dnsmasq-nanny-${ARCH} 1.14.5 1.14.7
registry.cn-hangzhou.aliyuncs.com
拉完镜像后,别忘了将node节点需要的镜像(proxy,pause)也tar到node节点上,并通过docker load加载到本地镜像仓库。
四.通过kubeadm init命令初始化master
在启动下面之前先要设置sysctl net.bridge.bridge-nf-call-iptables=1,不然check也会报错
kubeadm init --pod-network-cidr=172.16.0.0/16 --apiserver-advertise-address=192.168.58.3 --kubernetes-version v1.10.3
这里--pod-network-cidr表示k8s中pod使用的网络段,--apiserver-advertise-address表示k8s apiserver的地址使用master的192.168.58.3,最后的参数自然是版本,这里笔者建议将版本参数带上,因为k8s版本变化频繁。
如果你准备了上面的镜像的话,很快就会看到master已经初始化成功,同时会得到以下信息:
Your Kubernetes master has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
You can now join any number of machines by running the following on each node
as root:
kubeadm join 192.168.58.3:6443 --token uqvgpg.c3nnv8zqykj8eiii --discovery-token-ca-cert-hash sha256:342c9fc86f7b2fd4f90b4e0bca9857d44c2c0a3848238d662084dab8f288b68b
好了,这代表master已经初始化成功了,并提示你通过在node节点上执行最后一条命令能够把node节点加入到集群当中。接下来需要在master节点执行命令:
export KUBECONFIG=/etc/kubernetes/admin.conf
如果没有执行,接下来使用kubectl的时候都会得到错误的信息,如下所示:
[root@master-calico xkx]# kubectl get pods --all-namespaces
The connection to the server localhost:8080 was refused - did you specify the right host or port?
好了,我们执行完了以后,就可以通过如下命令来验证是否初始化成功:
[root@master-calico xkx]# kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system etcd-master-calico 1/1 Running 0 8m
kube-system kube-apiserver-master-calico 1/1 Running 0 8m
kube-system kube-controller-manager-master-calico 1/1 Running 0 8m
kube-system kube-dns-86f4d74b45-bzxw2 0/3 Pending 0 9m
kube-system kube-proxy-csxb7 1/1 Running 0 9m
kube-system kube-scheduler-master-calico 1/1 Running 0 8m
可以看到所有的容器都处于Running状态,除了kube-dns-86f4d74b45-bzxw2处于Pending,不用担心,那是因为还没有安装k8s的网络插件。
五.k8s网络插件安装和选择
k8s提供了丰富的第三方的网络插件,有Flannel,Calico等,这些网络插件的细节会在后面的文章进行探索,安装者应该根据具体场景进行选择,这里我们使用Calico。
通过执行以下命令,能够使得k8s下载Calico的相关容器并启动容器(注意:这里网络也可能是个问题,可以通过kubectl describe查看下正在下载的镜像版本,来通过阿里云进行拉去)
当然如果要指定版本的话,还是需要把yaml文件下载到本地。
kubectl apply -f https://docs.projectcalico.org/v3.1/getting-started/kubernetes/installation/hosted/rbac-kdd.yaml
kubectl apply -f https://docs.projectcalico.org/v3.1/getting-started/kubernetes/installation/hosted/kubernetes-datastore/calico-networking/1.7/calico.yaml
插件安装完成后可以看到所有的容器都启动了:
[root@master-calico ~]# kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system calico-node-mf7qk 2/2 Running 0 1m
kube-system etcd-master-calico 1/1 Running 0 2m
kube-system kube-apiserver-master-calico 1/1 Running 0 2m
kube-system kube-controller-manager-master-calico 1/1 Running 0 2m
kube-system kube-dns-86f4d74b45-jn5lp 3/3 Running 0 3m
kube-system kube-proxy-p852h 1/1 Running 0 3m
kube-system kube-scheduler-master-calico 1/1 Running 0 2m
六.将node节点加入到集群中
在加入节点之前请确保node节点中有需要的镜像:
[root@node1-calico xkx]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
quay.io/calico/node v3.1.3 7eca10056c8e 6 days ago 248 MB
quay.io/calico/cni v3.1.3 9f355e076ea7 6 days ago 68.8 MB
k8s.gcr.io/kube-proxy-amd64 v1.10.3 4261d315109d 2 weeks ago 97.1 MB
k8s.gcr.io/pause-amd64 3.1 da86e6ba6ca1 5 months ago 742 kB
gcr.io/google_containers/pause-amd64 3.0 99e59f495ffa 2 years ago 747 kB
执行命令:
kubeadm join 192.168.58.3:6443 --token hcl4ve.hg1d94r2efvps2jk --discovery-token-ca-cert-hash sha256:e58a49956896f7fcfb54bc225ea0df5cc9ba3bb52ffd6bfb0a5d3998f7c636a4
执行完成后得到结果:
[preflight] Running pre-flight checks.
[WARNING Service-Kubelet]: kubelet service is not enabled, please run 'systemctl enable kubelet.service'
[WARNING FileExisting-crictl]: crictl not found in system path
Suggestion: go get github.com/kubernetes-incubator/cri-tools/cmd/crictl
[preflight] Starting the kubelet service
[discovery] Trying to connect to API Server "192.168.58.3:6443"
[discovery] Created cluster-info discovery client, requesting info from "https://192.168.58.3:6443"
[discovery] Requesting info from "https://192.168.58.3:6443" again to validate TLS against the pinned public key
[discovery] Cluster info signature and contents are valid and TLS certificate validates against pinned roots, will use API Server "192.168.58.3:6443"
[discovery] Successfully established connection with API Server "192.168.58.3:6443"
This node has joined the cluster:
* Certificate signing request was sent to master and a response
was received.
* The Kubelet was informed of the new secure connection details.
Run 'kubectl get nodes' on the master to see this node join the cluster.
通过在master上执行kubectl get nodes可以看到节点已经成功的加入的集群了:
kubectl get nodes
NAME STATUS ROLES AGE VERSION
master-calico Ready master 12m v1.10.3
node1-calico Ready 3m v1.10.3
node2-calico Ready 16s v1.10.3
node3-calico Ready 13s v1.10.3
至此,通过kubeadm安装k8s集群完毕
八.总结
本文详细介绍了通过kubeadm来部署一个简单的k8s集群,集群只有一个master和3个node节点,这种部署方式应该只适用于测试环境,这种方式部署存在几个问题需要进一步思考:
1.Master节点上的k8s系统服务,都是通过容器提供的,在Master节点重启后,容器也会消亡,这时候就需要重新初始化集群,在生产环境是否还是按照这种方式部署,只是master节点部署多台。
2.etcd服务与master部署在一起,实际生产环境应该是分离的。
3.还未配置dashboard,来通过界面的方式管理k8s