在Rocky上部署K8S集群

一、系统架构

本系统部署在三台服务器上,系统为Rocky10

IP地址服务器名SwapFirewalld
192.168.2.101k8s-master关闭关闭
192.168.2.102k8s-slave1关闭关闭
192.168.2.103k8s-slave2关闭关闭

在三台服务器上的/etc/hosts写入如下内容

1
2
3
192.168.2.101 k8s-master
192.168.2.102 k8s-slave1
192.168.2.103 k8s-slave2

还有一个harbor服务器,IP为:192.168.2.104,启动的80端口。 执行命令,开启网络支持

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#  开启内核转发和网桥过滤
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

sudo modprobe overlay
sudo modprobe br_netfilter

cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables  = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward                 = 1
EOF

sudo sysctl --system

二、安装containerd

在三台服务器上执行

2.1、安装

使用下列命令进行安装

1
2
3
4
5
6
# 1. 安装流量转发工具
sudo dnf install -y yum-utils
# 2. 添加阿里云源
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 3. 安装最新版 containerd
sudo dnf install -y containerd.io

2.2、进行配置

创建配置文件并进行修改

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# 1. 创建配置目录并生成默认配置
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml

# 2. 启用 SystemdCgroup (K8s 官方推荐,增强稳定性)
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml

# 3. 修改 Sandbox 镜像地址为阿里云,版本指定为 3.10.1
# 注意:国内镜像站同步 registry.k8s.io 较慢,建议使用以下镜像路径
sudo sed -i 's|registry.k8s.io/pause:3.10.1|registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.10.1|g' /etc/containerd/config.toml

#4、配置信任192.168.2.104
sudo sed -i "s|config_path = \"\"|config_path = \"/etc/containerd/certs.d\"|g" /etc/containerd/config.toml
#如果这里配置不成功,请手工修改,保证内容如下
#[plugins.'io.containerd.cri.v1.images'.registry]
#      config_path = '/etc/containerd/certs.d'
#5、创建其他的文件
#为了连接上harbor执行下列配置
echo -n "admin:Harbor12345" | base64
# 将输出的内容写入/etc/containerd/certs.d/192.168.2.104/hosts.toml
mkdir -p /etc/containerd/certs.d/192.168.2.104
touch /etc/containerd/certs.d/192.168.2.104/hosts.toml
#在下列文件中写入
# 1. 创建配置目录(如果不存在)
sudo mkdir -p /etc/containerd/certs.d/192.168.2.104

# 2. 使用带有引号的 EOF 写入,防止特殊字符被 Shell 误解析
sudo tee /etc/containerd/certs.d/192.168.2.104/hosts.toml <<'EOF'
server = "http://192.168.2.104"

[host."http://192.168.2.104"]
  capabilities = ["pull", "resolve"]
  skip_verify = true

  [host."http://192.168.2.104".header]
    Authorization = "Basic YWRtaW46SGFyYm9yMTIzNDU="
EOF


#配置cri,让命令正常
cat <<EOF > /etc/crictl.yaml
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false
EOF

2.3、启动服务

1
2
3
4
sudo systemctl restart containerd
sudo systemctl enable containerd
# 检查 containerd 是否因为配置错误而无法启动
sudo systemctl status containerd

三、安装 Kubeadm, Kubelet, Kubectl

在所有节点执行

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.35/rpm/
enabled=1
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.35/rpm/repodata/repomd.xml.key
EOF

dnf install -y kubelet kubeadm kubectl
systemctl enable --now kubelet

四、集群初始化

4.1、启动集群

在master执行

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
kubeadm init \
  --apiserver-advertise-address=192.168.2.101 \
  --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers \
  --kubernetes-version=v1.35.2 \
  --service-cidr=10.96.0.0/12 \
  --pod-network-cidr=10.244.0.0/16
  
#在执行如下命令
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
#退出武器,再进入

如果正常,在输出的最后将出现,如下的提示,将该提示在另外两个节点执行

1
2
kubeadm join 192.168.2.101:6443 --token rghxkw.d2wlhlrjgeqye2t6 \
        --discovery-token-ca-cert-hash sha256:1e8e065bcf816fb681bc351ec47489619794cc339bb5ccb8259268c46128deea 

如果该命令遗忘,在master执行下列命令重新获取

1
`kubeadm token create --print-join-command`

现在使用kubectl get nodes查看系统状态,都应该是notready状态,需要安装网络组件

4.2、安装网络组件

因为网络问题,需要提前在harbor服务器上下载网络组件,并推送到私有仓库

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# 定义变量
HARBOR="192.168.2.104/library"

# 1. 下载并推送 Calico
images=(cni node kube-controllers)
for img in "${images[@]}"; do
    docker pull calico/$img:v3.27.0
    docker tag calico/$img:v3.27.0 $HARBOR/calico-$img:v3.27.0
    docker push $HARBOR/calico-$img:v3.27.0
done

# 2. 下载并推送 Ingress
docker pull registry.k8s.io/ingress-nginx/controller:v1.9.5
docker tag registry.k8s.io/ingress-nginx/controller:v1.9.5 $HARBOR/ingress-controller:v1.9.5
docker push $HARBOR/ingress-controller:v1.9.5

harbor上取得镜像之后,在master上执行

1
2
3
4
5
6
7
8
curl -O https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/calico.yaml
#将默认的镜像地址修改到192.168.2.104
sed -i 's|docker.io/calico/|192.168.2.104/library/calico-|g' calico.yaml
#启动网络组件
kubectl apply -f calico.yaml
#使用命令查看node状态,如果全部是ready即可
kubectl get nodes
#返回如下即可
NameSTATUSROLESAGEVERSION
k8s-masterReadycontrol-plane84mv1.35.3
k8s-slave1Ready81mv1.35.3
k8s-slave2Ready81mv1.35.3

五、部署ingress-nginx

5.1、下载镜像

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 1. 定义变量(方便后续操作)
ORIGIN_IMAGE="registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v20231011-8b53cabe0"
MY_HARBOR="192.168.2.104/library/kube-webhook-certgen:v20231011"

# 2. 拉取镜像(这里推荐用阿里源作为中转,比 registry.k8s.io 稳得多)
docker pull $ORIGIN_IMAGE

# 3. 打标签并推送到你的 Harbor
docker tag $ORIGIN_IMAGE $MY_HARBOR
docker push $MY_HARBOR

5.2、下载部署文件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 下载部署文件 
curl -O https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.9.5/deploy/static/provider/cloud/deploy.yaml
#替换成本地image
sed -i 's|registry.k8s.io/ingress-nginx/controller:v1.9.5|192.168.2.104/library/ingress-controller:v1.9.5|g' deploy.yaml 
# 替换刚才报错的 Webhook Certgen (注意去掉那个长长的 sha256 摘要,直接用 tag) 
sed -i 's|registry.k8s.io/ingress-nginx/kube-webhook-certgen:.*$|192.168.2.104/library/kube-webhook-certgen:v20231011|g' deploy.yaml
# 针对已经下载好的 deploy.yaml 
sed -i 's/@sha256:[a-f0-9]*//g' deploy.yaml 
# 验证,显示没有各种奇奇怪怪的sha256就行
grep "image:" deploy.yaml

5.3、启动

1
2
3
kubectl apply -f deploy.yaml
#检查,只要里面的pod运行起来就行
kubectl get pods -n ingress-nginx

六、自动更新证书

创建一个脚本,用来自动更新证书

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
cat > /usr/local/bin/k8s-cert-renew.sh << 'EOF'
#!/bin/bash
# ==============================================================================
# 脚本名称: k8s-cert-renew.sh
# 脚本说明: 每月自动续期 Kubernetes (kubeadm) 证书
# ==============================================================================

set -e

# 日志输出函数
log() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1"
}

log "开始执行 K8s 证书自动续期流程..."

# 1. 备份现有证书和配置 (保留最近30天的备份)
BACKUP_DIR="/etc/kubernetes/pki.backup.$(date +%Y%m%d)"
log "备份当前证书到 $BACKUP_DIR"
cp -r /etc/kubernetes/pki $BACKUP_DIR
\cp -f /etc/kubernetes/admin.conf /etc/kubernetes/admin.conf.backup.$(date +%Y%m%d)

# 清理超过30天的旧备份
find /etc/kubernetes/ -maxdepth 1 -name "pki.backup.*" -type d -mtime +30 -exec rm -rf {} \;
find /etc/kubernetes/ -maxdepth 1 -name "admin.conf.backup.*" -type f -mtime +30 -exec rm -f {} \;

# 2. 使用 kubeadm 续期所有证书
log "执行 kubeadm certs renew all..."
kubeadm certs renew all

# 3. 更新管理员的 kubeconfig 文件 (使用 \cp -f 绕过 alias 并强制覆盖)
log "更新 ~/.kube/config 配置文件..."
\cp -f /etc/kubernetes/admin.conf ~/.kube/config
chown $(id -u):$(id -g) ~/.kube/config

# 4. 重启控制平面组件以加载新证书
log "重启控制平面静态 Pod..."
export KUBECONFIG=/etc/kubernetes/admin.conf
kubectl delete pod -n kube-system -l component=kube-apiserver
kubectl delete pod -n kube-system -l component=kube-controller-manager
kubectl delete pod -n kube-system -l component=kube-scheduler
kubectl delete pod -n kube-system -l component=etcd

log "检查新证书有效期:"
kubeadm certs check-expiration | grep -E "CERTIFICATE|admin.conf"

log "K8s 证书续期流程执行完毕!"
EOF

对脚本添加可执行权限,并添加到计划任务

1
2
3
4
chmod +x /usr/local/bin/k8s-cert-renew.sh
crontab -e
#写入如下内容
0 1 1 * * /bin/bash /usr/local/bin/k8s-cert-renew.sh
comments powered by Disqus