需求:当前集群为一主两从,共3个节点,需要增加一个从节点。
当前集群如下:
IP | Hostname |
---|---|
10.20.1.139 | k8s-master01 |
10.20.1.140 | k8s-node01 |
10.20.1.141 | k8s-node02 |
需新增如下节点 | |
10.20.1.142 | k8s-node03 |
一、节点初始化设置
参考:基于Rocky9.3系统使用kubeadm安装k8s1.29集群
1. 设置主机名
hostnamectl set-hostname k8s-node03
2. 修改Host文件
cat >> /etc/hosts << "EOF"
10.20.1.139 k8s-master01
10.20.1.140 k8s-node01
10.20.1.141 k8s-node02
10.20.1.142 k8s-node03
EOF
3. 修改终端颜色
这里只是修改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
4. 更换系统软件源
# 更新源
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
5. 修改防火墙
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
6 禁用 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
修改完成后重启系统
reboot
7 设置时区
timedatectl set-timezone Asia/Shanghai
8 集群时间同步设置
timedatectl
dnf install -y chrony
systemctl enable chronyd.service
systemctl restart chronyd.service
systemctl status chronyd.service
vim /etc/chrony.conf
# 修改完chrony配置后,重启chrony服务
systemctl enable chronyd --now
chrony配置内容如下
# 添加阿里云NTP服务器 pool ntp1.aliyun.com iburst pool ntp2.aliyun.com iburst pool cn.pool.ntp.org iburst # 允许指定网段访问此时间服务器,不然只允许本地网络 allow 10.20.0.0/16
chrony配置内容
命令解析
# 检查时区和时间 timedatectl # 安装chrony进行时间同步,ntpdate在Rocky 9中不再支持 dnf install -y chrony # 启用chronyd服务 systemctl enable chronyd.service # 重启chronyd服务 systemctl restart chronyd.service # 查看chronyd服务状态 systemctl status chronyd.service
9 修改系统最大打开文件数
在 /etc/security/limits.conf
文件的末尾追加以下内容
* soft nofile 65535
* hard nofile 65535
目的:修改最大打开文件数限制
10 安装必要的库和修改 sysctl.conf
内核参数配置
dnf install -y epel-release
dnf install -y bridge-utils
modprobe br_netfilter
echo 'br_netfilter' >> /etc/modules-load.d/bridge.conf
cat >> /etc/sysctl.conf <<EOF
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
net.ipv4.ip_forward=1
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_tw_buckets = 20480
net.ipv4.tcp_max_syn_backlog = 20480
net.core.netdev_max_backlog = 262144
net.ipv4.tcp_fin_timeout = 20
EOF
# 重新加载 /etc/sysctl.conf 中的所有内核参数配置,并使其立即生效。
sysctl -p
命令解释
# 安装 EPEL(Extra Packages for Enterprise Linux) 仓库的 Release 包。 # EPEL 是由 Fedora 社区维护的一个软件仓库,提供许多额外的软件包,这些包在默认的 RHEL(或其衍生版如 CentOS、Rocky Linux 等)中没有包含。 yum install -y epel-release # 安装 bridge-utils 软件包。 # bridge-utils 是一个 Linux 工具集,用于创建和管理网络桥接(bridging)。 yum install -y bridge-utils # 加载 br_netfilter 内核模块。 # 该模块用于启用网络桥接(bridge)时的流量过滤功能。 # 允许通过桥接的网络流量被 iptables 规则管理。 # 在容器或虚拟化环境中,确保桥接网络的流量可以被正确处理。 modprobe br_netfilter # 将 br_netfilter 模块名称添加到 /etc/modules-load.d/bridge.conf 文件中。 # 配置系统在启动时自动加载 br_netfilter 模块。 echo 'br_netfilter' >> /etc/modules-load.d/bridge.conf # 向 /etc/sysctl.conf 文件添加配置,使桥接流量可以通过 iptables 规则管理。 # 启用桥接网络上的 IPv4 流量通过 iptables 的规则处理。 net.bridge.bridge-nf-call-iptables=1 # 向 /etc/sysctl.conf 文件添加配置,使桥接流量中的 IPv6 流量可以通过 ip6tables 规则管理。 net.bridge.bridge-nf-call-ip6tables=1 # 向 /etc/sysctl.conf 文件添加配置,启用 IP 转发功能。 # 用途:在容器网络或 Kubernetes 集群中,允许跨子网通信。 net.ipv4.ip_forward=1 # 启用 TCP SYN Cookie 技术,用于防范 SYN Flood 攻击。 # 在服务器收到大量的 TCP SYN 请求但无法分配足够资源时,启用 SYN Cookie 可通过一种临时编码方式验证连接合法性,避免资源耗尽。 net.ipv4.tcp_syncookies = 1 # 设置系统同时保持的 TCP TIME_WAIT 状态的连接数上限。达到上限后,系统会直接丢弃多余的连接(而不是继续占用资源)。 # 默认值180000,对于高并发的 Web 服务器或反向代理,适当调低该值(如 20480)以避免 TIME_WAIT 数量过多。 net.ipv4.tcp_max_tw_buckets = 20480 # 设置 TCP 三次握手中 SYN 请求的队列长度上限。 # 当服务器接收的 SYN 请求超过该值时,新的连接请求会被丢弃。 # 如果服务器负载较高且连接数较多,可以调高到 20480 或更高。 net.ipv4.tcp_max_syn_backlog = 20480 # 设置网络设备接收队列的最大长度。 # 如果接收队列中的数据包数量超过该值,内核将直接丢弃后续数据包。 # 在高流量环境中,设置为较高值(如 262144)以避免丢包,提高吞吐量。 net.core.netdev_max_backlog = 262144 # 设置 TCP 连接处于 FIN_WAIT2 状态的超时时间(单位:秒)。 # FIN_WAIT2 状态表示服务端已发送 FIN 包等待客户端确认,此状态会持续占用资源。 # 默认值:通常为 60 秒。 # 在高并发服务器上,将该值调低(如 20)以减少 FIN_WAIT2 状态的资源占用。 net.ipv4.tcp_fin_timeout = 20 # 重新加载 /etc/sysctl.conf 中的所有内核参数配置,并使其立即生效。 sysctl -p
11 关闭 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。
二、安装Docker服务
1 添加 docker-ce yum 源
在 master01、node01、node02 三台服务器分别执行
sudo dnf config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
sudo sed -i 's+download.docker.com+mirrors.aliyun.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo
sudo dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
命令解析
# 使用 dnf config-manager 命令添加 Docker 软件包的官方仓库(在这里是阿里云的镜像)。 sudo dnf config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # 修改 docker-ce.repo 文件中的镜像源地址,将默认的 download.docker.com 替换为阿里云的镜像地址 mirrors.aliyun.com/docker-ce。 sudo sed -i 's+download.docker.com+mirrors.aliyun.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo # 安装最新版本docker sudo dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
2 开启Docker服务
systemctl start docker
systemctl enable docker
3 配置 daemon.json
cat >>/etc/docker/daemon.json <<EOF
{
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "10"
},
"data-root":"/data/docker",
"exec-opts": ["native.cgroupdriver=systemd"],
"registry-mirrors": [
"https://kfp63jaj.mirror.aliyuncs.com",
"https://hub-mirror.c.163.com",
"https://mirror.baidubce.com"
]
}
EOF
配置解析
"data-root": "/data/docker" 指定 Docker 数据的存储目录为 /data/docker。 包括容器、镜像、卷等内容。 默认存储在 /var/lib/docker,此配置用于更改默认路径。 "exec-opts": ["native.cgroupdriver=systemd"] 配置 Docker 使用 systemd 作为 Cgroup 驱动程序。 推荐在使用现代 Linux 发行版(如 Rocky Linux 9)或 Kubernetes 时采用此配置,以实现更好的资源管理和兼容性。 "log-driver": "json-file" 指定 Docker 的日志驱动为 json-file。 json-file 是 Docker 默认的日志存储方式,将日志保存在 JSON 文件中。 "log-opts": {} 配置日志驱动的选项: "max-size": "100m":每个日志文件的最大大小为 100MB。 "max-file": "100":最多保留 100 个日志文件(滚动日志机制)。 "insecure-registries": ["harbor.xinxainghf.com"] 配置不安全的私有镜像仓库地址(即未启用 HTTPS 的仓库)。 例如,harbor.xinxainghf.com 是一个私有仓库地址。 "registry-mirrors": ["https://kfp63jaj.mirror.aliyuncs.com"] 配置 Docker 镜像加速器。 镜像地址为阿里云镜像服务,加速从官方 Docker Hub 拉取镜像的速度。
4 创建 Docker 服务的自定义配置目录
mkdir -p /etc/systemd/system/docker.service.d
用于存放 Docker 服务的自定义配置文件。
5 重新加载 Docker 配置
systemctl daemon-reload
systemctl restart docker
验证配置是否生效
docker info
三、安装 cri-docker
从 kubernetes 1.24 开始,dockershim 已经从 kubelet 中移除( dockershim 是 Kubernetes 的一个组件,主要目的是为了通过 CRI 操作 Docker),但因为历史问题 docker 却不支持 kubernetes 主推的CRI(容器运行时接口)标准,所以 docker 不能再作为 kubernetes 的容器运行时了,即从 kubernetesv1.24 开始不再使用 docker 了,默认使用的容器运行时是 containerd 。目前 containerd 比较新,可能存在一些功能不稳定的情况,所以这里我们使用容器运行时还是选择 docker。
如果想继续使用 docker 的话,可以在 kubelet 和 docker 之间加上一个中间层 cri-docker 。cri-docker 是一个支持CRI标准的 shim(垫片)。一头通过CRI跟kubelet 交互,另一头跟 docker api 交互,从而间接的实现了 kubernetes 以 docker 作为容器运行时。这里需要在全部节点执行 cri-docker 安装。
1 下载 cri-docker
# 创建目录,并下载 cri-docker 安装文件到目录中
mkdir -p /opt/software
cd /opt/software
wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.3.16/cri-dockerd-0.3.16.amd64.tgz
2 解压 cri-docker
tar -xvf /opt/software/cri-dockerd-0.3.16.amd64.tgz --strip-components=1 -C /usr/local/bin/
3 下载并修改 cri-docker 配置文件
3.1 下载 cri-docker 配置文件
在浏览器下载文件,通过xftp传到服务器上
# 下载 cri-docker.service
# cri-docker.service 下载地址:https://github.com/Mirantis/cri-dockerd/blob/v0.3.16/packaging/systemd/cri-docker.service
mv /opt/software/cri-docker.service /etc/systemd/system/
# 下载 cri-docker.socket
# cri-docker.socket 下载地址:https://github.com/Mirantis/cri-dockerd/blob/v0.3.16/packaging/systemd/cri-docker.socket
mv /opt/software/cri-docker.socket /etc/systemd/system/
3.2 修改 cri-docker 配置文件
修改 cri-docker.service 的启动命令 ExecStart
vim /etc/systemd/system/cri-docker.service
修改内容如下:
# ExecStart=/usr/bin/cri-dockerd --container-runtime-endpoint fd:// ExecStart=/usr/local/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
配置解析
ExecStart 作用: 定义 Systemd 启动服务时执行的命令。 此命令会在服务启动时运行。 /usr/local/bin/cri-dockerd 解释: cri-dockerd 的可执行文件路径。 作用: 启动 cri-dockerd 服务,为 Kubernetes 提供 CRI(容器运行时接口)支持。 --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.9 解释: 定义 Pod 的基础容器镜像。 --container-runtime-endpoint=unix:///var/run/cri-dockerd.sock 解释: 定义 CRI 的监听端点。 作用: cri-dockerd 使用 Unix Socket 文件 /var/run/cri-dockerd.sock 提供与 Kubernetes 的交互接口。 --cri-dockerd-root-directory=/data/dockershim 解释: 定义 cri-dockerd 的根目录,用于存储临时文件或配置数据。 作用: /data/dockershim 是修改后的 cri-dockerd 数据目录,默认存放在 /var/lib/dockershim,用于存放与 Docker 和 Kubernetes 通信相关的数据。 --cri-dockerd-root-directory=/data/docker 解释: 定义 Docker 的根目录。 作用: Docker 的所有容器数据、镜像数据都存放在 /data/docker 目录下。
修改cri-docker.socket的ListenStream参数
vim /etc/systemd/system/cri-docker.socket
修改内容如下:
# ListenStream=%t/cri-dockerd.sock ListenStream=/var/run/cri-dockerd.sock
配置解析
ListenStream 作用: 定义 cri-dockerd 服务监听的通信地址和端口。 在这里,指定了一个 Unix Socket 文件 /var/run/cri-dockerd.sock。 /var/run/cri-dockerd.sock 解释: 这是一个 Unix Domain Socket 文件路径。 Unix Sockets 是一种轻量级的进程间通信(IPC)方式,通常用于本地通信(与网络无关)。 cri-dockerd 和 Kubernetes 的 kubelet 通过这个 Socket 文件进行交互。
注意每个节点 cri-docker 都需要这么配置
4 启动 cri-docker 对应服务
systemctl daemon-reload
systemctl enable cri-docker
systemctl start cri-docker
systemctl is-active cri-docker
命令解析
# 告诉 Systemd 重新加载所有服务配置文件。 systemctl daemon-reload # 设置 cri-docker 服务为 开机自启。 systemctl enable cri-docker # 启动 cri-docker 服务。 systemctl start cri-docker # 检查 cri-docker 服务是否正在运行。 systemctl is-active cri-docker
四、节点加入集群
1 配置阿里云K8S源
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.29/rpm/
enabled=1
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.29/rpm/repodata/repomd.xml.key
EOF
2 安装K8S集群管理工具
yum install -y kubelet kubeadm kubectl
3 配置k8s Cgoup控制组
vim /etc/sysconfig/kubelet
配置内容如下:
KUBELET_EXTRA_ARGS="--cgroup-driver=systemd"
配置解析
KUBELET_EXTRA_ARGS 含义: KUBELET_EXTRA_ARGS 是一个变量,用于为 kubelet 添加自定义的启动参数。 这些参数会被系统初始化脚本或服务文件加载并传递给 kubelet 进程。 --cgroup-driver=systemd 作用: 指定 kubelet 使用的 cgroup 驱动(Cgroup Driver)。 Cgroup Driver 是 Kubernetes 用来与 Linux 内核 cgroup(控制组)交互的机制,负责资源(CPU、内存等)的限制和管理。 该参数将驱动类型设置为 systemd,表示使用 systemd 来管理 cgroup。
4 配置kubelet自启动
systemctl enable kubelet.service
5 Master 节点重新生成 Token
# 在集群 Master 节点执行命令
$ kubeadm token create --print-join-command
# 生成内容如下:
kubeadm join 10.20.1.139:6443 --token 4jlfko.bsw2lqp28syw1fb7 --discovery-token-ca-cert-hash sha256:9450138de7634306c27d22950c943dd348662019b710bc00248e815df86fa789
6 当前节点加入集群中
$ kubeadm join 10.20.1.139:6443 --token 4jlfko.bsw2lqp28syw1fb7 --discovery-token-ca-cert-hash sha256:9450138de7634306c27d22950c943dd348662019b710bc00248e815df86fa789 --cri-socket=unix:///var/run/cri-dockerd.sock
在master节点查看节点状态
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master01 Ready control-plane 5d2h v1.29.15
k8s-node01 Ready <none> 5d v1.29.15
k8s-node02 Ready <none> 5d v1.29.15
k8s-node03 NotReady <none> 18s v1.29.15
k8s-node03 节点已加入集群中。
k8s-node03 虽然已经加入集群中,但处于未就绪状态,查看原因:
# 在master节点查看Pod运行情况
$ kubectl get pods -n kube-system -o wide
通过查看Pod,了解到是由于 node03 节点的 calico Pod运行异常,calico 镜像拉取失败了。
导入Calico镜像
由于 colico 相关镜像在国外,这里使用代理的方式,提前下载好镜像,然后导入到 node03 节点中
# 查看要下载的镜像
# 查看集群初始化时,安装 Calico 插件使用的yaml文件,里面有calico所需的相关镜像
$ cat calico.yaml
# 拉取 Calico 镜像
docker pull docker.io/calico/cni:v3.26.3
docker pull docker.io/calico/node:v3.26.3
docker pull docker.io/calico/kube-controllers:v3.26.3
docker pull docker.io/calico/typha:v3.26.3
# Calico 镜像打包
docker save docker.io/calico/cni:v3.26.3 cni-v3.26.3.tar
docker save docker.io/calico/node:v3.26.3 node-v3.26.3.tar
docker save docker.io/calico/kube-controllers:v3.26.3 kube-controllers-v3.26.3.tar
docker save docker.io/calico/typha:v3.26.3 typha-v3.26.3.tar
# 导入 Calico 镜像
docker load -i cni-v3.26.3.tar
docker load -i node-v3.26.3.tar
docker load -i kube-controllers-v3.26.3.tar
docker load -i typha-v3.26.3.tar
再次查看集群Node状态
k8s-node03 节点导入calico镜像后,再次查看
# 在 master 节点查看节点状态
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master01 Ready control-plane 5d3h v1.29.15
k8s-node01 Ready <none> 5d1h v1.29.15
k8s-node02 Ready <none> 5d1h v1.29.15
k8s-node03 Ready <none> 25m v1.29.15
# 在master节点查看Pod运行情况
$ kubectl get pods -n kube-system -o wide
7 其它配置
让新加入的 k8s-node03 节点可执行 kubectl 命令,只要把 master上的管理文件 /etc/kubernetes/admin.conf
拷贝到 Worker 节点的 $HOME/.kube/config
就可以让 Worker 节点也可以实现 kubectl 命令管理。
# 在 node03 节点执行
[root@k8s-node03 ~]$ mkdir /root/.kube
# 在master节点执行
[root@k8s-master01 ~]$ scp /etc/kubernetes/admin.conf root@10.20.1.142:/root/.kube/config
测试:在 node03 节点测试
[root@k8s-node03 ~]$ kubectl get nodes NAME STATUS ROLES AGE VERSION k8s-master01 Ready control-plane 5d3h v1.29.15 k8s-node01 Ready <none> 5d1h v1.29.15 k8s-node02 Ready <none> 5d1h v1.29.15 k8s-node03 Ready <none> 42m v1.29.15
至此完成了新节点的的初始化,及加入k8s集群中
参考链接
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 george_95@126.com