Skip to content
第 214 / 250 章运维⏱ 12 分钟阅读

第 214 章:K8s 进阶与 Helm

学习目标

  • 掌握 StatefulSet / DaemonSet
  • 学会 PV / PVC 存储
  • 学会 Helm 包管理
  • 理解 K8s 网络与安全

一、StatefulSet(有状态)

适用于数据库、消息队列等有状态服务。

yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  serviceName: mysql           # 关联 headless service
  replicas: 3
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
        - name: mysql
          image: mysql:8
          ports:
            - containerPort: 3306
          env:
            - name: MYSQL_ROOT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-pass
                  key: password
          volumeMounts:
            - name: data
              mountPath: /var/lib/mysql
  volumeClaimTemplates:
    - metadata:
        name: data
      spec:
        accessModes: ["ReadWriteOnce"]
        storageClassName: standard
        resources:
          requests:
            storage: 10Gi

特点:

  • 稳定的 Pod 名(mysql-0mysql-1)
  • 每个 Pod 独立存储
  • 顺序启停
yaml
# Headless Service
apiVersion: v1
kind: Service
metadata:
  name: mysql
spec:
  clusterIP: None
  selector:
    app: mysql
  ports:
    - port: 3306

二、DaemonSet(节点守护)

每个节点都跑一个 Pod,常用于日志采集、监控。

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: exporter
          image: prom/node-exporter
          ports:
            - containerPort: 9100
          resources:
            limits:
              memory: 200Mi

三、Job / CronJob

3.1 Job(一次性)

yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: data-migration
spec:
  completions: 1
  parallelism: 1
  backoffLimit: 3
  template:
    spec:
      restartPolicy: OnFailure
      containers:
        - name: migration
          image: myapp:1.0
          command: ["node", "migrate.js"]

3.2 CronJob

yaml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: report-daily
spec:
  schedule: "0 2 * * *"            # 每天凌晨 2 点
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: OnFailure
          containers:
            - name: report
              image: myapp:1.0
              command: ["node", "report.js"]

四、存储(PV / PVC)

4.1 概念

4.2 PV 示例

yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-nfs
spec:
  capacity:
    storage: 100Gi
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  nfs:
    server: 192.168.1.10
    path: /data/nfs

4.3 PVC 示例

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

4.4 在 Pod 中使用

yaml
volumes:
  - name: data
    persistentVolumeClaim:
      claimName: pvc-data

五、HPA(自动扩缩)

yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: myapp-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: myapp
  minReplicas: 2
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
    - type: Resource
      resource:
        name: memory
        target:
          type: Utilization
          averageUtilization: 80

需要 metrics-server:

bash
minikube addons enable metrics-server
kubectl top node

六、Helm(K8s 包管理)

6.1 安装

bash
brew install helm
helm version

6.2 Chart 结构

mychart/
├── Chart.yaml          # 元数据
├── values.yaml         # 默认值
├── charts/             # 子 chart
└── templates/          # 模板
    ├── deployment.yaml
    ├── service.yaml
    └── ingress.yaml

6.3 Chart.yaml

yaml
apiVersion: v2
name: myapp
description: My application
type: application
version: 1.0.0
appVersion: "1.0"

6.4 values.yaml

yaml
replicaCount: 3

image:
  repository: myapp
  tag: "1.0"
  pullPolicy: IfNotPresent

service:
  type: ClusterIP
  port: 80

resources:
  limits:
    cpu: 500m
    memory: 512Mi
  requests:
    cpu: 100m
    memory: 128Mi

6.5 templates/deployment.yaml

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Values.name }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      app: {{ .Values.name }}
  template:
    metadata:
      labels:
        app: {{ .Values.name }}
    spec:
      containers:
        - name: app
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          ports:
            - containerPort: {{ .Values.service.port }}
          resources:
            {{- toYaml .Values.resources | nindent 12 }}

6.6 常用命令

bash
# 查找
helm search hub mysql

# 安装
helm repo add bitnami https://charts.bitnami.com/bitnami
helm install mydb bitnami/mysql

# 自定义 values
helm install myapp ./mychart --values my-values.yaml

# 列出
helm list

# 升级
helm upgrade myapp ./mychart --set replicaCount=5

# 回滚
helm rollback myapp 1

# 卸载
helm uninstall myapp

七、网络

7.1 K8s 网络原则

  • 每个 Pod 有独立 IP
  • Pod 间可直连(无 NAT)
  • 节点和 Pod 可互通
  • kubelet 端口范围 30000-32767

7.2 NetworkPolicy

yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: myapp-netpol
spec:
  podSelector:
    matchLabels:
      app: myapp
  policyTypes:
    - Ingress
    - Egress
  ingress:
    - from:
        - podSelector:
            matchLabels:
              role: frontend
      ports:
        - port: 3000
  egress:
    - to:
        - podSelector:
            matchLabels:
              app: db
      ports:
        - port: 3306

7.3 Service Mesh(Istio)

yaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: myapp
spec:
  hosts:
    - myapp
  http:
    - match:
        - headers:
            x-canary:
              exact: "true"
      route:
        - destination:
            host: myapp
            subset: v2
    - route:
        - destination:
            host: myapp
            subset: v1

八、安全

8.1 RBAC

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

8.2 SecurityContext

yaml
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
  containers:
    - name: app
      securityContext:
        allowPrivilegeEscalation: false
        readOnlyRootFilesystem: true
        capabilities:
          drop:
            - ALL

8.3 NetworkPolicy 隔离

默认所有 Pod 可互相访问,用 NetworkPolicy 限制。

九、Kustomize(配置管理)

yaml
# kustomization.yaml
resources:
  - deployment.yaml
  - service.yaml

namePrefix: dev-

images:
  - name: myapp
    newTag: 1.0
bash
kubectl apply -k overlays/dev

十、本章小结

资源用途
StatefulSet有状态
DaemonSet节点守护
CronJob定时
HPA自动扩缩
PV / PVC持久化
Helm包管理

动手练习

  1. 部署一个 StatefulSet MySQL
  2. 用 Helm 部署 Redis
  3. 配置 HPA 自动扩缩
  4. 用 NetworkPolicy 限制 Pod 访问

推荐阅读


下一章:第 215 章:CI/CD 与监控

本站基于 VitePress 构建 · 由 Codebook 团队维护