跳过正文
  1. 博客文章/

使用 Kube-VIP 部署高可用 Kubernetes 集群

·739 字·4 分钟·
Kubernetes Kube-Vip Containerd Kubeadm
Zayn
作者
Zayn
专注 Kubernetes、CI/CD、可观测性等云原生技术栈,记录生产环境中的实战经验与踩坑复盘。
目录

方案介绍
#

在私有环境中部署 Kubernetes 高可用集群时,传统方案需要准备硬件或软件负载均衡器来创建多控制平面集群。通常我们会选择使用 HAProxy + Keepalived 来实现这个功能:创建 2 个负载均衡器虚拟机,分配一个 VIP(虚拟 IP),通过 VIP 将流量重定向到后端的 Kubernetes 控制平面节点。架构如下图所示:

20210616142006

使用 Kube-VIP 的架构如下:

20210616142207

可以看到,使用 Kube-VIP 后架构更加优雅,无需额外的负载均衡服务器。

环境配置
#

节点信息
#

IP 地址主机名操作系统内核版本
192.168.8.81master-01CentOS Linux release 7.9.20095.4.128-1.el7.elrepo.x86_64
192.168.8.82master-02CentOS Linux release 7.9.20095.4.128-1.el7.elrepo.x86_64
192.168.8.83master-03CentOS Linux release 7.9.20095.4.128-1.el7.elrepo.x86_64
192.168.8.84node-01CentOS Linux release 7.9.20095.4.128-1.el7.elrepo.x86_64
192.168.8.85node-02CentOS Linux release 7.9.20095.4.128-1.el7.elrepo.x86_64
192.168.8.86node-03CentOS Linux release 7.9.20095.4.128-1.el7.elrepo.x86_64
192.168.8.100 (Kube-VIP 虚拟IP)---

软件版本
#

组件版本
Kubernetesv1.20.5
Containerdv1.4.6
Rancherv2.4.15

集群部署
#

以下节点初始化操作需要在所有节点上执行。

节点初始化
#

配置主机名解析
#

cat >> /etc/hosts << EOF
192.168.8.81 master-01
192.168.8.82 master-02
192.168.8.83 master-03
192.168.8.84 node-01
192.168.8.85 node-02
192.168.8.86 node-03
EOF

关闭 Swap
#

swapoff -a
sed -i 's/.*swap.*/#&/' /etc/fstab

设置主机名
#

hostnamectl set-hostname xxx # 例如:hostnamectl set-hostname master-01

关闭防火墙
#

systemctl stop firewalld
systemctl disable firewalld

关闭 SELinux
#

sed -i 's#SELINUX=enforcing#SELINUX=disabled#g' /etc/selinux/config
grep -i  ^selinux= /etc/selinux/config
setenforce 0
getenforce

更新内核
#

参考文档步骤

配置内核参数
#

sudo yum install -y conntrack ipvsadm ipset jq sysstat curl iptables

cat <<EOF | sudo tee /etc/modules-load.d/containerd.conf
overlay
br_netfilter
EOF

chmod a+x /etc/rc.local

cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf
net.bridge.bridge-nf-call-iptables  = 1
net.ipv4.ip_forward                 = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF

modprobe overlay
modprobe br_netfilter  # 加载内核模块

cat > /etc/rc.local << EOF
modprobe overlay
modprobe br_netfilter
EOF

sysctl -p /etc/sysctl.d/99-kubernetes-cri.conf

启用 IPVS 内核模块
#

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

安装和配置 Containerd
#

sudo yum install -y yum-utils device-mapper-persistent-data lvm2 \
&& sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo \
&& sudo yum makecache fast

yum install containerd -y

containerd config default > /etc/containerd/config.toml

sed -i "s#k8s.gcr.io#registry.cn-hangzhou.aliyuncs.com/google_containers#g"  /etc/containerd/config.toml
sed -i '/containerd.runtimes.runc.options/a\ \ \ \ \ \ \ \ \ \ \ \ SystemdCgroup = true' /etc/containerd/config.toml
sed -i "s#https://registry-1.docker.io#https://registry.cn-hangzhou.aliyuncs.com#g"  /etc/containerd/config.toml

systemctl daemon-reload
systemctl enable containerd
systemctl restart containerd

安装 crictl 客户端
#

crictl 是 Containerd 的命令行客户端工具

wget https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.21.0/crictl-v1.21.0-linux-amd64.tar.gz

sudo tar zxvf crictl-v1.21.0-linux-amd64.tar.gz -C /usr/local/bin

cat > /etc/crictl.yaml << EOF
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: true
EOF

安装 Kubernetes 组件
#

cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[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
EOF

yum list kubeadm --showduplicates | sort -r # 查看所有可用的 kubeadm 版本

yum install -y kubeadm-1.20.5 kubelet-1.20.5 kubectl-1.20.5

systemctl enable kubelet  # 启用 kubelet 服务自启动

可选:配置 kubectl 命令补全功能

yum install -y bash-completion
source /usr/share/bash-completion/bash_completion
source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc

Kubernetes 集群初始化
#

使用 kubeadm 首先初始化 master-01 节点,操作步骤如下:

生成 kubeadm 初始化配置文件
#

注意:由于控制平面地址配置为 VIP 地址,如果 Kube-VIP 尚未部署,kubeadm init 操作将一直处于 pending 状态直至超时。因此需要在执行初始化操作后立即部署 Kube-VIP。

kubeadm config print init-defaults > init_kubelet.yaml # 生成默认的初始化配置文件

# 修改后的初始化配置文件内容如下:
cat init_kubelet.yaml
apiVersion: kubeadm.k8s.io/v1beta2
bootstrapTokens:
- groups:
  - system:bootstrappers:kubeadm:default-node-token
  token: abcdef.0123456789abcdef
  ttl: 24h0m0s
  usages:
  - signing
  - authentication
kind: InitConfiguration
nodeRegistration:
  criSocket: /run/containerd/containerd.sock
---
apiServer:
  timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta2
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns:
  type: CoreDNS
etcd:
  local:
    dataDir: /var/lib/etcd
imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers
kind: ClusterConfiguration
controlPlaneEndpoint: "192.168.8.100:6443"
kubernetesVersion: v1.20.5
networking:
  dnsDomain: cluster.local
  serviceSubnet: 10.96.0.0/12
scheduler: {}
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: systemd
#protectKernelDefaults: false
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: ipvs

kubeadm init --config init_kubelet.yaml --upload-certs 

这里记录一个踩坑点,就是配置文件中所示的 “protectKernelDefaults”,添加了这个配置项后,会出现 kubelet 奔溃问题,将其注释掉后问题就解决了,下面图片中为官方文档中给出的注解。

image-20210624115549902

部署 Kube-VIP 静态 Pod
#

kubelet 静态 Pod 目录为 /etc/kubernetes/manifests/,只需将对应的 YAML 文件生成到此目录下,Pod 的生命周期将由 kubelet 管理。

export VIP=192.168.8.100 # VIP 地址
export INTERFACE=eth0
ctr image pull docker.io/plndr/kube-vip:0.3.1
mkdir -p /etc/kubernetes/manifests
ctr run --rm --net-host docker.io/plndr/kube-vip:0.3.1 vip \
/kube-vip manifest pod \
--interface $INTERFACE \
--vip $VIP \
--controlplane \
--services \
--arp \
--leaderElection | tee  /etc/kubernetes/manifests/kube-vip.yaml

image-20210624142906470

image-20210624142917982

image-20210624142932603

安装 CNI 网络插件
#

集群初始化后,需要安装网络插件才能正常使用。CNI 插件有多种选择,这里以 Cilium 为例。

curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash
helm repo add cilium https://helm.cilium.io/
helm install cilium cilium/cilium --version 1.9.4 \
--namespace kube-system

image-20210624144753427

添加其他控制平面节点
#

复制证书文件到其他控制平面节点
#

ssh-keygen  # 生成 SSH 密钥对

ssh-copy-id root@"node_id"  # 配置免密登录

USER=root # 可自定义用户
CONTROL_PLANE_IPS="192.168.8.82 192.168.8.83"

for host in ${CONTROL_PLANE_IPS}; do
    ssh "${USER}"@$host "mkdir -p /etc/kubernetes/pki/ /etc/kubernetes/pki/etcd/"
    scp /etc/kubernetes/pki/ca.crt "${USER}"@$host:/etc/kubernetes/pki/
    scp /etc/kubernetes/pki/ca.key "${USER}"@$host:/etc/kubernetes/pki/
    scp /etc/kubernetes/pki/sa.key "${USER}"@$host:/etc/kubernetes/pki/
    scp /etc/kubernetes/pki/sa.pub "${USER}"@$host:/etc/kubernetes/pki/
    scp /etc/kubernetes/pki/front-proxy-ca.crt "${USER}"@$host:/etc/kubernetes/pki/
    scp /etc/kubernetes/pki/front-proxy-ca.key "${USER}"@$host:/etc/kubernetes/pki/
    scp /etc/kubernetes/pki/etcd/ca.crt "${USER}"@$host:/etc/kubernetes/pki/etcd/
    scp /etc/kubernetes/pki/etcd/ca.key "${USER}"@$host:/etc/kubernetes/pki/etcd/
done

image-20210624145312992

image-20210624145345436

控制平面节点加入集群
#

kubeadm join 192.168.8.100:6443 --token hash.hash\
     --discovery-token-ca-cert-hash sha256:hash \
     --control-plane --certificate-key key

master-02 加入集群

image-20210624145645907

master-03 加入集群

image-20210624145724332

重要提醒:新加入集群的 Master 节点需要部署 Kube-VIP 静态 Pod,以确保集群具备高可用特性。请在每个新加入的控制平面节点上执行上述 Kube-VIP 部署步骤。

image-20210624150202416

image-20210624150219305

image-20210624150310623

添加 Worker 节点
#

kubeadm join 192.168.8.100:6443 --token hash.hash\
    --discovery-token-ca-cert-hash sha256:hash

image-20210624150546402

image-20210624150607013

可选配置优化
#

移除 Master 节点污点
#

生产环境中请谨慎操作,建议保留 Master 节点污点以避免业务 Pod 调度到控制平面节点。

kubectl taint nodes --all node-role.kubernetes.io/master-

参考文档
#

相关文章

Kubeadm 部署 kubernetes-v1.19.x 集群
·766 字·4 分钟
Kubernetes Kubeadm V1.19.x Install
使用 Kaniko 在 Kubernetes 中构建 Docker 镜像
·468 字·3 分钟
Kubernetes DevOps Kaniko Docker Kubernetes CI/CD
修复 Rancher 导入集群时 Scheduler 和 Controller Manager 不健康问题
·483 字·3 分钟
Kubernetes Rancher Kubekey