拓扑选择
配置高可用(HA)Kubernetes集群,有以下两种可选的etcd拓扑:
集群master节点与etcd节点共存,etcd也运行在控制平面节点上;
使用外部etcd节点,etcd节点与master在不同节点上运行;
- 第一种etcd拓扑架构图
- 第二种etcd拓扑架构图
部署要求
使用kubeadm部署高可用性Kubernetes集群的两种不同方法:
1.使用堆叠master节点。这种方法需要较少的基础设施,etcd成员和master节点位于同一位置。
2.使用外部etcd集群。这种方法需要更多的基础设施, master节点和etcd成员是分开的。
我们选择master节点和etcd都部署在一起
部署需求
至少3个master节点
至少3个worker节点
所有节点网络全部互通(公共或私有网络)
所有机器都有sudo权限,如果用root用户则不用sudo(不推荐)
能从一个设备到系统中所有节点的SSH访问
所有节点安装kubeadm和kubelet,kubectl是可选的。
针对外部etcd集群,你需要为etcd成员额外提供3个节点
负载均衡
master之间的高可用采用docker部署haproxy+keepalived的方式实现
基本配置
节点信息:
以下操作在所有节点执行。
- 配置主机名
其他的主机名以此类推
hostnamectl set-hostname k8s-master01
hostnamectl set-hostname k8s-node01
- 修改/etc/hosts
cat >> /etc/hosts << EOF
10.0.13.118 k8s-master01
10.0.13.119 k8s-master02
10.0.13.120 k8s-master03
10.0.13.160 k8s-node01
10.0.13.161 k8s-node02
10.0.13.162 k8s-node03
EOF
- 开启firewalld防火墙并允许所有流量
systemctl start firewalld && systemctl enable firewalld
firewall-cmd --set-default-zone=trusted
firewall-cmd --complete-reload
- 关闭selinux
sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config && setenforce 0
- 关闭swap
swapoff -a
yes | cp /etc/fstab /etc/fstab_bak
cat /etc/fstab_bak | grep -v swap > /etc/fstab
- 配置时间同步
使用chrony同步时间,centos7默认已安装,这里修改时钟源,所有节点与网络时钟源同步:
- 安装chrony:
yum install -y chrony
cp /etc/chrony.conf{,.bak}
#注释默认ntp服务器
sed -i 's/^server/#&/' /etc/chrony.conf
#指定上游公共 ntp 服务器
cat >> /etc/chrony.conf << EOF
server 0.asia.pool.ntp.org iburst
server 1.asia.pool.ntp.org iburst
server 2.asia.pool.ntp.org iburst
server 3.asia.pool.ntp.org iburst
EOF
- 设置时区
timedatectl set-timezone Asia/Shanghai
- 重启chronyd服务并设为开机启动:
systemctl enable chronyd && systemctl restart chronyd
- 验证,查看当前时间以及存在带*的行
timedatectl && chronyc sources
- 在所有的Kubernetes节点执行以下脚本
(若内核大于4.19替换nf_conntrack_ipv4为nf_conntrack):
cat > /etc/sysconfig/modules/ipvs.modules <<EOF
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
EOF
#执行脚本
chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack_ipv4
#安装相关管理工具
yum install ipset ipvsadm -y
- 配置内核参数
cat > /etc/sysctl.d/k8s.conf <<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_nonlocal_bind = 1
net.ipv4.ip_forward = 1
vm.swappiness=0
EOF
sysctl --system
- 安装并配置docker
#安装依赖软件包
yum install -y yum-utils device-mapper-persistent-data lvm2
#添加Docker repository,这里改为国内阿里云yum源
yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
#安装docker-ce
yum update -y && yum install -y docker-ce
##创建 /etc/docker 目录
mkdir /etc/docker
#配置 daemon.
cat > /etc/docker/daemon.json <<EOF
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=true"
],
"registry-mirrors": ["https://uyah70su.mirror.aliyuncs.com"]
}
EOF
#注意,由于国内拉取镜像较慢,配置文件最后追加了阿里云镜像加速配置。
mkdir -p /etc/systemd/system/docker.service.d
- 重启docker服务
systemctl daemon-reload && systemctl restart docker && systemctl enable docker
重复:以上所有操作要在所有节点执行
可以把上述配置写成脚本执行
- 安装负载均衡(k8s-master01节点执行)
负载均衡架构图
- 运行HA容器
使用的容器镜像为睿云智合开源项目breeze相关镜像,具体使用方法请访问:
https://github.com/wise2c-devops
其他选择:haproxy镜像也可以使用dockerhub官方镜像,但keepalived未提供官方镜像,可自行构建或使用dockerhub他人已构建好的镜像,本次部署全部使用breeze提供的镜像。
在3个master节点以容器方式部署haproxy,容器暴露6444端口,负载均衡到后端3个apiserver的6443端口,3个节点haproxy配置文件相同。
以下操作在master01节点执行
- 创建haproxy启动脚本
编辑start-haproxy.sh文件,修改Kubernetes Master节点IP地址为实际Kubernetes集群所使用的值(Master Port默认为6443不用修改):
mkdir -p /data/lb
cat > /data/lb/start-haproxy.sh << "EOF"
#!/bin/bash
MasterIP1=10.0.13.118
MasterIP2=10.0.13.119
MasterIP3=10.0.13.120
MasterPort=6443
docker run -d --restart=always --name HAProxy-K8S -p 6444:6444 \
-e MasterIP1=$MasterIP1 \
-e MasterIP2=$MasterIP2 \
-e MasterIP3=$MasterIP3 \
-e MasterPort=$MasterPort \
wise2c/haproxy-k8s
EOF
创建keepalived启动脚本
编辑start-keepalived.sh文件,修改虚拟IP地址VIRTUAL_IP、虚拟网卡设备名INTERFACE、虚拟网卡的子网掩码NETMASK_BIT、路由标识符RID、虚拟路由标识符VRID的值为实际Kubernetes集群所使用的值。(CHECK_PORT的值6444一般不用修改,它是HAProxy的暴露端口,内部指向Kubernetes Master Server的6443端口)
cat > /data/lb/start-keepalived.sh << "EOF"
#!/bin/bash
VIRTUAL_IP=10.0.13.180 vip注意必须是没用过的ip,设置时先ping一下看有没有人用过
INTERFACE=ens160
NETMASK_BIT=24
CHECK_PORT=6444
RID=10
VRID=160
MCAST_GROUP=224.0.0.18
docker run -itd --restart=always --name=Keepalived-K8S \
--net=host --cap-add=NET_ADMIN \
-e VIRTUAL_IP=$VIRTUAL_IP \
-e INTERFACE=$INTERFACE \
-e CHECK_PORT=$CHECK_PORT \
-e RID=$RID \
-e VRID=$VRID \
-e NETMASK_BIT=$NETMASK_BIT \
-e MCAST_GROUP=$MCAST_GROUP \
wise2c/keepalived-k8s
EOF
复制上述两个启动脚本到其他2个master节点
scp start-haproxy.sh start-keepalived.sh root@10.0.13.119:~
scp start-haproxy.sh start-keepalived.sh root@10.0.13.120:~
分别在3个master节点运行脚本启动haproxy和keepalived容器:
sh start-haproxy.sh && sh start-keepalived.sh
对了,记得脚本要授予执行权限
验证HA状态
docker ps
ip a | grep ens160
出现vip即为成功,三台都可以试下,vip不一定在master01上
netstat -tnlp | grep 6444
能出现端口信息即为成功
但是我在做这两个容器时出现问题,我的部署步骤和上面一致,但是没有出现vip
同样的操作同事是正常的出现vip的,所以我也没排查出来是什么问题
我的解决办法:
1.进入keepalived容器中,查看配置文件,发现/etc/keepalived/keepalived.conf配置文件里status显示BACKUP,属于非抢占模式,也没有日志文件可以查询,所以我把BACKUP改成MASTER抢占模式,重启服务(注意docker容器中没有systemctl等服务命令,所以选择把进程kill掉进行,它会自动重启),重启后在容器中执行ip a 发现出现了vip,也可以ping通vip,返回主机后也出现了vip,虽然不太清楚啥原因,但是正常了就先用着吧。
- 模拟故障迁移
在有vip这台主机上执行 docker stop HAProxy-K8S
可以看到vip漂移到k8s-master02节点
再把02节点也停掉,可以看到vip漂移到k8s-master03节点
但是把01节点恢复后,vip没有飘回来,说明还是有点问题,由于三台都挂掉的情况不太可能发生,所以目前在没找到问题的时候先这样用吧,如果真的全挂掉了就把容器删了重新做高可用即可。
- 安装kubeadm
以下操作在所有节点执行
由于官方源国内无法访问,这里使用阿里云yum源进行替换:
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
#安装kubeadm、kubelet、kubectl,注意这里默认安装当前最新版本v1.14.1:建议先查看所有版本,安装时加上版本号,总之版本很重要
yum install -y kubeadm kubelet kubectl(-1.14.1)
systemctl enable kubelet && systemctl start kubelet
初始化master节点(只在mater01主机上执行)
创建初始化配置文件
可以使用如下命令生成初始化配置文件
kubeadm config print init-defaults > kubeadm-config.yaml
vim kubeadm-config.yaml
下面填入master01的ip
下面填入vip和端口,默认6444
把默认镜像源改成阿里云的,注意下面的版本号改成和你安装的kubeadm一致,我的是1.14.1(重要)
这个podsubnet要和一会要装的flannel一致,可以设置和我的一样
下面开启ipvs,模式文件里是没有的,需要自己添加下面几行
- 初始化Master01节点
kubeadm init --config=kubeadm-config.yaml --experimental-upload-certs
该命令指定了初始化时需要使用的配置文件,其中添加–experimental-upload-certs参数可以在后续执行加入节点时自动分发证书文件。
只要初始化过程中不报错就不要打断它,它只是下载镜像需要时间,会卡住不动
初始化成功后的信息结尾处会出现两个
kubeadm join 10.0.13.180:6444 --token
注意保存,后面添加master节点和node节点会用到,注意是两个不一样的
无论是初始化失败或者集群已经完全搭建成功,你都可以直接执行kubeadm reset
命令清理集群或节点,然后重新执行kubeadm init或kubeadm join相关操作即可。
- 配置kubectl命令
无论在master节点或node节点,要能够执行kubectl命令必须进行以下配置:
root用户执行以下命令
cat << EOF >> ~/.bashrc
export KUBECONFIG=/etc/kubernetes/admin.conf
EOF
source ~/.bashrc
普通用户执行以下命令(参考init时的输出结果)
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 -n kube-system get pod
kubectl get cs
由于未安装网络插件,coredns处于pending状态,node处于notready状态。
- 安装网络插件
以下操作在master01节点执行即可。
安装flannel网络插件:
由于kube-flannel.yml文件指定的镜像从coreos镜像仓库拉取,可能拉取失败,可以从dockerhub搜索相关镜像进行替换,另外可以看到yml文件中定义的网段地址段为10.244.0.0/16。
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
sed -i 's#quay.io/coreos/flannel:v0.11.0-amd64#willdockerhub/flannel:v0.11.0-amd64#g' kube-flannel.yml
kubectl apply -f kube-flannel.yml
再次查看node和 Pod状态,全部为Running
- 加入master节点
依次将k8s-master02和k8s-master03加入到集群中,在02和03节点依次执行
这个信息在01节点初始化结束时会出现,注意有两条信息,别选错了
- 加入node节点
依次在node节点执行下面语句
- 验证集群状态
查看nodes运行情况
kubectl get nodes -o wide
查看pod运行情况
kubectl -n kube-system get pod -o wide
查看service
kubectl -n kube-system get svc
验证IPVS
查看kube-proxy日志,第一行输出Using ipvs Proxier.
kubectl -n kube-system logs -f kube-proxy-4vwbb
- 查看代理规则
[root@k8s-master01 ~]# ipvsadm -ln
- 执行以下命令查看etcd集群状态
至此部署完成,有错误一定要看日志输出