Kubernetes
幼苗
8 个月前
8 个月前
知识图谱

Kubernetes 核心指南


📦 Kubernetes 部署

构建 Pod

尽管 Kubernetes 可以编排和运行容器,但这些容器不得不被包装在一个叫 Pod 的 Kubernetes 结构中。就把 Pod 想象成一个围绕容器的轻量级包装器。事实上,我们有时会互换使用容器和 Pod 这两个术语。现在,你只需要知道 Kubernetes 在 Pod 中运行容器

要部署的 Pod 是在一个叫 pod.yml 的 YAML 文件中定义的:

apiVersion: v1
kind: Pod 
metadata:
  name: first-pod
  labels:
    project: qsk-book 
spec:
  containers:
  - name: web 
    image: nigelpoulton/qsk-book:1.0 
    ports:
    - containerPort: 8080

查询运行的 Pod:

kubectl get pods

部署 Pod:

$ kubectl apply -f pod.yml
pod/first-pod created
 
$ kubectl get pods 
NAME          READY       STATUS    RESTARTS      AGE
first-pod     1/1         Running       0         10s

kubectl 提供了 getdescribe 两个命令来查询对象的配置和状态:

kubectl describe pod first-pod
kubectl get pod first-pod

提示: 尽管 Pod 已经启动,应用正在运行,但你还需要另一个 Kubernetes 对象才能在网络上连接到该应用


连接到 Pod

连接到 Pod 中的应用需要一个独立的对象,称为 Service(服务)。Service 对象的唯一用途是提供到与 Pod 中运行的应用的稳定网络连通性。

svc-cloud.yml 文件定义了一个 Service 对象,以便在你的集群在云中时提供连接:

apiVersion: v1
kind: Service
metadata:
  name: cloud-lb
spec:
  type: LoadBalancer
  ports:
  - port: 80
    targetPort: 8080
  selector:
    project: qsk-book

spec.type: LoadBalancer 字段告诉 Kubernetes 在底层云平台上配置一个面向互联网的负载均衡器。该负载均衡器将在 80 端口接收流量,并转发到任何带有 project: qsk-book 标记的 Pod 的 8080 端口


部署 Service

同样的也是通过 apply 来部署 Service:

$ kubectl apply -f svc-local.yml
service/svc-local created

使用下面的命令来验证该 Service 已经启动和运行:

$ kubectl get svc
NAME      TYPE     CLUSTER-IP    EXTERNAL-IP PORT(S)       AGE
svc-local NodePort 10.108.72.184 <none>      80:31111/TCP  11s
  • CLUSTER-IP 值是内部 Kubernetes Pod 网络上的一个 IP 地址,被集群上运行的其他 Pod 和应用使用。

清理 Kubernetes

清理 Service:

$ kubectl delete svc cloud-lb
service "cloud-lb" deleted

清理 Pod:

$ kubectl delete pod first-pod 
pod "first-pod" deleted

🔄 自我修复

📚 官方文档:Deployment

有另一个称为 Deployment 的专用对象,用于提供自我修复(self-healing)。事实上,Deployment 也可以实现扩缩容和滚动更新。Deployment 用于管理运行一个应用负载的一组 Pod,通常适用于不保持状态的负载。

image

核心组成

  1. 容器提供操作系统和其他应用依赖。
  2. Pod 提供元数据和其他结构,以便容器在 Kubernetes 上运行。
  3. Deployment 提供云原生功能,包括自我修复。

Deployment 工作机制

有两个元素对 Deployment 的工作很重要:

  1. Deployment 对象:是定义 Pod 和容器的 YAML 配置。它还定义了要部署多少个 Pod 副本等事项。
  2. Deployment 控制器:是一个运行在控制面板上的进程,它始终在监控集群,确保所有的 Deployment 对象都按规定运行。

假设你在 Kubernetes 的 Deployment 清单中定义了一个应用。它定义了名为 zephyr-one 的 Pod 的 5 个副本。你使用 kubectl 将其发送给 Kubernetes,Kubernetes 将 5 个 Pod 调度到集群上。在这一点上,观察到的状态(observed state)期望状态(desired state) 一致。这是专业的说法,说的是集群正在运行你要求它运行的内容。

但是,假设一个节点发生故障了,名为 zephyr-one 的 Pod 数量下降到 4 个。观察到的状态不再与期望状态相匹配,此时就出现了问题。但不要紧张,Deployment 控制器监视着集群,并将看到这一变化。它知道你想要 5 个 Pod,但它只能观察到 4 个。因此,它将启动第 5 个 Pod,使观察到的状态重新与期望状态保持一致,这个过程对应的技术术语是和解(reconciliation),但我们经常称其为自我修复


Deployment 配置示例

kind: Deployment         # <<== 被定义的对象的类型
apiVersion: apps/v1      # <<== 要部署的对象的版本
metadata:
  name: qsk-deploy            
spec:
  replicas: 5            # <<== 要部署多少个 Pod 副本
  selector:
    matchLabels:         # <<== 告诉 Deployment 控制器
      project: qsk-book  # <<== 管理哪些 Pod
  template:
    metadata:
      labels:
        project: qsk-book # <<== Pod 标签
    spec:   
      containers:
      - name: qsk-pod
        imagePullPolicy: Always  # <<== 永远不使用本地镜像
        ports:
        - containerPort: 8080             # <<== 网络端口
        image: nigelpoulton/qsk-book:1.0  # <<== 要使用的镜像

查询 Deployments:

kubectl get deployments

部署 Deployments:

$ kubectl apply -f deploy.yml
deployment.apps/qsk-deploy created

Pod 和它们运行的应用有可能崩溃或发生故障。Kubernetes 可以通过启动一个新的 Pod 来替代失败的 Pod,从而尝试自我修复这样的情况。


📊 应用扩缩容

应用扩容

扩缩容的单位是 Pod,因此扩容将增加 Pod 副本,而缩容将删除 Pod 副本。

手动编辑 Deployment YAML 文件,将副本的数量增加到 10 个,并重新将其发送给 Kubernetes。

检查当前的副本数量:

$ kubectl get deployment qsk-deploy
NAME          READY   UP-TO-DATE   AVAILABLE   AGE
qsk-deploy    5/5     5            5           16h

编辑 deploy.yml 文件,将 spec.replicas 字段设置为 10,并保存修改:

apiVersion: apps/v1
kind: Deployment 
metadata:
  name: qsk-deploy 
spec:
  replicas: 5           # <<== 将这里改成 10
  selector: 
    matchLabels: 
      project: qsk-book 
<Snip>

使用 kubectl 将更新的文件重新发送给 Kubernetes。当 Kubernetes 收到该文件时,它将把期望状态从 5 个副本改为 10 个。Deployment 控制器将观察集群上的 5 个副本,并注意到它不符合新的期望状态。它将调度 5 个新副本,使观察到的状态与期望状态一致。


应用缩容

应用缩容在本节中,你将使用 kubectl scale 命令将 Pod 的数量缩减回 5 个。这种方法被称为命令式方法,不像声明式方法那样常见。

$ kubectl scale --replicas 5 deployment/qsk-deploy
deployment.apps/qsk-deploy scaled

注意:用 kubectl scale 命令式地完成扩缩容操作会很危险。


🔁 滚动更新

即使 Kubernetes 以有条不紊的方式每次更新 1 个副本,直到 5 个副本都运行新版本。

更新配置文件

更新 deploy.yml 文件:

1 apiVersion: apps/v1
2 kind: Deployment 
3 metadata:
4   name: qsk-deploy 
5 spec:
6   replicas: 5 
7   selector:
8     matchLabels:
9       project: qsk-book 
10  minReadySeconds: 20            # <<== 添加这一行
11  strategy:                      # <<== 添加这一行
12    type: RollingUpdate          # <<== 添加这一行
13    rollingUpdate:               # <<== 添加这一行
14      maxSurge: 1                # <<== 添加这一行
15      maxUnavailable: 0          # <<== 添加这一行
16  template:
17    metadata:
18      labels:
19        project: qsk-book 
20    spec:
21      containers:
22      - name: hello-pod 
23        imagePullPolicy: Always 
24        ports:
25        - containerPort: 8080 
26        image: nigelpoulton/qsk-book:1.1 # <<== 设置为 1.1

配置参数说明

  • minReadySeconds: 20:告诉 Kubernetes 在更新每个副本后要等待 20 秒

提示: Kubernetes 实际上没有更新副本,它所做的是删除现有的副本,并用一个运行新版本的全新副本来代替它们

  • 更新类型为 RollingUpdate:以滚动更新的方式执行对此 Deployment 的所有更新
  • 14 行和第 15 行强制 Kubernetes 一次更新一个 Pod,运行机制是:
    • 第 14 行中 maxSurge=1 允许 Kubernetes 在更新操作中增加一个额外的 Pod,期望状态需要 5 个 Pod,所以 Kubernetes 可以在更新期间将其增加到 6 个
    • 第 15 行中 maxUnavailable=0 防止 Kubernetes 在更新期间减少 Pod 的数量,期望状态还是需要 5 个 Pod,所以 Kubernetes 不允许比这更少
    • 结合起来,第 14 行和第 15 行迫使 Kubernetes 删除运行旧版本的副本的同时增加运行新版本的第六个副本。这个过程一直重复,直到 5 个副本全都在运行需要的版本。

监听滚动更新过程

当更新完毕 deploy.yml 后可以使用 apply 命令进行部署,然后使用如下命令进行监听:

$ kubectl rollout status deployment qsk-deploy
Waiting for rollout to finish: 1 out of 5 have been updated...
Waiting for rollout to finish: 1 out of 5 have been updated...
Waiting for rollout to finish: 2 out of 5 have been updated...
Waiting for rollout to finish: 2 out of 5 have been updated...
Waiting for rollout to finish: 3 out of 5 have been updated...
Waiting for rollout to finish: 3 out of 5 have been updated...
Waiting for rollout to finish: 4 out of 5 have been updated...
Waiting for rollout to finish: 4 out of 5 have been updated...
Waiting for rollout to finish: 2 old replicas are pending termination...
Waiting for rollout to finish: 1 old replicas are pending termination...
deployment "qsk-deploy" successfully rolled out
评论