📘 Kubernetes v1.28.2 + containerd 集群部署手册(CentOS 7.9)

适用环境:VMware 三节点集群

  • Master: 192.168.204.130
  • Worker-1: 192.168.204.131
  • Worker-2: 192.168.204.132
    技术栈kubeadm 初始化,containerd 作为容器运行时,网络插件选用 Flannel

目录

第一部分:部署前必读

第二部分:安装部署准备

第三部分:通用配置(所有节点)

第四部分:核心组件安装(所有节点)

第五部分:集群初始化与扩展

第六部分:验证与应用部署

第七部分:资源管理与运维

  • 7.1 删除部署
  • [7.2 常用 kubectl 命令速查](72-常用 kubectl 命令速查)

第八部分:第三方工具可视化管理


第一部分:部署前必读

1.1 各组件角色与关系总览

🎯 一句话理解 Kubernetes
它是一个“自动化工厂(声明式运维)”,你告诉它“我要 3 个 Nginx”,它就自动找机器、拉镜像、启动容器、配网络,挂了就重启,并保证它们一直运行。

组件 类型 作用(人话版) 跑在哪? 发音
kubeadm 集群“安装工” 一键搭建 Master,或让新机器加入集群 Master(初始化)、Worker(加入) /ˈkuːbiˌædəm/
kubelet 节点“管家” 盯着本机的 Pod,确保容器按要求跑起来 每台机器(Master + Worker)都要装 /ˈkuːbiˌlɛt/
kubectl 用户“遥控器” 你在终端敲的命令(如 kubectl get pods)都靠它发给集群 通常在 Master 或你的笔记本上 /ˈkuːbiˌkʌntl/
containerd 容器“调度员” 负责拉镜像、启停容器(听 kubelet 指挥) 每台机器 /kənˈteɪnərd/
runc 容器“执行者” 真正在 Linux 上 fork 出容器进程的底层工具 每台机器(被 containerd 调用) /rʌŋk/
Flannel 网络“搭桥工” 让不同机器上的 Pod 能互相通信(比如 A 机器的 Pod 能 ping B 机器的 Pod) 所有节点(以 Pod 形式运行) /ˈflænəl/

💡 小贴士

  • 所有带 “kube” 的词都读作 /ˈkuːb/(类似“库布”)。
  • 这些组件分工明确、各司其职,通过标准接口协作,不互相强耦合。

1.2 组件调用层级关系(自底向上)

想象你要在一台机器上启动一个容器,整个过程像“层层上报+层层执行”:

硬件(CPU / Memory / Disk / Network)
│
▼
Linux 内核(提供 cgroups, namespaces, netfilter, veth, etc.)
│
▼
runc(OCI 运行时)←───┐
│                      │
▲ 由 containerd-shim 调用(每个容器一个 shim)
│
containerd ──▶ 管理镜像、容器生命周期、snapshot、task
│               ├─ 拉取镜像(image service)
│               └─ 启动容器(通过 shim + runc)
│
▲ 通过 CRI(Unix Socket,如 /run/containerd/containerd.sock)
│
kubelet ──▶ 节点代理,负责 Pod 管理:
           ├─ 调 CRI → 创建 Pod 沙箱(即 Pause 容器)→ 再创建应用容器
           └─ 调 CNI → 配置网络(如 Flannel/Calico,通过 /opt/cni/bin/...)
│
▲ 由 systemd 管理(通常配置为 kubelet.service)
▲ containerd 通常也由 systemd 管理(containerd.service)

容器启动的调用链:kubelet 通过 CRI 调用 containerd,containerd 通过 shim 调用 runc 创建容器(包括 Pause 容器),底层依赖 Linux 内核的命名空间和 cgroups,网络由 CNI 插件配置,所有服务由 systemd 管理。

关键理解

  • kubelet 不直接操作容器,而是通过两个标准接口:
    • CRI(Container Runtime Interface) → 对接 containerd;
    • CNI(Container Network Interface) → 对接 Flannel。
  • 这种设计让 Kubernetes 不绑定具体技术——你可以换 Docker、Podman、Calico 等,只要符合标准就行。

Pod 是 Kubernetes 中最小的运行单元,可以包含一个或多个共享网络和存储的容器,通常用来部署一个应用实例。

Pod 中的所有容器共享同一个网络命名空间、IPC 命名空间、UTS 命名空间,并可挂载相同的存储卷。它们就像运行在同一台“逻辑主机”上的协作进程。

🔍 为什么要有 Pause 容器?
它是 Pod 的“基石”:所有容器共享它的网络、IPC 命名空间。即使应用容器崩溃重启,IP 和端口也不会变。


在 Kubernetes 中,一个 Pod 就像一套合租房,里面的容器要共享网络和 IP。
但 Linux 系统规定:只要房子里没人,房子就会被收回

Pause 容器就是那个“一直待在屋里不走的人”——它啥也不干,只负责占着房子。
这样,就算其他容器重启或退出,Pod 的网络和环境也不会丢。

没有 Pause 容器,Pod 的“家”就保不住。


1.3 整体架构图

┌──────────────────────────────┐
│        用户(你)             │
│            │                 │
│            ▼                 │
│       [ kubectl ]            │ ← 你的“遥控器”:发送命令
└────────────┬─────────────────┘
             │ (通过 HTTPS + TLS 安全通信)
             ▼
┌───────────────────────────────────────────────┐
│           控制平面(Control Plane)             │ ← 只运行在 Master 节点
│                                              │
│  ┌─────────────┐                             │
│  │ API Server  │◄──────────────────────┐     │ ← 所有请求的唯一入口
│  └──────▲──────┘                       │     │
│         │                              │     │
│   ┌─────┴─────┐    ┌──────────────┐   │      │
│   │   etcd    │    │  Scheduler   │   │      │ ← 调度器:决定新 Pod 放哪台 Worker
│   │(集群大脑)│      │(调度器)     │   │      │
│   └─────▲─────┘    └──────┬───────┘   │      │
│         │                   │         │      │
│   ┌─────┴───────────────────▼──────┐  │      │
│   │     Controller Manager         │  │      │ ← 控制器:确保实际状态 = 期望状态
│   │(如 Deployment、ReplicaSet 等)  │  │      │
│   └───────────────────────────────┘   │      │
│                                       │      │
└───────────────────┬───────────────────┘      │
                    │                          │
                    ▼                          │
          ┌──────────────────┐                 │
          │   kube-scheduler │─────────────────┘
          │   kube-controller│←(内部组件,通常合并展示)
          └──────────────────┘
                    │
                    ▼
    ┌───────────────────────────────┐
    │        工作节点(Worker Nodes)│ ← 运行你的应用
    │                               │
    │  ┌─────────────────────────┐  │
    │  │       kubelet           │  │ ← 每台机器的“管家”:管理 Pod 和容器
    │  ├─────────────────────────┤  │
    │  │     容器运行时          │  │ ← 如 containerd、Docker(运行容器)
    │  ├─────────────────────────┤  │
    │  │     CNI 插件(如 Flannel)│ │ ← 网络插件,以 DaemonSet 形式运行
    │  │                         │  │
    │  │  ┌───────────────────┐  │  │
    │  │  │   应用 Pod        │  │  │ ← 你的 Nginx、review.jar 等容器
    │  │  │ • 容器 A          │  │  │
    │  │  │ • 容器 B(可选)   │  │  │
    │  │  └───────────────────┘  │  │
    │  └─────────────────────────┘  │
    └───────────────────────────────┘
                    ▲
                    │
        所有 Pod 在同一个虚拟网络中(例如 10.244.0.0/16)
        → 跨节点通信就像在同一个局域网!

🧠 记住这个流程
你下命令 → API Server 接收 → etcd 存储 → 控制器响应 → 调度器分配 → kubelet 执行


1.4 工作流示例(部署 Nginx)

假设你执行:

kubectl apply -f nginx.yaml

背后发生了什么?

1️⃣ 你下命令
    → 运行 kubectl apply -f nginx.yaml
    → kubectl 将 YAML 转为 REST API 请求,通过 HTTPS 发送给 API Server
2️⃣ API Server 接收并验证
    → 检查身份、权限、资源合法性
    → 验证通过后,将“期望状态”(如一个 Nginx Deployment)持久化写入 etcd
3️⃣ Controller Manager 响应
    → Deployment 控制器监听到新对象,发现“当前没有 Pod,但应该有 1 个”
    → 自动创建对应的 ReplicaSet,再由 ReplicaSet 创建 Pod 对象(此时状态为 Pending,尚未绑定节点)
4️⃣ Scheduler 分配节点
    → 调度器发现这个 Pending 的 Pod
    → 根据资源、亲和性、污点等策略,选择一台合适的 Worker 节点
    → 将 pod.spec.nodeName 更新为该节点名,并写回 etcd
5️⃣ 目标节点的 kubelet 开始执行
kubelet 定期从 API Server 同步“分配给本机的 Pod”,一旦发现新任务,立即启动:
① 启动 Pause 容器
	→ 由容器运行时(如 containerd)创建,作为 Pod 的“网络沙箱”(共享网络/IPC 命名空间)
② 调用 CNI 插件(如 Flannel)
	→ 为 Pause 容器分配 IP(例如 10.244.1.5)
	→ 配置虚拟网卡(veth pair)、路由规则,接入集群网络
③ 启动应用容器(Nginx)
	→ 启动 Nginx 容器,并共享 Pause 容器的网络命名空间,实现 Pod 内多容器共用 IP
6️⃣ Pod 就绪,服务可用
	→ 所有容器启动成功,kubelet 上报状态为 Running
	→ 其他 Pod 或服务可通过 10.244.1.5 直接访问该 Nginx —— 跨节点通信如同局域网!

💡 核心思想总结:

你只声明“要什么”,Kubernetes 自动完成“在哪跑、怎么跑、挂了怎么办”
整个过程由 API Server + etcd + 控制器 + 调度器 + kubelet 协同完成,形成一个闭环的“控制循环”。


第二部分:安装部署准备

2.1 前提条件

  • 操作系统:CentOS Linux release 7.9.2009 (Core)
  • 用户权限:可使用 root 或具备 sudo 权限
  • 网络要求:
    • 三台虚拟机互通(能互相 ping
    • 网卡为 ens33(VMware NAT 模式,默认网关 192.168.204.2
    • 已启用 virbr0(由 libvirt 创建,可忽略)
  • 时间同步:建议启用 chronyd(本文略,因非关键阻塞项)

第三部分:通用配置(所有节点)

3.1 设置静态 IP

⚠️ 注意:每台机器 IP 不同,请按角色设置。 原因:Kubernetes 节点必须使用固定 IP 地址

# 查看当前连接名(通常为 "System eth0" 或类似)
nmcli con show

# 假设连接名为 "System eth0",替换为实际名称
INTERFACE="System eth0"

# Master 节点执行
sudo nmcli con mod "$INTERFACE" \
  ipv4.addresses 192.168.204.130/24 \
  ipv4.gateway 192.168.204.2 \
  ipv4.dns "8.8.8.8,114.114.114.114" \
  ipv4.method manual

# Worker-1 节点执行
sudo nmcli con mod "$INTERFACE" \
  ipv4.addresses 192.168.204.131/24 \
  ipv4.gateway 192.168.204.2 \
  ipv4.dns "8.8.8.8,114.114.114.114" \
  ipv4.method manual

# Worker-2 节点执行
sudo nmcli con mod "$INTERFACE" \
  ipv4.addresses 192.168.204.132/24 \
  ipv4.gateway 192.168.204.2 \
  ipv4.dns "8.8.8.8,114.114.114.114" \
  ipv4.method manual

# 重启网络连接生效
sudo nmcli con down "$INTERFACE" && sudo nmcli con up "$INTERFACE"

3.2 关闭防火墙(测试环境)

# 原因:避免防火墙阻断 k8s 组件间通信。
sudo systemctl stop firewalld
sudo systemctl disable firewalld

🔒 生产建议:保留防火墙,开放以下端口:

  • Master: 6443, 2379-2380, 10250, 10251, 10252
  • Worker: 10250, 30000-32767

3.3 禁用 SELinux

# 原因:SELinux 的强制访问控制(MAC)会阻止容器访问主机资源。
sudo setenforce 0
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

3.4 关闭 Swap

# 原因:Kubernetes 强制要求关闭 swap。
sudo swapoff -a
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab

3.5 配置主机名与 /etc/hosts

# k8s 使用主机名标识节点
# Master
sudo hostnamectl set-hostname k8s-master

# Worker-1
sudo hostnamectl set-hostname k8s-worker-1

# Worker-2
sudo hostnamectl set-hostname k8s-worker-2

所有节点/etc/hosts 中添加:

cat >> /etc/hosts <<EOF
192.168.204.130 k8s-master
192.168.204.131 k8s-worker-1
192.168.204.132 k8s-worker-2
EOF

3.6 启用内核模块与 sysctl 参数

# 原因:为容器网络和运行时提供内核级支持
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
vm.swappiness = 0
EOF

sudo sysctl --system

第四部分:核心组件安装(所有节点)

4.1 安装 containerd

1. 下载并解压
wget https://github.com/containerd/containerd/releases/download/v1.7.2/containerd-1.7.2-linux-amd64.tar.gz
sudo tar Cxzvf /usr/local containerd-1.7.2-linux-amd64.tar.gz
2. 生成并修改配置
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml

编辑 /etc/containerd/config.toml,修改以下两处:

# 找到 [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] 段落
# Kubernetes 推荐在启用了 systemd 的系统上将此值设为 true,以确保 Kubelet 和 containerd 使用相同的 cgroup 驱动。
SystemdCgroup = true

# 找到顶部的 sandbox_image 行(可能在 [plugins."io.containerd.grpc.v1.cri"] 下)
# 解决国内网络无法拉取 Google 镜像的问题
sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.9"
3. 安装 systemd 服务并启动
sudo wget https://raw.githubusercontent.com/containerd/containerd/main/containerd.service -P /usr/local/lib/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now containerd

说明containerd.service 是 systemd 用来启动、管理和自启 containerd 守护进程的配置文件。设置开机自启并受系统统一管理。

4. 验证
ctr version
# 应显示 Client 和 Server 均为 v1.7.2

4.2 安装 runc

# runc 负责根据 OCI 规范,直接在 Linux 系统上创建和运行容器。
wget https://github.com/opencontainers/runc/releases/download/v1.1.7/runc.amd64
sudo mv runc.amd64 /usr/bin/runc
sudo chmod +x /usr/bin/runc

runc -v
# 输出应包含 version 1.1.7

💡 若系统已有 runc,请先 which runc 确认路径再替换。


4.3 安装 Kubernetes 组件

1. 配置 YUM 源
sudo curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo

cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

sudo yum clean all && sudo yum makecache
2. 安装 kubeadm、kubelet、kubectl
sudo yum install -y kubeadm kubelet kubectl
sudo systemctl enable kubelet  # 注意:设置开机自启。此时不启动 start,由 kubeadm 控制
3. 验证版本
kubeadm version
# 应显示 v1.28.2

第五部分:集群初始化与扩展

5.1 初始化 Master 节点(仅在 k8s-master 执行)

1. 初始化集群
sudo kubeadm init \
  --apiserver-advertise-address=192.168.204.130 \
  --image-repository=registry.aliyuncs.com/google_containers \
  --kubernetes-version=v1.28.2 \
  --pod-network-cidr=10.244.0.0/16

✅ 成功后会输出类似以下的 join 命令,请复制保存

kubeadm join 192.168.204.130:6443 --token xxxx --discovery-token-ca-cert-hash sha256:xxxx
2. 配置 kubectl
# 让当前用户(或所有用户)能正常使用 kubectl 命令来管理 Kubernetes 集群
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

# 或全局生效(推荐)
echo 'export KUBECONFIG=/etc/kubernetes/admin.conf' >> /etc/profile
source /etc/profile

5.2 部署 Flannel 网络插件(仅在 Master 执行)

说明:只需在 Master 执行一次 kubectl apply,Flannel DaemonSet 会自动部署到所有节点。

1. 导入离线镜像(所有节点)

提前下载 flannel.tarflannel-cni-plugin-v1.1.2.tar 到各节点

ctr -n k8s.io images import flannel.tar
ctr -n k8s.io images import flannel-cni-plugin-v1.1.2.tar
2. 创建 kube-flannel.yml(仅在 Master 执行)
cat > kube-flannel.yml <<'EOF'
---
apiVersion: v1
kind: Namespace
metadata:
  name: kube-flannel
  labels:
    k8s-app: flannel
    pod-security.kubernetes.io/enforce: privileged
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: flannel
  namespace: kube-flannel
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: flannel
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get"]
- apiGroups: [""]
  resources: ["nodes"]
  verbs: ["get", "list", "watch"]
- apiGroups: [""]
  resources: ["nodes/status"]
  verbs: ["patch"]
- apiGroups: ["networking.k8s.io"]
  resources: ["clustercidrs"]
  verbs: ["list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: flannel
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: flannel
subjects:
- kind: ServiceAccount
  name: flannel
  namespace: kube-flannel
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: kube-flannel-cfg
  namespace: kube-flannel
  labels:
    tier: node
    app: flannel
data:
  cni-conf.json: |
    {
      "name": "cbr0",
      "cniVersion": "0.3.1",
      "plugins": [
        {
          "type": "flannel",
          "delegate": {
            "hairpinMode": true,
            "isDefaultGateway": true
          }
        },
        {
          "type": "portmap",
          "capabilities": {
            "portMappings": true
          }
        }
      ]
    }
  net-conf.json: |
    {
      "Network": "10.244.0.0/16",
      "Backend": {
        "Type": "vxlan"
      }
    }
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: kube-flannel-ds
  namespace: kube-flannel
  labels:
    tier: node
    app: flannel
spec:
  selector:
    matchLabels:
      app: flannel
  template:
    metadata:
      labels:
        tier: node
        app: flannel
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: kubernetes.io/os
                operator: In
                values:
                - linux
      hostNetwork: true
      priorityClassName: system-node-critical
      tolerations:
      - operator: Exists
        effect: NoSchedule
      serviceAccountName: flannel
      initContainers:
      - name: install-cni-plugin
        image: docker.io/flannel/flannel-cni-plugin:v1.1.2
        command: ["/bin/sh", "-c"]
        args: ["cp -f /flannel /opt/cni/bin/flannel;"]
        volumeMounts:
        - name: cni-bin
          mountPath: /opt/cni/bin
      - name: install-cni
        image: docker.io/flannel/flannel:v0.21.5
        command: ["/bin/sh", "-c"]
        args: ["set -e -x; cp -f /etc/kube-flannel/cni-conf.json /etc/cni/net.d/10-flannel.conflist;"]
        volumeMounts:
        - name: cni
          mountPath: /etc/cni/net.d
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
      containers:
      - name: kube-flannel
        image: docker.io/flannel/flannel:v0.21.5
        command: ["/opt/bin/flanneld"]
        args:
        - --ip-masq
        - --kube-subnet-mgr
        resources:
          requests:
            cpu: "100m"
            memory: "50Mi"
        securityContext:
          capabilities:
            add: ["NET_ADMIN", "NET_RAW"]
          privileged: false
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        volumeMounts:
        - name: run
          mountPath: /run/flannel
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
        - name: xtables-lock
          mountPath: /run/xtables.lock
      volumes:
      - name: run
        hostPath:
          path: /run/flannel
      - name: cni-bin
        hostPath:
          path: /opt/cni/bin
      - name: cni
        hostPath:
          path: /etc/cni/net.d
      - name: flannel-cfg
        configMap:
          name: kube-flannel-cfg
      - name: xtables-lock
        hostPath:
          path: /run/xtables.lock
          type: FileOrCreate
EOF
3. 应用配置(仅在 Master 执行)
kubectl apply -f kube-flannel.yml
4. 验证(仅在 Master 执行)
kubectl get pods -n kube-flannel
# 所有 Pod 应为 Running

5.3 Worker 节点加入集群(在 Worker-1 和 Worker-2 执行)

使用 Master 初始化时输出的 join 命令,例如:

sudo kubeadm join 192.168.204.130:6443 \
  --token plgh4f.9mev1hmunpf9bzpq \
  --discovery-token-ca-cert-hash sha256:d32be9a6a631687fba69ac9e9544ee4a931a686395aa65b1a60ba0f6e9ea0b64
  
  
 # 重新加入执行这个 
  
  # 方式一、 重置当前节点
  sudo kubeadm reset -f
  
  # 方式二
  # 删除 Kubernetes 相关目录
sudo rm -rf /etc/kubernetes/
sudo rm -rf /var/lib/kubelet/

# (可选)清理 CNI 缓存(避免网络冲突)
sudo rm -rf /var/lib/cni/
sudo rm -rf /run/flannel/   # 如果用 Flannel

# 重启 kubelet 和 containerd
sudo systemctl restart containerd
sudo systemctl restart kubelet 

🔁 若 token 过期,在 Master 重新生成:

kubeadm token create --print-join-command

第六部分:验证与应用部署

6.1 验证集群(Master 执行)

kubectl get nodes

预期输出

NAME           STATUS   ROLES           AGE   VERSION
k8s-master     Ready    control-plane   10m   v1.28.2
k8s-worker-1   Ready    <none>          2m    v1.28.2
k8s-worker-2   Ready    <none>          1m    v1.28.2

6.2 部署 Nginx 示例(Master 执行)

1. 创建 nginx-deploy.yaml
# 使用 cat 命令将以下内容写入 nginx-deploy.yaml 文件(此处为说明,实际使用时可忽略此行)
cat > nginx-deploy.yaml <<'EOF'
---
# ==============================
# 第一部分:Nginx Deployment 配置
# 用于声明式地管理 Nginx Pod 的副本数量和运行方式
# ==============================
apiVersion: apps/v1            # 使用 apps/v1 API 版本(Kubernetes 1.9+ 标准)
kind: Deployment               # 资源类型:Deployment(用于管理有状态/无状态应用的副本)
metadata:
  name: nginx                  # Deployment 的名称,在命名空间内必须唯一
spec:
  replicas: 1                  # 希望运行的 Pod 副本数(这里只部署 1 个实例)
  selector:
    matchLabels:
      app: nginx               # 通过标签选择器关联由该 Deployment 管理的 Pod
  template:                    # 定义 Pod 的模板(如何创建每个 Pod)
    metadata:
      labels:
        app: nginx             # 给 Pod 打上标签,必须与上面 selector.matchLabels 一致
    spec:
      containers:
      - name: nginx            # 容器名称(一个 Pod 可含多个容器,这里只有一个)
        image: docker.m.daocloud.io/library/nginx:1.25.5
                               # 使用 DaoCloud 加速镜像仓库拉取官方 Nginx 镜像(版本 1.25.5)
        ports:
        - containerPort: 80    # 容器内部监听的端口(Nginx 默认 HTTP 端口)

---
# ==============================
# 第二部分:Nginx Service 配置
# 为 Pod 提供稳定的网络访问入口
# ==============================
apiVersion: v1                 # Service 属于 core/v1 API
kind: Service                  # 资源类型:Service(抽象 Pod 的网络访问)
metadata:
  name: nginx-svc              # Service 的名称
spec:
  type: NodePort               # Service 类型:NodePort
                               # 会在每个集群节点上开放一个端口(范围默认 30000-32767)
  ports:
  - port: 80                   # Service 自身监听的端口(集群内部可通过 nginx-svc:80 访问)
    targetPort: 80             # 将流量转发到 Pod 的 80 端口(对应 containerPort)
    nodePort: 30081            # 在物理节点上暴露的端口(外部可通过 <NodeIP>:30081 访问)
  selector:
    app: nginx                 # 将流量路由到所有带有 app=nginx 标签的 Pod

EOF
2. 部署 & 验证
kubectl apply -f nginx-deploy.yaml

# 查看 Pod 分布
kubectl get pods -l app=nginx -o wide

# 测试访问(任一节点 IP)
curl http://192.168.204.130:30081
# 应返回 Nginx 欢迎页 HTML

6.3 部署 review.jar 包示例(Master 执行)

将本地构建的 Spring Boot 应用 review.jar 容器化并部署到 Kubernetes 集群中。整个流程包括:

  • 拉取基础 JDK 镜像;
  • 构建自定义应用镜像;
  • 推送至阿里云容器镜像服务(ACR);
  • 编写 Deployment 与 Service YAML 文件;
  • 在 Master 节点上完成部署和验证。
6.3.1 前提条件
  • 本地已安装 Docker Desktop,并能通过代理访问外网;
  • 已配置好 Kubernetes 集群(含 kubectl)
  • 拥有 阿里云 ACR 实例 的读写权限;
  • review.jar 文件位于当前工作目录下;
  • 系统时间与时区设置正确(推荐使用 Asia/Shanghai);
6.3.2 拉取并推送基础 JDK 镜像(JDK 8)
# 拉取官方 Temurin JDK 8 JRE 镜像
docker pull eclipse-temurin:8-jre

# 查看镜像是否成功拉取
docker images | findstr "temurin"

# 登录阿里云 ACR(请替换为你的实际用户名)
docker login --username=雷开你的门lc crpi.cn-hangzhou.personal.cr.aliyuncs.com

# 打标签并推送至私有仓库
docker tag eclipse-temurin:8-jre crpi.cn-hangzhou.personal.cr.aliyuncs.com/docker_lc_dev/eclipse-temurin-8-jre:8
docker push crpi.cn-hangzhou.personal.cr.aliyuncs.com/docker_lc_dev/eclipse-temurin-8-jre:8

💡 提示:若使用 Linux 或 macOS,请将 findstr 替换为 grep

6.3.3 构建 review 应用镜像

Dockerfile 内容如下

FROM crpi.cn-hangzhou.personal.cr.aliyuncs.com/docker_lc_dev/eclipse-temurin-8-jre:8
WORKDIR /app
COPY review.jar app.jar
EXPOSE 8091
ENTRYPOINT ["java", "-jar", "/app/app.jar"]

构建并推送镜像

docker build -t review:latest .
docker tag review:latest crpi.cn-hangzhou.personal.cr.aliyuncs.com/docker_lc_dev/review:latest
docker push crpi.cn-hangzhou.personal.cr.aliyuncs.com/docker_lc_dev/review:latest
6.3.4 编写 Kubernetes 部署文件

创建 review-deploy.yaml 文件:

---
# ----------------------------
# Deployment 配置:用于管理 Pod 的副本和生命周期
# ----------------------------
apiVersion: apps/v1          # 使用 apps/v1 API 版本(Kubernetes 1.9+ 推荐)
kind: Deployment             # 资源类型:Deployment
metadata:
  name: review               # Deployment 的名称
  namespace: default         # 所属命名空间(默认为 default)
  labels:
    app: review              # 给 Deployment 打上标签,便于识别和选择
spec:
  replicas: 1                # 希望运行的 Pod 副本数(这里只启动 1 个实例)
  selector:
    matchLabels:
      app: review            # 选择带有 app=review 标签的 Pod 进行管理
  template:                  # Pod 模板(定义如何创建 Pod)
    metadata:
      labels:
        app: review          # Pod 的标签,必须与上面 selector.matchLabels 一致
    spec:
      containers:
      - name: review         # 容器名称
        image: crpi.cn-hangzhou.personal.cr.aliyuncs.com/docker_lc_dev/review:latest
                             # 镜像地址(阿里云个人版容器镜像仓库)
        ports:
        - containerPort: 8091 # 容器内部监听的端口
        env:                 # 环境变量
        - name: TZ
          value: Asia/Shanghai  # 设置时区为上海(中国标准时间)
        - name: SERVER_PORT
          value: "8091"        # 应用监听的端口(字符串格式,部分应用要求如此)
        resources:           # 资源限制与请求
          requests:
            memory: "256Mi"   # 请求 256Mi 内存(调度时保证最低资源)
            cpu: "100m"       # 请求 0.1 个 CPU 核心(100m = 0.1 core)
          limits:
            memory: "512Mi"   # 最多允许使用 512Mi 内存(超出可能被 OOM Kill)
            cpu: "500m"       # 最多允许使用 0.5 个 CPU 核心
        imagePullPolicy: IfNotPresent  # 镜像拉取策略:本地存在则不拉取(适合开发测试)

---
# ----------------------------
# Service 配置:为 Pod 提供网络访问入口
# ----------------------------
apiVersion: v1               # Service 属于 core/v1 API
kind: Service                # 资源类型:Service
metadata:
  name: review-service       # Service 名称
  namespace: default         # 所属命名空间
spec:
  type: NodePort             # Service 类型:NodePort(在每台节点上开放一个端口)
  ports:
    - port: 8091             # Service 自身监听的端口(集群内可通过 <service>:8091 访问)
      targetPort: 8091       # 转发到 Pod 的目标端口(对应 containerPort)
      nodePort: 30091        # 在所有节点上暴露的物理端口(范围通常 30000-32767)
      protocol: TCP          # 使用 TCP 协议
  selector:
    app: review              # 将流量转发给带有 app=review 标签的 Pod
6.3.5 部署应用并验证
kubectl apply -f review-deploy.yaml
kubectl get pods -l app=review
curl http://192.168.204.131:30091/review/export

#Nginx代理

# ingress 代理  C:\Windows\System32\drivers\etc\hosts
kubectl get svc review-service
kubectl get ingress review-ingress
kubectl get svc -n ingress-nginx

http://review.local:32157/review/export
http://nacos.local:32157/nacos

⚠️ 注意:若返回 {"code":"500","message":"网络异常","data":null},证明网络通了,这个服务返回的。

6.3.6 补充建议(可选)
  • 健康检查:建议在 Deployment 中添加 livenessProbereadinessProbe
  • 配置管理:敏感配置建议使用 ConfigMapSecret
  • 日志收集:集成 Fluentd / Loki 等日志系统;
  • 自动构建:可结合 Jenkins 或 GitHub Actions 实现 CI/CD。

📌 总结:本章完整展示了从本地 JAR 包到 Kubernetes 部署的标准化流程,适用于开发测试环境快速上线。生产环境建议进一步增强安全性、可观测性与弹性伸缩能力。


第七部分:资源管理与运维

7.1 删除部署(推荐方式)

kubectl delete -f nginx-deploy.yaml
kubectl delete -f review-deploy.yaml
或者
kubectl delete deployment nginx
kubectl delete service nginx-svc

7.2 常用 kubectl 命令速查

场景 命令 说明
查看资源 kubectl get pods -o wide 查看 Pod 列表
kubectl get svckubectl get services 查看 Service
kubectl get deploy 查看 Deployment
kubectl get nodes 查看节点状态
kubectl get all 查看当前命名空间下所有核心资源
kubectl get cm 查看 ConfigMap
查看详情 kubectl describe pod <pod-name> 查看 Pod 详细事件和状态
kubectl logs <pod-name> 查看 Pod 日志
kubectl logs -f <pod-name> 实时跟踪日志(类似 tail -f
进入容器 kubectl exec -it <pod-name> -- /bin/sh 进入容器终端(Nginx 可用 /bin/bash/bin/sh
编辑资源 kubectl edit deploy nginx 在线编辑 Deployment 配置(会触发滚动更新)
扩缩容 kubectl scale deploy nginx --replicas=3 手动扩容到 3 个副本
查看 YAML kubectl get deploy nginx -o yaml 输出当前 Deployment 的完整 YAML
清理命名空间 kubectl delete all --all 删除当前命名空间下所有可删资源(谨慎!)
切换命名空间 kubectl config set-context --current --namespace=<ns> 设置默认命名空间
查看 API 资源 kubectl api-resources 列出所有支持的资源类型

💡 最佳实践:用 kubectl apply -f xxx.yaml 部署,就用 kubectl delete -f xxx.yaml 删除,确保一致性。



第八部分:第三方工具可视化管理

8.1 可视化方案对比

工具名称 类型 特点 适用场景 读音
Kubernetes Dashboard Web UI 官方提供,轻量级,支持基础资源查看与操作 快速上手、开发测试环境 /ˌkjuːbərˈniːtiːz ˈdæʃbɔːrd/
Lens 桌面客户端 功能强大,支持多集群、实时日志、终端、指标监控等;无需集群内部署组件 开发者本地管理多集群 /lɛnz/
Rancher Web 控制台 企业级平台,集成 CI/CD、监控、日志、多集群管理 中大型生产环境 /ˈræntʃər/
KubeSphere Web 控制台 国产开源,功能全面(含 DevOps、微服务治理),但部署较重 希望一站式平台的团队 /ˈkjuːb.sfɪər/
Octant 本地 Web VMware 开源,类似 Lens 的本地工具,需在本地运行 临时调试、轻量级可视化需求 /ˈɑːk.tənt/

推荐选择

  • 个人/小团队快速使用Lens(https://k8slens.dev/)
  • 需 Web 界面且简单可靠Kubernetes Dashboard

8.2 Kubernetes Dashboard 部署指南

步骤 1:部署官方 YAML(v2.7.0)
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml

⚠️ 注意:该 YAML 中引用的两个镜像在国内无法直接拉取:

  • kubernetesui/dashboard:v2.7.0
  • kubernetesui/metrics-scraper:v1.0.8
步骤 2:在可联网机器(如 Windows + Docker Desktop)拉取并推送到私有仓库
# 拉取镜像
docker pull kubernetesui/dashboard:v2.7.0
docker pull kubernetesui/metrics-scraper:v1.0.8

# 登录阿里云 ACR(替换为你的实际信息)
docker login --username=雷开你的门lc crpi.cn-hangzhou.personal.cr.aliyuncs.com

# 打标签并推送
docker tag kubernetesui/dashboard:v2.7.0 crpi.cn-hangzhou.personal.cr.aliyuncs.com/docker_lc_dev/dashboard:v2.7.0
docker push crpi.cn-hangzhou.personal.cr.aliyuncs.com/docker_lc_dev/dashboard:v2.7.0

docker tag kubernetesui/metrics-scraper:v1.0.8 crpi.cn-hangzhou.personal.cr.aliyuncs.com/docker_lc_dev/metrics-scraper:v1.0.8
docker push crpi.cn-hangzhou.personal.cr.aliyuncs.com/docker_lc_dev/metrics-scraper:v1.0.8
步骤 3:修改 recommended.yaml 使用私有镜像

将原 YAML 中的以下两处镜像地址替换为你的阿里云地址:

# Deployment: kubernetes-dashboard
image: crpi.cn-hangzhou.personal.cr.aliyuncs.com/docker_lc_dev/dashboard:v2.7.0

# Deployment: dashboard-metrics-scraper
image: crpi.cn-hangzhou.personal.cr.aliyuncs.com/docker_lc_dev/metrics-scraper:v1.0.8

💡 提示:其余 RBAC、Service、ConfigMap 等配置保持不变。

步骤 4:应用修改后的 YAML 并验证
kubectl apply -f recommended.yaml
kubectl get pods -n kubernetes-dashboard

✅ 预期输出:

NAME                                         READY   STATUS    RESTARTS   AGE
dashboard-metrics-scraper-657999b679-ts86z   1/1     Running   0          2m
kubernetes-dashboard-6c95b5b597-bc9z4        1/1     Running   0          2m

8.3 访问与登录 Dashboard

方式一:kubectl proxy(推荐,最安全)

本地电脑(已配置 kubeconfig)执行:

kubectl proxy

浏览器访问:

http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/
方式二:临时改为 NodePort(仅限测试)
kubectl -n kubernetes-dashboard edit service kubernetes-dashboard
# 将 type: ClusterIP 改为 type: NodePort

获取端口:

kubectl -n kubernetes-dashboard get svc kubernetes-dashboard
# 输出示例:443:30376/TCP

浏览器访问(注意是 https):

https://192.168.204.130:30376

⚠️ 需手动接受证书警告。

获取登录 Token(推荐方式)

创建管理员用户:

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(有效期默认 1 小时):

kubectl -n kubernetes-dashboard create token admin-user

复制输出的完整 Token,在 Dashboard 登录页选择 Token 并粘贴。


8.4 Dashboard 各模块功能详解

8.4.1 工作负载(Workloads)

序号 资源类型(英文) 中文名称 核心作用 典型应用场景 是否长期运行 是否有状态
1 Pods 容器组 最小部署单元,运行一个或多个容器 调试、临时任务、底层运行实例
2 Deployments 部署 声明式管理无状态应用,控制 ReplicaSet 和 Pod Web 服务、API 服务等无状态应用
3 ReplicaSets 副本集 确保指定数量的 Pod 副本始终运行 通常由 Deployment 自动管理,不直接使用
4 Replication Controllers 复制控制器 旧版 Pod 副本管理机制(已淘汰) 仅用于兼容早期 Kubernetes 版本
5 StatefulSets 有状态集 管理有状态应用,提供稳定网络标识与持久化存储,支持有序操作 数据库(MySQL、MongoDB)、ZooKeeper、Kafka 等
6 DaemonSets 守护进程集 在每个(或匹配条件的)节点上运行一个 Pod 日志收集(Fluentd)、监控代理、网络插件等
7 Jobs 任务 运行一次性任务,成功完成后终止 数据迁移、备份、批处理计算
8 CronJobs 定时任务 按 Cron 表达式周期性创建 Job 每日清理、定时报表、定时健康检查 否(按计划触发)
  1. Pods(容器组)
    • 最小的可部署单元,包含一个或多个共享资源的容器。
    • 通常由控制器(如 Deployment、StatefulSet 等)管理,不建议直接创建。
    • 用于查看实际运行的容器实例、状态、日志等。
  2. Deployments(部署)
    • 声明式管理无状态应用的 Pod 和 ReplicaSet。
    • 支持滚动更新、版本回滚、扩缩容等操作。
    • 适用于 Web 服务、API 服务等无状态应用。
  3. ReplicaSets(副本集)
    • 确保指定数量的 Pod 副本始终处于运行状态。
    • 通常由 Deployment 自动创建和管理,一般不直接使用。
    • 是 Deployment 实现副本控制的底层机制。
  4. Replication Controllers(复制控制器)
    • Kubernetes 早期用于管理 Pod 副本的控制器。
    • 功能已被 ReplicaSet 取代,现已基本弃用。
    • 仅用于兼容旧版本应用。
  5. StatefulSets(有状态集)
    • 专为有状态应用设计,提供稳定的网络标识(如 pod-0、pod-1)和持久化存储。
    • 支持有序部署、扩缩容和删除。
    • 适用于数据库(MySQL、MongoDB)、分布式中间件(ZooKeeper、Kafka)等。
  6. DaemonSets(守护进程集)
    • 确保集群中每个(或满足条件的)节点上都运行一个 Pod 副本。
    • 常用于部署日志收集器(Fluentd)、监控代理(Node Exporter)、网络插件(Calico)等系统级服务。
    • 新增节点时自动调度 Pod。
  7. Jobs(任务)
    • 运行一次性任务,直到 Pod 成功完成(退出码为 0)。
    • 适用于批处理场景,如数据导入、备份、计算任务等。
    • 完成后不会自动重启。
  8. CronJobs(定时任务)
    • 基于 Cron 表达式周期性地创建 Job。
    • 用于定期执行任务,如每日清理、定时报表生成、健康检查等。
    • 类似 Linux 的 crontab,但运行在 Kubernetes 集群中。

8.4.2 服务(Services)

🌐 Kubernetes Dashboard - 服务模块资源说明表单
序号 资源类型(英文) 中文名称 核心作用 工作层级 典型用途 是否必需
1 Service 服务 为一组 Pod 提供稳定的网络访问入口(ClusterIP、NodePort、LoadBalancer 等类型),实现服务发现与负载均衡。 四层(L4) (基于 TCP/UDP) 内部微服务通信、暴露应用到集群内或外部 ✅ 是(大多数应用都需要)
2 Ingress 入口路由 基于 HTTP/HTTPS 的七层路由规则,将外部请求按路径或域名转发到不同的 Service。需配合 Ingress Controller 使用。 七层(L7) (基于 HTTP/HTTPS) 对外暴露 Web 应用(如 example.com/api → backend-service) ❌ 否(仅需 HTTP 路由时使用)
3 IngressClass 入口类别 定义 Ingress 使用的控制器类型(如 nginx、traefik、aws-alb),用于指定由哪个 Ingress Controller 处理该 Ingress。 控制器调度层 在多 Ingress Controller 环境中指定路由处理者 ❌ 否(K8s ≥1.18 推荐使用)
🔍 补充说明
Service
  • 类型包括:
    • ClusterIP(默认,仅集群内访问)
    • NodePort(通过节点 IP + 端口访问)
    • LoadBalancer(云厂商自动创建外部负载均衡器)
    • ExternalName(映射到 DNS 名称)
  • 不依赖任何额外组件,Kubernetes 原生支持。
Ingress
  • 本身不提供功能,必须部署 Ingress Controller(如 Nginx Ingress Controller、Traefik、AWS ALB Controller)才能生效。

  • 支持基于 主机名(host)路径(path) 的路由。

  • 示例:

    # 访问 http://shop.example.com → 转发到 shop-service
    # 访问 http://blog.example.com → 转发到 blog-service
    
IngressClass
  • 自 Kubernetes 1.18 起引入,用于替代旧版 kubernetes.io/ingress.class 注解。
  • 每个 Ingress 可通过 .spec.ingressClassName 字段引用一个 IngressClass。
  • IngressClass 会关联一个具体的 Ingress Controller(通过 .spec.controller 字段)。
📌 使用关系图
外部用户
   ↓ (HTTP/HTTPS)
Ingress(定义路由规则)
   ↓ (引用 IngressClass)
IngressClass(指定由谁处理 → 如 nginx-ingress-controller)
   ↓
Service(负载均衡到后端 Pod)
   ↓
Pods(实际运行的应用)

8.4.3 配置与存储(Config & Storage)

🗂️ Kubernetes Dashboard - 配置与存储模块资源说明表单
序号 资源类型(英文) 中文名称 核心作用 存储内容类型 典型用途 安全性 是否持久化
1 ConfigMaps 配置字典 存储非敏感的配置数据(如环境变量、命令行参数、配置文件),供 Pod 使用。 明文(非加密) 应用配置(如 nginx.conf、feature flags) ❌ 低 否(配置数据,非存储卷本身)
2 Secrets 密钥 存储敏感信息(如密码、Token、TLS 证书),以 Base64 编码(非加密,需配合 etcd 加密或 RBAC 保护)。 敏感数据(Base64) 数据库密码、API 密钥、私钥、Docker Registry 凭据 ✅ 高(需额外安全措施) 否(但可挂载为卷)
3 Persistent Volume Claims (PVC) 持久卷声明 用户对存储资源的“申请”,向系统请求特定大小和访问模式的持久化存储。 ——(声明) 为有状态应用(如数据库)申请持久磁盘 取决于后端存储 ✅ 是(绑定 PV 后数据持久)
4 StorageClasses 存储类 定义存储的“类型”和“供应策略”(如 SSD、HDD、云硬盘),支持动态创建 PV。 ——(模板/策略) 实现按需自动分配持久卷(Dynamic Provisioning) —— ✅ 是(用于创建持久卷)
🔍 补充说明
ConfigMaps
  • 可通过以下方式注入 Pod:
    • 环境变量
    • 命令行参数
    • 挂载为只读卷(Volume)
  • 修改 ConfigMap 后,已挂载的卷不会自动更新(除非使用 subPath 以外的方式并启用 configMap 的自动重载机制)。
Secrets
  • 虽然内容以 Base64 编码,

    但不是加密

    !建议:

    • 启用 etcd 静态加密(Encryption at Rest)
    • 严格限制 RBAC 权限
    • 使用外部密钥管理服务(如 HashiCorp Vault、AWS Secrets Manager)
  • 常见类型:Opaquekubernetes.io/tlskubernetes.io/dockerconfigjson

Persistent Volume Claims (PVC)
  • PVC 是用户视角的“存储请求”,实际由 Persistent Volume (PV) 提供。
  • 生命周期独立于 Pod:Pod 删除后,PVC 和数据仍保留(取决于回收策略)。
  • 访问模式:ReadWriteOnce(RWO)、ReadOnlyMany(ROX)、ReadWriteMany(RWX)
StorageClasses
  • 关键字段:
    • provisioner:指定存储供应商(如 kubernetes.io/aws-ebs, csi-cephfsplugin
    • parameters:传递后端存储参数(如 type=gp3, fsType=xfs)
    • reclaimPolicy:回收策略(Delete / Retain
  • 只有标记为 (default) 的 StorageClass 才能在 PVC 不指定时自动使用。
📌 资源关系图
StorageClass
   ↓ (定义如何动态创建)
PersistentVolume (PV) ←→ PersistentVolumeClaim (PVC) ←(Pod 引用)
   ↑
Pod 挂载 PVC 作为持久卷

ConfigMap / Secret
   ↓ (通过 volumeMount 或 env 注入)
Pod 使用配置或密钥

💡 最佳实践建议

  • 不要将敏感信息放入 ConfigMap,应使用 Secret。
  • 优先使用动态存储(StorageClass + PVC),避免手动管理 PV。
  • 为 Secret 启用 RBAC 限制,防止未授权访问。

8.4.4 集群(Cluster)

🌐 Kubernetes Dashboard - 集群模块资源说明表单
序号 资源类型(英文) 中文名称 作用范围 核心作用 典型用途 是否命名空间隔离
1 Nodes 节点 集群级 表示集群中的工作机器(物理机或虚拟机),Kubernetes 调度 Pod 到 Node 上运行。 查看节点状态、资源使用、污点(Taints)、标签(Labels) ❌ 否
2 Namespaces 命名空间 集群级 将集群划分为多个虚拟子集群,实现资源隔离与组织管理。 多团队/多环境隔离(如 dev / test / prod) ✅ 是(本身是集群资源,但用于隔离其他资源)
3 Persistent Volumes (PV) 持久卷 集群级 集群中的一块存储资源(如云硬盘、NFS 卷),由管理员预配或通过 StorageClass 动态创建。 为 PVC 提供后端存储 ❌ 否
4 Events 事件 集群级 / 命名空间级 记录集群中发生的操作、调度、错误等事件(如 Pod 被调度、镜像拉取失败)。 故障排查、审计、监控 ✅ 是(部分事件属于命名空间)
5 Service Accounts 服务账户 命名空间级 为 Pod 或进程提供在集群内进行 API 调用的身份凭证(自动挂载到 Pod 中)。 Pod 访问 Kubernetes API(如控制器、Operator) ✅ 是
6 Roles 角色 命名空间级 定义在单个命名空间内的权限规则(如可读取 Pods、可创建 ConfigMaps)。 限制用户或服务账户在某命名空间的操作权限 ✅ 是
7 Role Bindings 角色绑定 命名空间级 Role 绑定到用户、组或 ServiceAccount,授予其对应权限。 授权开发人员访问 dev 命名空间 ✅ 是
8 Cluster Roles 集群角色 集群级 定义整个集群范围的权限(如可查看 Nodes、Namespaces、PVs)。 授权运维人员管理集群资源 ❌ 否
9 Cluster Role Bindings 集群角色绑定 集群级 ClusterRole 绑定到用户、组或 ServiceAccount,授予集群级权限。 授权 CI/CD 系统部署到任意命名空间 ❌ 否
10 Network Policies 网络策略 命名空间级 控制 Pod 之间的入站(ingress)和出站(egress)网络流量(需 CNI 支持)。 微服务间网络隔离(如禁止 frontend 访问 database 直连) ✅ 是
🔍 关键概念补充
🔐 RBAC(基于角色的访问控制)体系
  • Role + RoleBinding → 仅限单个命名空间
  • ClusterRole + ClusterRoleBinding全集群生效
  • 绑定对象可以是:
    • User(外部用户)
    • Group(用户组)
    • ServiceAccount(Pod 使用的身份)

💡 示例:

  • dev-team 用户绑定 dev-namespace 中的 pod-reader Role → 只能看该命名空间的 Pod。
  • monitoring-sa ServiceAccount 绑定 view ClusterRole → 可读取所有命名空间的资源。
🌐 Network Policies
  • 默认情况下,所有 Pod 可互相通信
  • 一旦在命名空间中应用 NetworkPolicy,未被允许的流量将被拒绝(白名单模式)。
  • 依赖支持 NetworkPolicy 的 CNI 插件(如 Calico、Cilium、Weave Net)。
📦 Persistent Volumes (PV) vs PVC
  • PV:集群级存储资源(由管理员或 StorageClass 创建)
  • PVC:命名空间级存储请求(由用户创建)
  • PVC 与 PV 通过 绑定(bound) 关联,实现解耦。
🧩 资源关系简图
ClusterRole ── ClusterRoleBinding ──→ User / Group / ServiceAccount(集群权限)
     ↑
     │
Role ─────── RoleBinding ─────────→ User / Group / ServiceAccount(命名空间权限)

ServiceAccount → 自动挂载到 Pod → Pod 使用其身份调用 API Server

NetworkPolicy → 应用于命名空间内的 Pod → 控制 Pod 间网络通信

PV ←─(动态/静态)─ PVC ←─ Pod(挂载使用)
✅ 最佳实践建议
  • 最小权限原则:只授予必要的权限。
  • 避免使用 default ServiceAccount 执行敏感操作,应创建专用 ServiceAccount。
  • 关键命名空间启用 NetworkPolicy,防止横向移动攻击。
  • 定期清理无用 Events,避免 etcd 膨胀。

8.4.5 自定义资源(Custom Resources)

🧩 Kubernetes Dashboard - 自定义资源模块说明表单
项目 内容
资源类型(英文) CustomResourceDefinition(简称 CRD)
中文名称 自定义资源定义
作用范围 集群级(Cluster-scoped)
核心作用 允许用户在不修改 Kubernetes 源码或编写复杂控制器的情况下,扩展 Kubernetes API,定义自己的资源类型(如 DatabaseCronJobBackupMachineLearningJob 等)。
工作原理 通过创建一个 CRD 对象,向 Kubernetes API Server 注册一种新的资源类型。注册后,用户即可像操作原生资源(如 Pod、Service)一样,使用 kubectl get myresourcekubectl apply -f xxx.yaml 等命令管理该资源。通常配合 自定义控制器(Custom Controller)Operator 使用,实现业务逻辑(如自动创建数据库实例、备份策略等)。
典型用途 封装复杂应用的部署与运维逻辑(如 etcd-operator、Prometheus Operator)定义领域特定资源(如 WebAppMLModelTenant)实现平台即服务(PaaS)抽象层
是否需要控制器? 强烈建议配合控制器使用 • 仅有 CRD 时,资源只是“静态配置”,无实际行为。 • 控制器监听 CR 变化,执行真实操作(如创建 Pod、调用外部 API)。
示例:CRD 定义 yaml<br>apiVersion: apiextensions.k8s.io/v1<br>kind: CustomResourceDefinition<br>metadata:<br> name: databases.example.com<br>spec:<br> group: example.com<br> versions:<br> - name: v1<br> served: true<br> storage: true<br> schema: { ... }<br> scope: Namespaced<br> names:<br> plural: databases<br> singular: database<br> kind: Database<br>
对应自定义资源(CR)示例 yaml<br>apiVersion: example.com/v1<br>kind: Database<br>metadata:<br> name: my-db<br>spec:<br> size: 3<br> engine: mysql-8.0<br>
在 Dashboard 中的作用 查看已注册的 CRD 列表查看每个 CRD 的版本、作用域、状态(部分 Dashboard 版本支持)直接查看/编辑对应的自定义资源(CR)实例
注意事项 删除 CRD 会同时删除所有该类型的自定义资源(CR),需谨慎操作!CRD 一旦创建,其结构(schema)应尽量保持向后兼容。建议使用 OpenAPI v3 schema 校验字段合法性。
🔗 关键概念关系图
CustomResourceDefinition (CRD)
        ↓ (定义)
Custom Resource (CR) —— 如 Database、BackupTask
        ↓ (被监听)
Custom Controller / Operator
        ↓ (执行)
Pods / Services / External Systems(实现业务逻辑)
✅ 总结一句话:

CRD 是 Kubernetes 的“插件机制”——它让你能像使用原生资源一样,定义和管理自己的应用专属资源类型。


8.5 安全加固建议

8.4 安全建议

  1. 禁止长期暴露 NodePort:测试完成后应改回 ClusterIP
  2. 避免使用默认账号登录kubernetes-dashboard ServiceAccount 权限有限且不安全。
  3. 生产环境应通过 Ingress + HTTPS + OAuth2 Proxy 或 Dex 实现认证
  4. 定期轮换 Token:可通过 --duration=8h 指定更长有效期(谨慎使用)。
  5. 限制 Dashboard 网络访问:结合 NetworkPolicy 或防火墙规则。

🔒 最佳实践:仅在必要时临时开启外部访问,日常管理优先使用 kubectl proxy 或 Lens。



资料文件下载

  • 迅雷云盘链接:https://pan.xunlei.com/s/VOiMDGlRvT7WmilG67Ci4pLoA1?pwd=myz5#
  • 包含文件containerd.service, runc.amd64, recommended.yaml, review.jar 相关构建物等

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐