Ubuntu22.04使用kubeadm安装k8s 1.26版本高可用集群

Posted 上海一亩地

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Ubuntu22.04使用kubeadm安装k8s 1.26版本高可用集群相关的知识,希望对你有一定的参考价值。

目录

阿里云ACK集群的架构


ACK集群升级的时候有预检步骤,可以看出他们就是使用的kubeadm部署的高可用集群,集群的证书有效期为一年,所以如果中间不执行升级操作,则一年到期后集群不可用。
ACK的亮点就在于,相比自由化部署,ACK为k8s master集群创建了一个小型SLB实例,Backend服务器指向master的6443端口。这样的好处是即使master瘫痪,网络也是正常的,易于排查。

ACK实例的创建过程如下

创建vpc和交换机。阿里云的vswitch交换机最多支持子网掩码16,既一台虚拟交换机最多能承受65535个ip的流量。
创建k8s集群,创建过程中需要规定vswitch,两个负载均衡器(一个用于访问集群,一个用于ingress),Service的二级域名,容器运行时,集群是否需要公网ip,工作负载的子网网段等信息。
创建过程需要20分钟,创建好后即可开箱使用。

安装前的准备

kubeadm部署高可用集群官方文档:https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/high-availability/

主机规划

主机名IP地址用途算力规划
k8s-haproxy01192.168.1.11k8s集群小负载均衡器1C2GB
k8s-haproxy02192.168.1.12k8s集群小负载均衡器1C2GB
master01192.168.1.13k8s master主节点2C4GB
master02192.168.1.14k8s master主节点2C4GB
master03192.168.1.15k8s master主节点2C4GB
loadbalance01192.168.1.16应用服务大负载均衡器2C4GB
loadbalance02192.168.1.17应用服务大负载均衡器2C4GB
loadbalance03192.168.1.18应用服务大负载均衡器2C4GB
loadbalance04192.168.1.19应用服务大负载均衡器2C4GB
worker01192.168.1.20k8s工作负载节点8C32GB
worker02192.168.1.21k8s工作负载节点8C32GB
192.168.1.10VIP(小负载均衡的入口IP)

基线准备

所有Linux必须满足防火墙、ipvs、流量转发或其他安全要求才能用于k8s部署,这一类型的准备工作叫做l基线准备。
所有机器都要完成如下配置,配置完成后最好打个系统快照。

# root密码一致
sudo passwd root

# 配置静态ip,如果你的机器是cloud init出来的就不用改了
vi /etc/netplan/00-network-manager.yaml
# 修改完后,重启网络
netplan apply

# 安装vim和ssh
apt update
apt -y install vim openssh-server openssh-client git

# 允许ssh通过密码访问root
vim /etc/ssh/sshd_config
# 修改两行
PermitRootLogin yes
PasswordAuthentication yes
# 修改后重启ssh
systemctl restart ssh
systemctl enable ssh

# 同步时间
timedatectl set-timezone Asia/Shanghai
# 如果你的机器无法访问公网,则上面的命令无法使用,需要在内网中部署chronyd时间服务器。

# 关闭防火墙
ufw disable

# 关闭swap
swapoff -a
vim /etc/fstab
去掉带swap的一行

#-----------------------以下配置为k8s容器运行时对linux系统内核的要求,必须做!
# 本机网桥流量导入iptables表中过滤
cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
vm.swappiness = 0
EOF
# 配置生效
sysctl --system

# 开启 IPVS 
# 顺带启动 br_netfilter 和 overlay,这两个是官方文档要求的。
# k8s的service有两种代理模式,一种是iptables,另一种是IPVS,IPVS的性能更强。
apt -y install ipset ipvsadm
cat > /etc/modules-load.d/k8s.conf << EOF
ip_vs
ip_vs_lc
ip_vs_lblc
ip_vs_lblcr
ip_vs_rr
ip_vs_wrr
ip_vs_sh
ip_vs_dh
ip_vs_fo
ip_vs_nq
ip_vs_sed
ip_vs_ftp
ip_vs_sh
ip_tables
ip_set
ipt_set
ipt_rpfilter
ipt_REJECT
ipip
xt_set
br_netfilter
nf_conntrack
overlay
EOF
# 重启让内核配置生效
reboot

# hosts文件不用配置,不用vim /etc/hosts/
# 以后添加机器难道还要修改hosts不成?网上的各种教程都让你配hosts,用脚指头想想OK?
# 你可以部署一个内网的DNS服务器,实现FQDN服务。

如下是官方文档截图,证明我不是在瞎配。

所有k8s master、worker节点安装kubeadm+kubectl+kubelet

  1. 官方文档要求所有k8s相关节点的hostname、MAC地址和网卡product_uuid都不相同,每台节点具备唯一的MAC和uuid。
    查看主机名
hostname

查看MAC:

ip link

查看uuid

cat /sys/class/dmi/id/product_uuid
  1. 确保所有master节点的6443端口没有被占用
nc 127.0.0.1 6443
# 命令没有任何返回,表示6443端口没有被占用。
  1. 二进制包安装containerd
    从kubernetes 1.24开始,kubelet不在支持docker,所以我们需要安装containerd作为容器运行时。cri-cni包里有全部containerd集成到k8s的组件。
# 下载二进制包
wget https://github.com/containerd/containerd/releases/download/v1.6.14/cri-containerd-cni-1.6.14-linux-amd64.tar.gz

# 解压
tar -zxf cri-containerd-cni-1.6.14-linux-amd64.tar.gz
# 解压出3个目录:etc、opt、usr

# 安装
cp usr/local/bin/* /usr/local/bin/
cp etc/systemd/system/containerd.service /usr/lib/systemd/system/

# 生成配置文件
mkdir /etc/containerd
containerd config default > /etc/containerd/config.toml

# 修改配置文件
vim /etc/containerd/config.toml
-------------------------------------------
sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.6" # 61行
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]  # 153行
  [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]  # 缩进2个空格,在153行下新增
     endpoint=[
        "http://docker.mirrors.ustc.edu.cn",
        "http://hub-mirror.c.163.com"
      ]

# 重启containerd
systemctl daemon-reload
systemctl restart containerd.service
systemctl enable containerd.service

# 查看ctr和containerd的版本
ctr version
-----------------------------
ctr github.com/containerd/containerd v1.6.14
root@master01:~# ctr version
Client:
  Version:  v1.6.14
  Revision: 9ba4b250366a5ddde94bb7c9d1def331423aa323
  Go version: go1.18.9

Server:
  Version:  v1.6.14
  Revision: 9ba4b250366a5ddde94bb7c9d1def331423aa323
  UUID: 7dffa579-f530-4f67-a0c6-57135c477ed4

相关截图


  1. 单独安装runc和安全计算模式库libseccomp
wget https://github.com/opencontainers/runc/releases/download/v1.1.4/runc.amd64
cp runc.amd64 /usr/local/bin/runc
chmod +x /usr/local/bin/runc
runc -v

# 安装libseccomp
apt -y install libseccomp-dev
  1. 安装CNI网络组件
    CRI是k8s调度容器运行时的统一接口,默认已经集成到containerd1.15版本及以上中。而CNI就是CRI与Containerd之间的网络连接器。
    由于在config.toml中默认的CNI安装路径是/opt/cni/bin/,所以我们就安装在这里。
wget https://github.com/containernetworking/plugins/releases/download/v1.1.1/cni-plugins-linux-amd64-v1.1.1.tgz
mkdir -p /opt/cni/bin/
tar -zxf cni-plugins-linux-amd64-v1.1.1.tgz -C /opt/cni/bin/
  1. 一切准备就绪,可以安装kubeadm、kubectl、kubelet了。
    官方apt镜像如下

    但是很可惜,镜像地址是google.com,中国大陆有墙访问不了,所以需要使用国内阿里云镜像。虽然ubuntu22.04代号是jammy但是目前kubernetes的apt库最高是xenial,只能用它了。
# 创建apt库
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl
sudo curl -fsSLo /etc/apt/keyrings/kubernetes-archive-keyring.gpg http://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-archive-keyring.gpg] https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list

# 安装
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl

# 锁定版本,防止这些包被升级
sudo apt-mark hold kubelet kubeadm kubectl

创建集群负载均衡器HAproxy

Kubernetes官方文档中关于kubeadm创建高可用的教程中写道:首先创建一个负载均衡器,后端服务器端口6443.

安装keepalived 和haproxy

在两台haproxy主机上执行命令,安装keepalived和haproxy

apt -y install haproxy keepalived

配置haproxy

haproxy的功能是负载均衡器,通过访问haproxy的ip和暴露端口就能随机访问一个kube-apiserver,实现负载均衡。将frontend的流量随机的导入backend的负载均衡。
两台haproxy主机进行如下配置,两台主机配置相同。
vim /etc/haproxy/haproxy.cfg

global
        log /dev/log    local0
        log /dev/log    local1 notice
        chroot /var/lib/haproxy
        stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
        stats timeout 30s
        user haproxy
        group haproxy
        daemon

        # Default SSL material locations
        ca-base /etc/ssl/certs
        crt-base /etc/ssl/private

        # See: https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate
        ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
        ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
        ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets

defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        timeout connect 5000
        timeout client  50000
        timeout server  50000
        errorfile 400 /etc/haproxy/errors/400.http
        errorfile 403 /etc/haproxy/errors/403.http
        errorfile 408 /etc/haproxy/errors/408.http
        errorfile 500 /etc/haproxy/errors/500.http
        errorfile 502 /etc/haproxy/errors/502.http
        errorfile 503 /etc/haproxy/errors/503.http
        errorfile 504 /etc/haproxy/errors/504.http


frontend kube-apiserver
        mode  tcp 
        bind  *:6443
        option  tcplog
        default_backend  kube-apiserver

listen stats
        mode    http
        bind    *:8888
        stats auth    admin:password
        stats refresh    5s
        stats realm    HAproxy\\ Statistics
        stats uri   /stats
        log    127.0.0.1 local3 err

backend kube-apiserver
        mode    tcp
        balance    roundrobin
        server master01 192.168.1.13:6443 check
        server master02 192.168.1.14:6443 check
        server master03 192.168.1.15:6443 check


haproxy的配置文件中,global和defaults的是默认就有的,不用修改。所以在文件末尾添加frontend、listen stats、backend就行了。
frontend:入口,本机对外暴露的端口和允许ip。*表示任何ip都允许访问。有的k8s安装教程中将haproxy和kube-apiserver安装在同一台linux中,apiserver已经将6443端口给占用了,则frontend中bind得换一个端口,可以写 *:9443。本文的haproxy部署在独立的linux中,所以直接暴露6443就好了。
阿里云也是这么干的,对外暴露6443端口。如果你手头不是很宽裕,那就将haproxy和apiserver部署在一起吧。

backend:反向代理,连接后端服务的负载均衡。server的IP地址就是3台master节点的IP。
listen stats 监控面板的端口、用户名、密码。
配置完成后重启haproxy。

systemctl restart haproxy

浏览器登录http://<haproxy主机的ip>:8888/stats即可登录状态面板查看haproxy的状态,用户名和密码参见配置文件中 stats auth那一行。
目前尚未部署kube-apiserver,所以没有backend存活。

配置keepalived

haproxy的功能类似nginx,其实就是一个反向代理和负载均衡的功能。我们为了实现高可用,往往部署了多个haproxy,但是haproxy主机的ip各不相同,我们需要用一个虚拟ip作为访问入口,将haproxy合并起来,这就需要keepalived。
keepalived的功能就是存活检查,将VIP绑定到一个存活的haproxy上,如果当前haproxy瘫痪,自动将VIP绑定到其他haproxy上。keepalived的功能类似于网卡聚合里面的mode1 active-backup,资源利用率比较低。多个haproxy存活时也只能同时使用1个haproxy,所以是小负载均衡。
如果配置ingress的大型负载均衡,则使用nginx+LVS+keepalived模式,让多个nginx同时参与工作。
在配置keepalived前,先查看本机的主网卡设备名

我的是eth0,这个网卡名称将会写入keepalived配置文件中的,所以一定要查看。如果你是用docker容器部署keepalived,则默认网卡名称是ens33。
编写keepalived配置文件如下
vim /etc/keepalived/keepalived.conf

! Configuration File for keepalived

global_defs 
    router_id LVS_1
    script_user root
    enable_script_security


vrrp_script checkhaproxy

    script "/etc/keepalived/check-haproxy.sh"
    interval 2
    weight -5
    fall 2
    rise 1


vrrp_instance VI_1 
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1

    virtual_ipaddress 
        192.168.1.10
    

    authentication 
        auth_type PASS
        auth_pass password
    

    track_script 
        checkhaproxy
    


配置讲解:state MASTER只能有一台,其他haproxy主机一律配置成BACKUP。所以本案例中haproxy01配置成MASTER,haproxy02配置成BACKUP。interface是VIP桥接的网卡设备名称,这要与linux主网卡名保持一致。virtual_ipaddress就是VIP地址。
配置文件中有一个状态检查的shell脚本/etc/keepalived/check-haproxy.sh,需要在启动keepalived之前创建好。
vim /etc/keepalived/check-haproxy.sh

#!/bin/bash

# grep 6443这里,如果你的haproxy中的frontend中配置的是其他端口,则需要修改成对应端口
# count变量的值就是6443端口的frontend个数,如果大于0就正常退出(exit 0),否则异常退出。
count=`netstat -apn|grep 6443|wc -l`
if [ $count -gt 0 ]
then
    exit 0
else
    exit 1
fi

为shell脚本添加执行权限

chmod +x /etc/keepalived/check-haproxy.sh

重启keepalived,reboot linux,并测试VIP是否能通:

systemctl restart keepalived
systemctl enable keepalived

# 配置完linux后,最好重启以下服务器
reboot

# 启动好后,ping一下VIP。
ping 192.168.1.10
PING 192.168.1.10 (192.168.1.10) 56(84) bytes of data.
64 bytes from 192.168.1.10: icmp_seq=1 ttl=64 time=0.034 ms
64 bytes from 192.168.1.10: icmp_seq=2 ttl=64 time=0.028 ms
64 bytes from 192.168.1.10: icmp_seq=3 ttl=64 time=0.027 ms
^C
--- 192.168.1.10 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2055ms
rtt min/avg/max/mdev = 0.027/0.029/0.034/0.003 ms

# 测试 VIP到 haproxy 6443端口的连通性
nc -v 192.168.1.10 6443
Connection to 192.168.1.10 6443 port [tcp/*] succeeded!

如果ping不通,说明配置有问题,查看报错

systemctl status keepalived

到此,HAproxy小负载均衡器就实现了,以后通过VIP:6443访问K8S集群。

kubeadm部署第一台master节点

kubeadm init如果填写的是某台主机的ip地址,则创建的是单机版的k8s。如果填写的是负载均衡器的IP地址,则创建的是高可用集群。主要区别在于创建的CA证书不同。单机版的CA证书不支持高可用集群。
先尝试下载k8s的所有容器镜像,这样稍后init速度会很快。kubeadm默认从google镜像仓库下载容器镜像,又会被墙,所以指定从阿里云下载容器镜像。
每台master和worker节点执行下面这个命令:

kubeadm config images pull \\
    --image-repository registry.aliyuncs.com/google_containers \\
    --cri-socket=unix:///var/run/containerd/containerd.sock
# docker的cri接口地址是unix:///var/run/cri-dockerd.sock

在master01上执行如下命令,创建第一台control plane。由于从kubernetes 1.24开始,kubelet不在支持docker,所以我们选择containerd作为容器运行时。kubelet的这次升级将直接连接containerd,移除了shim和dockerd相关代码,没有中间商赚差价。

先在master01上执行如下命令,创建k8s集群版,然后其他master服务器加入这个集群

# 命令格式 kubeadm init --control-plane-endpoint "LOAD_BALANCER_DNS:LOAD_BALANCER_PORT" --upload-certs
kubeadm init \\
    --control-plane-endpoint "192.168.1.10:6443" \\
    --image-repository registry.aliyuncs.com/google_containers \\
    --upload-certs --cri-socket=unix:///var/run/containerd/containerd.sock

创建不要1分钟,且成功:

Your Kubernetes control-plane has initialized successfully!

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/

You can now join any number of the control-plane node running the following command on each as root:

  kubeadm join 192.168.1.10:6443 --token 5utynu.c7fim1jqkawqg7pk \\
	--discovery-token-ca-cert-hash sha256:9a5569b481e0574ef45620449c5b69f8632183274a4e59b7ef246a64db151fcf \\
	--control-plane --certificate-key a99e6c08b1a18f2f636d8e7d0a793ecda35b74ff5b3ab91e63a3f9221749853e

Please note that the certificate-key gives access to cluster sensitive data, keep it secret!
As a safeguard, uploaded-certs will be deleted in two hours; If necessary, you can use
"kubeadm init phase upload-certs --upload-certs" to reload certs afterward.

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

kubeadm join 192.168.1.10:6443 --token 5utynu.c7fim1jqkawqg7pk \\
	--discovery-token-ca-cert-hash sha256:9a5569b481e0574ef45620449c5b69f8632183274a4e59b7ef246a64db151fcf

其中master节点加入集群的命令

kubeadm join 192.168.1.10:6443 --token 5utynu.c7fim1jqkawqg7pk --discovery-token-ca-cert-hash sha256:9a5569b481e0574ef45620449c5b69f8632183274a4e59b7ef246a64db151fcf --control-plane --certificate-key a99e6c08b1a18f2f636d8e7d0a793ecda35b74ff5b3ab91e63a3f9221749853e

worker节点加入集群的命令

kubeadm join 192.168.1.10:6443 --token 5utynu.c7fim1jqkawqg7pk -discovery-token-ca-cert-hash sha256:9a5569b481e0574ef45620449c5b69f8632183274a4e59b7ef246a64db151fcf

Calico网络组件一键安装

此时通过 kubectl get nodes 能发现,所有的worker都是not ready状态,原因是网络组件没有安装,集群没有Service功能。
通过calico的官方yaml文件能一次安装所有calico组件,包括daemon set、deployment、service 、rbac认证等等,难度高,但是都是全自动化的。

kubectl apply -f "https://docs.projectcalico.org/manifests/calico.yaml"

安装完成

此时集群全部完成,可以正常使用,如果担心证书,可以研究一下kubeadm更新集群CA证书的方法。你也可以安装一个Dashboard。

以上是关于Ubuntu22.04使用kubeadm安装k8s 1.26版本高可用集群的主要内容,如果未能解决你的问题,请参考以下文章

ubuntu22.04x64 安装k8s1.23.x

使用Ubuntu22.04搭建k8s环境和一些k8s基础知识

Ubuntu通过kubeadm快速搭建k8s集群

Ubuntu server22.04 ,kubernetes(k8s)1.24.0,congtainerd 1.6.4安装笔记

使用Kubeadm部署k8s

kubernetes— 记一次用kubeadm搭建kubernetes v1.9.0集群