管理工作负载

您已部署应用程序并通过服务公开它。现在该怎么办?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

资源将按照它们在清单中出现的顺序创建。因此,最好先指定服务,因为这将确保调度程序可以在控制器(如 Deployment)创建与服务关联的 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

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

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 输出格式(将每个资源打印为资源/名称)打印创建的资源。然后你只 grep 服务,然后用 kubectl get 打印它。

对本地文件的递归操作

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

例如,假设有一个目录 project/k8s/development 包含所有用于开发环境的 manifests,按资源类型组织

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)

相反,请在 --filename/-f 参数旁边指定 --recursive-R 命令行参数

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 支持几种更新操作,每种操作都适用于不同的场景。

您可以运行应用程序的多个副本,并使用 rollout 将流量逐渐转移到新的健康 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

并在推出期间允许 Kubernetes 添加更多临时副本,方法是将 最大激增 设置为 100%

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

您可以将推出与 DaemonSets、Deployments 或 StatefulSets 一起使用。

管理推出

您可以使用 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 前端版本,它带有不同值的 track 标签(即 canary),这样两组 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 patch、JSON merge patch 和 strategic merge patch。

有关更多详细信息,请参见 使用 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)