3. 所有节点安装Docker/kubeadm/kubelet
所有节点安装Docker/kubeadm/kubelet ,Kubernetes默认CRI(容器运行时)为Docker,因此先安装Docker。
- 安装之前确保没有其他dockers版本,如果有,需要删除干净后再安装,卸载方式可以参考这篇文章卸载docker。
- 安装Docker,所有master+node都要安装
# 下载docker的yum源 wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo # 安装docker,找上一步的yum源去安装 yum -y install docker-ce-18.06.1.ce-3.el7 # 开机自启动并且启动docker systemctl enable docker && systemctl start docker # 查看docker状态 systemctl status docker # 查看docker版本 docker --version
# 设置docker拉取镜像的加速器 cat > /etc/docker/daemon.json << EOF { "registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"] } EOF # 重启docker systemctl daemon-reload systemctl restart docker
- 添加阿里云yum源,所有节点(master+node)
cat >/etc/yum.repos.d/docker.repo<<EOF [docker-ce-edge] name=Docker CE Edge - \$basearch baseurl=https://mirrors.aliyun.com/docker-ce/linux/centos/7/\$basearch/edge enabled=1 gpgcheck=1 gpgkey=https://mirrors.aliyun.com/docker-ce/linux/centos/gpg EOF
# 重启docker systemctl restart docker
- 添加kubernetes软件源
cat > /etc/yum.repos.d/kubernetes.repo << EOF [kubernetes] name=Kubernetes baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64 enabled=1 gpgcheck=0 repo_gpgcheck=0 gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg EOF
- 安装kubeadm,kubectl,kubelet
由于版本更新频繁,这里指定版本号部署:
# 安装kubelet、kubeadm、kubectl,同时指定版本 yum install -y kubelet-1.18.0 kubeadm-1.18.0 kubectl-1.18.0 # 启动并设置开机启动 systemctl start kubelet systemctl enable kubelet
4. 部署Kubernetes Master
4.1 创建kubreadm配置文件
在具有vip的master上进行初始化操作,这里为master1
# 创建文件夹 mkdir /usr/local/kubernetes/manifests -p # 到manifests目录 cd /usr/local/kubernetes/manifests/ # 新建yaml文件 vim kubeadm-config.yaml
下面内容修改IP 后复制进去
apiVersion: kubeadm.k8s.io/v1beta2 # 集群主版本,根据集群版本号决定 bootstrapTokens: - groups: - system:bootstrappers:kubeadm:default-node-token token: abcdef.0123456789abcdef ttl: 24h0m0s usages: - signing - authentication kind: InitConfiguration localAPIEndpoint: advertiseAddress: 192.168.2.200 #本机ip bindPort: 6443 #apiserver集群端口号 nodeRegistration: criSocket: /var/run/dockershim.sock name: k8s-master1 #本机hostname taints: - effect: NoSchedule key: node-role.kubernetes.io/master --- apiServer: certSANs: - k8s-master1 - k8s-master2 - k8s-master3 - 192.168.2.200 # master1 ip - 192.168.2.201 # master2 ip - 192.168.2.204 # master3 ip - 192.168.2.203 # 虚拟vip keepalive出来的ip - 127.0.0.1 extraArgs: authorization-mode: Node,RBAC timeoutForControlPlane: 2m0s # 注册时间2分钟 apiVersion: kubeadm.k8s.io/v1beta2 certificatesDir: /etc/kubernetes/pki clusterName: kubernetes # 集群名字 controlPlaneEndpoint: "192.168.2.203:16443" # 虚拟ip + haproxy绑定的端口号 controllerManager: {} dns: type: CoreDNS etcd: local: dataDir: /var/lib/etcd imageRepository: registry.aliyuncs.com/google_containers kind: ClusterConfiguration kubernetesVersion: v1.18.0 # 集群版本,需要与kubeadm版本一致 networking: dnsDomain: cluster.local podSubnet: 10.244.0.0/16 # pod 内网ip网段 serviceSubnet: 10.96.0.0/12 # svc 内网ip网段 scheduler: {}
这里补充一个自动生成kubeadm-config.yaml
文件的命令,生成模板后需要修改。kubeadm config print init-defaults > kubeadm-config.yaml
.
4.2 在master1节点执行
kubeadm init --config kubeadm-config.yaml
执行完成后,就会在拉取镜像【需要等待…】
初始化节点
如果上面的yaml文件已经执行过一次,再次执行就会报错,这时,就需要将集群初始化后才能执行。
步骤:
# 1. 还原由 kubeadm init 或 kubeadm join 所做的更改 kubeadm reset -f # 2. 删除相关文件 rm -rf /etc/kubernetes/* rm -rf /var/lib/etcd/*
然后再次执行yaml文件即可。
按照执行出的结果提示配置环境变量,使用kubectl工具
# 执行下方命令 mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config # 查看节点 kubectl get nodes # 查看集群健康状态 kubectl get cs # 查看pod kubectl get pods -n kube-system
由于没有安装网络插件,所以会有pending状态,无妨,继续往下执行就好了。
按照提示保存以下内容,一会要使用
kubeadm join k8s-vip:16443 --token ivcq40.a1bb605g6df4xhdw \ --discovery-token-ca-cert-hash sha256:b65dcb57a2934439562ae138f552942600296edc04cdefb7da93031cf23c9a08 \ --control-plane
–control-plane : 只有在添加master节点的时候才有
5. 安装集群网络
从官方地址获取到flannel的yaml,在master1上执行
# 创建文件夹 mkdir flannel cd flannel # 下载yaml文件 wget -c https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
安装flannel网络,执行完apply之后需要等待一会,pending状态才会变成running。
kubectl apply -f kube-flannel.yml
检查,都已经running,且master已经ready。
kubectl get pods -n kube-system
6. master节点加入Kubernetes集群
6.1 复制密钥及相关文件
从master1复制密钥及相关文件到master2、master3
# master1中执行,修改IP,分别改为master2/3的IP执行2遍 ssh root@192.168.2.201 mkdir -p /etc/kubernetes/pki/etcd # 修改IP;master2\master3的IP,用master1连接master2\master3;输入密码 # 复制相应的文件到master2/master3 scp /etc/kubernetes/admin.conf root@192.168.2.201:/etc/kubernetes scp /etc/kubernetes/pki/{ca.*,sa.*,front-proxy-ca.*} root@192.168.2.201:/etc/kubernetes/pki scp /etc/kubernetes/pki/etcd/ca.* root@192.168.2.201:/etc/kubernetes/pki/etcd
6.2 master2和master3加入到集群
在master2、master3上执行在master1上init后输出的join命令,需要带上参数–control-plane表示把master控制节点加入集群。
# master2&master上依次执行 kubeadm join k8s-vip:16443 --token ivcq40.a1bb605g6df4xhdw \ --discovery-token-ca-cert-hash sha256:b65dcb57a2934439562ae138f552942600296edc04cdefb7da93031cf23c9a08 \ --control-plane
按照提示执行输出的3行命令
在master1上检查状态
kubectl get nodes kubectl get pods --all-namespaces
7. node节点加入Kubernetes集群
向集群添加新节点,执行在kubeadm init输出的kubeadm join命令,不加参数–control-plane
# 在node1上执行 kubeadm join k8s-vip:16443 --token ivcq40.a1bb605g6df4xhdw \ --discovery-token-ca-cert-hash sha256:b65dcb57a2934439562ae138f552942600296edc04cdefb7da93031cf23c9a08
提示:
#token是有时间期限的,如果过期了,执行如下命令获取后再执行。 kubectl create token --print-join-command #补充一个生成certificate-key的命令 kubeadm init phase upload-certs --upload-certs
报错解决,没有错误继续往下
执行命令后,报错no such host,如下:
这时候,需要将node1节点里的hosts表里的内容保持与master节点一致,再次执行就可以了。
集群网络重新安装,因为添加了新的node节点
# 在master1节点上执行 kubectl apply -f flannel/kube-flannel.yml
检查状态
kubectl get nodes kubectl get pods --all-namespaces
8. 测试kubernetes集群
在Kubernetes集群中创建一个pod,验证是否正常运行:
# 创建nginx deployment kubectl create deployment nginx --image=nginx # 暴露端口 kubectl expose deployment nginx --port=80 --target-port=80 --type=NodePort # 查看状态 kubectl get pod,svc
然后通过任何一个master或node节点或者虚拟IP加上端口号,都能够访问nginx页面;如果想要通过域名访问服务,可以参考这篇文章。注意一定要在master节点上添加污点容忍,不然无法通过虚拟IP 对应域名进行访问。这里要用第二种方式部署ingress-controller。
9. 模拟
我们现在有3个master节点,1个node节点,经过上述测试,发现集群可以正常访问nginx服务,因为三台master在正常运行,我们现在模拟挂掉一台master,让另外2台master正常运行,看一下会有什么效果:
1、首先,先查看集群是否正常,执行kubectl get nodes
命令,发现各个节点都处于ready状态
2、我们现在把master3这台服务器关掉,再看集群状态,关掉一会之后,发现master3节点状态变成了NotReady。
我们再使用其他节点的IP加上端口号访问nginx试一下,发现可以正常访问;如果使用master3节点的IP加端口号就无法访问nginx,是因为master3服务器已经关闭。
3、到现在为止,我们有2台正在运行的master,现在我们再关闭一台master,把master2也关掉,只留一台master,试一下会怎么样?
关闭前的状态:
关闭后再次执行kubectl get nodes
命令,发现报错了,显示无法连接到服务器。
虽然这时候在访问nginx还是可以正常访问,但是此时的集群已经坏掉了。
所以,如果有3个master节点,必须要保证2个正常运行;如果有5个master,必须保证3个正常运行。假设有N个master节点,必须保证有(N+1)/2个节点正常运行,才能保证集群正常。