📘 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 个副本
查看 YAMLkubectl 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 DashboardWeb UI官方提供,轻量级,支持基础资源查看与操作快速上手、开发测试环境/ˌkjuːbərˈniːtiːz ˈdæʃbɔːrd/
Lens桌面客户端功能强大,支持多集群、实时日志、终端、指标监控等;无需集群内部署组件开发者本地管理多集群/lɛnz/
RancherWeb 控制台企业级平台,集成 CI/CD、监控、日志、多集群管理中大型生产环境/ˈræntʃər/
KubeSphereWeb 控制台国产开源,功能全面(含 DevOps、微服务治理),但部署较重希望一站式平台的团队/ˈkjuːb.sfɪər/
Octant本地 WebVMware 开源,类似 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)

序号资源类型(英文)中文名称核心作用典型应用场景是否长期运行是否有状态
1Pods容器组最小部署单元,运行一个或多个容器调试、临时任务、底层运行实例
2Deployments部署声明式管理无状态应用,控制 ReplicaSet 和 PodWeb 服务、API 服务等无状态应用
3ReplicaSets副本集确保指定数量的 Pod 副本始终运行通常由 Deployment 自动管理,不直接使用
4Replication Controllers复制控制器旧版 Pod 副本管理机制(已淘汰)仅用于兼容早期 Kubernetes 版本
5StatefulSets有状态集管理有状态应用,提供稳定网络标识与持久化存储,支持有序操作数据库(MySQL、MongoDB)、ZooKeeper、Kafka 等
6DaemonSets守护进程集在每个(或匹配条件的)节点上运行一个 Pod日志收集(Fluentd)、监控代理、网络插件等
7Jobs任务运行一次性任务,成功完成后终止数据迁移、备份、批处理计算
8CronJobs定时任务按 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 - 服务模块资源说明表单
序号资源类型(英文)中文名称核心作用工作层级典型用途是否必需
1Service服务为一组 Pod 提供稳定的网络访问入口(ClusterIP、NodePort、LoadBalancer 等类型),实现服务发现与负载均衡。四层(L4) (基于 TCP/UDP)内部微服务通信、暴露应用到集群内或外部✅ 是(大多数应用都需要)
2Ingress入口路由基于 HTTP/HTTPS 的七层路由规则,将外部请求按路径或域名转发到不同的 Service。需配合 Ingress Controller 使用。七层(L7) (基于 HTTP/HTTPS)对外暴露 Web 应用(如 example.com/api → backend-service)❌ 否(仅需 HTTP 路由时使用)
3IngressClass入口类别定义 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 - 配置与存储模块资源说明表单
序号资源类型(英文)中文名称核心作用存储内容类型典型用途安全性是否持久化
1ConfigMaps配置字典存储非敏感的配置数据(如环境变量、命令行参数、配置文件),供 Pod 使用。明文(非加密)应用配置(如 nginx.conf、feature flags)❌ 低否(配置数据,非存储卷本身)
2Secrets密钥存储敏感信息(如密码、Token、TLS 证书),以 Base64 编码(非加密,需配合 etcd 加密或 RBAC 保护)。敏感数据(Base64)数据库密码、API 密钥、私钥、Docker Registry 凭据✅ 高(需额外安全措施)否(但可挂载为卷)
3Persistent Volume Claims (PVC)持久卷声明用户对存储资源的“申请”,向系统请求特定大小和访问模式的持久化存储。——(声明)为有状态应用(如数据库)申请持久磁盘取决于后端存储✅ 是(绑定 PV 后数据持久)
4StorageClasses存储类定义存储的“类型”和“供应策略”(如 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 - 集群模块资源说明表单
序号资源类型(英文)中文名称作用范围核心作用典型用途是否命名空间隔离
1Nodes节点集群级表示集群中的工作机器(物理机或虚拟机),Kubernetes 调度 Pod 到 Node 上运行。查看节点状态、资源使用、污点(Taints)、标签(Labels)❌ 否
2Namespaces命名空间集群级将集群划分为多个虚拟子集群,实现资源隔离与组织管理。多团队/多环境隔离(如 dev / test / prod)✅ 是(本身是集群资源,但用于隔离其他资源)
3Persistent Volumes (PV)持久卷集群级集群中的一块存储资源(如云硬盘、NFS 卷),由管理员预配或通过 StorageClass 动态创建。为 PVC 提供后端存储❌ 否
4Events事件集群级 / 命名空间级记录集群中发生的操作、调度、错误等事件(如 Pod 被调度、镜像拉取失败)。故障排查、审计、监控✅ 是(部分事件属于命名空间)
5Service Accounts服务账户命名空间级为 Pod 或进程提供在集群内进行 API 调用的身份凭证(自动挂载到 Pod 中)。Pod 访问 Kubernetes API(如控制器、Operator)✅ 是
6Roles角色命名空间级定义在单个命名空间内的权限规则(如可读取 Pods、可创建 ConfigMaps)。限制用户或服务账户在某命名空间的操作权限✅ 是
7Role Bindings角色绑定命名空间级Role 绑定到用户、组或 ServiceAccount,授予其对应权限。授权开发人员访问 dev 命名空间✅ 是
8Cluster Roles集群角色集群级定义整个集群范围的权限(如可查看 Nodes、Namespaces、PVs)。授权运维人员管理集群资源❌ 否
9Cluster Role Bindings集群角色绑定集群级ClusterRole 绑定到用户、组或 ServiceAccount,授予集群级权限。授权 CI/CD 系统部署到任意命名空间❌ 否
10Network 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社区

更多推荐