三、K8s 1.31版本安装教程手册
以一台Master主机,两台Node主机为例。
环境规划
| K8s集群角色 | IP地址 | 主机名 |
|---|---|---|
| 控制节点-Master1 | 172.25.254.10/24 | k8s-master1.kaser.org |
| 工作节点-Node1 | 172.25.254.50/24 | k8s-node1.kaser.org |
| 工作节点-Node2 | 172.25.254.60/24 | k8s-node2.kaser.org |
3.0 搭建私有Harbor私有仓库
以下Harbor仓库在RHEL9.3中完成的
bash
[root@reg ~]# systemctl disable --now firewalld
Removed "/etc/systemd/system/multi-user.target.wants/firewalld.service".
Removed "/etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service".
[root@reg ~]# getenforce
Disabled
[root@reg ~]# vim /etc/yum.repos.d/docker.repo
[docker]
name=docker
baseurl=https://mirrors.aliyun.com/docker-ce/linux/rhel/9.3/x86_64/stable/
gpgckeck=1
gpgkey=https://mirrors.aliyun.com/docker-ce/linux/rhel/gpg
[root@reg yum.repos.d]# yum makecache
[root@reg yum.repos.d]# rpm -qa | grep podman
podman-4.6.1-5.el9.x86_64
cockpit-podman-76-1.el9_3.noarch
[root@reg yum.repos.d]# rm -rf podman-4.6.1-5.el9.x86_64
[root@reg yum.repos.d]# rm -rf cockpit-podman-76-1.el9_3.noarch
# 上传所需文件
[root@reg ~]# cd /mnt/
[root@reg mnt]# ls
docker.tar.gz packages.zip
[root@reg mnt]# tar zxf docker.tar.gz
[root@reg mnt]# unzip packages.zip
[root@reg mnt]# ls
docker docker.tar.gz packages packages.zip
[root@reg mnt]# cd docker/
[root@reg docker]# yum install *.rpm
# 为确保启用 Docker 对 iptables 规则的自动管理(默认开启,写上是确保)
# 在第 15 行命令,在后面加上参数 --iptables=true
# iptables=true --> 记得加s,记得不要有空格
[root@reg docker]# vim /usr/lib/systemd/system/docker.service
15 ExecStart =/usr/bin/dockerd -H fd:// --containerd =/run/containerd/containerd.sock --iptables=true
[root@reg docker]# systemctl daemon-reload
[root@reg docker]# systemctl restart docker
bash
# 启用 Linux 内核的 IP 转发功能。
# 这是容器访问外网(或外部访问容器)的必要条件
# 必须开启,否则容器网络不通
[root@reg docker]# sysctl -a | grep ip_forward
net.ipv4.ip_forward = 1
[root@reg docker]# echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
[root@reg docker]# sysctl -p
[root@reg docker]# systemctl enable --now docker.service
[root@reg docker]# docker info
bash
# 以下除了 rhel9 不需要做,其他版本的系统建议去做
# 激活内核网络选项
]# echo br_netfilter > /etc/modules-load.d/docker_mod.conf
]# modprobe br_netfilter
]# vim /etc/sysctl.d/docker.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
]# sysctl --system
]# systemctl restart docker
bash
# 创建了证书与密钥
[root@reg ~]# mkdir -p /data/certs
[root@reg ~]# openssl req -newkey rsa:4096 \
-nodes -sha256 -keyout /data/certs/kaser.org.key \
-addext "subjectAltName = DNS: reg.kaser.org" \
-x509 -days 365 -out /data/certs/kaser.org.crt
Common Name (eg, your name or your server's hostname) []:reg.kaser.org
# 创建证书目录并部署信任证书(使 Docker 客户端信任私有仓库的 HTTPS 证书)
[root@reg ~]# mkdir -p /etc/docker/certs.d/reg.kaser.org/
[root@reg ~]# cp /data/certs/kaser.org.crt /etc/docker/certs.d/reg.kaser.org/ca.crt
[root@reg ~]# systemctl restart docker
bash
[root@reg ~]# cd /mnt/packages/
[root@reg packages]# cp -p harbor-offline-installer-v2.5.4.tgz /root
[root@reg packages]# cd
[root@reg ~]# tar zxf harbor-offline-installer-v2.5.4.tgz
[root@reg ~]# cd harbor
[root@reg harbor]# cp harbor.yml.tmpl harbor.yml
# 需要修改内容如下(如果一致,不变即可):
[root@reg harbor]# vim harbor.yml
5 hostname: reg.dhj.org
17 certificate: /data/certs/kaser.org.crt # 看自己的存放位置
18 private_key: /data/certs/kaser.org.key # 看自己的存放位置
34 harbor_admin_password: admin # 初始密码
47 data_volume: /data # 此处挂载的目录(需要跟上面证书与密钥在一个目录下)
# 根据 --help 反馈出来的参数来执行脚本时添加参数
harbor]# ./install.sh --help
[root@reg harbor]# ./install.sh --with-chartmuseum
# 将yml里面第一行的version行删去
[root@reg harbor]# vim docker-compose.yml
[root@reg harbor]# systemctl daemon-reload
[root@reg harbor]# systemctl restart docker
[root@reg harbor]# docker compose down
[root@reg harbor]# docker compose up -d
bash
# 去浏览器中去测试 172.25.254.5
bash
[root@reg ~]# cd /etc/docker/
[root@reg docker]# vim daemon.json
{
"registry-mirrors": ["https://reg.kaser.org"]
}
[root@reg docker]# systemctl restart docker
[root@reg docker]# docker logout reg.kaser.org
~]# cd harbor/
[root@reg harbor]# docker compose restart
[root@reg harbor]# docker login reg.dhj.org -uadmin -padmin
~]# docker info | grep "reg.kaser.org"
bash
# 测试是否成功:打包一个镜像并推送到私有仓库并查看是否推送成功
[root@reg ~]# docker tag alpine:latest reg.kaser.org/test/alpine:v1
[root@reg ~]# docker push reg.kaser.org/test/alpine:v1
# 查看是否上传成功!
[root@reg ~]# curl -k https://reg.kaser.org/v2/_catalog -u admin:admin
{"repositories":["test/alpine"]}
# 更激进一点测试,在终端上
[root@reg harbor]# docker rmi reg.kaser.org/test/alpine:v1
# 将本地的镜像删除之后,从Harbor上拉取,查看是否可以拉取成功
[root@reg harbor]# docker pull reg.kaser.org/test/alpine:v1
[root@reg harbor]# docker images
# v2/_catalog 是 Docker Registry API v2 版本中的一个特定端点(endpoint)
# 用于列出私有镜像仓库(Registry)中所有可用的镜像仓库名称。
# 成功即为部署完成!
bash
# 下面为将Harbor仓库部署到其余主机上去
其余主机 ~]# mkdir /etc/docker/certs.d/reg.kaser.org/ -p
[root@reg ~]# scp /etc/docker/certs.d/reg.kaser.org/ca.crt root@172.25.254.10:/etc/docker/certs.d/reg.kaser.org/ca.crt
[root@reg ~]# scp /etc/docker/certs.d/reg.kaser.org/ca.crt root@172.25.254.50:/etc/docker/certs.d/reg.kaser.org/ca.crt
[root@reg ~]# scp /etc/docker/certs.d/reg.kaser.org/ca.crt root@172.25.254.60:/etc/docker/certs.d/reg.kaser.org/ca.crt
其余主机 ~]# systemctl restart docker
其余主机 ~]# systemctl enable --now docker
# 每个主机的加速器地址等待后面docker安装完之后进行
3.1 机器初始化
3.1.1 火墙、SELinux并配置静态IP
bash
~]# nmcli c show
~]# nmcli c modify 网卡名 ipv4.method manual ipv4.addresses xxxx ipv4.gateway xxxx ipv4.dns 223.5.5.5
~]# hostnamectl set-hostname xxxx
~]# bash
~]# systemctl disable --now firewalld
~]# vi /etc/selinux/config
SELINUX=disabled
~]# reboot
附加:防火墙开启情况
bash
# 如果要开启防火墙,则需要将对应端口放行
kube-apiserver 6443
etcd 2379 2380
kube-controller-manager 10257
kube-scheduler 10259
kubelet 10250
kube-proxy 1024 -- 65535
calico TCP 179 UDP 4789 TCP 5743 UDP 4789 443
# 放开 kube-apiserver 端口 6443
sudo firewall-cmd --permanent --zone=public --add-port=6443/tcp
# 放开 etcd 端口 2379 和 2380
sudo firewall-cmd --permanent --zone=public --add-port=2379/tcp
sudo firewall-cmd --permanent --zone=public --add-port=2380/tcp
# 放开 kube-controller-manager 端口 10257
sudo firewall-cmd --permanent --zone=public --add-port=10257/tcp
# 放开 kube-scheduler 端口 10259
sudo firewall-cmd --permanent --zone=public --add-port=10259/tcp
# 放开 kubelet 端口 10250
sudo firewall-cmd --permanent --zone=public --add-port=10250/tcp
# 放开 Kube-proxy 的动态分配端口范围(TCP)
# 注意:这里假设动态端口范围为 1024 到 65535
sudo firewall-cmd --permanent --zone=public --add-port=1024-65535/tcp
# 放开 Calico 的端口
sudo firewall-cmd --permanent --zone=public --add-port=179/tcp
sudo firewall-cmd --permanent --zone=public --add-port=4789/udp
sudo firewall-cmd --permanent --zone=public --add-port=5743/tcp
sudo firewall-cmd --permanent --zone=public --add-port=443/udp
# 重新加载防火墙规则
sudo firewall-cmd --reload
# 参数说明:这些命令将端口添加到 public 区域,并使用 --permanent 标志将更改永久性保存,以便在系统重启后生效。
# 请根据你的网络配置和安全策略,适当调整命令中的区域和端口。
3.1.2 部署软件仓库、安装Epel拓展库并下载相关包
bash
~]# cd /etc/yum.repos.d/
yum.repos.d]# rm -rf *
~]# vim /etc/yum.repos.d/aliyun.repo
[AppStream]
name=AppStream
baseurl=https://mirrors.aliyun.com/rockylinux/8/AppStream/x86_64/os/
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/rockylinux/8/AppStream/x86_64/os/RPM-GPG-KEY-rockyofficial
[BaseOS]
name=BaseOS
baseurl=https://mirrors.aliyun.com/rockylinux/8/BaseOS/x86_64/os/
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/rockylinux/8/AppStream/x86_64/os/RPM-GPG-KEY-rockyofficial
yum clean all && yum makecache
# 下载Epel库
~]# rpm -ivh https://mirrors.aliyun.com/epel/epel-release-latest-8.noarch.rpm
~]# /usr/bin/crb enable
~]# yum install epel-release
# 下载所需包
]# yum install -y device-mapper-persistent-data lvm2 wget net-tools socat nfs-utils lrzsz gcc gcc-c++ make cmake libxml2-devel openssl-devel curl curl-devel unzip sudo chrony libaio-devel wget vim ncurses-devel autoconf ipvsadm conntrack telnet ipvsadm
3.1.2 配置时间同步
bash
# 配置时间同步并创建计划性任务
~]# yum install -y chrony
# 这里使用的是阿里云的ntp时间同步服务器
~]# vim /etc/chrony.conf
3 server ntp.aliyun.com iburst
# iburst 选项说明: 如果设置该选项,前四轮询之间的间隔将是2秒,而不是minpoll
# 这对于在chronyd启动后快速获得时钟的第一次更新非常有用。即:重启chronyd后,2秒后,直接同步一次时间。
~]# systemctl enable --now chronyd.service
~]# systemctl restart chronyd.service
# 后续如果出现偏差,使用以下两个命令进行查看并手动同步
]# chronyc sources # 查看同步状态
]# chronyc makestep # 手动同步
3.1.3 安装Docker并配置镜像加速器的地址
每台主机都需要安装
bash
~]# vim /etc/yum.repos.d/docker-ce.repo
[docker-ce]
name=docker-ce
baseurl=https://mirrors.aliyun.com/docker-ce/linux/rhel/8/x86_64/stable/
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/docker-ce/linux/rhel/gpg
# 修改机器内核参数
# 有些操作系统执行`modprobe br_netfilter`会报错(那就不用管了)
# modprobe br_netfilter 的作用是将 br_netfilter 模块添加到 Linux 内核中。
~]# modprobe br_netfilter
~]# vim /etc/sysctl.d/docker.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
~]# sysctl -p /etc/sysctl.d/docker.conf
# 进行安装Dcoker
# 这里建议查看系统中docker-ce的版本,建议使用docker-ce-26.1.3
]# yum list --showduplicates docker-ce | grep 26.1.3
~]# yum install -y docker-ce-26.1.3
~]# systemctl enable --now docker
~]# systemctl status docker.service
############################################################################################
# 这里介绍的是:如果下载的版本错误了,怎么办?
0.查看自己的版本
]# docekr --version
1. 完全卸载当前 Docker
]# systemctl stop docker && systemctl stop containerd
]# yum remove -y docker-ce
2. 清理残留配置
]# rm -rf /var/lib/docker && rm -rf /var/lib/containerd
3. 安装统一的 26.x 版本(26的版本也是可以的)
]# yum install -y docker-ce-26.1.3
4. 启动服务
]# systemctl enable --now docker
]# docker --version
############################################################################################
# 此时需要将docker作为我们的默认库
# 编写主机的镜像库的加速节点
reg ~]# vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://reg.kaser.org"]
}
[root@reg ~]# scp /etc/docker/daemon.json root@172.25.254.10:/etc/docker/daemon.json
[root@reg ~]# scp /etc/docker/daemon.json root@172.25.254.50:/etc/docker/daemon.json
[root@reg ~]# scp /etc/docker/daemon.json root@172.25.254.60:/etc/docker/daemon.json
# 重载配置
其余主机 ~]# systemctl daemon-reload && systemctl restart docker
# 登陆harbor仓库
其余主机]# docker login reg.kaser.org -uadmin -padmin
net.bridge.bridge-nf-call-ip6tables = 1允许 Linux 内核在网络层面上进行 IPv6 数据包的过滤和处理;
net.bridge.bridge-nf-call-iptables = 1允许 Linux 内核在网络层面上进行 IPv4 数据包的过滤和处理
net.ipv4.ip_forward = 1启用了 Linux 内核的 IP 转发功能,允许 Linux 主机将收到的数据包从一个网络接口转发到另一个网络接口
3.1.4 配置主机间免密登录并编写主机hosts文件
bash
[root@k8s-master1 ~]# ssh-keygen # 一路回车Enter
# 将本地密钥文件及私钥文件拷贝到其余主机上
[root@k8s-master1 ~]# ssh-copy-id 172.25.254.5
- yes
- root
[root@k8s-master1 ~]# ssh-copy-id 172.25.254.50
[root@k8s-master1 ~]# ssh-copy-id 172.25.254.60
bash
[root@k8s-master1 ~]# vim /etc/hosts
[root@k8s-master1 ~]# cat /etc/hosts
......
172.25.254.5 reg.kaser.org
172.25.254.10 k8s-master1.kaser.org
172.25.254.50 k8s-node1.kaser.org
172.25.254.60 k8s-node2.kaser.org
[root@k8s-master1 ~]# scp /etc/hosts root@172.25.254.50:/etc/hosts
[root@k8s-master1 ~]# scp /etc/hosts root@172.25.254.60:/etc/hosts
3.1.5 关闭交换分区swap
强烈建议关闭swap分区来提升性能。
**swap交换分区是一种在计算机中使用的虚拟内存技术。**当物理空间不足以容纳当前运行的程序时,操作系统会把一部分内存空间暂时转移至硬盘上,以便为当前程序提供内存所需的内存空间。此过程称之为"交换"
交换分区就是硬盘上专门预留给操作系统进行交换的一块空间。
交换分区的使用,可以有效避免程序因为内存不足而崩溃或运行缓慢的问题,但是硬盘的读写速度比内存要慢的很多,因此交换分区的使用会对系统的性能产生一定的影响。
在Kunbernetes中,需要频繁的使用内存和磁盘等系统资源。如果使用了交换分区,会导致Kubernetes的运行速度变慢,从而影响整个集群的性能。
因此,在安装k8s时,通常都会建议关闭swap交换分区。
bash
# 强烈建议永久关闭swap交换分区
[root@k8s-master1 ~]# vim /etc/fstab
# 进入文件之后将swap那一行注释掉即可
[root@k8s-master1 ~]# scp /etc/fstab root@172.25.254.50:/etc/fstab
[root@k8s-master1 ~]# scp /etc/fstab root@172.25.254.60:/etc/fstab
# 如果需要临时关闭的话,看下面的命令
m1 & n1 & n2 ~]# swapoff -a
3.2 安装containerd服务
在k8s中,每个容器都需要运行一个容器运行时(containerd),用于管理和运行容器。
就像我们在电脑上需要安装一个软件才能打开一个文件一样,在k8s中需要安装一个容器运行时才能在pod中运行容器。
k8s中的容器运行时就像一个保姆一样,它负责容器的生命周期和资源隔离,确保容器能够在节点上稳定地运行。
在k8s中,当一个pod被创建时,k8s会根据pod中定义的容器信息,将它们交给容器运行时来创建和运行。
bash
# 版本安装错误再使用此内容
# 以下为删除containerd的服务(会导致docker一并消失)
yum remove -y containerd.io containerd runc && rm -rf /var/lib/containerd /etc/containerd /run/containerd && rm -f /etc/cni/net.d/* && yum autoremove -y
bash
# 查询可用版本(验证仓库是否生效)
# 选一个三台主机都有的版本
]# yum list containerd.io --showduplicates | grep -E "1.6|1.7"
m1 & n1 & n2 ~]# yum install containerd.io-1.6.31* -y
[root@k8s-master1 ~]# cd /etc/containerd/
[root@k8s-master1 containerd]# rm -rf *
# 上传资源包里面的文件
[root@k8s-master1 containerd]# ls
config.toml
# 直接资源包里面的配置文件即可(只需要修改harbor相关的ip即可)
[root@k8s-master1 containerd]# vim config.toml
# 如下图所示:
# 这里查看一下自己的Harbor仓库地址并启动一下
[root@reg ~]# hostname -i
172.25.254.5
[root@reg ~]# cd harbor/ && docker compose up -d
[root@reg harbor]# hostname
reg.kaser.org
[root@reg harbor]# docker login reg.kaser.org -uadmin -padmin
~]# cd /etc/containerd/
[root@k8s-master1 containerd]# scp /etc/containerd/config.toml root@172.25.254.50:/etc/containerd/config.toml
[root@k8s-master1 containerd]# scp /etc/containerd/config.toml root@172.25.254.60:/etc/containerd/config.toml
其余主机 ~]# systemctl enable --now containerd
这里建议给每台主机打一个快照(后面就可以无限次去练习K8s的安装)
3.3 配置阿里云kubernetes软件仓库镜像并下载相关必须软件
bash
# 自己去阿里云官方镜像开源镜像站去搜索kubernetes的软件仓库(软件仓库地址的版本最好与我保持一致)
#
[root@k8s-master1 ~]# vim /etc/yum.repos.d/k8s.repo
[k8s]
name=k8s
baseurl=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.31/rpm/
enabeled=1
gpgckeck=1
gpgkey=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.31/rpm/repodata/repomd.xml.key
[root@k8s-master1 ~]# scp /etc/yum.repos.d/k8s.repo root@172.25.254.50:/etc/yum.repos.d/k8s.repo
[root@k8s-master1 ~]# scp /etc/yum.repos.d/k8s.repo root@172.25.254.60:/etc/yum.repos.d/k8s.repo
# 修改机器内核参数
# 有些操作系统执行`modprobe br_netfilter`会报错(那就不用管了)
# modprobe br_netfilter 的作用是将 br_netfilter 模块添加到 Linux 内核中。
[root@k8s-master1 ~]# modprobe br_netfilter
[root@k8s-master1 ~]# vim /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
[root@k8s-master1 ~]# scp /etc/sysctl.d/k8s.conf root@172.25.254.50:/etc/sysctl.d/k8s.conf
[root@k8s-master1 ~]# scp /etc/sysctl.d/k8s.conf root@172.25.254.60:/etc/sysctl.d/k8s.conf
m1 && n1 && n2 ~]# sysctl -p /etc/sysctl.d/k8s.conf
m1 && n1 && n2 ~]# yum clean all && yum makecache
m1 && n1 && n2 ~]# yum install -y kubeadm-1.31.3 kubelet-1.31.3 kubectl-1.31.3
1.kubeadm
初始化k8s集群的工具,安装各种各样的组件
2.kubelet
安装在集群所有节点上,用于启动pod
组件都是基于pod运行的,只要opod启动,就需要kubelet
3.kubectl
部署、管理应用的工具
查看各种资源、创建、删除和更新各种组件
m1 && n1 && n2 ~]# systemctl enable --now kubelet.service
# 此时的kubelet暂时启动不起来,只是为了方便将kubelet设置为开机自启
3.4 部署 kubernetes 集群
3.4.1 生成 kubeadm.yaml 文件并编辑
bash
# 生成 kubeadm 初始化集群时使用的默认配置文件,并将其保存为 kubeadm.yaml
[root@k8s-master1 ~]# kubeadm config print init-defaults > kubeadm.yaml
[root@k8s-master1 ~]# vim kubeadm.yaml
# 修改1:修改自己的maste节点ip
12 advertiseAddress: 172.25.254.10
# 修改2:指定 containerd容器进行时
# 可通过此命令进行查找 find / -name "containerd.sock" 如果不一样了,修改即可
15 criSocket: unix:///run/containerd/containerd.sock
# 修改3:修改自己的master节点的主机名
18 name: k8s-master1.kaser.org
# 修改4:国外加速站点网络是个大麻烦,所以使用国内阿里云的
41 imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers
# 修改5:kubernetes的版本
43 kubernetesVersion: 1.31.3
# 新增指定pod网段的参数
46 serviceSubnet: 10.96.0.0/12
47 podSubnet: 10.244.0.0/16
# 52-59都是要新添的行数(不要把---和---忘记!)
52 ---
53 apiVersion: kubeproxy.config.k8s.io/v1alpha1
54 kind: KubeProxyConfiguration
55 mode: ipvs
56 ---
57 apiVersion: kubelet.config.k8s.io/v1beta1
58 kind: KubeletConfiguration
59 cgroupDriver: systemd
# 这两段的YAML配置分别用于 Kubernetes 的核心组件 kube-proxy 和 kubelet
######################################################################
# kube-proxy 配置:流量代理模式设置为:IPVS(IP Virtual Server) 模式
# 配合利用 Linux 内核的 IPVS 模块 实现高性能的负载均衡
# 显著提升 Service 的网络性能和稳定性
# 相较于 iptables 模式,特点如下:
# 1.支持更复杂的负载均衡算法(轮询、最少连接、源IP哈希等)
# 2.处理大规模 Service 时性能更高
# 3.支持会话保持
# 适用场景:
# 对网络性能要求高的生产集群(如大规模微服务,高流量场景等)
# 前提条件:
# 节点需要提前加载 ip_vs 内核模块(通常通过 ipvsadm 工具验证)
######################################################################
# kube-let 配置:指定 kubelet 使用 systemd 作为 cgroup 的驱动
# cgroup驱动的作用:
# 1.k8s 通过 cgroup 限制容器的cpu/内存资源。
# 2.cgroupDriver 决定了 kubelet 与系统 cgroup 管理的交互方式
# 配置作用:
# 1.统一 cgroup 的管理
# 2.避免与宿主机(systemd)冲突
bash
# 安装k8s需要下载哪些镜像,如何查看?
# (看清楚自己的版本号,也可以去查别的版本需要下载哪些镜像)
]# kubeadm config images list --kubernetes-version=1.31.3 --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers
3.4.1.1 kubeadm.yaml文件参数解释
bash
1、localAPIEndpoint: Kubernetes API Server 监听的地址和端口。
advertiseAddress:
指定控制节点的 IP 地址,即 API Server 暴露给集群内其他节点的地址。
bindPort:
指定 API Server 监听的端口,默认为 6443。
nodeRegistration:
控制节点的注册信息。
criSocket:
指定容器运行时使用的 CRI Socket,即容器与 Kubernetes API Server 之间的通信通道。这里指定为 Containerd 的 Socket 地址。
imagePullPolicy:
指定容器镜像拉取策略,这里指定为如果本地已有镜像则不拉取。
name:
控制节点的名称,主机名
taints:
控制节点的 taints,即节点的标记,用于限制哪些 Pod 可以调度到该节点。这里指定为空,即不对 Pod 的调度进行限制。
2、podSubnet: 10.244.0.0/16
# 指定pod网段, 需要新增加这个
serviceSubnet: 10.96.0.0/12
# 指定Service网段
在Kubernetes集群中,每个Pod都会被分配一个IP地址,这些IP地址需要从一个预定义的IP地址池中分配。
podSubnet参数用于指定Pod IP地址池的范围,它定义了Pod的IP地址范围,例如10.244.0.0/16表示IP地址从10.244.0.1到10.244.255.255。10.244.0.0/16可用的 IP 地址数量是 216−2=65534216−2=65534
同样地,Kubernetes服务(Service)也会被分配一个IP地址,用于暴露Kubernetes服务的端口。 serviceSubnet参数用于指定Service IP地址池的范围,它定义了Service的IP地址范围,例如10.96.0.0/12表示IP地址从10.96.0.1到10.96.255.255。/12 表示了网络的子网掩码长度,即前 12 位是网络地址,剩余的 32-12=20 位是主机地址。
对于一个 /12 的网络,总共有 220−2 个可用的 IP 地址,因为其中两个 IP 地址分别用作网络地址和广播地址。所以可用的 IP 地址数量是 220−2=1048574220−2=1048574。
3.4.2 基于kubeadm.yaml初始化k8s集群
bash
# 上传资源包里面的资源
# 手动导入镜像
master1 && node1 && node2 ]# ctr -n=k8s.io images import k8s1_31_3
# 控制节点上执行
[root@k8s-master1 ~]# kubeadm init --config=kubeadm.yaml --ignore-preflight-errors=SystemVerification
# 出现以下即为成功(一定注意,各主机间软件的版本号要一致!)

3.4.3 初始化完成之后进行关键步骤
bash
# 集群初始化后的关键配置步骤如下:
# 主要用于设置 kubectl 命令行工具的访问权限,使当前用户能够管理集群。
1.在当前用户的家目录创建 .kube 隐藏目录(用于存放 kubectl 配置文件)
[root@k8s-master1 ~]# mkdir -p $HOME/.kube
2.将集群的管理员配置文件复制到用户专属的 kubectl 配置路径
[root@k8s-master1 ~]# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
3.修正配置文件的所有权,确保当前用户有权限读取该文件
[root@k8s-master1 ~]# sudo chown $(id -u):$(id -g) $HOME/.kube/config
[root@k8s-master1 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master1.kaser.org NotReady control-plane 24m v1.31.3
3.4.4 扩容k8s集群-新添工作节点
bash
1.控制节点操作!!!!
# 这条命令每个人不一样
# 建议每次新添节点时,将此命令执行一遍(由于有token的有效期)
[root@k8s-master1 ~]# kubeadm token create --print-join-command
kubeadm join 172.25.254.10:6443 --token umnmn7.gq2z7pafjgnxgjup --discovery-token-ca-cert-hash sha256:afc04b2693b84e0e0688c2ab4e5011fc56cbfa069ad35cd8292081162ca54d0b
2.新增节点操作!!! # 新增参数:--ignore-preflight-errors=SystemVerification
# 以下命令就是控制节点输出 + 新增参数即可
]# kubeadm join 172.25.254.10:6443 --token umnmn7.gq2z7pafjgnxgjup --discovery-token-ca-cert-hash sha256:afc04b2693b84e0e0688c2ab4e5011fc56cbfa069ad35cd8292081162ca54d0b --ignore-preflight-errors=SystemVerification
3.控制节点查看节点状况:
[root@k8s-master1 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master1.kaser.org NotReady control-plane 39m v1.31.3
k8s-node1.kaser.org NotReady <none> 41s v1.31.3
k8s-node2.kaser.org NotReady <none> 37s v1.31.3
# 此时,节点已经加入到集群之中,充当了工作节点
4.可以将工作节点打标签,以便于观察 --> work
[root@k8s-master1 ~]# kubectl label nodes k8s-node1.kaser.org node-role.kubernetes.io/work=work
[root@k8s-master1 ~]# kubectl label nodes k8s-node2.kaser.org node-role.kubernetes.io/work=work
# 再次查看nodes是否有变化
[root@k8s-master1 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master1.kaser.org NotReady control-plane 47m v1.31.3
k8s-node1.kaser.org NotReady work 9m7s v1.31.3
k8s-node2.kaser.org NotReady work 9m3s v1.31.3

3.4.5 安装kubernetes网络组件-Calico
3.4.5.1 Calico 介绍
calico 是一个开源的网络和安全解决方案;
它为容器、虚拟机、主机、Kubernetes 提供了高效、可拓展和安全的网络连接和策略管理。
Calico 在 k8s 中的功能:
- 支持网络隔离、多租户场景;
- 为 pod 提供独立的 IP 地址;
- 支持跨主机的容器通信,pod 可以通过 IP 地址直接互相访问;
- 提供网络安全策略,支持网络流量控制和访问授权、实现网络安全隔离。
Calico 的优点:
- 网络性能高:
- Calico 使用 Linux 内核中的路由和过滤技术,避免了 NAT,因此可以提供更好的网络性能和更低的延迟;
- 高可用性:
- Calico 可以配置为高可用模式,从而保证集群的稳定性和可用性;
- 安全:
- Calico 可以提供高级的安全策略和访问控制,从而保护 k8s 集群中的容器和服务;
- 灵活性:
- Calico 的网络架构非常灵活,可以适应不同的应用场景和需求,支持不同的拓扑结构和部署模式;
- 社区活跃:
- Calico 是开源项目,拥有庞大的社区支持和活跃的开发者社区,可以获得及时的技术支持和更新。
3.4.5.2 Calico 安装
bash
1.# 将资源包中的 calico 所需要的软件镜像上传到每台主机中,并进行手动导入
m1 && n1 && n2 ~]# ctr -n=k8s.io images import calico.tar.gz
...
2.# 在控制节点上上传 calico.yaml 文件并视情况修改
[root@k8s-master1 ~]# vim calico.yaml
4767 - name: IP_AUTODETECTION_METHOD
4768 value: "interface=ens160"
# 注意:
# 查看每个节点的网卡名字 `nmcli c show`去检查以下
# 如果不是,则修改为自己的网卡名 `interface=xxxxx`
# 指定 `IP_AUTODETECTION_METHOD` 环境变量是为了确保该插件能够在正确的网络接口上自动检测 Pod IP 地址。
# 这个环境变量的值 "interface=ens160" 指定了 Calico 插件使用 ens160 接口来分配 IP 地址给 Kubernetes Pod,而不是使用默认的自动检测方式。
# 通常情况下,Kubernetes Pod 中容器的 IP 地址是由容器运行时(如 Docker 或 CRI-O)自动分配的。
# 但是,对于某些网络插件(如 Calico)来说,为了能够正确地配置网络,需要手动指定使用哪个网络接口来自动检测 Pod IP 地址。
# 这样可以确保 Calico 插件能够正确地配置 Pod 网络。
3.# 使用 yaml 文件安装 calico 网络插件
~]# kubectl apply -f calico.yaml
# 稍等一会,服务就会启动
# 查看状态
[root@k8s-master1 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master1.kaser.org Ready control-plane 18h v1.31.3
k8s-node1.kaser.org Ready work 17h v1.31.3
k8s-node2.kaser.org Ready work 17h v1.31.3
# 查看状态,如下图所示
[root@k8s-master1 ~]# kubectl get pods -n kube-system

3.4.5.3 kubernetes 集群中常见网络插件对比
Flannel
- 轻量级的 CNI 插件
- 使用 VXLAN 技术实现网络的通信和隔离
- 适用于小规模集群
- 使用 iptables 来实现 NAT,支持多种后端存储(包括 etcd,consul,zookeeper等)
Calico
- 完全基于BGP协议的 CNI 插件,可以实现高性能和高拓展性的网络功能
- 使用 IPIP,BGP,VXLAN 技术,可以轻松扩展网络规模
- 他还支持网络安全策略、网络流浪策略和网络监控等功能
Weave Net
- 简单易用的 CNI 插件
- 使用虚拟路由和 Overlay 网络实现容器之间的通信和隔离
- 它提供一种快速、可靠和可拓展的解决方案,并支持多云环境
Cilium
- 是一个支持 L3,L4和L7 网络安全的 CNI 插件,具有网络和安全功能集成
- 使用 eBPF 技术,可以实现更好的性能和可观测性
对于小规模的 kubernetes 集群,Flannel 和 Weave Net 比较适合,而对于大规模的集群,Calico、Cilium 则是一个更好的选择。
3.4.6 测试 k8s 创建的 pod 是否可以正常访问网络和 coredns
bash
# 将资源包中的 busybox-1-28.tar.gz 上传到 node1 和 node2 工作节点并手动导入镜像
n1 && n2 ~]# ctr -n k8s.io images import busybox-1-28.tar.gz
# 在控制节点创建 pod 并进行测试
[root@k8s-master1 ~]# kubectl run busybox --image docker.io/library/busybox:1.28 --image-pull-policy=IfNotPresent --restart=Never --rm -it busybox -- sh
...
/ # nslookup kubernetes
Server: 10.96.0.10 # 这里的 10.96.0.10 是 coredns 的 ClusterIP,说明coredns配置完成
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: kubernetes
Address 1: 10.96.0.1 kubernetes.default.svc.cluster.local
/ #
/ # ping www.baidu.com -c3 # 这里反馈的数据,可以反映出 Calico 网络插件已经成功安装了
PING www.baidu.com (36.152.44.93): 56 data bytes
64 bytes from 36.152.44.93: seq=0 ttl=127 time=60.296 ms
64 bytes from 36.152.44.93: seq=1 ttl=127 time=46.668 ms
64 bytes from 36.152.44.93: seq=2 ttl=127 time=39.905 ms
--- www.baidu.com ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 39.905/48.956/60.296 ms
# busybox要用指定的1.28版本,不能用最新版本,最新版本,nslookup会解析不到dns和ip
3.4.7 延长 kubernetes 的证书有效期
3.4.7.1 延长步骤
bash
# 检查自己的证书有效期
[root@k8s-master1 ~]# openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -text |grep Not
Not Before: Dec 27 12:51:28 2025 GMT
Not After : Dec 27 12:56:28 2026 GMT
# 很显然,一年之后就没了(学习阶段没啥大的影响,但是在生产环境中,证书有效期是一个很棘手的问题)
# 因此,使用编写"延长有效期的脚本"进行延长
# 上传资源包中的脚本 update-kubeadm-cert.sh (下面代码段中提供完整代码)
[root@k8s-master1 ~]# vim update-kubeadm-cert.sh
# 赋予脚本执行权限并执行
[root@k8s-master1 ~]# chmod +x update-kubeadm-cert.sh
[root@k8s-master1 ~]# ./update-kubeadm-cert.sh all
# 由于延长证书有效期,会重启所有 pod
# 因此,如果要延长,请在安装完 k8s 集群时就进行操作,以免导致业务崩溃
[root@k8s-master1 ~]# kubectl get pods -n kube-system
# 再次查看有限期,发现确实延长到了100年 ^_^
[root@k8s-master1 ~]# openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -text |grep Not
Not Before: Dec 28 08:13:37 2025 GMT
Not After : Dec 4 08:13:37 2125 GMT
# 以下为脚本完整代码,有需要可以进行拷贝
3.4.7.2 延长证书脚本源代码
bash
#!/bin/bash
#name:Kaser WeChat:Cyber4K
set -o errexit
set -o pipefail
# set -o xtrace
log::err() {
printf "[$(date +'%Y-%m-%dT%H:%M:%S.%N%z')]: \033[31mERROR: \033[0m$@\n"
}
log::info() {
printf "[$(date +'%Y-%m-%dT%H:%M:%S.%N%z')]: \033[32mINFO: \033[0m$@\n"
}
log::warning() {
printf "[$(date +'%Y-%m-%dT%H:%M:%S.%N%z')]: \033[33mWARNING: \033[0m$@\n"
}
check_file() {
if [[ ! -r ${1} ]]; then
log::err "can not find ${1}"
exit 1
fi
}
# get x509v3 subject alternative name from the old certificate
cert::get_subject_alt_name() {
local cert=${1}.crt
check_file "${cert}"
local alt_name=$(openssl x509 -text -noout -in ${cert} | grep -A1 'Alternative' | tail -n1 | sed 's/[[:space:]]*Address//g')
printf "${alt_name}\n"
}
# get subject from the old certificate
cert::get_subj() {
local cert=${1}.crt
check_file "${cert}"
local subj=$(openssl x509 -text -noout -in ${cert} | grep "Subject:" | sed 's/Subject:/\//g;s/\,/\//;s/[[:space:]]//g')
printf "${subj}\n"
}
cert::backup_file() {
local file=${1}
if [[ ! -e ${file}.old-$(date +%Y%m%d) ]]; then
cp -rp ${file} ${file}.old-$(date +%Y%m%d)
log::info "backup ${file} to ${file}.old-$(date +%Y%m%d)"
else
log::warning "does not backup, ${file}.old-$(date +%Y%m%d) already exists"
fi
}
# generate certificate whit client, server or peer
# Args:
# $1 (the name of certificate)
# $2 (the type of certificate, must be one of client, server, peer)
# $3 (the subject of certificates)
# $4 (the validity of certificates) (days)
# $5 (the x509v3 subject alternative name of certificate when the type of certificate is server or peer)
cert::gen_cert() {
local cert_name=${1}
local cert_type=${2}
local subj=${3}
local cert_days=${4}
local alt_name=${5}
local cert=${cert_name}.crt
local key=${cert_name}.key
local csr=${cert_name}.csr
local csr_conf="distinguished_name = dn\n[dn]\n[v3_ext]\nkeyUsage = critical, digitalSignature, keyEncipherment\n"
check_file "${key}"
check_file "${cert}"
# backup certificate when certificate not in ${kubeconf_arr[@]}
# kubeconf_arr=("controller-manager.crt" "scheduler.crt" "admin.crt" "kubelet.crt")
# if [[ ! "${kubeconf_arr[@]}" =~ "${cert##*/}" ]]; then
# cert::backup_file "${cert}"
# fi
case "${cert_type}" in
client)
openssl req -new -key ${key} -subj "${subj}" -reqexts v3_ext \
-config <(printf "${csr_conf} extendedKeyUsage = clientAuth\n") -out ${csr}
openssl x509 -in ${csr} -req -CA ${CA_CERT} -CAkey ${CA_KEY} -CAcreateserial -extensions v3_ext \
-extfile <(printf "${csr_conf} extendedKeyUsage = clientAuth\n") -days ${cert_days} -out ${cert}
log::info "generated ${cert}"
;;
server)
openssl req -new -key ${key} -subj "${subj}" -reqexts v3_ext \
-config <(printf "${csr_conf} extendedKeyUsage = serverAuth\nsubjectAltName = ${alt_name}\n") -out ${csr}
openssl x509 -in ${csr} -req -CA ${CA_CERT} -CAkey ${CA_KEY} -CAcreateserial -extensions v3_ext \
-extfile <(printf "${csr_conf} extendedKeyUsage = serverAuth\nsubjectAltName = ${alt_name}\n") -days ${cert_days} -out ${cert}
log::info "generated ${cert}"
;;
peer)
openssl req -new -key ${key} -subj "${subj}" -reqexts v3_ext \
-config <(printf "${csr_conf} extendedKeyUsage = serverAuth, clientAuth\nsubjectAltName = ${alt_name}\n") -out ${csr}
openssl x509 -in ${csr} -req -CA ${CA_CERT} -CAkey ${CA_KEY} -CAcreateserial -extensions v3_ext \
-extfile <(printf "${csr_conf} extendedKeyUsage = serverAuth, clientAuth\nsubjectAltName = ${alt_name}\n") -days ${cert_days} -out ${cert}
log::info "generated ${cert}"
;;
*)
log::err "unknow, unsupported etcd certs type: ${cert_type}, supported type: client, server, peer"
exit 1
esac
rm -f ${csr}
}
cert::update_kubeconf() {
local cert_name=${1}
local kubeconf_file=${cert_name}.conf
local cert=${cert_name}.crt
local key=${cert_name}.key
# generate certificate
check_file ${kubeconf_file}
# get the key from the old kubeconf
grep "client-key-data" ${kubeconf_file} | awk {'print$2'} | base64 -d > ${key}
# get the old certificate from the old kubeconf
grep "client-certificate-data" ${kubeconf_file} | awk {'print$2'} | base64 -d > ${cert}
# get subject from the old certificate
local subj=$(cert::get_subj ${cert_name})
cert::gen_cert "${cert_name}" "client" "${subj}" "${CAER_DAYS}"
# get certificate base64 code
local cert_base64=$(base64 -w 0 ${cert})
# backup kubeconf
# cert::backup_file "${kubeconf_file}"
# set certificate base64 code to kubeconf
sed -i 's/client-certificate-data:.*/client-certificate-data: '${cert_base64}'/g' ${kubeconf_file}
log::info "generated new ${kubeconf_file}"
rm -f ${cert}
rm -f ${key}
# set config for kubectl
if [[ ${cert_name##*/} == "admin" ]]; then
mkdir -p ~/.kube
cp -fp ${kubeconf_file} ~/.kube/config
log::info "copy the admin.conf to ~/.kube/config for kubectl"
fi
}
cert::update_etcd_cert() {
PKI_PATH=${KUBE_PATH}/pki/etcd
CA_CERT=${PKI_PATH}/ca.crt
CA_KEY=${PKI_PATH}/ca.key
check_file "${CA_CERT}"
check_file "${CA_KEY}"
# generate etcd server certificate
# /etc/kubernetes/pki/etcd/server
CART_NAME=${PKI_PATH}/server
subject_alt_name=$(cert::get_subject_alt_name ${CART_NAME})
cert::gen_cert "${CART_NAME}" "peer" "/CN=etcd-server" "${CAER_DAYS}" "${subject_alt_name}"
# generate etcd peer certificate
# /etc/kubernetes/pki/etcd/peer
CART_NAME=${PKI_PATH}/peer
subject_alt_name=$(cert::get_subject_alt_name ${CART_NAME})
cert::gen_cert "${CART_NAME}" "peer" "/CN=etcd-peer" "${CAER_DAYS}" "${subject_alt_name}"
# generate etcd healthcheck-client certificate
# /etc/kubernetes/pki/etcd/healthcheck-client
CART_NAME=${PKI_PATH}/healthcheck-client
cert::gen_cert "${CART_NAME}" "client" "/O=system:masters/CN=kube-etcd-healthcheck-client" "${CAER_DAYS}"
# generate apiserver-etcd-client certificate
# /etc/kubernetes/pki/apiserver-etcd-client
check_file "${CA_CERT}"
check_file "${CA_KEY}"
PKI_PATH=${KUBE_PATH}/pki
CART_NAME=${PKI_PATH}/apiserver-etcd-client
cert::gen_cert "${CART_NAME}" "client" "/O=system:masters/CN=kube-apiserver-etcd-client" "${CAER_DAYS}"
# restart etcd
docker ps | awk '/k8s_etcd/{print$1}' | xargs -r -I '{}' docker restart {} || true
log::info "restarted etcd"
}
cert::update_master_cert() {
PKI_PATH=${KUBE_PATH}/pki
CA_CERT=${PKI_PATH}/ca.crt
CA_KEY=${PKI_PATH}/ca.key
check_file "${CA_CERT}"
check_file "${CA_KEY}"
# generate apiserver server certificate
# /etc/kubernetes/pki/apiserver
CART_NAME=${PKI_PATH}/apiserver
subject_alt_name=$(cert::get_subject_alt_name ${CART_NAME})
cert::gen_cert "${CART_NAME}" "server" "/CN=kube-apiserver" "${CAER_DAYS}" "${subject_alt_name}"
# generate apiserver-kubelet-client certificate
# /etc/kubernetes/pki/apiserver-kubelet-client
CART_NAME=${PKI_PATH}/apiserver-kubelet-client
cert::gen_cert "${CART_NAME}" "client" "/O=system:masters/CN=kube-apiserver-kubelet-client" "${CAER_DAYS}"
# generate kubeconf for controller-manager,scheduler,kubectl and kubelet
# /etc/kubernetes/controller-manager,scheduler,admin,kubelet.conf
cert::update_kubeconf "${KUBE_PATH}/controller-manager"
cert::update_kubeconf "${KUBE_PATH}/scheduler"
cert::update_kubeconf "${KUBE_PATH}/admin"
set +e
grep kubelet-client-current.pem /etc/kubernetes/kubelet.conf > /dev/null 2>&1
kubelet_cert_auto_update=$?
set -e
if [[ "$kubelet_cert_auto_update" == "0" ]]; then
log::warning "does not need to update kubelet.conf"
else
cert::update_kubeconf "${KUBE_PATH}/kubelet"
fi
# generate front-proxy-client certificate
# use front-proxy-client ca
CA_CERT=${PKI_PATH}/front-proxy-ca.crt
CA_KEY=${PKI_PATH}/front-proxy-ca.key
check_file "${CA_CERT}"
check_file "${CA_KEY}"
CART_NAME=${PKI_PATH}/front-proxy-client
cert::gen_cert "${CART_NAME}" "client" "/CN=front-proxy-client" "${CAER_DAYS}"
# restart apiserve, controller-manager, scheduler and kubelet
docker ps | awk '/k8s_kube-apiserver/{print$1}' | xargs -r -I '{}' docker restart {} || true
log::info "restarted kube-apiserver"
docker ps | awk '/k8s_kube-controller-manager/{print$1}' | xargs -r -I '{}' docker restart {} || true
log::info "restarted kube-controller-manager"
docker ps | awk '/k8s_kube-scheduler/{print$1}' | xargs -r -I '{}' docker restart {} || true
log::info "restarted kube-scheduler"
systemctl restart kubelet
log::info "restarted kubelet"
}
main() {
local node_tpye=$1
KUBE_PATH=/etc/kubernetes
CAER_DAYS=36500
# backup $KUBE_PATH to $KUBE_PATH.old-$(date +%Y%m%d)
cert::backup_file "${KUBE_PATH}"
case ${node_tpye} in
etcd)
# update etcd certificates
cert::update_etcd_cert
;;
master)
# update master certificates and kubeconf
cert::update_master_cert
;;
all)
# update etcd certificates
cert::update_etcd_cert
# update master certificates and kubeconf
cert::update_master_cert
;;
*)
log::err "unknow, unsupported certs type: ${cert_type}, supported type: all, etcd, master"
printf "Documentation: hanxianchao
example:
'\033[32m./update-kubeadm-cert.sh all\033[0m' update all etcd certificates, master certificates and kubeconf
/etc/kubernetes
├── admin.conf
├── controller-manager.conf
├── scheduler.conf
├── kubelet.conf
└── pki
├── apiserver.crt
├── apiserver-etcd-client.crt
├── apiserver-kubelet-client.crt
├── front-proxy-client.crt
└── etcd
├── healthcheck-client.crt
├── peer.crt
└── server.crt
'\033[32m./update-kubeadm-cert.sh etcd\033[0m' update only etcd certificates
/etc/kubernetes
└── pki
├── apiserver-etcd-client.crt
└── etcd
├── healthcheck-client.crt
├── peer.crt
└── server.crt
'\033[32m./update-kubeadm-cert.sh master\033[0m' update only master certificates and kubeconf
/etc/kubernetes
├── admin.conf
├── controller-manager.conf
├── scheduler.conf
├── kubelet.conf
└── pki
├── apiserver.crt
├── apiserver-kubelet-client.crt
└── front-proxy-client.crt
"
exit 1
esac
}
main "$@"
3.4.8 k8s的注意事项
如何设置所有节点可以进行 kubectl 命令操作?
bash
[root@k8s-master1 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master1.kaser.org Ready control-plane 20h v1.31.3
k8s-node1.kaser.org Ready work 19h v1.31.3
k8s-node2.kaser.org Ready work 19h v1.31.3
# 情况:控制节点可以,工作节点不可以(会发生连接拒绝)
n1 && n2 ~]# kubectl get nodes
E1228 17:29:11.446256 120819 memcache.go:265] "Unhandled Error" err="couldn't get current server API group list: Get \"http://localhost:8080/api?timeout=32s\": dial tcp [::1]:8080: connect: connection refused"
...
# 工作节点创建目录
n1 && n2 ~]# mkdir /root/.kube
# 将控制节点文件复制到工作节点
m1 ~]# scp .kube/config root@172.25.254.50:/root/.kube/config
m1 ~]# scp .kube/config root@172.25.254.60:/root/.kube/config
# 进行测试
n1 && n2 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master1.kaser.org Ready control-plane 20h v1.31.3
k8s-node1.kaser.org Ready work 19h v1.31.3
k8s-node2.kaser.org Ready work 19h v1.31.3
3.4.9 其余版本1.26 1.27 1.30 1.34(资源包都有对应资源)
bash
内容大差不差,可以自己练习