使用kube-vip+containerd在openstack上搭建集群

  1. 1. 环境准备
    1. 1.1. 环境初始化
    2. 1.2. 内核升级
    3. 1.3. 依赖服务安装
    4. 1.4. 容器运行时Containerd
  2. 2. 安装k8s
  3. 3. 初始化前准备
    1. 3.1. Kube-vip 配置
    2. 3.2. openstack配置
  4. 4. 启动k8s
    1. 4.1. 添加cni插件
  5. 5. 后记
    1. 5.1. 部分QA
    2. 5.2. k8s版本选择
    3. 5.3. 为什么采用containerd

环境准备

本文档仅做演示,除搭建master外其余操作与普通k8s集群相同,故省略部分操作

当前使用机器的操作系统均为CentOS7

主机名称 ip地址 备注
K8s-master-1 10.1.12.217 master节点
K8s-master-2 10.1.12.169 master节点
api.k8s.local 10.1.12.218 master(虚拟浮动IP)

环境初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
cat  > /etc/hosts <<EOF
10.1.12.217 k8s-master-1
10.1.12.169 K8s-master-2
10.1.12.218 K8s-master-2
10.1.12.218 api.k8s.local
EOF
# 修改hosts
setenforce 0
sed -i 's/enforcing/disabled/g' /etc/selinux/config
# 关闭selinux
systemctl disable firewalld --now
#关闭防火墙
swapoff -a
# 关闭交换分区
cat > /etc/sysctl.d/k8s.conf <<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF
# 网络相关设置
sysctl -p /etc/sysctl.d/k8s.conf

cat > /etc/sysconfig/modules/ipvs.modules <<EOF
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack
EOF
# Linux内核4.19版本将 nf_conntrack_ipv4 更新为 nf_conntrack
# 如果不升级内核请将最后一条改为nf_conntrack_ipv4


chmod 755 /etc/sysconfig/modules/ipvs.modules
bash /etc/sysconfig/modules/ipvs.modules
lsmod | grep -e ip_vs -e nf_conntrack
# IPVS 模块启用

modprobe br_netfilter

内核升级

内核升级的原因以及版本选择请看文末QA

1
2
3
4
5
6
7
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
yum install https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm
yum list available --disablerepo=* --enablerepo=elrepo-kernel
yum -y install kernel-lt-5.4.147-1.el7.elrepo --enablerepo=elrepo-kernel
# 启用内核
grub2-set-default 'CentOS Linux (5.4.147-1.el7.elrepo.x86_64) 7 (Core)'
# 此处请根据实际情况决定

依赖服务安装

1
yum -y install ipset chrony ipvsadm 

开启时间同步:

1
2
3
4
5
6
7
8
chronyc sources
210 Number of sources = 4
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
^- 193.182.111.141 2 6 377 10 -1390us[-1390us] +/- 176ms
^* 111.230.189.174 2 6 275 76 -2407us[-5565us] +/- 35ms
^- a.chl.la 2 6 377 11 -22ms[ -22ms] +/- 128ms
^- de-user.deepinid.deepin.> 3 6 377 14 -23ms[ -23ms] +/- 144ms

容器运行时Containerd

较多用户可能采用tar安装的方式安装containerd,本人相对较懒,由于docker-ce中也采用containerd,故直接安装docker-ce提供的软件包即可

1
2
3
4
5
6
7
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 sed -i 's+download.docker.com+mirrors.aliyun.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo
sudo yum makecache fast
# 以上都是阿里巴巴镜像源复制的内容
yum -y install containerd.io
# 安装containerd

修改containerd配置文件:

1
2
3
4
5
6
7
8
9
10
11
mkdir -p /etc/containerd
containerd config default > /etc/containerd/config.toml
# 初始化containerd配置文件
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
# 设置containerd 的cgroup driver为systemd
sed -i "s#https://registry-1.docker.io#https://registry.cn-hangzhou.aliyuncs.com#g" /etc/containerd/config.toml
# 添加阿里镜像加速

systemctl restart containerd

安装k8s

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 cat > /etc/yum.repos.d/kubernetes.repo <<EOF
[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 makecache fast
yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
# 安装组件

初始化前准备

安装完kubernetes的组件后,crictl命令就可以使用了,但是我们发现实际使用会报错,原因是没有修改containerd的sock路径

1
2
3
4
5
cat <<EOF > /etc/crictl.yaml
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false

修改kubelet启动配置,配置cgroup为systemd,否则会出现hostname无法解析的错误

1
echo 'KUBELET_EXTRA_ARGS="--cgroup-driver=systemd"' > /etc/sysconfig/kubelet

Kube-vip 配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
mkdir -p /etc/kubernetes/manifests/
# 配置vip地址
export VIP=10.1.12.218
# 设置网卡名称
export INTERFACE=eth0
ctr image pull docker.io/plndr/kube-vip:v0.3.8
# 使用下面的容器输出静态Pod资源清单
ctr run --rm --net-host docker.io/plndr/kube-vip:v0.3.8 vip \
/kube-vip manifest pod \
--interface $INTERFACE \
--vip $VIP \
--controlplane \
--services \
--arp \
--leaderElection | tee /etc/kubernetes/manifests/kube-vip.yaml
# 参数备注
# 除了以上参数
# 还支持CIDR 端口等其他配置,详情请参阅文档

openstack配置

注意! 此处非必需

openstack的网络类型下,需要手动调整网络端口,在网络–> 子网->端口中找到相应机器的端口

添加额外ip地址,添加后虚拟ip即可生效

启动k8s

1
2
3
4
systemctl enable --now kubelet
# 启动kubelet
kubeadm config print init-defaults --component-configs KubeletConfiguration > kubeadm.yaml
# 生成模板文件

模板文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
apiVersion: kubeadm.k8s.io/v1beta3
bootstrapTokens:
- groups:
- system:bootstrappers:kubeadm:default-node-token
token: abcdef.0123456789abcdef
ttl: 24h0m0s
usages:
- signing
- authentication
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: 10.1.12.217 # 指定当前节点内网IP
bindPort: 6443
nodeRegistration:
criSocket: /run/containerd/containerd.sock # 使用 containerd的Unix socket 地址
imagePullPolicy: IfNotPresent
name: k8s-master-ha-1
taints: # 给master添加污点,master节点不能调度应用
- effect: "NoSchedule"
key: "node-role.kubernetes.io/master"
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: ipvs # kube-proxy 模式
---
apiVersion: kubeadm.k8s.io/v1beta3
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns: {}
etcd:
local:
dataDir: /var/lib/etcd
imageRepository: registry.aliyuncs.com/kainstall # 设置k8s镜像仓库,此处为白嫖的seokeo自动同步的仓库
kind: ClusterConfiguration
kubernetesVersion: 1.22.0
controlPlaneEndpoint: api.k8s.local:6443 # 设置控制平面Endpoint地址
apiServer:
extraArgs:
authorization-mode: Node,RBAC
timeoutForControlPlane: 4m0s
certSANs: # 添加其他master节点的相关信息
- api.k8s.local
- k8s-master-1
- k8s-master-2
- 10.1.12.217
- 10.1.12.169


networking:
dnsDomain: cluster.local
serviceSubnet: 10.96.0.0/12
podSubnet: 10.244.0.0/16 # 指定 pod 子网
scheduler: {}
---
apiVersion: kubelet.config.k8s.io/v1beta1
authentication:
anonymous:
enabled: false
webhook:
cacheTTL: 0s
enabled: true
x509:
clientCAFile: /etc/kubernetes/pki/ca.crt
authorization:
mode: Webhook
webhook:
cacheAuthorizedTTL: 0s
cacheUnauthorizedTTL: 0s
clusterDNS:
- 10.96.0.10
clusterDomain: cluster.local
cpuManagerReconcilePeriod: 0s
evictionPressureTransitionPeriod: 0s
fileCheckFrequency: 0s
healthzBindAddress: 127.0.0.1
healthzPort: 10248
httpCheckFrequency: 0s
imageMinimumGCAge: 0s
kind: KubeletConfiguration
cgroupDriver: systemd # 配置 cgroup driver
logging: {}
memorySwap: {}
nodeStatusReportFrequency: 0s
nodeStatusUpdateFrequency: 0s
rotateCertificates: true
runtimeRequestTimeout: 0s
shutdownGracePeriod: 0s
shutdownGracePeriodCriticalPods: 0s
staticPodPath: /etc/kubernetes/manifests
streamingConnectionIdleTimeout: 0s
syncFrequency: 0s
volumeStatsAggPeriod: 0s

Master1 初始化

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

Master2 加入节点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
mkdir -p /etc/kubernetes/manifests/
# 配置vip地址
export VIP=10.1.12.218
# 设置网卡名称
export INTERFACE=eth0
ctr image pull docker.io/plndr/kube-vip:v0.3.8
# 使用下面的容器输出静态Pod资源清单
ctr run --rm --net-host docker.io/plndr/kube-vip:v0.3.8 vip \
/kube-vip manifest pod \
--interface $INTERFACE \
--vip $VIP \
--controlplane \
--services \
--arp \
--leaderElection | tee /etc/kubernetes/manifests/kube-vip.yaml

# 以上为kube-vip的设置

kubeadm join api.k8s.local:6443 --token abcdef.0123456789abcdef --discovery-token-ca-cert-hash sha256:fde095725e7cc1bb903da85c14ff6558bc5fd359e93b6abc05b49ec5cc11c4bd --control-plane --certificate-key fce19cd067ffcca32b171b90628d60bd56d9fbc8aa97cc57be1600612f285a62

加入Node

1
kubeadm join api.k8s.local:6443 --token abcdef.0123456789abcdef --discovery-token-ca-cert-hash sha256:fde095725e7cc1bb903da85c14ff6558bc5fd359e93b6abc05b49ec5cc11c4bd 

添加cni插件

1
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

此时所有的节点都会变成ready状态

后记

部分QA

Q: 为什么要升级内核

A:CentOS7为例,它的内核版本为3.10,3.10版本内核的release日期是2013年,且不说k8s,Docker容器开始进入视野也是13年以后的事情,并且随着Docker逐步更新,对内核版本的依赖也逐渐加强,许多高级特性都需要较高版本的内核才能使用,如DockerLinux CGroup memory 在4.0以下版本的内核表现并不稳定

Q: 内核版本如何选择

A: 同样以CentOS为例,添加了elrepo之后 通常会给出新旧两个版本的内核可供升级,个人倾向于相对老版本的内核,稳定性更佳。如现在(2021-09-23),执行查询后可看到内核版本共两个, 相对较老的版本为5.4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
yum list available --disablerepo=* --enablerepo=elrepo-kernel
已加载插件:fastestmirror
Loading mirror speeds from cached hostfile
* elrepo-kernel: elrepo.org
可安装的软件包
kernel-lt.x86_64 5.4.147-1.el7.elrepo elrepo-kernel
kernel-lt-devel.x86_64 5.4.147-1.el7.elrepo elrepo-kernel
kernel-lt-doc.noarch 5.4.147-1.el7.elrepo elrepo-kernel
kernel-lt-headers.x86_64 5.4.147-1.el7.elrepo elrepo-kernel
kernel-lt-tools.x86_64 5.4.147-1.el7.elrepo elrepo-kernel
kernel-lt-tools-libs.x86_64 5.4.147-1.el7.elrepo elrepo-kernel
kernel-lt-tools-libs-devel.x86_64 5.4.147-1.el7.elrepo elrepo-kernel
kernel-ml-devel.x86_64 5.14.6-1.el7.elrepo elrepo-kernel
kernel-ml-doc.noarch 5.14.6-1.el7.elrepo elrepo-kernel
kernel-ml-headers.x86_64 5.14.6-1.el7.elrepo elrepo-kernel
kernel-ml-tools.x86_64 5.14.6-1.el7.elrepo elrepo-kernel
kernel-ml-tools-libs.x86_64 5.14.6-1.el7.elrepo elrepo-kernel
kernel-ml-tools-libs-devel.x86_64 5.14.6-1.el7.elrepo elrepo-kernel
perf.x86_64 5.14.6-1.el7.elrepo elrepo-kernel
python-perf.x86_64 5.14.6-1.el7.elrepo elrepo-kernel

以下为google GKE的节点内核版本

Anthos clusters on VMware 版本 Kubernetes 版本 节点内核版本
1.8.2 v1.20.9-gke.701 5.4.0.1021.22 (ubuntu)、5.4.120-r118 (cos)
1.8.1 v1.20.8-gke.1500 5.4.0-1018.19 (ubuntu)、5.4.120-r116 (cos)
1.8.0-gke.25 1.20.5-gke.1301 5.4.0.1015.16 (ubuntu)、5.4.104-r99 (cos)
1.8.0-gke.21 1.20.5-gke.1301 5.4.0.1015.16 (ubuntu)、5.4.104-r99 (cos)
1.7.3-gke.6 v1.19.12-gke.1100 5.4.0.1021.22 (ubuntu)、5.4.120-r118 (cos)
1.7.3-gke.2 1.19.12-gke.1100 5.4.0.1021.22 (ubuntu)、5.4.120-r118 (cos)
1.7.2 1.19.10 5.4.0.1015.16 (ubuntu)、5.4.104-r99 (cos)
1.7.1 1.19.7 5.4.0.1014.15 (ubuntu)、5.4.104-r97 (cos)
1.7.0 1.19.7 5.4.0.1010.11 (ubuntu)、5.4.92 (cos)
1.6.4 1.18.20 5.4.0.1021.22
1.6.3 1.18.18 5.4.0.1014.15
1.6.2 1.18.13 5.4.0.1009.10
1.6.1 1.18.13 5.4.0.1007.8
1.6.0 1.18.6 5.4.0.1004.5

k8s版本选择

参考EKS(AWS推出的kubernetes平台)每个小版本后第六个修补版本为相对稳定性强的版本

1.14.6 1.15.6

为什么采用containerd

去docker化是kubernetes发展的大势所趋,采用containerd更符合时代需要

参考链接:

木子的笔记

使用kube-vip搭建高可用kubernetes集群