Lesson 0014:Kubernetes 核心——Pod、Deployment、Service

← Lesson 0013 讲了网络和负载均衡。Kubernetes 把容器编排、负载均衡、服务发现、自愈全部内置了——这就是为什么它是云原生的操作系统。

K8s 解决什么问题?

你手动管 Docker:docker rundocker stop、配端口、设重启策略。管 3 个容器还行。管 50 个呢?跨 5 台机器呢?

Kubernetes = 容器操作系统。你声明「我要 3 个 nginx 副本,CPU 不超过 500m,挂了自动重启」,K8s 自己去调度、监控、修复。

架构:Master + Node

Control Plane (Master)               Worker Nodes
┌──────────────────────┐       ┌──────────────────┐
│ API Server           │       │ kubelet          │
│ Scheduler            │       │ container runtime│
│ Controller Manager   │       │ kube-proxy       │
│ etcd (数据库)        │       │    Pod  Pod  Pod  │
└──────────────────────┘       └──────────────────┘

你只跟 API Server 打交道(通过 kubectl)。Scheduler 决定 Pod 放哪个 Node。Controller Manager 持续对比「实际状态」和「期望状态」。

核心对象一:Pod——最小调度单元

Pod 是 K8s 的最小单元,包含一个或多个共享网络和存储的容器。

# pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-app
  labels:
    app: web              # 标签——Service 靠这个找 Pod
spec:
  containers:
    - name: app
      image: nginx:alpine
      ports:
        - containerPort: 80
kubectl apply -f pod.yaml       # 创建
kubectl get pods                 # 列出
kubectl describe pod my-app      # 详细信息(排错用)
kubectl logs my-app              # 看日志
kubectl exec -it my-app -- sh    # 进去
kubectl delete pod my-app        # 删除
一般不直接创建 Pod。 Pod 是临时性的——挂了就没了。用 Deployment 管理 Pod 的生命周期。

核心对象二:Deployment——管理 Pod 的控制器

Deployment 声明「我要 N 个一模一样的 Pod」,K8s 保证实际数量 = 期望数量。

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-deploy
spec:
  replicas: 3                       # 3 个副本
  selector:
    matchLabels:
      app: web
  template:                          # Pod 模板
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: nginx
          image: nginx:alpine
          ports:
            - containerPort: 80
kubectl apply -f deployment.yaml
kubectl get deployments
kubectl get pods                    # 看到 3 个 Pod

# 滚动更新
kubectl set image deployment/web-deploy nginx=nginx:1.25
kubectl rollout status deployment/web-deploy

# 回滚
kubectl rollout undo deployment/web-deploy

# 扩缩容
kubectl scale deployment/web-deploy --replicas=5

核心对象三:Service——稳定的网络入口

Pod 的 IP 是临时的(Pod 重建 IP 就变了)。Service 提供固定的 Cluster IP + DNS 名,自动负载均衡到健康的 Pod。

# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: web-svc
spec:
  selector:
    app: web                  # 选中带 app=web 标签的 Pod
  ports:
    - port: 80                # Service 的端口
      targetPort: 80          # Pod 的端口
  type: ClusterIP             # 仅集群内部可访问(默认)
Service Type效果什么时候用
ClusterIP集群内部访问服务间通信(默认)
NodePort每个 Node 开一个端口(30000-32767)调试 / 简单暴露
LoadBalancer云服务商创建外部 LB生产对外暴露

核心对象四:Namespace——虚拟集群

kubectl get namespaces
kubectl create namespace staging
kubectl apply -f deployment.yaml -n staging
# 不同 namespace 的资源互相隔离,同名不冲突

本地运行 K8s

# 装 minikube(推荐)或 kind
# minikube:
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
minikube start

# kind (Kubernetes in Docker):
# 你已经有 Docker,kind 更快
# curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.20.0/kind-linux-amd64
# chmod +x ./kind && sudo mv ./kind /usr/local/bin/kind
# kind create cluster

# 验证
kubectl cluster-info
kubectl get nodes

动手练习

如果你有 minikube/kind,跑这个:

# 创建 Deployment + Service
kubectl create deployment nginx --image=nginx:alpine --replicas=3 --port=80
kubectl expose deployment nginx --type=NodePort --port=80

# 查看
kubectl get all
# NAME                         READY   STATUS    RESTARTS   AGE
# pod/nginx-xxx-xxx            1/1     Running   0          10s
# pod/nginx-xxx-yyy            1/1     Running   0          10s
# pod/nginx-xxx-zzz            1/1     Running   0          10s
# service/nginx   TYPE:NodePort   PORT(S):80:3xxxx/TCP

# 访问
minikube service nginx --url     # minikube
# 或 kubectl port-forward svc/nginx 8080:80  # 通用方式
curl http://localhost:8080

小测验

Q1:Pod 和 Deployment 的关系是?
Q2:Service 为什么需要?Pod 不是有 IP 吗?
Q3:滚动更新时如果新版本 Pod 启动失败,K8s 怎么做?

下一步

Lesson 0015:K8s 网络与配置 →——Ingress、ConfigMap、Secret、Volume、PVC。

← Lesson 0013 · Lesson 0015 →