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 应用至关重要。