Skip to content

第四部分 Kubernetes 核心基础

Kubernetes(简称 K8s)是 Google 开源的容器编排平台,用于自动化部署、扩展和管理容器化应用。本部分从零开始讲解 K8s 架构、核心对象、工作负载、服务发现、存储和权限控制。


第 11 章 Kubernetes 架构与核心组件

11.1 什么是 Kubernetes

Kubernetes 是一个开源的容器编排系统,可以:

  • 自动化容器的部署和复制
  • 随时扩展或收缩容器规模
  • 提供容器间的负载均衡
  • 实现滚动更新和回滚
  • 自动故障恢复
  • 管理存储和配置

11.2 Kubernetes 架构

┌─────────────────────────────────────────────────────────────┐
│                     Kubernetes 集群                         │
│                                                             │
│  ┌───────────────────────────────────────────────────────┐  │
│  │                  控制平面(Control Plane)             │  │
│  │  ┌──────────┐  ┌──────────┐  ┌──────────┐            │  │
│  │  │ API Server│  │ etcd    │  │Scheduler │            │  │
│  │  └──────────┘  └──────────┘  └──────────┘            │  │
│  │  ┌─────────────────────────────────────────────────┐  │  │
│  │  │     Controller Manager(控制器管理器)           │  │  │
│  │  └─────────────────────────────────────────────────┘  │  │
│  └───────────────────────────────────────────────────────┘  │
│                            │                                │
│  ┌───────────────────────────────────────────────────────┐  │
│  │                    工作节点(Worker Node)             │  │
│  │  ┌──────────────┐  ┌──────────────┐  ┌────────────┐  │  │
│  │  │ kubelet      │  │ kube-proxy   │  │ Container │  │  │
│  │  │              │  │              │  │ Runtime   │  │  │
│  │  └──────────────┘  └──────────────┘  └────────────┘  │  │
│  │  ┌─────────────────────────────────────────────────┐  │  │
│  │  │              Pod(容器组)                       │  │  │
│  │  │  ┌──────────┐  ┌──────────┐                    │  │  │
│  │  │  │ Container│  │ Container│                    │  │  │
│  │  │  └──────────┘  └──────────┘                    │  │  │
│  │  └─────────────────────────────────────────────────┘  │  │
│  └───────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────┘

11.3 控制平面组件

组件作用
kube-apiserver集群的入口,处理所有 REST 请求
etcd分布式键值存储,保存集群所有数据
kube-scheduler负责将 Pod 调度到合适的节点
kube-controller-manager运行各种控制器,维护集群期望状态
cloud-controller-manager与云厂商 API 交互(云环境使用)

11.4 工作节点组件

组件作用
kubelet在每个节点上运行,管理 Pod 生命周期
kube-proxy维护节点网络规则,实现 Service 负载均衡
Container Runtime容器运行时,如 containerd、CRI-O

11.5 核心对象概述

对象说明
PodK8s 最小调度单位,一个或多个容器的组合
Deployment管理无状态应用,支持滚动更新和扩缩容
StatefulSet管理有状态应用,如数据库
DaemonSet每个节点运行一个 Pod
Service为一组 Pod 提供稳定访问入口
Ingress七层负载均衡和路由
ConfigMap存储配置数据
Secret存储敏感数据
PersistentVolume持久化存储卷
PersistentVolumeClaim存储卷声明
Namespace资源隔离
RBAC基于角色的访问控制

11.6 kubectl 基础命令

bash
# 查看节点
kubectl get nodes

# 查看 Pod
kubectl get pods
kubectl get pods -o wide
kubectl get pods -n kube-system

# 查看所有命名空间
kubectl get pods --all-namespaces
kubectl get pods -A

# 查看资源详细信息
kubectl describe pod nginx

# 查看日志
kubectl logs nginx
kubectl logs -f nginx

# 进入容器
kubectl exec -it nginx -- /bin/bash

# 创建资源
kubectl apply -f nginx.yaml

# 删除资源
kubectl delete -f nginx.yaml

# 查看资源定义
kubectl get pod nginx -o yaml

# 查看帮助
kubectl --help
kubectl get --help

11.7 本章实验

实验 11-1:查看集群组件

bash
# 1. 查看节点
kubectl get nodes -o wide

# 2. 查看系统 Pod
kubectl get pods -n kube-system

# 3. 查看组件状态
kubectl get componentstatuses

# 4. 查看 API 资源
kubectl api-resources

11.8 本章练习

  1. 解释控制平面和工作节点的区别。
  2. 列举 K8s 的 5 个核心对象。
  3. 使用 kubectl 查看集群中所有 Pod。
  4. 使用 kubectl describe 查看一个 Pod 的详细信息。

第 12 章 Pod 与容器设计模式

12.1 什么是 Pod

Pod 是 Kubernetes 的最小调度单位,可以包含一个或多个紧密相关的容器。Pod 中的容器:

  • 共享网络命名空间(IP、端口空间)
  • 共享存储卷
  • 共享 Linux 命名空间(可选)

12.2 创建第一个 Pod

yaml
# pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.25
    ports:
    - containerPort: 80
bash
kubectl apply -f pod.yaml
kubectl get pods
kubectl describe pod nginx-pod
kubectl logs nginx-pod
kubectl exec -it nginx-pod -- /bin/bash

12.3 Pod 生命周期

Pending -> ContainerCreating -> Running -> Succeeded/Failed/Unknown

Pod 状态:

状态说明
Pending已创建,等待调度或拉取镜像
Running至少一个容器在运行
Succeeded所有容器正常退出
Failed至少一个容器异常退出
Unknown无法获取 Pod 状态
CrashLoopBackOff容器反复崩溃重启
ImagePullBackOff镜像拉取失败
ErrImagePull镜像拉取出错
OOMKilled容器因内存不足被终止

12.4 Pod 探针(Probe)

探针用于检测容器健康状态。

探针类型作用
livenessProbe检测容器是否存活,失败则重启容器
readinessProbe检测容器是否准备好接收流量,失败则从 Service 中移除
startupProbe检测容器是否启动完成,避免慢启动容器被误杀
yaml
apiVersion: v1
kind: Pod
metadata:
  name: probe-demo
spec:
  containers:
  - name: app
    image: nginx:1.25
    ports:
    - containerPort: 80
    livenessProbe:
      httpGet:
        path: /
        port: 80
      initialDelaySeconds: 10
      periodSeconds: 5
    readinessProbe:
      httpGet:
        path: /
        port: 80
      initialDelaySeconds: 5
      periodSeconds: 3

12.5 多容器 Pod 设计模式

Sidecar 模式

一个主容器 + 一个辅助容器,辅助容器增强主容器功能。

例子:Nginx + Logrotate

yaml
apiVersion: v1
kind: Pod
metadata:
  name: sidecar-demo
spec:
  containers:
  - name: web
    image: nginx:1.25
    volumeMounts:
    - name: logs
      mountPath: /var/log/nginx
  - name: logrotate
    image: logrotate:latest
    volumeMounts:
    - name: logs
      mountPath: /var/log/nginx
  volumes:
  - name: logs
    emptyDir: {}

Init 容器

Init 容器在应用容器启动之前运行,用于初始化工作。

yaml
apiVersion: v1
kind: Pod
metadata:
  name: init-demo
spec:
  initContainers:
  - name: init-myservice
    image: busybox:1.36
    command: ['sh', '-c', 'until nslookup myservice; do echo waiting; sleep 2; done']
  containers:
  - name: app
    image: nginx:1.25

12.6 Pod 资源限制

yaml
apiVersion: v1
kind: Pod
metadata:
  name: resource-demo
spec:
  containers:
  - name: app
    image: nginx:1.25
    resources:
      requests:
        memory: "64Mi"
        cpu: "100m"
      limits:
        memory: "128Mi"
        cpu: "200m"
  • requests:调度时保证分配的资源
  • limits:容器能使用的最大资源

12.7 本章实验

实验 12-1:创建带探针的 Pod

bash
# 1. 创建 Pod
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: nginx-probe
spec:
  containers:
  - name: nginx
    image: nginx:1.25
    ports:
    - containerPort: 80
    livenessProbe:
      httpGet:
        path: /
        port: 80
      initialDelaySeconds: 5
      periodSeconds: 5
    readinessProbe:
      httpGet:
        path: /
        port: 80
      initialDelaySeconds: 3
      periodSeconds: 3
EOF

# 2. 查看 Pod 状态
kubectl get pod nginx-probe -w

# 3. 查看探针事件
kubectl describe pod nginx-probe

# 4. 测试存活探针
kubectl exec -it nginx-probe -- rm /usr/share/nginx/html/index.html
# 观察 Pod 是否重启
kubectl get pod nginx-probe

12.8 本章练习

  1. 创建一个包含两个容器的 Pod,一个是 Nginx,一个是 busybox,busybox 每秒向 Nginx 发送请求。
  2. 为一个 Pod 配置 livenessProbe 和 readinessProbe。
  3. 使用 Init 容器等待某个 Service 可用后再启动主容器。
  4. 解释 requests 和 limits 的区别。

第 13 章 工作负载资源

13.1 Deployment

Deployment 用于管理无状态应用,支持滚动更新、回滚和扩缩容。

yaml
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.25
        ports:
        - containerPort: 80
        resources:
          requests:
            memory: "64Mi"
            cpu: "100m"
          limits:
            memory: "128Mi"
            cpu: "200m"
bash
kubectl apply -f deployment.yaml
kubectl get deployments
kubectl get pods -l app=nginx

# 扩缩容
kubectl scale deployment nginx-deployment --replicas=5

# 滚动更新
kubectl set image deployment/nginx-deployment nginx=nginx:1.26

# 查看滚动更新状态
kubectl rollout status deployment/nginx-deployment

# 查看历史版本
kubectl rollout history deployment/nginx-deployment

# 回滚到上一个版本
kubectl rollout undo deployment/nginx-deployment

# 回滚到指定版本
kubectl rollout undo deployment/nginx-deployment --to-revision=2

13.2 StatefulSet

StatefulSet 用于管理有状态应用,如数据库、消息队列。

特点:

  • 稳定的网络标识(Pod 名固定)
  • 稳定的存储(每个 Pod 独立 PVC)
  • 有序部署和扩缩容
yaml
# statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  serviceName: "nginx-headless"
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.25
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi

Pod 名称:

web-0
web-1
web-2

13.3 DaemonSet

DaemonSet 确保每个(或部分)节点上运行一个 Pod 副本。

常见用途:

  • 日志收集(Fluentd、Filebeat)
  • 监控代理(Node Exporter)
  • 网络代理(Calico、Flannel)
yaml
# daemonset.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: node-exporter
spec:
  selector:
    matchLabels:
      app: node-exporter
  template:
    metadata:
      labels:
        app: node-exporter
    spec:
      containers:
      - name: node-exporter
        image: prom/node-exporter:latest
        ports:
        - containerPort: 9100

13.4 Job 和 CronJob

Job

Job 用于运行一次性任务。

yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: pi
spec:
  template:
    spec:
      containers:
      - name: pi
        image: perl:5.34
        command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never
  backoffLimit: 4

CronJob

CronJob 用于定时执行任务。

yaml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "*/5 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox:1.36
            command: ['sh', '-c', 'date; echo Hello from Kubernetes']
          restartPolicy: OnFailure

13.5 工作负载对比

工作负载适用场景特点
Deployment无状态应用滚动更新、回滚、扩缩容
StatefulSet有状态应用稳定网络标识、稳定存储
DaemonSet每个节点一个 Pod日志、监控、网络代理
Job一次性任务任务完成即结束
CronJob定时任务类似 Linux cron

13.6 本章实验

实验 13-1:Deployment 滚动更新和回滚

bash
# 1. 创建 Deployment
kubectl apply -f deployment.yaml

# 2. 查看 Pod
kubectl get pods -l app=nginx

# 3. 扩容到 5 个副本
kubectl scale deployment nginx-deployment --replicas=5

# 4. 更新镜像版本
kubectl set image deployment/nginx-deployment nginx=nginx:1.26

# 5. 观察滚动更新
kubectl rollout status deployment/nginx-deployment

# 6. 查看历史
kubectl rollout history deployment/nginx-deployment

# 7. 回滚
kubectl rollout undo deployment/nginx-deployment

13.7 本章练习

  1. 创建一个 3 副本的 Nginx Deployment。
  2. 将 Deployment 扩容到 5 副本,再缩容到 2 副本。
  3. 更新镜像版本,观察滚动更新过程,然后回滚。
  4. 创建一个 StatefulSet,观察 Pod 名称和 PVC。
  5. 创建一个 DaemonSet,查看每个节点上的 Pod。

第 14 章 服务发现与网络

14.1 Service 概述

Service 为一组 Pod 提供稳定的访问入口。Pod 的 IP 会变化,Service 提供固定的 ClusterIP、DNS 名和负载均衡。

14.2 Service 类型

类型说明
ClusterIP默认类型,仅在集群内部访问
NodePort在每个节点上开放一个端口,外部可通过节点 IP 访问
LoadBalancer在云环境中自动创建负载均衡器
ExternalName将 Service 映射到外部 DNS 名

14.3 ClusterIP Service

yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  type: ClusterIP
bash
kubectl apply -f service.yaml
kubectl get svc nginx-service

# 在集群内访问
curl http://nginx-service
# 或通过 DNS:
curl http://nginx-service.default.svc.cluster.local

14.4 NodePort Service

yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-nodeport
spec:
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    nodePort: 30080
  type: NodePort
bash
# 外部访问
# http://<NodeIP>:30080

14.5 LoadBalancer Service

yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-lb
spec:
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  type: LoadBalancer

在云环境中会自动创建负载均衡器,分配外部 IP。

14.6 Headless Service

Headless Service 不分配 ClusterIP,直接返回 Pod IP,常用于 StatefulSet。

yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-headless
spec:
  selector:
    app: nginx
  ports:
  - port: 80
    name: web
  clusterIP: None

14.7 Ingress

Ingress 提供七层负载均衡和路由,基于域名和路径转发流量。

yaml
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
  - host: app.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-service
            port:
              number: 80

常见 Ingress 控制器:

  • NGINX Ingress Controller
  • Traefik
  • HAProxy Ingress
  • Kong

14.8 K8s 网络模型

K8s 网络要求:

  1. 所有 Pod 可以直接通信,无需 NAT
  2. 节点上的 Agent(kubelet、kube-proxy)可以与所有 Pod 通信
  3. Pod 看到自己的 IP 与其他 Pod 看到的一致

常见 CNI 插件:

CNI特点
Calico功能丰富,支持网络策略
Flannel简单易用
Cilium基于 eBPF,高性能
Weave易用,自动发现

14.9 网络策略(NetworkPolicy)

NetworkPolicy 用于控制 Pod 之间的网络访问。

yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-nginx
spec:
  podSelector:
    matchLabels:
      app: nginx
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend
    ports:
    - protocol: TCP
      port: 80

14.10 本章实验

实验 14-1:Service 访问测试

bash
# 1. 创建 Deployment
kubectl create deployment nginx --image=nginx:1.25 --replicas=3

# 2. 创建 Service
kubectl expose deployment nginx --port=80 --target-port=80 --type=ClusterIP

# 3. 查看 Service
kubectl get svc nginx

# 4. 创建测试 Pod 访问 Service
kubectl run test --image=busybox:1.36 --rm -it --restart=Never -- sh
# 在容器内执行:
wget -O- http://nginx

实验 14-2:Ingress 部署

bash
# 1. 安装 NGINX Ingress Controller(minikube)
minikube addons enable ingress

# 2. 创建 Deployment 和 Service
kubectl create deployment nginx --image=nginx:1.25
kubectl expose deployment nginx --port=80

# 3. 创建 Ingress
kubectl apply -f ingress.yaml

# 4. 配置 hosts 或获取入口 IP 后访问
kubectl get ingress

14.11 本章练习

  1. 创建一个 Deployment 和 ClusterIP Service,从集群内访问 Service。
  2. 将 Service 改为 NodePort,从集群外访问。
  3. 部署 NGINX Ingress Controller,创建一个基于域名的 Ingress。
  4. 创建一个 NetworkPolicy,只允许特定 Pod 访问 Nginx。

第 15 章 配置管理与持久化存储

15.1 ConfigMap

ConfigMap 用于存储非敏感配置数据。

yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  database_host: "mysql"
  database_port: "3306"
  app.properties: |
    key1=value1
    key2=value2

使用方式:

yaml
apiVersion: v1
kind: Pod
metadata:
  name: config-demo
spec:
  containers:
  - name: app
    image: nginx:1.25
    env:
    - name: DB_HOST
      valueFrom:
        configMapKeyRef:
          name: app-config
          key: database_host
    volumeMounts:
    - name: config-vol
      mountPath: /etc/config
  volumes:
  - name: config-vol
    configMap:
      name: app-config

15.2 Secret

Secret 用于存储敏感数据,如密码、Token、证书。

bash
# 创建 Secret
kubectl create secret generic db-password \
  --from-literal=password=xxx

# 从文件创建
kubectl create secret tls tls-cert \
  --cert=cert.pem \
  --key=key.pem
yaml
apiVersion: v1
kind: Secret
metadata:
  name: db-password
type: Opaque
stringData:
  password: xxx

使用方式:

yaml
spec:
  containers:
  - name: app
    image: nginx:1.25
    env:
    - name: DB_PASSWORD
      valueFrom:
        secretKeyRef:
          name: db-password
          key: password

Secret 数据默认以 base64 编码存储,不是加密。生产环境应启用 etcd 加密。

15.3 持久化存储

PersistentVolume(PV)

PV 是集群中的一块存储资源。

yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-demo
spec:
  capacity:
    storage: 5Gi
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: standard
  hostPath:
    path: /tmp/k8s-pv

PersistentVolumeClaim(PVC)

PVC 是用户对存储资源的请求。

yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-demo
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  storageClassName: standard

在 Pod 中使用 PVC

yaml
apiVersion: v1
kind: Pod
metadata:
  name: pvc-demo-pod
spec:
  containers:
  - name: app
    image: nginx:1.25
    volumeMounts:
    - name: data
      mountPath: /usr/share/nginx/html
  volumes:
  - name: data
    persistentVolumeClaim:
      claimName: pvc-demo

15.4 StorageClass

StorageClass 定义存储的"类",实现动态供给。

yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: standard
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer

在云环境中:

yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: alicloud-ssd
provisioner: diskplugin.csi.alibabacloud.com
parameters:
  type: cloud_ssd
reclaimPolicy: Delete
allowVolumeExpansion: true

15.5 本章实验

实验 15-1:ConfigMap 和 Secret 使用

bash
# 1. 创建 ConfigMap
kubectl apply -f - <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
  name: game-config
data:
  game.properties: |
    enemies=aliens
    lives=3
EOF

# 2. 创建 Secret
kubectl create secret generic db-creds \
  --from-literal=username=xxx \
  --from-literal=password=xxx

# 3. 查看
kubectl get configmap game-config -o yaml
kubectl get secret db-creds -o yaml

实验 15-2:动态存储供给

bash
# 1. 查看 StorageClass
kubectl get storageclass

# 2. 创建 PVC
kubectl apply -f - <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
EOF

# 3. 查看 PVC 状态
kubectl get pvc my-pvc

# 4. 创建使用 PVC 的 Pod
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: pvc-test
spec:
  containers:
  - name: app
    image: nginx:1.25
    volumeMounts:
    - name: data
      mountPath: /data
  volumes:
  - name: data
    persistentVolumeClaim:
      claimName: my-pvc
EOF

15.6 本章练习

  1. 创建一个 ConfigMap,并在 Pod 中以环境变量和卷两种方式使用。
  2. 创建一个 Secret,并在 Pod 中以环境变量方式使用。
  3. 创建一个 PVC 并挂载到 Pod 中,写入数据后删除 Pod,重新创建验证数据是否保留。
  4. 解释 PV、PVC、StorageClass 的关系。

第 16 章 权限控制与多租户

16.1 Namespace

Namespace 用于资源隔离,适合多团队、多环境场景。

bash
# 创建命名空间
kubectl create namespace dev
kubectl create namespace prod

# 在指定命名空间创建资源
kubectl create deployment nginx --image=nginx -n dev

# 查看命名空间
kubectl get namespaces

16.2 RBAC 基础

RBAC(Role-Based Access Control)基于角色的访问控制。

核心资源:

资源说明
Role命名空间级别的权限
ClusterRole集群级别的权限
RoleBinding将 Role 绑定到用户/组/ServiceAccount
ClusterRoleBinding将 ClusterRole 绑定到用户/组/ServiceAccount

16.3 Role 和 RoleBinding

yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: dev
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]
yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods
  namespace: dev
subjects:
- kind: User
  name: alice
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

16.4 ServiceAccount

ServiceAccount 用于 Pod 内应用访问 K8s API。

bash
# 创建 ServiceAccount
kubectl create serviceaccount my-sa -n dev

# 查看 Secret/Token
kubectl get serviceaccount my-sa -n dev -o yaml

16.5 多租户实践

多租户场景下的隔离手段:

  • Namespace 隔离:按团队/项目/环境划分
  • RBAC:控制不同用户的权限
  • ResourceQuota:限制命名空间资源总量
  • LimitRange:限制 Pod/Container 资源默认值
  • NetworkPolicy:控制网络访问
yaml
apiVersion: v1
kind: ResourceQuota
metadata:
  name: dev-quota
  namespace: dev
spec:
  hard:
    requests.cpu: "10"
    requests.memory: 20Gi
    limits.cpu: "20"
    limits.memory: 40Gi
    pods: "50"

16.6 本章实验

实验 16-1:创建只读用户

bash
# 1. 创建命名空间
kubectl create namespace dev

# 2. 创建 Role
kubectl apply -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: dev
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]
EOF

# 3. 创建 ServiceAccount 和 RoleBinding
kubectl apply -f - <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
  name: dev-reader
  namespace: dev
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: dev-reader-binding
  namespace: dev
subjects:
- kind: ServiceAccount
  name: dev-reader
  namespace: dev
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io
EOF

# 4. 验证权限
kubectl auth can-i get pods --as=system:serviceaccount:dev:dev-reader -n dev

16.7 本章练习

  1. 创建 dev 和 prod 两个命名空间。
  2. 创建一个只能读取 dev 命名空间 Pod 的 Role 和 RoleBinding。
  3. 创建一个 ServiceAccount,并授予其只读权限。
  4. 为 dev 命名空间设置 ResourceQuota,限制 CPU 和内存总量。

第四部分总结

完成本阶段学习后,你应该能够:

  • 理解 K8s 架构和核心组件
  • 熟练创建和管理 Pod、Deployment、StatefulSet、DaemonSet、Job、CronJob
  • 配置 Service、Ingress、NetworkPolicy
  • 使用 ConfigMap、Secret、PV/PVC/StorageClass
  • 使用 Namespace、RBAC、ResourceQuota 实现多租户

进入下一阶段:Kubernetes 集群运维