使用containerd安装k8s的1.21版本

1、准备

  • 每台机器 2 GB 或更多的 RAM
  • 2 CPU 核或更多
  • 集群中的所有机器的网络彼此均能相互连接
  • 关闭selinux和firewalld
  • 关闭swap分区
  • 添加hosts解析

2、确保每个节点上 MAC 地址和 product_uuid 的唯一性

  • 使用命令 ip linkifconfig -a 来获取网络接口的 MAC 地址
  • 使用 cat /sys/class/dmi/id/product_uuid 命令对 product_uuid 校验

一般来讲,硬件设备会拥有唯一的地址,但是有些虚拟机的地址可能会重复。 Kubernetes 使用这些值来唯一确定集群中的节点。

3、允许 iptables 检查桥接流量

3.1 安装依赖包

1
yum install -y epel-release conntrack ipvsadm ipset jq sysstat curl iptables libseccomp

3.2 关闭防火墙

1
iptables -F && iptables -X && iptables -F -t nat && iptables -X -t nat && iptables -P FORWARD ACCEPT

确保 br_netfilter 模块被加载。这一操作可以通过运行 lsmod | grep br_netfilter 来完成。若要显式加载该模块,可执行 modprobe br_netfilter

为了让你的 Linux 节点上的 iptables 能够正确地查看桥接流量,你需要确保在你的 sysctl 配置中将 net.bridge.bridge-nf-call-iptables 设置为 1。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
cat <<EOF | tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF

cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward=1
net.ipv4.tcp_tw_recycle=0
vm.swappiness=0
vm.overcommit_memory=1
vm.panic_on_oom=0
fs.inotify.max_user_watches=89100
fs.file-max=52706963
fs.nr_open=52706963
net.ipv6.conf.all.disable_ipv6=1
net.netfilter.nf_conntrack_max=2310720
EOF
sysctl --system

3.3 加载内核模块

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

chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules

4、检查所需端口

4.1 控制平面节点

协议 方向 端口范围 作用 使用者
TCP 入站 6443 Kubernetes API 服务器 所有组件
TCP 入站 2379-2380 etcd 服务器客户端 API kube-apiserver, etcd
TCP 入站 10250 Kubelet API kubelet 自身、控制平面组件
TCP 入站 10251 kube-scheduler kube-scheduler 自身
TCP 入站 10252 kube-controller-manager kube-controller-manager 自身

4.2 工作节点

协议 方向 端口范围 作用 使用者
TCP 入站 10250 Kubelet API kubelet 自身、控制平面组件
TCP 入站 30000-32767 NodePort 服务† 所有组件

5、安装 runtime

为了在 Pod 中运行容器,Kubernetes 使用容器运行时Container Runtime

默认情况下,Kubernetes 使用 容器运行时接口(Container Runtime Interface,CRI) 来与你所选择的容器运行时交互。

如果你不指定运行时,则 kubeadm 会自动尝试检测到系统上已经安装的运行时, 方法是扫描一组众所周知的 Unix 域套接字。 下面的表格列举了一些容器运行时及其对应的套接字路径:

运行时 域套接字
Docker /var/run/dockershim.sock
containerd /run/containerd/containerd.sock
CRI-O /var/run/crio/crio.sock

如果同时检测到 Docker 和 containerd,则优先选择 Docker。 这是必然的,因为 Docker 18.09 附带了 containerd 并且两者都是可以检测到的, 即使你仅安装了 Docker。 如果检测到其他两个或多个运行时,kubeadm 输出错误信息并退出。

kubelet 通过内置的 dockershim CRI 实现与 Docker 集成。

5.1 使用 containerd 作为 CRI 运行时

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
cat <<EOF | tee /etc/modules-load.d/containerd.conf
overlay
br_netfilter
EOF

modprobe overlay
modprobe br_netfilter

# 设置必需的 sysctl 参数,这些参数在重新启动后仍然存在。
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

# 应用 sysctl 参数而无需重新启动
sysctl --system

5.2 安装 containerd

  1. 从官方Docker仓库安装 containerd.io 软件包

    1
    2
    3
    4
    5
    yum install -y yum-utils
    yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo
    yum install -y containerd.io
  2. 配置 containerd

    1
    2
    mkdir -p /etc/containerd
    containerd config default | tee /etc/containerd/config.toml
  3. 重新启动 containerd

    1
    2
    systemctl restart containerd
    systemctl enable containerd

    5.3 使用 systemd cgroup 驱动程序

结合 runc 使用 systemd cgroup 驱动,在 /etc/containerd/config.toml 中设置

1
2
3
4
5
sandbox_image = "registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.2" #换成阿里云
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
...
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true

再次重新启动 containerd

1
systemctl restart containerd

6、安装 kubeadm、kubelet 和 kubectl

需要在每台机器上安装以下的软件包:

  • kubeadm:用来初始化集群的指令。
  • kubelet:在集群中的每个节点上用来启动 Pod 和容器等。
  • kubectl:用来与集群通信的命令行工具。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
exclude=kubelet kubeadm kubectl
EOF

yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
systemctl enable --now kubelet

kubelet 现在每隔几秒就会重启,因为它陷入了一个等待 kubeadm 指令的死循环。

1
2
3
cat > /etc/sysconfig/kubelet <<EOF
KUBELET_EXTRA_ARGS=--cgroup-driver=systemd --container-runtime=remote --container-runtime-endpoint=/run/containerd/containerd.sock
EOF

7、初始化控制平面节点

如果计划将单个控制平面 kubeadm 集群升级成高可用, 应该指定 --control-plane-endpoint 为所有控制平面节点设置共享端点。 端点可以是负载均衡器的 DNS 名称或 IP 地址。

7.1 kubeadm init

选项

–apiserver-advertise-address string API 服务器所公布的其正在监听的 IP 地址。如果未设置,则使用默认网络接口。
–apiserver-bind-port int32 默认值:6443 API 服务器绑定的端口。
–apiserver-cert-extra-sans stringSlice 用于 API Server 服务证书的可选附加主题备用名称(SAN)。可以是 IP 地址和 DNS 名称。
–cert-dir string 默认值:”/etc/kubernetes/pki” 保存和存储证书的路径
–certificate-key string 用于加密 kubeadm-certs Secret 中的控制平面证书的密钥。
–config string kubeadm 配置文件的路径。
–control-plane-endpoint string 为控制平面指定一个稳定的 IP 地址或 DNS 名称。
–cri-socket string 要连接的 CRI 套接字的路径。如果为空,则 kubeadm 将尝试自动检测此值;仅当安装了多个 CRI 或具有非标准 CRI 插槽时,才使用此选项。
–dry-run 不要应用任何更改;只是输出将要执行的操作。
–experimental-patches string 包含名为 “target[suffix][+patchtype].extension” 的文件的目录路径。 例如,”kube-apiserver0+merge.yaml” 或仅仅是 “etcd.json”。 “patchtype” 可以是 “strategic”、”merge” 或 “json” 之一,并且它们与 kubectl 支持的补丁格式匹配。 默认的 “patchtype” 为 “strategic”。 “extension” 必须为 “json” 或 “yaml”。 “suffix” 是一个可选字符串,可用于确定首先按字母顺序应用哪些补丁。
–feature-gates string 一组用来描述各种功能特性的键值(key=value)对。选项是: IPv6DualStack=true|false (ALPHA - default=false)
-h, –help init 操作的帮助命令
–ignore-preflight-errors stringSlice 错误将显示为警告的检查列表;例如:’IsPrivilegedUser,Swap’。取值为 ‘all’ 时将忽略检查中的所有错误。
–image-repository string 默认值:”k8s.gcr.io” 选择用于拉取控制平面镜像的容器仓库
–kubernetes-version string 默认值:”stable-1” 为控制平面选择一个特定的 Kubernetes 版本。
–node-name string 指定节点的名称。
–pod-network-cidr string 指明 pod 网络可以使用的 IP 地址段。如果设置了这个参数,控制平面将会为每一个节点自动分配 CIDRs。
–service-cidr string 默认值:”10.96.0.0/12” 为服务的虚拟 IP 地址另外指定 IP 地址段
–service-dns-domain string 默认值:”cluster.local” 为服务另外指定域名,例如:”myorg.internal”。
–skip-certificate-key-print 不要打印用于加密控制平面证书的密钥。
–skip-phases stringSlice 要跳过的阶段列表
–skip-token-print 跳过打印 ‘kubeadm init’ 生成的默认引导令牌。
–token string 这个令牌用于建立控制平面节点与工作节点间的双向通信。格式为 [a-z0-9]{6}.[a-z0-9]{16} - 示例:abcdef.0123456789abcdef
–token-ttl duration 默认值:24h0m0s 令牌被自动删除之前的持续时间(例如 1 s,2 m,3 h)。如果设置为 ‘0’,则令牌将永不过期
–upload-certs 将控制平面证书上传到 kubeadm-certs Secret。

8、使用自定义的镜像

默认情况下, kubeadm 会从 k8s.gcr.io 仓库拉取镜像。如果请求的 Kubernetes 版本是 CI 标签 (例如 ci/latest),则使用 gcr.io/kubernetes-ci-images

允许的自定义功能有:

  • 使用其他的 imageRepository 来代替 k8s.gcr.io
  • useHyperKubeImage 设置为 true,使用 HyperKube 镜像。
  • 为 etcd 或 DNS 附件提供特定的 imageRepositoryimageTag

请注意配置文件中的配置项 kubernetesVersion 或者命令行参数 --kubernetes-version 会影响到镜像的版本。

以使用 kubeadm config print 命令打印默认配置, 并使用 kubeadm config migrate 命令将旧版本的配置转化成新版本。 kubeadm config images listkubeadm config images pull 命令可以用来列出并拉取 kubeadm 所需的镜像。

8.1 拉取阿里云镜像

1
kubeadm config images pull --image-repository registry.cn-hangzhou.aliyuncs.com/google_containers

8.2 初始化

1
kubeadm init   --kubernetes-version=v1.21.0   --pod-network-cidr=10.244.0.0/16   --apiserver-advertise-address=192.168.120.128   --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers

备注:如果初始化有问题,使用reset重置

image-20210507164407170

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

8.3 安装calico网络

1
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml#移除母版上的污点kubectl taint nodes --all node-role.kubernetes.io/master-

8.4 添加自动补全命令

1
2
3
4
yum install -y epel-release bash-completion
source /usr/share/bash-completion/bash_completion
source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc

根据初始化成功的提示加入从节点即可