Ubuntu22.04通过kubeadm搭建k8s高可用集群
初始化hosts
如果网络包含本地dns服务可以直接配置dns,这里以修改/etc/hosts举例(需要在每台机器上配置)
192.168.0.129 master01
192.168.0.128 node01
192.168.0.127 node02
192.168.0.201 master02
192.168.0.202 node03
我们先搭建一主多从的简单结构,后续再添加第二个master节点
1. 初始化环境(所有主机)
以下操作需要在所有主机上执行,如果是虚拟机可以尝试配置好第一台后进行复制
1.1. 更新操作系统到最新状态
sudo apt update
sudo apt upgrade -y
# 修改主机名到对应名称
sudo hostnamectl set-hostname master01
sudo reboot
1.2. 禁用防火墙
sudo systemctl disable ufw
sudo apt install -y policycoreutils
sudo setenforce 0
sudo sed -i 's#=permissive#=disabled#g' /etc/selinux/config
sudo sestatus #确保状态为disabled
1.3. 禁用swap分区
sudo swapoff -a
sudo sed -ri 's/.swap./#&/' /etc/fstab
或者直接编辑/etc/fstab文件,注释掉swap这一行
1.4. 配置网络桥接协议
编辑/etc/modules-load.d/k8s.conf
overlay
br_netfilter
执行脚本
modprobe overlay
modprobe br_netfilter
设置sysctl参数,编辑/etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
应用设置
sudo sysctl --system
1.5. 开启ipvs
sudo apt install -y ipvsadm ipset
编辑ipvs配置文件/etc/modules-load.d/ipvs.conf
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack
临时加载
sudo modprobe -- ip_vs
sudo modprobe -- ip_vs_rr
sudo modprobe -- ip_vs_wrr
sudo modprobe -- ip_vs_sh
配置到系统模块中,编辑/etc/modules,末尾添加
ip_vs_sh
ip_vs_wrr
ip_vs_rr
ip_vs
nf_conntrack
重启
sudo reboot
1.6. 安装kubeadm, kubelet, kubectl
添加key
sudo curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
sudo apt update
1.6.1. 安装containerd.io
sudo apt install -y containerd.io
# 生成默认配置文件
containerd config default | sudo tee /etc/containerd/config.toml
编辑containerd配置文件/etc/containerd/config.toml
- 修改pause镜像路径(原镜像拉不下来)
替换
k8s.gcr.io/pause:x.x
为registry.aliyuncs.com/google_containers/pause:x.x
(x.x保持不变)
- 启用SystemdCgroup
修改SystemdCgroup=true
- 镜像加速
[plugins."io.containerd.grpc.v1.cri".registry.mirrors] #添加下面几行
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
endpoint = ["https://ul2pzi84.mirror.aliyuncs.com"]
# 可选,如果存在本地私有镜像需要使用http协议的,继续添加,如本例中镜像服务器如harbor地址是192.168.0.100:5000
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."192.168.0.100:5000"]
endpoint = ["http://192.168.0.100:5000"]
如果存在本地私有镜像需要使用http协议的,还需要补充配置:
[plugins."io.containerd.grpc.v1.cri".registry.configs] #添加下面两行
[plugins."io.containerd.grpc.v1.cri".registry.configs."192.168.0.100:5000".tls]
insecure_skip_verify = true
重启containerd
sudo systemctl daemon-reload
sudo systemctl restart containerd
# 查看运行状态
sudo systemctl status containerd
1.6.2. 添加阿里云镜像地址
apt-get update && apt-get install -y apt-transport-https
curl -fsSL https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.28/deb/Release.key |
gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.28/deb/ /" |
tee /etc/apt/sources.list.d/kubernetes.list
apt-get update
1.6.3. 安装kubeadm, kubectl, kubelet
sudo apt install -y kubelet kubeadm kubectl
# 阻止自动更新
sudo apt-mark hold kubelet kubeadm kubectl
2. 部署master节点
# 列出需要的镜像
sudo kubeadm config images list --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers
# 提前下载需要的镜像
sudo kubeadm config images pull --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers
# 初始化master节点
sudo kubeadm init --api-server-address=192.168.0.129 \
--image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16 \
-v=5
关于init参数:
- api-server-address 填写master主机ip
- image-repository 加速镜像地址
- service-cidr service网络,建议按原样填写,后续配置网络更方便
- pod-network-cidr pod网络,建议按原样填写,后续配置网络更方便
- v=5 日志等级,可选参数,通常用于诊断异常
如果最后有返回例如以下命令即可认为初始化完成
kubeadm join 192.168.0.129:6443 --token oo9zli.nbk9av0cx8agd8t7 \
--discovery-token-ca-cert-hash sha256:e564e8df99820d84d468024d6ca09ee9e4fc14585ce4e8597ce1db9f8d0fa0bb
2.1. 配置kubectl
mkdir -p ~/.kube
sudo cp -i /etc/kubernetes/admin.conf ~/.kube/config
sudo chown $(id -u):$(id -g) ~/.kube/config
3. 部署worker节点
首先跟随第一步初始化节点服务器
24小时内在其他节点执行master节点安装完成返回的命令即可添加worker节点,或者在master节点执行
sudo kubeadm token create --print-join-command
得到前面的join脚本,token有效期通常为24小时。也可以添加--ttl 0
生成永久token
4. 配置网络插件
此时查看k8s节点状态,执行
kubectl get nodes
# 将会得到如下返回结果
NAME STATUS ROLES AGE VERSION
master1 NotReady control-plane 15m v1.24.2
node1 NotReady <none> 14m v1.24.2
node2 NotReady <none> 5m49s v1.24.2
k8s支持flannel
, calico
, canal
等网络插件,这里以最简单的flannel举例:
wget -c https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
# 如果下载困难可以用其他工具下载此文件
kubectl apply -f kube-flannel.yml
# 最后确认所有node ready即可
kubectl get nodes
# 或者查看kube-system下所有pod都正常启动
kubectl get pods -n kube-system
5. 升级高可用集群
5.1. 配置负载均衡
查看kubeadm-config配置
kubectl -n kube-system get cm kubeadm-config -o yaml
可以得到如下返回
apiVersion: v1
data:
ClusterConfiguration: |
apiServer:
extraArgs:
authorization-mode: Node,RBAC
timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta3
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns: {}
etcd:
local:
dataDir: /var/lib/etcd
imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers
kind: ClusterConfiguration
kubernetesVersion: v1.26.3
networking:
dnsDomain: cluster.local
podSubnet: 10.244.0.0/16
serviceSubnet: 10.96.0.0/12
controlPlaneEndpoint: endpoint.k8s.svc:6443 #这一行通常没有
scheduler: {}
kind: ConfigMap
metadata:
creationTimestamp: "2023-03-23T02:24:01Z"
name: kubeadm-config
namespace: kube-system
resourceVersion: "30712"
uid: 2d150613-90cd-4369-a0e7-50aa0232461c
我们这里用一台nginx的stream代理模式创建负载均衡,在另一台主机的nginx上配置:
stream {
upstream k8s-endpoint{
server 192.168.0.129:6443;
# 后续master节点配置完成后可以往下添加
}
server {
listen 6443;
proxy_pass k8s-endpoint;
}
}
# 确认nginx代理可以访问(nginx-ip自行修改)
curl -k -v <nginx-ip>:6443
# 编辑刚刚的kubeadm-config,把nginx的ip和端口配置到controlPlaneEndpoint中
kubectl -n kube-system edit cm kubeadm-config
5.2. 准备接入证书和文件
在旧master主机上执行
sudo kubeadm init phase upload-certs --upload-certs
# 得到如下结果
[upload-certs] Storing the certificates in Secret "kubeadm-certs" in the "kube-system" Namespace
[upload-certs] Using certificate key:
a615c6fb67eff694085de21480c462de2bc65b545884957ae0d37b109000e281
# 记录这个key id
sudo kubeadm token create --print-join-command
# 记录返回的脚本
从master主机复制以下文件到新master主机相同目录(新主机按第一步完成初始化配置):
- /etc/kubernetes/pki/ca.crt
- /etc/kubernetes/pki/ca.key
- /etc/kubernetes/pki/sa.crt
- /etc/kubernetes/pki/sa.key
- /etc/kubernetes/pki/front-proxy-ca.crt
- /etc/kubernetes/pki/front-proxy-ca.key
- /etc/kubernetes/pki/etcd/ca.crt
- /etc/kubernetes/pki/etcd/ca.key
- /etc/kubernetes/admin.conf
5.3. 注册新主机
最后在新主机上执行
kubeadm join 192.168.80.10:16443 --token il1ddh.6s1rp74bb3cf18wv --discovery-token-ca-cert-hash sha256:b7c2ecb0c238eadf5c6b8657137203c11633fd4c812bcea10e1dfbc61a36861f --control-plane --certificate-key a615c6fb67eff694085de21480c462de2bc65b545884957ae0d37b109000e281
注意token和cert key使用前面抄录的值