Kubernetes 入门:开发者的第一课

项目迁移到 K8s,被迫学习。记录入门经验。

为什么需要 K8s

Docker 解决了”我的机器上能跑”的问题,但:

  • 容器挂了怎么办?
  • 怎么扩展多个副本?
  • 怎么做滚动更新?
  • 怎么管理配置和密钥?

K8s 解决这些运维问题。

核心概念

概念说明
Pod最小部署单元,一个或多个容器
Deployment管理 Pod 副本数、更新策略
Service提供稳定的访问入口
ConfigMap配置管理
Secret敏感信息管理
IngressHTTP 路由入口

部署一个应用

1. 编写 Deployment

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 3  # 副本数
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: my-app
          image: my-app:v1.0.0
          ports:
            - containerPort: 3000
          resources:
            requests:
              memory: "128Mi"
              cpu: "100m"
            limits:
              memory: "256Mi"
              cpu: "500m"
          env:
            - name: NODE_ENV
              value: "production"

2. 创建 Service

# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: my-app-service
spec:
  selector:
    app: my-app
  ports:
    - port: 80
      targetPort: 3000
  type: ClusterIP

3. 创建 Ingress

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

4. 部署

kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
kubectl apply -f ingress.yaml

K8s 架构

常用命令

命令用途
kubectl get pods查看 Pod
kubectl get deployments查看 Deployment
kubectl logs <pod>查看日志
kubectl describe pod <pod>查看详情
kubectl exec -it <pod> -- sh进入容器
kubectl apply -f <file>应用配置
kubectl delete -f <file>删除资源
kubectl scale deployment my-app --replicas=5扩缩容

配置管理

ConfigMap

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  database_url: "postgres://db:5432/mydb"
  redis_url: "redis://redis:6379"

使用:

envFrom:
  - configMapRef:
      name: app-config

Secret

apiVersion: v1
kind: Secret
metadata:
  name: app-secret
type: Opaque
data:
  database_password: cGFzc3dvcmQxMjM=  # base64 编码

健康检查

livenessProbe:
  httpGet:
    path: /health
    port: 3000
  initialDelaySeconds: 10
  periodSeconds: 10

readinessProbe:
  httpGet:
    path: /ready
    port: 3000
  initialDelaySeconds: 5
  periodSeconds: 5
  • liveness:容器是否存活,失败会重启
  • readiness:容器是否就绪,失败会从 Service 移除

滚动更新

spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1        # 最多多 1 个 Pod
      maxUnavailable: 0  # 最少保持全部可用

更新镜像:

kubectl set image deployment/my-app my-app=my-app:v2.0.0

K8s 会逐步用新 Pod 替换旧 Pod。

资源限制

设置说明
requests调度时的最小保证
limits运行时的最大限制
resources:
  requests:
    memory: "128Mi"
    cpu: "100m"
  limits:
    memory: "256Mi"
    cpu: "500m"

100m 表示 0.1 核 CPU。

本地开发

Minikube

# 安装
brew install minikube

# 启动
minikube start

# 使用本地镜像
eval $(minikube docker-env)

kubectl 上下文

# 查看上下文
kubectl config get-contexts

# 切换上下文
kubectl config use-context minikube

本地开发环境

调试技巧

查看 Pod 状态

kubectl get pods -w  # 实时监控

状态说明:

状态说明
Pending等待调度
Running运行中
Succeeded成功完成
Failed失败
CrashLoopBackOff崩溃循环
ImagePullBackOff镜像拉取失败

查看事件

kubectl get events --sort-by='.lastTimestamp'

查看资源使用

kubectl top pods
kubectl top nodes

常见问题

Pod 启动失败

  1. 检查镜像是否存在
  2. 检查资源是否足够
  3. 检查配置是否正确
  4. 查看事件和日志

服务无法访问

  1. 检查 Service selector 和 Pod label
  2. 检查端口配置
  3. 检查 Ingress 配置

内存不足

  1. 调整 limits
  2. 优化应用内存使用
  3. 检查内存泄漏

开发者需要掌握的程度

级别内容
必须会写 Deployment、Service、查看日志
应该会ConfigMap、Secret、健康检查
了解即可网络策略、PV/PVC、Operator

总结

K8s 很复杂,但开发者不需要全懂。

掌握基本概念和常用命令,能排查常见问题就够了。深入的运维知识交给专业的人。

推荐资源:

  • Kubernetes 官方文档
  • Kubernetes in Action(书)
  • Play with Kubernetes(在线练习)