13 个鲜为人知的 Kubernetes 隐藏技巧

DavidW (skyDragon) 2024-06-12 10:53:33
Kubernetes 作为一个功能丰富的平台,它拥有一个强大的生态系统,这使得它在提升容器化应用的管理效率、扩展性以及安全性方面表现出色。以下将分享13条实用技巧,每一条都包含了详细概念、应用实例、适用场景以及执行时需考虑的要点。

 

1.使用 PreStop Hooks 优雅地关闭 Pod

 

要点说明:PreStop Hooks是一种 Kubernetes 特性,它允许在 Pod 被标记为终止时,自动运行特定的命令或脚本来执行一些必要的操作。这一特性对于应用程序的平稳关闭至关重要,它允许应用在关闭前保存其状态,执行清理操作以防止数据损坏,并确保应用能够顺利重启。

 

应用示例:

 

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
apiVersion: v1kind: Podmetadata:  name: graceful-shutdown-examplespec:  containers:  - name: sample-container    image: nginx    lifecycle:      preStop:        exec:          command: ["/bin/sh", "-c", "sleep 30 && nginx -s quit"]

 

通过配置,可以为 nginx 服务器设定一个 30 秒的缓冲期,以便在关闭之前完成当前的请求处理。

 

适用场景:PreStop Hooks 特别适用于那些对服务连续性有严格要求的环境中,比如在执行部署、扩展操作或 Pod 重启时,以实现最小化的停机时间。

 

注意事项:需要注意的是,Kubernetes 提供了一个终止优雅期给 Pod,但如果 PreStop Hooks中定义的脚本执行时间超出了这个期限,Kubernetes 将不会等待脚本完成,而是会强制终止 Pod,这可能会引发你本想避免的问题。

 

2. 使用 Kubelet 实现自动密钥轮换

 

要点说明:Kubernetes 提供了一个自动化的功能,允许在不重启使用这些密钥的 Pods 的情况下,自动更新密钥。此特性对于维护高安全标准至关重要,它通过定期更新敏感信息,如数据库密码、API 密钥或 TLS 证书,而不影响应用程序的正常运行。

 

应用示例:假设你在 Kubernetes 中更新了一个密钥。Kubernetes 将在不需要任何干预的情况下更新 Pod 中挂载的密钥,确保应用程序始终具有最新的凭据,而无需手动更新或重新启动。

 

适用场景:对于安全合规性要求高的应用程序,如金融、医疗或政府服务等,该特性对于实现密钥的定期轮换至关重要。

 

注意事项:应用程序设计应支持动态读取更新的密钥。对于那些在启动时将密钥缓存起来的应用程序,它们可能无法识别新的密钥变更,除非被重新启动。因此,确保应用程序能够定期检测密钥的更改,或者能够对密钥的更新做出适当的响应。

 

3. 使用临时容器调试 Pods

 

要点说明:临时容器提供了一种方法,允许您在不改变原始规范的情况下,临时将调试容器附加到正在运行的 pod 上。这对于在生产环境中调试实时问题非常有用,尤其是在您不能承受服务中断的情况下。

 

应用示例:

 

  •  
kubectl alpha debug -it podname --image=busybox --target=containername

这个命令向您现有的 pod 添加了一个 busybox 容器,允许您执行命令并检查 pod 的环境,而不会改变其运行状态。 

 

适用场景:当在实时环境中诊断问题时,尤其是在标准日志和指标不能提供足够信息时,使用临时容器——它是实时、深入分析生产问题的强大工具。 

 

注意事项:由于临时容器可以访问 pod 的资源和敏感数据,因此要谨慎使用它们,尤其是在生产环境中。确保只有授权人员可以部署临时容器,以避免潜在的安全风险。

 

4. 基于自定义指标的

水平 Pod 自动伸缩

 

要点说明:水平 Pod 自动伸缩器(HPA)可以基于自定义指标来扩展您的部署,而不仅仅是标准的 CPU 和内存使用情况。这对于具有特定业务指标或性能指标(如队列长度、请求延迟或自定义应用程序指标)的扩展需求的应用程序特别有用。

 

使用示例:

 

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
apiVersion: autoscaling/v2beta2kind: HorizontalPodAutoscalermetadata:  name: custom-metric-hpaspec:  scaleTargetRef:    apiVersion: apps/v1    kind: Deployment    name: your-application  minReplicas: 1  maxReplicas: 10  metrics:  - type: Pods    pods:      metric:        name: your_custom_metric      target:        type: AverageValue        averageValue: 10

 

这个 HPA 配置基于自定义指标 your_custom_metric 的平均值来扩展您的应用程序。

 

适用场景:对于传统基于资源的指标不能准确代表负载或需要基于业务需求进行微调扩展行为的应用程序,使用自定义指标扩展。

 

注意事项:置自定义指标涉及与支持自定义指标的指标服务器(如 Prometheus)集成。确保您的指标是负载的可靠指标,以防止过度或不足的扩展。

 

5. 使用初始化容器进行设置脚本

 

要点说明:初始化容器在 Pod 中的应用容器之前运行,非常适合需要在应用程序启动之前完成的设置脚本。这可能包括数据库迁移、配置文件创建或等待外部服务可用等任务。初始化容器可以运行一系列设置任务,确保每个步骤在主应用程序容器启动之前都成功完成。

 

使用示例:

 

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
apiVersion: v1kind: Podmetadata:  name: myapp-podspec:  containers:  - name: myapp-container    image: myapp  initContainers:  - name: init-myservice    image: busybox    command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;']

 

此示例使用初始化容器,等待名为myservice的服务可用后,再启动主应用程序容器。

 

适用场景:当您的应用程序容器依赖于外部服务或配置在它们启动前可用时,初始化容器非常珍贵,它们保证您的应用程序在环境准备就绪的情况下启动。

 

注意事项:所有初始化容器成功完成后,才会阻塞整个 pod 的启动。确保初始化容器高效运行,并且能够优雅地处理失败,以防止它们成为瓶颈或导致 pod 启动失败。

 

6.针对工作负载特定调度的节点亲和性

 

要点说明:节点亲和性允许您根据节点上的标签指定规则,限制您的 pod 可以调度到哪些节点。这对于将工作负载导向具有特定硬件(如 GPU)的节点、确保数据本地性或遵守合规和数据主权要求非常有用。

 

使用示例:

 

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
apiVersion: v1kind: Podmetadata:  name: with-node-affinityspec:  containers:  - name: with-node-affinity    image: nginx  affinity:    nodeAffinity:      requiredDuringSchedulingIgnoredDuringExecution:        nodeSelectorTerms:        - matchExpressions:          - key: disktype            operator: In            values:            - ssd

 

此 pod 将仅调度到带有标签 disktype=ssd 的节点上。

 

适用场景:当您的应用程序需要特定节点能力,或当您需要出于性能优化、法律或监管原因控制工作负载的分布时,就可以使用节点亲和性。

 

注意事项:过度使用节点亲和性可能导致集群利用率低下和调度复杂性。为了维持高效的资源利用率,您需要保证集群中的标签和亲和性分布是均衡的。

 

7. 用于 Pod 隔离的污点和容忍度

 

要点说明:污点和容忍度共同确保 pod 不被调度到不适当的节点上。节点上的污点排斥不容忍该污点的 pod。容忍度应用于 pod,允许它们调度到带有污点的节点。这种机制对于将节点专用于特定工作负载(如 GPU 密集型应用程序)或确保只有特定 pod 在包含敏感数据的节点上运行至关重要。

 

使用示例:

 

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
# 对节点应用污点kubectl taint nodes node1 key=value:NoSchedule

# 具有容忍度的 Pod 规范apiVersion: v1kind: Podmetadata:  name: mypodspec:  containers:  - name: mypod    image: nginx  tolerations:  - key: "key"    operator: "Equal"    value: "value"    effect: "NoSchedule"

 

此设置确保 mypod 可以调度到带有其他 pod 无法容忍的特定污点的 node1。

 

适用场景:在多租户集群中,污点和容忍度的作用很大,其中隔离工作负载对安全或性能至关重要。除此之外,它们也适用于运行需要专用资源的专业化工作负载。

 

注意事项:配置不当的污点和容忍度可能导致调度问题,pod 可能无法按预期调度,或某些节点被低估。定期审查您的污点和容忍度设置,以确保它符合您的调度要求。

 

 

8.用于关键工作负载的

Pod 优先级和抢占

 

要点说明:Kubernetes 允许您为 pod 分配优先级,必要时高优先级 pod 可以抢占(驱逐)低优先级 pod。这确保了关键工作负载即使在高度拥堵的集群中也有所需的资源。

 

使用示例:

 

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
# PriorityClass definitionapiVersion: scheduling.k8s.io/v1kind: PriorityClassmetadata:  name: high-priorityvalue: 1000000globalDefault: falsedescription: "This priority class should be used for XYZ service pods only."
# Pod specification with priorityClassNameapiVersion: v1kind: Podmetadata:  name: high-priority-podspec:  containers:  - name: high-priority    image: nginx  priorityClassName: high-priority

 

此配置定义了一个高优先级类并将其分配给一个 pod,确保它可以抢占其他低优先级的 pod。
 

适用场景:对于对您的业务运营至关重要的应用程序,请使用 pod 优先级和抢占,特别是在资源争用常见的集群中运行时。

 

注意事项:不当使用可能导致不太关键的应用程序资源匮乏。平衡不同工作负载的需求,并考虑对集群健康和应用程序性能的整体影响至关重要。

 

9. 用于动态配置的 ConfigMaps 和 Secrets

 

要点说明:ConfigMaps 和 Secrets 提供了将配置数据注入到 pod 中的机制。这允许配置的外部化,使应用程序更容易配置,而无需硬编码配置数据。ConfigMaps 适用于非敏感数据,而 Secrets 用于敏感数据。

 

使用示例:

 

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
# ConfigMap ExampleapiVersion: v1kind: ConfigMapmetadata:  name: app-configdata:  config.json: |    {      "key": "value",      "databaseURL": "http://mydatabase.example.com"    }# Pod Spec using ConfigMapapiVersion: v1kind: Podmetadata:  name: myapp-podspec:  containers:    - name: myapp-container      image: myapp      volumeMounts:      - name: config-volume        mountPath: /etc/config  volumes:    - name: config-volume      configMap:        name: app-config

 

此配置将 app-config 的内容注入到 pod 中,允许应用程序从 /etc/config/config.json 读取其配置。

 

适用场景:每当您需要外部化应用程序的配置或秘密数据时,使其更易于管理、更新和维护,而无需重建您的容器镜像。

 

注意事项:虽然 ConfigMaps 非常适合存储非敏感数据,但避免使用它们存储应保持安全的数据。始终使用 Secrets 存储密码、令牌、密钥和其他敏感数据,并注意保护 Secrets 的最佳实践,例如在静止时对其进行加密。

 

10. 用于直接容器调试的 Kubectl Debug

 

要点说明:kubectl debug 提供了一种创建临时副本 Pod 并替换其容器为调试版本或添加新的故障排除工具的方式,而不会影响原始 Pod。这在不影响应用程序运行状态的情况下,在实时环境中调试问题非常有用。

 

使用示例:

 

  •  
kubectl debug pod/myapp-pod -it --copy-to=myapp-debug --container=myapp-container --image=busybox

 

此命令创建 myapp-pod 的副本,将 myapp-container 替换为 busybox 镜像以进行调试。

 

适用场景:当您需要调试在生产中崩溃或表现异常的 pod 时,此技巧非常有价值。它允许实时调试,对服务的影响最小。

 

注意事项:调试 pod 仍可能影响整个集群的资源分配,并可能访问敏感数据。确保严格控制对调试命令的访问,并且使用后清理调试 pod。

 

11. 使用请求和限制进行

高效的资源管理

要点说明:Kubernetes 允许您为 pod 中的每个容器指定 CPU 和内存(RAM)的请求和限制。请求保证容器获得指定数量的资源,而限制确保容器永远不超过分配的数量。这有助于有效管理资源分配,并防止任何单一应用程序独占集群资源。

 

使用示例:

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
apiVersion: v1kind: Podmetadata:  name: resource-demospec:  containers:  - name: demo-container    image: nginx    resources:      requests:        memory: "64Mi"        cpu: "250m"      limits:        memory: "128Mi"        cpu: "500m"

 

此 pod 规范为 demo-container 请求了特定数量的 CPU 和内存,确保它拥有最佳性能所需的资源,同时防止它超出指定的限制。

 

适用场景:对所有容器应用请求和限制,以确保可预测的应用程序性能并避免在集群中运行的应用程序之间的资源争用。

 

注意事项:设置过低的限制可能导致 pod 被终止或无法调度,如果集群无法提供所请求的资源。相反,设置过高可能导致集群资源利用效率低下。监视应用程序性能并根据需要调整请求和限制。

 

12. 用于扩展 Kubernetes 的

自定义资源定义(CRDs)

 

要点说明:CRDs 允许您通过创建像原生 Kubernetes 对象一样操作的自定义资源来扩展 Kubernetes。这对于向您的集群添加特定领域的功能、促进自定义操作和与外部系统集成非常强大。

 

使用示例:

 

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
apiVersion: apiextensions.k8s.io/v1kind: CustomResourceDefinitionmetadata:  name: crontabs.stable.example.comspec:  group: stable.example.com  versions:  - name: v1    served: true    storage: true  scope: Namespaced  names:    plural: crontabs    singular: crontab    kind: CronTab  shortNames:  - ct

 

此 CRD 在集群中定义了一个新的资源类型 CronTab,它可以用来安排任务,就像传统的 cron 作业一样,但具有 Kubernetes 原生的管理。

 

适用场景:CRDs 对于扩展 Kubernetes 功能以满足您的应用程序或服务的特定需求非常有用,例如引入特定领域的资源类型或与外部服务和 API 集成。

 

注意事项:设计和管理 CRD 需要很好地理解 Kubernetes 内部和 API 机制。设计不良的 CRD 可能导致性能问题并使集群管理复杂化。始终确保 CRD 经过充分测试,并考虑对集群稳定性和性能的影响。

 

13. 用于动态交互和自动化的Kubernetes API

 

要点说明:Kubernetes API 支持与您的集群进行动态交互,使您能够以编程方式自动化扩展、部署和管理任务。通过利用 API,您可以创建实时与集群交互的脚本或应用程序,实现超越静态配置文件和手动命令所能实现的复杂自动化和集成场景。

 

使用示例:以下是一个使用 curl 与 Kubernetes API 交互的基本示例,用于获取默认命名空间中的 pod 列表。这假定您拥有访问令牌,并且 Kubernetes API 可在 https://<kubernetes-api-server> 上访问。

 

  •  
  •  
  •  
curl -X GET https://<kubernetes-api-server>/api/v1/namespaces/default/pods \  -H "Authorization: Bearer <your-access-token>" \  -H 'Accept: application/json'

 

对于更复杂的交互,考虑使用各种编程语言(如 Go、Python、Java)提供的客户端库,这些库抽象了 HTTP 请求,并提供了更方便的接口来使用 Kubernetes API。

 

适用场景:Kubernetes API 在开发自定义自动化、动态扩展策略、CI/CD 集成,甚至是扩展 Kubernetes 功能范围的自定义控制器方面非常强大。当您需要将 Kubernetes 操作与外部系统集成或创建自定义部署工作流时,它特别有用。

 

注意事项:直接与 Kubernetes API 交互需要仔细处理认证和授权。确保您的脚本和应用程序遵循最小权限原则,只请求其运行所需的权限。此外,当进行频繁或复杂的查询时,请注意 API 服务器可能的负载,因为这可能会影响集群性能。始终验证和清理您的 API 客户端的输入,以避免安全漏洞,特别是如果它们与外部系统或用户生成的内容交互。

 

这个技巧使开发人员和运维人员能够根据其独特的操作环境定制 Kubernetes,实现可以显著提高操作效率和灵活性的自动化和集成水平。

 

作者丨DavidW (skyDragon)
来源丨overcast.blog/13-kubernetes-tricks-you-didnt-know-647de6364472
dbaplus社群欢迎广大技术人员投稿,投稿邮箱:editor@dbaplus.cn
最新评论
访客 2024年04月08日

如果字段的最大可能长度超过255字节,那么长度值可能…

访客 2024年03月04日

只能说作者太用心了,优秀

访客 2024年02月23日

感谢详解

访客 2024年02月20日

一般干个7-8年(即30岁左右),能做到年入40w-50w;有…

访客 2023年08月20日

230721

活动预告