本文主要介绍了通过kubeadm部署3master节点高可用k8s 1.17.3集群
更新于 2021-03-28
集群规划
| 主机名 | IP地址 | 用途 |
|---|---|---|
| SCA-LUM700011 | 10.8.138.8 | nginx+nfs+运维节点 |
| SCA-LUM700007 | 10.8.138.5 | master-1 |
| SCA-LUM700008 | 10.8.138.6 | Master-2 |
| SCA-LUM700012 | 10.8.138.10 | Master-3 |
| SCA-LUM700013 | 10.8.138.9 | Node-1 |
| SCA-LUM700014 | 10.8.138.11 | node-2 |
操作系统centos7.6,前端还有一个elb,地址为10.8.138.12,代理master的apiserver。kube-proxy使用ipvs模式,集群使用1.17.3版本
安装工具
nfs的作用是为集群提供共享存储,nginx后面用来代理集群的ingress等服务。在SCA-LUM700011这台nfs服务器上有挂载的磁盘,先对其格式化并创建nfs的数据目录:
1 | mkfs.xfs /dev/vdb -f |
安装nfs相关服务并启动nfs:
1 | yum install -y nfs-utils rpcbind |
在集群的每一个节点上执行下面的命令安装nfs-utils工具:
1 | yum install -y nfs-utils |
nginx将作为一个代理,代理集群中的服务,这里使用yum方式安装nginx。
1 | # 安装依赖 |
ansible可以方便批量执行指令,首先在SCA-LUM700011这台创建ssh key并分发到其他节点,将这台服务器作为运维节点,下面使用的ansible就在这个上面运行。
1 | ssh-keygen |
安装ansible:
1 | yum install -y ansible |

内核优化
注意,我这里计划使用ipvs模式,需要升级内核版本,每台服务器都升级一下
1 | # 载入公钥 |
1 | cat > /etc/k8s.conf << EOF |
fs.file-max表示系统级别最大文件句柄数量;net.ipv4.neigh.default.gc_thresh1表示存在于ARP高速缓存中的最少层数,如果少于这个数垃圾收集器将不会运行。缺省值是128;net.ipv4.neigh.default.gc_thresh2保存在ARP高速缓存中的最多的记录软限制。垃圾收集器在开始收集前允许记录数超过这个数字 5 秒。缺省值是 512;net.ipv4.neigh.default.gc_thresh3保存在ARP高速缓存中的最多记录的硬限制,一旦高速缓存中的数目高于此,垃圾收集器将马上运行。缺省值是1024;net.netfilter.nf_conntrack_max内核内存中netfilter可以同时处理的“任务”(连接跟踪条目);net.netfilter.nf_conntrack_buckets哈希表大小(只读)(64位系统、8G内存默认 65536,16G翻倍,如此类推);net.core.netdev_max_backlog网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目;fs.inotify.max_user_instances默认值: 128 指定了每一个real user ID可创建的inotify instatnces的数量上限;fs.inotify.max_user_watches默认值: 8192 指定了每个inotify instance相关联的watches的上限;
执行下面的命令在每个节点生效配置:
1 | ansible cluster -m copy -a 'src=/etc/sysctl.d/k8s.conf dest=/etc/sysctl.d/k8s.conf mode=0755' |
部署前准备
通过ansible为每个节点设置host文件:
1 | ansible cluster -m shell -a 'cat >> /etc/hosts <<EOF |
需要给集群所有的节点安装docker
首先添加repo文件:
1 | ansible cluster -m shell -a 'yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo' |
设置存储目录,一般docker的数据存放路径为/var/lib/docker,所以在每个服务器上最好都有一个数据盘挂载到该目录下,防止docker数据过多爆盘。这里以一台服务器的设置为例:
1 | mkdir /var/lib/docker |
安装docker
1 | # 查看当前可用的版本 |
设置配置文件:
1 | cat > daemon.json <<EOF |
启动服务:
1 | ansible cluster -m shell -a 'systemctl daemon-reload' |
1 | ansible cluster -m shell -a 'swapoff -a' |
本集群的service网络采用ipvs模式:
1 | # 配置内核参数 |
安装基础服务
添加yum源
1 | cat > /etc/yum.repos.d/kubernetes.repo << EOF |
安装kubelet、kubectl、kubeadm
这里安装的是1.17.3版本:
1 | # 安装kubectl、kubeadm、kubelet |
部署master节点
这一步在任意一个master上执行,这里我在master1上执行。需要配置下kubeadm的相关参数。
配置kubeadm参数
1 | cat > kubeadm-config.yaml << EOF |
- 其中
10.8.138.12为我前端slb的IP地址,代理后端三个master节点的6443; - 根据实际情况在
certSANs中添加IP和域名; - 注意修改其中的kubernetes的版本,以及ipvs模式的调度算法(这里我使用的是lc)
验证配置
下面的命令可以验证配置是否有误,并不会真正执行:
1 | kubeadm init --config=kubeadm-config.yaml --upload-certs --dry-run |
创建集群
1 | # 创建集群 |
执行成功的话,会出现下面的信息:

从上边可以看出,添加master节点和node节点就可以在对应服务器上执行下面的命令:
1 | 添加master |
命令中的token有两个小时时效,时效后需要重新获取
添加其他的master节点
在剩下的两个master节点SCA-LUM700008和SCA-LUM700012执行下面的命令:
1 | kubeadm join 10.8.138.12:6443 --token z9ibq2.s5ttzyxvc49mep02 \ |
不需要拷贝kubeadm-config.yaml文件,会通过第一个apiserver去配置信息;
设置kubectl
1 | # 自动补全 |
验证master部署情况
1 | # 查看master |

这里有些pod没有启动是正常的,因为集群还没部署完成。
确认kubeproxy开启了ipvs
首先查看网卡信息,多了一个kube-ipvs0网卡:
1 | $ ip a s |
查看ipvs规则:
1 | $ ipvsadm -Ln |
部署etcd
更新etcd配置
更新后会自动重启服务:
1 | ansible master -m shell -a 'sed -i "/--initial-cluster=/c\ - --initial-cluster=sca-lum700012=https://10.8.138.10:2380,sca-lum700007=https://10.8.138.5:2380,sca-lum700008=https://10.8.138.6:2380" /etc/kubernetes/manifests/etcd.yaml' |
查看etcd节点状态
1 | # 下载etcdctl |

查看集群状态
1 | ETCDCTL=3 etcdctl --cluster --write-out=table --cert /etc/kubernetes/pki/etcd/peer.crt --key /etc/kubernetes/pki/etcd/peer.key --cacert /etc/kubernetes/pki/etcd/ca.crt --endpoints https://10.8.138.10:2379,https://10.8.138.5:2379,https://10.8.138.6:2379 endpoint status |

etcd节点健康状态
1 | ETCDCTL=3 etcdctl --cluster --write-out=table --cert /etc/kubernetes/pki/etcd/peer.crt --key /etc/kubernetes/pki/etcd/peer.key --cacert /etc/kubernetes/pki/etcd/ca.crt --endpoints https://10.8.138.10:2379,https://10.8.138.5:2379,https://10.8.138.6:2379 endpoint health |

部署node节点
在所有node节点上执行下面的命令:
1 | kubeadm join 10.8.138.12:6443 --token z9ibq2.s5ttzyxvc49mep02 \ |
查看:
1 | kubectl get node |
节点已经添加进来了,因为没有部署CNI所以都是NOTREADY。
部署calico
下载calico
1 | # 下载calico的yaml文件 |
部署calico
修改calico.yaml:
1 | # 修改为pod网段 |
部署calico:
1 | kubectl apply -f calico.yaml |
部署完成后,查看节点状态,应该都READY:
1 | kubectl get node |
设置calico命令行工具
下载calico命令行工具:
1 | # 下载 |
查看calico节点
1 | calicoctl node status |
查看ippool
1 | calicoctl get ippool -o wide |
查看ip状态
1 | calicoctl ipam show |

集群校验
1 | kubectl config get-clusters |

nginx服务其配置
SCA-LUM700011作为nginx服务器,将会代理ingress服务,所以先设置一下。
自签证书
1 | # 确认安装了openssl |
修改nginx主配置文件
修改/etc/nginx/nginx.conf文件为如下内容:
1 | user nginx; |
这里使用include导入其他的配置文件,所有服务的nginx配置都放在/etc/nginx/conf.d下,如果目录不存在需要自己创建。
在``/etc/nginx/conf.d下先创建一个通用配置文件common.ini`,这个是所有配置文件都要用的,所以抽离出来:
1 | location = /favicon.ico { |
创建一个测试配置
在/etc/nginx/conf.d下新建一个配置文件https.conf:
1 | server { |
在/usr/share/nginx/html下创建测试页面:
1 | $ echo "this is https page" > /usr/share/nginx/html/index.html |
绑定host
因为我是测试环境,且我要通过域名的方式访问服务,所以需要绑定host,这一步在自己的电脑上操作,过程不赘述。
重启nginx并访问
执行下面的命令检查配置并重新加载:
1 | nginx -t |
然后通过浏览器访问域名:https-server.example.com,应该就可以看到设置的https页面了。
注意,有的浏览器对于自签证书是不信任的,需要手动下载证书然后在电脑中导入就可以了。




