管理工作负载

您已经部署了应用程序并通过 Service 公开了它。接下来呢?Kubernetes 提供了许多工具来帮助您管理应用程序部署,包括扩展和更新。

组织资源配置

许多应用程序需要创建多个资源,例如 Deployment 和 Service。通过将它们分组在同一个文件中(在 YAML 中用 --- 分隔),可以简化对多个资源的管理。例如

apiVersion: v1
kind: Service
metadata:
  name: my-nginx-svc
  labels:
    app: nginx
spec:
  type: LoadBalancer
  ports:
  - port: 80
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-nginx
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

可以像创建单个资源一样创建多个资源

kubectl apply -f https://k8s.io/examples/application/nginx-app.yaml
service/my-nginx-svc created
deployment.apps/my-nginx created

资源将按照它们在清单中出现的顺序创建。因此,最好先指定 Service,因为这将确保调度器可以在控制器(例如 Deployment)创建与 Service 关联的 Pod 时分散它们。

kubectl apply 也接受多个 -f 参数

kubectl apply -f https://k8s.io/examples/application/nginx/nginx-svc.yaml \
  -f https://k8s.io/examples/application/nginx/nginx-deployment.yaml

建议将与同一个微服务或应用程序层相关的资源放在同一个文件中,并将与应用程序关联的所有文件分组在同一个目录中。如果应用程序的层使用 DNS 相互绑定,则可以将堆栈的所有组件一起部署。

URL 也可以指定为配置源,这对于直接从源代码管理系统中的清单部署非常方便

kubectl apply -f https://k8s.io/examples/application/nginx/nginx-deployment.yaml
deployment.apps/my-nginx created

如果需要定义更多清单,例如添加 ConfigMap,也可以这样做。

外部工具

本节仅列出用于管理 Kubernetes 上的工作负载的最常用工具。要查看更完整的列表,请查看 CNCF Landscape 中的应用程序定义和镜像构建

Helm

Helm 是一个用于管理预配置 Kubernetes 资源包的工具。这些包称为 *Helm 图表*。

Kustomize

Kustomize 遍历 Kubernetes 清单以添加、删除或更新配置选项。它既可以作为独立的二进制文件使用,也可以作为 kubectl 的原生功能使用。

kubectl 中的批量操作

资源创建并不是 kubectl 可以批量执行的唯一操作。它还可以从配置文件中提取资源名称以执行其他操作,特别是删除您创建的相同资源

kubectl delete -f https://k8s.io/examples/application/nginx-app.yaml
deployment.apps "my-nginx" deleted
service "my-nginx-svc" deleted

对于两个资源,您可以使用 resource/name 语法在命令行上指定这两个资源

kubectl delete deployments/my-nginx services/my-nginx-svc

对于更多资源,您会发现使用 -l--selector 指定选择器(标签查询)更容易,以便按标签过滤资源

kubectl delete deployment,services -l app=nginx
deployment.apps "my-nginx" deleted
service "my-nginx-svc" deleted

链接和过滤

因为 kubectl 以它接受的相同语法输出资源名称,所以您可以使用 $()xargs 链接操作

kubectl get $(kubectl create -f docs/concepts/cluster-administration/nginx/ -o name | grep service/ )
kubectl create -f docs/concepts/cluster-administration/nginx/ -o name | grep service/ | xargs -i kubectl get '{}'

输出可能类似于

NAME           TYPE           CLUSTER-IP   EXTERNAL-IP   PORT(S)      AGE
my-nginx-svc   LoadBalancer   10.0.0.208   <pending>     80/TCP       0s

使用上述命令,首先您在 examples/application/nginx/ 下创建资源,并使用 -o name 输出格式(将每个资源打印为 resource/name)打印创建的资源。然后,您使用 grep 仅获取 Service,然后使用 kubectl get 打印它。

对本地文件的递归操作

如果您碰巧将资源组织在特定目录中的多个子目录中,则可以通过在 --filename/-f 参数旁边指定 --recursive-R 来对子目录递归执行操作。

例如,假设有一个目录 project/k8s/development,其中包含开发环境所需的所有清单,按资源类型组织

project/k8s/development
├── configmap
│   └── my-configmap.yaml
├── deployment
│   └── my-deployment.yaml
└── pvc
    └── my-pvc.yaml

默认情况下,对 project/k8s/development 执行批量操作将在目录的第一级停止,不会处理任何子目录。如果您尝试使用以下命令创建此目录中的资源,我们会遇到错误

kubectl apply -f project/k8s/development
error: you must provide one or more resources by argument or filename (.json|.yaml|.yml|stdin)

而是指定 --recursive-R 命令行参数以及 --filename/-f 参数

kubectl apply -f project/k8s/development --recursive
configmap/my-config created
deployment.apps/my-deployment created
persistentvolumeclaim/my-pvc created

--recursive 参数适用于接受 --filename/-f 参数的任何操作,例如:kubectl createkubectl getkubectl deletekubectl describe,甚至 kubectl rollout

当提供了多个 -f 参数时,--recursive 参数也有效

kubectl apply -f project/k8s/namespaces -f project/k8s/development --recursive
namespace/development created
namespace/staging created
configmap/my-config created
deployment.apps/my-deployment created
persistentvolumeclaim/my-pvc created

如果您有兴趣了解更多关于 kubectl 的信息,请继续阅读命令行工具 (kubectl)

在不停机的情况下更新应用程序

在某些时候,您最终需要更新已部署的应用程序,通常是通过指定新的镜像或镜像标签。 kubectl 支持多种更新操作,每种操作都适用于不同的场景。

您可以运行应用程序的多个副本,并使用 *滚动更新* 将流量逐渐转移到新的健康 Pod。最终,所有正在运行的 Pod 都将拥有新软件。

本页的这一部分将指导您如何使用 Deployment 创建和更新应用程序。

假设您正在运行 nginx 版本 1.14.2

kubectl create deployment my-nginx --image=nginx:1.14.2
deployment.apps/my-nginx created

确保有 1 个副本

kubectl scale --replicas 1 deployments/my-nginx --subresource='scale' --type='merge' -p '{"spec":{"replicas": 1}}'
deployment.apps/my-nginx scaled

并通过将 *最大激增* 设置为 100%,允许 Kubernetes 在滚动更新期间添加更多临时副本

kubectl patch --type='merge' -p '{"spec":{"strategy":{"rollingUpdate":{"maxSurge": "100%" }}}}'
deployment.apps/my-nginx patched

要更新到版本 1.16.1,请使用 kubectl edit.spec.template.spec.containers[0].imagenginx:1.14.2 更改为 nginx:1.16.1

kubectl edit deployment/my-nginx
# Change the manifest to use the newer container image, then save your changes

就是这样!Deployment 将在后台逐步声明式地更新已部署的 nginx 应用程序。它确保在更新过程中只有一定数量的旧副本可能关闭,并且只有一定数量的新副本可以创建超过所需的 Pod 数量。要详细了解这是如何发生的,请访问Deployment

您可以将滚动更新与 DaemonSet、Deployment 或 StatefulSet 一起使用。

管理滚动更新

您可以使用 kubectl rollout 来管理现有应用程序的渐进式更新。

例如

kubectl apply -f my-deployment.yaml

# wait for rollout to finish
kubectl rollout status deployment/my-deployment --timeout 10m # 10 minute timeout

或者

kubectl apply -f backing-stateful-component.yaml

# don't wait for rollout to finish, just check the status
kubectl rollout status statefulsets/backing-stateful-component --watch=false

您还可以暂停、恢复或取消滚动更新。访问 kubectl rollout 了解更多信息。

金丝雀部署

需要多个标签的另一种情况是区分同一组件的不同版本或配置的部署。常见的做法是将新应用程序版本(在 Pod 模板中通过镜像标签指定)的 *金丝雀* 与先前版本并排部署,以便新版本在完全推出之前可以接收实时生产流量。

例如,您可以使用 track 标签来区分不同的版本。

主要的稳定版本将具有值为 stabletrack 标签

name: frontend
replicas: 3
...
labels:
   app: guestbook
   tier: frontend
   track: stable
...
image: gb-frontend:v3

然后,您可以创建 guestbook 前端的新版本,该版本带有不同值(即 canary)的 track 标签,以便两组 Pod 不会重叠

name: frontend-canary
replicas: 1
...
labels:
   app: guestbook
   tier: frontend
   track: canary
...
image: gb-frontend:v4

前端服务将通过选择其标签的公共子集(即省略 track 标签)来跨越两组副本,以便流量将被重定向到两个应用程序

selector:
   app: guestbook
   tier: frontend

您可以调整稳定版本和金丝雀版本的副本数量,以确定将接收实时生产流量的每个版本的比率(在本例中为 3:1)。一旦您确信,您可以将稳定轨道更新到新的应用程序版本并删除金丝雀版本。

更新注解

有时您可能希望将注解附加到资源。注解是任意的非标识元数据,供 API 客户端(例如工具或库)检索。这可以使用 kubectl annotate 完成。例如

kubectl annotate pods my-nginx-v4-9gw19 description='my frontend running nginx'
kubectl get pods my-nginx-v4-9gw19 -o yaml
apiVersion: v1
kind: pod
metadata:
  annotations:
    description: my frontend running nginx
...

有关更多信息,请参阅注解kubectl annotate

扩展应用程序

当应用程序上的负载增加或减少时,请使用 kubectl 扩展您的应用程序。例如,要将 nginx 副本的数量从 3 个减少到 1 个,请执行以下操作

kubectl scale deployment/my-nginx --replicas=1
deployment.apps/my-nginx scaled

现在,您只有一个由 Deployment 管理的 Pod。

kubectl get pods -l app=nginx
NAME                        READY     STATUS    RESTARTS   AGE
my-nginx-2035384211-j5fhi   1/1       Running   0          30m

要让系统根据需要自动选择 nginx 副本的数量(范围从 1 到 3),请执行以下操作

# This requires an existing source of container and Pod metrics
kubectl autoscale deployment/my-nginx --min=1 --max=3
horizontalpodautoscaler.autoscaling/my-nginx autoscaled

现在,您的 nginx 副本将根据需要自动扩展和缩减。

有关更多信息,请参阅kubectl scalekubectl autoscale水平 Pod 自动缩放器文档。

资源的原地更新

有时,需要对您创建的资源进行狭窄的、非破坏性的更新。

kubectl apply

建议在源代码管理中维护一组配置文件(请参阅配置即代码),以便可以与它们配置的资源的代码一起维护和版本控制。然后,您可以使用kubectl apply将您的配置更改推送到集群。

此命令会将您要推送的配置版本与先前版本进行比较,并应用您所做的更改,而不会覆盖对您未指定的属性的任何自动更改。

kubectl apply -f https://k8s.io/examples/application/nginx/nginx-deployment.yaml
deployment.apps/my-nginx configured

要详细了解底层机制,请阅读服务器端应用

kubectl edit

或者,您也可以使用kubectl edit更新资源

kubectl edit deployment/my-nginx

这相当于先get资源,在文本编辑器中编辑,然后使用更新后的版本apply资源

kubectl get deployment my-nginx -o yaml > /tmp/nginx.yaml
vi /tmp/nginx.yaml
# do some edit, and then save the file

kubectl apply -f /tmp/nginx.yaml
deployment.apps/my-nginx configured

rm /tmp/nginx.yaml

这使您可以更轻松地进行更重大的更改。请注意,您可以使用EDITORKUBE_EDITOR环境变量指定编辑器。

有关更多信息,请参阅kubectl edit

kubectl patch

您可以使用kubectl patch就地更新 API 对象。此子命令支持 JSON 补丁、JSON 合并补丁和策略性合并补丁。

有关更多详细信息,请参阅使用 kubectl patch 就地更新 API 对象

破坏性更新

在某些情况下,您可能需要更新初始化后无法更新的资源字段,或者您可能希望立即进行递归更改,例如修复由 Deployment 创建的损坏 Pod。要更改此类字段,请使用replace --force,这将删除并重新创建资源。在这种情况下,您可以修改原始配置文件

kubectl replace -f https://k8s.io/examples/application/nginx/nginx-deployment.yaml --force
deployment.apps/my-nginx deleted
deployment.apps/my-nginx replaced

下一步

此页面上的项目指的是提供 Kubernetes 所需功能的第三方产品或项目。Kubernetes 项目作者不对这些第三方产品或项目负责。有关更多详细信息,请参阅CNCF 网站指南

在提议添加额外第三方链接的更改之前,您应该阅读内容指南

上次修改时间:2024 年 2 月 19 日下午 4:54 PST:修改工作负载管理概念 (5639b8bb45)