容器云平台的集群高可用安装部署及配置(一)etcd 组件的高可用部署
【作者】周飒,上海某金融单位系统架构师。从事数据中心运维工作,主要负责数据中心kubernetes容器私有云的建设及维护,2020 容器云职业技能大赛百位专家委员会成员。
容器云平台的集群高可用安装部署
Kubernetes(简称k8s)凭借着其优良的架构,灵活的扩展能力,丰富的应用编排模型,成为了容器编排领域的事实标准,也是各大企业进行容器云平台建设的首选技术。无论是在公有云环境使用还是在私有云环境使用,k8s集群的生产高可用是一个不能回避的话题。本章节阐述了k8s容器云平台的高可用部署方式,其核心思想是让k8s master节点中的各类组件(etcd/kube-apiserver/kube-controller-man-ager/kube-scheduler)具备高可用性,不存在组件的单点故障。学习本章节,学员可以掌握k8s环境下如何让各组件组成集群以达到高可用的效果,为k8s在生产的高可用部署实践提供参考和指导。
1 k8s集群高可用部署说明
1.1 环境准备
要实现k8s集群的高可用,集群至少需要3节点。本章节以下面的3节点为例进行部署说明。
◎ 主机名:k8s-1; IP:172.16.90.39
◎ 主机名:k8s-2; IP:172.16.90.40
◎ 主机名:k8s-3; IP:172.16.90.41
3节点均为CentOS 7操作系统,建议升级内核到4.4以上,因为CentOS 7自带的3.10内核存在一些bug,会导致Docker,Kubernetes运行不稳定,特别是高版本的Docker、Kubernetes(参考https://github.com/kubernetes/kubernetes/issues/61937)。
节点上需要做如下配置。
◎ ssh免密登录,将k8s-1的ssh公钥分发到另外两个节点,ssh-copy-id root@k8s-2
◎ 各节点上关闭防火墙,systemctl stop firewalld && systemctl disable firewalld
◎ 各节点上关闭SELinux,setenforce 0 && sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/seli-nux/config
1.2 部署策略及高可用原理
以下部署的Kubernetes版本为1.14.2,etcd的版本为3.3.13。
Kubernetes的节点角色分为master和node两种,node节点默认已经有高可用了,因为pod会分配到各个node上,如果有node挂了,k8s就会将node置为Not Ready,随后到其他健康的node上新建pod,保证副本数为预期状态。因此要实现Kubernetes集群的高可用,实际上是要实现master节点的高可用。
master节点上运行了如下组件:
◎ etcd
◎ kube-apiserver
◎ kube-scheduler
◎ kube-controller-manager
其中,etcd采用以上3节点实现高可用,etcd会保证所有的节点都会保存数据,并保证数据的一致性和正确性,在正常运行的状态下,集群中会有一个 leader,其余的节点都是 followers。通常情况下,如果是follower节点宕机,如果剩余可用节点数量超过半数,不影响集群正常工作。如果是leader节点宕机,那么follower就收不到心跳而超时,发起竞选获得投票,成为新的leader,继续为集群提供服务。
kube-apiserver、kube-scheduler和kube-controller-manager三个组件均以多实例模式运行。
kube-apiserver是无状态的,一般可以采用以下两种方式实现高可用:
(1) 通过配置haproxy或nginx等负载均衡器进行代理访问kube-apiserver,从而保证kube-apiserver服务的高可用性,haproxy或nginx等负载均衡器自身使用keepalived绑定一个vip实现高可用;
(2) 在每个master和node节点配置一个nginx,后端对接多个kube-apiserver实例,nginx对多个kube-apiserver实例做健康检查和负载均衡,kubelet、kube-proxy、controller-manager、scheduler组件通过本地的nginx访问kube-apiserver,从而实现kube-apiserver的高可用。
本章节以第二种方式为例来介绍k8s集群的高可用部署。
kube-scheduler和kube-controller-manager是有状态的服务,多个实例会通过向apiserver中的endpoint加锁的方式来选举产生一个leader实例,其它实例处于阻塞模式,当leader挂了后,会重新选举产生新的leader,从而保证服务的可用性。因此这两个组件采用多实例部署即可实现高可用。
2. etcd组件的高可用部署
2.1 创建CA自签名根证书
Kubernetes系统各组件需要使用x509证书对通信进行加密和认证。本章节在部署各组件前,需要创建CA自签名根证书,用来给后续创建的其他组件证书进行签发。
# 创建相应的工作目录
mkdir -p /opt/k8s/bin && mkdir -p /opt/k8s/cert
# 安装cfssl工具
wget -O /opt/k8s/bin/cfssl https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
wget -O /opt/k8s/bin/cfssljson https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
# 添加执行权限及配置PATH
chmod +x /opt/k8s/bin/*
echo 'PATH=/opt/k8s/bin:$PATH' >>/root/.bashrc
source /root/.bashrc
# 创建根证书配置文件
cat > ca-config.json <<EOF
{
'signing': {
'default': {
'expiry': '87600h'
},
'profiles': {
'kubernetes': {
'usages': [
'signing',
'key encipherment',
'server auth',
'client auth'
],
'expiry': '87600h'
}
}
}
}
EOF
# 创建根证书签名请求文件
cat > ca-csr.json <<EOF
{
'CN': 'kubernetes',
'key': {
'algo': 'rsa',
'size': 2048
},
'names': [
{
'C': 'CN',
'ST': 'ShangHai',
'L': 'ShangHai',
'O': 'k8s',
'OU': '4Paradigm'
}
],
'ca': {
'expiry': '876000h'
}
}
EOF
# 根据以上信息创建CA证书和私钥
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
会生成3个文件
◎ ca.pem
◎ ca-key.pem
◎ ca.csr
将CA证书(ca.pem)、CA私钥(ca-key.pem)及CA配置文件(ca-config.json)拷贝到所有节点的/etc/k8s/cert目录下,若没有该目录需创建
2.2 下载etcd及创建etcd证书私钥
在https://github.com/etcd-io/etcd/releases下载etcd的安装包。这里下载3.3.13版本的etcd。
wget \
https://github.com/coreos/etcd/releases/download/v3.3.13/etcd-v3.3.13-linux-amd64.tar.gz
tar -xvf etcd-v3.3.13-linux-amd64.tar.gz
将解压得到的文件夹中的二进制可执行文件etcd及etcdctl拷贝到三个节点的/opt/k8s/bin目录下,并赋予执行权限。
使用前一步创建的CA证书,来签发etcd集群各节点使用的x509证书,用于加密客户端与etcd集群、etcd集群之间的数据通信。
cat > etcd-csr.json <<EOF
{
'CN': 'etcd',
'hosts': [
'127.0.0.1',
'172.16.90.39',
'172.16.90.40',
'172.16.90.41'
],
'key': {
'algo': 'rsa',
'size': 2048
},
'names': [
{
'C': 'CN',
'ST': 'ShangHai',
'L': 'ShangHai',
'O': 'k8s',
'OU': '4Paradigm'
}
]
}
EOF
# 使用CA证书创建证书和私钥
cfssl gencert -ca=ca.pem \
-ca-key=ca-key.pem \
-config=ca-config.json \
-profile=kubernetes etcd-csr.json | cfssljson -bare etcd
该命令会生成3个文件
◎ etcd.pem (etcd使用的证书)
◎ etcd-key.pem (etcd的私钥)
◎ etcd.csr (etcd的证书签名请求文件)
将etcd.pem及etcd-key.pem拷贝到所有节点的/etc/etcd/cert/目录下,若没有该目录需创建。
2.3 创建etcd的systemd unit文件
注意,以上文件是k8s-1节点上使用的etcd service文件,另外两个节点需要把以上文件中的红色部分替换为自身节点的主机名或IP。
按照以上内容创建好3个节点的etcd service文件后,将文件拷贝并重命名为相应节点的/etc/systemd/system/etcd.service文件。
2.4 各节点启动etcd服务
分别登录到各节点,执行如下命令。
# 创建etcd的数据目录
mkdir -p /data/k8s/etcd/data
mkdir -p /data/k8s/etcd/wal
# 启动etcd服务
systemctl daemon-reload
systemctl enable etcd
systemctl start etcd
# 检查etcd启动结果是否为active running
systemctl status etcd | grep Active
# 查看etcd日志
journalctl -u etcd
2.5 验证服务状态
分别在各节点执行如下命令,endpoints中的IP需要替换为实际节点的IP。
若集群服务状态正常,则会分别输出如下结果:
查看集群当前的leader。
输出如下,显示第3个节点为leader。