5.3.1 Kubernetes 基础概念

5.3.1 Kubernetes 基础概念 #

Kubernetes 是一个开源的容器编排平台,用于自动化容器化应用的部署、扩展和管理。理解 Kubernetes 的核心概念和架构是进行 Go 开发的基础。

Kubernetes 架构概述 #

集群架构 #

Kubernetes 集群由控制平面(Control Plane)和工作节点(Worker Nodes)组成:

┌─────────────────────────────────────────────────────────┐
│                    Control Plane                        │
├─────────────┬─────────────┬─────────────┬─────────────┤
│   API       │   etcd      │ Scheduler   │ Controller  │
│   Server    │             │             │ Manager     │
└─────────────┴─────────────┴─────────────┴─────────────┘
                            │
        ┌───────────────────┼───────────────────┐
        │                   │                   │
┌───────▼────────┐ ┌────────▼────────┐ ┌────────▼────────┐
│  Worker Node 1  │ │  Worker Node 2  │ │  Worker Node N  │
├─────────────────┤ ├─────────────────┤ ├─────────────────┤
│ kubelet         │ │ kubelet         │ │ kubelet         │
│ kube-proxy      │ │ kube-proxy      │ │ kube-proxy      │
│ Container       │ │ Container       │ │ Container       │
│ Runtime         │ │ Runtime         │ │ Runtime         │
└─────────────────┘ └─────────────────┘ └─────────────────┘

控制平面组件 #

API Server

  • 集群的统一入口点
  • 处理 REST API 请求
  • 验证和配置 API 对象
  • 与 etcd 交互存储数据

etcd

  • 分布式键值存储
  • 存储集群的所有配置数据
  • 提供一致性和高可用性

Scheduler

  • 负责 Pod 调度决策
  • 根据资源需求和约束选择节点
  • 考虑亲和性、反亲和性等规则

Controller Manager

  • 运行各种控制器
  • 监控集群状态并进行调节
  • 包括 Node、Replication、Service 等控制器

工作节点组件 #

kubelet

  • 节点代理程序
  • 管理 Pod 生命周期
  • 与容器运行时交互
  • 向 API Server 报告节点状态

kube-proxy

  • 网络代理组件
  • 维护网络规则
  • 实现 Service 抽象
  • 负载均衡流量分发

Container Runtime

  • 容器运行时环境
  • 支持 Docker、containerd、CRI-O 等
  • 负责镜像管理和容器执行

核心资源对象 #

Pod - 最小部署单元 #

Pod 是 Kubernetes 中最小的可部署单元,包含一个或多个容器:

# pod-example.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
    app: nginx
spec:
  containers:
    - name: nginx
      image: nginx:1.20
      ports:
        - containerPort: 80
      resources:
        requests:
          memory: "64Mi"
          cpu: "250m"
        limits:
          memory: "128Mi"
          cpu: "500m"
      env:
        - name: ENV_VAR
          value: "production"
      volumeMounts:
        - name: config-volume
          mountPath: /etc/nginx/conf.d
  volumes:
    - name: config-volume
      configMap:
        name: nginx-config
  restartPolicy: Always
  nodeSelector:
    disktype: ssd

ReplicaSet - 副本控制 #

ReplicaSet 确保指定数量的 Pod 副本始终运行:

# replicaset-example.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: nginx-replicaset
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.20
          ports:
            - containerPort: 80

Deployment - 声明式更新 #

Deployment 为 Pod 和 ReplicaSet 提供声明式更新:

# deployment-example.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.20
          ports:
            - containerPort: 80
          livenessProbe:
            httpGet:
              path: /
              port: 80
            initialDelaySeconds: 30
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /
              port: 80
            initialDelaySeconds: 5
            periodSeconds: 5

Service - 服务发现 #

Service 为 Pod 提供稳定的网络端点:

# service-example.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: ClusterIP
---
# LoadBalancer 类型的 Service
apiVersion: v1
kind: Service
metadata:
  name: nginx-loadbalancer
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: LoadBalancer

ConfigMap 和 Secret - 配置管理 #

ConfigMap 存储非敏感配置数据:

# configmap-example.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  database_url: "postgresql://localhost:5432/mydb"
  log_level: "info"
  config.yaml: |
    server:
      port: 8080
      host: 0.0.0.0
    database:
      driver: postgres
      host: localhost
      port: 5432

Secret 存储敏感数据:

# secret-example.yaml
apiVersion: v1
kind: Secret
metadata:
  name: app-secret
type: Opaque
data:
  username: YWRtaW4= # base64 encoded 'admin'
  password: MWYyZDFlMmU2N2Rm # base64 encoded password
---
# TLS Secret
apiVersion: v1
kind: Secret
metadata:
  name: tls-secret
type: kubernetes.io/tls
data:
  tls.crt: LS0tLS1CRUdJTi... # base64 encoded certificate
  tls.key: LS0tLS1CRUdJTi... # base64 encoded private key

Ingress - 外部访问 #

Ingress 管理集群外部对服务的访问:

# ingress-example.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
  tls:
    - hosts:
        - myapp.example.com
      secretName: myapp-tls
  rules:
    - host: myapp.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: nginx-service
                port:
                  number: 80
          - path: /api
            pathType: Prefix
            backend:
              service:
                name: api-service
                port:
                  number: 8080

存储管理 #

PersistentVolume 和 PersistentVolumeClaim #

PersistentVolume (PV) 是集群中的存储资源:

# persistent-volume.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-example
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: fast-ssd
  hostPath:
    path: /data/pv-example
---
# 使用 NFS 的 PV
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv
spec:
  capacity:
    storage: 100Gi
  accessModes:
    - ReadWriteMany
  nfs:
    server: nfs-server.example.com
    path: /exported/path

PersistentVolumeClaim (PVC) 是对存储的请求:

# persistent-volume-claim.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-example
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  storageClassName: fast-ssd

StorageClass - 动态存储 #

StorageClass 定义存储的类别和参数:

# storage-class.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast-ssd
provisioner: kubernetes.io/aws-ebs
parameters:
  type: gp2
  fsType: ext4
  encrypted: "true"
reclaimPolicy: Delete
allowVolumeExpansion: true
volumeBindingMode: WaitForFirstConsumer

命名空间与资源管理 #

命名空间 #

命名空间提供资源隔离:

# namespace-example.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: development
  labels:
    environment: dev
    team: backend
---
apiVersion: v1
kind: Namespace
metadata:
  name: production
  labels:
    environment: prod
    team: backend

ResourceQuota - 资源配额 #

限制命名空间中的资源使用:

# resource-quota.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-quota
  namespace: development
spec:
  hard:
    requests.cpu: "4"
    requests.memory: 8Gi
    limits.cpu: "8"
    limits.memory: 16Gi
    persistentvolumeclaims: "10"
    pods: "10"
    services: "5"

LimitRange - 资源限制 #

设置资源的默认值和限制:

# limit-range.yaml
apiVersion: v1
kind: LimitRange
metadata:
  name: limit-range
  namespace: development
spec:
  limits:
    - default:
        memory: "512Mi"
        cpu: "500m"
      defaultRequest:
        memory: "256Mi"
        cpu: "250m"
      max:
        memory: "1Gi"
        cpu: "1"
      min:
        memory: "128Mi"
        cpu: "100m"
      type: Container

网络模型 #

集群网络 #

Kubernetes 网络模型的基本要求:

  • 每个 Pod 都有唯一的 IP 地址
  • Pod 之间可以直接通信,无需 NAT
  • 节点和 Pod 之间可以直接通信
  • Service 提供稳定的网络端点

NetworkPolicy - 网络策略 #

控制 Pod 之间的网络流量:

# network-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all
  namespace: production
spec:
  podSelector: {}
  policyTypes:
    - Ingress
    - Egress
---
# 允许特定流量的策略
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend-to-backend
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: backend
  policyTypes:
    - Ingress
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: frontend
      ports:
        - protocol: TCP
          port: 8080

实际应用示例 #

Go Web 应用部署 #

创建一个完整的 Go Web 应用部署配置:

// main.go
package main

import (
    "encoding/json"
    "fmt"
    "log"
    "net/http"
    "os"
    "time"
)

type HealthResponse struct {
    Status    string    `json:"status"`
    Timestamp time.Time `json:"timestamp"`
    Version   string    `json:"version"`
    Hostname  string    `json:"hostname"`
}

func healthHandler(w http.ResponseWriter, r *http.Request) {
    hostname, _ := os.Hostname()

    response := HealthResponse{
        Status:    "healthy",
        Timestamp: time.Now(),
        Version:   os.Getenv("APP_VERSION"),
        Hostname:  hostname,
    }

    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(response)
}

func readinessHandler(w http.ResponseWriter, r *http.Request) {
    // 检查依赖服务状态
    w.WriteHeader(http.StatusOK)
    fmt.Fprint(w, "ready")
}

func main() {
    http.HandleFunc("/health", healthHandler)
    http.HandleFunc("/ready", readinessHandler)
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Hello from Kubernetes! Pod: %s\n", os.Getenv("HOSTNAME"))
    })

    port := os.Getenv("PORT")
    if port == "" {
        port = "8080"
    }

    log.Printf("Server starting on port %s", port)
    log.Fatal(http.ListenAndServe(":"+port, nil))
}
# Dockerfile
FROM golang:1.19-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o main .

FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/main .
EXPOSE 8080
CMD ["./main"]
# k8s-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: go-web-app
  labels:
    app: go-web-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: go-web-app
  template:
    metadata:
      labels:
        app: go-web-app
    spec:
      containers:
        - name: go-web-app
          image: go-web-app:latest
          ports:
            - containerPort: 8080
          env:
            - name: APP_VERSION
              value: "1.0.0"
            - name: PORT
              value: "8080"
          resources:
            requests:
              memory: "64Mi"
              cpu: "250m"
            limits:
              memory: "128Mi"
              cpu: "500m"
          livenessProbe:
            httpGet:
              path: /health
              port: 8080
            initialDelaySeconds: 30
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /ready
              port: 8080
            initialDelaySeconds: 5
            periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
  name: go-web-app-service
spec:
  selector:
    app: go-web-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
  type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: go-web-app-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
    - host: go-app.local
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: go-web-app-service
                port:
                  number: 80

常用 kubectl 命令 #

基本操作命令 #

# 查看集群信息
kubectl cluster-info
kubectl get nodes
kubectl get namespaces

# 资源操作
kubectl apply -f deployment.yaml
kubectl get pods
kubectl get services
kubectl get deployments

# 查看资源详情
kubectl describe pod <pod-name>
kubectl describe service <service-name>

# 日志查看
kubectl logs <pod-name>
kubectl logs -f <pod-name>  # 实时跟踪
kubectl logs <pod-name> -c <container-name>  # 多容器 Pod

# 进入容器
kubectl exec -it <pod-name> -- /bin/sh
kubectl exec -it <pod-name> -c <container-name> -- /bin/bash

# 端口转发
kubectl port-forward pod/<pod-name> 8080:80
kubectl port-forward service/<service-name> 8080:80

# 资源扩缩容
kubectl scale deployment <deployment-name> --replicas=5

# 滚动更新
kubectl set image deployment/<deployment-name> <container-name>=<new-image>
kubectl rollout status deployment/<deployment-name>
kubectl rollout history deployment/<deployment-name>
kubectl rollout undo deployment/<deployment-name>

调试和故障排除 #

# 查看事件
kubectl get events --sort-by=.metadata.creationTimestamp

# 查看资源使用情况
kubectl top nodes
kubectl top pods

# 调试网络连接
kubectl run debug --image=nicolaka/netshoot -it --rm -- /bin/bash

# 查看资源配置
kubectl get pod <pod-name> -o yaml
kubectl get service <service-name> -o json

# 标签和选择器
kubectl get pods -l app=nginx
kubectl get pods --show-labels
kubectl label pod <pod-name> environment=production

通过掌握这些 Kubernetes 基础概念和操作,您将为后续的 client-go 开发和 Operator 开发奠定坚实的基础。理解这些核心概念对于开发云原生 Go 应用至关重要。