人人都能学编程
English 开始学习
专项 · DevOps第 5 课 / 共 5 课免费阅读

Kubernetes 基础 · DevOps:容器、CI 与 Kubernetes

怎么让一个应用的很多副本一直运行,并把流量分给它们?

课程目录

为什么需要它

生产环境的应用会在好几台机器上运行好几个副本,这样一次崩溃或一次部署不会让网站挂掉。Kubernetes 是做这件事最常用的系统:你描述想要的状态(这个镜像跑三个副本,通过 80 端口访问),它会一直让现实符合这个描述,按需重启和迁移容器。

直觉理解

Kubernetes 的对象用 YAML 描述。有两种你到处都会遇到:

  • Deployment 让一个容器保持 N 个副本(Pod)在运行。它的 Pod 模板带有标签,比如 app: shop。
  • Service 给这些 Pod 一个稳定的地址,把流量分给它们。它用选择器找到自己的 Pod,选择器必须和 Pod 的标签完全匹配。
客户端 → Service(端口 80)--选择器 app: shop--> 标签为 app: shop 的 Pod(containerPort 8000)

有三处必须对上,它们是「网站没响应」最常见的原因:

  1. Deployment 的 selector.matchLabels = Pod 模板的 labels
  2. Service 的 selector = Pod 的 labels
  3. Service 的 targetPort = 容器的 containerPort

还有两个设置让它可以上生产:readinessProbe 就绪探针(应用通过健康检查之后才发流量)和 resources 资源(每个 Pod 申请多少 CPU 和内存)。

kubectl apply -f app.yaml 把文件发给集群;剩下的交给 Kubernetes。

定义

Pod

The smallest thing Kubernetes runs: one or more containers sharing a network address.
Kubernetes 运行的最小单位:一个或几个共享网络地址的容器。

Deployment

Keeps a set number of identical pods running and replaces them gradually on updates.
让固定数量的相同 Pod 保持运行,更新时逐步替换。

Service

A stable address that load-balances across the pods its selector matches.
一个稳定的地址,在选择器匹配到的 Pod 之间做负载均衡。

标签选择器

key: value pairs an object uses to find other objects with the same labels.
对象用来查找带有相同标签的其他对象的 键: 值 对。

示例

一个 Deployment 和它的 Service

在互动课里运行

商店的三个 Pod,通过 80 端口访问。每个连接都对得上。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: shop
spec:
  replicas: 3
  selector:
    matchLabels:
      app: shop
  template:
    metadata:
      labels:
        app: shop
    spec:
      containers:
        - name: shop
          image: shop:1.4
          ports:
            - containerPort: 8000
          readinessProbe:
            httpGet:
              path: /health
              port: 8000
          resources:
            requests:
              cpu: 100m
              memory: 128Mi
---
apiVersion: v1
kind: Service
metadata:
  name: shop
spec:
  selector:
    app: shop
  ports:
    - port: 80
      targetPort: 8000
逐步执行
  1. L6保持三个 Pod 运行;死了一个,就补一个新的。
  2. L8Deployment 管理标签为 app: shop 的 Pod……
  3. L12……它的模板给每个新 Pod 打上这个标签。
  4. L20GET /health 成功之前不给流量。
  5. L26申请十分之一个 CPU 核心和 128 MiB 内存。
  6. L35Service 把流量发给带这个标签的 Pod。
  7. L38……发到容器监听的端口上。

常见错误

选择器和标签对不上

选择器匹配不到 Pod 的 Service 会接受连接,却无处可发。标签要原样复制,包括拼写。

targetPort 与 port

port 是 Service 监听的端口;targetPort 必须是容器的端口。弄混了就会出现「connection refused」。

没有就绪探针

没有它,Pod 一启动就接到流量,此时应用还没准备好,于是每次部署都会出错。

小测验

1. Service 怎么找到它的 Pod?

  1. A它的选择器匹配 Pod 的标签
  2. B通过 Deployment 的名字
  3. C通过镜像名
查看答案

答案:A

Kubernetes 对象就是靠标签和选择器互相找到的。

2. 容器监听 3000。Service 写了 `port: 80`。`targetPort` 必须是多少?

  1. A3000
  2. B80
  3. C随便;它会被忽略
查看答案

答案:A

targetPort 是 Service 转发到的地方:容器的端口。

动手练习

3 道练习,分三层:先预测程序的输出,再按新需求改程序,最后从零写一个。代码在浏览器里运行,提交马上判题。

  1. 预测输出流量能到吗?

    发给 shop Service 的请求能到达 Pod 吗?

  2. 改需求修好坏掉的 Service

    web Service 拒绝连接,而且只有一个 Pod,所以每次部署都会停机。让 Service 转发到容器真正监听的端口,并运行 3 个副本。

  3. 从零写部署一个 API

    写一个 Deployment 和一个 Service,名字都是 api:

    • 镜像 shop-api:1.4,3 个副本,Pod 标签 app: api,容器监听 8080
    • 就绪探针:对 8080 端口发 HTTP GET /health
    • 资源申请:cpu: 100m,memory: 128Mi
    • Service 选择 app: api,监听 80 端口,转发到 8080

    两个对象之间用一行 --- 分隔。

在互动课里练这一课

打开互动课,这些例子都能直接改、直接运行,练习题提交马上判题。免费开始,不用注册。

互动课按顺序解锁:前面的课还没学,会先带你到课程地图。

本课术语

术语中文英文定义
KubernetesKubernetesA system that runs and heals containers across many machines.
PodPodOne or more containers that Kubernetes runs together.
Service (Kubernetes)Service(Kubernetes)A stable address for a set of pods, found by labels.
Readiness probe就绪探针A health check that decides when a pod gets traffic.