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)有三处必须对上,它们是「网站没响应」最常见的原因:
- Deployment 的
selector.matchLabels= Pod 模板的labels - Service 的
selector= Pod 的labels - 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- L6保持三个 Pod 运行;死了一个,就补一个新的。
- L8Deployment 管理标签为 app: shop 的 Pod……
- L12……它的模板给每个新 Pod 打上这个标签。
- L20GET /health 成功之前不给流量。
- L26申请十分之一个 CPU 核心和 128 MiB 内存。
- L35Service 把流量发给带这个标签的 Pod。
- L38……发到容器监听的端口上。
常见错误
选择器和标签对不上
选择器匹配不到 Pod 的 Service 会接受连接,却无处可发。标签要原样复制,包括拼写。
targetPort 与 port
port 是 Service 监听的端口;targetPort 必须是容器的端口。弄混了就会出现「connection refused」。
没有就绪探针
没有它,Pod 一启动就接到流量,此时应用还没准备好,于是每次部署都会出错。
小测验
1. Service 怎么找到它的 Pod?
查看答案
答案:A
Kubernetes 对象就是靠标签和选择器互相找到的。
2. 容器监听 3000。Service 写了 `port: 80`。`targetPort` 必须是多少?
查看答案
答案:A
targetPort 是 Service 转发到的地方:容器的端口。
动手练习
3 道练习,分三层:先预测程序的输出,再按新需求改程序,最后从零写一个。代码在浏览器里运行,提交马上判题。
- 预测输出流量能到吗?
发给
shopService 的请求能到达 Pod 吗? - 改需求修好坏掉的 Service
webService 拒绝连接,而且只有一个 Pod,所以每次部署都会停机。让 Service 转发到容器真正监听的端口,并运行 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
两个对象之间用一行
---分隔。 - 镜像
本课术语
| 术语 | 中文 | 英文定义 |
|---|---|---|
| Kubernetes | Kubernetes | A system that runs and heals containers across many machines. |
| Pod | Pod | One 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. |