4、Kubernetes集群部署:K8s架构理解、kubeadm搭建集群、部署Dashboard、Pod与Service管理
好,咱们进入第四章节。说实话,Kubernetes 这块内容,是低代码平台能否真正扛住生产压力的分水岭。很多同学在单机 Docker 上跑得挺欢,一上集群就各种翻车。我当年第一次部署 K8s 集群时,也是踩了不少坑,今天就把这些经验掰开揉碎讲给你听。
4.1 先搞懂 K8s 架构:别急着动手
很多人一上来就敲命令,结果出了问题完全不知道从哪查。我个人习惯是,先花半小时把架构图看明白。
Kubernetes 说白了就两大块:控制平面和工作节点。
- 控制平面(Master):集群的大脑。包含 API Server、Scheduler、Controller Manager、etcd。API Server 是唯一入口,你所有操作都得经过它。
- 工作节点(Node):真正跑容器的地方。每个节点上有 kubelet、kube-proxy、容器运行时(比如 containerd)。
为什么会这样设计?你想想看,如果每个节点都能直接改集群状态,那不乱套了?所以所有变更必须经过 API Server,它负责鉴权、校验,然后写入 etcd。Scheduler 负责把 Pod 分配到合适的节点上。Controller Manager 则像个监工,确保集群状态跟你期望的一致。
4.2 用 kubeadm 搭建集群:我推荐的方式
搭建 K8s 集群的方式有好几种,kubeadm、二进制部署、minikube 等等。对于生产环境,我强烈推荐 kubeadm。它帮你把很多繁琐的证书生成、组件配置都自动化了,但又不是黑盒,出了问题你能知道去哪查。
下面是我总结的标准化步骤,你照着做基本不会出错:
4.2.1 环境准备
我建议至少准备 3 台机器(1 个 Master + 2 个 Node)。系统用 Ubuntu 20.04 或 CentOS 7.9 都行。每台机器都要做:
# 关闭 swap(K8s 要求必须关)
sudo swapoff -a
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
# 开启内核模块
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
# 设置 sysctl 参数
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
4.2.2 安装容器运行时
K8s 从 1.24 版本开始移除了对 Docker 的直接支持,推荐用 containerd。我个人习惯用 containerd,性能更好,也更轻量。
# 安装 containerd
sudo apt-get update
sudo apt-get install -y containerd
# 生成默认配置
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
# 修改配置,使用 systemd cgroup 驱动
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
sudo systemctl restart containerd
sudo systemctl enable containerd
4.2.3 安装 kubeadm、kubelet、kubectl
# 添加 K8s 源
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl
curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-archive-keyring.gpg
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
# 安装指定版本(我建议用稳定版,比如 1.28)
sudo apt-get update
sudo apt-get install -y kubelet=1.28.0-00 kubeadm=1.28.0-00 kubectl=1.28.0-00
sudo apt-mark hold kubelet kubeadm kubectl
4.2.4 初始化 Master 节点
这一步是关键。在 Master 机器上执行:
sudo kubeadm init \
--apiserver-advertise-address=192.168.1.100 \
--pod-network-cidr=10.244.0.0/16 \
--kubernetes-version=1.28.0
初始化成功后,会输出一段 kubeadm join 命令,记得保存好,那是 Worker 节点加入集群的凭证。
4.2.5 配置 kubectl
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
# 验证
kubectl get nodes
4.2.6 安装网络插件
我推荐 Flannel,简单稳定:
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
4.2.7 Worker 节点加入
在每台 Worker 节点上执行刚才保存的 join 命令:
sudo kubeadm join 192.168.1.100:6443 --token xxxxx --discovery-token-ca-cert-hash sha256:xxxxx
等几分钟,在 Master 上执行 kubectl get nodes,应该能看到所有节点状态为 Ready。
4.3 部署 Dashboard:可视化运维
命令行虽然强大,但可视化界面在某些场景下更直观。我一般会给团队部署一个 Dashboard,方便非运维人员查看资源状态。
# 部署 Dashboard
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml
# 创建管理员用户
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kubernetes-dashboard
EOF
# 获取登录 token
kubectl -n kubernetes-dashboard create token admin-user
然后通过 kubectl proxy 访问:http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/
4.4 Pod 与 Service 管理:核心实操
集群搭好了,总得跑点东西吧?Pod 是 K8s 最小的调度单元,Service 则是稳定的网络入口。
4.4.1 创建第一个 Pod
我一般不用命令行直接创建 Pod,而是写 YAML 文件,方便版本管理。
# nginx-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
kubectl apply -f nginx-pod.yaml
kubectl get pods -o wide
4.4.2 用 Deployment 管理 Pod
Deployment 能保证你期望的 Pod 数量始终满足。比如我要跑 3 个 Nginx:
# nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
kubectl apply -f nginx-deployment.yaml
kubectl get deployment
kubectl get pods
你会发现 Pod 名字后面带了一串随机字符,那是 Deployment 自动生成的。如果你删掉一个 Pod,Deployment 会立刻再起一个。
4.4.3 Service:让 Pod 可以被访问
Pod 的 IP 是动态的,重启就变了。Service 提供了一个固定的入口。我常用的有三种类型:
| 类型 | 说明 | 适用场景 |
|---|---|---|
| ClusterIP | 集群内部可访问 | 内部服务调用 |
| NodePort | 通过节点 IP + 端口访问 | 测试环境、简单暴露 |
| LoadBalancer | 云厂商提供负载均衡器 | 生产环境对外暴露 |
# nginx-service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
type: NodePort
kubectl apply -f nginx-service.yaml
kubectl get service
然后你就可以通过任意节点的 IP + NodePort 访问 Nginx 了。比如 http://192.168.1.101:30080。
4.5 本章小结
这一章内容不少,但都是实打实的干货。从架构理解到集群搭建,再到 Dashboard 和核心资源管理,每一步我都尽量把踩过的坑告诉你。你想想看,如果当初有人告诉我这些,我至少能少熬三个通宵。
下一章我们会深入讲存储和配置管理,到时候再聊。