集群规划#
| 节点名 | IP 地址 |
|---|---|
| k8s-01 | 10.37.43.62 |
| k8s-02 | 10.37.91.93 |
上述 2 台机器混合部署本教程的 Etcd、Master 节点和 Worker 节点。
如果你想部署 3 节点合次的 Kubernetes 集群,只需要修改以下几个地方即可:
修改 environment.sh 脚本文件,将新节点按其他节点的配置格式在 NODE_IPS、NODE_NAMES、ETCD_ENDPOINTS、ETCD_NODES 变量中更新;
创建 CSR 文件时,将新的节点 IP 添加到 hosts 字段中;
修改 for (( i=0; i < 2; i++ )) 中的 2 为 3;
所有需要在每个节点执行的命令,都需要在新节点执行。
注意:如果没有特殊说明,需要在所有节点上执行本章节的初始化操作。
设置主机名#
hostnamectl set-hostname k8s-01 # 登录 k8s-01 机器,执行 hostnamectl 命令
hostnamectl set-hostname k8s-02 # 登录 k8s-02 机器,执行 hostnamectl 命令
如果 DNS 不支持主机名称解析,还需要在每台机器的 /etc/hosts 文件中添加主机名和 IP 的对应关系:
cat >> /etc/hosts <<EOF
10.37.91.93 k8s-01
10.37.43.62 k8s-02
EOF
退出,重新登录 root 账号,可以看到主机名生效。
添加节点信任关系#
以下操作要在所有节点上执行:
sed -i 's/PubkeyAuthentication no/PubkeyAuthentication yes/g' /etc/ssh/sshd_config
sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config
sed -i 's/^#\s*\(AuthorizedKeysFile\s\+.*\)/\1/' /etc/ssh/sshd_config
systemctl restart sshd
以下操作只需要在 k8s-01 节点上进行,设置 root 账户可以无密码登录所有节点:
ssh-keygen -t rsa
ssh-copy-id root@k8s-01
ssh-copy-id root@k8s-02
添加完节点信任关系之后,最好手动分别执行 ssh root@k8s-01、ssh root@k8s-02、ssh root@10.37.91.93、ssh root@10.37.43.62 命令测试下是否可以无密码登录,防止因为 sshd 配置的原因,引起的无密码登录失败。
更新 PATH 变量#
echo 'export PATH=/opt/k8s/bin:$PATH' >> $HOME/.bashrc
source /root/.bashrc
/opt/k8s/bin 目录保存本章节下载的安装文件。
安装依赖包#
在部署 Kubernetes 集群之前需要在所有节点上安装必要的依赖,安装命令如下:
apt install -y policycoreutils jq chrony conntrack ipvsadm ipset jq iptables curl sysstat wget socat git
- 本章节的 kube-proxy 使用 ipvs 模式,ipvsadm 为 ipvs 的管理工具;
- Etcd 集群各机器需要时间同步,chrony 用于系统时间同步;
关闭防火墙#
关闭防火墙,清理防火墙规则,设置默认转发策略:
systemctl stop nftables
systemctl disable nftables
iptables -F && iptables -X && iptables -F -t nat && iptables -X -t nat
iptables -P FORWARD ACCEPT
关闭 swap 分区#
关闭 swap 分区,否则 kubelet 会启动失败(可以设置 kubelet 启动参数 --fail-swap-on 为 false 关闭 swap 检查):
swapoff -a
sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
关闭 SELinux#
关闭 SELinux,否则 kubelet 挂载目录时可能报错 Permission denied:
setenforce 0
sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config
优化内核参数#
cat > kubernetes.conf <<EOF
net.ipv4.ip_forward=1
net.ipv4.tcp_tw_recycle=0
net.ipv4.neigh.default.gc_thresh1=1024
net.ipv4.neigh.default.gc_thresh2=2048
net.ipv4.neigh.default.gc_thresh3=4096
vm.swappiness=0
vm.overcommit_memory=1
vm.panic_on_oom=0
fs.inotify.max_user_instances=8192
fs.inotify.max_user_watches=1048576
fs.file-max=52706963
fs.nr_open=52706963
net.ipv6.conf.all.disable_ipv6=1
EOF
cp kubernetes.conf /etc/sysctl.d/kubernetes.conf
sysctl -p /etc/sysctl.d/kubernetes.conf
- 关闭 tcp_tw_recycle,否则与 NAT 冲突,可能导致服务不通;
设置系统时区#
timedatectl set-timezone Asia/Shanghai
设置系统时钟同步#
systemctl enable chrony
systemctl start chrony
查看同步状态:
timedatectl status
输出:
Local time: Wed 2024-10-09 14:51:07 CST
Universal time: Wed 2024-10-09 06:51:07 UTC
RTC time: Wed 2024-10-09 06:51:07
Time zone: Asia/Shanghai (CST, +0800)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no
- System clock synchronized: yes,表示时钟已同步;
- NTP service: active,表示开启了时钟同步服务;
执行以下命令将当前的 UTC 时间写入硬件时钟:
# 将当前的 UTC 时间写入硬件时钟
timedatectl set-local-rtc 0
# 重启依赖于系统时间的服务
systemctl restart rsyslog
systemctl restart chrony
关闭无关的服务#
以下服务如果有开启则关闭,没有开启则忽略:
systemctl stop postfix && systemctl disable postfix
创建相关安装目录#
创建安装目录命令如下:
mkdir -p /opt/k8s/{bin,work} /etc/{kubernetes,etcd}/cert
分发集群配置参数脚本#
后续使用的环境变量都定义在文件 environment.sh 中,请根据自己的机器、网络情况修改,然后拷贝到所有节点。本套课程部署时使用的 environment.sh 内容如下:
#!/usr/bin/bash
# 生成 EncryptionConfig 所需的加密 key
export ENCRYPTION_KEY=$(head -c 32 /dev/urandom | base64)
# 集群各机器 IP 数组
export NODE_IPS=(10.37.91.93 10.37.43.62)
# 集群各 IP 对应的主机名数组
export NODE_NAMES=(k8s-01 k8s-02)
# etcd 集群服务地址列表
export ETCD_ENDPOINTS="https://10.37.91.93:2379,https://10.37.43.62:2379"
# etcd 集群间通信的 IP 和端口
export ETCD_NODES="k8s-01=https://10.37.91.93:2380,k8s-02=https://10.37.43.62:2380"
# kube-apiserver 的反向代理(kube-nginx)地址端口
export KUBE_APISERVER="https://127.0.0.1:8443"
# 节点间互联网络接口名称
export IFACE="eth0"
# etcd 数据目录
export ETCD_DATA_DIR="/data/k8s/etcd/data"
# etcd WAL 目录,建议是 SSD 磁盘分区,或者和 ETCD_DATA_DIR 不同的磁盘分区
export ETCD_WAL_DIR="/data/k8s/etcd/wal"
# k8s 各组件数据目录
export K8S_DIR="/data/k8s/k8s"
## DOCKER_DIR 和 CONTAINERD_DIR 二选一
# docker 数据目录
export DOCKER_DIR="/data/k8s/docker"
# containerd 数据目录
export CONTAINERD_DIR="/data/k8s/containerd"
## 以下参数一般不需要修改
# TLS Bootstrapping 使用的 Token,可以使用命令 head -c 16 /dev/urandom | od -An -t x | tr -d ' ' 生成
BOOTSTRAP_TOKEN="41f7e4ba8b7be874fcff18bf5cf41a7c"
# 最好使用 当前未用的网段 来定义服务网段和 Pod 网段
# 服务网段,部署前路由不可达,部署后集群内路由可达(kube-proxy 保证)
SERVICE_CIDR="10.254.0.0/16"
# Pod 网段,建议 /16 段地址,部署前路由不可达,部署后集群内路由可达(flanneld 保证)
CLUSTER_CIDR="172.30.0.0/16"
# 服务端口范围(NodePort Range)
export NODE_PORT_RANGE="30000-32767"
# kubernetes 服务 IP(一般是 SERVICE_CIDR 中第一个IP)
export CLUSTER_KUBERNETES_SVC_IP="10.254.0.1"
# 集群 DNS 服务 IP(从 SERVICE_CIDR 中预分配)
export CLUSTER_DNS_SVC_IP="10.254.0.2"
# 集群 DNS 域名(末尾不带点号)
export CLUSTER_DNS_DOMAIN="cluster.local"
# 将二进制目录 /opt/k8s/bin 加到 PATH 中
export PATH=/opt/k8s/bin:$PATH
根据部署的节点信息修改了以下环境变量的值:NODE_IPS、NODE_NAMES、ETCD_ENDPOINTS、ETCD_NODES。
执行以下命令,将 environment.sh 文件分发到所有节点上:
source environment.sh # 先修改
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
scp environment.sh root@${node_ip}:/opt/k8s/bin/
ssh root@${node_ip} "chmod +x /opt/k8s/bin/*"
done