一、系统环境
- 操作系统:Rocky Linux 9.3
- 内核版本:5.14.0-284.11.1.el9_2.x86_64
- 容器运行时:Docker + CRI-Docker
- Kubernetes 版本:1.29.2
- 网络插件:Calico
二、集群规划
基于二进制安装包,部署三主两从的高可用集群。
| 主机名称 | IPV4地址 | CPU/内存/磁盘 | 说明 | 软件 |
|---|---|---|---|---|
| 10.20.1.203 | 2C/4G/200G | 外网节点(可翻墙) | 下载各种所需安装包 | |
| Master01 | 10.20.1.101 | 2C/4G/200G | master节点(已有) | apiserver、controller-manager、scheduler、etcd、 kubelet、kube-proxy、nginx |
| Master02 | 10.20.1.102 | 2C/4G/200G | master节点(已有) | apiserver、controller-manager、scheduler、etcd、 kubelet、kube-proxy、nginx |
| Master03 | 10.20.1.103 | 2C/4G/200G | master节点(已有) | apiserver、controller-manager、scheduler、etcd、 kubelet、kube-proxy、nginx |
| Node01 | 10.20.1.104 | 2C/4G/200G | node节点(已有) | kubelet、kube-proxy、nginx |
| Node02 | 10.20.1.105 | 2C/4G/200G | node节点(已有) | kubelet、kube-proxy、nginx |
| Node03 | 10.20.1.106 | 2C/4G/200G | node节点(新节点) | kubelet、kube-proxy、nginx |
| Node04 | 10.20.1.107 | 2C/4G/200G | node节点(新节点) | kubelet、kube-proxy、nginx |
| Node05 | 10.20.1.108 | 2C/4G/200G | node节点(新节点) | kubelet、kube-proxy、nginx |
三、基础环境配置(所有节点)
1. 主机名设置
设置集群中各个节点的主机名
Node03 节点
hostnamectl set-hostname k8s-node03
Node04 节点
hostnamectl set-hostname k8s-node04
Node05 节点
hostnamectl set-hostname k8s-node05
2. 配置静态IP
集群内的每个几点都需要配置唯一的IP地址,这里同时配置了 IPV4地址 和 IPV6地址。
Node 节点
[root@k8s-master01 ~]# cat /etc/NetworkManager/system-connections/ens34.nmconnection
[ipv4]
method=manual
address1=10.20.1.106/24;10.20.1.1
dns=61.132.163.68;114.114.114.114
[ipv6]
method=manual
addresses=2400:3200::106/64
gateway=2400:3200::1
dns=2400:3200::1;2400:3200:baba::1;2001:4860:4860::8888;2001:4860:4860::8844
3. 修改hosts文件
配置集群各节点 hostname 和 ip 的映射
cat >> /etc/hosts << "EOF"
10.20.1.101 k8s-master01 m1
10.20.1.102 k8s-master02 m2
10.20.1.103 k8s-master03 m3
10.20.1.104 k8s-node01 n1
10.20.1.105 k8s-node02 n2
10.20.1.106 k8s-node03 n3
10.20.1.107 k8s-node04 n4
10.20.1.108 k8s-node05 n5
2400:3200::101 k8s-master01 m1
2400:3200::102 k8s-master02 m2
2400:3200::103 k8s-master03 m3
2400:3200::104 k8s-node01 n1
2400:3200::105 k8s-node02 n2
2400:3200::106 k8s-node03 n3
2400:3200::107 k8s-node04 n4
2400:3200::108 k8s-node05 n5
EOF
验证 hosts 文件配置
cat /etc/hosts
ping k8s-master01 -c 4 # 默认使用 IPv4
ping6 k8s-master01 -c 4 # 使用 IPv6
4. 修改终端颜色
这里只是修改shell终端显示文本的颜色,非必要步骤。
cat << EOF >> ~/.bashrc
PS1="\[\e[37;47m\][\[\e[32;47m\]\u\[\e[34;47m\]@\h \[\e[36;47m\]\w\[\e[0m\]]\\$ "
EOF
# 让修改立即见效
source ~/.bashrc
命令解析:
这段命令用于修改当前用户的 Bash Shell 提示符(
PS1),并将其设置写入到~/.bashrc文件中,以便在每次登录或启动 Shell 时自动加载该配置。PS1="..." 定义 Shell 的主提示符格式(Prompt String 1),即你在终端中输入命令时显示的提示符。最终效果如下:
5. 更换系统软件源
将 Rocky 默认源替换成阿里源,提升软件安装速度。
# 更新源
sed -e 's|^mirrorlist=|#mirrorlist=|g' \
-e 's|^#baseurl=http://dl.rockylinux.org/$contentdir|baseurl=https://mirrors.aliyun.com/rockylinux|g' \
-i.bak /etc/yum.repos.d/[Rr]ocky*.repo
# 刷新dnf缓存
dnf makecache
# 验证源更新
dnf repolist
命令解析:
# 使用 sed 命令修改 Rocky Linux 的 YUM/DNF 源配置文件,切换到阿里云的镜像源。 sed -e 's|^mirrorlist=|#mirrorlist=|g' \ -e 's|^#baseurl=http://dl.rockylinux.org/$contentdir|baseurl=https://mirrors.aliyun.com/rockylinux|g' \ -i.bak /etc/yum.repos.d/[Rr]ocky*.repo # 将以 mirrorlist= 开头的行注释掉(在前面加 #) -e 's|^mirrorlist=|#mirrorlist=|g' # 将以 #baseurl= 开头并指向默认 Rocky Linux 源的行取消注释,并替换为阿里云镜像源 URL。 's|^#baseurl=http://dl.rockylinux.org/$contentdir|baseurl=https://mirrors.aliyun.com/rockylinux|g' # -i.bak:直接修改文件,并为原文件创建备份(扩展名为 .bak)。 # 修改 /etc/yum.repos.d/ 目录下所有以 rocky 或 Rocky 开头的 .repo 文件。 # 修改完成后,原始文件会被备份为 .bak 文件。 -i.bak /etc/yum.repos.d/[Rr]ocky*.repo # 更新本地缓存,确保系统可以快速查询软件包信息。 dnf makecache
6. 修改防火墙
关闭默认防火墙firewalld,配置 iptables 防火墙
systemctl stop firewalld
systemctl disable firewalld
yum -y install iptables-services
systemctl start iptables
iptables -F
systemctl enable iptables
service iptables save
命令解析:
# 停止运行 firewalld systemctl stop firewalld # 禁止 firewalld 开机自启 systemctl disable firewalld # 安装 iptables 服务,用于管理 Linux 的防火墙规则 yum -y install iptables-services # 使防火墙规则立即生效,并开始运行 iptables 防火墙服务。 systemctl start iptables # 删除当前的防火墙规则,通常用于重置或清理防火墙规则。 iptables -F # 设置 iptables 服务开机自启动,确保服务器重启后,iptables 服务会自动加载防火墙规则。 systemctl enable iptables # 将当前 iptables 的规则配置保存到文件中(通常是 /etc/sysconfig/iptables),以便在系统重启或 iptables 服务重新启动后,能够自动加载保存的规则。 service iptables save
7. 禁用 Selinux
setenforce 0
sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
grubby --update-kernel ALL --args selinux=0
命令解析:
# 将 SELinux 的模式设置为 Permissive(宽容模式)。 # 0:表示设置为 Permissive 模式,此模式下 SELinux 不会强制执行安全策略,而是记录违规日志。 # 1:表示 Enforcing 模式,此模式下 SELinux 会强制执行安全策略。 setenforce 0 # 修改 SELinux 配置文件 /etc/selinux/config,将 SELINUX 设置为 disabled。永久禁用 SELinux,即使系统重启也不会再启用。 sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config # 通过 grubby 工具将 selinux=0 参数添加到所有内核启动配置中。 grubby --update-kernel ALL --args selinux=0 grubby --info DEFAULT # 查看是否禁用, grubby --info DEFAULT # 回滚内核层禁用操作,、 grubby --update-kernel ALL --remove-args selinux
8. 设置时区
timedatectl set-timezone Asia/Shanghai
9. 关闭 swap 分区
swapoff -a
sed -i 's:/dev/mapper/rl-swap:#/dev/mapper/rl-swap:g' /etc/fstab
命令解析:
# 立即关闭系统中所有的交换分区 swapoff -a # 注释掉 /etc/fstab 文件中定义的交换分区挂载条目,防止系统在重启后重新启用交换分区。 sed -i 's:/dev/mapper/rl-swap:#/dev/mapper/rl-swap:g' /etc/fstab # 验证交换分区是否关系 free -h 输出中 Swap 一栏的值会变为 0。
10. 安装基本工具
dnf -y install openssh-server wget tree bash-completion psmisc vim net-tools lrzsz nfs-utils epel-release telnet rsync yum-utils device-mapper-persistent-data lvm2 git tar curl
11. 修改系统最大打开文件数
cat >> /etc/security/limits.conf <<EOF
* soft nofile 655360
* hard nofile 131072
* soft nproc 655350
* hard nproc 655350
* soft memlock unlimited
* hard memlock unlimited
EOF
echo "ulimit -SHn 65535" >> /etc/profile
source /etc/profile
命令解析:
soft nofile 655360
soft表示软限制,nofile 表示一个进程可打开的最大文件数,默认值为1024。这里的软限制设置为655360,即一个进程可打开的最大文件数为655360。hard nofile 131072
hard表示硬限制,即系统设置的最大值。nofile表示一个进程可打开的最大文件数,默认值为4096。这里的硬限制设置为131072,即系统设置的最大文件数为131072。soft nproc 655350
soft表示软限制,nproc表示一个用户可创建的最大进程数,默认值为30720。这里的软限制设置为655350,即一个用户可创建的最大进程数为655350。hard nproc 655350
hard表示硬限制,即系统设置的最大值。nproc表示一个用户可创建的最大进程数,默认值为4096。这里的硬限制设置为655350,即系统设置的最大进程数为655350。soft memlock unlimited
seft表示软限制,memlock表示一个进程可锁定在RAM中的最大内存,默认值为64 KB。这里的软限制设置为unlimited,即一个进程可锁定的最大内存为无限制。hard memlock unlimited
hard表示硬限制,即系统设置的最大值。memlock表示一个进程可锁定在RAM中的最大内存,默认值为64 KB。这里的硬限制设置为unlimited,即系统设置的最大内存锁定为无限制。
12. 安装 ipvs
# 安装 ipvs
yum install ipvsadm ipset sysstat conntrack libseccomp -y
cat >> /etc/modules-load.d/ipvs.conf <<EOF
ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_sh
nf_conntrack
ip_tables
ip_set
xt_set
ipt_set
ipt_rpfilter
ipt_REJECT
ipip
EOF
systemctl restart systemd-modules-load.service
lsmod | grep -e ip_vs -e nf_conntrack
命名解析:
ipvsadm 命令行工具,用于管理IPVS(IP Virtual Server)
ipset 内核级工具,用于高效管理IP地址、端口或MAC地址的集合(sets)
sysstat 系统性能监控工具包,包括sar、iostat、mpstat等命令,用于收集和报告CPU、内存、磁盘I/O、网络等系统统计数据
conntrack 命令行工具(conntrack-tools的一部分),用于管理Netfilter的连接跟踪表(connection tracking table)
libseccomp 这是一个库,用于支持seccomp(Secure Computing Mode),seccomp是Linux内核功能,用于限制进程的系统调用(syscall),从而增强安全性(如沙箱化)
cat >> ….. 显示的加载内核模块
- ip_vs 核心IPVS模块,提供虚拟服务器功能,用于L4负载均衡
- ip_vs_rr IPVS的 round-robin 调度算法模块(轮询)
- ip_vs_wrr IPVS的 weighted round-robin 调度算法模块(加权轮询)
- ip_vs_sh IPVS的 source hashing 调度算法模块(源地址哈希)
- nf_conntrack Netfilter连接跟踪模块,跟踪网络连接状态(用于NAT和防火墙)
- ip_tables iptables的核心模块,用于IPv4包过滤和NAT
- ip_set IP集合管理模块,支持高效的IP列表处理
- xt_set iptables的扩展模块,用于与ip_set集成
- ipt_set iptables的set匹配模块(类似xt_set,但特定于IPv4)
- ipt_rpfilter iptables的反向路径过滤模块,防止IP欺骗攻击
- ipt_REJECT iptables的REJECT目标模块,用于拒绝包并发送拒绝消息
- ipip 隧道模块,用于封装IP包(类似VPN隧道)
systemctl restart systemd-modules-load.service:立即加载这些模块(因为/etc/modules-load.d/目录下的.conf文件会被systemd-modules-load服务读取)
lsmod | grep -e ip_vs -e nf_conntrack:检查模块是否加载成功。
13. 开启路由转发
echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf
sysctl -p
14. 排除 calico 网卡被 NetworkManager 所管理
cat > /etc/NetworkManager/conf.d/calico.conf << EOF
[keyfile]
unmanaged-devices=interface-name:cali*;interface-name:tunl*;interface-name:vxlan.calico;interface-name:vxlan-v6.calico;interface-name:wireguard.cali;interface-name:wg-v6.cali
EOF
systemctl restart NetworkManager
命令解析:
这个参数用于指定不由 NetworkManager 管理的设备。它由以下两个部分组成 interface-name:cali* 表示以 "cali" 开头的接口名称被排除在 NetworkManager 管理之外。例如,"cali0", "cali1" 等接口不受 NetworkManager 管理 interface-name:tunl* 表示以 "tunl" 开头的接口名称被排除在 NetworkManager 管理之外。例如,"tunl0", "tunl1" 等接口不受 NetworkManager 管理 interface-name:vxlan.calico 匹配名为vxlan.calico的接口,Calico在VXLAN模式下可能使用该接口名进行跨节点通信(VXLAN是一种覆盖网络技术) interface-name:vxlan-v6.calico 匹配名为vxlan-v6.calico的接口,这是Calico在支持IPv6的VXLAN模式下使用的接口名 interface-name:wireguard.cali 匹配名为wireguard.cali的接口,Calico支持使用WireGuard(一种高性能VPN协议)进行加密通信,这个接口用于WireGuard隧道。 interface-name:wg-v6.cali 匹配名为wg-v6.cali的接口,这是Calico在IPv6网络中使用的WireGuard接口 通过使用这个参数,可以将特定的接口排除在 NetworkManager 的管理范围之外,以便其他工具或进程可以独立地管理和配置这些接口
15. 修改内核参数
cat > /etc/sysctl.d/k8s.conf << EOF
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-iptables = 1
fs.may_detach_mounts = 1
vm.overcommit_memory=1
vm.panic_on_oom=0
fs.inotify.max_user_watches=89100
fs.file-max=52706963
fs.nr_open=52706963
net.netfilter.nf_conntrack_max=2310720
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_intvl =15
net.ipv4.tcp_max_tw_buckets = 36000
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_max_orphans = 327680
net.ipv4.tcp_orphan_retries = 3
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.ip_conntrack_max = 65536
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_timestamps = 0
net.core.somaxconn = 16384
net.ipv6.conf.all.disable_ipv6 = 0
net.ipv6.conf.default.disable_ipv6 = 0
net.ipv6.conf.lo.disable_ipv6 = 0
net.ipv6.conf.all.forwarding = 1
EOF
sysctl --system
命令解析:
这些是Linux系统的一些参数设置,用于配置和优化网络、文件系统和虚拟内存等方面的功能。以下是每个参数的详细解释: net.ipv4.ip_forward = 1 这个参数启用了IPv4的IP转发功能,允许服务器作为网络路由器转发数据包。 net.bridge.bridge-nf-call-iptables = 1 当使用网络桥接技术时,将数据包传递到iptables进行处理。 fs.may_detach_mounts = 1 允许在挂载文件系统时,允许被其他进程使用。 vm.overcommit_memory=1 该设置允许原始的内存过量分配策略,当系统的内存已经被完全使用时,系统仍然会分配额外的内存。 vm.panic_on_oom=0 当系统内存不足(OOM)时,禁用系统崩溃和重启。 fs.inotify.max_user_watches=89100 设置系统允许一个用户的inotify实例可以监控的文件数目的上限。 fs.file-max=52706963 设置系统同时打开的文件数的上限。 fs.nr_open=52706963 设置系统同时打开的文件描述符数的上限。 net.netfilter.nf_conntrack_max=2310720 设置系统可以创建的网络连接跟踪表项的最大数量。 net.ipv4.tcp_keepalive_time = 600 设置TCP套接字的空闲超时时间(秒),超过该时间没有活动数据时,内核会发送心跳包。 net.ipv4.tcp_keepalive_probes = 3 设置未收到响应的TCP心跳探测次数。 net.ipv4.tcp_keepalive_intvl = 15 设置TCP心跳探测的时间间隔(秒)。 net.ipv4.tcp_max_tw_buckets = 36000 设置系统可以使用的TIME_WAIT套接字的最大数量。 net.ipv4.tcp_tw_reuse = 1 启用TIME_WAIT套接字的重新利用,允许新的套接字使用旧的TIME_WAIT套接字。 net.ipv4.tcp_max_orphans = 327680 设置系统可以同时存在的TCP套接字垃圾回收包裹数的最大数量。 net.ipv4.tcp_orphan_retries = 3 设置系统对于孤立的TCP套接字的重试次数。 net.ipv4.tcp_syncookies = 1 启用TCP SYN cookies保护,用于防止SYN洪泛攻击。 net.ipv4.tcp_max_syn_backlog = 16384 设置新的TCP连接的半连接数(半连接队列)的最大长度。 net.ipv4.ip_conntrack_max = 65536 设置系统可以创建的网络连接跟踪表项的最大数量。 net.ipv4.tcp_timestamps = 0 关闭TCP时间戳功能,用于提供更好的安全性。 net.core.somaxconn = 16384 设置系统核心层的连接队列的最大值。 net.ipv6.conf.all.disable_ipv6 = 0 启用IPv6协议。 net.ipv6.conf.default.disable_ipv6 = 0 启用IPv6协议。 net.ipv6.conf.lo.disable_ipv6 = 0 启用IPv6协议。 net.ipv6.conf.all.forwarding = 1 允许IPv6数据包转发。
16. 集群时间同步设置
在 K8S-二进制高可用部署 中已经设置了以 Master01、Master02、Master03 作为时间同步的主节点,这里只需要设置 Node 节点从 Master 同步时间即可。
Node节点
yum install chrony -y
cat > /etc/chrony.conf << EOF
pool 10.20.1.101 iburst
pool 10.20.1.102 iburst
pool 10.20.1.103 iburst
driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync
keyfile /etc/chrony.keys
leapsectz right/UTC
logdir /var/log/chrony
EOF
systemctl restart chronyd ; systemctl enable chronyd
#使用客户端进行验证
chronyc sources -v
17. 配置免密登录
配置 k8s-master01 节点免密登录到其它节点,方便后续从 master01 节点往其它节点发送文件。
master-01
yum install -y expect
ssh-keygen -t rsa -P "" -f /root/.ssh/id_rsa
export user=root
export pass=123456
host=(k8s-master01 k8s-master02 k8s-master03 k8s-node01 k8s-node02 k8s-node03 k8s-node04 k8s-node05 m1 m2 m3 n1 n2 n3 n4 n5)
for host in ${host[@]};do expect -c "
spawn ssh-copy-id -i /root/.ssh/id_rsa.pub $user@$host
expect {
\"*yes/no*\" {send \"yes\r\"; exp_continue}
\"*password*\" {send \"$pass\r\"; exp_continue}
\"*Password*\" {send \"$pass\r\";}
}";
done
命令解析:
# 一个自动化交互工具,用于处理需要用户输入的命令行交互 yum install -y expect # 生成RSA类型的SSH密钥对(公钥和私钥),并存储在指定路径。-P "":设置空密码(无口令保护),便于自动化使用 ssh-keygen -t rsa -P "" -f /root/.ssh/id_rsa export user=root export pass=123456 # 定义一个Bash数组host,包含集群中所有节点的主机名和别名 host=(k8s-master01 k8s-master02 k8s-master03 k8s-node01 k8s-node02) # 遍历host数组,对每个节点执行expect脚本 for host in ${host[@]};do expect -c " # 启动ssh-copy-id命令,将公钥文件/root/.ssh/id_rsa.pub分发到目标节点 spawn ssh-copy-id -i /root/.ssh/id_rsa.pub $user@$host expect { # 匹配:当ssh-copy-id提示是否信任目标主机 # 动作:发送yes并换行(\r),确认连接 # exp_continue:继续匹配后续模式(不退出expect) \"*yes/no*\" {send \"yes\r\"; exp_continue} # 匹配:当提示输入密码(大写Password) # 动作:发送变量$pass(即123456)并换行 # exp_continue:继续匹配后续模式。 \"*password*\" {send \"$pass\r\"; exp_continue} \"*Password*\" {send \"$pass\r\";} }"; done
18. 安装 Docker
18.1 安装 Docker 二进制包
k8s-node节点
# 二进制包下载地址:https://download.docker.com/linux/static/stable/x86_64/
# 创建目录,后续下载的文件都放在这里
mkdir -p /opt/software/ /opt/module/ && chmod 777 -R /opt/software/ /opt/module/
# 下载 Docker
wget https://download.docker.com/linux/static/stable/x86_64/docker-28.4.0.tgz
# 解压二进制包
tar xf docker-*.tgz
# 拷贝解压后的二进制包到 /usr/bin 目录下
cp docker/* /usr/bin/
# 验证
$ docker --version
Docker version 28.4.0, build d8eb465
# 查看 containerd 版本
$ containerd --version
containerd github.com/containerd/containerd v1.7.28 b98a3aace656320842a23f4a392a33f46af97866
18.2 配置 containerd.service
containerd 的作用:它是一个独立的守护进程(daemon),处理低级任务,如镜像拉取、容器启动/停止、快照管理、网络/存储挂载等。它基于 OCI(Open Container Initiative)标准,与 runC(Docker 的另一个组件,用于实际执行容器)协作。
dockerd 的作用:Docker Daemon (dockerd) 不再直接管理容器,而是作为一个高层管理器,通过 gRPC 接口与 containerd 通信。dockerd 处理用户命令(如 docker run)、镜像构建、网络/卷管理等,并将容器相关操作委托给 containerd。
Docker底层依赖 containerd ,如果不安装 containerd ,Docker 会启动失败,因为 dockerd 需要连接到 containerd.sock(由 containerd 服务生成)。这会导致整个链条崩溃:cri-dockerd → dockerd → containerd。
即使 Kubernetes 通过 cri-dockerd 使用 Docker,Docker 本身还是依赖 containerd 来实际执行容器操作。没有 containerd,cri-dockerd 和 Docker 都无法工作。
# 下载 containerd.service, 版本需要与 docker 二进制包中的 containerd 一致
# https://github.com/containerd/containerd/blob/main/containerd.service
wget https://raw.githubusercontent.com/containerd/containerd/refs/tags/v1.7.28/containerd.service
# containerd 路径修改后,内容如下:
cat >/etc/systemd/system/containerd.service <<EOF
[Unit]
Description=containerd container runtime
Documentation=https://containerd.io
After=network.target local-fs.target dbus.service
[Service]
ExecStartPre=-/sbin/modprobe overlay
ExecStart=/usr/bin/containerd
Type=notify
Delegate=yes
KillMode=process
Restart=always
RestartSec=5
LimitNPROC=infinity
LimitCORE=infinity
LimitNOFILE=infinity
TasksMax=infinity
OOMScoreAdjust=-999
[Install]
WantedBy=multi-user.target
EOF
# 设置 containerd 开机自启
systemctl enable --now containerd.service
# 验证
systemctl is-enabled containerd.service
命令解析:
[Unit] Description=containerd container runtime:指定服务的描述信息。 Documentation=https://containerd.io:指定服务的文档链接。 After=network.target local-fs.target:指定服务的启动顺序,在网络和本地文件系统启动之后再启动该服务。 [Service] ExecStartPre=-/sbin/modprobe overlay:在启动服务之前执行的命令,使用-表示忽略错误。 ExecStart=/usr/bin/containerd:指定服务的启动命令。 Type=notify:指定服务的类型,notify表示服务会在启动完成后向systemd发送通知。 Delegate=yes:允许服务代理其他服务的应答,例如收到关机命令后终止其他服务。 KillMode=process:指定服务终止时的行为,process表示终止服务进程。 Restart=always:指定服务终止后是否自动重启,always表示总是自动重启。 RestartSec=5:指定服务重启的时间间隔,单位为秒。 LimitNPROC=infinity:限制服务的最大进程数,infinity表示没有限制。 LimitCORE=infinity:限制服务的最大核心数,infinity表示没有限制。 LimitNOFILE=1048576:限制服务的最大文件数,指定为1048576。 TasksMax=infinity:限制服务的最大任务数,infinity表示没有限制。 OOMScoreAdjust=-999:指定服务的OOM(Out of Memory)得分,负数表示降低被终止的概率。 [Install] WantedBy=multi-user.target:指定服务的安装方式,multi-user.target表示该服务在多用户模式下安装。
18.3 配置 docker.service
下载地址:https://github.com/moby/moby/blob/master/contrib/init/systemd/docker.service
# 下载 docker.service
wget https://raw.githubusercontent.com/moby/moby/refs/tags/v28.4.0/contrib/init/systemd/docker.service
# 修改后写入到指定目录中
cat > /etc/systemd/system/docker.service <<EOF
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target nss-lookup.target docker.socket firewalld.service containerd.service time-set.target cri-docker.service
Wants=network-online.target containerd.service
Requires=docker.socket containerd.service
StartLimitBurst=3
StartLimitIntervalSec=60
[Service]
Type=notify
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutStartSec=0
RestartSec=2
Restart=always
LimitNPROC=infinity
LimitCORE=infinity
TasksMax=infinity
Delegate=yes
KillMode=process
OOMScoreAdjust=-500
[Install]
WantedBy=multi-user.target
EOF
命令解析:
[Unit] Description: 描述服务的作用,这里是Docker Application Container Engine,即Docker应用容器引擎。 Documentation: 提供关于此服务的文档链接,这里是Docker官方文档链接。 After: 说明该服务在哪些其他服务之后启动,这里是在网络在线、firewalld服务和containerd服务后启动。 Wants: 说明该服务想要的其他服务,这里是网络在线服务。 Requires: 说明该服务需要的其他服务,这里是docker.socket和containerd.service。 [Service] Type: 服务类型,这里是notify,表示服务在启动完成时发送通知。 ExecStart: 命令,启动该服务时会执行的命令,这里是/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock,即启动dockerd并指定一些参数,其中-H指定dockerd的监听地址为fd://,--containerd指定containerd的sock文件位置。 ExecReload: 重载命令,当接收到HUP信号时执行的命令,这里是/bin/kill -s HUP $MAINPID,即发送HUP信号给主进程ID。 TimeoutSec: 服务超时时间,这里是0,表示没有超时限制。 RestartSec: 重启间隔时间,这里是2秒,表示重启失败后等待2秒再重启。 Restart: 重启策略,这里是always,表示总是重启。 StartLimitBurst: 启动限制次数,这里是3,表示在启动失败后最多重试3次。 StartLimitInterval: 启动限制时间间隔,这里是60秒,表示两次启动之间最少间隔60秒。 LimitNOFILE: 文件描述符限制,这里是infinity,表示没有限制。 LimitNPROC: 进程数限制,这里是infinity,表示没有限制。 LimitCORE: 核心转储限制,这里是infinity,表示没有限制。 TasksMax: 最大任务数,这里是infinity,表示没有限制。 Delegate: 修改权限,这里是yes,表示启用权限修改。 KillMode: 杀死模式,这里是process,表示杀死整个进程组。 OOMScoreAdjust: 用于调整进程在系统内存紧张时的优先级调整,这里是-500,表示将OOM分数降低500。 [Install] WantedBy: 安装目标,这里是multi-user.target,表示在多用户模式下安装。 在WantedBy参数中,我们可以使用以下参数: multi-user.target:指定该服务应该在多用户模式下启动。 graphical.target:指定该服务应该在图形化界面模式下启动。 default.target:指定该服务应该在系统的默认目标(runlevel)下启动。 rescue.target:指定该服务应该在系统救援模式下启动。 poweroff.target:指定该服务应该在关机时启动。 reboot.target:指定该服务应该在重启时启动。 halt.target:指定该服务应该在停止时启动。 shutdown.target:指定该服务应该在系统关闭时启动。 这些参数可以根据需要选择一个或多个,以告知系统在何时启动该服务。
18.4 准备 docker 的 socket 文件
下载地址:https://github.com/moby/moby/blob/v28.4.0/contrib/init/systemd/docker.socket
# 下载 docker.socket
wget https://raw.githubusercontent.com/moby/moby/refs/tags/v28.4.0/contrib/init/systemd/docker.socket
# 修改后写入到指定路径
cat > /etc/systemd/system/docker.socket <<EOF
[Unit]
Description=Docker Socket for the API
[Socket]
# If /var/run is not implemented as a symlink to /run, you may need to
# specify ListenStream=/var/run/docker.sock instead.
ListenStream=/var/run/docker.sock
SocketMode=0660
SocketUser=root
SocketGroup=docker
[Install]
WantedBy=sockets.target
EOF
命令解析:
这是一个用于Docker API的socket配置文件,包含了以下参数: [Unit] Description:描述了该socket的作用,即为Docker API的socket。 [Socket] ListenStream:指定了 socket 的监听地址,该 socket 会监听在 /var/run/docker.sock 上,即 Docker 守护程序使用的默认 sock 文件。 SocketMode:指定了socket文件的权限模式,此处为0660,即用户和用户组有读写权限,其他用户无权限。 SocketUser:指定了socket文件的所有者,此处为root用户。 SocketGroup:指定了socket文件的所属用户组,此处为docker用户组。 [Install] WantedBy:指定了该socket被启用时的目标,此处为sockets.target,表示当sockets.target启动时启用该socket。 该配置文件的作用是为 Docker 提供 API 访问的通道,它监听在 /var/run/docker.sock 上,具有 root 用户权限,但只接受 docker 用户组的成员的连接,并且其他用户无法访问。这样,只有 docker 用户组的成员可以通过该 socket 与 Docker 守护进程进行通信。
18.5 配置 Docker 加速器
# 创建 docker 配置目录 和 数据目录
mkdir /etc/docker/ /data/docker -pv
# 写入docker配置,这里也修改了docker默认的数据目录
cat > /etc/docker/daemon.json <<EOF
{
"exec-opts": ["native.cgroupdriver=systemd"],
"registry-mirrors": [
"https://kfp63jaj.mirror.aliyuncs.com",
"https://hub-mirror.c.163.com",
"https://mirror.baidubce.com"
],
"max-concurrent-downloads": 10,
"log-driver": "json-file",
"log-level": "warn",
"log-opts": {
"max-size": "10m",
"max-file": "3"
},
"data-root": "/data/docker"
}
EOF
命令解析:
该参数文件中包含以下参数: exec-opts: 用于设置Docker守护进程的选项,native.cgroupdriver=systemd表示使用systemd作为Cgroup驱动程序。 registry-mirrors: 用于指定Docker镜像的镜像注册服务器。在这里有三个镜像注册服务器:https://docker.m.daocloud.io、https://docker.mirrors.ustc.edu.cn和http://hub-mirror.c.163.com。 max-concurrent-downloads: 用于设置同时下载镜像的最大数量,默认值为3,这里设置为10。 log-driver: 用于设置Docker守护进程的日志驱动程序,这里设置为json-file。 log-level: 用于设置日志的级别,这里设置为warn。 log-opts: 用于设置日志驱动程序的选项,这里有两个选项:max-size和max-file。max-size表示每个日志文件的最大大小,这里设置为10m,max-file表示保存的最大日志文件数量,这里设置为3。 data-root: 用于设置Docker守护进程的数据存储根目录,默认为/var/lib/docker,这里设置为 /data/docker。
18.6 启动 Docker
# 创建一个名为 docker 的组
groupadd docker
# 通知systemd重新加载所有单元配置文件(unit files),以识别新创建或修改的配置文件
systemctl daemon-reload
# 启用并立即启动Docker的socket单元(docker.socket),使其在系统启动时自动运行,并现在开始监听。
systemctl enable --now docker.socket
# 启用并立即启动Docker守护进程服务(docker.service),使其在系统启动时自动运行,并现在开始运行。
systemctl enable --now docker.service
# 重启docker.socket单元
systemctl restart --now docker.socket
# 重启docker.service单元,即重新启动Docker守护进程。
systemctl restart docker.service
# 验证:查看 docker 服务状态
systemctl status docker.service
# 验证:查看docker信息
docker info
19. 安装 cri-docker
19.1 安装 cri-docker 二进制包
cri-docker 与 docker的版本匹配关系:https://github.com/Mirantis/cri-dockerd/releases/tag/v0.4.0
# 下载 cri-docker 二进制包
wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.4.0/cri-dockerd-0.4.0.amd64.tgz
# 解压
tar xvf cri-dockerd-*.amd64.tgz
# 复制到 /usr/bin/
cp cri-dockerd/cri-dockerd /usr/bin/
# 授权
chmod +x /usr/bin/cri-dockerd
# 验证
$ cri-dockerd --version
cri-dockerd 0.4.0 (b9b8893)
19.2 配置 cri-docker.service
从 github 获取文件:https://github.com/Mirantis/cri-dockerd/tree/master/packaging/systemd
# 下载 cri-docker.service 文件
wget https://raw.githubusercontent.com/Mirantis/cri-dockerd/refs/tags/v0.4.0/packaging/systemd/cri-docker.service
# 修改 ExecStart 启动命令后,写入到指定目录
cat > /usr/lib/systemd/system/cri-docker.service <<EOF
[Unit]
Description=CRI Interface for Docker Application Container Engine
Documentation=https://docs.mirantis.com
After=network-online.target firewalld.service docker.service
Wants=network-online.target
Requires=cri-docker.socket
[Service]
Type=notify
# 修啊该启动命令
ExecStart=/usr/bin/cri-dockerd --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.9 --container-runtime-endpoint=unix:///var/run/cri-dockerd.sock --cri-dockerd-root-directory=/data/dockershim --cri-dockerd-root-directory=/data/docker
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always
StartLimitBurst=3
StartLimitInterval=60s
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
TasksMax=infinity
Delegate=yes
KillMode=process
[Install]
WantedBy=multi-user.target
EOF
命令解析:
[Unit] Description:该参数用于描述该单元的功能,这里描述的是CRI与Docker应用容器引擎的接口。 Documentation:该参数指定了相关文档的网址,供用户参考。 After:该参数指定了此单元应该在哪些其他单元之后启动,确保在网络在线、防火墙和Docker服务启动之后再启动此单元。 Wants:该参数指定了此单元希望也启动的所有单元,此处是希望在网络在线之后启动。 Requires:该参数指定了此单元需要依赖的单元,此处是cri-docker.socket单元。 [Service] Type:该参数指定了服务的类型,这里是notify,表示当服务启动完成时向系统发送通知。 ExecStart:该参数指定了将要运行的命令和参数,此处是执行/usr/bin/cri-dockerd 命令,并指定了网络插件为cni和Pod基础设施容器的镜像为registry.aliyuncs.com/google_containers/pause:3.9。 - --container-runtime-endpoint=unix:///var/run/cri-dockerd.sock - 定义 CRI 的监听端点。 - --cri-dockerd-root-directory=/data/dockershim - 定义 cri-dockerd 的根目录,用于存储临时文件或配置数据。 - --cri-dockerd-root-directory=/data/docker - 定义 Docker 的根目录。 ExecReload:该参数指定在服务重载时运行的命令,此处是发送HUP信号给主进程。 TimeoutSec:该参数指定了服务启动的超时时间,此处为0,表示无限制。 RestartSec:该参数指定了自动重启服务的时间间隔,此处为2秒。 Restart:该参数指定了在服务发生错误时自动重启,此处是始终重启。 StartLimitBurst:该参数指定了在给定时间间隔内允许的启动失败次数,此处为3次。 StartLimitInterval:该参数指定启动失败的时间间隔,此处为60秒。 LimitNOFILE:该参数指定了允许打开文件的最大数量,此处为无限制。 LimitNPROC:该参数指定了允许同时运行的最大进程数,此处为无限制。 LimitCORE:该参数指定了允许生成的core文件的最大大小,此处为无限制。 TasksMax:该参数指定了此服务的最大任务数,此处为无限制。 Delegate:该参数指定了是否将控制权委托给指定服务,此处为是。 KillMode:该参数指定了在终止服务时如何处理进程,此处是通过终止进程来终止服务。 [Install] WantedBy:该参数指定了希望这个单元启动的多用户目标。在这里,这个单元希望在multi-user.target启动。
19.3 配置 cri-docker.socket
从 github 获取文件:https://github.com/Mirantis/cri-dockerd/tree/master/packaging/systemd
# 下载
wget https://raw.githubusercontent.com/Mirantis/cri-dockerd/refs/tags/v0.4.0/packaging/systemd/cri-docker.socket
# 修改 ListenStream,并写入到指令目录
cat > /usr/lib/systemd/system/cri-docker.socket <<EOF
[Unit]
Description=CRI Docker Socket for the API
PartOf=cri-docker.service
[Socket]
ListenStream=/var/run/cri-dockerd.sock
SocketMode=0660
SocketUser=root
SocketGroup=docker
[Install]
WantedBy=sockets.target
EOF
命令解析:
该配置文件是用于systemd的单元配置文件(unit file),用于定义一个socket单元。 [Unit] Description:表示该单元的描述信息。 PartOf:表示该单元是cri-docker.service的一部分。 [Socket] ListenStream:指定了该socket要监听的地址和端口,这里要与 cri-docker.service 配置的 ExecStart 指定的套接字一致,都为 /var/run/cri-dockerd.sock。Unix域套接字用于在同一台主机上的进程之间通信。 SocketMode:指定了socket文件的权限模式,此处为0660,即用户和用户组有读写权限,其他用户无权限。 SocketUser:指定了socket文件的所有者,此处为root用户。 SocketGroup:指定了socket文件的所属用户组,此处为docker用户组。 [Install] WantedBy:部分定义了该单元的安装配置信息。WantedBy=sockets.target表示当sockets.target单元启动时,自动启动该socket单元。sockets.target是一个系统服务,用于管理所有的socket单元。
19.4 启动 cri-docker
# 通知systemd重新加载所有单元配置文件(unit files),以识别新创建或修改的配置文件
systemctl daemon-reload
# 设置开机自启
systemctl enable --now cri-docker.service
systemctl enable --now cri-docker.socket
# 重启cri-docker.service单元,即重新启动cri-docker守护进程。
systemctl restart cri-docker.service
# 验证,查看状态
systemctl status cri-docker.service
四、导入镜像
# calico 镜像必须导入,每个Node节点都需要运行Calico网络
docker load -i /opt/software/images/calico/cni-v3.28.0.tar
docker load -i /opt/software/images/calico/node-v3.28.0.tar
docker load -i /opt/software/images/calico/kube-controllers-v3.28.0.tar
docker load -i /opt/software/images/calico/typha-v3.28.0.tar
五、Node 配置
1. Nginx 配置
1.1 编译安装
node节点
# 安装编译环境
yum install -y openssl-devel pcre-devel gcc
# 下载解压 nginx 二进制文件
wget http://nginx.org/download/nginx-1.25.3.tar.gz
tar xvf nginx-*.tar.gz
cd nginx-1.25.3
# 进行编译
./configure --prefix=/usr/local/nginx --sbin-path=/bin/ --user=nginx --group=nginx --with-stream --with-http_ssl_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --without-http --without-http_uwsgi_module --without-http_scgi_module --without-http_fastcgi_module
make && make install
# 验证
$ nginx -v
nginx version: nginx/1.25.3
1.2 nginx 配置文件
node节点
# 写入配置文件(在所有主机上执行)
cat > /usr/local/nginx/conf/kube-nginx.conf <<EOF
worker_processes 1;
user nobody;
events {
worker_connections 1024;
}
stream {
upstream backend {
least_conn;
hash $remote_addr consistent;
server 10.20.1.101:6443 max_fails=3 fail_timeout=30s;
server 10.20.1.102:6443 max_fails=3 fail_timeout=30s;
server 10.20.1.103:6443 max_fails=3 fail_timeout=30s;
}
server {
listen 127.0.0.1:8443;
proxy_connect_timeout 1s;
proxy_pass backend;
}
}
EOF
命令解析:
该命令用于创建 Nginx 配置文件 /usr/local/nginx/conf/kube-nginx.conf,配置 Nginx 作为 Kubernetes API 服务器的负载均衡器,处理 TCP 流量(端口 6443)
upstream backend
将本地 8443 端口的请求分发到三个 master 节点的 API 服务器的 6443 端口
least_conn;
选择当前活跃连接数最少的后端服务器进行负载均衡
hash $remote_addr consistent;
基于客户端 IP($remote_addr)进行一致性哈希,确保同一客户端始终连接到同一后端服务器
max_fails=3 fail_timeout=30s;
max_fails=3(失败 3 次后标记为不可用),fail_timeout=30s(标记不可用后 30 秒内不尝试)
6443 端口是 Kubernetes API 服务器(kube-apiserver)的默认端口,接受来自客户端(如 kubectl、kubelet、控制器等)的 HTTPS 请求。
8443 端口是 kube-apiserver 的代理端口,用于接收请求,并将请求转发到真正的 6443 端口
1.3 配置 Nginx Service
node节点
cat > /etc/systemd/system/kube-nginx.service <<EOF
[Unit]
Description=kube-apiserver nginx proxy
After=network.target
After=network-online.target
Wants=network-online.target
[Service]
Type=forking
ExecStartPre=/bin/nginx -c /usr/local/nginx/conf/kube-nginx.conf -p /usr/local/nginx -t
ExecStart=/bin/nginx -c /usr/local/nginx/conf/kube-nginx.conf -p /usr/local/nginx
ExecReload=/bin/nginx -c /usr/local/nginx/conf/kube-nginx.conf -p /usr/local/nginx -s reload
PrivateTmp=true
Restart=always
RestartSec=5
StartLimitInterval=0
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
命令解析:
创建一个 systemd 单元文件,用于管理系统服务。这个文件定义了一个名为 kube-nginx 的服务,负责运行 Nginx 作为 Kubernetes API 服务器的负载均衡代理
Nginx 在这里被配置为 TCP 负载均衡器(非 HTTP),运行在每个 master 节点(k8s-master01、k8s-master02、k8s-master03,IP 分别为 192.168.10.11、12、13),监听本地 127.0.0.1:8443 端口,并将请求分发到三个 master 节点的 API 服务器端口 6443。
After=network.target :基本网络接口配置完成
After=network-online.target :网络完全在线(可路由外部)
Wants=network-online.target :声明弱依赖,建议(但不强制)在 network-online.target 启动后运行服务
Type=forking:
forking 表示主进程派生子进程(如 Nginx master 进程派生 worker),systemd 跟踪子进程 PID(从 PID 文件读取)
ExecStartPre=/bin/nginx -c /usr/local/nginx/conf/kube-nginx.conf -p /usr/local/nginx -t
启动前执行的预命令。-t 测试配置文件语法
ExecStart=/bin/nginx -c /usr/local/nginx/conf/kube-nginx.conf -p /usr/local/nginx
启动服务的核心命令,运行 Nginx。 博客上下文:启动 Nginx,加载 kube-nginx.conf,启用 TCP 负载均衡(8443 到 6443)
ExecReload=/bin/nginx -c /usr/local/nginx/conf/kube-nginx.conf -p /usr/local/nginx -s reload
重新加载配置的命令(systemctl reload kube-nginx)。-s reload 发送信号平滑重载
PrivateTmp=true :为服务分配私有 /tmp 和 /var/tmp 目录,隔离系统临时文件
Restart=always :失败或退出时自动重启。always 表示无论原因都重启
RestartSec=5 :重启前等待时间(秒)
StartLimitInterval=0 :重启时间窗口(秒),0 表示无限制。
LimitNOFILE=65536 :最大文件描述符数,防止 “too many open files” 错误
WantedBy=multi-user.target : 服务在多用户模式下启用, 确保 Nginx 随系统启动。
1.4 设置 Nginx 开机自启
# 刷新系统服务
systemctl daemon-reload
# 设置 kube-nginx 开机自启
systemctl enable --now kube-nginx.service
# 查看 nginx 启动状态
systemctl status kube-nginx.service
2. 复制文件至 node 节点
在 master01 节点操作
2.1 复制证书
user=root
host=(k8s-node03 k8s-node04 k8s-node05)
for i in ${host[@]}; do
ssh $user@$i "sudo mkdir -p /etc/kubernetes/pki/";
rsync --rsync-path="sudo rsync" /etc/kubernetes/pki/{ca.pem,ca-key.pem,front-proxy-ca.pem} $user@$i:/etc/kubernetes/pki/;
rsync --rsync-path="sudo rsync" /etc/kubernetes/{bootstrap-kubelet.kubeconfig,kube-proxy.kubeconfig,kubelet.kubeconfig} $user@$i:/etc/kubernetes/;
done
2.2 复制二进制安装包
# 拷贝 worker 组件
hots='k8s-node03 k8s-node04 k8s-node05'
user=root
for i in $hots; do
echo $i;
rsync --rsync-path="sudo rsync" /usr/local/bin/kube{let,-proxy} $user@$i:/usr/local/bin/;
done
3. 配置 kubelet(所有节点)
3.1 编辑 kubelet.service
Node节点
# 当使用 docker 作为 Runtime
# IPv4示例
cat > /usr/lib/systemd/system/kubelet.service << EOF
[Unit]
Description=Kubernetes Kubelet
Documentation=https://github.com/kubernetes/kubernetes
After=network-online.target firewalld.service cri-docker.service docker.socket containerd.service
Wants=network-online.target
Requires=docker.socket containerd.service
[Service]
ExecStart=/usr/local/bin/kubelet \\
--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.kubeconfig \\
--kubeconfig=/etc/kubernetes/kubelet.kubeconfig \\
--config=/etc/kubernetes/kubelet-conf.yml \\
--container-runtime-endpoint=unix:///run/cri-dockerd.sock \\
--node-labels=node.kubernetes.io/node=
[Install]
WantedBy=multi-user.target
EOF
# IPv6示例
# 若不使用IPv6那么忽略此项即可
# 下方 --node-ip 更换为每个节点的IP即可
# cat > /usr/lib/systemd/system/kubelet.service << EOF
# [Unit]
# Description=Kubernetes Kubelet
# Documentation=https://github.com/kubernetes/kubernetes
# After=network-online.target firewalld.service cri-docker.service docker.socket # containerd.service
# Wants=network-online.target
# Requires=docker.socket containerd.service
# [Service]
# ExecStart=/usr/local/bin/kubelet \\
# --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.kubeconfig \\
# --kubeconfig=/etc/kubernetes/kubelet.kubeconfig \\
# --config=/etc/kubernetes/kubelet-conf.yml \\
# --container-runtime-endpoint=unix:///run/cri-dockerd.sock \\
# --node-labels=node.kubernetes.io/node= \\
# --node-ip=192.168.1.31,2408:822a:245:8c01::fab
# [Install]
# WantedBy=multi-user.target
# EOF
- 注意node-labels=node.kubernetes.io/node=
''ubuntu为''centos为空
命令解析:
- –bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.kubeconfig:引导 kubeconfig 文件路径。用于 TLS Bootstrapping(节点自动加入集群的机制)。kubelet 使用此文件向 API Server 请求证书,首次启动时使用
- –kubeconfig=/etc/kubernetes/kubelet.kubeconfig:最终的 kubeconfig 文件路径。引导成功后,kubelet 会切换到这个文件,用于与 Kubernetes API Server 通信。
- –config=/etc/kubernetes/kubelet-conf.yml:kubelet 的 YAML 配置文件路径(包含详细配置,如 cgroup 驱动、Pod 限制等)。这个文件在稍后定义。
- –container-runtime-endpoint=unix:///run/cri-dockerd.sock:容器运行时端点。指定使用 cri-dockerd 的 Unix socket(因为使用 Docker + cri-dockerd 作为 CRI 兼容运行时,而不是直接用 containerd 或 CRI-O)。
- –node-labels=node.kubernetes.io/node=:节点标签。为空值(可以自定义标签,如用于节点分组)。这里的 = 后无内容,表示一个空标签
3.2 编辑 kubelet-conf.yml
官方文档:https://kubernetes.io/zh-cn/docs/reference/config-api/kubelet-config.v1beta1/
Master01
cat > /etc/kubernetes/kubelet-conf.yml <<EOF
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
address: 0.0.0.0
port: 10250
readOnlyPort: 10255
authentication:
anonymous:
enabled: false
webhook:
cacheTTL: 2m0s
enabled: true
x509:
clientCAFile: /etc/kubernetes/pki/ca.pem
authorization:
mode: Webhook
webhook:
cacheAuthorizedTTL: 5m0s
cacheUnauthorizedTTL: 30s
cgroupDriver: systemd
cgroupsPerQOS: true
clusterDNS:
- 10.96.0.10
clusterDomain: cluster.local
containerLogMaxFiles: 5
containerLogMaxSize: 10Mi
contentType: application/vnd.kubernetes.protobuf
cpuCFSQuota: true
cpuManagerPolicy: none
cpuManagerReconcilePeriod: 10s
enableControllerAttachDetach: true
enableDebuggingHandlers: true
enforceNodeAllocatable:
- pods
eventBurst: 10
eventRecordQPS: 5
evictionHard:
imagefs.available: 15%
memory.available: 100Mi
nodefs.available: 10%
nodefs.inodesFree: 5%
evictionPressureTransitionPeriod: 5m0s
failSwapOn: true
fileCheckFrequency: 20s
hairpinMode: promiscuous-bridge
healthzBindAddress: 127.0.0.1
healthzPort: 10248
httpCheckFrequency: 20s
imageGCHighThresholdPercent: 85
imageGCLowThresholdPercent: 80
imageMinimumGCAge: 2m0s
iptablesDropBit: 15
iptablesMasqueradeBit: 14
kubeAPIBurst: 10
kubeAPIQPS: 5
makeIPTablesUtilChains: true
maxOpenFiles: 1000000
maxPods: 110
nodeStatusUpdateFrequency: 10s
oomScoreAdj: -999
podPidsLimit: -1
registryBurst: 10
registryPullQPS: 5
resolvConf: /etc/resolv.conf
rotateCertificates: true
runtimeRequestTimeout: 2m0s
serializeImagePulls: true
staticPodPath: /etc/kubernetes/manifests
streamingConnectionIdleTimeout: 4h0m0s
syncFrequency: 1m0s
volumeStatsAggPeriod: 1m0s
EOF
命令解析:
创建 Kubernetes 的 kubelet 配置文件 /etc/kubernetes/kubelet-conf.yml。该文件是 kubelet 的主要配置文件,定义了 kubelet 的运行行为、资源管理、网络配置等关键参数。kubelet 是 Kubernetes 节点上的核心组件,负责管理 Pod、容器生命周期、节点资源等。
apiVersion: 指定配置文件使用的 Kubernetes API 版本。这里是 kubelet.config.k8s.io/v1beta1,表示 kubelet 配置的 v1beta1 版本。
kind: 指定配置类型为 KubeletConfiguration,这是 kubelet 的专用配置类型。
address: kubelet 的监听地址。0.0.0.0 表示监听所有网络接口,允许外部访问(如 API Server 或 kubectl)。
port: kubelet 的主端口,用于处理 HTTPS 请求(如状态查询、命令执行)。默认值为 10250。
readOnlyPort: 只读端口,提供无认证的只读访问(如健康检查或状态查询)。默认值为 10255。注意:在高安全性环境中,建议禁用只读端口(设置为 0)以防止未经授权的访问。
authentication: 定义 kubelet 的认证机制。
- anonymous.enabled: 是否允许匿名访问。false 表示禁用匿名访问,增强安全性。
- webhook.enabled: 是否启用 Webhook 认证。true 表示 kubelet 通过向 API Server 发送 Webhook 请求验证客户端身份。
- webhook.cacheTTL: Webhook 认证结果的缓存时间,设置为 2m0s(2 分钟),减少重复验证开销。
- x509.clientCAFile: 指定用于验证客户端证书的 CA 文件路径(/etc/kubernetes/pki/ca.pem)。客户端(如 API Server)必须提供由该 CA 签发的证书。
authorization: 定义 kubelet 的授权机制。
- mode: Webhook: 使用 Webhook 模式向 API Server 请求授权决定(基于 RBAC 或其他授权策略)。
- webhook.cacheAuthorizedTTL: 已授权请求的缓存时间,5m0s(5 分钟)。
- webhook.cacheUnauthorizedTTL: 未授权请求的缓存时间,30s(30 秒)。较短的未授权缓存时间确保快速更新拒绝策略。
cgroupDriver: 指定 kubelet 使用的 cgroup 驱动程序。systemd 表示使用 systemd 管理 cgroup,与 Docker 的 systemd cgroup 驱动一致(配置了 Docker 的 daemon.json 使用 native.cgroupdriver=systemd)。
cgroupsPerQOS: 是否为不同 QoS(服务质量)级别的 Pod 创建单独的 cgroup。true 启用此功能,确保 Guaranteed、Burstable 和 BestEffort Pod 的资源隔离。
clusterDNS: 指定集群内 DNS 服务的 IP 地址。10.96.0.10 是 CoreDNS 的服务 IP(与安装 CoreDNS 时配置的 clusterIP 一致)。
clusterDomain: 指定集群的 DNS 域名后缀。cluster.local 是默认值,用于解析服务名称(如 my-service.default.svc.cluster.local)。
containerLogMaxFiles: 每个容器的最大日志文件数(轮转日志)。5 表示保留最多 5 个日志文件。
containerLogMaxSize: 每个日志文件的最大大小。10Mi 表示 10MB,超过后会触发日志轮转。
contentType: 指定 kubelet 与 API Server 通信时使用的内容类型。application/vnd.kubernetes.protobuf 表示使用 Protobuf 格式(比 JSON 更高效)。
cpuCFSQuota: 是否为容器启用 CPU CFS(Completely Fair Scheduler)配额。true 表示限制容器 CPU 使用量,基于 Pod 的 QoS 设置。
cpuManagerPolicy: CPU 分配策略。none 表示不使用 CPU 管理器(不分配专用 CPU 核心,Pod 共享 CPU 资源)。
cpuManagerReconcilePeriod: CPU 管理器的协调周期。10s 表示每 10 秒检查并调整 CPU 分配(尽管策略为 none,此参数仍需设置)。
enableControllerAttachDetach: 是否允许控制器管理卷的挂载和卸载。true 表示由 kubelet 和控制器协同处理卷操作。
enableDebuggingHandlers: 是否启用调试端点(如 /debug/pprof)。true 允许访问调试信息,便于性能分析。
enforceNodeAllocatable: 指定强制限制的资源类型。pods 表示对 Pod 分配的资源进行限制,确保节点保留系统和 kubelet 所需的资源(如内存、CPU)。
eventBurst: 事件处理的突发容量。10 表示允许短时间内处理最多 10 个事件。
eventRecordQPS: 每秒记录的事件数。5 表示平均每秒记录 5 个事件,控制事件报告频率以避免 API Server 过载。
evictionHard: 定义硬性驱逐阈值,当资源低于以下值时,kubelet 会驱逐 Pod 以回收资源:
- imagefs.available: 镜像文件系统可用空间低于 15% 时触发驱逐。
- memory.available: 可用内存低于 100Mi(100MB)时触发驱逐。
- nodefs.available: 节点文件系统可用空间低于 10% 时触发驱逐。
- nodefs.inodesFree: 节点文件系统可用 inode 低于 5% 时触发驱逐。
evictionPressureTransitionPeriod: 驱逐压力过渡期。5m0s 表示在资源压力缓解后,等待 5 分钟才停止驱逐。
failSwapOn: 是否允许在启用 swap 分区时启动 kubelet。true 表示如果 swap 启用,kubelet 将启动失败(当前已禁用 swap)。
fileCheckFrequency: 检查文件变更的频率。20s 表示每 20 秒检查一次(如 Pod 配置文件)。
hairpinMode: 指定 hairpin 流量(Pod 访问自身服务 IP)的处理方式。promiscuous-bridge 表示使用网桥的混杂模式,适用于 Calico 等 CNI 插件。
healthzBindAddress: 健康检查监听地址。127.0.0.1 表示仅本地可访问,增强安全性。
healthzPort: 健康检查端口。10248 是默认值,用于 /healthz 端点。
httpCheckFrequency: HTTP 健康检查频率。20s 表示每 20 秒检查一次。
imageGCHighThresholdPercent: 镜像垃圾回收的上限阈值。磁盘使用率达到 85% 时触发回收。
imageGCLowThresholdPercent: 镜像垃圾回收的下限阈值。回收后磁盘使用率低于 80% 时停止。
imageMinimumGCAge: 镜像的最小保留时间。2m0s 表示镜像至少保留 2 分钟,防止频繁回收。
iptablesDropBit: 用于标记丢弃数据包的 iptables 位。15 是默认值。
iptablesMasqueradeBit: 用于 SNAT(源地址转换)的 iptables 位。14 是默认值。
makeIPTablesUtilChains: 是否创建 iptables 工具链。true 表示 kubelet 自动管理 iptables 规则。
kubeAPIBurst: 与 API Server 通信的突发请求数。10 表示短时间内最多发送 10 个请求。
kubeAPIQPS: 与 API Server 通信的每秒请求数。5 表示平均每秒 5 个请求,控制负载。
maxOpenFiles: 最大打开文件数。1000000 允许 kubelet 处理大量文件描述符。
maxPods: 节点上最大 Pod 数。110 是默认值,限制节点负载。
podPidsLimit: 每个 Pod 的最大 PID 数。-1 表示无限制。
nodeStatusUpdateFrequency: 节点状态更新频率。10s 表示每 10 秒向 API Server 报告节点状态。
oomScoreAdj: kubelet 进程的 OOM(内存不足)优先级。-999 表示低优先级,降低被杀死概率。
registryBurst: 从镜像仓库拉取镜像的突发请求数。10 表示最多 10 个并发请求。
registryPullQPS: 镜像拉取的每秒请求数。5 表示平均每秒 5 个请求。
resolvConf: DNS 解析配置文件路径。/etc/resolv.conf 是系统默认值。
rotateCertificates: 是否启用证书轮换。true 表示自动更新过期证书。
runtimeRequestTimeout: 容器运行时请求超时时间。2m0s 表示 2 分钟。
serializeImagePulls: 是否串行拉取镜像。true 表示一次拉取一个镜像,降低资源争用。
staticPodPath: 静态 Pod 的清单目录。/etc/kubernetes/manifests 用于存放静态 Pod 的 YAML 文件。
streamingConnectionIdleTimeout: 流式连接(如 kubectl exec)的空闲超时。4h0m0s 表示 4 小时。
syncFrequency: Pod 同步频率。1m0s 表示每分钟同步一次 Pod 状态。
volumeStatsAggPeriod: 卷统计聚合周期。1m0s 表示每分钟收集一次卷使用数据。
3.3 启动 kubelet
systemctl daemon-reload
systemctl enable --now kubelet
systemctl status kubelet
3.4 测试
[root@k8s-master01 ~]$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master01 Ready <none> 9d v1.29.2
k8s-master02 Ready <none> 9d v1.29.2
k8s-master03 Ready <none> 9d v1.29.2
k8s-node01 Ready <none> 9d v1.29.2
k8s-node02 Ready <none> 9d v1.29.2
k8s-node03 NotReady <none> 53s v1.29.2
k8s-node04 NotReady <none> 25s v1.29.2
k8s-node05 NotReady <none> 20s v1.29.2
4. kube-proxy 配置(所有Node节点)
4.1 编辑 kube-proxy.service
Node 节点
cat > /usr/lib/systemd/system/kube-proxy.service << EOF
[Unit]
Description=Kubernetes Kube Proxy
Documentation=https://github.com/kubernetes/kubernetes
After=network.target
[Service]
ExecStart=/usr/local/bin/kube-proxy \\
--config=/etc/kubernetes/kube-proxy.yaml \\
--cluster-cidr=172.16.0.0/12,fc00:2222::/112 \\
--v=2
Restart=always
RestartSec=10s
[Install]
WantedBy=multi-user.target
EOF
命令解析:
kube-proxy是Kubernetes的核心组件之一,负责处理Service和Pod的网络代理(如负载均衡、NAT等),确保集群内的网络通信正常工作。
适用节点:所有Kubernetes节点(Master和Node),因为kube-proxy需要在每个节点上运行,以处理本地Pod的网络流量。
ExecStart=/usr/local/bin/kube-proxy
执行命令:指定服务的启动命令,即运行/usr/local/bin/kube-proxy二进制文件
–config=/etc/kubernetes/kube-proxy.yaml
配置参数:指定kube-proxy的配置文件路径。这个YAML文件(教程中稍后定义)包含详细配置,如代理模式(IPVS)、绑定地址、连接跟踪等。使用配置文件可以分离配置,便于维护和统一所有节点。
–cluster-cidr=172.16.0.0/12,fc00:2222::/112
172.16.0.0/12:IPv4 Pod CIDR(私有地址段,范围从172.16.0.0到172.31.255.255,可容纳大量Pod)。
fc00:2222::/112:IPv6 Pod CIDR(ULA私有地址,支持双栈网络)。
4.2 编辑 kube-proxy.yaml
官方文档:https://kubernetes.io/zh-cn/docs/reference/config-api/kube-proxy-config.v1alpha1/
cat > /etc/kubernetes/kube-proxy.yaml << EOF
apiVersion: kubeproxy.config.k8s.io/v1alpha1
bindAddress: 0.0.0.0
clientConnection:
acceptContentTypes: ""
burst: 10
contentType: application/vnd.kubernetes.protobuf
kubeconfig: /etc/kubernetes/kube-proxy.kubeconfig
qps: 5
clusterCIDR: 172.16.0.0/12,fc00:2222::/112
configSyncPeriod: 15m0s
conntrack:
max: null
maxPerCore: 32768
min: 131072
tcpCloseWaitTimeout: 1h0m0s
tcpEstablishedTimeout: 24h0m0s
enableProfiling: false
healthzBindAddress: 0.0.0.0:10256
hostnameOverride: ""
iptables:
masqueradeAll: false
masqueradeBit: 14
minSyncPeriod: 0s
syncPeriod: 30s
ipvs:
masqueradeAll: true
minSyncPeriod: 5s
scheduler: "rr"
syncPeriod: 30s
kind: KubeProxyConfiguration
metricsBindAddress: 127.0.0.1:10249
mode: "ipvs"
nodePortAddresses: null
oomScoreAdj: -999
portRange: ""
udpIdleTimeout: 250ms
EOF
命令解析:
kube-proxy 的配置文件,定义了 Kubernetes 集群中 kube-proxy 组件的行为。kube-proxy 运行在每个节点上,负责处理 Service 和 Pod 的网络代理(如负载均衡、NAT),支持 Kubernetes 的网络功能。
apiVersion: kubeproxy.config.k8s.io/v1alpha1
指定配置文件的 API 版本,告诉 Kubernetes 使用 kubeproxy.config.k8s.io/v1alpha1 版本的 KubeProxyConfiguration 资源格式来解析此文件
bindAddress: 0.0.0.0
监听所有网络接口(IPv4 和 IPv6),允许 kube-proxy 接受来自任何网络接口的请求。0.0.0.0 确保 kube-proxy 能处理两种协议的流量
clientConnection: 定义 kube-proxy 与 Kubernetes API 服务器的通信参数
- acceptContentTypes: “” :指定 kube-proxy 接受的 API 响应内容类型,空字符串表示接受默认类型(通常由 contentType 定义)
- burst: 10 允许的突发请求数(QPS 的上限),控制 kube-proxy 向 API 服务器发送请求的速率
- contentType: application/vnd.kubernetes.protobuf 与 API 服务器通信时使用的内容类型,比 JSON(application/json)更高效,减少网络带宽
- kubeconfig: /etc/kubernetes/kube-proxy.kubeconfig 访问 API 服务器的 kubeconfig 文件路径
- qps: 5 每秒向 API 服务器发送的请求数,限制 kube-proxy 的 API 请求速率,qps: 5 表示每秒最多 5 个请求,配合 burst 控制突发
clusterCIDR: 172.16.0.0/12,fc00:2222::/112 定义集群的 Pod IP 地址范围(Pod CIDR),与 Calico 的 CALICO_IPV4POOL_CIDR 和 CALICO_IPV6POOL_CIDR 一致(calico.yaml 或 calico-ipv6.yaml)
configSyncPeriod: 15m0s kube-proxy 同步配置的间隔时间,每 15 分钟,kube-proxy 从 API 服务器重新获取 Service 和 Endpoint 配置,更新本地代理规则
conntrack: 配置连接跟踪(Connection Tracking),用于 NAT 和负载均衡
- max: null 系统中连接跟踪表的最大条目数,null 表示使用系统默认值(通常由内核参数 net.nf_conntrack_max 决定)
- maxPerCore: 32768 每个 CPU 核心的连接跟踪条目上限
- min: 131072 连接跟踪表的最小条目数
- tcpCloseWaitTimeout: 1h0m0s TCP 连接在 CLOSE_WAIT 状态的超时时间,连接关闭后,等待 1 小时释放资源,防止短时间内频繁释放导致性能问题
- tcpEstablishedTimeout: 24h0m0s 已建立的 TCP 连接的超时时间, 保持长连接(如数据库连接)24 小时,减少重新建立开销
enableProfiling: false 是否启用 kube-proxy 的性能分析(profiling),false 禁用 profiling,降低资源消耗
healthzBindAddress: 0.0.0.0:10256 健康检查监听地址和端口,kube-proxy 在 0.0.0.0:10256 提供 /healthz 端点,供 kubelet 或外部工具检查状态
hostnameOverride: “” 覆盖 kube-proxy 报告的节点主机名,空字符串表示使用节点默认主机名(由 uname -n 或 kubelet 提供)
iptables: 配置 iptables 代理模式(尽管当前使用 IPVS,此配置仍保留)
- masqueradeAll: false 是否对所有出站流量执行 NAT 伪装(SNAT),false 表示仅对 Service 相关的流量执行 NAT,减少开销
- masqueradeBit: 14 iptables 伪装时使用的标记位,默认值 14 用于标记 NAT 流量,防止冲突
- minSyncPeriod: 0s iptables 规则同步的最小间隔,0s 表示无最小间隔,允许快速同步
- syncPeriod: 30s iptables 规则同步的周期,每 30 秒同步 iptables 规则,确保与 API 服务器一致
ipvs: 配置 IPVS 代理模式(本文明确使用 mode: “ipvs”)
- masqueradeAll: true 是否对所有出站流量执行 NAT 伪装。true 表示对所有 Pod 流量执行 SNAT,适合 IPVS 模式,确保外部访问(如 NodePort)正确。
- minSyncPeriod: 5s IPVS 规则同步的最小间隔。确保至少 5 秒同步一次,防止频繁更新导致性能问题。
- scheduler: “rr” IPVS 负载均衡调度算法。rr(Round Robin,轮询)平均分配 Service 流量到后端 Pod
- syncPeriod: 30s IPVS 规则同步周期。每 30 秒同步 IPVS 规则,确保与 API 服务器一致。
kind: KubeProxyConfiguration 指定资源的类型,声明这是 kube-proxy 的配置文件
metricsBindAddress: 127.0.0.1:10249 指标(metrics)监听地址和端口,kube-proxy 在 127.0.0.1:10249 提供 Prometheus 格式的指标,供监控系统(如 Prometheus)采集
mode: “ipvs” kube-proxy 的代理模式, ipvs 模式使用 Linux IPVS(IP Virtual Server)实现高效负载均衡。
nodePortAddresses: null NodePort 服务的监听地址。null 表示监听所有接口(0.0.0.0)
oomScoreAdj: -999 调整 kube-proxy 进程的 OOM(Out of Memory)优先级,-999 降低被 OOM Killer 杀死的概率,优先级接近系统关键进程。
portRange: “” 分配 NodePort 的端口范围。空字符串使用默认范围(30000-32767)。
udpIdleTimeout: 250ms UDP 连接的空闲超时时间。250 毫秒后关闭空闲 UDP 连接,释放资源。
4.3 启动 kube-proxy
systemctl daemon-reload
systemctl enable --now kube-proxy.service
systemctl status kube-proxy.service
4.4 查看集群状态
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master01 Ready <none> 9d v1.29.2
k8s-master02 Ready <none> 9d v1.29.2
k8s-master03 Ready <none> 9d v1.29.2
k8s-node01 Ready <none> 9d v1.29.2
k8s-node02 Ready <none> 9d v1.29.2
k8s-node03 Ready <none> 15m v1.29.2
k8s-node04 Ready <none> 14m v1.29.2
k8s-node05 Ready <none> 14m v1.29.2
提示:当 Nginx、kubelet、kube-proxy 都安装好后,新建的 Node 节点会自动开始运行 calico Pod
$ kubectl get pods -A NAMESPACE NAME READY STATUS RESTARTS AGE kube-system calico-kube-controllers-8d76c5f9b-vtnc9 1/1 Running 1 (121m ago) 126m kube-system calico-node-6vj7z 1/1 Running 0 126m kube-system calico-node-bm9t6 1/1 Running 0 16m kube-system calico-node-jxq4g 1/1 Running 0 16m kube-system calico-node-s7k6p 1/1 Running 3 (124m ago) 126m kube-system calico-node-t9vgb 1/1 Running 2 (120m ago) 126m kube-system calico-node-tlz9j 1/1 Running 0 16m kube-system calico-node-w2vrb 1/1 Running 1 (121m ago) 125m kube-system calico-node-xc5x5 1/1 Running 1 (121m ago) 126m kube-system calico-typha-7cdb5b98f7-b9rvd 1/1 Running 0 125m kube-system coredns-68746bb699-tr8qb 1/1 Running 0 125m kube-system metrics-server-6d4cb7955c-w2wnd 1/1 Running 4 (120m ago) 125m kubernetes-dashboard dashboard-metrics-scraper-5657497c4c-8kzbs 1/1 Running 0 125m kubernetes-dashboard kubernetes-dashboard-5b749d9495-kb6b4 1/1 Running 2 (120m ago) 125m因此,需要保证新建的 Node 节点上有 calico 镜像,如果镜像拉取失败,Node 节点将处于 NotReady 状态
六、安装命令补全
所有节点
yum install bash-completion -y
source /usr/share/bash-completion/bash_completion
source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc
七、测试
3. Nginx 部署测试
资源清单: nginx-test.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 30
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: nginx
image: nginx:1.29.3
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
namespace: default
spec:
ports:
- port: 80
targetPort: 80 # 修正:必须是 Pod 实际监听的端口号
protocol: TCP
nodePort: 30339
selector:
app: myapp
执行资源清单:
# 执行资源清单
$ kubectl apply -f nginx-test.yaml
# 查看 Service
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 8d
nginx-svc NodePort 10.98.200.91 <none> 80:30339/TCP 3h21m
# 查看 Deployment
$ kubectl get deploy -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
nginx 30/30 30 30 3m29s nginx nginx:1.29.3 app=myapp
# 查看Pod
$ kubectl get pods -o wide -w
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-6444df9cd5-2cx9t 1/1 Running 0 3m6s 172.17.54.136 k8s-node05 <none> <none>
nginx-6444df9cd5-5llx5 1/1 Running 0 2m54s 172.18.195.10 k8s-master03 <none> <none>
nginx-6444df9cd5-628p6 1/1 Running 0 3m1s 172.17.54.139 k8s-node05 <none> <none>
nginx-6444df9cd5-65gnq 1/1 Running 0 2m54s 172.18.195.11 k8s-master03 <none> <none>
nginx-6444df9cd5-6gkl6 1/1 Running 0 2m54s 172.25.244.212 k8s-master01 <none> <none>
nginx-6444df9cd5-8m2nv 1/1 Running 0 3m1s 172.27.14.201 k8s-node02 <none> <none>
nginx-6444df9cd5-8xl7q 1/1 Running 0 3m1s 172.25.92.76 k8s-master02 <none> <none>
nginx-6444df9cd5-b4tjh 1/1 Running 0 2m54s 172.25.214.200 k8s-node03 <none> <none>
nginx-6444df9cd5-bxq95 1/1 Running 0 2m54s 172.27.14.202 k8s-node02 <none> <none>
nginx-6444df9cd5-c8r9w 1/1 Running 0 2m54s 172.17.125.20 k8s-node01 <none> <none>
nginx-6444df9cd5-cq5xz 1/1 Running 0 3m1s 172.29.115.134 k8s-node04 <none> <none>
nginx-6444df9cd5-dcss9 1/1 Running 0 3m6s 172.25.214.199 k8s-node03 <none> <none>
nginx-6444df9cd5-fmzpc 1/1 Running 0 3m1s 172.27.14.200 k8s-node02 <none> <none>
nginx-6444df9cd5-ggfkn 1/1 Running 0 3m4s 172.25.244.211 k8s-master01 <none> <none>
nginx-6444df9cd5-j9pfn 1/1 Running 0 2m54s 172.29.115.136 k8s-node04 <none> <none>
nginx-6444df9cd5-kbhxv 1/1 Running 0 3m8s 172.29.115.135 k8s-node04 <none> <none>
nginx-6444df9cd5-kt7qw 1/1 Running 0 3m4s 172.17.125.18 k8s-node01 <none> <none>
nginx-6444df9cd5-l62jc 1/1 Running 0 2m54s 172.17.54.138 k8s-node05 <none> <none>
nginx-6444df9cd5-lmcnf 1/1 Running 0 2m54s 172.17.54.137 k8s-node05 <none> <none>
nginx-6444df9cd5-lztdb 1/1 Running 0 2m54s 172.25.92.77 k8s-master02 <none> <none>
nginx-6444df9cd5-m9xfv 1/1 Running 0 2m54s 172.29.115.137 k8s-node04 <none> <none>
nginx-6444df9cd5-ms4xg 1/1 Running 0 3m1s 172.25.214.201 k8s-node03 <none> <none>
nginx-6444df9cd5-ms7g7 1/1 Running 0 3m1s 172.25.244.213 k8s-master01 <none> <none>
nginx-6444df9cd5-nnh47 1/1 Running 0 2m54s 172.25.214.202 k8s-node03 <none> <none>
nginx-6444df9cd5-pbtf4 1/1 Running 0 2m54s 172.18.195.12 k8s-master03 <none> <none>
nginx-6444df9cd5-pcgqz 1/1 Running 0 2m54s 172.17.125.19 k8s-node01 <none> <none>
nginx-6444df9cd5-pfx5n 1/1 Running 0 3m4s 172.25.92.75 k8s-master02 <none> <none>
nginx-6444df9cd5-shqtn 1/1 Running 0 3m4s 172.18.195.9 k8s-master03 <none> <none>
nginx-6444df9cd5-sjbp7 1/1 Running 0 2m54s 172.25.92.74 k8s-master02 <none> <none>
nginx-6444df9cd5-t4hnx 1/1 Running 0 3m1s 172.17.125.17 k8s-node01 <none> <none>
新建的各个node节点, 都正常运行Pod
网络测试
$ kubectl exec -it nginx-6444df9cd5-2cx9t -- /bin/bash
root@nginx-6594975dd-fds78:/# curl -k https://10.96.0.1:443
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {},
"status": "Failure",
"message": "forbidden: User \"system:anonymous\" cannot get path \"/\"",
"reason": "Forbidden",
"details": {},
"code": 403
}
说明:
- Pod 网络到 Kubernetes API Server 是通的。
- 返回 403 而不是超时或连接失败,说明请求已经到达 API Server。
- 403 的原因是你没有提供认证信息(anonymous user),这是正常的,如果只是测试网络,不需要担心。
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 george_95@126.com
