使用 kubeadm 1.24.3 搭建 k8s 集群

# 环境准备

Centos8 三台.

1
2
3
k8s-master-01 192.168.0.10
k8s-node-01 192.168.0.20
k8s-node-02 192.168.0.21

注意,这三台机器不要做任何配置,尤其不要安装 docker , 因为从 k8s 1.20.x 开始, kubernetes 弃用了 dockershim , 在 1.20.4 正式移除了 dockershim .

Docker support in the kubelet is now deprecated and will be removed in a future release. The kubelet uses a module called “dockershim” which implements CRI support for Docker and it has seen maintenance issues in the Kubernetes community.

原文地址: kubernetes 1.20 变更日志

但是 kubernetes 是支持符合为 Kubernetes 创建的容器运行接口 Container Runtime Interface (CRI) 的运行时。 Docker 构建的镜像,将在你的集群的所有运行时中继续工作,一如既往。

# 设置系统主机名以及 host 文件的相互解析

1
hostnamectl set-hostname k8s-master-01

# 安装依赖包

1
2
3
yum install -y conntrack ipvsadm ipset jq iptables curl sysstat libseccomp wget vim net-tools git

yum install -y chrony # 配置时间同步

# 关闭防火墙

1
systemctl stop firewalld && systemctl disable firewalld

# 关闭 SELinux

1
2
swapoff -a && sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
setenforce 0 && sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config

# 调整内核参数

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
cat > kubernetes.conf <<EOF
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
net.ipv4.ip_forward=1
net.ipv4.tcp_tw_recycle=0
vm.swappiness=0 # 禁止使用 swap 空间,只有当系统 OOM 时才允许使用它
vm.overcommit
_
memory=1 # 不检查物理内存是否够用
vm.panic_on_oom=0 # 开启 OOM
fs.inotify.max_user_instances=8192
fs.inotify.max_user_watches=1048576
fs.file-max=52706963
fs.nr
_
open=52706963
net.ipv6.conf.all.disable_ipv6=1
net.netfilter.nf
_
conntrack
_
max=2310720
EOF
cp kubernetes.conf /etc/sysctl.d/kubernetes.conf
sysctl -p /etc/sysctl.d/kubernetes.conf

# 调整系统时区

1
2
3
4
5
6
7
# 设置系统时区为 中国/上海
timedatectl set-timezone Asia/Shanghai
# 将当前的 UTC 时间写入硬件时钟
timedatectl set-local-rtc 0
# 重启依赖于系统时间的服务
systemctl restart rsyslog
systemctl restart crond

# 关闭系统不需要服务

1
systemctl stop postfix && systemctl disable postfix

# 设置 rsyslogd 和 systemd journald

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
mkdir /var/log/journal # 持久化保存日志的目录
mkdir /etc/systemd/journald.conf.d
cat > /etc/systemd/journald.conf.d/99-prophet.conf <<EOF
[Journal]
# 持久化保存到磁盘
Storage=persistent
# 压缩历史日志
Compress=yes
SyncIntervalSec=5m
RateLimitInterval=30s
RateLimitBurst=1000
# 最大占用空间 10G
SystemMaxUse=10G
# 单日志文件最大 200M
SystemMaxFileSize=200M
# 日志保存时间 2 周
MaxRetentionSec=2week
# 不将日志转发到 syslog
ForwardToSyslog=no
EOF
systemctl restart systemd-journald

# 安装 containerd

# 创建 /etc/modules-load.d/containerd.conf 配置文件:

1
2
3
4
cat << EOF > /etc/modules-load.d/containerd.conf
overlay
br_netfilter
EOF

执行下面的命令,使其生效

1
2
modprobe overlay
modprobe br_netfilter

创建 /etc/sysctl.d/99-kubernetes-cri.conf 配置文件:

1
2
3
4
5
6
cat << EOF > /etc/sysctl.d/99-kubernetes-cri.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
user.max_user_namespaces=28633
EOF

执行以下命令使配置生效:

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

# 关闭 swap

Kubernetes 1.8 开始要求关闭系统的 Swap,如果不关闭,默认配置下 kubelet 将无法启动。 关闭系统的 Swap 方法如下:

1
swapoff -a

修改 /etc/fstab 文件,注释掉 SWAP 的自动挂载,使用 free -m 确认 swap 已经关闭。

swappiness 参数调整,修改 /etc/sysctl.d/99-kubernetes-cri.conf 添加下面一行:

1
vm.swappiness=0

执行 sysctl -p /etc/sysctl.d/99-kubernetes-cri.conf 使修改生效。

# 安装 containerd

在各个服务器节点上安装容器运行时 Containerd

下载 Containerd 的二进制包:

1
2
3
wget https://github.com/containerd/containerd/releases/download/v1.6.4/cri-containerd-cni-1.6.4-linux-amd64.tar.gz

tar -zxvf cri-containerd-cni-1.6.4-linux-amd64.tar.gz -C /

生成 containerd 的配置文件

1
2
mkdir -p /etc/containerd
containerd config default > /etc/containerd/config.toml

修改前面生成的配置文件 /etc/containerd/config.toml

1
2
3
4
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
...
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true

再修改 /etc/containerd/config.toml 中的

1
2
3
4
[plugins."io.containerd.grpc.v1.cri"]
...
# sandbox_image = "k8s.gcr.io/pause:3.6"
sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.7"

配置 containerd 开机启动,并启动 containerd

1
systemctl enable containerd --now

使用 crictl 测试一下,确保可以打印出版本信息并且没有错误信息输出:

1
crictl version

如下输出:

1
2
3
4
Version:  0.1.0
RuntimeName: containerd
RuntimeVersion: v1.6.4
RuntimeApiVersion: v1alpha2

# 配置服务器支持开启 ipvs

执行下面的脚本

1
2
3
4
5
6
7
8
9
10
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
EOF

chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack

上面脚本创建了的 /etc/sysconfig/modules/ipvs.modules 文件,保证在节点重启后能自动加载所需模块。 使用 lsmod | grep -e ip_vs -e nf_conntrack 命令查看是否已经正确加载所需的内核模块。

接下来,就可以使用 kubeadm 部署 k8s 集群了。

# 安装 k8s 集群

安装 k8s 集群有很多种方式,这里使用 kubeadm 安装

# 安装 kubeadm

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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 makecache

sudo yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes

systemctl enable --now kubelet

# 配置 kubeadm 配置文件

配置 kubeadm 的配置文件. touch kubeadm-config.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
apiVersion: kubeadm.k8s.io/v1beta3
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: 192.168.96.151
bindPort: 6443
nodeRegistration:
criSocket: unix:///run/containerd/containerd.sock
taints:
- effect: PreferNoSchedule
key: node-role.kubernetes.io/master
---
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
kubernetesVersion: v1.24.0
imageRepository: registry.aliyuncs.com/google_containers
networking:
podSubnet: 10.244.0.0/16
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: systemd
failSwapOn: false
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: ipvs

这里定制了 imageRepository 为阿里云的 registry ,避免因 gcr 被墙,无法直接拉取镜像。 criSocket 设置了容器运行时为 containerd 。 同时设置 kubeletcgroupDriversystemd ,设置 kube-proxy 代理模式为 ipvs

可以通过 kubeadm config print init-defaults --component-configs KubeletConfiguration 可以打印集群初始化默认的使用的配置.

在开始初始化集群之前可以使用 kubeadm config images pull --config kubeadm-config.yaml 预先在各个服务器节点上拉取所 k8s 需要的容器镜像。

# 初始化 k8s master 节点

master 节点上执行 kubeadm init --config kubeadm-config.yaml ,

看到最后有打印: Your Kubernetes control-plane has initialized successfully!

就说明执行成功了。

然后还有提示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
To start using your cluster, you need to run the following as a regular user:

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

Alternatively, if you are the root user, you can run:

export KUBECONFIG=/etc/kubernetes/admin.conf

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 192.168.0.10:6443 --token e0nvot.l8sgzcgl07d5baq6 \
--discovery-token-ca-cert-hash sha256:d07d9a5b919c23177881134e3ccf90e26fcb173133b8f6172cbf3d74f3c6a75d

所以,我们按照提示执行。

1
2
3
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

然后再 两台 node 节点上执行 如下命令来加入到集群中。

1
2
kubeadm join 192.168.0.10:6443 --token e0nvot.l8sgzcgl07d5baq6 \
--discovery-token-ca-cert-hash sha256:d07d9a5b919c23177881134e3ccf90e26fcb173133b8f6172cbf3d74f3c6a75d

查看一下集群状态,确认个组件都处于 healthy 状态,是否有错误:

1
2
3
4
5
6
kubectl get cs
Warning: v1 ComponentStatus is deprecated in v1.19+
NAME STATUS MESSAGE ERROR
scheduler Healthy ok
controller-manager Healthy ok
etcd-0 Healthy {"health":"true","reason":""}

集群初始化如果遇到问题,可以使用 kubeadm reset 命令进行清理.

这样 k8s 集群就部署完成了。

# 最后

希望和你一起遇见更好的自己

qrcode

更新于 阅读次数

请我喝[咖啡]~( ̄▽ ̄)~*

方小白 微信支付

微信支付

方小白 支付宝

支付宝

方小白 numberpay

numberpay