文章目录

对于kubelet和containerd重要提示
在升级至1.24之前,请确认containerd版本

  1. 以下容器运行时已经或即将全面兼容Kubernetes 1.24:

  2. containerd v1.6.4及更高,v1.5.11及更高
  3. CRI-O 1.24及更高

若CNI插件尚未升级且/或CNI配置文件中未声明CNI配置版本时,则containerd v1.6.0-v1.6.3版本将导致Pod CNI网络setup及tear down发生问题。containerd团队报告称,这些问题已经在containerd v1.6.4中得到解决。
在containerd v1.6.0-v1.6.3时,如果你未升级CNI插件且/或声明CNI配置版本,则可能遇到CNI版本不兼容或无法为沙箱删除网络等错误。

Kubernetes 1.24新特性

  • 各beta API默认关闭
    在默认情况下,新的各beta API不会在集群内得到启用。但全部原有beta API及其新版本将在1.24中继续默认启用
  • OpenAPI v3
    Kubernetes 1.24开始为API的OpenAPI v3发布格式提供beta支持。
  • 存储容量与存储卷扩展双双迎来通用版本
    存储容量跟踪通过CSIStorageCapacity对象公开当前可用的存储容量,并对使用后续绑定的CSI存储卷的pod进行调度增强。
    存储卷扩展则新增对现有持久卷的重新调整功能。
  • NonPreemptingPriority迎来稳定版
    此功能为PriorityClasses添加了新的选项,可开启或关闭Pod抢占机制
  • 存储插件迁移
    目前Kubernetes开发团队正在迁移树内存储插件,希望在实现CSI插件的同时、保持原有API的正常起效。Azure Disk与OpenStack Cinder等插件已经完成了迁移。
  • gRPC探针升级至beta版
    在1.24版本中,gRPC探针功能已经进入beta阶段且默认启用。现在,大家可以在Kubernetes中为自己的gRPC应用程序原生配置启动、活动与就绪探测,而且无需公开HTTP商战或者使用额外的可执行文件。
  • Kubelet证书提供程序升级至beta版
    最初在Kubernetes 1.20版本中以alpha版亮相的kubelet镜像证书提供程序现已升级至beta版。现在,kubelet将使用exec插件动态检索容器镜像注册表的凭证,而不再将凭证存储在节点文件系统之上。
  • 避免为服务分配IP时发生冲突
    Kubernetes 1.24引入了一项新的选择性功能,允许用户为服务的静态IP分配地址保留一个软范围。通过手动启用此项功能,集群将从您指定的服务IP池中自动获取地址,从而降低冲突风险。

也就是说,服务的ClusterIP能够以下列方式分配:
动态分配,即集群将在配置的服务IP范围内自动选择一个空闲IP。
静态分配,意味着用户需要在已配置的服务IP范围内指定一个IP。
服务ClusterIP是唯一的;因此若尝试使用已被分配的ClusterIP进行服务创建,则会返回错误结果。

环境准备

我本地有kubernetes 1.18环境,接下来对环境进行初始化

  1. 目前kubernetes版本

  2. [root@k8s-01~]# kubectl get node
  3. NAME STATUS ROLES AGE VERSION
  4. k8s-01Ready master 243d v1.18.3
  5. k8s-02Ready master 243d v1.18.3
  6. k8s-03Ready master 243d v1.18.3
  7. k8s-04Ready243d v1.18.3
  8. k8s-05Ready243d v1.18.3

卸载集群命令

  1. 建议所有服务器都执行

  2. !/bin/bash

  3. kubeadm reset -f
  4. modprobe -r ipip
  5. lsmod
  6. rm -rf ~/.kube/
  7. rm -rf /etc/kubernetes/
  8. rm -rf /etc/systemd/system/kubelet.service.d
  9. rm -rf /etc/systemd/system/kubelet.service
  10. rm -rf /usr/bin/kube*
  11. rm -rf /etc/cni
  12. rm -rf /opt/cni
  13. rm -rf /var/lib/etcd
  14. rm -rf /var/etcd
  15. yum -y remove kubeadm kubectl kubelet docker
  16. reboot

    基础环境配置

    | IP地址 | 主机名 | 服务 | 配置 | | —- | —- | —- | —- | | 192.168.31.10 | k8s-01 | k8s-master、containerd、keepalived、nginx | 2c8g | | 192.168.31.11 | k8s-02 | k8s-master、containerd、keepalived、nginx | 2c8g | | 192.168.31.12 | k8s-03 | k8s-master、containerd、keepalived、nginx | 2c8g | | 192.168.31.13 | k8s-04 | k8s-node、containerd | 1c4g | | 192.168.31.14 | k8s-05 | k8s-node、containerd | 1c4g |

VIP: 192.168.31.111 域名:apiserver.frps.cn

  • apiserver.frps.cn:6443 为VIP
  • kube-apiserver 三台节点
  • kube-schedulet 三台节点
  • kube-controller-manager 三台节点
  • ETCD 三台节点

服务版本

服务名称 版本号
内核 5.14.3-1.el7.elrepo.x86_64
containerd v1.6.4
ctr v1.6.4
k8s 1.24

初始化环境
初始化环境需要全部节点都执行
批量修改主机名,以及免密

  1. hostnamectl set-hostname k8s01 #所有机器按照要求修改
  2. bash #刷新主机名
  3. 配置host

  4. cat >>/etc/hosts <<EOF
  5. 192.168.31.100 k8s-01
  6. 192.168.31.101 k8s-02
  7. 192.168.31.102 k8s-03
  8. 192.168.31.103 k8s-04
  9. 192.168.31.104 k8s-05
  10. EOF
  11. 设置k8s-01为分发机 (只需要在k8s-01服务器操作即可)

  12. wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
  13. curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
  14. yum install -y expect
  15. 分发公钥

  16. ssh-keygen -t rsa -P “”-f /root/.ssh/id_rsa
  17. for i in k8s-01 k8s-02 k8s-03 k8s-04 k8s-05;do
  18. expect -c “
  19. spawn ssh-copy-id -i /root/.ssh/id_rsa.pub root@$i
  20. expect {
  21. yes/no“ {send “yesr”; exp_continue}
  22. password“ {send “123456r”; exp_continue}
  23. Password“ {send “123456r”;}
  24. } “
  25. done

我这里密码为123456,请根据需求自行更改
所有节点关闭Selinux、iptables、swap分区

  1. systemctl stop firewalld
  2. systemctl disable firewalld
  3. iptables -F && iptables -X && iptables -F -t nat && iptables -X -t nat
  4. iptables -P FORWARD ACCEPT
  5. swapoff -a
  6. sed -i ‘/ swap / s/^(.*)$/#1/g’/etc/fstab
  7. setenforce 0
  8. sed -i ‘s/^SELINUX=.*/SELINUX=disabled/‘/etc/selinux/config

所有节点配置yum源

  1. curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
  2. wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
  3. yum clean all
  4. yum makecache

新安装的服务器可以安装下面的软件包,可以解决99%的依赖问题

  1. yum -y install gcc gcc-c++ make autoconf libtool-ltdl-devel gd-devel freetype-devel libxml2-devel libjpeg-devel libpng-devel openssh-clients openssl-devel curl-devel bison patch libmcrypt-devel libmhash-devel ncurses-devel binutils compat-libstdc++-33 elfutils-libelf elfutils-libelf-devel glibc glibc-common glibc-devel libgcj libtiff pam-devel libicu libicu-devel gettext-devel libaio-devel libaio libgcc libstdc++ libstdc++-devel unixODBC unixODBC-devel numactl-devel glibc-headers sudo bzip2 mlocate flex lrzsz sysstat lsof setuptool system-config-network-tui system-config-firewall-tui ntsysv ntp pv lz4 dos2unix unix2dos rsync dstat iotop innotop mytop telnet iftop expect cmake nc gnuplot screen xorg-x11-utils xorg-x11-xinit rdate bc expat-devel compat-expat1 tcpdump sysstat man nmap curl lrzsz elinks finger bind-utils traceroute mtr ntpdate zip unzip vim wget net-tools

由于开启内核 ipv4 转发需要加载 br_netfilter 模块,所以加载下该模块:

  1. modprobe br_netfilter
  2. modprobe ip_conntrack
  3. 每台节点

将上面的命令设置成开机启动,因为重启后模块失效,下面是开机自动加载模块的方式。首先新建 /etc/rc.sysinit 文件,内容如下所示:

  1. cat >>/etc/rc.sysinit<<EOF
  2. !/bin/bash

  3. for file in/etc/sysconfig/modules/*.modules ; do
  4. [ -x $file ] && $file
  5. done
  6. EOF

然后在/etc/sysconfig/modules/目录下新建如下文件:

  1. echo “modprobe br_netfilter”>/etc/sysconfig/modules/br_netfilter.modules
  2. echo “modprobe ip_conntrack”>/etc/sysconfig/modules/ip_conntrack.modules

增加权限
chmod 755 /etc/sysconfig/modules/br_netfilter.modules
chmod 755 /etc/sysconfig/modules/ip_conntrack.modules
然后重启后,模块就可以自动加载了
优化内核参数

  1. cat > kubernetes.conf <<EOF
  2. net.bridge.bridge-nf-call-iptables=1
  3. net.bridge.bridge-nf-call-ip6tables=1
  4. net.ipv4.ip_forward=1
  5. vm.swappiness=0# 禁止使用 swap 空间,只有当系统 OOM 时才允许使用它
  6. vm.overcommit_memory=1# 不检查物理内存是否够用
  7. vm.panic_on_oom=0# 开启 OOM
  8. fs.inotify.max_user_instances=8192
  9. fs.inotify.max_user_watches=1048576
  10. fs.file-max=52706963
  11. fs.nr_open=52706963
  12. net.ipv6.conf.all.disable_ipv6=1
  13. net.netfilter.nf_conntrack_max=2310720
  14. EOF
  15. cp kubernetes.conf /etc/sysctl.d/kubernetes.conf
  16. sysctl -p /etc/sysctl.d/kubernetes.conf
  17. 分发到所有节点

  18. for i in k8s-02 k8s-03 k8s-04 k8s-05
  19. do
  20. scp kubernetes.conf root@$i:/etc/sysctl.d/
  21. ssh root@$i sysctl -p /etc/sysctl.d/kubernetes.conf
  22. ssh root@$i echo ‘1’>>/proc/sys/net/ipv4/ip_forward
  23. done
  24. for后面节点根据需求修改

bridge-nf 使得netfilter可以对Linux网桥上的 IPv4/ARP/IPv6 包过滤。比如,设置net.bridge.bridge-nf-call-iptables=1后,二层的网桥在转发包时也会被 iptables的 FORWARD 规则所过滤。常用的选项包括:
net.bridge.bridge-nf-call-arptables:是否在 arptables 的 FORWARD 中过滤网桥的 ARP 包
net.bridge.bridge-nf-call-ip6tables:是否在 ip6tables 链中过滤 IPv6 包
net.bridge.bridge-nf-call-iptables:是否在 iptables 链中过滤 IPv4 包
net.bridge.bridge-nf-filter-vlan-tagged:是否在 iptables/arptables 中过滤打了 vlan 标签的包。
所有节点安装ipvs

  1. 为什么要使用IPVS,从k8s的1.8版本开始,kube-proxy引入了IPVS模式,IPVS模式与iptables同样基于Netfilter,但是采用的hash表,因此当service数量达到一定规模时,hash查表的速度优势就会显现出来,从而提高service的服务性能。
  2. ipvs依赖于nf_conntrack_ipv4内核模块,4.19包括之后内核里改名为nf_conntrack,1.13.1之前的kube-proxy的代码里没有加判断一直用的nf_conntrack_ipv4,好像是1.13.1后的kube-proxy代码里增加了判断,我测试了是会去load nf_conntrack使用ipvs正常
  3. cat >/etc/sysconfig/modules/ipvs.modules <<EOF
  4. !/bin/bash

  5. modprobe — ip_vs
  6. modprobe — ip_vs_rr
  7. modprobe — ip_vs_wrr
  8. modprobe — ip_vs_sh
  9. modprobe — nf_conntrack
  10. EOF
  11. chmod 755/etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack
  12. 查看是否已经正确加载所需的内核模块

所有节点安装ipset
yum install ipset -y
ipset介绍

  1. iptables是Linux服务器上进行网络隔离的核心技术,内核在处理网络请求时会对iptables中的策略进行逐条解析,因此当策略较多时效率较低;而是用IPSet技术可以将策略中的五元组(协议,源地址,源端口,目的地址,目的端口)合并到有限的集合中,可以大大减少iptables策略条目从而提高效率。测试结果显示IPSet方式效率将比iptables提高100倍

为了方面ipvs管理,这里安装一下ipvsadm。
yum install ipvsadm -y
所有节点设置系统时区

  1. timedatectl set-timezone Asia/Shanghai
  2. 将当前的 UTC 时间写入硬件时钟

  3. timedatectl set-local-rtc 0
  4. 重启依赖于系统时间的服务

  5. systemctl restart rsyslog
  6. systemctl restart crond

升级内核 (可选方案)

  1. rpm —import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
  2. rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm
  3. 默认安装为最新内核

  4. yum —enablerepo=elrepo-kernel install kernel-ml
  5. 修改内核顺序

  6. grub2-set-default0&& grub2-mkconfig -o /etc/grub2.cfg
  7. 使用下面命令看看确认下是否启动默认内核指向上面安装的内核

  8. grubby —default-kernel
  9. 这里的输出结果应该为我们升级后的内核信息

  10. reboot
  11. 可以等所有初始化步骤结束进行reboot操作

接下来更新一下软件包版本
yum update -y

Containerd 安装

Kubeadm搭建高可用(k8s)Kubernetes v1.24.0集群 - 图1

Kubernetes容器运行时弃用Docker转型Containerd

在安装containerd前,我们需要优先升级libseccomp
在centos7中yum下载libseccomp的版本是2.3的,版本不满足我们最新containerd的需求,需要下载2.4以上的
Containerd需要在所有节点升级安装

  1. 卸载原来的

  2. [i4t@web01 ~]# rpm -qa | grep libseccomp
  3. libseccomp-devel-2.3.1-4.el7.x86_64
  4. libseccomp-2.3.1-4.el7.x86_64
  5. [i4t@web01 ~]# rpm -e libseccomp-devel-2.3.1-4.el7.x86_64 —nodeps
  6. [i4t@web01 ~]# rpm -e libseccomp-2.3.1-4.el7.x86_64 —nodeps
  7. 下载高于2.4以上的包

  8. [i4t@web01 ~]# wget http://rpmfind.net/linux/centos/8-stream/BaseOS/x86_64/os/Packages/libseccomp-2.5.1-1.el8.x86_64.rpm
  9. 安装

  10. [i4t@web01 ~]# rpm -ivh libseccomp-2.5.1-1.el8.x86_64.rpm
  11. warning: libseccomp-2.5.1-1.el8.x86_64.rpm:Header V3 RSA/SHA256 Signature, key ID 8483c65d: NOKEY
  12. Preparing…################################# [100%]
  13. Updating/ installing…
  14. 1:libseccomp-2.5.1-1.el8################################# [100%]
  15. 查看当前版本

  16. [root@web01 ~]# rpm -qa | grep libseccomp
  17. libseccomp-2.5.1-1.el8.x86_64

下载安装containerd
github地址:https://containerd.io/downloads/
Containerd安装我们使用1.6.1版本号
containerd-1.6.1-linux-amd64.tar.gz 只包含containerd
cri-containerd-cni-1.6.4-linux-amd64.tar.gz 包含containerd以及cri runc等相关工具包,建议下载本包

  1. 下载tar.gz包

  2. containerd工具包,包含cri runc等

  3. wget https://github.com/containerd/containerd/releases/download/v1.6.4/cri-containerd-cni-1.6.4-linux-amd64.tar.gz
  4. 备用下载地址

  5. wget https://d.frps.cn/file/kubernetes/containerd/cri-containerd-cni-1.6.4-linux-amd64.tar.gz

工具包文件如下

  1. cri-containerd-cni会将我们整个containerd相关的依赖都进行下载下来

  2. [root@k8s-01 containerd]# tar zxvf cri-containerd-cni-1.6.4-linux-amd64.tar.gz -C /#我们直接让它给我们对应的目录给替换掉
  3. etc/
  4. etc/systemd/
  5. etc/systemd/system/
  6. etc/systemd/system/containerd.service
  7. etc/crictl.yaml
  8. etc/cni/
  9. etc/cni/net.d/
  10. etc/cni/net.d/10-containerd-net.conflist
  11. usr/
  12. usr/local/
  13. usr/local/sbin/
  14. usr/local/sbin/runc
  15. usr/local/bin/
  16. usr/local/bin/crictl
  17. usr/local/bin/ctd-decoder
  18. usr/local/bin/ctr
  19. usr/local/bin/containerd-shim
  20. usr/local/bin/containerd
  21. usr/local/bin/containerd-shim-runc-v1
  22. usr/local/bin/critest
  23. usr/local/bin/containerd-shim-runc-v2
  24. usr/local/bin/containerd-stress
  25. opt/
  26. opt/containerd/
  27. opt/containerd/cluster/
  28. opt/containerd/cluster/version
  29. opt/containerd/cluster/gce/
  30. opt/containerd/cluster/gce/cni.template
  31. opt/containerd/cluster/gce/env
  32. opt/containerd/cluster/gce/configure.sh
  33. opt/containerd/cluster/gce/cloud-init/
  34. opt/containerd/cluster/gce/cloud-init/node.yaml
  35. opt/containerd/cluster/gce/cloud-init/master.yaml
  36. opt/cni/
  37. opt/cni/bin/
  38. opt/cni/bin/firewall
  39. opt/cni/bin/portmap
  40. opt/cni/bin/host-local
  41. opt/cni/bin/ipvlan
  42. opt/cni/bin/host-device
  43. opt/cni/bin/sbr
  44. opt/cni/bin/vrf
  45. opt/cni/bin/static
  46. opt/cni/bin/tuning
  47. opt/cni/bin/bridge
  48. opt/cni/bin/macvlan
  49. opt/cni/bin/bandwidth
  50. opt/cni/bin/vlan
  51. opt/cni/bin/dhcp
  52. opt/cni/bin/loopback
  53. opt/cni/bin/ptp

上面的文件都是二进制文件,直接移动到对应的目录并配置好环境变量就可以进行使用了。
如果我们机器上通过yum安装docker了,可以用下面的命令进行卸载

  1. sudo yum remove docker
  2. docker-client
  3. docker-client-latest
  4. docker-common
  5. docker-latest
  6. docker-latest-logrotate
  7. docker-logrotate
  8. docker-engine

接下来我们为每台服务器配置Containerd

  1. 创建配置文件目录

  2. [root@k8s-01~]# mkdir /etc/containerd -p
  3. 生成默认配置文件

  4. [root@k8s-01~]# containerd config default>/etc/containerd/config.toml
  5. —config,-c可以在启动守护程序时更改此路径

  6. 配置文件的默认路径位于/etc/containerd/config.toml

替换默认pause镜像地址
默认情况下k8s.gcr.io无法访问,所以使用我提供的阿里云镜像仓库地址即可

  1. sed -i ‘s/k8s.gcr.io/registry.cn-beijing.aliyuncs.com/abcdocker/‘/etc/containerd/config.toml
  2. 所有节点更换默认镜像地址

  3. 我这里使用阿里云地址

配置systemd作为容器的cgroup driver
sed -i ‘s/SystemdCgroup = false/SystemdCgroup = true/‘ /etc/containerd/config.toml
Containerd官方操作手册
默认cri-containerd-cni包中会有containerd启动脚本,我们已经解压到对应的目录,可以直接调用启动

  1. [root@k8s-01~]# systemctl enable containerd —now
  2. Created symlink from/etc/systemd/system/multi-user.target.wants/containerd.service to /etc/systemd/system/containerd.service.
  3. [root@k8s-01~]# systemctl status containerd #查看containerd启动状态
  4. ● containerd.service - containerd container runtime
  5. Loaded: loaded (/etc/systemd/system/containerd.service; enabled; vendor preset: disabled)
  6. Active: active (running) since Thu2022-05-1222:59:19 EDT;3s ago
  7. Docs: https://containerd.io
  8. Process:30048ExecStartPre=/sbin/modprobe overlay (code=exited, status=0/SUCCESS)
  9. Main PID:30050(containerd)
  10. Memory:24.5M
  11. CGroup:/system.slice/containerd.service
  12. └─30050/usr/local/bin/containerd
  13. May1222:59:19 web01 containerd[30050]: time=”2022-05-12T22:59:19.153514446-04:00” level=info msg=”Get image filesystem path “/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs””
  14. May1222:59:19 web01 containerd[30050]: time=”2022-05-12T22:59:19.154085898-04:00” level=info msg=”Start subscribing containerd event”
  15. May1222:59:19 web01 containerd[30050]: time=”2022-05-12T22:59:19.154137039-04:00” level=info msg=”Start recovering state”
  16. May1222:59:19 web01 containerd[30050]: time=”2022-05-12T22:59:19.154230615-04:00” level=info msg=”Start event monitor”
  17. May1222:59:19 web01 containerd[30050]: time=”2022-05-12T22:59:19.154276701-04:00” level=info msg=”Start snapshots syncer”
  18. May1222:59:19 web01 containerd[30050]: time=”2022-05-12T22:59:19.154299287-04:00” level=info msg=”Start cni network conf syncer for default”
  19. May1222:59:19 web01 containerd[30050]: time=”2022-05-12T22:59:19.154316094-04:00” level=info msg=”Start streaming server”
  20. May1222:59:19 web01 containerd[30050]: time=”2022-05-12T22:59:19.154675632-04:00” level=info msg=serving… address=/run/containerd/containerd.sock.ttrpc
  21. May1222:59:19 web01 containerd[30050]: time=”2022-05-12T22:59:19.154755704-04:00” level=info msg=serving… address=/run/containerd/containerd.sock
  22. May1222:59:19 web01 containerd[30050]: time=”2022-05-12T22:59:19.155220379-04:00” level=info msg=”containerd successfully booted in 0.027654s”

ctr在我们解压包中已经附带了,直接可以使用

  1. [root@k8s-01~]# ctr version
  2. Client:#ctr版本号
  3. Version: v1.6.4
  4. Revision:212e8b6fa2f44b9c21b2798135fc6fb7c53efc16
  5. Go version: go1.17.9
  6. Server:
  7. Version: v1.6.4#containerd版本号
  8. Revision:212e8b6fa2f44b9c21b2798135fc6fb7c53efc16
  9. UUID: b376d7b6-c97e-4b39-8144-9624ade3ba84
  10. 可以使用下面命令查看containerd版本号

  11. [root@k8s-01~]# containerd —version
  12. containerd github.com/containerd/containerd v1.6.4212e8b6fa2f44b9c21b2798135fc6fb7c53efc16

    api-server 高可用部署 (单master可跳过)

    nginx代理后端3台apiserver,所以需要在每台apiserver中安装nginx。keeplived起到vip的作用
    需要在master节点安装

  13. 首先我们在原有的基础上添加一个host,只需要在master节点上执行即可

  14. cat >>/etc/hosts<< EOF
  15. 192.168.31.10 k8s-master-01
  16. 192.168.31.11 k8s-master-02
  17. 192.168.31.12 k8s-master-03
  18. 192.168.31.111 apiserver.frps.cn
  19. EOF

安装nginx
为了方便后面扩展插件,我这里使用编译安装nginx

  1. 编译安装nginx

  2. 安装依赖

  3. yum install pcre pcre-devel openssl openssl-devel gcc gcc-c++ automake autoconf libtool make wget vim lrzsz -y
  4. wget https://nginx.org/download/nginx-1.20.2.tar.gz
  5. tar xf nginx-1.20.2.tar.gz
  6. cd nginx-1.20.2/
  7. useradd nginx -s /sbin/nologin -M
  8. ./configure —prefix=/opt/nginx/—with-pcre —with-http_ssl_module —with-http_stub_status_module —with-stream —with-http_stub_status_module —with-http_gzip_static_module
  9. make && make install
  10. 使用systemctl管理,并设置开机启动

  11. cat >/usr/lib/systemd/system/nginx.service<<EOF
  12. /usr/lib/systemd/system/nginx.service

  13. [Unit]
  14. Description=The nginx HTTP and reverse proxy server
  15. After=network.target sshd-keygen.service
  16. [Service]
  17. Type=forking
  18. EnvironmentFile=/etc/sysconfig/sshd
  19. ExecStartPre=/opt/nginx/sbin/nginx -t -c /opt/nginx/conf/nginx.conf
  20. ExecStart=/opt/nginx/sbin/nginx -c /opt/nginx/conf/nginx.conf
  21. ExecReload=/opt/nginx/sbin/nginx -s reload
  22. ExecStop=/opt/nginx/sbin/nginx -s stop
  23. Restart=on-failure
  24. RestartSec=42s
  25. [Install]
  26. WantedBy=multi-user.target
  27. EOF
  28. 开机启动

  29. [root@k8s-01 nginx-1.20.2]# systemctl enable nginx —now
  30. Created symlink from/etc/systemd/system/multi-user.target.wants/nginx.service to /usr/lib/systemd/system/nginx.service.
  31. yum安装nginx

  32. yum install nginx -y
  33. yum安装nginx需要注意下面的配置文件路径就是/etc/nginx/conf/nginx.conf

检查服务是否启动

  1. [root@k8s-01 nginx-1.20.2]# ps -ef|grep nginx
  2. root 840401020:15?00:00:00 nginx: master process /opt/nginx/sbin/nginx -c /opt/nginx/conf/nginx.conf
  3. nobody 8404184040020:15?00:00:00 nginx: worker process
  4. root 8404451752020:16 pts/000:00:00 grep —color=auto nginx

修改nginx配置文件

  1. vim nginx.conf
  2. user nginx nginx;
  3. worker_processes auto;
  4. events {
  5. worker_connections 20240;
  6. use epoll;
  7. }
  8. error_log /var/log/nginx_error.log info;
  9. stream {
  10. upstream kube-servers {
  11. hash $remote_addr consistent;
  12. server k8s-master-01:6443 weight=5 max_fails=1 fail_timeout=3s;#这里可以写IP
  13. server k8s-master-02:6443 weight=5 max_fails=1 fail_timeout=3s;
  14. server k8s-master-03:6443 weight=5 max_fails=1 fail_timeout=3s;
  15. }
  16. server {
  17. listen 8443 reuseport;
  18. proxy_connect_timeout 3s;
  19. 加大timeout

  20. proxy_timeout 3000s;
  21. proxy_pass kube-servers;
  22. }
  23. }
  24. 分发到其它master节点

  25. for i in k8s-02 k8s-03
  26. do
  27. scp nginx.conf root@$i:/opt/nginx/conf/
  28. ssh root@$i systemctl restart nginx
  29. done

配置Keeplived
前面我们也说了,高可用方案需要一个VIP,供集群内部访问

  1. yum install -y keepalived
  2. 在所有master节点安装

修改配置文件

  • router_id 节点IP
  • mcast_src_ip 节点IP
  • virtual_ipaddress VIP

请根据自己IP实际上情况修改

  1. cat >/etc/keepalived/keepalived.conf <<EOF
  2. !ConfigurationFilefor keepalived
  3. global_defs {
  4. router_id 192.168.31.10#节点ip,master每个节点配置自己的IP
  5. }
  6. vrrp_script chk_nginx {
  7. script “/etc/keepalived/check_port.sh 8443”
  8. interval 2
  9. weight -20
  10. }
  11. vrrp_instance VI_1 {
  12. state MASTER
  13. interface eth0
  14. virtual_router_id 251
  15. priority 100
  16. advert_int 1
  17. mcast_src_ip 192.168.31.10#节点IP
  18. nopreempt
  19. authentication {
  20. auth_type PASS
  21. auth_pass 11111111
  22. }
  23. track_script {
  24. chk_nginx
  25. }
  26. virtual_ipaddress {
  27. 192.168.31.111#VIP
  28. }
  29. }
  30. EOF
  31. 编写健康检查脚本

  32. vim /etc/keepalived/check_port.sh
  33. CHK_PORT=$1
  34. if[-n “$CHK_PORT”];then
  35. PORT_PROCESS=ss -lt|grep $CHK_PORT|wc -l
  36. if[ $PORT_PROCESS -eq 0];then
  37. echo “Port $CHK_PORT Is Not Used,End.”
  38. exit1
  39. fi
  40. else
  41. echo “Check Port Cant Be Empty!”
  42. fi

启动keepalived
systemctl enable —now keepalived
测试vip是否正常
ping vip
ping apiserver.frps.cn #我们的域名

Kubeadm 安装配置

首先我们需要在k8s-01配置kubeadm源
下面kubeadm操作只需要在k8s-01上即可
国内源
packages.cloud.google.com这里懂的都懂,下面改成阿里云源

  1. cat </etc/yum.repos.d/kubernetes.repo
  2. [kubernetes]
  3. name=Kubernetes
  4. baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
  5. enabled=1
  6. gpgcheck=0
  7. repo_gpgcheck=0
  8. gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
  9. http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
  10. EOF

官方文档推荐源

  1. cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
  2. [kubernetes]
  3. name=Kubernetes
  4. baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-$basearch
  5. enabled=1
  6. gpgcheck=1
  7. repo_gpgcheck=1
  8. gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
  9. exclude=kubelet kubeadm kubectl
  10. EOF

k8s-01节点安装kubeadm和master相关依赖组建
yum install -y kubelet-1.24.0 kubeadm-1.24.0 kubectl-1.24.0 —disableexcludes=kubernetes
将k8s-01节点的kubelet设置成开机启动:
systemctl enable —now kubelet
配置kubeadm文件
这里我们在k8s-01上配置打印init默认配置信息
kubeadm config print init-defaults >kubeadm-init.yaml
虽然kubeadm作为etcd节点的管理工具,但请注意kubeadm不打算支持此类节点的证书轮换或升级。长期计划是使用etcdadm来工具来进行管理。
因为我这里要做集群,请根据我这里的配置按需修改

  1. [root@k8s-01~]# cat kubeadm-init.yaml
  2. apiVersion: kubeadm.k8s.io/v1beta3
  3. bootstrapTokens:
    • groups:
    • system:bootstrappers:kubeadm:default-node-token
  4. token: abcdef.0123456789abcdef
  5. ttl:24h0m0s
  6. usages:
    • signing
    • authentication
  7. kind:InitConfiguration
  8. localAPIEndpoint:
  9. advertiseAddress:192.168.31.10#k8s-01 ip地址
  10. bindPort:6443
  11. nodeRegistration:
  12. criSocket: unix:///var/run/containerd/containerd.sock
  13. imagePullPolicy:IfNotPresent
  14. name: k8s-01
  15. taints:null

  16. apiServer:
  17. timeoutForControlPlane:4m0s
  18. apiVersion: kubeadm.k8s.io/v1beta3
  19. certificatesDir:/etc/kubernetes/pki
  20. clusterName: kubernetes
  21. controllerManager:{}
  22. dns:{}
  23. etcd:
  24. local:
  25. dataDir:/var/lib/etcd
  26. imageRepository: k8s.gcr.io
  27. kind:ClusterConfiguration
  28. kubernetesVersion:1.24.0
  29. controlPlaneEndpoint: apiserver.frps.cn:8443#高可用地址,我这里填写vip
  30. networking:
  31. dnsDomain: cluster.local
  32. serviceSubnet:10.96.0.0/12
  33. podSubnet:10.244.0.0/16
  34. scheduler:{}

  35. apiVersion: kubeproxy.config.k8s.io/v1alpha1
  36. kind:KubeProxyConfiguration
  37. mode: ipvs # kube-proxy 模式

  38. apiVersion: kubelet.config.k8s.io/v1beta1
  39. authentication:
  40. anonymous:
  41. enabled:false
  42. webhook:
  43. cacheTTL:0s
  44. enabled:true
  45. x509:
  46. clientCAFile:/etc/kubernetes/pki/ca.crt
  47. authorization:
  48. mode:Webhook
  49. webhook:
  50. cacheAuthorizedTTL:0s
  51. cacheUnauthorizedTTL:0s
  52. clusterDNS:
  53. -10.96.0.10
  54. clusterDomain: cluster.local
  55. cpuManagerReconcilePeriod:0s
  56. evictionPressureTransitionPeriod:0s
  57. fileCheckFrequency:0s
  58. healthzBindAddress:127.0.0.1
  59. healthzPort:10248
  60. httpCheckFrequency:0s
  61. imageMinimumGCAge:0s
  62. kind:KubeletConfiguration
  63. cgroupDriver: systemd # 配置 cgroup driver
  64. logging:{}
  65. memorySwap:{}
  66. nodeStatusReportFrequency:0s
  67. nodeStatusUpdateFrequency:0s
  68. rotateCertificates:true
  69. runtimeRequestTimeout:0s
  70. shutdownGracePeriod:0s
  71. shutdownGracePeriodCriticalPods:0s
  72. staticPodPath:/etc/kubernetes/manifests
  73. streamingConnectionIdleTimeout:0s
  74. syncFrequency:0s
  75. volumeStatsAggPeriod:0s

检查配置文件是否有错误
[root@k8s-01 ~]# kubeadm init —config kubeadm-init.yaml —dry-run
正确如下
image.png
预先拉取镜像

  1. [root@k8s-01~]# kubeadm config images list —config kubeadm-init.yaml
  2. k8s.gcr.io/kube-apiserver:v1.24.0
  3. k8s.gcr.io/kube-controller-manager:v1.24.0
  4. k8s.gcr.io/kube-scheduler:v1.24.0
  5. k8s.gcr.io/kube-proxy:v1.24.0
  6. k8s.gcr.io/pause:3.7
  7. k8s.gcr.io/etcd:3.5.3-0
  8. k8s.gcr.io/coredns/coredns:v1.8.6

提前下载镜像导入,默认情况使用的是k8s.gcr.io,这个镜像地址我们无法pull,所以使用导入的方式

  1. wget https://d.frps.cn/file/kubernetes/image/k8s_all_1.24.tar
  2. 拷贝到其它节点

  3. for i in k8s-02 k8s-03 k8s-04 k8s-05;do
  4. scp k8s_all_1.24.tar root@$i:/root/
  5. ssh root@$i ctr -n k8s.io i import k8s_all_1.24.tar
  6. done

检查

  1. [root@k8s-01~]# ctr -n k8s.io i ls -q
  2. k8s.gcr.io/coredns/coredns:v1.8.6
  3. k8s.gcr.io/etcd:3.5.3-0
  4. k8s.gcr.io/kube-apiserver:v1.24.0
  5. k8s.gcr.io/kube-controller-manager:v1.24.0
  6. k8s.gcr.io/kube-proxy:v1.24.0
  7. k8s.gcr.io/kube-scheduler:v1.24.0
  8. k8s.gcr.io/pause:3.7

    Kubectl 安装

    这一步可以省略,可以通过后续yum安装,这一步可以忽略
    kubeadm不会安装或管理kubelet,kubectl因此需要确保它们kubeadm和Kubernetes版本相匹配。如果不这样,则存在版本偏差的风险。但是,支持kubelet和k8s之间的一个小版本偏差,但kubelet版本可能永远不会超过API Server版本

  9. 下载1.24.0 kubectl工具

  10. [root@k8s-01~]# curl -LO https://dl.k8s.io/release/v1.24.0/bin/linux/amd64/kubectl
  11. [root@k8s-01~]# chmod +x kubectl && mv kubectl /usr/local/bin/
  12. 检查kubectl工具版本号

  13. [root@k8s-01~]# kubectl version —client —output=yaml
  14. clientVersion:
  15. buildDate:”2022-05-03T13:46:05Z”
  16. compiler: gc
  17. gitCommit:4ce5a8954017644c5420bae81d72b09b735c21f0
  18. gitTreeState: clean
  19. gitVersion: v1.24.0
  20. goVersion: go1.18.1
  21. major:”1”
  22. minor:”24”
  23. platform: linux/amd64
  24. kustomizeVersion: v4.5.4
  25. 拷贝kubectl到其它master节点

  26. for i in k8s-02 k8s-03;do
  27. scp /usr/local/bin/kubectl root@$i:/usr/local/bin/kubectl
  28. ssh root@$i chmod +x /usr/local/bin/kubectl
  29. done

接下来开始初始化
[root@k8s-01 ~]# kubeadm init —config kubeadm-init.yaml —upload-certs
初始化过程
image.png
初始化完成
image.png
记住init后打印的token,复制kubectl的kubeconfig,kubectl的kubeconfig路径默认是~/.kube/config
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
初始化的配置文件为保存在configmap里面
kubectl -n kube-system get cm kubeadm-config -o yaml
接下来执行kubectl就可以看到node了
[root@k8s-01 ~]# kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-01 Ready control-plane 4m18s v1.24.0

Master节点配置

前面我们已经为所有master节点配置了一下服务

  • nginx
  • keeplived
  • containerd

接下来只需要给其它master节点安装k8s组件

  1. cat </etc/yum.repos.d/kubernetes.repo
  2. [kubernetes]
  3. name=Kubernetes
  4. baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
  5. enabled=1
  6. gpgcheck=0
  7. repo_gpgcheck=0
  8. gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
  9. http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
  10. EOF

安装相关组件
yum install -y kubelet-1.24.0 kubeadm-1.24.0 kubectl-1.24.0 —disableexcludes=kubernetes
启动kubelet
systemctl enable —now kubelet
master执行添加节点

  1. kubeadm join apiserver.frps.cn:8443—token abcdef.0123456789abcdef
  2. —discovery-token-ca-cert-hash sha256:a54c17e514edba57226f969268227b749d8bfb8802ae99112e08cbcabcd22ae0
  3. —control-plane —certificate-key f7b0eb9c7e0aac2c95eef083c591950109434250a6df9cc0dc1ec9fb04461250

设置kubectl config文件

  1. mkdir -p $HOME/.kube
  2. sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  3. sudo chown $(id -u):$(id -g) $HOME/.kube/config

目前我们3台master节点已经添加完毕

  1. [root@k8s-02~]# kubectl get node
  2. NAME STATUS ROLES AGE VERSION
  3. k8s-01Ready control-plane 15m v1.24.0
  4. k8s-02Ready control-plane 6m25s v1.24.0
  5. k8s-03Ready control-plane 14m v1.24.0

    Node节点配置

    node节点安装kubeadm

  6. cat </etc/yum.repos.d/kubernetes.repo

  7. [kubernetes]
  8. name=Kubernetes
  9. baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
  10. enabled=1
  11. gpgcheck=0
  12. repo_gpgcheck=0
  13. gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
  14. http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
  15. EOF

安装相关组件
yum install -y kubeadm-1.24.0 —disableexcludes=kubernetes
添加join命令

  1. kubeadm join apiserver.frps.cn:8443—token abcdef.0123456789abcdef
  2. —discovery-token-ca-cert-hash sha256:a54c17e514edba57226f969268227b749d8bfb8802ae99112e08cbcabcd22ae0

如果我们后续需要添加node节点时,可以到k8s-01节点执行下面的命令获取token相关信息

  1. [root@k8s-01~]# kubeadm token create —print-join-command
  2. kubeadm join apiserver.frps.cn:8443—token sgvcen.qf87ykht9gopqe0d —discovery-token-ca-cert-hash sha256:f535fdf0af19022a30760fd5069c648019a3f4b4828bfb2eb566224d76d21647

如果我们添加某台节点异常了,修改后可以执行下面的命令,然后在重新join加入集群
kubeadm reset
验证所有服务器是否添加到集群中

  1. [root@k8s-01~]# kubectl get node -o wide
  2. NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
  3. k8s-01Ready control-plane 22m v1.24.0192.168.31.10CentOSLinux7(Core)5.17.8-1.el7.elrepo.x86_64 containerd://1.6.4
  4. k8s-02Ready control-plane 13m v1.24.0192.168.31.11CentOSLinux7(Core)5.17.8-1.el7.elrepo.x86_64 containerd://1.6.4
  5. k8s-03Ready control-plane 21m v1.24.0192.168.31.12CentOSLinux7(Core)5.17.8-1.el7.elrepo.x86_64 containerd://1.6.4
  6. k8s-04Ready107s v1.24.0192.168.31.13CentOSLinux7(Core)5.17.8-1.el7.elrepo.x86_64 containerd://1.6.4
  7. k8s-05Ready6m6s v1.24.0192.168.31.14CentOSLinux7(Core)3.10.0-1160.62.1.el7.x86_64 containerd://1.6.4

    网络配置

    这个时候其实集群还不能正常使用,因为还没有安装网络插件,接下来安装网络插件,可以在文档 https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/ 中选择我们自己的网络插件,这里我们安装 flannel
    wget http://down.i4t.com/k8s1.24/kube-flannel.yml
    根据需求修改网卡配置,我这里以eth0为主

  8. containers:

    • name: kube-flannel
  9. image: quay.io/coreos/flannel:v0.12.0-amd64
  10. command:
  11. -/opt/bin/flanneld
  12. args:
  13. —-ip-masq
  14. —-kube-subnet-mgr
  15. —-iface=eth0 # 如果是多网卡的话,指定内网网卡的名称

温馨提示: 在kubeadm.yaml文件中设置了podSubnet网段,同时在flannel中网段也要设置相同的。 (我这里默认就是相同的配置)
执行
[root@k8s-01 ~]# kubectl apply -f kube-flannel.yml

CNI插件问题

默认情况下containerd也会有一个cni插件,但是我们已经安装Flannel了,我们需要使用Flannel的cni插件,需要将containerd里面的cni配置文件进行注释,否则2个配置会产生冲突
因为如果这个目录中有多个 cni 配置文件,kubelet 将会使用按文件名的字典顺序排列的第一个作为配置文件,所以前面默认选择使用的是 containerd-net 这个插件。

  1. mv /etc/cni/net.d/10-containerd-net.conflist /etc/cni/net.d/10-containerd-net.conflist.bak
  2. ifconfig cni0 down && ip link delete cni0
  3. systemctl daemon-reload
  4. systemctl restart containerd kubelet

接下来我们所有的pod都可以正常运行了
image.png

验证集群

等kube-system命名空间下的Pod都为Running,这里先测试一下dns是否正常

  1. cat<<EOF | kubectl apply -f -
  2. apiVersion: apps/v1
  3. kind:Deployment
  4. metadata:
  5. name: nginx
  6. spec:
  7. selector:
  8. matchLabels:
  9. app: nginx
  10. template:
  11. metadata:
  12. labels:
  13. app: nginx
  14. spec:
  15. containers:
    • image: nginx:alpine
  16. name: nginx
  17. ports:
    • containerPort:80

  18. apiVersion: v1
  19. kind:Service
  20. metadata:
  21. name: nginx
  22. spec:
  23. selector:
  24. app: nginx
  25. type:NodePort
  26. ports:
    • protocol: TCP
  27. port:80
  28. targetPort:80
  29. nodePort:30001

  30. apiVersion: v1
  31. kind:Pod
  32. metadata:
  33. name: busybox
  34. namespace:default
  35. spec:
  36. containers:
    • name: busybox
  37. image: abcdocker9/centos:v1
  38. command:
    • sleep
  39. -“3600”
  40. imagePullPolicy:IfNotPresent
  41. restartPolicy:Always
  42. EOF

创建后Pod我们进行检查
image.png
使用nslookup查看是否能返回地址

  1. [root@k8s-01~]# kubectl exec-ti busybox — nslookup kubernetes
  2. Server:10.96.0.10
  3. Address:10.96.0.10#53
  4. Name: kubernetes.default.svc.cluster.local
  5. Address:10.96.0.1

测试nginx svc以及Pod内部网络通信是否正常

  1. for i in k8s-01 k8s-02 k8s-03 k8s-04 k8s-05
  2. do
  3. ssh root@$i curl -s 10.99.209.220#nginx svc ip
  4. ssh root@$i curl -s 10.244.3.4#pod ip
  5. done

访问宿主机nodePort端口
image.png

Kubernetes kubectl 命令自动补全

Related Posts:

  1. Kubernetes 1.14 二进制集群安装
  2. Kubenetes 1.13.5 集群二进制安装
  3. Kubernetes容器运行时弃用Docker转型Containerd
  4. Kuerbernetes 1.11 集群二进制安装