> 技术文档 > 真实企业k8s全网最详细升级

真实企业k8s全网最详细升级


主机角色

地址

master01 nginx+keepalibed

192.168.20.102

master02nginx+keepalibed

192.168.20.103

master03nginx+keepalibed

192.168.20.104

node01

192.168.20.105

# 1、修改主机名hostnamectl set-hostname k8s-master01hostnamectl set-hostname k8s-master02hostnamectl set-hostname k8s-master03hostnamectl set-hostname k8s-node01# 2、三台机器添加host解析cat >> /etc/hosts << \"EOF\"192.168.20.101 k8s-master01192.168.20.102 k8s-master02192.168.20.103 k8s-master03192.168.20.104 k8s-node01192.168.20.200 api-serverEOF

关闭一些服务

# 1、关闭selinuxsed -i \'s#enforcing#disabled#g\' /etc/selinux/configsetenforce 0 # 2、禁用防火墙,网络管理,邮箱systemctl disable --now firewalld NetworkManager postfix # 3、关闭swap分区swapoff -a ​# 注释swap分区cp /etc/fstab /etc/fstab_baksed -i \'/swap/d\' /etc/fstab

sshd优化

# 1、加速访问sed -ri \'s@^#UseDNS yes@UseDNS no@g\' /etc/ssh/sshd_config sed -ri \'s#^GSSAPIAuthentication yes#GSSAPIAuthentication no#g\' /etc/ssh/sshd_config grep ^UseDNS /etc/ssh/sshd_config grep ^GSSAPIAuthentication /etc/ssh/sshd_configsystemctl restart sshd # 2、密钥登录(主机点做):为了让后续一些远程拷贝操作更方便ssh-keygenssh-copy-id -i root@k8s-master-01ssh-copy-id -i root@k8s-node-01ssh-copy-id -i root@k8s-node-02

增大文件打开数量

cat > /etc/security/limits.d/k8s.conf <<\'EOF\' * soft nofile 65535 * hard nofile 131070 EOF ulimit -Sn ulimit -Hn

所有节点配置模块自动加载,此步骤不做的话(kubeadm init直接失败)

modprobe br_netfiltermodprobe ip_conntrackcat >>/etc/rc.sysinit</etc/sysconfig/modules/br_netfilter.modulesecho \"modprobe ip_conntrack\" >/etc/sysconfig/modules/ip_conntrack.moduleschmod 755 /etc/sysconfig/modules/br_netfilter.moduleschmod 755 /etc/sysconfig/modules/ip_conntrack.moduleslsmod | grep br_netfilter
# =====================》chrony服务端:服务端我们可以自己搭建,也可以直接用公网上的时间服务器,所以是否部署服务端看你自己# 1、安装yum -y install chrony​# 2、修改配置文件mv /etc/chrony.conf /etc/chrony.conf.bak​cat > /etc/chrony.conf < /etc/chrony.conf << EOFserver 192.168.20.101 iburstdriftfile /var/lib/chrony/driftmakestep 10 3rtcsynclocal stratum 10keyfile /etc/chrony.keylogdir /var/log/chronystratumweight 0.05noclientloglogchange 0.5 EOF# 3、启动chronydsystemctl restart chronyd.servicesystemctl enable chronyd.servicesystemctl status chronyd.service # 4、验证chronyc sources -v

更新yum源

# 1、清理rm -rf /etc/yum.repos.d/*yum remove epel-release -yrm -rf /var/cache/yum/x86_64/6/epel/ # 2、安装阿里的base与epel源curl -s -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo curl -s -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repoyum clean all;yum makecache # 或者用华为的也行# curl -o /etc/yum.repos.d/CentOS-Base.repo https://repo.huaweicloud.com/repository/conf/CentOS-7-reg.repo # yum install -y https://repo.huaweicloud.com/epel/epel-release-latest-7.noarch.rpm

更新系统内核

 yum update -y --exclud=kernel*

安装基础常用软件

yum -y install expect wget jq psmisc vim net-tools telnet yum-utils device-mapper-persistent-data lvm2 git ntpdate chrony bind-utils rsync unzip git bash-comepletion
[root@localhost ~]# cat /etc/redhat-releaseCentOS Linux release 7.9.2009 (Core)[root@localhost ~]# unaunalias uname[root@localhost ~]# uname -r3.10.0-1160.71.1.el7.x86_64

三个节点操作

 #安装yum localinstall -y /root/kernel-lt* #调到默认启动grub2-set-default 0 && grub2-mkconfig -o /etc/grub2.cfg #查看当前默认启动的内核grubby --default-kernel #重启系统reboot

三个节点安装ipvs

# 1、安装ipvsadm等相关工具yum -y install ipvsadm ipset sysstat conntrack libseccomp # 2、配置加载cat > /etc/sysconfig/modules/ipvs.modules < /dev/null 2>&1 if [ $? -eq 0 ]; then /sbin/modprobe ${kernel_module} fi done EOF chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep ip_vs

安装 containerd(三台节点都要做)

制这里

rpm -e libseccomp-2.3.1-4.el7.x86_64 --nodeps先卸载wget https://mirrors.aliyun.com/centos/8/BaseOS/x86_64/os/Packages/libseccomp-2.5.1-1.el8.x86_64.rpmrpm -ivh libseccomp-2.5.1-1.el8.x86_64.rpm

cd /etc/yum.repos.dwget http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo yum install containerd* -y

复制这里

mkdir -pv /etc/containerdcontainerd config default > /etc/containerd/config.toml替换默认pause镜像地址:这一步很重要grep sandbox_image /etc/containerd/config.tomlsed -i \'s/registry.k8s.io/registry.cn-hangzhou.ailiyuncs.com\\/google_containers/\' /etc/containerd/config.tomlgrep sandbox_image /etc/containerd/config.toml请务必确认新地址是否可用:sandbox_image=\"registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.6\"配置systemd作为容器的cgroup drivergrep SystemdCgroup /etc/containerd/config.tomlsed -i \'s/SystemdCgroup \\= false/SystemdCgroup \\=true/\' /etc/containerd/config.tomlgrep SystemdCgroup /etc/containerd/config.toml配置加速器(必须配置,不然后续安装cni插件无法从不docker。io下载)sed -i \'s/config_path\\ =.*/config_path = \\\"\\/etc\\/containerd\\/certs.d\\\"/g\' /etc/containerd/config.toml
mkdir -p /etc/containerd/certs.d/docker.iocat > /etc/containerd/certs.d/docker.io/hosts.toml << EOFserver = \"https://docker.io\"[host.\"https://dockerproxy.com\"]capabilities = [\"pull\", \"resolve\"][host.\"https://docker.m.daocloud.io\"]capabilities = [\"pull\", \"resolve\"][host.\"https://docker.agsv.top\"]capabilities = [\"pull\", \"resolve\"][host.\"https://registry.docker-cn.com\"]capabilities = [\"pull\", \"resolve\"]EOF

配置开机自启动conrainerd

systemctl daemon-reload && systemctl restart containerdsystemctl enable --now containerdsystemctl status containerd

测试拉取没问题

ctr image pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.9

安装keepalibed加nginx

# 1、添加repo源cat > /etc/yum.repos.d/nginx.repo < /etc/nginx/nginx.conf <<\'EOF\' 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-master01:6443 weight=5 max_fails=1 fail_timeout=3s; server k8s-master02:6443 weight=5 max_fails=1 fail_timeout=3s; server k8s-master03:6443 weight=5 max_fails=1 fail_timeout=3s; } server { listen 8443 reuseport; # 监听8443端口proxy_connect_timeout 3s; proxy_timeout 3000s; proxy_pass kube-servers; } } EOF # 4、启动systemctl restart nginx systemctl enable nginx systemctl status nginx

三台部署master部署keepalived

yum -y install keepalived

修改keepalive的配置文件(根据实际环境,interface eth0可能需要修改为interface ens33)

 # 编写配置文件,各个master节点需要修改router_id和mcast_src_ip的值即可。 # ==================================> master01 cat > /etc/keepalived/keepalived.conf < master02 cat > /etc/keepalived/keepalived.conf < master03 cat > /etc/keepalived/keepalived.conf <<EOF ! Configuration File for keepalived global_defs { router_id 192.168.20.103 } vrrp_script chk_nginx { script \"/etc/keepalived/check_port.sh 8443\" interval 2 weight -20 } vrrp_instance VI_1 { state BACKUP interface ens36 virtual_router_id 100 priority 100 advert_int 1 mcast_src_ip 192.168.20.103 # nopreempt # 这行注释掉,否则即使一个具有更高优先级的备份节点出现,当前的 MASTER 也不会被抢占,直至 MASTER 失效。authentication { auth_type PASS auth_pass 11111111 } track_script { chk_nginx } virtual_ipaddress { 192.168.20.200 } } EOF

所有master节点上创建健康检查脚本

 vim /etc/keepalived/check_port.sh#!/bin/bash# 设置环境变量,确保所有必要的命令路径正确PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binCHK_PORT=$1if [ -n \"$CHK_PORT\" ]; then PORT_PROCESS=$(/usr/sbin/ss -lt | grep \":$CHK_PORT\" | wc -l) if [ $PORT_PROCESS -eq 0 ]; then echo \"Port $CHK_PORT Is Not Used,End.\" exit 1 fielse echo \"Check Port Cant Be Empty!\" exit 1fi

启动

systemctl restart keepalived systemctl enable keepalived systemctl status keepalived 
动态查看keepalived日志 journalctl -u keepalived -f

安装k8s的管理工具

降本增效

三台机器准备k8s源

cat > /etc/yum.repos.d/kubernetes.repo << \"EOF\"[kubernetes]name=Kubernetesbaseurl=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.30/rpm/enabled=1gpgcheck=1gpgkey=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.30/rpm/repodata/repomd.xml.keyEOFyum install -y kubelet-1.30* kubeadm-1.30* kubectl-1.30*systemctl enable kubelet && systemctl start kubelet && systemctl status kubelet

主节点操作(node节点不执行)

仅在master节点执行kubeadm config images list

kubeadm config print init-defaults > kubeadm.yaml
apiVersion: kubeadm.k8s.io/v1beta3kind: InitConfigurationbootstrapTokens:- groups:- system:bootstrappers:kubeadm:default-node-tokentoken: abcdef.0123456789abcdefttl: 24h0m0susages:- signing- authenticationlocalAPIEndpoint:advertiseAddress: 0.0.0.0bindPort: 6443nodeRegistration:criSocket: unix:///var/run/containerd/containerd.sockimagePullPolicy: IfNotPresentname: k8s-master01taints: null---apiVersion: kubeadm.k8s.io/v1beta3kind: ClusterConfigurationapiServer:timeoutForControlPlane: 4m0scertificatesDir: /etc/kubernetes/pkiclusterName: kubernetescontrollerManager: {}dns: {}etcd:local:dataDir: /var/lib/etcdimageRepository: registry.cn-hangzhou.aliyuncs.com/google_containerskubernetesVersion: 1.30.3networking:dnsDomain: cluster.localserviceSubnet: 10.96.0.0/12podSubnet: 10.244.0.0/16scheduler: {}---apiVersion: kubeproxy.config.k8s.io/v1alpha1kind: KubeProxyConfigurationmode: ipvs---apiVersion: kubelet.config.k8s.io/v1beta1kind: KubeletConfigurationcgroupDriver: systemd

多个master节点加入集群

上传证书

将集群控制平面所需的证书上传到集群中,并存储在一个叫做 kubeadm-certs 的 Secret 中
root@master01 ~]# kubeadm init phase upload-certs --upload-certs # 你也可以在安装的时候kubeadm init的默认加上选项--upload-certs来上传证书,那这一步就不需要了输出结果... [upload-certs] Using certificate key: 75fb3ae07478f5777b187e45cd5e85cdf9f3bd8dbeeaf5919416e9022b394dea # 得到该值,后续添加master需要用到它
上述指令做了3件事1. 上传证书到集群:将已经生成的控制平面证书上传到 Kubernetes 集群,使得这些证书可以在多个 Master 节点之间共享。 2. 生成证书密钥:生成一个唯一的密钥用于加密和保护这些证书。3. 输出证书密钥:在终端输出这个证书密钥,后续添加新的 Master 节点时需要使用。上述指令目的是:方便其他 Master 节点在加入集群时能够共享这些证书。这个步骤极大简化了多 Master 节点的配置过程,确保所有 Master 节点使用相同的证书。是否一定要做这一步?不一定。如果你没有这一步骤,那么每一个新加入的 Master 节点会自己生成一份新的证书,这样可能导致集群内的证书不一致,增加管理复杂度。使用 kubeadm init phase upload-certs -- upload-certs 可以确保所有控制平面节点使用相同的证书,简化管理并且提高安全性和一致性。因此,尽管这一步不是绝对必要的,但强烈推荐使用它。
(2)添加master节点到集群 所有master节点加入集群,需要用到上面的token信息,需要使用\"--certificate-key\"选项指定。(你的环境要替换!)master02节点上
kubeadm join 192.168.20.101:6443 --token abcdef.0123456789abcdef \\--discovery-token-ca-cert-hash sha256:ce75317e5c7b888e761adbdbbc10bae617add4f420996f243bb980f5265ceb95 \\--control-plane \\--certificate-key 12124c6c0ae362a19a73eae3b60b6315fdf73fbb0e3c16610a9a970306c86f97 

yaml文件拉起集群

kubeadm init --config=kubeadm.yaml --ignore-preflight-errors=SystemVerification --ignore-preflight-errors=Swapmkdir -p $HOME/.kubesudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/configsudo chown $(id -u):$(id -g) $HOME/.kube/config#~/.kube/config 是 kubectl 的配置文件,里面包含了访问 Kubernetes 集群所需的身份信息、API Server 地址、证书等内容。#没有这个文件是访问不到api server的,scp拷贝到node节点scp -r /root/.kube root@worker01:/root/scp -r /root/.kube root@worker02:/root/#可选echo \"export KUBECONFIG=/etc/kubernetes/admin.conf\" >> vi /etc/profilesource /etc/profile#自动补齐命令source <(kubectl completion bash) # set up autocomplete in bash into the current shell, bash-completion package should be installed first.echo \"source > ~/.bashrc # add autocomplete permanently to your bash shell.alias k=kubectlcomplete -o default -F __start_kubectl k#持久化生效echo \"alias k=kubectl\" >> ~/.bashrcecho \"complete -o default -F __start_kubectl k\" >> ~/.bashrc

master加入集群

kubeadm join api-server:8443 --token abcdef.0123456789abcdef \\ --discovery-token-ca-cert-hash sha256:25791614a45d7b9acdaf8b3ccce172340f47a2be67adf095848b0c19d4f6a854 \\ --control-plane \\ --certificate-key 1d1649f3ac26e27034cbabe8f818526157414c262abcf67c0716abb514fdf40b 

node加入集群

kubeadm join 192.168.68.110:6443 --token abcdef.0123456789abcdef \\ --discovery-token-ca-cert-hash sha256:ba98a530c894883ad7e6a22056e2e163db26b25571a8187a2b2c9c10163b6155 

安装网络插件

wget https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.ymlgrep -i image kube-flannel.yml #查看flannel版本[root@master01 flannel]# vim kube-flannel.yml apiVersion: v1data: ... net-conf.json: | { \"Network\": \"10.244.0.0/16\", # 与--pod-network-cidr保持一致 \"Backend\": { \"Type\": \"vxlan\" } }
阿里云镜像
grep -i image kube-flannel.yml #查看flannel版本和镜像,一共有三个镜像 image: ghcr.io/flannel-io/flannel:v0.26.7 image: ghcr.io/flannel-io/flannel-cni-plugin:v1.6.2-flannel1#这两个个镜像在国内用阿里云的容器镜像服务做一个镜像仓库得到两个地址#registry.cn-shanghai.aliyuncs.com/egon-k8s-test/flannel:v0.26.7#registry.cn-shanghai.aliyuncs.com/egon-k8s-test/flannel-cni-plugin:v1.6.2-flannel1#然后修改flannel.yml里的镜像地址

安装时错误的解决方法

kubeadm reset -frm -rf ~/.kube/rm -rf /etc/kubernetes/rm -rf /etc/cnirm -rf /opt/cnirm -rf /var/lib/etcdrm -rf /var/etcd 选做项yum clean allyum remove kube*rm -rf /etc/systemd/system/kubelet.service.drm -rf /etc/systemd/system/kubelet.servicerm -rf /usr/bin/kube*

etcd使用(补充)

补充:etcdctl的官网下载地址:https://github.com/etcd-io/etcd/releasesETCDCTL_API=3 etcdctl \\--endpoints=https://192.168.71.103:2379,https://192.168.71.101:2379,https://192.168.71.102:2379 \\--cacert=/etc/kubernetes/pki/etcd/ca.crt \\--cert=/etc/kubernetes/pki/etcd/server.crt \\--key=/etc/kubernetes/pki/etcd/server.key \\member listETCDCTL_API=3 etcdctl \\--endpoints=https://127.0.0.1:2379 \\--cacert=/etc/kubernetes/pki/etcd/ca.crt \\--cert=/etc/kubernetes/pki/etcd/server.crt \\--key=/etc/kubernetes/pki/etcd/server.key \\member listETCDCTL_API=3 etcdctl \\--endpoints=https://127.0.0.1:2379 \\--cacert=/etc/kubernetes/pki/etcd/ca.crt \\--cert=/etc/kubernetes/pki/etcd/server.crt \\--key=/etc/kubernetes/pki/etcd/server.key \\get / --prefix --keys-onlyETCDCTL_API=3 etcdctl \\--endpoints=https://127.0.0.1:2379 \\--cacert=/etc/kubernetes/pki/etcd/ca.crt \\--cert=/etc/kubernetes/pki/etcd/server.crt \\--key=/etc/kubernetes/pki/etcd/server.key \\get /registry/deployments/default/mynginxetcd数据中存放的不是json原文,而是protocol buffer序列化之后的数据二、k8s版本升级方案与实践(1.31.0)(******)背景:k8s没有一个LTS长期稳定版本注意:1、升级前最好备份所有组件及数据---》etcd(/var/lib/etcd)ETCDCTL_API=3 etcdctl \\--endpoints=https://127.0.0.1:2379 \\--cacert=/etc/kubernetes/pki/etcd/ca.crt \\--cert=/etc/kubernetes/pki/etcd/server.crt \\--key=/etc/kubernetes/pki/etcd/server.key \\snapshot save etcdbackupfile.db # 把当前节点的etcd数据导出为快照mv /var/lib/etcd /var/lib/etcd_bakmkdir /var/lib/etcdETCDCTL_API=3 etcdctl \\--endpoints=https://127.0.0.1:2379 \\--cacert=/etc/kubernetes/pki/etcd/ca.crt \\--cert=/etc/kubernetes/pki/etcd/server.crt \\--key=/etc/kubernetes/pki/etcd/server.key \\snapshot restore etcdbackupfile.db --data-dir=/var/lib/etcd

升级方案

背景:k8s没有一个LTS长期稳定版本
(1)升级前最好备份所有组件及数据,例如etcd(2)不要跨两个大版本进行升级,可能会存在版本bug,如:1.19.4-->1.20.4 通常ok 1.19.4-->1.21.4 慎重跨多个版本的可以逐个版本依次进行升级,因为下一个版本通常会考虑到针对上一个版本的升级兼容性例如1.19.4-->1.21.4 可以先从1.19.4 升级到1.20.4然后再从1.20.4 升级到 1.21.4(3)升级前要在测试环境进行充分的演练,充分考虑到回滚方案(事先将回滚动作制作成脚本,方便生产环境遇到问题时快速响应)

前提注意(etcd备份)

注意:1、升级前最好备份所有组件及数据---》etcd(/var/lib/etcd)ETCDCTL_API=3 etcdctl \\--endpoints=https://127.0.0.1:2379 \\--cacert=/etc/kubernetes/pki/etcd/ca.crt \\--cert=/etc/kubernetes/pki/etcd/server.crt \\--key=/etc/kubernetes/pki/etcd/server.key \\snapshot save etcdbackupfile.db # 把当前节点的etcd数据导出为快照

升级方案

对于线上环境,升级k8s需要做到不中断当前业务容器的灰度升级,常见方案有如下两种(1)方案一:蓝绿方式仿照现有k8s集群,部署一套新环境,在新环境里部署指定版本的k8s,然后把业务应用也部署到新环境。然后将流量切换到新环境(2)方案二:先更新master上的k8s服务版本,再逐个批量更新Node上的k8s服务版本(高版本的master通常可以管理更低版本的node,但版本差异过大也会有问题)蓝绿的方式没啥没说的(就是部署一套全新环境,然后切流量即可),我们直接看方案二吧

我主要安装k8s的方案二,针对kubeadm方式升级

1

为了考虑到资源最大化,把master节点也进行调度,污点去掉(但是不建议,为了降本增效,这里做了测试环境去做)[root@k8s-master01 ~]# kubectl taint node k8s-master01 node-role.kubernetes.io/control-plane:NoSchedule-node/k8s-master01 untainted[root@k8s-master01 ~]#kubectl taint node k8s-master02 node-role.kubernetes.io/control-plane:NoSchedule-[root@k8s-master01 ~]#kubectl taint node k8s-master03 node-role.kubernetes.io/control-plane:NoSchedule-查看[root@k8s-master01 ~]# kubectl describe node k8s-master01 | grep -i taintTaints: [root@k8s-master01 ~]# kubectl describe node k8s-master02 | grep -i taintTaints: 

升级过程中发现报错

从错误信息来看,Kubernetes 节点 k8s-master03 上的 kubelet 无法为 Pod 创建网络沙箱,原因是找不到 loopback CNI 插件

解决方案

1. 登录到问题节点

首先需要登录到 k8s-master03 节点执行后续操作:

ssh k8s-master03

2. 检查 CNI 插件目录

确认 /opt/cni/bin 目录下是否缺少 loopback 插件:

ls -l /opt/cni/bin | grep loopback

如果没有输出,说明确实缺少该插件。

3. 安装 CNI 基础插件

从官方下载并安装 CNI 基础插件包(包含 loopback 插件):

# 创建 CNI 目录(如果不存在)sudo mkdir -p /opt/cni/bin# 下载 CNI 插件包(选择合适的版本,这里使用 v1.3.0)sudo curl -L \"https://github.com/containernetworking/plugins/releases/download/v1.3.0/cni-plugins-linux-amd64-v1.3.0.tgz\" -o /tmp/cni-plugins.tgz# 解压到 /opt/cni/bin 目录sudo tar -zxvf /tmp/cni-plugins.tgz -C /opt/cni/bin# 验证 loopback 插件是否安装成功ls -l /opt/cni/bin | grep loopback

应该看到类似以下输出:

-rwxr-xr-x 1 root root 9886720 Jul 1 16:30 loopback

4. 检查 CNI 配置文件

确保 /etc/cni/net.d/ 目录下有网络配置文件(例如 Flannel、Calico 等):

ls -l /etc/cni/net.d/
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

5. 重启 kubelet 服务

sudo systemctl restart kubelet# 检查 kubelet 状态sudo systemctl status kubelet

6. 验证问题是否解决

# 在控制节点上执行kubectl get nodes k8s-master03# 检查之前失败的 Pod 是否重新创建成功kubectl get pods -A

如果仍有 Pod 处于 TerminatingPending 状态,可以尝试删除它们让 Kubernetes 重新创建:

kubectl delete pod  -n  --force --grace-period=0

检查一下我的pod服务

apiVersion: apps/v1kind: Deploymentmetadata: name: mynginxspec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx-test image: crpi-c3mxuhf0d0v0fwpq.cn-beijing.personal.cr.aliyuncs.com/wyz-123/nginx:v1 command: [\"tail\", \"-f\", \"/dev/null\"] ports: - containerPort: 80
一切正常

继续升级

配置新的yum源,版本为1.30->>>1.31

[kubernetes]name=Kubernetesbaseurl=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.31/rpm/enabled=1gpgcheck=1gpgkey=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.31/rpm/repodata/repomd.xml.key

更新

yum clean all;yum makecache

升级节点步骤综述

升级节点步骤综述 下面说的node包括master node与worker node整体顺序是:先升master再升级worker升级或更新节点步骤:(其他node节点如果要升级,则采用一样的步骤)1、先隔离Node节点的业务流量,备份好数据(如果是master节点则记着备份/var/lib/etcd目录)2、cordon禁止新pod调度到当前node # kubectl cordon node master013、对关键服务创建PDB保护策略,确保下一步的排空时,关键服务的pod至少有1个副本可用(在当前节点以外的节点上有分布)4、drain排空业务pod(静态pod不可能被排空,我们要升级的就是静态pod及kubelet等组件)5、升级当前node上的软件6、uncordon当前nod
添加PDB保护策略:(虽然我们建议一个关键的不可中断服务通常应该至少两副本,但实际情况可能不会这么规范,此时如果你们部门的小弟执行了上面的步骤排空了pod导致了过程中服务不可用这个锅就是你的了,我们可以添加PDB策略来对一些关键服务进行硬性限制,加了之后再去drain排空的时候,如果存在一些受PDB保护的应用,则会drain失败,此时会硬性要求你先扩容副本,因为你已经cordon过了,再启新副本一定是在新节点上

开始升级--升级master节点

注意在你的负载中,先把master01的负载先摘掉,业务流量别打过去

备份etcd

ETCDCTL_API=3 etcdctl \\--endpoints=https://127.0.0.1:2379 \\--cacert=/etc/kubernetes/pki/etcd/ca.crt \\--cert=/etc/kubernetes/pki/etcd/server.crt \\--key=/etc/kubernetes/pki/etcd/server.key \\snapshot save etcdbackupfile.db

还原

ETCDCTL_API=3 etcdctl \\--endpoints=https://127.0.0.1:2379 \\--cacert=/etc/kubernetes/pki/etcd/ca.crt \\--cert=/etc/kubernetes/pki/etcd/server.crt \\--key=/etc/kubernetes/pki/etcd/server.key \\snapshot restore etcdbackupfile.db --data-dir=/xxx

禁止调度了,我要升级,pod不影响,知识迁移到别的pod了

kubectl cordon k8s-master01

对关键服务创建PDB保护策略(无则略)

drain排空业务pod(静态pod不可能被排空,我们要升级的就是静态pod及kubelet等组件

kubectl drain k8s-master01 --delete-local-data --ignore-daemonsets --force

迁移i成功

静态pod没有排掉,因为我们需要升级这些

在master节点上,升级kubadm,对应版本必须一致1.31.0

 yum install -y kubeadm-1.31.0 --disableexcludes=kubernetes

看一下升级计划

kubeadm upgrade plan

问题:发现在查看计划列表的时候,版本不兼容

找到合适的版本即可

 kubectl -n kube-system set image deployment/coredns coredns=registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:v1.11.1

更新列表

kubeadm upgrade apply v1.31.0

如果是高可用还需要在其他 master 节点上执行命令:(否则会导致其上的pod无法正确启动,如果你之 前没有做过cordon排空那该节点上的pod就会处于CreateContainerConfigError状态,执行下述命令才 可以恢复正常)

kubeadm upgrade node 

在master节点上执行升级kubelet和kubectl

 yum install -y kubelet-1.31.0 kubectl-1.31.0 --disableexcludes=kubernetes

重启

systemctl daemon-reload && systemctl restart kubelet

解除可以调度

 kubectl uncordon k8s-master01

升级node节点(同理上述操作)

前提:升级节点的软件,或者是硬件例如增大内存,都会涉及到的节点的暂时不可用,这与停机维护是一个问题,我们需要考虑的核心问题是节点不可用过程中,如何确保节点上的pod服务不中断!

没权限

从k8s的master给一份

配置新的yum源,版本为1.30->>>1.31

[kubernetes]name=Kubernetesbaseurl=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.31/rpm/enabled=1gpgcheck=1gpgkey=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.31/rpm/repodata/repomd.xml.key

更新

yum clean all;yum makecache

禁止调度了,我要升级,pod不影响,知识迁移到别的pod了

kubectl cordon k8s-node01

对关键服务创建PDB保护策略(无则略)

drain排空业务pod(静态pod不可能被排空,我们要升级的就是静态pod及kubelet等组件

kubectl drain k8s-node01 --delete-local-data --ignore-daemonsets --force

在node节点上,升级kubadm,对应版本必须一致1.31.0

 yum install -y kubeadm-1.31.0 --disableexcludes=kubernetes

因为node上没有api-server这种服务就不需要kubeadm apply

kubeadm upgrade node 

在node节点上执行升级kubelet和kubectl

 yum install -y kubelet-1.31.0 kubectl-1.31.0 --disableexcludes=kubernetes

重启

systemctl daemon-reload && systemctl restart kubelet

解除可以调度

 kubectl uncordon k8s-node01