Kubernetes入门:从概念到第一个集群部署

为什么需要 Kubernetes

Docker 解决了“单机容器化”的问题,但生产环境要面对的是:几十上百个容器跨多台机器运行、某台机器宕机要自动迁移、流量要负载均衡、版本要滚动更新与回滚、配置和密钥要集中管理。手动维护这些几乎不可能,这就是容器编排系统存在的意义。Kubernetes(K8s)在激烈的竞争中胜出,成为云原生时代的事实标准。

本文用最小认知负担带你入门:先理清核心概念,再动手部署第一个应用。

核心概念:一张图理清关系

理解 K8s,先记住这条数据流:Pod 跑容器,Deployment 管 Pod,Service 暴露 Pod,Ingress 把外部流量接入 Service

  • Pod:K8s 最小调度单位,一个或多个紧密协作的容器共享网络和存储。通常一 Pod 一容器。

  • Deployment:声明“我要几个什么样的 Pod”,负责副本数、滚动更新、回滚。它是无状态应用的标配。

  • Service:为一组 Pod 提供稳定的访问入口和负载均衡。Pod 的 IP 会变,Service 提供固定 DNS 名和虚拟 IP。

  • Ingress:七层路由,把 HTTP/HTTPS 流量按域名/路径转发到不同 Service。

  • ConfigMap / Secret:管理配置和敏感信息,与镜像解耦。

  • Namespace:逻辑隔离,把集群划分成多个虚拟集群。
  • Pod 与 Deployment

    先看一个最简单的 Deployment,运行 3 个 Nginx 副本:

    yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deploy
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
            - name: nginx
              image: nginx:1.27-alpine
              ports:
                - containerPort: 80
              resources:
                requests:
                  cpu: 50m
                  memory: 64Mi
                limits:
                  cpu: 200m
                  memory: 128Mi

    关键字段解读:

  • replicas: 3:期望运行 3 个 Pod。

  • selector.matchLabels + template.labels:Deployment 通过标签找到它管理的 Pod,两者必须匹配。

  • resources:声明资源请求与上限,是调度和稳定性的基础。不设资源限制的容器是集群不稳定的头号元凶
  • bash
    kubectl apply -f deployment.yaml
    kubectl get pods -l app=nginx
    kubectl rollout status deployment/nginx-deploy

    Service:给 Pod 一个稳定入口

    Pod 重启后 IP 会变,不能直接给前端用。Service 通过标签选择器动态关联一组 Pod,提供稳定 DNS 名:

    yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-svc
    spec:
      selector:
        app: nginx
      ports:
        - port: 80
          targetPort: 80
      type: ClusterIP

  • ClusterIP(默认):集群内可达,外部不可达。

  • NodePort:在每个节点开一个端口,可从外部访问,适合调试。

  • LoadBalancer:云厂商提供外部负载均衡器,生产常用。
  • 集群内其他服务可以通过 nginx-svc.default.svc.cluster.local 这个 DNS 名访问。

    Ingress:统一外部入口

    LoadBalancer 类型的 Service 每个都占一个云负载均衡器,成本高。Ingress 用一个入口按域名/路径路由到多个 Service:

    yaml
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: web-ingress
      annotations:
        nginx.ingress.kubernetes.io/rewrite-target: /
    spec:
      ingressClassName: nginx
      rules:
        - host: app.example.com
          http:
            paths:
              - path: /
                pathType: Prefix
                backend:
                  service:
                    name: nginx-svc
                    port:
                      number: 80
              - path: /api
                pathType: Prefix
                backend:
                  service:
                    name: api-svc
                    port:
                      number: 8080

    Ingress 需要安装 Ingress Controller(如 ingress-nginx)才能生效,它是真正处理流量的组件。

    配置与密钥分离

    把配置从镜像里剥离出来,是 12-Factor App 的核心实践。

    yaml
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: app-config
    data:
      LOG_LEVEL: "info"
      DB_HOST: "db.internal"
    ---
    apiVersion: v1
    kind: Secret
    metadata:
      name: app-secret
    type: Opaque
    stringData:
      DB_PASSWORD: "super-secret"

    在 Deployment 中注入:

    yaml
    spec:
      containers:
        - name: app
          image: myapp:1.0
          envFrom:
            - configMapRef:
                name: app-config
            - secretRef:
                name: app-secret

    Secret 只是 base64 编码,并非加密,生产环境应配合云厂商的 KMS 或外部密钥管理(如 External Secrets Operator)。

    健康检查:让 K8s 自动恢复故障

    yaml
    spec:
      containers:
        - name: app
          image: myapp:1.0
          livenessProbe:
            httpGet:
              path: /health
              port: 8080
            initialDelaySeconds: 10
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /ready
              port: 8080
            initialDelaySeconds: 5
            periodSeconds: 5

  • livenessProbe:失败则重启容器,恢复“卡死”进程。

  • readinessProbe:失败则从 Service 端点摘除,不再接收流量,但不会重启。这保证了滚动更新时不把流量打到还没就绪的新 Pod。
  • 滚动更新与回滚

    Deployment 默认滚动更新:逐步创建新 Pod、逐步删除旧 Pod,全程服务不中断。

    bash
    # 更新镜像版本
    kubectl set image deployment/nginx-deploy nginx=nginx:1.28-alpine
    
    # 查看发布历史
    kubectl rollout history deployment/nginx-deploy
    
    # 回滚到上一版本
    kubectl rollout undo deployment/nginx-deploy
    
    # 回滚到指定版本
    kubectl rollout undo deployment/nginx-deploy --to-revision=2

    配合 readinessProbe 和合理的 maxUnavailable / maxSurge,可以实现零停机发布。

    本地练手:用 kind 起一个集群

    无需云账号,本地就能练:

    bash
    # 安装 kind(Kubernetes in Docker)
    kind create cluster --name demo
    
    kubectl get nodes
    # 部署前面的 yaml
    kubectl apply -f deployment.yaml
    kubectl apply -f service.yaml
    
    # 端口转发,本地访问
    kubectl port-forward svc/nginx-svc 8080:80
    # 浏览器打开 http://localhost:8080

    小结

    K8s 的学习曲线确实陡,但核心模型并不复杂:Pod 是运行单元,Deployment 管理副本与更新,Service 提供稳定网络,Ingress 统一入口,ConfigMap/Secret 管配置。从这五个对象入手,先在本地用 kind 跑通一个完整应用,再逐步接触 StatefulSet、HPA、PV/PVC 等进阶概念。别一上来就背全部 API,动手部署一次远比读十遍文档有效。当你能熟练地声明式管理应用并做滚动更新与回滚时,你就真正迈进了云原生的大门。

    💬 评论区 (0)

    暂无评论,快来抢沙发吧!