管理工作负载
您已部署应用程序并通过 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,因为这将确保调度器可以在创建 Service 关联的 Pod 时将它们分散开来,例如由 Deployment 控制器。
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 景观中。
Helm
Helm 是一种用于管理预配置 Kubernetes 资源的包的工具。这些包被称为 Helm charts。
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
使用上述命令,首先在 docs/concepts/cluster-administration/nginx/ 下创建资源,并使用 -o name 输出格式(以资源/名称的形式打印每个资源)打印创建的资源。然后,我们 grep 仅 Service,然后使用 kubectl get 打印它。
本地文件上的递归操作
如果您碰巧将资源组织在特定目录内的多个子目录中,您还可以通过指定 --recursive 或 -R 以及 --filename/-f 参数,对子目录执行操作。
例如,假设有一个目录 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)
相反,指定 --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 create、kubectl get、kubectl delete、kubectl 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 在 rollout 期间添加更多临时副本,通过设置 100% 的 surge maximum
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].image 从 nginx: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。
您可以使用 rollout 与 DaemonSets、Deployments 或 StatefulSets。
管理 rollout
您可以使用 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
您还可以暂停、恢复或取消 rollout。访问 kubectl rollout 以了解更多信息。
金丝雀部署
需要多个标签的另一个场景是区分相同组件的不同发布版本或配置。部署新应用程序发布的 金丝雀(通过 Pod 模板中的镜像标签指定)与之前的发布版本并排部署,以便在完全推出之前,新的发布版本可以接收实时生产流量,这是一种常见做法。
例如,您可以使用 track 标签来区分不同的发布版本。
主要的、稳定的发布版本将具有 track 标签,其值为 stable
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
...
有关更多信息,请参阅 annotations 和 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=my-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 scale、kubectl 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
这允许你更轻松地进行更重要的更改。请注意,你可以使用 EDITOR 或 KUBE_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
接下来
- 了解如何使用
kubectl进行应用程序内省和调试,请参阅 如何使用kubectl进行应用程序内省和调试。
此页面上的项目引用了提供 Kubernetes 所需功能的第三方产品或项目。Kubernetes 项目作者不对这些第三方产品或项目负责。有关更多详细信息,请参阅 CNCF 网站指南。
在提出添加额外的第三方链接的更改之前,您应该阅读 内容指南。