- 背景
- 以下容器运行时已经或即将全面兼容Kubernetes 1.24:
- 目前kubernetes版本
- 建议所有服务器都执行
- !/bin/bash
- 配置host
- 设置k8s-01为分发机 (只需要在k8s-01服务器操作即可)
- 分发公钥
- 每台节点
- !/bin/bash
- 分发到所有节点
- for后面节点根据需求修改
- !/bin/bash
- 查看是否已经正确加载所需的内核模块
- 将当前的 UTC 时间写入硬件时钟
- 重启依赖于系统时间的服务
- 默认安装为最新内核
- 修改内核顺序
- 使用下面命令看看确认下是否启动默认内核指向上面安装的内核
- 这里的输出结果应该为我们升级后的内核信息
- 可以等所有初始化步骤结束进行reboot操作
- 卸载原来的
- 下载高于2.4以上的包
- 安装
- 查看当前版本
- 下载tar.gz包
- containerd工具包,包含cri runc等
- 备用下载地址
- cri-containerd-cni会将我们整个containerd相关的依赖都进行下载下来
- 创建配置文件目录
- 生成默认配置文件
- —config,-c可以在启动守护程序时更改此路径
- 配置文件的默认路径位于/etc/containerd/config.toml
- 所有节点更换默认镜像地址
- 我这里使用阿里云地址
- 可以使用下面命令查看containerd版本号
- 首先我们在原有的基础上添加一个host,只需要在master节点上执行即可
- 编译安装nginx
- 安装依赖
- 使用systemctl管理,并设置开机启动
- /usr/lib/systemd/system/nginx.service
- 开机启动
- yum安装nginx
- yum安装nginx需要注意下面的配置文件路径就是/etc/nginx/conf/nginx.conf
- 加大timeout
- 分发到其它master节点
- 在所有master节点安装
- 编写健康检查脚本
- 拷贝到其它节点
- 下载1.24.0 kubectl工具
- 检查kubectl工具版本号
- 拷贝kubectl到其它master节点
文章目录
- 背景
- Kubernetes 1.24新特性
- kubeadm 搭建Kubernetes 1.18集群
- 环境准备
- 基础环境配置
- Containerd 安装
- Kubernetes容器运行时弃用Docker转型Containerd
- api-server 高可用部署 (单master可跳过)
- Kubeadm 安装配置
- Kubectl 安装
- Master节点配置
- Node节点配置
- 网络配置
- CNI插件问题
- 验证集群
-
背景
Kubernetes 1.24新特性
从kubelet中移除dockershim
自1.20版本被弃用之后,dockershim组件终于在1.24的kubelet中被删除。从1.24开始,大家需要使用其他受到支持的运行时选项(例如containerd或CRI-O);如果您选择Docker Engine作为运行时,则需要使用cri-dockerd。
对于kubelet和containerd重要提示
在升级至1.24之前,请确认containerd版本
若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环境,接下来对环境进行初始化
目前kubernetes版本
- [root@k8s-01~]# kubectl get node
- NAME STATUS ROLES AGE VERSION
- k8s-01Ready master 243d v1.18.3
- k8s-02Ready master 243d v1.18.3
- k8s-03Ready master 243d v1.18.3
- k8s-04Ready
243d v1.18.3 - k8s-05Ready
243d v1.18.3
卸载集群命令
建议所有服务器都执行
!/bin/bash
- kubeadm reset -f
- modprobe -r ipip
- lsmod
- rm -rf ~/.kube/
- rm -rf /etc/kubernetes/
- rm -rf /etc/systemd/system/kubelet.service.d
- rm -rf /etc/systemd/system/kubelet.service
- rm -rf /usr/bin/kube*
- rm -rf /etc/cni
- rm -rf /opt/cni
- rm -rf /var/lib/etcd
- rm -rf /var/etcd
- yum -y remove kubeadm kubectl kubelet docker
- 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 |
初始化环境
初始化环境需要全部节点都执行
批量修改主机名,以及免密
- hostnamectl set-hostname k8s01 #所有机器按照要求修改
- bash #刷新主机名
配置host
- cat >>/etc/hosts <<EOF
- 192.168.31.100 k8s-01
- 192.168.31.101 k8s-02
- 192.168.31.102 k8s-03
- 192.168.31.103 k8s-04
- 192.168.31.104 k8s-05
- EOF
设置k8s-01为分发机 (只需要在k8s-01服务器操作即可)
- wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
- curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
- yum install -y expect
分发公钥
- ssh-keygen -t rsa -P “”-f /root/.ssh/id_rsa
- for i in k8s-01 k8s-02 k8s-03 k8s-04 k8s-05;do
- expect -c “
- spawn ssh-copy-id -i /root/.ssh/id_rsa.pub root@$i
- expect {
- “yes/no“ {send “yesr”; exp_continue}
- “password“ {send “123456r”; exp_continue}
- “Password“ {send “123456r”;}
- } “
- done
我这里密码为123456,请根据需求自行更改
所有节点关闭Selinux、iptables、swap分区
- systemctl stop firewalld
- systemctl disable firewalld
- iptables -F && iptables -X && iptables -F -t nat && iptables -X -t nat
- iptables -P FORWARD ACCEPT
- swapoff -a
- sed -i ‘/ swap / s/^(.*)$/#1/g’/etc/fstab
- setenforce 0
- sed -i ‘s/^SELINUX=.*/SELINUX=disabled/‘/etc/selinux/config
所有节点配置yum源
- curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
- wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
- yum clean all
- yum makecache
新安装的服务器可以安装下面的软件包,可以解决99%的依赖问题
- 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 模块,所以加载下该模块:
将上面的命令设置成开机启动,因为重启后模块失效,下面是开机自动加载模块的方式。首先新建 /etc/rc.sysinit 文件,内容如下所示:
- cat >>/etc/rc.sysinit<<EOF
!/bin/bash
- for file in/etc/sysconfig/modules/*.modules ; do
- [ -x $file ] && $file
- done
- EOF
然后在/etc/sysconfig/modules/目录下新建如下文件:
- echo “modprobe br_netfilter”>/etc/sysconfig/modules/br_netfilter.modules
- 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
然后重启后,模块就可以自动加载了
优化内核参数
- cat > kubernetes.conf <<EOF
- net.bridge.bridge-nf-call-iptables=1
- net.bridge.bridge-nf-call-ip6tables=1
- net.ipv4.ip_forward=1
- vm.swappiness=0# 禁止使用 swap 空间,只有当系统 OOM 时才允许使用它
- vm.overcommit_memory=1# 不检查物理内存是否够用
- vm.panic_on_oom=0# 开启 OOM
- fs.inotify.max_user_instances=8192
- fs.inotify.max_user_watches=1048576
- fs.file-max=52706963
- fs.nr_open=52706963
- net.ipv6.conf.all.disable_ipv6=1
- net.netfilter.nf_conntrack_max=2310720
- EOF
- cp kubernetes.conf /etc/sysctl.d/kubernetes.conf
- sysctl -p /etc/sysctl.d/kubernetes.conf
分发到所有节点
- for i in k8s-02 k8s-03 k8s-04 k8s-05
- do
- scp kubernetes.conf root@$i:/etc/sysctl.d/
- ssh root@$i sysctl -p /etc/sysctl.d/kubernetes.conf
- ssh root@$i echo ‘1’>>/proc/sys/net/ipv4/ip_forward
- done
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
- 为什么要使用IPVS,从k8s的1.8版本开始,kube-proxy引入了IPVS模式,IPVS模式与iptables同样基于Netfilter,但是采用的hash表,因此当service数量达到一定规模时,hash查表的速度优势就会显现出来,从而提高service的服务性能。
- 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正常
- cat >/etc/sysconfig/modules/ipvs.modules <<EOF
!/bin/bash
- modprobe — ip_vs
- modprobe — ip_vs_rr
- modprobe — ip_vs_wrr
- modprobe — ip_vs_sh
- modprobe — nf_conntrack
- EOF
- chmod 755/etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack
查看是否已经正确加载所需的内核模块
所有节点安装ipset
yum install ipset -y
ipset介绍
- iptables是Linux服务器上进行网络隔离的核心技术,内核在处理网络请求时会对iptables中的策略进行逐条解析,因此当策略较多时效率较低;而是用IPSet技术可以将策略中的五元组(协议,源地址,源端口,目的地址,目的端口)合并到有限的集合中,可以大大减少iptables策略条目从而提高效率。测试结果显示IPSet方式效率将比iptables提高100倍
为了方面ipvs管理,这里安装一下ipvsadm。
yum install ipvsadm -y
所有节点设置系统时区
- timedatectl set-timezone Asia/Shanghai
将当前的 UTC 时间写入硬件时钟
- timedatectl set-local-rtc 0
重启依赖于系统时间的服务
- systemctl restart rsyslog
- systemctl restart crond
升级内核 (可选方案)
- rpm —import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
- rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm
默认安装为最新内核
- yum —enablerepo=elrepo-kernel install kernel-ml
修改内核顺序
- grub2-set-default0&& grub2-mkconfig -o /etc/grub2.cfg
使用下面命令看看确认下是否启动默认内核指向上面安装的内核
- grubby —default-kernel
这里的输出结果应该为我们升级后的内核信息
- reboot
可以等所有初始化步骤结束进行reboot操作
Containerd 安装
Kubernetes容器运行时弃用Docker转型Containerd
在安装containerd前,我们需要优先升级libseccomp
在centos7中yum下载libseccomp的版本是2.3的,版本不满足我们最新containerd的需求,需要下载2.4以上的
Containerd需要在所有节点升级安装
卸载原来的
- [i4t@web01 ~]# rpm -qa | grep libseccomp
- libseccomp-devel-2.3.1-4.el7.x86_64
- libseccomp-2.3.1-4.el7.x86_64
- [i4t@web01 ~]# rpm -e libseccomp-devel-2.3.1-4.el7.x86_64 —nodeps
- [i4t@web01 ~]# rpm -e libseccomp-2.3.1-4.el7.x86_64 —nodeps
下载高于2.4以上的包
- [i4t@web01 ~]# wget http://rpmfind.net/linux/centos/8-stream/BaseOS/x86_64/os/Packages/libseccomp-2.5.1-1.el8.x86_64.rpm
安装
- [i4t@web01 ~]# rpm -ivh libseccomp-2.5.1-1.el8.x86_64.rpm
- warning: libseccomp-2.5.1-1.el8.x86_64.rpm:Header V3 RSA/SHA256 Signature, key ID 8483c65d: NOKEY
- Preparing…################################# [100%]
- Updating/ installing…
- 1:libseccomp-2.5.1-1.el8################################# [100%]
查看当前版本
- [root@web01 ~]# rpm -qa | grep libseccomp
- 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等相关工具包,建议下载本包
下载tar.gz包
containerd工具包,包含cri runc等
- wget https://github.com/containerd/containerd/releases/download/v1.6.4/cri-containerd-cni-1.6.4-linux-amd64.tar.gz
备用下载地址
- wget https://d.frps.cn/file/kubernetes/containerd/cri-containerd-cni-1.6.4-linux-amd64.tar.gz
工具包文件如下
cri-containerd-cni会将我们整个containerd相关的依赖都进行下载下来
- [root@k8s-01 containerd]# tar zxvf cri-containerd-cni-1.6.4-linux-amd64.tar.gz -C /#我们直接让它给我们对应的目录给替换掉
- etc/
- etc/systemd/
- etc/systemd/system/
- etc/systemd/system/containerd.service
- etc/crictl.yaml
- etc/cni/
- etc/cni/net.d/
- etc/cni/net.d/10-containerd-net.conflist
- usr/
- usr/local/
- usr/local/sbin/
- usr/local/sbin/runc
- usr/local/bin/
- usr/local/bin/crictl
- usr/local/bin/ctd-decoder
- usr/local/bin/ctr
- usr/local/bin/containerd-shim
- usr/local/bin/containerd
- usr/local/bin/containerd-shim-runc-v1
- usr/local/bin/critest
- usr/local/bin/containerd-shim-runc-v2
- usr/local/bin/containerd-stress
- opt/
- opt/containerd/
- opt/containerd/cluster/
- opt/containerd/cluster/version
- opt/containerd/cluster/gce/
- opt/containerd/cluster/gce/cni.template
- opt/containerd/cluster/gce/env
- opt/containerd/cluster/gce/configure.sh
- opt/containerd/cluster/gce/cloud-init/
- opt/containerd/cluster/gce/cloud-init/node.yaml
- opt/containerd/cluster/gce/cloud-init/master.yaml
- opt/cni/
- opt/cni/bin/
- opt/cni/bin/firewall
- opt/cni/bin/portmap
- opt/cni/bin/host-local
- opt/cni/bin/ipvlan
- opt/cni/bin/host-device
- opt/cni/bin/sbr
- opt/cni/bin/vrf
- opt/cni/bin/static
- opt/cni/bin/tuning
- opt/cni/bin/bridge
- opt/cni/bin/macvlan
- opt/cni/bin/bandwidth
- opt/cni/bin/vlan
- opt/cni/bin/dhcp
- opt/cni/bin/loopback
- opt/cni/bin/ptp
上面的文件都是二进制文件,直接移动到对应的目录并配置好环境变量就可以进行使用了。
如果我们机器上通过yum安装docker了,可以用下面的命令进行卸载
- sudo yum remove docker
- docker-client
- docker-client-latest
- docker-common
- docker-latest
- docker-latest-logrotate
- docker-logrotate
- docker-engine
接下来我们为每台服务器配置Containerd
创建配置文件目录
- [root@k8s-01~]# mkdir /etc/containerd -p
生成默认配置文件
- [root@k8s-01~]# containerd config default>/etc/containerd/config.toml
—config,-c可以在启动守护程序时更改此路径
配置文件的默认路径位于/etc/containerd/config.toml
替换默认pause镜像地址
默认情况下k8s.gcr.io无法访问,所以使用我提供的阿里云镜像仓库地址即可
- sed -i ‘s/k8s.gcr.io/registry.cn-beijing.aliyuncs.com/abcdocker/‘/etc/containerd/config.toml
所有节点更换默认镜像地址
我这里使用阿里云地址
配置systemd作为容器的cgroup driver
sed -i ‘s/SystemdCgroup = false/SystemdCgroup = true/‘ /etc/containerd/config.toml
Containerd官方操作手册
默认cri-containerd-cni包中会有containerd启动脚本,我们已经解压到对应的目录,可以直接调用启动
- [root@k8s-01~]# systemctl enable containerd —now
- Created symlink from/etc/systemd/system/multi-user.target.wants/containerd.service to /etc/systemd/system/containerd.service.
- [root@k8s-01~]# systemctl status containerd #查看containerd启动状态
- ● containerd.service - containerd container runtime
- Loaded: loaded (/etc/systemd/system/containerd.service; enabled; vendor preset: disabled)
- Active: active (running) since Thu2022-05-1222:59:19 EDT;3s ago
- Docs: https://containerd.io
- Process:30048ExecStartPre=/sbin/modprobe overlay (code=exited, status=0/SUCCESS)
- Main PID:30050(containerd)
- Memory:24.5M
- CGroup:/system.slice/containerd.service
- └─30050/usr/local/bin/containerd
- 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””
- May1222:59:19 web01 containerd[30050]: time=”2022-05-12T22:59:19.154085898-04:00” level=info msg=”Start subscribing containerd event”
- May1222:59:19 web01 containerd[30050]: time=”2022-05-12T22:59:19.154137039-04:00” level=info msg=”Start recovering state”
- May1222:59:19 web01 containerd[30050]: time=”2022-05-12T22:59:19.154230615-04:00” level=info msg=”Start event monitor”
- May1222:59:19 web01 containerd[30050]: time=”2022-05-12T22:59:19.154276701-04:00” level=info msg=”Start snapshots syncer”
- 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”
- May1222:59:19 web01 containerd[30050]: time=”2022-05-12T22:59:19.154316094-04:00” level=info msg=”Start streaming server”
- 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
- May1222:59:19 web01 containerd[30050]: time=”2022-05-12T22:59:19.154755704-04:00” level=info msg=serving… address=/run/containerd/containerd.sock
- 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在我们解压包中已经附带了,直接可以使用
- [root@k8s-01~]# ctr version
- Client:#ctr版本号
- Version: v1.6.4
- Revision:212e8b6fa2f44b9c21b2798135fc6fb7c53efc16
- Go version: go1.17.9
- Server:
- Version: v1.6.4#containerd版本号
- Revision:212e8b6fa2f44b9c21b2798135fc6fb7c53efc16
- UUID: b376d7b6-c97e-4b39-8144-9624ade3ba84
可以使用下面命令查看containerd版本号
- [root@k8s-01~]# containerd —version
containerd github.com/containerd/containerd v1.6.4212e8b6fa2f44b9c21b2798135fc6fb7c53efc16
api-server 高可用部署 (单master可跳过)
nginx代理后端3台apiserver,所以需要在每台apiserver中安装nginx。keeplived起到vip的作用
需要在master节点安装首先我们在原有的基础上添加一个host,只需要在master节点上执行即可
- cat >>/etc/hosts<< EOF
- 192.168.31.10 k8s-master-01
- 192.168.31.11 k8s-master-02
- 192.168.31.12 k8s-master-03
- 192.168.31.111 apiserver.frps.cn
- EOF
安装nginx
为了方便后面扩展插件,我这里使用编译安装nginx
编译安装nginx
安装依赖
- yum install pcre pcre-devel openssl openssl-devel gcc gcc-c++ automake autoconf libtool make wget vim lrzsz -y
- wget https://nginx.org/download/nginx-1.20.2.tar.gz
- tar xf nginx-1.20.2.tar.gz
- cd nginx-1.20.2/
- useradd nginx -s /sbin/nologin -M
- ./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
- make && make install
使用systemctl管理,并设置开机启动
- cat >/usr/lib/systemd/system/nginx.service<<EOF
/usr/lib/systemd/system/nginx.service
- [Unit]
- Description=The nginx HTTP and reverse proxy server
- After=network.target sshd-keygen.service
- [Service]
- Type=forking
- EnvironmentFile=/etc/sysconfig/sshd
- ExecStartPre=/opt/nginx/sbin/nginx -t -c /opt/nginx/conf/nginx.conf
- ExecStart=/opt/nginx/sbin/nginx -c /opt/nginx/conf/nginx.conf
- ExecReload=/opt/nginx/sbin/nginx -s reload
- ExecStop=/opt/nginx/sbin/nginx -s stop
- Restart=on-failure
- RestartSec=42s
- [Install]
- WantedBy=multi-user.target
- EOF
开机启动
- [root@k8s-01 nginx-1.20.2]# systemctl enable nginx —now
- Created symlink from/etc/systemd/system/multi-user.target.wants/nginx.service to /usr/lib/systemd/system/nginx.service.
yum安装nginx
- yum install nginx -y
yum安装nginx需要注意下面的配置文件路径就是/etc/nginx/conf/nginx.conf
检查服务是否启动
- [root@k8s-01 nginx-1.20.2]# ps -ef|grep nginx
- root 840401020:15?00:00:00 nginx: master process /opt/nginx/sbin/nginx -c /opt/nginx/conf/nginx.conf
- nobody 8404184040020:15?00:00:00 nginx: worker process
- root 8404451752020:16 pts/000:00:00 grep —color=auto nginx
修改nginx配置文件
- vim nginx.conf
- user nginx nginx;
- worker_processes auto;
- events {
- worker_connections 20240;
- use epoll;
- }
- error_log /var/log/nginx_error.log info;
- stream {
- upstream kube-servers {
- hash $remote_addr consistent;
- server k8s-master-01:6443 weight=5 max_fails=1 fail_timeout=3s;#这里可以写IP
- server k8s-master-02:6443 weight=5 max_fails=1 fail_timeout=3s;
- server k8s-master-03:6443 weight=5 max_fails=1 fail_timeout=3s;
- }
- server {
- listen 8443 reuseport;
- proxy_connect_timeout 3s;
加大timeout
- proxy_timeout 3000s;
- proxy_pass kube-servers;
- }
- }
分发到其它master节点
- for i in k8s-02 k8s-03
- do
- scp nginx.conf root@$i:/opt/nginx/conf/
- ssh root@$i systemctl restart nginx
- done
配置Keeplived
前面我们也说了,高可用方案需要一个VIP,供集群内部访问
修改配置文件
- router_id 节点IP
- mcast_src_ip 节点IP
- virtual_ipaddress VIP
请根据自己IP实际上情况修改
- cat >/etc/keepalived/keepalived.conf <<EOF
- !ConfigurationFilefor keepalived
- global_defs {
- router_id 192.168.31.10#节点ip,master每个节点配置自己的IP
- }
- vrrp_script chk_nginx {
- script “/etc/keepalived/check_port.sh 8443”
- interval 2
- weight -20
- }
- vrrp_instance VI_1 {
- state MASTER
- interface eth0
- virtual_router_id 251
- priority 100
- advert_int 1
- mcast_src_ip 192.168.31.10#节点IP
- nopreempt
- authentication {
- auth_type PASS
- auth_pass 11111111
- }
- track_script {
- chk_nginx
- }
- virtual_ipaddress {
- 192.168.31.111#VIP
- }
- }
- EOF
编写健康检查脚本
- vim /etc/keepalived/check_port.sh
- CHK_PORT=$1
- if[-n “$CHK_PORT”];then
- PORT_PROCESS=
ss -lt|grep $CHK_PORT|wc -l - if[ $PORT_PROCESS -eq 0];then
- echo “Port $CHK_PORT Is Not Used,End.”
- exit1
- fi
- else
- echo “Check Port Cant Be Empty!”
- fi
启动keepalived
systemctl enable —now keepalived
测试vip是否正常
ping vip
ping apiserver.frps.cn #我们的域名
Kubeadm 安装配置
首先我们需要在k8s-01配置kubeadm源
下面kubeadm操作只需要在k8s-01上即可
国内源
packages.cloud.google.com这里懂的都懂,下面改成阿里云源
- cat <
/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
官方文档推荐源
- cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
- [kubernetes]
- name=Kubernetes
- baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-$basearch
- enabled=1
- gpgcheck=1
- repo_gpgcheck=1
- gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
- exclude=kubelet kubeadm kubectl
- 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来工具来进行管理。
因为我这里要做集群,请根据我这里的配置按需修改
- [root@k8s-01~]# cat kubeadm-init.yaml
- apiVersion: kubeadm.k8s.io/v1beta3
- bootstrapTokens:
- groups:
- system:bootstrappers:kubeadm:default-node-token
- token: abcdef.0123456789abcdef
- ttl:24h0m0s
- usages:
- signing
- authentication
- kind:InitConfiguration
- localAPIEndpoint:
- advertiseAddress:192.168.31.10#k8s-01 ip地址
- bindPort:6443
- nodeRegistration:
- criSocket: unix:///var/run/containerd/containerd.sock
- imagePullPolicy:IfNotPresent
- name: k8s-01
- taints:null
- apiServer:
- timeoutForControlPlane:4m0s
- apiVersion: kubeadm.k8s.io/v1beta3
- certificatesDir:/etc/kubernetes/pki
- clusterName: kubernetes
- controllerManager:{}
- dns:{}
- etcd:
- local:
- dataDir:/var/lib/etcd
- imageRepository: k8s.gcr.io
- kind:ClusterConfiguration
- kubernetesVersion:1.24.0
- controlPlaneEndpoint: apiserver.frps.cn:8443#高可用地址,我这里填写vip
- networking:
- dnsDomain: cluster.local
- serviceSubnet:10.96.0.0/12
- podSubnet:10.244.0.0/16
- scheduler:{}
- apiVersion: kubeproxy.config.k8s.io/v1alpha1
- kind:KubeProxyConfiguration
- mode: ipvs # kube-proxy 模式
- apiVersion: kubelet.config.k8s.io/v1beta1
- authentication:
- anonymous:
- enabled:false
- webhook:
- cacheTTL:0s
- enabled:true
- x509:
- clientCAFile:/etc/kubernetes/pki/ca.crt
- authorization:
- mode:Webhook
- webhook:
- cacheAuthorizedTTL:0s
- cacheUnauthorizedTTL:0s
- clusterDNS:
- -10.96.0.10
- clusterDomain: cluster.local
- cpuManagerReconcilePeriod:0s
- evictionPressureTransitionPeriod:0s
- fileCheckFrequency:0s
- healthzBindAddress:127.0.0.1
- healthzPort:10248
- httpCheckFrequency:0s
- imageMinimumGCAge:0s
- kind:KubeletConfiguration
- cgroupDriver: systemd # 配置 cgroup driver
- logging:{}
- memorySwap:{}
- nodeStatusReportFrequency:0s
- nodeStatusUpdateFrequency:0s
- rotateCertificates:true
- runtimeRequestTimeout:0s
- shutdownGracePeriod:0s
- shutdownGracePeriodCriticalPods:0s
- staticPodPath:/etc/kubernetes/manifests
- streamingConnectionIdleTimeout:0s
- syncFrequency:0s
- volumeStatsAggPeriod:0s
检查配置文件是否有错误
[root@k8s-01 ~]# kubeadm init —config kubeadm-init.yaml —dry-run
正确如下
预先拉取镜像
- [root@k8s-01~]# kubeadm config images list —config kubeadm-init.yaml
- k8s.gcr.io/kube-apiserver:v1.24.0
- k8s.gcr.io/kube-controller-manager:v1.24.0
- k8s.gcr.io/kube-scheduler:v1.24.0
- k8s.gcr.io/kube-proxy:v1.24.0
- k8s.gcr.io/pause:3.7
- k8s.gcr.io/etcd:3.5.3-0
- k8s.gcr.io/coredns/coredns:v1.8.6
提前下载镜像导入,默认情况使用的是k8s.gcr.io,这个镜像地址我们无法pull,所以使用导入的方式
- wget https://d.frps.cn/file/kubernetes/image/k8s_all_1.24.tar
拷贝到其它节点
- for i in k8s-02 k8s-03 k8s-04 k8s-05;do
- scp k8s_all_1.24.tar root@$i:/root/
- ssh root@$i ctr -n k8s.io i import k8s_all_1.24.tar
- done
检查
- [root@k8s-01~]# ctr -n k8s.io i ls -q
- k8s.gcr.io/coredns/coredns:v1.8.6
- k8s.gcr.io/etcd:3.5.3-0
- k8s.gcr.io/kube-apiserver:v1.24.0
- k8s.gcr.io/kube-controller-manager:v1.24.0
- k8s.gcr.io/kube-proxy:v1.24.0
- k8s.gcr.io/kube-scheduler:v1.24.0
-
Kubectl 安装
这一步可以省略,可以通过后续yum安装,这一步可以忽略
kubeadm不会安装或管理kubelet,kubectl因此需要确保它们kubeadm和Kubernetes版本相匹配。如果不这样,则存在版本偏差的风险。但是,支持kubelet和k8s之间的一个小版本偏差,但kubelet版本可能永远不会超过API Server版本 下载1.24.0 kubectl工具
- [root@k8s-01~]# curl -LO https://dl.k8s.io/release/v1.24.0/bin/linux/amd64/kubectl
- [root@k8s-01~]# chmod +x kubectl && mv kubectl /usr/local/bin/
检查kubectl工具版本号
- [root@k8s-01~]# kubectl version —client —output=yaml
- clientVersion:
- buildDate:”2022-05-03T13:46:05Z”
- compiler: gc
- gitCommit:4ce5a8954017644c5420bae81d72b09b735c21f0
- gitTreeState: clean
- gitVersion: v1.24.0
- goVersion: go1.18.1
- major:”1”
- minor:”24”
- platform: linux/amd64
- kustomizeVersion: v4.5.4
拷贝kubectl到其它master节点
- for i in k8s-02 k8s-03;do
- scp /usr/local/bin/kubectl root@$i:/usr/local/bin/kubectl
- ssh root@$i chmod +x /usr/local/bin/kubectl
- done
接下来开始初始化
[root@k8s-01 ~]# kubeadm init —config kubeadm-init.yaml —upload-certs
初始化过程
初始化完成
记住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组件
- cat <
/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 install -y kubelet-1.24.0 kubeadm-1.24.0 kubectl-1.24.0 —disableexcludes=kubernetes
启动kubelet
systemctl enable —now kubelet
master执行添加节点
- kubeadm join apiserver.frps.cn:8443—token abcdef.0123456789abcdef
- —discovery-token-ca-cert-hash sha256:a54c17e514edba57226f969268227b749d8bfb8802ae99112e08cbcabcd22ae0
- —control-plane —certificate-key f7b0eb9c7e0aac2c95eef083c591950109434250a6df9cc0dc1ec9fb04461250
设置kubectl config文件
- mkdir -p $HOME/.kube
- sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
- sudo chown $(id -u):$(id -g) $HOME/.kube/config
目前我们3台master节点已经添加完毕
- [root@k8s-02~]# kubectl get node
- NAME STATUS ROLES AGE VERSION
- k8s-01Ready control-plane 15m v1.24.0
- k8s-02Ready control-plane 6m25s v1.24.0
k8s-03Ready control-plane 14m v1.24.0
Node节点配置
node节点安装kubeadm
cat <
/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 install -y kubeadm-1.24.0 —disableexcludes=kubernetes
添加join命令
- kubeadm join apiserver.frps.cn:8443—token abcdef.0123456789abcdef
- —discovery-token-ca-cert-hash sha256:a54c17e514edba57226f969268227b749d8bfb8802ae99112e08cbcabcd22ae0
如果我们后续需要添加node节点时,可以到k8s-01节点执行下面的命令获取token相关信息
- [root@k8s-01~]# kubeadm token create —print-join-command
- kubeadm join apiserver.frps.cn:8443—token sgvcen.qf87ykht9gopqe0d —discovery-token-ca-cert-hash sha256:f535fdf0af19022a30760fd5069c648019a3f4b4828bfb2eb566224d76d21647
如果我们添加某台节点异常了,修改后可以执行下面的命令,然后在重新join加入集群
kubeadm reset
验证所有服务器是否添加到集群中
- [root@k8s-01~]# kubectl get node -o wide
- NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
- k8s-01Ready control-plane 22m v1.24.0192.168.31.10
CentOSLinux7(Core)5.17.8-1.el7.elrepo.x86_64 containerd://1.6.4 - k8s-02Ready control-plane 13m v1.24.0192.168.31.11
CentOSLinux7(Core)5.17.8-1.el7.elrepo.x86_64 containerd://1.6.4 - k8s-03Ready control-plane 21m v1.24.0192.168.31.12
CentOSLinux7(Core)5.17.8-1.el7.elrepo.x86_64 containerd://1.6.4 - k8s-04Ready
107s v1.24.0192.168.31.13 CentOSLinux7(Core)5.17.8-1.el7.elrepo.x86_64 containerd://1.6.4 k8s-05Ready
6m6s v1.24.0192.168.31.14 CentOSLinux7(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为主containers:
- name: kube-flannel
- image: quay.io/coreos/flannel:v0.12.0-amd64
- command:
- -/opt/bin/flanneld
- args:
- —-ip-masq
- —-kube-subnet-mgr
- —-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 这个插件。
- mv /etc/cni/net.d/10-containerd-net.conflist /etc/cni/net.d/10-containerd-net.conflist.bak
- ifconfig cni0 down && ip link delete cni0
- systemctl daemon-reload
- systemctl restart containerd kubelet
验证集群
等kube-system命名空间下的Pod都为Running,这里先测试一下dns是否正常
- cat<<EOF | kubectl apply -f -
- apiVersion: apps/v1
- kind:Deployment
- metadata:
- name: nginx
- spec:
- selector:
- matchLabels:
- app: nginx
- template:
- metadata:
- labels:
- app: nginx
- spec:
- containers:
- image: nginx:alpine
- name: nginx
- ports:
- containerPort:80
- apiVersion: v1
- kind:Service
- metadata:
- name: nginx
- spec:
- selector:
- app: nginx
- type:NodePort
- ports:
- protocol: TCP
- port:80
- targetPort:80
- nodePort:30001
- apiVersion: v1
- kind:Pod
- metadata:
- name: busybox
- namespace:default
- spec:
- containers:
- name: busybox
- image: abcdocker9/centos:v1
- command:
- sleep
- -“3600”
- imagePullPolicy:IfNotPresent
- restartPolicy:Always
- EOF
创建后Pod我们进行检查
使用nslookup查看是否能返回地址
- [root@k8s-01~]# kubectl exec-ti busybox — nslookup kubernetes
- Server:10.96.0.10
- Address:10.96.0.10#53
- Name: kubernetes.default.svc.cluster.local
- Address:10.96.0.1
测试nginx svc以及Pod内部网络通信是否正常
- for i in k8s-01 k8s-02 k8s-03 k8s-04 k8s-05
- do
- ssh root@$i curl -s 10.99.209.220#nginx svc ip
- ssh root@$i curl -s 10.244.3.4#pod ip
- done
