作者:SRE运维博客
博客地址:https://www.cnsre.cn
文章地址:https://www.cnsre.cn/posts/210602036084/
相关话题:https://www.cnsre.cn/tags/kubernetes/
配置要求
至少2台 2核4G 的服务器
本文档中,CPU必须为 x86架构
CentOS 7.8 或 CentOS Stream 8
安装后的软件版本为
Kubernetes v1.21.x
calico 3.17.1
nginx-ingress 1.9.1
Containerd.io 1.4.3
操作系统兼容性
CentOS版本
本文档是否兼容
备注
CentOS Stream 8
😄
已验证
CentOS 7.8
😄
已验证
CentOS 7.7
😞
未验证
CentOS 7.6
😞
未验证
Kubernetes v1.21 开始,默认移除 docker 的依赖,如果宿主机上安装了 docker 和 containerd,将优先使用 docker 作为容器运行引擎,如果宿主机上未安装 docker 只安装了 containerd,将使用 containerd 作为容器运行引擎;
本文使用 containerd 作为容器运行引擎;
kubeadm 是 Kubernetes 官方支持的安装方式,“二进制” 不是。本文档采用 kubernetes.io 官方推荐的 kubeadm 工具安装 kubernetes 集群。
检查 centos / hostname
1
2
3
4
5
6
7
8
9
10
11
# 在 master 节点和 worker 节点都要执行
cat /etc/redhat-release
# 此处 hostname 的输出将会是该机器在 Kubernetes 集群中的节点名字
# 不能使用 localhost 作为节点的名字
hostname
# 请使用 lscpu 命令,核对 CPU 信息
# Architecture: x86_64 本安装文档不支持 arm 架构
# CPU(s): 2 CPU 内核数量不能低于 2
lscpu
修改 hostname
1
2
3
4
5
6
# 修改 hostname
hostnamectl set-hostname your-new-host-name
# 查看修改结果
hostnamectl status
# 设置 hostname 解析
echo "127.0.0.1 $( hostname) " >> /etc/hosts
检查网络
在所有节点执行命令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[ root@demo-master-a-1 ~] $ ip route show
default via 172.21.0.1 dev eth0
169.254.0.0/16 dev eth0 scope link metric 1002
172.21.0.0/20 dev eth0 proto kernel scope link src 172.21.0.12
[ root@demo-master-a-1 ~] $ ip address
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:16:3e:12:a4:1b brd ff:ff:ff:ff:ff:ff
inet 172.17.216.80/20 brd 172.17.223.255 scope global dynamic eth0
valid_lft 305741654sec preferred_lft 305741654sec
ip route show
命令中,可以知道机器的默认网卡,通常是 eth0
,如 default via 172.21.0.23 dev eth0
ip address
命令中,可显示默认网卡的 IP 地址,Kubernetes 将使用此 IP 地址与集群内的其他节点通信,如 172.17.216.80
所有节点上 Kubernetes 所使用的 IP 地址必须可以互通(无需 NAT 映射、无安全组或防火墙隔离)
安装
使用 root 身份在所有节点执行如下代码,以安装软件:
containerd
nfs-utils
kubectl / kubeadm / kubelet
快速安装
手动安装
请将脚本最后的 1.21.0 替换成您需要的版本号(必须是 1.21 的小版本,不能是 1.19.1 等) 脚本中间的 v1.21.x 不要替换
docker hub 镜像请根据自己网络的情况任选一个
第四行为腾讯云 docker hub 镜像
第六行为DaoCloud docker hub 镜像
第八行为华为云 docker hub 镜像
第十行为阿里云 docker hub 镜像
1
2
3
4
5
6
7
8
9
10
11
# 在 master 节点和 worker 节点都要执行
# 最后一个参数 1.21.0 用于指定 kubenetes 版本,支持所有 1.21.x 版本的安装
# 腾讯云 docker hub 镜像
# export REGISTRY_MIRROR="https://mirror.ccs.tencentyun.com"
# DaoCloud 镜像
# export REGISTRY_MIRROR="http://f1361db2.m.daocloud.io"
# 华为云镜像
# export REGISTRY_MIRROR="https://05f073ad3c0010ea0f4bc00b7105ec20.mirror.swr.myhuaweicloud.com"
# 阿里云 docker hub 镜像
export REGISTRY_MIRROR = https://registry.cn-hangzhou.aliyuncs.com
curl -sSL https://kuboard.cn/install-script/v1.21.x/install_kubelet.sh | sh -s 1.21.0
手动执行以下代码,结果与快速安装相同。 请将脚本第79行(已高亮)的 ${1} 替换成您需要的版本号,例如 1.21.0
docker hub 镜像请根据自己网络的情况任选一个
第四行为腾讯云 docker hub 镜像
第六行为DaoCloud docker hub 镜像
第八行为阿里云 docker hub 镜像
1
2
3
4
5
6
7
8
# 在 master 节点和 worker 节点都要执行
# 最后一个参数 1.21.0 用于指定 kubenetes 版本,支持所有 1.21.x 版本的安装
# 腾讯云 docker hub 镜像
# export REGISTRY_MIRROR="https://mirror.ccs.tencentyun.com"
# DaoCloud 镜像
# export REGISTRY_MIRROR="http://f1361db2.m.daocloud.io"
# 阿里云 docker hub 镜像
export REGISTRY_MIRROR = https://registry.cn-hangzhou.aliyuncs.com
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
94
#!/bin/bash
# 在 master 节点和 worker 节点都要执行
# 安装 containerd
# 参考文档如下
# https://kubernetes.io/docs/setup/production-environment/container-runtimes/#containerd
cat <<EOF | sudo tee /etc/modules-load.d/containerd.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
# Setup required sysctl params, these persist across reboots.
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
# Apply sysctl params without reboot
sysctl --system
# 卸载旧版本
yum remove -y containerd.io
# 设置 yum repository
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 安装 containerd
yum install -y containerd.io-1.4.3
mkdir -p /etc/containerd
containerd config default > /etc/containerd/config.toml
sed -i "s#k8s.gcr.io#registry.aliyuncs.com/k8sxio#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# ${ REGISTRY_MIRROR } #g" /etc/containerd/config.toml
systemctl daemon-reload
systemctl enable containerd
systemctl restart containerd
# 安装 nfs-utils
# 必须先安装 nfs-utils 才能挂载 nfs 网络存储
yum install -y nfs-utils
yum install -y wget
# 关闭 防火墙
systemctl stop firewalld
systemctl disable firewalld
# 关闭 SeLinux
setenforce 0
sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
# 关闭 swap
swapoff -a
yes | cp /etc/fstab /etc/fstab_bak
cat /etc/fstab_bak | grep -v swap > /etc/fstab
# 配置K8S的yum源
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 remove -y kubelet kubeadm kubectl
# 安装kubelet、kubeadm、kubectl
# 将 ${1} 替换为 kubernetes 版本号,例如 1.20.1
yum install -y kubelet-${ 1 } kubeadm-${ 1 } kubectl-${ 1 }
crictl config runtime-endpoint /run/containerd/containerd.sock
# 重启 docker,并启动 kubelet
systemctl daemon-reload
systemctl enable kubelet && systemctl start kubelet
containerd --version
kubelet --version
如果此时执行 systemctl status kubelet 命令,将得到 kubelet 启动失败的错误提示,请忽略此错误,因为必须完成后续步骤中 kubeadm init 的操作,kubelet 才能正常启动
初始化 master 节点
APISERVER_NAME 不能是 master 的 hostname
APISERVER_NAME 必须全为小写字母、数字、小数点,不能包含减号
POD_SUBNET 所使用的网段不能与 master节点/worker节点 所在的网段重叠。该字段的取值为一个 CIDR 值,如果您对 CIDR 这个概念还不熟悉,请仍然执行 export POD_SUBNET=10.100.0.1/16 命令,不做修改
快速初始化
手动初始化
请将脚本最后的 1.21.0 替换成您需要的版本号(必须是 1.21 的小版本,不能是 1.19.1 等) 脚本中间的 v1.21.x 不要替换
1
2
3
4
5
6
7
8
9
10
# 只在 master 节点执行
# 替换 x.x.x.x 为 master 节点实际 IP(请使用内网 IP)
# export 命令只在当前 shell 会话中有效,开启新的 shell 窗口后,如果要继续安装过程,请重新执行此处的 export 命令
export MASTER_IP = x.x.x.x
# 替换 apiserver.demo 为 您想要的 dnsName
export APISERVER_NAME = apiserver.demo
# Kubernetes 容器组所在的网段,该网段安装完成后,由 kubernetes 创建,事先并不存在于您的物理网络中
export POD_SUBNET = 10.100.0.1/16
echo " ${ MASTER_IP } ${ APISERVER_NAME } " >> /etc/hosts
curl -sSL https://kuboard.cn/install-script/v1.21.x/init_master.sh | sh -s 1.21.0
手动执行以下代码,结果与快速安装相同。 请将脚本第79行(已高亮)的 ${1} 替换成您需要的版本号,例如 1.21.0
1
2
3
4
5
6
7
8
9
# 只在 master 节点执行
# 替换 x.x.x.x 为 master 节点的内网IP
# export 命令只在当前 shell 会话中有效,开启新的 shell 窗口后,如果要继续安装过程,请重新执行此处的 export 命令
export MASTER_IP = x.x.x.x
# 替换 apiserver.demo 为 您想要的 dnsName
export APISERVER_NAME = apiserver.demo
# Kubernetes 容器组所在的网段,该网段安装完成后,由 kubernetes 创建,事先并不存在于您的物理网络中
export POD_SUBNET = 10.100.0.1/16
echo " ${ MASTER_IP } ${ APISERVER_NAME } " >> /etc/hosts
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
#!/bin/bash
# 只在 master 节点执行
# 脚本出错时终止执行
set -e
if [ ${# POD_SUBNET } -eq 0 ] || [ ${# APISERVER_NAME } -eq 0 ] ; then
echo -e "\033[31;1m请确保您已经设置了环境变量 POD_SUBNET 和 APISERVER_NAME \033[0m"
echo 当前POD_SUBNET = $POD_SUBNET
echo 当前APISERVER_NAME = $APISERVER_NAME
exit 1
fi
# 查看完整配置选项 https://godoc.org/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2
rm -f ./kubeadm-config.yaml
cat <<EOF > ./kubeadm-config.yaml
---
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
kubernetesVersion: v${1}
imageRepository: registry.aliyuncs.com/k8sxio
controlPlaneEndpoint: "${APISERVER_NAME}:6443"
networking:
serviceSubnet: "10.96.0.0/16"
podSubnet: "${POD_SUBNET}"
dnsDomain: "cluster.local"
dns:
type: CoreDNS
imageRepository: swr.cn-east-2.myhuaweicloud.com${2}
imageTag: 1.8.0
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: systemd
EOF
# kubeadm init
# 根据您服务器网速的情况,您需要等候 3 - 10 分钟
echo ""
echo "抓取镜像,请稍候..."
kubeadm config images pull --config= kubeadm-config.yaml
echo ""
echo "初始化 Master 节点"
kubeadm init --config= kubeadm-config.yaml --upload-certs
# 配置 kubectl
rm -rf /root/.kube/
mkdir /root/.kube/
cp -i /etc/kubernetes/admin.conf /root/.kube/config
# 安装 calico 网络插件
# 参考文档 https://docs.projectcalico.org/v3.13/getting-started/kubernetes/self-managed-onprem/onpremises
echo ""
echo "安装calico-3.17.1"
rm -f calico-3.17.1.yaml
kubectl create -f https://kuboard.cn/install-script/v1.21.x/calico-operator.yaml
wget https://kuboard.cn/install-script/v1.21.x/calico-custom-resources.yaml
sed -i "s#192.168.0.0/16# ${ POD_SUBNET } #" calico-custom-resources.yaml
kubectl create -f calico-custom-resources.yaml
检查 master 初始化结果
1
2
3
4
5
6
7
# 只在 master 节点执行
# 执行如下命令,等待 3-10 分钟,直到所有的容器组处于 Running 状态
watch kubectl get pod -n kube-system -o wide
# 查看 master 节点初始化结果
kubectl get nodes -o wide
初始化 worker节点
获得 join命令参数
在 master 节点上执行
1
2
3
4
# 只在 master 节点执行
kubeadm token create --print-join-command
# 返回如下
kubeadm join apiserver.demo:6443 --token 9ukzcs.qp4ozxbn1knc13sx --discovery-token-ca-cert-hash sha256:0cb945ea0c6329b4df58cf358e2be697fd31a85f55c23d47356f06f69a27283d
该 token 的有效时间为 2 个小时,2小时内,您可以使用此 token 初始化任意数量的 worker 节点。
初始化worker
针对所有的 worker 节点执行
1
2
3
4
5
6
7
8
9
# 只在 worker 节点执行
# 替换 x.x.x.x 为 master 节点的内网 IP
export MASTER_IP = x.x.x.x
# 替换 apiserver.demo 为初始化 master 节点时所使用的 APISERVER_NAME
export APISERVER_NAME = apiserver.demo
echo " ${ MASTER_IP } ${ APISERVER_NAME } " >> /etc/hosts
# 替换为 master 节点上 kubeadm token create 命令的输出
kubeadm join apiserver.demo:6443 --token 9ukzcs.qp4ozxbn1knc13sx --discovery-token-ca-cert-hash sha256:0cb945ea0c6329b4df58cf358e2be697fd31a85f55c23d47356f06f69a27283d
检查初始化结果
在 master 节点上执行
1
2
3
4
5
6
7
# 只在 master 节点执行
kubectl get nodes -o wide
# 输出结果如下所示
[ root@master ~] # kubectl get nodes
NAME STATUS ROLES AGE VERSION
master Ready control-plane,master 54m v1.21.0
node1 Ready <none> 35m v1.21.0
安装 Ingress Controller
快速安装
卸载IngressController
在 master 节点上执行
部分情况下,下面的这条指令,您需要执行两次才能成功。
1
2
# 只在 master 节点执行
kubectl apply -f https://kuboard.cn/install-script/v1.21.x/nginx-ingress.yaml
在 master 节点上执行
只在您想选择其他 Ingress Controller 的情况下卸载
1
2
# 只在 master 节点执行
kubectl delete -f https://kuboard.cn/install-script/v1.21.x/nginx-ingress.yaml
配置域名解析
将域名 cnsre.cn 解析到 demo-worker-a-2 的 IP 地址 z.z.z.z (也可以是 demo-worker-a-1 的地址 y.y.y.y)
验证配置
在浏览器访问 cnsre.cn ,将得到 404 NotFound 错误页面
作者:SRE运维博客
博客地址:https://www.cnsre.cn
文章地址:https://www.cnsre.cn/posts/210602036084/
相关话题:https://www.cnsre.cn/tags/kubernetes/