Kubernetes 集群搭建实战:从零开始构建你的 K8s 环境
环境准备
1. 服务器配置
-
Harbor 仓库节点
- IP:
172.25.254.200
- 域名:
reg.registry.org
- 用途:部署 Harbor 私有镜像仓库。
- IP:
-
Kubernetes 集群节点
- Master 节点 (控制平面)
- IP:
172.25.254.201
- 域名:
reg.master.org
- IP:
- Worker 节点 1
- IP:
172.25.254.202
- 域名:
reg.worker1.org
- IP:
- Worker 节点 2
- IP:
172.25.254.203
- 域名:
reg.worker2.org
- IP:
- Master 节点 (控制平面)
2. 软件版本
- Harbor :
v2.5.4
- Kubernetes :
v1.30.0
- Docker :
27.1.2
- CRI 运行时 :
cri-dockerd v0.3.14
- 网络插件 :
Flannel v0.25.5
步骤一:部署 Harbor 私有镜像仓库
1. 安装 Docker
在 172.25.254.200
(Harbor 仓库节点)上安装 Docker:
# 解压 Docker 安装包
tar zxvf docker.tar.gz
# 安装 RPM 包
dnf install *.rpm -y
# 修改 Docker 启动参数(启用 iptables)
vim /lib/systemd/system/docker.service
# 添加参数:--iptables=true
# 启动并启用 Docker 服务
systemctl enable --now docker.service
2. 配置 HTTPS 证书
Harbor 需要 HTTPS 支持,生成自签名证书:
mkdir -p /data/certs
openssl req -newkey rsa:4096 -nodes -sha256 \
-keyout /data/certs/https.key \
-addext "subjectAltName = DNS:reg.registry.org" \
-x509 -days 365 -out /data/certs/https.crt
3. 安装 Harbor
# 解压 Harbor 安装包
tar zxvf harbor-offline-installer-v2.5.4.tgz
# 配置 harbor.yml
cd harbor
cp harbor.yml.tmpl harbor.yml
vim harbor.yml
# 修改以下参数:
hostname: reg.registry.org
certificate: /data/certs/https.crt
private_key: /data/certs/https.key
harbor_admin_password: 123456
# 启动 Harbor
./install.sh --with-chartmuseum
访问 https://reg.registry.org
,使用 admin/123456
登录 Harbor 管理界面。

步骤二:配置 Kubernetes 节点
1. 禁用 Swap
Kubernetes 不支持 Swap,需在所有节点禁用:
# 修改 fstab 文件
vim /etc/fstab
# 注释掉 swap 分区行
# 禁用 Swap 并永久生效
systemctl mask swap.target
swapoff -a
reboot
2. 安装 Docker
将 172.25.254.200
上的 Docker 安装包传输到其他节点:
# 在 Harbor 节点执行
scp docker.tar.gz root@172.25.254.201:/root
scp docker.tar.gz root@172.25.254.202:/root
scp docker.tar.gz root@172.25.254.203:/root
# 在所有节点执行以下命令
tar zxvf docker.tar.gz
dnf install *.rpm -y
systemctl enable --now docker.service
3. 配置 Docker 镜像仓库
在所有节点配置 Docker 使用 Harbor 作为镜像仓库:
# 上传证书到节点
for i in 201 202 203; do
ssh root@172.25.254.$i "mkdir -p /etc/docker/certs.d/reg.registry.org"
scp /data/certs/https.crt root@172.25.254.$i:/etc/docker/certs.d/reg.registry.org/ca.crt
done
# 配置 daemon.json
vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://reg.registry.org"]
}
systemctl restart docker
步骤三:安装 Kubernetes 组件
1. 安装 CRI 运行时(cri-dockerd)
# 上传 RPM 包到所有节点
for i in 201 202 203; do
scp cri-dockerd-*.rpm libcgroup-*.rpm root@172.25.254.$i:/mnt/
done
# 安装 cri-dockerd
dnf install -y /mnt/cri-dockerd-*.rpm /mnt/libcgroup-*.rpm
# 修改 cri-docker.service 配置
vim /lib/systemd/system/cri-docker.service
# 添加参数:
ExecStart=/usr/bin/cri-dockerd --container-runtime-endpoint fd:// --network-plugin=cni --pod-infra-container-image=reg.registry.org/k8s/pause:3.9
systemctl enable --now cri-docker.service
2. 安装 Kubernetes RPM 包
# 上传 k8s RPM 包到所有节点
tar zxvf k8s-1.30.tar.gz
dnf install -y *.rpm
# 启动 kubelet 服务
systemctl enable --now kubelet.service
步骤四:初始化 Kubernetes 集群
1. 在 Master 节点初始化集群
kubeadm init \
--pod-network-cidr=10.244.0.0/16 \
--image-repository reg.registry.org/k8s \
--kubernetes-version v1.30.0 \
--cri-socket=unix:///var/run/cri-dockerd.sock
# 配置 kubectl
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
source ~/.bash_profile
2. 部署网络插件(Flannel)
# 加载 Flannel 镜像
docker load -i flannel-0.25.5.tar.gz
# 推送镜像到 Harbor
docker tag flannel/flannel:v0.25.5 reg.registry.org/flannel/flannel:v0.25.5
docker tag flannel/flannel-cni-plugin:v1.5.1-flannel1 reg.registry.org/flannel/flannel-cni-plugin:v1.5.1-flannel1
docker push reg.registry.org/flannel/flannel:v0.25.5
docker push reg.registry.org/flannel/flannel-cni-plugin:v1.5.1-flannel1
# 修改 Flannel 配置文件
sed -i 's|docker.io/flannel|reg.registry.org/flannel|g' kube-flannel.yml
kubectl apply -f kube-flannel.yml
步骤五:加入 Worker 节点
1. 生成 Token 并加入集群
# 在 Master 节点生成加入命令
kubeadm token create --print-join-command
# 在 Worker 节点执行命令
kubeadm join 172.25.254.201:6443 \
--token <token> \
--discovery-token-ca-cert-hash <hash> \
--cri-socket=unix:///var/run/cri-dockerd.sock
2. 验证节点状态
# 在 Master 节点查看节点状态
kubectl get nodes
# 输出示例:
NAME STATUS ROLES AGE VERSION
reg.master.org Ready control-plane 10m v1.30.0
reg.worker1.org Ready <none> 5m v1.30.0
reg.worker2.org Ready <none> 3m v1.30.0
步骤六:测试 Kubernetes 集群
1. 部署一个测试 Pod
# 登录 Harbor 仓库
docker login reg.registry.org -u admin -p 123456
# 创建测试 Pod
kubectl run test-private --image=reg.registry.org/library/nginx:latest
# 查看 Pod 状态
kubectl get pods -o wide
# 输出示例:
NAME READY STATUS RESTARTS IP NODE NOMINATED NODE READINESS GATES
test-private 1/1 Running 0 10.244.2.5 reg.worker2.org <none> <none>
2. 验证 Pod 功能
# 进入 Pod 容器
kubectl exec -it test-private -- sh
# 测试 Nginx 服务
curl http://127.0.0.1
总结
通过以上步骤,你已经成功搭建了一个包含私有镜像仓库 Harbor 和 Kubernetes 集群的环境。该集群支持多节点扩展、私有镜像拉取以及基本的网络通信。未来可以进一步探索以下方向:
- 高可用集群:通过多个 Master 节点实现 HA。
- 持久化存储:集成 Ceph 或 NFS 提供持久化卷。
- 监控与日志:部署 Prometheus 和 ELK 栈实现集群监控与日志分析。
configmap
configmap的功能
configMap用于保存配置数据,以键值对形式存储。
configMap 资源提供了向 Pod 注入配置数据的方法。
镜像和配置文件解耦,以便实现镜像的可移植性和可复用性。
etcd限制了文件大小不能超过1M
configmap的使用场景
填充环境变量的值
设置容器内的命令行参数
填充卷的配置文件
configmap创建方式
字面值创建
kubectl create cm userlist --from-literal name1=1 --from-literal pass1=lee 【创建】
kubectl get configmaps
kubectl get cm 【configmaps可以缩减为cm】
kubectl describe cm userlist 查看结果:
通过文件创建
cat name1
name:1
cat pass1
pass:1
kubectl delete cm userlist
kubectl create cm userlist --from-file name1 --from-file pass1
kubectl describe cm userlist 查看结果:
通过目录创建
mkdir -p lee
mv name1 pass1 lee/
ls lee/
kubectl delete cm userlist
kubectl create cm userlist --from-file lee/
通过yaml文件创建
kubectl create cm userlist --from-literal db_host=172.25.254.100 --from-literal db_port=3306 --dry-run=client -o yaml > userlist.yaml
vim userlist.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: lee-config
data:
db_host: "172.25.254.100"
db_port: "3306"
kubectl delete cm userlist
kubectl apply -f userlist.yaml
kubectl describe cm lee-config 查看结果:

configmap的使用方式
通过环境变量的方式直接传递给pod
通过pod的 命令行运行方式
作为volume的方式挂载到pod内
使用configmap填充环境变量
将cm中的内容映射为指定变量
vim testpod.yml
apiVersion: v1
kind: Pod
metadata:
labels:
run: testpod
name: testpod
spec:
containers:
- image: busyboxplus:latest
name: testpod
command:
-
/bin/sh
-
-c
-
env
env:
- name: key1
valueFrom:
configMapKeyRef:
name: lee-config #从 ConfigMap lee-config读取db_host的值赋给环境变量 key1
key: db_host
- name: key2
valueFrom:
configMapKeyRef:
name: lee-config #从 ConfigMap lee-config读取db_port的值赋给环境变量 key1
key: db_port
restartPolicy: Never
kubectl apply -f testpod.yml
kubectl logs pods/testpod

k8s调度器
- 调度器在 K8s 中的位置与核心流程
API Server ←→ etcd ←→ kube-scheduler ←→ kubelet
创建:用户提交 Pod 描述(YAML/Helm/Operator)。
监听:调度器通过 Watch 机制捕获到 spec.nodeName="" 的 Pod。
过滤:根据资源、污点、亲和性等"硬性条件"过滤出可行节点(Feasible Nodes)。
打分:对可行节点按策略打分,最高分胜出。
绑定:将 spec.nodeName 写入 Pod 对象,目标节点的 kubelet 开始真正启动容器。
重调度:节点故障或资源不足 → 删除原 Pod → 回到步骤 2。
调度器是控制面唯一的"决策大脑",但它不做网络/存储分配;它只是给 Pod 选"座位"。
- 调度方式全景图
级别 方法 典型场景 备注
强制 nodeName 排障、DaemonSet 优先级最高,绕过调度器
标签 nodeSelector 指定 gpu=true、ssd=true 简单,功能有限
亲和 nodeAffinity 软/硬亲和 支持 In/NotIn/Gt/Lt/Exists
Pod 间 podAffinity / podAntiAffinity 同域部署、打散 需大量计算,大集群慎用
污点 taint + toleration 隔离生产/测试、驱逐 NoSchedule / PreferNoSchedule / NoExecute
高级 多调度器、扩展器、Score 插件 自定义算法 自 1.19 支持 Scheduling Framework
- 手把手实战:从简单到高阶
3.1 nodeName ------ 一把梭,但风险高
apiVersion: v1
kind: Pod
metadata:
name: one-shot-tool
spec:
nodeName: k8s-node2 # 直接绑定,不经过调度器
containers:
- name: debug
image: alpine:latest
command: ["sleep", "3600"]
缺点:节点不存在或资源不足时直接 Pending,调度器不会帮你重试。

3.2 nodeSelector ------ 80% 场景已够用
给节点打标签
kubectl label node k8s-node1 disktype=ssd zone=beijing
spec:
nodeSelector:
disktype: ssd
zone: beijing
小技巧:对同一类节点批量打标签 kubectl label node -l node-role.kubernetes.io/worker= tier=frontend

