z-k8s高可用Kubernetes集群准备

KVM虚拟机运行环境已经按照 构建Kubernetes云计算环境 准备就绪,现在具备服务器列表如下:

z-k8s高可用Kubernetes集群服务器列表

IP

主机名

说明

192.168.6.204

z-b-data-1

etcd+haproxy+keeplived

192.168.6.205

z-b-data-2

etcd+haproxy+keeplived

192.168.6.206

z-b-data-3

etcd+haproxy+keeplived

192.168.6.101

z-k8s-m-1

管控节点1

192.168.6.102

z-k8s-m-2

管控节点2

192.168.6.103

z-k8s-m-3

管控节点3

192.168.6.111

z-k8s-n-1

工作节点1(sr-iov)

192.168.6.112

z-k8s-n-2

工作节点2(sr-iov)

192.168.6.113

z-k8s-n-3

工作节点3(vgpu)

192.168.6.114

z-k8s-n-4

工作节点4(vgpu)

192.168.6.115

z-k8s-n-5

工作节点5

z-k8s 集群的管控节点和工作节点,全面安装 Docker containerd运行时(runtime) 运行时

  • 基础数据存储服务器 z-b-data-X :

    • 直接运行软件,不安装Docker容器化,也不运行Kubelet

    • 独立运行,不纳入K8s,仅作为基础服务提供( etcd - 分布式kv存储 )

  • 管控节点 z-k8s-m-X :

    • 安装containerd/Kubelet/Kubeadm

  • 工作节点 z-k8s-n-X :

    • 安装containerd/Kubelet/Kubeadm

注解

Kubernetes 1.24 移除了Docker直接支持,推荐使用 containerd运行时(runtime) 作为运行时,不仅可以节约资源而且更为安全(减少攻击面)。不过 containerd 文档资料较少,不如 Docker Atlas 有较为丰富的文档。例如,我 Docker btrfs 存储驱动 存储容器镜像,但是 containerd的btrfs 支持非常有限(不成熟),无法充分发挥 Btrfs - Linux存储系统 的优秀特性(实际依然是 OverlayFS文件系统 on btrfs),性能和稳定性不佳。

注解

我原先在 Kubernetes集群引导(单master) 部署 kubeadm 有详细步骤,本文是再次实践,以完成 Kubernetes集群引导(高可用)

安装 containerd运行时(runtime) 运行时(最新部署)

首先采用 containerd存储xfs文件系统 将containerd所使用的存储目录文件系统,由之前 Docker btrfs 存储驱动 切换为 XFS文件系统 :

  • 卸载 docker :

卸载docker.io
sudo systemctl stop docker
sudo systemctl stop docker.socket
sudo apt purge docker.io
sudo apt autoremove
将btrfs磁盘转换成xfs
sudo umount /var/lib/docker
sudo sed -i 's/^\/dev\/vdb1/#\/dev\/vdb1/g' /etc/fstab
sudo mkfs.xfs -f -n ftype=1 /dev/vdb1
echo "/dev/vdb1  /var/lib/containerd  xfs  defaults,uquota,pquota  0 1" | sudo tee -a /etc/fstab

sudo systemctl stop containerd
sudo mv /var/lib/containerd /var/lib/containerd.bak

sudo mkdir /var/lib/containerd
sudo mount /var/lib/containerd

sudo su -
(cd /var/lib/containerd.bak && tar cf - .) | (cd /var/lib/containerd && tar xf -)

sudo systemctl start containerd

然后采用 安装containerd官方执行程序 完成以下 containerd 安装:

安装最新v1.6.6 containerd官方二进制程序
wget https://github.com/containerd/containerd/releases/download/v1.6.6/containerd-1.6.6-linux-amd64.tar.gz
sudo tar Cxzvf /usr/local containerd-1.6.6-linux-amd64.tar.gz
安装containerd的systemd配置文件
sudo mkdir -p /usr/local/lib/systemd/system
sudo curl https://raw.githubusercontent.com/containerd/containerd/main/containerd.service -o /usr/local/lib/systemd/system/containerd.service
sudo systemctl daemon-reload
sudo unlink /etc/systemd/system/containerd.service
sudo systemctl enable containerd

然后安装 runc :

安装runc
wget https://github.com/opencontainers/runc/releases/download/v1.1.3/runc.amd64
sudo install -m 755 runc.amd64 /usr/local/sbin/runc
安装cni-plugins
wget https://github.com/containernetworking/plugins/releases/download/v1.1.1/cni-plugins-linux-amd64-v1.1.1.tgz
sudo mkdir -p /opt/cni/bin
tar Cxzvf /opt/cni/bin cni-plugins-linux-amd64-v1.1.1.tgz
  • 执行以下命令创建containerd的默认网络配置(该步骤可以提供kubernetes集群节点自举所依赖的网络):

生成Kuberntes自举所需的默认containerd网络配置
sudo mkdir /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml

注解

完成了 Kubernetes 容器运行时(Container Runtimes) 安装后,需要进一步完成 kubeadm 中网络和cgroup配置,见下文

安装Docker运行时(归档)

  • 安装 Kubernetes 容器运行时(Container Runtimes) Docker

    sudo apt update
    sudo apt upgrade -y
    
    sudo apt install docker.io -y
    
  • 将个人用户账号 huatai 添加到 docker 用户组方便执行docker命令:

    sudo usermod -aG docker $USER
    

docker存储驱动btrfs

VM数据盘( /var/lib/docker )准备

为了提升性能和存储效率,采用 Docker btrfs 存储驱动 ,所以执行:

注解

数据磁盘用于docker,所以命名是 <vm-name>.<disk-name> ,这里案例是用于 z-k8s-m-1 虚拟机的 docker 磁盘,所以命名为 z-k8s-m-1.docker

  • 创建磁盘完成后检查:

    virsh vol-list images_rbd
    

可以看到:

Name               Path
---------------------------------------------------
z-k8s-m-1          libvirt-pool/z-k8s-m-1
z-k8s-m-1.docker   libvirt-pool/z-k8s-m-1.docker
...
  • 准备设备XML文件

rbd磁盘设备XML
 1<disk type='network' device='disk'>
 2  <driver name='qemu' type='raw' cache='none' io='native'/>
 3  <auth username='libvirt'>
 4    <secret type='ceph' uuid='3f203352-fcfc-4329-b870-34783e13493a'/>
 5  </auth>
 6  <source protocol='rbd' name='libvirt-pool/z-k8s-m-1.docker'>
 7    <host name='192.168.6.204' port='6789'/>
 8    <host name='192.168.6.205' port='6789'/>
 9    <host name='192.168.6.206' port='6789'/>
10  </source>
11  <target dev='vdb' bus='virtio'/>
12</disk>
  • 添加磁盘文件:

    virsh attach-device z-k8s-m-1 z-k8s-m-1.docker-disk.xml --live --config
    
  • 此时在虚拟机 z-k8s-m-1 内部可以看到新磁盘设备 fdisk -l

    Disk /dev/vdb: 9.32 GiB, 10000000000 bytes, 19531250 sectors
    Units: sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    

这个磁盘设备将用于docker

  • 脚本 vm_docker-disk.sh 帮助完成上述自动化过程

rbd磁盘(用于docker)注入脚本
 1#!/bin/env bash
 2
 3. /etc/profile
 4
 5vm=$1
 6suffix=docker #表示磁盘用途
 7rbd_pool="libvirt-pool"
 8hosts_csv=/home/huatai/github.com/cloud-atlas/source/real/private_cloud/priv_cloud_infra/hosts.csv
 9
10
11function init {
12
13    if [ ! -f docker-disk.xml ]; then
14
15cat > ${suffix}-disk.xml <<__XML__
16<disk type='network' device='disk'>
17  <driver name='qemu' type='raw' cache='none' io='native'/>
18  <auth username='libvirt'>
19    <secret type='ceph' uuid='3f203352-fcfc-4329-b870-34783e13493a'/>
20  </auth>
21  <source protocol='rbd' name='libvirt-pool/RBD_DISK'>
22    <host name='192.168.6.204' port='6789'/>
23    <host name='192.168.6.205' port='6789'/>
24    <host name='192.168.6.206' port='6789'/>
25  </source>
26  <target dev='vdb' bus='virtio'/>
27</disk>
28__XML__
29
30     fi
31
32     ip=`grep ",${vm}," $hosts_csv | awk -F, '{print $2}'`
33
34     if [ -z $ip ]; then
35         echo "You input vm name is invalid, can't find vm IP"
36         echo "Please check $hosts_csv"
37         exit 1
38     fi
39}
40
41function inject_vm_disk {
42    virsh vol-create-as --pool images_rbd --name ${vm}.${suffix} --capacity 10GB --allocation 10GB --format raw
43    cat ${suffix}-disk.xml | sed "s/RBD_DISK/${vm}.${suffix}/g" > ${vm}.${suffix}-disk.xml
44    virsh attach-device $vm ${vm}.${suffix}-disk.xml --live --config
45}
46
47init
48inject_vm_disk
  • 执行方法:

    ./vm_docker-disk.sh z-k8s-m-2
    

btrfs存储驱动

在虚拟机内部配置 Docker btrfs 存储驱动 :

  • 在虚拟机内部安装 btrfs 管理软件包 btrfs-progs

    sudo apt install btrfs-progs -y
    
  • 磁盘分区:

    sudo parted /dev/vdb mklabel gpt
    sudo parted -a optimal /dev/vdb mkpart primary 0% 100%
    
  • 创建 btrfs

    sudo mkfs.btrfs -f -L docker /dev/vdb1
    
  • 添加 /etc/fstab 配置:

    echo "/dev/vdb1    /var/lib/docker    btrfs   defaults,compress=lzo    0 1" | sudo tee -a /etc/fstab
    
  • 停止Docker:

    sudo systemctl stop docker.socket
    sudo systemctl stop docker
    
  • 备份 /var/lib/docker 目录内容,并清空该目录:

    sudo cp -au /var/lib/docker /var/lib/docker.bk
    sudo rm -rf /var/lib/docker/*
    
  • 挂载btrfs文件系统:

    sudo mount /var/lib/docker
    
  • 检查挂载:

    mount | grep vdb1
    
  • /var/lib/docker.bk 内容恢复回 /var/lib/docker/

    sudo su -
    cp -au /var/lib/docker.bk/* /var/lib/docker/
    
  • 创建 /etc/docker/daemon.json :

创建Docker btrfs配置脚本
 1cat > /etc/docker/daemon.json << EOF
 2{
 3  "exec-opts": ["native.cgroupdriver=systemd"],
 4  "log-driver": "json-file",
 5  "log-opts": {
 6    "max-size": "100m"
 7  },
 8  "storage-driver": "btrfs"
 9}
10EOF
  • 启动docker:

    sudo systemctl start docker
    
  • 检查docker 是否使用btrfs:

    docker info
    

转发IPv4和允许iptables查看bridged流量

  • 执行以下脚本配置 sysctl :

配置k8s节点iptalbes
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

sudo modprobe overlay
sudo modprobe br_netfilter

# sysctl params required by setup, params persist across reboots
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables  = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward                 = 1
EOF

# Apply sysctl params without reboot
sudo sysctl --system

配置Cgroup v2

容器运行环境快速起步 详细说明了 Kubernetes 可以使用 Control Group v2 来更精细化管控资源。配置方法是在内核参数传递 systemd.unified_cgroup_hierarchy=1 。当时我配置采用修订 /etc/default/grubGRUB_CMDLINE_LINUX 行添加上述参数,然后再执行 sudo update-grub 更新启动。

另外一种常用的修订内核参数方法是使用 grubby修改内核参数 工具:

配置k8s节点cgroup v2
sudo apt install grubby -y
sudo grubby --update-kernel=ALL \
    --args="systemd.unified_cgroup_hierarchy=1"

配置 Systemd进程管理器 cgroup驱动

配置containerd的runc使用systemd cgroup驱动
[plugins]
  [plugins."io.containerd.grpc.v1.cri"]
    [plugins."io.containerd.grpc.v1.cri".containerd]
      [plugins."io.containerd.grpc.v1.cri".containerd.runtimes]
        [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
          ...
          runtime_type = "io.containerd.runc.v2"
          [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
            ...
            SystemdCgroup = true

重启 containerd

sudo systemctl restart containerd

参考