Ubuntu22.04通过kubeadm搭建k8s高可用集群

2023-03-25 by 没有评论

初始化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.xregistry.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使用前面抄录的值