一、实验虚拟机规划
本实验共使用 4 台虚拟机,角色与 IP 如下:
| 主机名 | IP 地址 | 建议配置 | 角色 |
|---|---|---|---|
| reg.timinglee.org | 172.25.254.254 | 1 CPU、1 GB 内存 | Harbor 私有仓库 |
| k8s-master | 172.25.254.100 | 4 CPU、内存大于 4 GB | Kubernetes control-plane |
| k8s-node1 | 172.25.254.10 | 2 CPU、2 GB 内存 | worker 节点 |
| k8s-node2 | 172.25.254.20 | 2 CPU、2 GB 内存 | worker 节点 |
二、统一主机名与 hosts 解析
在 4 台虚拟机上分别执行对应命令设置主机名:
bash
# 在 Harbor 主机执行
hostnamectl set-hostname reg.timinglee.org
# 在 master 执行
hostnamectl set-hostname k8s-master
# 在 node1 执行
hostnamectl set-hostname k8s-node1
# 在 node2 执行
hostnamectl set-hostname k8s-node2
4 台虚拟机都执行以下命令写入 hosts 解析:
bash
cat >> /etc/hosts <<'EOF'
172.25.254.254 reg.timinglee.org harbor
172.25.254.100 k8s-master master
172.25.254.10 k8s-node1 node1
172.25.254.20 k8s-node2 node2
EOF
getent hosts reg.timinglee.org k8s-master k8s-node1 k8s-node2
ping -c 2 172.25.254.254
三、第一阶段:在 Harbor 主机部署私有仓库
1. 安装 Docker 并配置本地 RPM 源
以下命令只在 reg.timinglee.org(172.25.254.254)执行:
bash
cat > /etc/yum.repos.d/docker-online.repo <<'EOF'
[docker-online]
name=docker-online
baseurl=https://mirrors.aliyun.com/docker-ce/linux/rhel/9.6/x86_64/stable/
gpgcheck=0
enabled=1
EOF
dnf install -y httpd createrepo_c
mkdir -p /var/www/html/docker
sed -i 's/^Listen 80$/Listen 4444/' /etc/httpd/conf/httpd.conf
systemctl enable --now httpd
dnf install docker-ce --downloadonly --destdir /mnt/ -y
mv /mnt/*.rpm /var/www/html/docker/
createrepo_c /var/www/html/docker/
cat > /etc/yum.repos.d/docker.repo <<'EOF'
[docker]
name=docker-local
baseurl=http://172.25.254.254:4444/docker
gpgcheck=0
enabled=1
EOF
dnf clean all
dnf install -y docker-ce
systemctl enable --now docker
2. 配置 Docker 内核参数
bash
echo br_netfilter > /etc/modules-load.d/docker_mod.conf
modprobe br_netfilter
cat > /etc/sysctl.d/docker.conf <<'EOF'
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
systemctl restart systemd-modules-load.service
sysctl --system
sysctl net.ipv4.ip_forward
sysctl net.bridge.bridge-nf-call-iptables
3. 生成 Harbor 自签名 HTTPS 证书
bash
mkdir -p /data/certs
openssl req -newkey rsa:4096 -nodes -sha256 \
-keyout /data/certs/timinglee.org.key \
-x509 -days 365 \
-out /data/certs/timinglee.org.crt \
-subj "/C=CN/ST=Shaanxi/L=Xian/O=kubernetes/OU=harbor/CN=reg.timinglee.org" \
-addext "subjectAltName = DNS:reg.timinglee.org"
4. 安装并启动 Harbor
bash
tar zxf harbor-offline-installer-v2.5.4.tgz -C /opt
cd /opt/harbor
cp harbor.yml.tmpl harbor.yml
编辑 /opt/harbor/harbor.yml,确认以下配置:
yaml
hostname: reg.timinglee.org
https:
port: 443
certificate: /data/certs/timinglee.org.crt
private_key: /data/certs/timinglee.org.key
harbor_admin_password: lee
bash
cd /opt/harbor
./install.sh --with-chartmuseum
cat > /etc/systemd/system/harbor.service <<'EOF'
[Unit]
Description=Harbor with Docker Compose
After=docker.service network-online.target
Requires=docker.service
[Service]
Type=oneshot
WorkingDirectory=/opt/harbor
ExecStart=/usr/bin/docker compose up -d
ExecStop=/usr/bin/docker compose down
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now harbor
docker compose ps
5. Harbor 主机信任证书并登录
bash
mkdir -p /etc/docker/certs.d/reg.timinglee.org
cp /data/certs/timinglee.org.crt /etc/docker/certs.d/reg.timinglee.org/ca.crt
systemctl restart docker
cd /opt/harbor
docker compose up -d
docker login reg.timinglee.org -u admin
# 密码:lee
6. 创建 Harbor 项目
在 Harbor Web 页面创建 k8s、library、flannel-io 三个项目,或使用 API:
bash
curl -k -u admin:lee -X POST \
https://reg.timinglee.org/api/v2.0/projects \
-H 'Content-Type: application/json' \
-d '{"project_name":"k8s","public":true}'
四、第二阶段:初始化三台 Kubernetes 节点
以下命令在 k8s-master、k8s-node1、k8s-node2 三台节点分别执行。
1. 关闭 swap
bash
swapoff -a
sed -i '/[[:space:]]swap[[:space:]]/s/^/#/' /etc/fstab
swapon --show
2. 安装 Docker
bash
cat > /etc/yum.repos.d/docker.repo <<'EOF'
[docker]
name=docker-local
baseurl=http://172.25.254.254:4444/docker
gpgcheck=0
enabled=1
EOF
dnf clean all
dnf install -y docker-ce
systemctl enable --now docker
3. 配置内核参数与 Docker 镜像加速
bash
echo br_netfilter > /etc/modules-load.d/docker_mod.conf
modprobe br_netfilter
cat > /etc/sysctl.d/kubernetes.conf <<'EOF'
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
systemctl restart systemd-modules-load.service
sysctl --system
cat > /etc/docker/daemon.json <<'EOF'
{
"registry-mirrors": ["https://reg.timinglee.org"]
}
EOF
systemctl restart docker
4. 信任 Harbor 证书
先在每台节点创建目录:
bash
mkdir -p /etc/docker/certs.d/reg.timinglee.org
然后在 Harbor 主机执行分发:
bash
for ip in 100 10 20; do
scp /data/certs/timinglee.org.crt \
root@172.25.254.$ip:/etc/docker/certs.d/reg.timinglee.org/ca.crt
done
5. 配置 Kubernetes 软件源
bash
cat > /etc/yum.repos.d/kubernetes.repo <<'EOF'
[kubernetes]
name=kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.35/rpm/
gpgcheck=0
enabled=1
EOF
dnf clean all
dnf --showduplicates list kubeadm kubelet kubectl
6. 安装 cri-dockerd(三台节点都要安装)
bash
tar zxf cri-dockerd-0.4.4.amd64.tgz
cd cri-dockerd
install -o root -g root -m 0755 cri-dockerd /usr/local/bin/cri-dockerd
cp cri-docker.service cri-docker.socket /lib/systemd/system/
编辑 /lib/systemd/system/cri-docker.service,确保 ExecStart 类似:
ini
[Unit]
Description=CRI Interface for Docker Application Container Engine
After=network-online.target docker.service
Wants=network-online.target
Requires=docker.service
[Service]
Type=notify
ExecStart=/usr/local/bin/cri-dockerd
--container-runtime-endpoint fd://
--network-plugin=cni
--pod-infra-container-image=reg.timinglee.org/k8s/pause:3.10.1
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always
[Install]
WantedBy=multi-user.target
bash
systemctl daemon-reload
systemctl enable --now cri-docker.service
systemctl status cri-docker.service --no-pager
ls -l /var/run/cri-dockerd.sock
7. 安装 Kubernetes 软件
在 k8s-master 执行:
bash
dnf install -y kubelet-1.35.7 kubeadm-1.35.7 kubectl-1.35.7
systemctl enable kubelet
在 k8s-node1 和 k8s-node2 分别执行:
bash
dnf install -y kubelet-1.35.7 kubeadm-1.35.7
systemctl enable kubelet
五、第三阶段:准备并上传 Kubernetes 镜像
1. 在 master 查看所需镜像
bash
kubeadm config images list \
--kubernetes-version v1.35.7 \
--image-repository registry.k8s.io
2. 拉取镜像并打 tag 推送到 Harbor
bash
kubeadm config images pull \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.35.7 \
--cri-socket=unix:///var/run/cri-dockerd.sock
docker login reg.timinglee.org -u admin
docker tag registry.aliyuncs.com/google_containers/kube-apiserver:v1.35.7
reg.timinglee.org/k8s/kube-apiserver:v1.35.7
docker push reg.timinglee.org/k8s/kube-apiserver:v1.35.7
docker tag registry.aliyuncs.com/google_containers/kube-controller-manager:v1.35.7
reg.timinglee.org/k8s/kube-controller-manager:v1.35.7
docker push reg.timinglee.org/k8s/kube-controller-manager:v1.35.7
docker tag registry.aliyuncs.com/google_containers/kube-scheduler:v1.35.7
reg.timinglee.org/k8s/kube-scheduler:v1.35.7
docker push reg.timinglee.org/k8s/kube-scheduler:v1.35.7
docker tag registry.aliyuncs.com/google_containers/kube-proxy:v1.35.7
reg.timinglee.org/k8s/kube-proxy:v1.35.7
docker push reg.timinglee.org/k8s/kube-proxy:v1.35.7
docker tag registry.aliyuncs.com/google_containers/coredns:v1.13.1
reg.timinglee.org/k8s/coredns:v1.13.1
docker push reg.timinglee.org/k8s/coredns:v1.13.1
docker tag registry.aliyuncs.com/google_containers/pause:3.10.1
reg.timinglee.org/k8s/pause:3.10.1
docker push reg.timinglee.org/k8s/pause:3.10.1
docker tag registry.aliyuncs.com/google_containers/etcd:3.6.6-0
reg.timinglee.org/k8s/etcd:3.6.6-0
docker push reg.timinglee.org/k8s/etcd:3.6.6-0
六、第四阶段:初始化控制平面并加入 worker
1. 在 k8s-master 初始化
bash
kubeadm init \
--pod-network-cidr=10.244.0.0/16 \
--image-repository reg.timinglee.org/k8s \
--kubernetes-version v1.35.7 \
--cri-socket=unix:///var/run/cri-dockerd.sock
2. 配置 master 的 kubectl
bash
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
kubectl get nodes
3. 生成 worker 加入命令
bash
kubeadm token create --print-join-command
把输出命令复制到 k8s-node1 和 k8s-node2,并补上 cri-dockerd 参数:
bash
kubeadm join 172.25.254.100:6443 \
--token <现场生成的TOKEN> \
--discovery-token-ca-cert-hash sha256:<现场生成的HASH> \
--cri-socket=unix:///var/run/cri-dockerd.sock
回到 master 验证:
bash
kubectl get nodes -o wide
七、第五阶段:安装 Flannel 网络插件
1. 推送 Flannel 镜像到 Harbor
bash
docker tag flannel/flannel-cni-plugin:v1.6.2-flannel1 \
reg.timinglee.org/flannel-io/flannel-cni-plugin:v1.6.2-flannel1
docker push reg.timinglee.org/flannel-io/flannel-cni-plugin:v1.6.2-flannel1
docker tag flannel/flannel:v0.26.5
reg.timinglee.org/flannel-io/flannel:v0.26.5
docker push reg.timinglee.org/flannel-io/flannel:v0.26.5
2. 下载并修改 Flannel YAML
bash
wget https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
sed -i 's#docker.io/flannel/flannel-cni-plugin:v1.6.2-flannel1#reg.timinglee.org/flannel-io/flannel-cni-plugin:v1.6.2-flannel1#g' kube-flannel.yml
sed -i 's#docker.io/flannel/flannel:v0.26.5#reg.timinglee.org/flannel-io/flannel:v0.26.5#g' kube-flannel.yml
grep -n 'image:' kube-flannel.yml
3. 在 master 应用 Flannel
bash
kubectl apply -f kube-flannel.yml
kubectl get pods -n kube-flannel -o wide
kubectl get nodes -o wide
三个节点都变为 Ready 即完成集群部署。
八、第六阶段:上传业务镜像并验证
bash
docker tag myapp:v1 reg.timinglee.org/library/myapp:v1
docker push reg.timinglee.org/library/myapp:v1
docker tag myapp:v2 reg.timinglee.org/library/myapp:v2
docker push reg.timinglee.org/library/myapp:v2
kubectl run myapp-pod --image=reg.timinglee.org/library/myapp:v1
kubectl get pods -o wide
kubectl delete pod myapp-pod
九、推荐完整执行顺序
- 创建 4 台虚拟机,确认 IP、主机名和 /etc/hosts。
- 在 172.25.254.254 安装 Docker 和 Harbor。
- 生成 HTTPS 证书,创建 k8s、library、flannel-io 项目。
- 将 Harbor 证书复制到 master、node1、node2。
- 三台节点关闭 swap。
- 三台节点安装并配置 Docker、内核参数和 registry mirror。
- 三台节点安装 cri-dockerd,确认 /var/run/cri-dockerd.sock。
- master 安装 kubelet、kubeadm、kubectl;worker 安装 kubelet、kubeadm。
- 下载或导入 Kubernetes 镜像,打 tag 后推送到 Harbor。
- 在 master 执行 kubeadm init。
- 配置 master 的 kubeconfig。
- 在 node1、node2 执行 kubeadm join。
- 将 Flannel 镜像推送到 Harbor,修改 YAML 并在 master apply。
- 确认三台节点 Ready,确认所有系统 Pod 正常。
- 上传 myapp:v1 和 myapp:v2 到 Harbor,开始业务实验。