Azure Kubenetes 服务入门指南(二)
七、操作 Azure Kubenetes 服务
一旦您部署了第一个 AKS 集群,了解如何配置、监控和管理 AKS 环境是非常重要的。将应用部署到 AKS 集群时,AKS 操作员的角色至关重要,因为集群优化是 AKS 中的关键操作流程。
在本章中,我们将从集群操作者的角度探讨如何操作 AKS 集群。我们将回顾处理集群操作的流程,如何为 AKS 配置数据存储,以及 AKS 中的网络、安全和身份验证如何工作。然后,我们将使用 Azure Monitor for containers 深入 AKS 监控领域。最后,我们将介绍 Azure Kubernetes 服务的业务连续性和灾难恢复(DR)规划流程和最佳实践。本章结束时,您将从 AKS 操作员的配置、监控和管理角度全面了解 AKS 集群的操作。
Azure Kubernetes 服务中的集群操作
在操作 Azure Kubernetes 服务集群时,熟悉集群常见操作非常重要。以下部分概述了您在使用 AKS 时会遇到的一些常见集群操作。
注意
下面几节中的解释是在 Azure Cloud Shell 中执行的。如果您使用本地安装,请通过执行az –version确保您运行的是 Azure CLI 版本 2.0.65 或更高版本。
手动扩展 AKS 集群节点
应用的资源需求确实会随时间而变化。在这种情况下,您可以手动或自动扩展 AKS 集群,以增加或减少节点数量。在缩减规模操作中,您的 AKS 节点被小心地封锁和排空,以最大限度地减少应用中断。在向上扩展操作中,在工作节点被标记为就绪之前,AKS 会一直等待,然后才会在其上调度 pod。
以下示例首先获取 jcbaksrg01 资源组中 jcbaksclu01 群集的节点池名称。
az aks show --resource-group jcbaksrg01 --name jcbaksclu01 --query agentPoolProfiles
Listing 7-1az aks show command
您可以在下面的输出中看到名称是 nodepool1。
{
"count": 1,
"maxPods": 110,
"name": "nodepool1",
"osDiskSizeGb": 30,
"osType": "Linux",
"storageProfile": "ManagedDisks",
"vmSize": "Standard_DS2_v2"
}
]
Listing 7-2az aks show command output
然后,您可以使用az aks scale command来扩展集群节点。以下示例将 jcbaksclu01 的节点计数从 1 调整到 3。
az aks scale --resource-group jcbaksrg01 --name jcbaksclu01 --node-count 3 --nodepool-name nodepool1
Listing 7-3az aks scale command
您应该会看到以下类似的输出,显示集群已成功扩展到三个节点,如 agentPoolProfiles 部分所示:
{
"aadProfile": null,
"addonProfiles": null,
"agentPoolProfiles": [
{
"count": 3,
"maxPods": 110,
"name": "nodepool1",
"osDiskSizeGb": 30,
"osType": "Linux",
"storageProfile": "ManagedDisks",
"vmSize": "Standard_DS2_v2",
"vnetSubnetId": null
}
],
[...]
}
升级 AKS 集群
在 AKS 集群的生命周期中,您需要将其升级到最新的或者特定的 Kubernetes 版本。以下示例说明了如何升级 AKS 集群中单个默认节点池的主组件。
首先,通过对集群执行如下的az aks get-upgrades命令,检查集群是否有新的 Kubernetes 版本。
az aks get-upgrades --resource-group jcbaksrg01 --name jcbaksclu01 --output table
Listing 7-4az aks get-upgrades command
如果有任何可用的升级,您应该会看到类似下面的输出。在本例中,您的集群可以升级到 Kubernetes 版本 1.14.5 和 1.14.6。
Name ResourceGroup MasterVersion NodePoolVersion Upgrades
------- --------------- --------------- ----------------- --------------
default jcbaksrg01 1.13.10 1.13.10 1.14.5, 1.14.6
Listing 7-5az aks get-upgrades command output
如果没有可用的升级,您应该会看到以下错误消息作为输出。
ERROR: Table output unavailable. Use the --query option to specify an appropriate query. Use --debug for more info.
Listing 7-6No upgrades available error
注意
升级 AKS 集群时,不能跳过 Kubernetes 次要版本。例如,允许从 1.12.x 升级到 1.13.x 或从 1.13.x 升级到 1.14.x,但不允许从 1.12.x 升级到 1.14.x。要从 1.12.x 升级到 1.14.x,首先从 1.12.x 升级到 1.13.x,然后从 1.13.x 升级到 1.14.x。
现在我们可以使用az aks upgrade命令将 AKS 集群升级到 Kubernetes 版本 1.14.5。
az aks upgrade --resource-group jcbaksrg01 --name jcbaksclu01 --kubernetes-version 1.14.5
Listing 7-7az aks upgrade command
注意
根据您拥有的节点数量,升级 AKS 集群可能需要一些时间。升级操作所需的时间可以通过 10 分钟 x 集群中的节点总数来计算。在此示例中,升级操作必须在 30 分钟内成功,否则 AKS 将使操作失败,以避免不可恢复的群集状态。如果您遇到任何升级失败,请在达到该超时时间后重试群集升级操作。
您可以通过运行以下命令来确认集群升级是否成功。
az aks show --resource-group jcbaksrg01 --name jcbaksclu01 --output table
Listing 7-8Verify AKS upgrade operation
您应该会看到确认集群版本为 1.14.5 的输出
Name Location ResourceGroup KubernetesVersion ProvisioningState Fqdn
----------- ------------------ --------------- ------------------- ------------------- ---------------------------------------------------------
jcbaksclu01 australiasoutheast jcbaksrg01 1.14.5 Succeeded jcbaksclu01-dns-6bede950.hcp.australiasoutheast.azmk8s.io
Listing 7-9Verify AKS upgrade operation output
删除 AKS 集群
尽管您可以使用清单 7-10 中所示的一行代码来删除 AKS 集群,但是在继续此操作之前,请确保您已经备份了您的配置和数据。
az aks delete --name jcbaksclu01 --resource-group jcbaksrg01
Listing 7-10az aks delete command to delete an AKS cluster
创建虚拟节点
您可以使用虚拟节点来快速扩展 AKS 中的应用工作负载。使用虚拟节点的优势在于,您可以快速配置 pod,并且只需按每秒的执行时间付费。如果您正在使用集群自动缩放器(预览功能),则需要等到节点部署完成后再运行其他窗格。目前,只有 Linux 节点和 pod 支持虚拟节点。
截至目前,以下 Azure 区域支持虚拟节点:
-
澳大利亚东部(澳大利亚东部)
-
美国中部
-
美国东部(East US)
-
美国东部 2 (eastus2)
-
日本东部
-
北欧(北欧)
-
东南亚
-
美国中西部
-
西欧(西欧)
-
美国西部
-
美国西部 2 号
请记住,虚拟节点依赖于 Azure 容器实例(ACI)中可用的功能,因此它们还不支持以下场景:
-
使用服务主体提取 ACR 映像。你可以使用 Kubernetes 的秘密作为一个解决办法。
-
虚拟网络限制包括 VNet 对等、Kubernetes 网络策略和网络安全组的互联网出站流量。
-
初始化容器。
-
主机别名。
-
ACI 中 exec 的参数。
-
Daemonsets 不会将 pod 部署到虚拟节点。
-
虚拟节点不支持 Windows 服务器节点(目前在 AKS 的预览版中)。但是,您可以使用虚拟节点来调度 Windows 服务器容器,而不需要 AKS 群集中的 Windows 服务器节点。
注意
可以从以下 URL 找到创建和配置 AKS 集群以使用虚拟节点的完整分步说明:
使用 Azure CLI ( https://docs.microsoft.com/en-au/azure/aks/virtual-nodes-cli?view=azure-cli-latest
使用 Azure 门户( https://docs.microsoft.com/en-au/azure/aks/virtual-nodes-portal?view=azure-cli-latest )
通过 Azure Kubernetes 服务使用虚拟 Kubelet
当使用 Azure Container Instances (ACI)时,你不必管理底层计算基础设施,因为 Azure 会为你做这些。在货物信息预报系统中运行的容器按每运行一个容器的秒数收费。您可以将虚拟 Kubelet provider for ACI 与 Linux 和 Windows 容器一起使用,并且可以在容器实例上调度它,就像它部署在常规 Kubernetes 节点中一样。
下图说明了虚拟 Kubelet 的工作原理。实质上,虚拟 Kubelet 将自己注册为 Kubernetes 集群中的一个节点。这使得开发人员可以通过将 Kubernetes 连接到其他 API,伪装成常规的 kubelet,从而允许自己的 API 与 pods 和容器进行交互。
注意
AKS 现在提供了对使用虚拟节点在 ACI 上调度容器的本地支持,目前只支持 Linux 容器。因此,建议只在需要调度 Windows 容器实例时才使用 Virtual Kubelet。
关于在 AKS 上使用 Virtual Kubelet 的分步说明,请参考以下网址: https://docs.microsoft.com/en-au/azure/aks/virtual-kubelet?view=azure-cli-latest 。
图 7-1
虚拟库伯莱架构
使用 Kubernetes 仪表板
Kubernetes 的默认仪表板体验包括一个 web 仪表板,您可以使用它来完成基本的管理任务。该仪表板允许您查看和监控应用的基本运行状况和指标,创建和部署容器服务,以及修改现有应用。仪表板在 kube-system 名称空间下运行。
以下命令为 jcbaskrg01 资源组中的 jcbaksclus01 集群启动 Kubernetes 仪表板。
注意
对于启用了 RBAC 的 AKS 集群,请确保在启动 Kubernetes 仪表板之前创建了 ClusterRoleBinding。默认情况下,Kubernetes 仪表板以最小的读者访问权限进行部署,并且可以显示 RBAC 访问错误。以下代码片段说明了如何使用kubectl create clusterrolebinding命令为我们的示例创建绑定:
kubectl create clusterrolebinding kubernetes-dashboard --clusterrole=cluster-admin --serviceaccount=kube-system:kubernetes-dashboard。
az aks browse --resource-group jcbaksrg01 --name jcbaksclu01
Listing 7-11Starting the Kubernetes dashboard with az aks browse command
除非弹出窗口在浏览器中被阻止,否则在 Azure Cloud Shell 中执行上述命令后,您应该会被自动重定向到 web 浏览器中的新选项卡。如果没有,请将 Azure CLI 中显示的 URL 地址复制并粘贴到您的 web 浏览器中,如下所示。
图 7-3
Kubernetes 的控制板
图 7-2
蓝色 CLI 中的 open kuble dashboard
扩展蓝色立方体服务
当您在 Azure Kubernetes 服务中部署 n 个应用时,将需要根据需求增加或减少分配的计算资源。这将要求底层 Kubernetes 节点做出相应的改变。有些情况下,需要快速调配许多额外的应用实例。
本节探讨了 AKS 中的核心扩展概念,这些概念将帮助您实现上述目标。
手动缩放窗格或节点
为了测试您的应用如何响应 AKS 集群中资源可用性的变化,您可以手动扩展 pod(副本)和节点。通过手动扩展这些资源,您可以在 AKS 集群中定义一定数量的资源。为了手动缩放,首先要定义单元或节点数,然后 Kubernetes API 根据单元或节点数安排创建额外的单元或节点。
关于在 AKS 集群中扩展 pod 的完整教程可以从以下 URL 找到: https://docs.microsoft.com/en-au/azure/aks/tutorial-kubernetes-scale#manually-scale-pods 。在“手动扩展 AKS 集群节点”一节中,我们讨论了手动扩展 AKS 集群节点的步骤。
自动缩放窗格或节点
AKS 集群需要一种方法来自动扩展 pod 或节点,以便根据应用接收的流量来适应不断变化的应用需求。AKS 集群可以通过以下两种方式之一进行扩展:
-
horizontal podautoscaler(HPA):这利用 Kubernetes 集群中的度量服务器来监控 pod 的资源需求。如果应用请求更多资源,副本的数量会自动增加以满足需求。
-
集群自动缩放器:监视由于资源限制而无法在节点上调度的 pod。然后,群集可以自动增加节点数量。
水平吊舱自动缩放器
图 7-4
水平 pod 自动缩放架构
在 Kubernetes 中,水平 pod 自动缩放器(HPA)用于监控资源需求并自动缩放 pod 的数量。默认情况下,HPA 每 30 秒检查一次指标 API,以确定 pod 计数是否有任何必要的变化。如果在任何时候需要进行更改,pod 的数量会分别增加或减少。在 AKS 中,部署了 Metrics Server for Kubernetes 1.8+的 AKS 群集支持 HPA。
如果您正在为 AKS 集群配置水平单元自动缩放器,您将必须定义该集群可以运行的最小和最大单元数量。除此之外,您还可以声明一个要监控的指标,以及任何扩展决策所基于的指标,即 CPU 使用率。
关于在 AKS 集群中设置水平自动缩放器的完整教程可以从以下 URL 找到: https://docs.microsoft.com/en-au/azure/aks/tutorial-kubernetes-scale#autoscale-pods 。
注意
在每 30 秒发生一次的指标 API 检查之间,AKS 群集中以前的规模事件可能尚未成功完成。这种现象可能会导致 HPA 在之前的扩展事件能够掌握应用工作负载并相应地调整资源需求之前更改机架数量。为了最大限度地减少此类竞赛事件,在 AKS 集群中设置了冷却或延迟值。这些值描述了一个秤事件发生后,HPA 必须等待多长时间才能触发另一个秤事件。通过这样做,它将允许新的 pod 计数生效,并允许 Metrics API 反映新分配的工作负载。放大事件的默认延迟值为 3 分钟,而缩小事件的默认延迟值为 5 分钟。目前,用户不能设置这些冷却值。
群集自动缩放器(预览)
图 7-5
集群自动缩放架构
Cluster autoscaler(预览版)可以根据节点池中请求的计算资源调整节点数量,以快速响应不断变化的 pod 需求。如果集群自动缩放器决定需要资源变化,它可以相应地增加或减少 AKS 集群中的节点数量。运行 Kubernetes 1.10.x 或更高版本的支持 RBAC 的 AKS 集群支持集群自动缩放功能。
通常,群集自动缩放器与水平 pod 自动缩放器一起使用。HPA 根据应用需求增加或减少单元的数量,而集群自动缩放器会调整运行这些额外单元所需的节点数量。
注意
集群自动缩放是 AKS 中的一个预览功能。
关于集群自动缩放器入门的完整教程可以从以下 URL 找到: https://docs.microsoft.com/en-au/azure/aks/cluster-autoscaler 。
使用 Azure 容器实例按需爆发
图 7-6
Azure 容器实例爆炸
与 Azure Container Instances (ACI)集成允许您快速扩展 AKS 集群。Kubernetes 中的内置组件可以扩展 pod 和节点数量。但是,如果您的应用要求快速扩展,HPA 可能会调度比使用节点池中的现有计算资源所能提供的更多的 pod。这种现象会触发群集自动缩放器在节点池中部署额外的节点;但是,这些额外的节点可能需要一些时间来配置,并允许 Kubernetes 调度程序在这些节点上运行 pods。
连接到 AKS 的 ACI 成为您的 AKS 集群的安全和逻辑扩展。目前有两种方法可以在 AKS 上启用 ACI:
-
虚拟 Kubelet :当安装在 AKS 集群中时,该组件可以将 ACI 呈现为虚拟 Kubernetes 节点。它支持 Linux 和 Windows 节点。
-
虚拟节点:目前在预览版中,这些节点被部署到与您的 AKS 集群相同的 VNet 中的一个附加子网。该虚拟网络允许 ACI 和 AKS 之间的流量得到保护。目前仅支持 Linux 节点。
Azure Kubernetes 服务的存储选项
部署到 AKS 集群的应用需要存储来存储和检索它们的数据。对于一些工作负载,这些存储可以是节点上的本地快速存储,可以在删除 pod 时释放,而其他一些工作负载可能需要 Azure 中托管的持久数据存储。如果在不同的节点上重新安排单元,则多个单元可能需要共享相同的数据卷和/或重新连接数据卷。还可能需要将敏感数据或应用配置呈现到 pod 中。图 7-7 描述了 AKS 集群的存储架构。
图 7-7
AKS 中的存储架构
在本节中,我们将探讨 AKS 中的核心概念,这些概念解释了如何为您的应用工作负载提供存储。
卷
一个卷代表一种在整个应用生命周期中跨 pod 存储、检索和持久化数据的方法。通常,在 AKS 上存储和检索数据所需的容量是基于 Azure 存储的。这些数据卷既可以手动创建,然后直接分配给 pod,也可以在需要时由 AKS 自动创建和分配。这些数据卷可以使用
-
Azure Disks :这些可以用来创建一个 Kubernetes DataDisk 资源。Azure 磁盘可以使用 Azure 高级存储或 Azure 标准存储。对于生产和开发工作负载,建议使用高级存储。它们以读写一次的方式装载,因此只对单个节点可用。
-
Azure 文件用于将由 Azure 存储帐户支持的 SMB 3.0 共享安装到 pods。使用 Azure 文件,您可以在多个节点和单元之间共享数据。Azure 文件支持 Azure 高级存储和 Azure 标准存储。
还可以利用 Kubernetes 卷将数据注入到容器使用的 pod 中。Kubernetes 中的其他卷类型包括
-
emptyDir :用作 pod 的临时空间
-
secret :用于将敏感数据注入 pod,如密码
-
configMap :用于将键值对属性注入到 pod 中,比如应用配置信息
持久卷
持久卷(PV)由 Kubernetes API 创建和管理。它可以在单个 pod 的生命周期之后继续存在,而作为 pod 生命周期的一部分创建的传统卷只会在 pod 被删除之前一直存在。您可以使用 Azure 磁盘或文件来提供 PV。
持久卷可以由集群管理员手动创建,也可以由 Kubernetes API 服务器动态生成。如果调度请求当前不可用的存储,Kubernetes 将创建底层 Azure 磁盘或文件存储,并将其附加到 pod。这个场景被称为动态预配置,它使用一个存储类来确定需要什么类型的 Azure 存储。
存储类别
为了对不同的存储层进行分类,您可以创建一个存储类。StorageClass 还定义了回收策略。当 pod 被删除,并且可能不再需要持久卷时,回收策略控制 Azure 存储资源的行为。删除一个单元后,存储资源既可以删除,也可以保留以供将来的单元使用。
AKS 中可以创建两个初始存储类:
-
默认:利用 Azure 标准存储创建托管磁盘。回收策略声明,当相应的 pod 被删除时,Azure 磁盘也将被删除。
-
managed-premium :利用 Azure Premium 存储创建托管磁盘。回收策略声明,当相应的 pod 被删除时,Azure 磁盘也将被删除。
如果在创建 PV 时未指定 StorageClass,则使用默认的 StorageClass。
在以下 YAML 清单中,声明将使用高级管理磁盘,并且在删除 pod 时必须保留 Azure 磁盘:
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: managed-premium-retain
provisioner: kubernetes.io/azure-disk
reclaimPolicy: Retain
parameters:
storageaccounttype: Premium_LRS
kind: Managed
Listing 7-12Defining a storage class in YAML
持续量声明
如果您想要创建具有定义的存储类别、访问模式和大小的磁盘或文件存储,请定义一个 PersistentVolumeClaim。如果没有现有的资源来为基于其 StorageClass 的声明提供服务,那么 Kubernetes API 服务器可以动态地提供底层存储资源。一旦将卷连接到 pod,pod 定义也将包括卷装载。
在将可用存储资源分配给请求该资源的 pod 后,PV 将绑定到 PersistentVolumeClaim。永久卷与声明的映射是 1:1
下面是一个 YAML 清单示例,它表示托管高级存储类的 PV 索赔,磁盘大小为 5 Gi。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: azure-managed-disk
spec:
accessModes:
- ReadWriteOnce
storageClassName: managed-premium
resources:
requests:
storage: 5Gi
Listing 7-13Defining a PersistentVolumeClaim in YAML
创建 pod 定义时,会指定一个 PV 声明来请求所需的存储。在这里,您还可以为您的应用指定 volumeMount 来读取和写入数据。下面的 YAML 清单说明了如何使用前面的 PV 声明在/mnt/azure 安装卷。
kind: Pod
apiVersion: v1
metadata:
name: nginx
spec:
containers:
- name: myfrontend
image: nginx
volumeMounts:
- mountPath: "/mnt/azure"
name: volume
volumes:
- name: volume
persistentVolumeClaim:
claimName: azure-managed-disk
Listing 7-14Defining a volumeMount in a PersistentVolumeClaim in YAML
我们简要讨论了适用于 AKS 工作负载的存储选项。下一步是为 AK 创建动态和静态卷。Microsoft 文档中的以下文章全面概述了如何做到这一点:
-
使用 Azure 磁盘创建静态卷(
https://docs.microsoft.com/en-au/azure/aks/azure-disk-volume)。 -
使用 Azure 文件(
https://docs.microsoft.com/en-au/azure/aks/azure-files-volume)创建静态卷。 -
使用 Azure 磁盘创建动态卷(
https://docs.microsoft.com/en-au/azure/aks/azure-disks-dynamic-pv)。 -
使用 Azure 文件(
https://docs.microsoft.com/en-au/azure/aks/azure-files-dynamic-pv)创建动态卷。
Azure Kubernetes 服务中的网络
微服务方法中的应用组件必须协同工作来处理它们期望的任务。这种应用通信可以使用 Kubernetes 提供的一些组件来实现。例如,应用可以在内部或外部公开,可以进行负载均衡以实现高可用性,并具有 SSL。入口流量和多个组件路由的 TLS 终端。此外,出于安全考虑,开发人员可能需要您限制 pod 和节点之间的网络流量。
在本节中,我们将深入了解 AKS 的核心网络概念,以及为您的 pod 和节点提供安全网络连接的一些示例。
Kubenet vs. Azure 容器网络接口(CNI)
AKS 群集使用以下两种网络模型之一:
Kubenet(基本)网络
这是 AKS 集群的默认配置选项。在 kubenet 中,AKS 节点从 Azure VNet 子网获得一个 IP 地址。Pods 从逻辑上不同于节点的 Azure VNet 子网的地址空间接收 IP 地址。为了让 pods 访问 Azure VNet 上的资源,需要配置网络地址转换(NAT)。流量的源 IP 地址通过 NAT 转换为节点的主 IP 地址。
节点使用 kubenet Kubernetes 插件。您可以允许 Azure Fabric 为您创建和配置 VNet,或者将您的 AKS 集群部署到预定义 VNet 的现有子网中。即使您部署到预定义的 VNet,也只有节点会收到可路由的 IP 地址;pods 使用 NAT 与 AKS 集群外部的其他资源进行通信。
Azure 容器网络接口(CNI) -高级网络
每个 pod 从子网获得一个 IP 地址,如果您使用 Azure CNI 模型,可以直接访问它。但是请记住,这些 IP 地址在整个 VNet 网络空间中必须是唯一的,并且必须提前做好规划。每个节点支持的最大 pod 数量有一个配置参数。然后为该节点保留每个节点相同数量的 IP 地址。
下表列出了 kubenet 和 Azure CNI 之间的行为差异。
表 7-1
库伯内特和蔚蓝 CNI 之间的行为差异
|能力
|
库伯内特
|
CNI 蓝色
| | --- | --- | --- | | 在现有或新的虚拟网络中部署集群 | 受支持–手动应用 udr | 支持 | | Pod-pod 连接 | 支持 | 支持 | | Pod-VM 连接性;同一虚拟网络中的虚拟机 | 由 pod 启动时工作 | 双向工作 | | Pod-VM 连接性;对等虚拟网络中的虚拟机 | 由 pod 启动时工作 | 双向工作 | | 使用 VPN 或快速路由进行内部访问 | 由 pod 启动时工作 | 双向工作 | | 对由服务端点保护的资源的访问 | 支持 | 支持 | | 使用负载均衡器服务、应用网关或入口控制器公开 Kubernetes 服务 | 支持 | 支持 | | 默认 Azure DNS 和专用区域 | 支持 | 支持 |
表 7-2 从高层次上列出了 kubenet 和 Azure CNI 的优缺点。
表 7-2
库伯内特 vs 蔚蓝 CNI 的优缺点
|模型
|
优势
|
不足之处
| | --- | --- | --- | | 库伯内特 | 节省 IP 地址空间。使用 Kubernetes 内部或外部负载均衡器从集群外部访问 pod。 | 您必须手动管理和维护用户定义的路线(udr)。每个集群最多 400 个节点。 | | CNI 蓝色 | pod 获得完全的虚拟网络连接,并且可以从群集外部直接访问。 | 需要更多的 IP 地址空间。 |
无论您选择了哪种网络模型,AKS 的支持策略都描述了网络调整功能,例如您可以在 AKS 集群中使用的服务端点和 udr:
-
如果您为 AKS 群集手动创建虚拟网络资源,则在配置您自己的 udr 或服务端点时会得到支持。
-
如果 Azure 平台自动为您的 AKS 集群创建虚拟网络资源,则不支持手动更改这些 AKS 管理的资源来配置您自己的 udr 或服务端点。
注意
有关 AKS 支持策略的完整记录,请访问以下网址: https://docs.microsoft.com/en-au/azure/aks/support-policies 。
网络安全组和网络策略
不建议手动配置网络安全组规则来过滤 AKS 群集中的 pod 流量。Azure 平台将创建和更新适当的规则,作为 AKS 托管服务的一部分。为了自动将流量过滤规则应用到 pod,您可以利用网络策略。一方面,它是 AKS 中可用的功能,允许您控制 pod 之间的流量。您可以根据分配的标签、命名空间或流量端口等设置来决定是允许还是拒绝流量。另一方面,网络安全组是针对 AKS 节点的,而不是 pod。
注意
有关在 AKS 中使用 Azure 网络策略保护 pod 流量的分步说明,请访问以下 URL: https://docs.microsoft.com/en-au/azure/aks/use-network-policies 。
Azure Kubernetes 服务中的访问和身份
在 Azure 中,有多种方法来验证和保护 AKS 集群。基于角色的访问控制(RBACs)允许授予用户或组仅访问他们需要的资源的权限。通过将 AKS 与 Azure Active Directory 集成,您能够进一步增强安全性和权限结构。本节高度概括了操作 AKS 集群时可用的访问和身份选项。
不可思议的服务帐户
服务帐户是 Kubernetes 中的主要用户类型,它存在于 Kubernetes API 中,并由它管理。服务帐户凭证存储为 Kubernetes 机密,这允许授权的 pods 使用它们与 API 服务器通信。API 请求为服务帐户或常规用户帐户提供身份验证令牌。普通用户帐户被用来为使用 AKS 集群的管理员或开发人员提供传统的访问,尽管 Kubernetes API 本身并没有为这种场景提供身份管理解决方案。通过将 AKS 与 Azure Active Directory 集成,可以实现这个目标。
Azure 活动目录集成
Azure Active Directory (AAD)是一个多租户、基于云的目录和身份管理解决方案,提供核心目录服务、应用访问管理和身份保护。您可以将本地身份集成到 AKS 集群中,通过将 AKS 与 AAD 集成来提供统一的帐户管理和安全流程。
例如,在集成了 AAD 的 AKS 集群中,您可以授权用户或组访问某个名称空间内或整个集群中的 Kubernetes 资源。为了检索kubectl配置上下文,用户可以执行az aks get-credentials命令。之后,当用户使用kubectl与 AKS 集群交互时,他们将被提示使用各自的 Azure AD 凭据登录。这样,用户只能访问 AKS 集群管理员定义的资源。
Azure 基于角色的访问控制(RBACs)
除了 Kubernetes API 提供的 RBAC,AKS 集群访问还可以通过 Azure 基于角色的访问控制(RBAC)来管理。区别在于,Kubernetes RBAC 旨在处理您的 AKS 集群内的资源,而 Azure RBAC 旨在处理您的 Azure 订阅内的资源。Azure RBAC 使您能够创建角色定义,概述应用于 AKS 群集的权限。然后,您可以为包含已定义范围的角色定义分配用户或组,该范围可以是单个资源、资源组或整个 Azure 订阅。
角色、集群角色、角色绑定和集群角色绑定
在 Kubernetes RBAC,您首先将权限定义为一个角色。Kubernetes 角色授予权限,没有拒绝权限的概念。角色用于在名称空间内授予权限。
ClusterRole 的用途类似于角色,但是 ClusterRole 可以应用于整个集群的资源,而不是特定的名称空间。
当您定义了角色后,您可以通过角色绑定为这些 Kubernetes RBAC 分配权限。在 AAD 集成的 AKS 集群中,绑定是 Azure AD 用户被授予在集群中执行操作的权限的方式。角色绑定用于为已定义的名称空间分配角色,在该名称空间中,您可以隔离对各个集群的访问。
另一方面, ClusterRoleBinding 的工作方式与角色绑定相同,但是可以应用于整个集群中的资源,而不是特定的名称空间。在需要授权管理员或支持工程师访问 AKS 集群中所有资源的情况下,这种方法非常理想。
使用 Azure 策略控制部署(预览)
Azure Policy 可以与 AKS 集成,因此您可以以集中和一致的方式将策略强制应用到您的 AKS 集群。通过使用看门人,Azure Policy 允许您集中管理和报告 Azure 资源和 AKS 集群的合规状态,这是一个针对开放策略代理(OPA)的准入控制器 webhook。
按照以下步骤启用该功能并将其应用到您的 AKS 集群。
启用预览
首先,您必须启用Microsoft.ContainerService资源提供者和Microsoft.PolicyInsights资源提供者,然后被批准加入预览。以下示例说明了如何在 Azure Cloud Shell 中使用 Azure CLI 实现这一点。
# Provider register: Register the Azure Kubernetes Services provider
az provider register --namespace Microsoft.ContainerService
# Provider register: Register the Azure Policy provider
az provider register --namespace Microsoft.PolicyInsights
# Feature register: enables installing the add-on
az feature register --namespace Microsoft.ContainerService --name AKS-AzurePolicyAutoApprove
# Feature register: enables the add-on to call the Azure Policy resource provider
az feature register --namespace Microsoft.PolicyInsights --name AKS-DataplaneAutoApprove
Listing 7-15Join the AKS Policy preview via Azure CLI
Azure 策略加载项
这个附加组件安装在 azure-policy 名称空间中,将 azure 策略服务连接到网守准入控制器。以下是该附加组件的功能:
-
使用 Azure 策略检查对 AKS 群集的分配
-
下载并缓存策略详细信息,包括作为配置映射的 rego 策略定义
-
对 AKS 群集运行完全扫描符合性检查
-
向 Azure Policy 报告审核和合规详细信息
安装先决条件
在 AKS 集群中安装插件之前,您需要安装预览扩展。为此,请遵循以下步骤:
-
确保您运行的是 Azure CLI 版本 2.0.62。运行 az - version 来查找版本。
-
AKS 集群必须是 1.10 版或更高版本。以下 Azure CLI 摘录说明了如何检查这一点。
-
为
AKS, aks-preview安装 0.4.0 版 Azure CLI 预览版扩展。
az aks list
Listing 7-16Check AKS version
# Install/update the preview extension
az extension add --name aks-preview
# Validate the version of the preview extension
az extension show --name aks-preview --query [version]
Listing 7-17Install Azure CLI preview extension for AKS
注意
如果已经部署了 aks-preview 扩展,请卸载执行az extension update --name aks-preview命令的任何更新。
正在安装 Azure 策略加载项
一旦安装了前面的先决条件,您就可以继续安装 Azure Policy 插件。以下 Azure CLI 摘录说明了如何做到这一点。
az aks enable-addons --addons azure-policy --name jcbaksclu01 --resource-group jcbaksrg01
Listing 7-18Install Azure Policy add-on
将策略定义分配给 AK
目前 Azure 的 AKS 策略是有限的预览版,只支持内置的策略定义。您可以找到使用 Azure 门户管理 AK 的内置策略,如下所示:
-
点击左侧窗格中的所有服务,然后搜索并选择策略。
-
在 Azure Policy 页面,选择定义。
-
从类别下拉列表中,点击全选,然后选择 Kubernetes 服务。
-
选择要应用的策略定义,然后选择分配按钮。
注意
在为 AKS 定义分配 Azure 策略时,确保范围必须包括 AKS 群集资源。
策略验证
Azure Policy 插件每 5 分钟向 Azure Policy Service 检查一次策略分配的变化。azure-policy 命名空间中的所有 configmaps 都被删除,然后在此刷新周期中由附加组件为网守重新创建。
该插件要求每 5 分钟对群集进行一次全面扫描。一旦从全面扫描中收集到详细信息,以及网关守护设备对尝试更改群集的任何实时评估,结果将报告回 Azure Policy,以包括合规性详细信息,如 Azure 策略分配。在审计周期中,仅返回活动策略分配的结果。
注意
不建议或不支持对命名空间进行更改,尽管群集管理员可能拥有对 azure-policy 命名空间的权限,并且任何手动更改都会在刷新周期中丢失。
Azure 策略加载项日志
Azure Policy 附加组件日志作为 Kubernetes 控制器/容器保存在 AKS 集群中。这些日志显示在 AKS 集群的 Insights 页面中。
网关守护设备日志
您需要检查新资源请求的日志。按照以下 URL 中的过程在 AKS 中启用和查看 Kubernetes 主节点日志: https://docs.microsoft.com/en-au/azure/aks/view-master-logs 。
清单 7-19 是查看新资源请求的拒绝事件的示例查询。
| where Category == "kube-audit"
| where log_s contains "admission webhook"
| limit 100
Listing 7-19KQL query to view denied events on new resource requests
要查看网关守护设备容器中的日志,请遵循上一篇文章中的步骤,并检查诊断设置窗格中的 kube-apiserver 选项。
Azure Kubernetes 服务中的安全概念
AKS 群集的安全性与数据中心的任何其他资源一样至关重要。网络策略和秘密等 Kubernetes 安全组件得到了 Azure 功能的补充,如网络安全组和协调的 AKS 集群升级。
主安全
Kubernetes 主组件是 Azure 提供的 AKS 托管服务的一部分。每个 AKS 集群都有自己的单租户、专用的 Kubernetes master 来提供 Azure 中的 API 服务器、调度程序等。这个主机由 Azure 管理和维护。Kubernetes API 服务器使用公共 IP 地址和完全限定的域名(FQDN)的默认行为。对 API 服务器的访问可以通过使用 Kubernetes RBACs 和 Azure Active Directory 来控制。
节点安全性
AKS 节点是由你自己管理和维护的 Azure 虚拟机。Linux AKS 节点运行在带有莫比容器运行时的优化 Ubuntu 发行版上。Windows 服务器节点(目前在 AKS 中预览版)运行优化的 Windows Server 2019 版本和莫比容器运行时。在 AKS 集群中创建或扩展操作期间,这些节点会自动部署最新的操作系统安全更新和配置。
以下是规划 AKS 节点安全性时的一些事实和注意事项:
-
Azure 平台每晚都会自动将 OS 安全补丁应用到 Linux 节点上。
-
如果 Linux 操作系统安全更新需要重新启动主机,它不会自动执行。
-
您既可以手动重启 Linux 节点,也可以使用 Kubernetes 的开源重启守护程序 Kured 。
-
Windows Update 不会自动运行并应用 Windows 服务器节点的最新更新。
-
您应该自己对 AKS 群集中的 Windows 服务器节点池执行升级。此升级过程会创建运行最新 Windows Server 映像和修补程序的节点,然后删除旧节点。
-
默认情况下,节点部署在专用虚拟网络子网中,没有分配公共 IP 地址。SSH 默认启用,仅在使用内部 IP 地址进行故障排除和访问时可用。
-
节点使用 Azure 管理的磁盘进行存储。对于大多数虚拟机 SKU,这些都是优质磁盘,存储的数据在 Azure 平台内自动加密。
-
需要额外的安全功能,如 Pod 安全策略或更细粒度的基于角色的访问控制(RBAC ),以保护节点免受多租户使用中可能出现的漏洞攻击。
-
对于敌对的多租户工作负载,您应该通过利用虚拟机管理程序级别的安全性来使用物理隔离的集群,其中 Kubernetes 的安全域成为整个集群,而不是单个节点。
-
多租户工作负载的最佳实践是使用逻辑隔离来分隔团队和项目。建议尽量减少为隔离团队或应用而部署的物理 AKS 集群的数量。
集群升级
AKS 集群升级过程包括从集群中单独隔离节点,以便不能在这些节点上安排新的 pod。然后,这些节点被清空,并按照以下过程进行升级:
-
一个新节点部署到运行最新操作系统映像和修补程序的节点池中。
-
现有节点中的一个被识别并标记用于升级。此节点上的 pod 会在节点池中的其他节点上正常终止和调度。
-
然后从 AKS 群集中删除该目标节点。
-
群集中的下一个节点使用相同的过程进行隔离和排空,直到作为升级过程的一部分,所有节点都被成功替换。
不可告人的秘密
敏感数据如访问凭证或密钥可以通过使用一个Kubernetes?? 秘密被摄取到 pod 中。这个秘密首先是使用 Kubernetes API 创建的,当您定义您的 pod 或部署时,可以请求一个特定的秘密。这些秘密仅提供给具有需要秘密的调度 pod 的节点,并且存储在 tmpfs 中,而不是写入磁盘中。当节点上的最后一个 pod 请求删除密码时,密码将从节点的 tmpfs 中删除。此外,Kubernetes 的秘密存储在一个定义的名称空间中,只能由同一名称空间中的 pod 访问。
通过使用 Kubernetes secrets,您可以最大限度地减少 pod 或服务 YAML 清单中定义的敏感信息。在这里,您将请求存储在 Kubernetes API 服务器中的秘密,作为您的 YAML 清单的一部分。通过使用这种方法,您只提供了对秘密的特定 pod 访问。
注意
原始机密清单文件包含 base64 格式的机密数据,因此,该文件应被视为敏感信息,不应提交给源代码管理。
监视蓝色立方体服务
操作 Azure Kubernetes 服务的一个重要部分是能够监控在 AKS 实例中运行的集群、节点和工作负载。运行生产工作负载需要可靠的可靠性。Azure 附带了 Kubernetes,Azure Monitor 中提供了开箱即用的容器监控。在这一节中,我们将深入探讨 Azure Monitor 中可用的 Kubernetes 和容器监控服务。
Azure 容器监视器
概观
Azure Monitor 中的监控服务被称为 Azure Monitor for containers。Azure Monitor for containers 从两个角度为您提供监控:第一个角度直接来自 AKS 集群,第二个角度是您的订阅中的所有 AKS 集群。监控查看两个关键区域“健康状态”和“性能图表”,包括
-
洞察力:监控 Kubernetes 集群和容器。
-
指标:基于指标的聚类和 pod 图表。它基于一个时间序列数据库,该数据库直接从 AKS 资源提供程序收集数据,以获得 pod 和节点上的基本和标准性能指标。
-
Log Analytics: K8s and container logs viewing and search. It is the platform where Azure Monitor for containers store the data. You can run KQL queries to view all telemetries that Azure Monitor for containers collects such as perf, health, kubernetes events, container logs, and inventory.
图 7-8
Azure 容器架构监视器
启用监控
启用 AKS 监控的最简单方法是部署 AKS 集群。有关部署 AKS 集群的详细信息,请参考第五章“部署 Azure Kubernetes 服务”。
可以使用以下方法之一启用对现有 AKS 集群的监控:
-
在 Azure Monitor 中或 Azure 门户的 AKS 集群中
-
azure PowerShell cmdlet New-AzResourceGroupDeployment 使用 ARM 模板此处:
https://docs.microsoft.com/en-us/azure/azure-monitor/insights/container-insights-enable-existing-clusters#enable-using-an-azure-resource-manager-template -
蓝色 CLI
-
仿地成形
启用 AKS 集群监控的最佳和最快方式是从 Azure Cloud Shell 中的 Azure CLI。要从 web 浏览器执行此操作,请导航至 https://shell.azure.com PowerShell 并运行以下程序。
az aks enable-addons -a monitoring -n ExistingAKSCluster -g ExistingAKSClusterResourceGroup
Listing 7-20Enabling Azure Monitor for containers using Azure CLI
Azure 监视器
在 Azure Monitor 中,你会在洞察下找到容器。在这里,您将看到 Azure 订阅中所有 AKS 群集的运行状况摘要。此外,您将看到 AKS 集群有多少个节点和系统/用户单元,以及节点或单元是否有任何健康问题。从这里单击一个集群,它会将您带到 AKS 集群本身的 Insights 部分。单击 AKS 集群会将您带到 Azure Monitor for containers 的 Insights 部分,该部分位于实际的 AKS 集群上。在这里,您将看到见解、指标和日志。现在让我们深入了解这三个领域。
图 7-9
Azure Monitor for containers 概述页面
洞察力
在 Insights 区域,您会发现许多关于监控 AKS 集群的有用数据。在 Insights 中,有四个区域:集群、节点、控制器和容器。
串
在“Cluster”选项卡中,您会发现包含 AKS 集群运行状况关键性能指标的图表。它提供了节点计数和状态以及单元计数的性能图表,以及群集内的聚合节点内存和 CPU 利用率。在这里,您可以将时间范围从实时、小时更改为天,并添加筛选器以将范围缩小到特定信息,如服务、命名空间、节点池和您想要查看的节点。
节点
在 Nodes 选项卡上,您将看到 AKS 集群中运行的节点,以及正常运行时间、节点上的 pod 数量、CPU 使用率、内存工作集和内存 RSS。您可以单击节点旁边的箭头将其展开,显示正在其上运行的窗格。这为您提供了一种快速查看 AKS 集群中嘈杂邻居的方法。
控制器
在控制器选项卡上,您可以找到集群控制器的运行状况。同样,这里您将看到每个控制器的 CPU 使用率、内存工作集和内存 RSS,以及运行控制器的是什么。例如,您可以看到 kubernetes-dashboard pod 在 kubernetes-dashboard 控制器上运行。
您还可以查看 kubernetes-dashboard 窗格的属性。这些属性将为您提供诸如 pod 名称、pod 状态、Uid、标签等信息。
容器
在 Containers 选项卡上,您将找到 AKS 集群中的所有容器。和其他选项卡一样,您可以看到 CPU 使用率、内存工作集和内存 RSS。您还将看到状态、它所属的单元、它正在运行的节点、它的正常运行时间以及它是否有任何重新启动。
您还可以在“容器”选项卡中查看容器日志。为此,请选择一个容器来显示其属性。在属性中,您可以单击查看容器实时日志(如下图所示)或查看容器日志。每三分钟收集一次容器日志数据。STDOUT 和 STDERR 是从每个 Docker 容器发送到日志分析的日志输出。
图 7-10
Azure Monitor for containers 实时日志和事件
点击**查看实时数据(预览)**将带您进入日志分析日志搜索页面,该容器的日志和事件显示在结果窗格中。
注意
动态数据在节点、控制器和容器选项卡中可用。它们将向您显示 kubernetes 事件(每个集群、名称空间和/或节点和/或 pod)和容器日志。
图 7-11
Azure Monitor for containers 分析视图
kube-system 当前未被收集并发送至日志分析。如果您不熟悉 Docker 日志,可以在这里的这篇 Docker 日志文章中找到关于 STDOUT 和 STDERR 的更多信息: https://docs.docker.com/config/containers/logging 。
注意
如果您想要为 kube-system 收集日志,您可以按照以下条款更改配置图: https://docs.microsoft.com/en-us/azure/azure-monitor/insights/container-insights-agent-config
韵律学
在 metrics 区域,您可以看到基于指标的节点和 pod 图表,这些图表有助于您了解有关 AKS 集群的重要信息。下面的屏幕截图显示了几个示例图表,这些图表根据命名空间和集群中的可用核心总数按阶段划分显示了 pod。
图 7-12
Azure 容器监视器度量视图
在撰写本书时,唯一可用的标准度量名称空间是Microsoft . container service/managed clusters(来自 AKS 资源提供商)和自定义度量名称空间 insights.container/nodes 和 insights.container/pods (来自 container insights)。聚合可以是总和或平均值,您可以在下面的屏幕截图中看到这些指标:
图 7-13
Azure 容器监视器可用指标
在 metrics 区域中,您可以将图表固定到 Azure dashboard,并且可以基于条件(如窗格何时处于失败状态)创建警报。
图 7-14
为 Azure Monitor for containers 创建警报规则
日志分析
日志分析是 Azure Monitor 的一个特性。日志分析被许多 Azure 服务用来查看日志和搜索;分析数据以确定趋势、模式和问题;通过机器学习进行异常检测;以及更多。在日志分析中,您可以深入了解您的 AKS 集群和容器。以下屏幕截图显示了在 Azure Monitor for containers 中收集的日志架构:
图 7-15
Azure Monitor for containers 日志架构
ContainerInsights 架构中的数据类型显示在日志分析搜索结果中。显示日志分析搜索页面的一种方法是在 AKS 群集中单击日志。从搜索页面,您可以筛选搜索结果或运行查询。
从“日志分析搜索”页面,您可以构建查询来检索限定范围的数据。下面是三个用于检索 AKS 数据的日志分析查询示例。
Pods that have a restart count greater than 0 in the last 48 hours
let startTimestamp = ago(48hrs);
KubePodInventory
| where ClusterName =~ "AKSCLUSTERNAME"
| where ContainerRestartCount > 0
| where isnotnull(Name)
Listing 7-21KQL query samples for retrieving AKS data
容器生命周期
ContainerInventory
| project Computer, Name, Image, ImageTag, ContainerState, CreatedTime, StartedTime, FinishedTime
| render table
久别事件
KubeEvents_CL
| where not(isempty(Namespace_s))
| sort by TimeGenerated desc
| render table
通过日志分析创建警报规则
我们使用下面的示例查询来返回基于所有阶段的 pod 阶段计数—失败的 、 待定的 、 未知的 、 正在运行的 或 成功的—通过日志分析查询来创建警报规则。
let endDateTime = now();
let startDateTime = ago(1h);
let trendBinSize = 1m;
let clusterName = '<your-cluster-name>';
KubePodInventory
| where TimeGenerated < endDateTime
| where TimeGenerated >= startDateTime
| where ClusterName == clusterName
| distinct ClusterName, TimeGenerated
| summarize ClusterSnapshotCount = count() by bin(TimeGenerated, trendBinSize), ClusterName
| join hint.strategy=broadcast (
KubePodInventory
| where TimeGenerated < endDateTime
| where TimeGenerated >= startDateTime
| distinct ClusterName, Computer, PodUid, TimeGenerated, PodStatus
| summarize TotalCount = count(),
PendingCount = sumif(1, PodStatus =~ 'Pending'),
RunningCount = sumif(1, PodStatus =~ 'Running'),
SucceededCount = sumif(1, PodStatus =~ 'Succeeded'),
FailedCount = sumif(1, PodStatus =~ 'Failed')
by ClusterName, bin(TimeGenerated, trendBinSize)
) on ClusterName, TimeGenerated
| extend UnknownCount = TotalCount - PendingCount - RunningCount - SucceededCount - FailedCount
| project TimeGenerated,
TotalCount = todouble(TotalCount) / ClusterSnapshotCount,
PendingCount = todouble(PendingCount) / ClusterSnapshotCount,
RunningCount = todouble(RunningCount) / ClusterSnapshotCount,
SucceededCount = todouble(SucceededCount) / ClusterSnapshotCount,
FailedCount = todouble(FailedCount) / ClusterSnapshotCount,
UnknownCount = todouble(UnknownCount) / ClusterSnapshotCount
| summarize AggregatedValue = avg(PendingCount) by bin(TimeGenerated, trendBinSize)
Listing 7-22KQL query sample to retrieve pod phase counts based on all phases
注意
以下为容器资源利用率创建预警规则的过程需要利用新的日志预警 API,如下 URL 所示: https://docs.microsoft.com/en-us/azure/azure-monitor/platform/alerts-log-api-switch 。
按照以下步骤,使用日志分析查询在 Azure Monitor 中创建日志警报:
-
登录 Azure 门户,从左侧窗格中选择 Monitor ,导航到 Insights ,然后选择 Containers 。
-
从受监控集群选项卡的列表中选择一个集群。
-
选择日志打开监控下的 Azure Monitor 日志页面。在该页面中,您可以编写和执行 Azure Log Analytics 查询。
-
在日志页面,选择**+新建预警规则**。
-
在条件部分,当<逻辑未定义> 自定义日志条件时,选择。因为我们直接从 Azure Monitor 日志页面创建警报规则,所以会自动选择自定义日志搜索信号类型。
-
将列表 7-22 中的查询粘贴到搜索查询字段中。
-
按照以下步骤配置警报:
-
在基于的下拉列表中选择公制测量**。这里,一个度量测量为查询中值高于我们指定阈值的每个对象创建一个警报。**
-
在条件下,选择大于的**,输入 75 作为 CPU 和内存利用率告警的初始基线阈值。对于低磁盘空间警报,输入 90 。您可以输入符合标准的不同值。**
-
在基于部分的触发预警下,选择连续违规**。在下拉列表中选择大于的,输入 2 。**
-
如果您想为容器 CPU 或内存利用率配置一个警报,选择上聚合下的容器名**。如果要为集群节点配置低磁盘警报,选择 ClusterId 。**
-
在基于段评估的下,将周期值配置为 60 分钟。这样,规则将每隔 5 分钟执行一次,并将返回从当前时间开始的最后一个小时内创建的记录。当您将时间跨度设置为较宽的窗口(这将导致潜在的数据延迟)时,可确保查询返回数据,以避免任何从未触发警报的误报。
-
-
点击完成。
-
在警报规则名称字段中提供一个有意义的名称。您还可以指定一个描述,它提供了这个警报的详细信息。最后,为此警报选择适当的严重性级别。
-
在创建时接受启用规则的默认值,以便立即激活警报。
-
您可以选择现有的操作组或创建新组。这是确保每次触发此警报时采取相同操作的方法。您可以根据您的 ITSM 团队管理事件的方式来配置此部分。
-
点击创建预警规则完成预警规则。规则立即开始执行。
有关使用日志分析查询语言创建警报的更多信息,您可以在此处访问微软文档: https://docs.microsoft.com/en-us/azure/azure-monitor/insights/container-insights-alerts 。
库伯勒原木
如果某个节点有问题,应该使用 Azure Monitor for containers 中提供的节点监控开始故障排除。如果需要超越 Azure Monitor for containers,可以使用 kubelet 日志。您可以使用 journalctl 从任何 AKS 节点查看 kubelet 日志。为此,您需要首先 SSH 到您想要查看日志的集群节点。通过 SSH 连接到节点后,执行以下语法。
sudo journalctl -u kubelet -o cat
Listing 7-23kubelet log retrieval
这将开始滚动 kubelet 日志,让您深入了解节点上发生的活动。
Kubernetes 主组件日志
值得注意的是,使用 AKS 时,默认情况下不会收集 Kubernetes 主节点日志。没有收集这些日志,因为 AKS 是微软的托管服务,它们管理主 Kubernetes 节点。因此,深入研究主节点的故障排除并不常见。如果您需要查看来自任何主节点的日志,您可以打开日志收集,将日志发送到日志分析工作区。
要在 Azure 门户中启用主节点日志收集,请导航到 AKS 资源组。不要转到具有此名称格式 MC _ resource group name _ AKS cluster name _ REGION 的 AKS 资源组。进入 AKS 资源组后,单击诊断设置。单击 AKS 集群。
图 7-16
AKS 集群的诊断设置
然后点击添加诊断设置。
图 7-17
为 AKS 集群添加诊断设置
如下图所示配置诊断设置,将日志发送到日志分析工作区。您将为诊断收集命名,选择或创建新的日志分析工作区,并选择要从中收集日志的主节点。
图 7-18
为 AKS 集群配置诊断设置
保存诊断日志设置后,您现在应该在 AKS 资源组上看到该设置,如图 7-19 所示。
图 7-19
已配置 AKS 集群的诊断设置
要查看来自 Kubernetes 主节点的实际日志,请转到您将日志发送到的日志分析工作区,并运行清单 7-24 中所示的搜索查询之一。
AzureDiagnostics
| Where Category == "kube-apiserver"
| project log_s
AzureDiagnostics
| where Category == "kube-controller-manager"
| project log_s
AzureDiagnostics
| where Category == "kube-scheduler"
| project log_s
AzureDiagnostics
| where Category == "kube-audit"
| project log_s
AzureDiagnostics
| where Category == "guard"
| project log_s
AzureDiagnostics
| where Category == "cluster-autoscaler"
| project log_s
Listing 7-24KQL queries to retrieve Kubernetes master logs
Azure Kubernetes 服务中的业务连续性和灾难恢复
在您的 AKS 群集中运行的应用将具有业务所要求的特定服务级别目标和协议(SLO 和 SLA)。作为 AKS 操作员,您的职责之一是考虑如何部署和管理 AKS,以满足这些 SLA 和 SLO。所有服务都会有这样或那样的中断,Azure Kubernetes 服务也不例外。通过了解 AKS 的底层组件以及它们如何提供服务,您可以满足或超过应用所有者的期望。
思考 SLA 和您的需求
考虑灾难恢复时,了解一些基本概念是很有用的。在灾难恢复中有一些主要的保护措施,即恢复时间目标(RTO)和恢复点目标(RPO)。RTO 定义了发生中断时恢复服务所需的时间。RPO 定义了发生此类宕机时丢失的数据量。
这两个术语都依赖于正式灾难的声明,即整个网站或服务完全不可用。还可能存在这样的情况,其中站点或服务处于降级模式,并且决定故障转移到服务的另一个站点或实例。RTO 和 RPO 是在发布灾难声明时衡量的。
在宣告失败之前,您可以确保 AKS 集群的部署方式能够防止常见的失败。让我们看看存在的各种级别的故障,以及如何使用 AKS 和 Azure 特性来防范它们。
数据持久性和复制
在 AKS 集群中运行的应用可能具有写入永久存储的有状态数据。需要考虑的一点是该存储提供的复制和保护级别。存储可能位于以下任何位置:
-
Azure VM 工作节点上的本地存储
-
Azure 托管磁盘
-
Azure 文件
-
其他 NFS 解决方案
Azure VM worker 节点上的本地存储使用 Azure 托管磁盘,持久托管磁盘卷的树内供应机制也是如此。托管磁盘仅提供本地冗余存储,这为数据中心内的驱动器故障提供保护,但不为 Azure 中的数据中心故障提供保护。Azure 文件可以配置为使用地理冗余存储,其中数据从一个 Azure 数据中心复制到另一个区域的配对数据中心。其他 NFS 解决方案可能提供不同级别的冗余。
如果应用卷上存在必须针对站点故障进行保护的持久数据,则应部署某种类型的复制或数据保护解决方案,以便在发生故障时保护这些数据。
防止故障
除了防止数据故障之外,AKS 中还可能发生许多其他故障。下面几节将回顾每一个错误和可能的缓解策略,以保护您的应用。
主节点故障
Azure Kubernetes 服务是一种托管服务,不提供对集群主节点层的可见性。如果主节点出现故障,群集将自动用新的主节点替换该主节点。作为操作员,对于主节点的故障,您几乎无能为力。
工作节点故障
作为工作节点的 Azure 虚拟机偶尔会出现错误和故障。如果某个节点出现故障,AKS 服务会用一个正常工作的节点替换该节点。然而,在一段时间内,您的运行能力会下降。对于关键群集,建议运行时具有足够的备用容量,以在不影响性能的情况下吸收单个节点的故障。
群集可以手动配置足够的节点来支持当前的性能要求,并有足够的开销来在停机期间维持性能。例如,让我们假设您有一个运行在 75%容量的四节点集群。如果一个节点丢失,其他三个节点将需要以 100%的容量运行,以符合当前的性能目标,直到第四个节点被替换。这是一种不太理想的情况。通过向群集中添加第五个节点,总体群集利用率现在将为 60%,而在停机期间,单个节点的损失将导致利用率增加到 75%。
手动配置集群大小是一个选项,但是众所周知,集群消耗是可变的。因此,更有意义的做法是监控当前利用率,并根据需要触发扩展集群的操作,或者利用当前预览中的集群自动扩展功能。
数据中心故障
Microsoft Azure 区域由多个数据中心组成。最近,许多 Azure 区域都引入了可用性区域。每个可用性区域都是一组地理上独立的资源,与同一区域的其他可用性区域有高带宽、低延迟的连接。可用性区域的目的是针对给定区域的数据中心故障提供保护。
AKS 具有预览功能,允许 AKS 群集跨越多个可用性区域。如果数据中心发生故障,假设每个可用性区域都有可用的工作节点,您的应用和 AKS 管理平面将继续不间断运行。该功能可能会在不久的将来全面推出,但是需要重新部署集群,以便将其迁移到可用性区域。目前,AKS 的数据中心中断需要像区域性故障一样处理。
区域性失败
虽然 Azure 的区域性中断非常罕见,但也不是完全没有听说过。AKS 群集不会跨区域扩展,因此问题就变成了在您的群集上运行的应用需要什么级别的保护。有几种不同的运营模式:
-
冷启动
-
标灯
-
暖星团
-
热集群
每一种都有不同的成本和回收特性。冷启动包括在另一个区域创建新的 AKS 集群。群集中应用的持久性将从备份中恢复。一旦 AKS 群集调配完毕并开始运行,并且备份恢复到适当的存储目标,应用就可以在群集上启动。这是成本最低的选项,并将具有较高的 RTO 和 RPO。
试点照明场景将包括在另一个容量减少的区域运行 AKS 集群。同样,集群中运行的应用的持久数据将从备份中恢复。在发生灾难时,群集将被扩展,备份将被恢复,应用将被部署。由于群集容量减少,这是一个低成本选项,并且仍然具有较高的 RTO 和 RPO。
暖集群场景包括在另一个已经运行应用的区域运行完全配置的 AKS 集群。某些类型的存储复制服务可能存在几分钟或几小时的延迟。恢复只需将面向公众的 DNS 条目切换到热站点。由于群集和数据复制的容量更高,这是一个成本较高的解决方案,但 RTO 和 RPO 都大大降低了。
在热集群场景中,一个完全配置的 AKS 集群在另一个区域运行,应用已经在运行并为请求提供服务。在这种情况下,存储复制解决方案需要接近同步。一个区域出现故障,只需在另一个区域上扩展集群即可处理额外的负载。这是迄今为止成本最高的解决方案,但是对于故障,RTO 和 RPO 接近于零。
每种解决方案都有其优点和缺点;因此,与额外保护的成本相比,应用所有者需要确定其应用的可接受停机时间和数据丢失量。
摘要
在 AKS 中部署应用之前,了解如何正确管理 AKS 资源很重要。AKS 集群操作员的角色是这里的关键。尽管 AKS 是一项受管理的 Kubernetes 服务,但需要提前规划一些管理操作,如扩展、身份和访问、联网、安全、监控和业务连续性规划。
在本章中,您了解了在 AKS 中经常会遇到的常见集群管理操作。我们探讨了如何正确扩展 AKS 集群,AKS 可用的存储选项,以及开始管理 AKS 集群所需的 AKS 网络、访问和身份以及安全概念。然后,我们研究了 Azure Monitor for containers 如何帮助您监控 AKS 资源。最后,我们讨论了 Azure Kubernetes 服务部署的业务连续性和灾难恢复最佳实践。
八、Azure Kubernetes 服务的 Helm 图
部署在 Kubernetes 上的应用通常由多个部分组成。一种常见的做法是将多个组件组合成一个单独的 yaml 文件,该文件将使用带有-f开关的kubectl apply提交给集群。跨多个环境部署同一个应用也很常见,无论这些环境是独立的 Kubernetes 集群还是同一个集群中的不同名称空间。跨多个环境使用单个 yaml 文件和kubectl进行应用部署的方法有几个缺点。Helm 的创建就是为了解决这些缺点。
在本章中,我们将探索 Helm 的用例,以及它如何增强 Kubernetes 上的应用部署体验。我们将在开发和生产场景中回顾在 AKS 集群上安装 Helm 客户端和 Tiller 的过程。然后,我们将深入 Helm 图表的结构——Helm 中应用部署的基本构造。最后,我们将经历在 AKS 中部署和更新 Helm 图版本的过程。在本章结束时,您将对 Helm 有一个坚实的理解,以及它如何与 AKS 一起使用来简化和增强应用部署过程。
Helm 概述
Helm 是一个开源项目,由云本地计算基金会与微软、谷歌、Bitnami 等合作维护。Helm 的主要目标是帮助管理基于 Kubernetes 的应用,包括这些应用的定义、安装和升级。一个有用的方式认为 Helm 是 Kubernetes 的一个包经理。与 apt、yum 或 Chocolatey 一样,Helm 也有包含可以本地复制和安装的包的存储库——本地意思是 Kubernetes。它还可以处理这些应用的升级和删除。
Helm 用于管理 Kubernetes 应用的基本结构是 Helm 图表。该图表以标准化的格式定义了组成应用的组件,这些组件可以在源代码控制中共享和存储。当图表与配置信息结合并部署在 Kubernetes 集群上时,它被称为版本。
用例
Helm 旨在简化 Kubernetes 上的应用管理。在这方面,Helm 简化了几个主要用例。Kubernetes 应用往往由多种资源和组件组成。Helm charts 通过以声明的方式描述组件和依赖关系,帮助您管理这些应用的复杂性。
应用不是静态部署,而是定期更新。Kubernetes 上的更新过程可能会很棘手。Helm 提供了更简单的更新体验,将应用的修订和更新作为一个整体来管理,而不是作为其组成部分。新版本的图表可以包括验证测试、发布过程的定制挂钩,以及一个简单的回滚过程(如果最新的图表有问题的话)。
开发人员试图遵循“不要重复自己”的枯燥原则。Helm 将这一概念扩展到 Kubernetes 应用的部署。掌 Helm 图表可以引用其他图表以获得相关性,例如,单个 web 前端图表可以在一个环境中的多个应用中重复使用。图表的共享可以在公共或私有的存储库中进行,在 Azure Container Registry 的情况下,图表可以存储在与图表所使用的容器相同的注册表中。
优于 Kubectl
Kubectl是管理 Kubernetes 的首选 CLI 工具,Helm 并不打算在所有活动中取代kubectl。事实上,kubectl通常与 Helm CLI 配合使用,用于故障排除、调查和跟踪集群中的应用部署。kubectl和helm都与 Kubernetes API 交互来完成他们的工作。Helm 的优势是可以使用为 Helm 编写的模板,它有几个更高级别的命令,抽象出多个kubectl命令。例如,当使用helm install部署应用时,Helm 软件直接与 Kubernetes API 交互,并以一种需要多个kubectl命令的方式协调集群上的资源部署。
关键组件
为了简化 Kubernetes 应用的管理,Helm 提供了几个组成安装的关键组件。
注意
Helm 当前的主要版本是版本 2。Helm 的第 3 版正处于开发的 alpha 阶段,包含了 Helm 构建方式的几个大的变化。特别是,Tiller 组件将在版本 3 中被删除。为了本章的目的,我们将专门讨论版本 2。
Helm 客户端
Helm 客户端是用 Go 编写的二进制文件,运行在用户的本地机器上或某种 CI/CD 平台上。在那方面,它相当于kubectl。客户端可以安装在多种操作系统上,包括 Windows、MacOS 和 Linux。最新版本的 Helm 客户端二进制文件总是可以在 Helm GitHub 发布页面上找到( https://github.com/helm/helm/releases )。要在本地安装客户端,您可以使用 Chocolately for Windows、Homebrew for Mac 或 Snap for 某些 Linux 发行版。清单 8-1 展示了一个用 Chocolately 在 Windows 机器上安装 Helm 客户端的例子。
#Install the client
$ choco install kubernetes-helm -y
Chocolatey v0.10.3
Installing the following packages:
kubernetes-helm
By installing you accept licenses for the packages.
...
The install of kubernetes-helm was successful.
Software installed to 'C:\ProgramData\chocolatey\lib\kubernetes-helm\tools'
#Check the client version after installation
$ helm version
Client: &version.Version{SemVer:"v2.14.2", GitCommit:"a8b13cc5ab6a7dbef0a58f5061bcc7c0c61598e7", GitTreeState:"clean"}
Listing 8-1Installing the Helm client on a Windows machine
由于我们还没有配置到 Kubernetes 集群的连接,服务器版本将返回一个错误。
Helm 柄
Tiller 是 Helm 的服务器端组件,它接收 Helm 客户端发出的命令,并通过 Kubernetes API 在集群上执行这些命令。Tiller 组件通常部署在 Kubernetes 集群上,它将在那里部署应用,尽管这不是完全必要的。也可以在 Kubernetes 集群之外运行 Tiller 组件。Helm 杆部件主要负责四件事情:
-
监听来自 Helm 客户端的请求
-
将图表和配置信息部署为版本
-
在发布的整个生命周期中跟踪发布
-
从集群中升级或删除版本
Tiller 可以使用带有 RBAC 规则的服务帐户运行,这些规则定义了 Tiller 可以访问哪些名称空间。Tiller 将有能力在 Kubernetes 集群上创建和销毁应用;因此,使用角色来限制 Tiller 实例可以采取的操作是有意义的。在生产环境中,或者实际上在任何非开发环境中,Tiller 应该使用一个具有适当限制的服务帐户来控制它可以在集群中管理哪些资源。
当 Tiller 安装在集群上时,它会创建一个集群内 gRPC 端点,默认情况下该端点未经身份验证。基本上,这意味着集群中的任何进程都可以向 Tiller 端点发出命令,并执行这些命令。对于开发集群来说,这可能是可以接受的。所有其他群集环境都应该努力使用 TLS 来保护 Tiller 端点上的身份验证。当 TLS 与 Tiller 一起启用时,与 Tiller 端点的所有通信都通过可信根证书颁发机构颁发的 TLS 证书进行相互身份验证。
Helm 库
Helm 使用的图表可以存储在存储库中。存储库可以是私有的,也可以是公共的。Helm 项目在他们的 GitHub 网站( https://github.com/helm/charts )上维护着一个官方的公共图表库。这是一个很好的起点来寻找普通应用的官方版本的掌 Helm 图,例如 Wordpress 、 FluentD 和 Jenkins 。
图表存储库只是一个 web 服务器,带有一个index.yaml文件,该文件列出了存储在存储库中的所有图表,以及关于每个图表的一些信息。建立一个 Helm 知识库超出了本书的范围,但是这个过程相对简单,可以使用 ChartMuseum 、 GitHub Pages 或者一个简单的 web 服务器来完成。
Azure Container Registry 也能够存储 Helm 图。本章后面将给出一个使用 ACR 存储 Helm 角图的例子。
云原生应用捆绑包
云原生应用捆绑包(CNAB)是由微软和 Docker 创建的一个开源项目,用于处理应用的打包,这些应用不仅仅利用容器和 Kubernetes 进行部署。例如,一个三层 web 应用可以使用 Azure CosmosDB 提供数据库服务,使用 AKS 提供应用和 web 层,使用 Azure 函数进行业务逻辑处理。CNAB 捆绑包将能够部署和管理所有这些组件。Helm 只关注部署在 Kubernetes 环境中的应用组件。虽然形势仍在变化,CNAB 和赫尔姆完成了两个不同的,相关的目标。
安装 AKS 上的 Helm
正如在 Helm 组件一节中提到的,安装 Helm 有两个基本组件。Helm 客户端运行在本地工作站上,Tiller 服务器端组件运行在 Kubernetes 集群上。要设置 Helm 使用 AKS,需要满足几个要求。
要求
Azure Kubernetes 集群部署时默认启用了 RBAC。要让 Tiller 组件在集群上与 RBAC 一起正常工作,需要创建一个服务帐户并将其与集群角色相关联。对于非开发环境,启用 TLS 也是最佳实践。在接下来的两节中,我们将介绍设置服务帐户和提供必要证书的过程,以便在 Tiller 和 Helm 客户端之间启用 TLS 身份验证。
RBAC 和服务帐户
Kubernetes 中基于角色的访问控制包括几个不同的组件。角色定义了一组动作,被分配的实体可以对集群中的资源执行这些动作。集群有内置的角色,如集群管理、管理、编辑和查看。角色可以是两种类型之一,Role是特定于名称空间的,ClusterRole是集群范围的。通过使用RoleBinding或ClusterRoleBinding类型,可以将角色分配给服务帐户、用户和组。在清单 8-2 中,我们定义了一个用于 Tiller 的服务帐户。
apiVersion: v1
kind: ServiceAccount
metadata:
name: tiller
namespace: kube-system
Listing 8-2Definition for a Tiller service account
创建服务帐户后,可以为其分配角色。在清单 8-3 中,我们将使用ClusterRoleBinding类型将 tiller 服务帐户与内置的ClusterRole cluster-admin 关联起来。
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: tiller
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: tiller
namespace: kube-system
Listing 8-3Binding the cluster-admin role to the Tiller service account
根据环境的需求,还可以创建一个定制的Role并使用RoleBinding将其绑定到一个特定的名称空间,Tiller 将被允许在该名称空间中部署资源。出于我们的目的,Tiller 将被允许跨集群中的所有名称空间部署资源。在清单 8-4 中,这两个配置都已经保存到文件helm-rbac.yaml,中,并且kubectl apply正在将要配置 Tiller 的 AKS 集群上运行。
$ kubectl apply -f helm-rbac.yml
serviceaccount "tiller" created
clusterrolebinding.rbac.authorization.k8s.io "tiller" created
Listing 8-4Binding the cluster-admin role to the Tiller service account
Tiller 的服务帐户现在可用,并绑定到集群管理角色。
TLS 注意事项
部署完整的公钥基础设施(PKI)超出了本书的范围。事实上,整本书都是关于这个话题的。如果您的组织已经建立了内部 PKI,那么利用它是有意义的。在下面的例子中,我们将使用openssl来创建证书。这里有三个证书:根证书颁发机构、tiller 证书和 helm 客户端证书。tiller 和 helm 客户端证书将由根 CA 证书批准和签名,Tiller 和 Helm 将被配置为信任根 CA 证书。由于他们都信任根 CA,他们将信任由根 CA 签署的证书,这意味着 Tiller 和 Helm 将信任彼此的证书是有效的。
清单 8-5 中的所有命令将在当前工作目录中创建证书和密钥。
#First we must create the root CA.
#Big thanks to this article: https://medium.com/google-cloud/install-secure-helm-in-gke-254d520061f7
$SUBJECT = "/C=US/ST=Pennsylvania/L=Springfield/O=IAKS, Inc./OU=IT/CN=iaks.sh"
#Create a CA key
openssl genrsa -out ca.key.pem 4096
#Creata a CA certificate
openssl req -key ca.key.pem -new -x509 -days 7300 -sha256 -out ca.cert.pem -extensions v3_ca -subj $SUBJECT
#Then we need to create the certificate request for the Tiller certificate and process it.
#Create a key for the tiller cert
openssl genrsa -out tiller.key.pem 4096
#Create a new certificate request
openssl req -new -sha256 -key tiller.key.pem -out tiller.csr.pem -subj $SUBJECT
#Create the certificate from the request
openssl x509 -req -days 365 -CA ca.cert.pem -CAkey ca.key.pem -CAcreateserial -in tiller.csr.pem -out tiller.cert.pem
#Finally, we need to create the certificate request for the Helm client certificate and process it.
#Create a key for the helm client
openssl genrsa -out helm.key.pem 4096
#Create a new certificate request
openssl req -new -sha256 -key helm.key.pem -out helm.csr.pem -subj $SUBJECT
#Create the certificate from the request
openssl x509 -req -days 365 -CA ca.cert.pem -CAkey ca.key.pem -CAcreateserial -in helm.csr.pem -out helm.cert.pem
Listing 8-5Creating TLS certificates for Tiller and Helm communication
现在我们有了所有必需的证书和它们匹配的私钥。在当前目录中,我们应该看到清单 8-6 中的文件。
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 7/16/2019 1:39 PM 2070 ca.cert.pem
-a---- 7/16/2019 1:39 PM 3298 ca.key.pem
-a---- 7/16/2019 1:40 PM 18 ca.srl
-a---- 7/16/2019 1:40 PM 1946 helm.cert.pem
-a---- 7/16/2019 1:40 PM 1736 helm.csr.pem
-a---- 7/16/2019 1:40 PM 3298 helm.key.pem
-a---- 7/16/2019 1:40 PM 1946 tiller.cert.pem
-a---- 7/16/2019 1:40 PM 1736 tiller.csr.pem
-a---- 7/16/2019 1:39 PM 3294 tiller.key.pem
Listing 8-6Directory listing of TLS certificates and private keys
将使用 Helm 客户端进行连接的每个用户都应该获得他们自己的证书,包括在 CI/CD 流水线中运行的任何自动化帐户。在生产场景中,证书的颁发将通过证书颁发机构来处理。虽然可以使用第三方证书颁发机构,但在这种情况下,内部 CA 更有意义。Kubernetes 集群可能会使用内部名称,并由内部用户访问。没有必要花钱购买可信第三方的证书。
init 头盔
一旦 Tiller 安装的先决条件得到满足,下一步就是运行命令helm init来初始化集群。在开发环境中,只需使用命令暗示的所有默认值运行helm init就足够了。因为我们将使用服务帐户和证书,所以我们需要给helm init命令添加参数。
清单 8-7 中的命令使用 tiller 服务帐户,并安装 tiller 私钥、证书和根 CA 证书。此外,Tiller 的证书信息默认保存在ConfigMap中。由于信息的敏感性,最佳实践是覆盖默认设置,而使用一个Secret类型的资源来保存数据。
$ helm init /
--override 'spec.template.spec.containers[0].command={/tiller,--storage=secret}' /
--tiller-tls /
--tiller-tls-cert ".\tiller.cert.pem" /
--tiller-tls-key ".\tiller.key.pem" /
--tiller-tls-verify /
--tls-ca-cert ".\ca.cert.pem" /
--service-account tiller
Listing 8-7Initializing Tiller on the AKS cluster
蒂勒是作为一个部署安装在 Kubernetes。默认情况下,它在一个副本集中运行一个 pod,并包含一个与ClusterIP相关联的服务。pod 和服务都在清单 8-8 中进行了描述。
$ kubectl describe pod tiller-deploy-6656966795-7sxqx --namespace kube-system
Name: tiller-deploy-6656966795-7sxqx
Namespace: kube-system
Priority: 0
PriorityClassName: <none>
Node: aks-agentpool-28083664-0/10.240.0.4
Start Time: Tue, 16 Jul 2019 14:01:20 -0400
Labels: app=helm
name=tiller
pod-template-hash=6656966795
Annotations: <none>
Status: Running
IP: 10.244.0.8
Controlled By: ReplicaSet/tiller-deploy-6656966795
Containers:
tiller:
Container ID: docker://fd05f519da5911b07e0d2aa476b0c9661fe3181ee63a043ca5188eb675bbb64b
Image: gcr.io/kubernetes-helm/tiller:v2.14.2
Image ID: docker-pullable://gcr.io/kubernetes-helm/tiller@sha256:be79aff05025bd736f027eaf4a1b2716ac1e09b88e0e9493c962642519f19d9c
Ports: 44134/TCP, 44135/TCP
Host Ports: 0/TCP, 0/TCP
Command:
/tiller
--storage=secret
State: Running
Started: Tue, 16 Jul 2019 14:01:32 -0400
Ready: True
Restart Count: 0
Liveness: http-get http://:44135/liveness delay=1s timeout=1s period=10s #success=1 #failure=3
Readiness: http-get http://:44135/readiness delay=1s timeout=1s period=10s #success=1 #failure=3
Environment:
TILLER_NAMESPACE: kube-system
TILLER_HISTORY_MAX: 0
TILLER_TLS_VERIFY: 1
TILLER_TLS_ENABLE: 1
TILLER_TLS_CERTS: /etc/certs
Mounts:
/etc/certs from tiller-certs (ro)
/var/run/secrets/kubernetes.io/serviceaccount from tiller-token-2dbcn (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
tiller-certs:
Type: Secret (a volume populated by a Secret)
SecretName: tiller-secret
Optional: false
tiller-token-2dbcn:
Type: Secret (a volume populated by a Secret)
SecretName: tiller-token-2dbcn
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
$ kubectl describe svc tiller-deploy --namespace kube-system
Name: tiller-deploy
Namespace: kube-system
Labels: app=helm
name=tiller
Annotations: <none>
Selector: app=helm,name=tiller
Type: ClusterIP
IP: 10.0.84.117
Port: tiller 44134/TCP
TargetPort: tiller/TCP
Endpoints: 10.244.0.8:44134
Session Affinity: None
Events: <none>
Listing 8-8Tiller pod and service details
运行初始化后,可以通过运行清单 8-9 中的命令来测试从 Helm 客户端到 Tiller 的连接。
$ helm version --tls --tls-ca-cert ca.cert.pem /
--tls-cert helm.cert.pem --tls-key helm.key.pem
Client: &version.Version{SemVer:"v2.14.2", GitCommit:"a8b13cc5ab6a7dbef0a58f5061bcc7c0c61598e7", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.14.2", GitCommit:"a8b13cc5ab6a7dbef0a58f5061bcc7c0c61598e7", GitTreeState:"clean"}
Listing 8-9Testing helm client connectivity to Tiller
在该命令中,我们指定我们想要使用 TLS,并且还传递了 CA 证书、 helm 客户端证书和 helm 客户端密钥。显然,我们不想在每次运行 helm 命令时都指定这些选项。当使用--tls标志时,helm 客户端将在用户主目录的.helm目录中查找 TLS 文件。清单 8-10 中的命令会将文件复制到正确的路径,并提供 helm 客户端所需的文件名。
copy ca.cert.pem "~\.helm\ca.pem"
copy helm.cert.pem "~\.helm\cert.pem"
copy helm.key.pem "~\.helm\key.pem"
Listing 8-10Copying
the helm TLS certs and keys to the .helm directory
复制这些文件后,只需在运行 helm 客户端命令时指定--tls。如果命令中没有设置--tls标志,那么 helm 客户端将会无限期挂起。
Helm 柄服务启动并运行,准备接受 Helm 柄命令。现在是时候构建一个图表提交给 Tiller 了。
头盔图表
Helm 图表是 Helm 用来部署应用的基本结构。该图表与配置设置相结合,并提交给 Tiller。Tiller 将把图表和设置合成到一个版本中,并在 Kubernetes 集群上提供该版本。图表是文件和目录的明确集合。有些文件和目录是必需的,比如Chart.yaml文件。根据图表,其他文件和目录是可选的。
在本章的剩余部分,我们将引用一个名为 iaks 的现有图表,该图表部署了一个投票应用,它具有 node.js 前端和 redis 后端。
图表内容
清单 8-11 显示了 Helm 图表的标准文件和文件夹结构。所需文件以粗体显示。
ChartName (parent directory)
Listing 8-11Standard chart file and folder structure
-
Chart.yaml :包含关于图表的信息
-
许可证:图表的人类可读许可证
-
README.md:人类可读的降价文件
-
requirements.yaml:图表依赖列表
-
values.yaml :图表的默认配置值
-
图表:该图表所依赖的图表目录
-
模板:模板目录
-
templates/NOTES.txt:带有用法说明的可读文件
虽然图表和模板目录不是必需的,但它们是保留给 Helm 使用的。添加到图表中的任何其他文件都将包括在内,但不一定有任何特殊意义。
清单 8-12 显示了 iaks 图表的结构。
C:.
│ .helmignore
│ Chart.yaml
│ values.yaml
│
└───templates
NOTES.txt
vote-back-deployment.yaml
vote-back-service.yaml
vote-front-deployment.yaml
vote-front-service.yaml
Listing 8-12iaks chart structure
图表. yaml
Chart.yaml文件定义了 Helm 将用来解释图表的值。列表 8-13 包含潜在的文件条目,所需条目以粗体显示。
-
apiVersion :现在总是设置为 v1
-
名称:图表的名称
-
版本:该图表的 SemVer 2 版本
-
kubeversion:永远范围相容于 kubeversion
-
描述:描述图表及其目的的单句话
-
关键词:关键词列表
-
主页:项目主页 URL
-
来源:项目的源代码 URL
-
维护者:项目维护者的列表
-
引擎:模板引擎的名称(默认为 gotpl)
-
icon: SVG or PNG 影像网址
-
appVersion:应用的版本号
-
已弃用:布尔值,指示图表是否已弃用
-
tillerVersion:兼容 Tiller 版本的永久范围
file entries
Listing 8-13Chart.yaml
清单 8-14 显示了 iaks 图表的Chart.yaml文件的内容。
apiVersion: v1
appVersion: "1.0"
description: A Helm chart for deploying the IAKS Voting App
name: iaks
version: 0.1.0
Listing 8-14iaks Chart.yaml contents
请注意,appVersion和version条目并不相同。图表的版本可能会改变,但应用的版本不会改变。
价值观. yaml
values.yaml文件定义了项目中图表和模板使用的默认设置。所有图表和模板都可以访问顶层values.yaml文件中定义的设置。也可以在模板和图表子目录中提供values.yaml文件。在部署图表时,可以通过提供一个额外的带有值的 yaml 文件或者使用--set标志并在命令行提供设置来覆盖Values.yaml文件中定义的设置。
模板和图表将通过使用名称空间样式引用符号来引用在values.yaml中定义的设置。名称空间以代表名称空间顶部的.开始,然后其他字符串向下钻取文件中的值。例如,values.yaml 文件可能有一个类似于清单 8-15 中的条目。
image:
repository: iaks/azure-voting-app
tag: v1-alpine
Listing 8-15Example values.yaml snippet
模板将通过使用符号.Values.image.tag来引用标签。
除了文件或命令行提供的值之外,图表和模板还可以访问预定义的值。这些包括关于版本、图表和文件的信息。Helm 文档中提供了预定义值的详尽列表。
清单 8-16 显示了 iaks 图表的values.yaml文件的内容。
# Default values for iaks.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
voteBack:
replicaCount: 1
appName: azure-vote-back
image:
repository: redis
tag: 5.0.5
pullPolicy: IfNotPresent
ports:
name: redis
port: 6379
service:
port: 6379
voteFront:
replicaCount: 1
appName: azure-vote-front
image:
repository: iaks/azure-voting-app
tag: v1-alpine
pullPolicy: IfNotPresent
ports:
name: http
port: 80
vote1Value: "Chocolate"
vote2Value: "Peanut Butter"
title: "IAKS Voting App"
service:
type: LoadBalancer
port: 80
targetPort: http
name: http
Listing 8-16iaks values.yaml contents
许可证
LICENSE文件是以纯文本格式编写的,旨在展示图表中安装的应用所包含的软件许可证。Helm 客户端不读取许可证。如果用户选择使用图表,它就在那里供用户解析和默认。
iaks 图表没有许可证文件。
README.md
README.md是用 markdown 写的,旨在帮助用户正确使用图表。至少,它应该描述图表的作用、运行图表的先决条件、包含在values.yaml文件中的设置以及默认设置。本文档中还应包含部署图表的任何其他有用信息。如果图表在某些存储库上发布,将显示README文件。
如果有一些快速入门说明需要在部署后显示给用户,它们可以包含在模板目录下的NOTES.txt文件中。NOTES.txt文件将被评估为模板,然后显示在命令行上。
清单 8-17 显示了从 iaks 图表README.md中截取的文本。
# IAKS Voting App
Example application for the Helm chapter of the Introducing Azure Kubernetes Service book.
## Install Chart
To install the IAKS Chart into your Kubernetes cluster :
Clone the chart down to your local file system.
```bash
helm install --namespace "iaks" --name "iaksv1" ./iaks
...
Listing 8-17iaks README.md contents
#### 需求. yaml
正在定义的图表可能使用其他图表作为其部署的一部分。这些图表可以手动复制到*图表*目录并保存在那里。对于需要严格控制依赖图表的版本和内容的团队来说,将它们直接复制到*图表*目录中可能是有意义的。但是,这使得图表是静态的,需要手动更新。
当运行`helm dependency update`命令时,包含在`requirements.yaml`文件中的图表被动态提取。由此产生的图表以压缩图表的形式存储在*图表*目录中。在 requirements.yaml 文件中,每个图表都在依赖关系中列出,如清单 8-18 所示。
dependencies:
- name: chart_name version: 1.2.3 repository: mycharts.com/charts
Listing 8-18Example requirements.yaml entry
当新版本可用时,可以在依赖关系中更新版本号,并再次运行`helm dependency update`命令。这将提取图表的新版本,并将其存储在*图表*目录中。
有几个附加的可选字段可以添加到依赖项列表中。这些可选字段用于更高级的部署情况,您可能在初次尝试使用 Helm 时不需要它们。
如果一个应用需要同一图表的多个副本,或者同一图表的不同版本,可以包括的`alias`字段。`alias`字段将改变下载图表的名称以匹配别名值。
`condition`字段指定了顶层父`values.yaml`中的 *yaml* 实体的逗号分隔列表,每个实体解析为一个布尔值。将该值设置为`false`将阻止图表作为依赖项包含在图表中。
`tags`字段是与图表相关联的标签列表。在顶层父值中,可以使用标签和一个布尔值来启用或禁用每个`tag`。如果某个依赖图表的任何`tag`被启用,它将被包括在依赖关系中。
**iaks** 图表没有 requirements.yaml 文件。
#### 图表目录
*图表*目录将包含要作为父图表的依赖项包含的图表。正如 Requirements.yaml 一节中提到的,图表可以通过手动复制文件来填充,或者通过使用`requirements.yaml`文件来动态填充。包含在*图表*目录中的图表可以是未打包的图表,也可以是图表档案。如果使用归档文件,每个图表应该是它自己单独的文件;如果图表被解压缩,每个图表应该是它自己的目录。
**iaks** 图表不使用任何其他图表作为依赖项。
#### 模板目录
*模板*目录包含 Helm 图模板。当 Helm 为一个版本渲染图表时,它会评估包含在*模板*文件夹中的所有文件。模板文件的大部分功能都使用 Go 模板语言。Helm 还借用了 Sprig 库中的一些函数,包括一些 Helm 特有的特殊函数。
*模板*目录中的文件用于在 yaml 中创建可行的 Kubernetes 定义文件。模板语言用于操作文件内容,动态生成有效的 yaml 文件,合并由`values.yaml`文件提供的值或由用户在运行`helm install`时提供的值。
**iaks** 图表有前端和后端部署和服务的模板,以及一个`NOTES.txt`。我们将在处理模板函数的部分更详细地检查这些文件。
### 图表存储库
Helm 处理存储在存储库中的图表。helm 客户端有一个命令子集,用于处理本地存储的图表和远程存储库。让我们从查看默认安装的 Helm 中可用的图表库列表开始,如清单 8-19 所示。
$ helm repo list NAME URL stable kubernetes-charts.storage.googleapis.com local http://127.0.0.1:8879/charts incubator storage.googleapis.com/kubernetes-…
Listing 8-19Listing of Helm repositories
如你所见,Helm 从官方 Helm 库的*马厩*和*孵化器*图表开始。它还创建了一个监听端口 8879 的本地存储库。默认情况下,*本地*存储库没有图表。我们可以通过运行清单 8-20 中的命令来确认这一点。
$ helm search /local No results found
Listing 8-20Contents of the local repository
对清单 8-21 中所示的*稳定*库运行相同的命令会产生大约 278 个图表!
$ helm search stable/ NAME CHART VERSION APP VERSION DESCRIPTION stable/acs-engine-autoscaler 2.2.2 2.1.1 DEPRECATED Scales worker nodes within agent pools stable/aerospike 0.2.7 v4.5.0.5 A Helm chart for Aerospike in Kubernetes stable/airflow 2.8.2 1.10.2 Airflow is a platform to programmatically author, schedul...
Listing 8-21Contents of the stable repository
图表列表缓存在本地。要更新存储库的内容,可以执行命令`helm repo update`。将图表打包并推送到存储库的过程将在本章的后面介绍。
### 部署流程
将 Helm chart 部署为 Kubernetes 集群上的运行应用是通过命令`helm install`执行的。install 命令允许以附加 yaml 文件的形式或使用命令中的`--set`标志提交值。运行时提交的值中的设置与图表中的`values.yaml`文件合并,生成一个更新的`values.yaml`文件,其中包含将在安装过程中使用的最终配置数据。
例如,假设`helm install -f myvalues.yaml ./mychart`正在运行。图表中已有的`values.yaml`文件的内容如清单 8-22 所示。
voteBack: replicaCount: 1 appName: azure-vote-back image: repository: redis tag: 5.0.5 pullPolicy: IfNotPresent ports: name: redis port: 6379
Listing 8-22values.yaml file with default configuration
myvalues.yaml 文件的内容如清单 8-23 所示。
voteBack: replicaCount: 2 label: mylabel
Listing 8-23Contents of myvalues.yaml
这两个文件将合并在一起,`myvalues.yaml`文件的内容优先于`values.yaml`文件的内容。清单 8-24 有结果文件的内容。
voteBack: replicaCount: 2 label: mylabel appName: azure-vote-back image: repository: redis tag: 5.0.5 pullPolicy: IfNotPresent ports: name: redis port: 6379
Listing 8-24Contents of the new values.yaml file
Tiller 接受图表和值,并创建一组有效的 Kubernetes 定义,这些定义通过 Kubernetes API 提交给集群。按照 Helm 的说法,提交的部署被称为*发布*。
Helm 版本包含几条描述版本的信息,包括以下内容:
* **AppVersion** :基于 Chart.yaml 中 AppVersion 设置的版本号
* **图表**:Chart . YAML 中附加版本号的图表名称
* **Name** :安装时给版本起的名字
* **名称空间**:安装该版本的名称空间
* **修订版**:第一次安装时从 1 开始,每次执行更新或回滚时递增
* **状态**:版本的当前状态,通常为已经完成安装的版本部署
* **更新**:最后一次版本的某些方面发生变化
可以通过运行`helm list`或缩短版本`helm ls`来检索当前的发布列表。默认情况下,该命令只显示状态为`DEPLOYED`的版本。可以添加标志`--all`来查看任何状态的所有发布。
可以使用以下命令之一更新 Helm 版本:
* `helm delete`:从集群中删除发布,并将发布状态更改为已删除
* `helm upgrade`:用提交的值升级当前版本
* `helm rollback`:将当前版本恢复为提交的修订号
### 创建 Helm 图
有许多优秀的图表已经可以作为创建自己的 Helm 图的起点。Helm 还包括从预定义模板开始绘制图表的工具。
#### 掌 Helm 创建
Helm 使为新图表设置文件和目录结构变得简单。`helm create`命令将在指定的路径下创建一个新的目录,并在该目录下创建几个 Helm 图的必需和可选文件。命令`helm create iaks-chart`将创建一个名为 iaks-chart 的新 Helm 图。
该命令在当前路径中创建一个名为 iaks-chart 的目录,并用清单 8-25 中所示的文件和目录填充它。
C:. │ .helmignore │ Chart.yaml │ values.yaml │ ├───charts └───templates │ deployment.yaml │ ingress.yaml │ NOTES.txt │ service.yaml │ _helpers.tpl │ └───tests test-connection.yaml
Listing 8-25Contents of the new iaks-chart Helm chart
这些文件包含一个基本的 *nginx* 应用,包括一个入口控制器,一个用于*nginx*pod 的服务,以及一个*nginx*pod 的部署。它还包括一个测试来验证 *nginx* 应用的部署是否成功。
#### 模板功能
helm 图表中的模板结合使用了 Go 模板语言函数、Sprig 函数和 Helm 中的自定义函数。这些函数获取模板文件的内容和安装期间提交的值,并呈现出有效的 Kubernetes 定义。
Go 模板语言是一个高级主题,超出了本章的范围,但是这里有一些入门的指导。
* 模板文件中应该由模板引擎评估的任何值都将以双花括号{{ }}开始和结束。
* value.yaml 文件中的值使用命名空间路径表示法引用,例如. Values.dockerTag。
* Helm 有一本关于模板开发入门的入门书。你可以在这个链接了解更多( [`https://helm.sh/docs/chart_template_guide/#getting-started-with-a-chart-template`](https://helm.sh/docs/chart_template_guide/%2523getting-started-with-a-chart-template) )。
看一个例子将有助于说明模板语言是如何使用的。清单 8-26 显示了 **iaks** 图表中`vote-back-service.yaml`文件的内容。
apiVersion: v1 kind: Service metadata: name: {{ .Values.voteBack.appName }} spec: ports: - port: {{ .Values.voteBack.service.port }} selector: app: {{ .Values.voteBack.appName }}
Listing 8-26Contents of the new vote-back-service.yaml file
`{{ }}`调用模板引擎来评估双花括号中的内容。在清单中,`metadata.name`正在评估表达式`.Values.voteBack.appName`。指的是发布提交的`values.yaml`文件中的设置。该设置的默认设置是 *azure-vote-back* ,因此模板引擎将呈现文件的这一部分,如清单 8-27 所示。
metadata: name: azure-vote-back
Listing 8-27Rendered value for metadata.name
可以将函数添加到流水线中的评估中,以操作该值。例如,假设名称需要全部小写。清单 8-28 展示了如何通过流水线将值传递给`lower`来操作文本。
metadata: name: {{ .Values.voteBack.appName | lower }}
Listing 8-28Using the lower function on a value
这是一个使用模板函数的简单例子。根据应用的需要,更复杂的评估是可能的。
#### 图表测试
Helm 不知道图表中定义的应用应该做什么。如果发布的所有组件都创建成功,那么 Helm 认为发布是成功的。图表测试为用户提供了一种验证应用组件功能是否正常的方法。它们也可以在自动化环境中使用,以验证流水线中的发布。
图表测试是驻留在*模板*目录中的模板文件,或者更常见的是驻留在*模板*目录中的*测试*子目录中。每个测试都是一个 *pod* 定义。pod 应该运行一些操作,然后以一个值退出,`0`被认为是成功,任何其他值被认为是失败。pod 定义可以是单个 *yaml* 文件的一部分,也可以分成多个 *yaml* 文件,每个测试一个。
Helm 有两个指示测试是否成功的测试挂钩,`test-success`和`test-failure`。这些钩子被添加到吊舱的注释中,如清单 8-29 所示。
metadata: annotations: "helm.sh/hook": test-success
Listing 8-29Helm test hooks
注释向 Helm 表明这些 pod 定义是测试,而不是应用的一部分。通过使用要测试的发布名称运行`helm test`来调用测试。
#### 打包图表
一旦图表可供使用,就可以打包并上传到图表存储库中。打包图表会创建该图表的版本化存档。图表的内容被压缩成一个 tgz 文件。可以通过使用`helm package`命令并将该命令指向包含图表的目录来打包图表。
清单 8-30 显示了包装 **iaks** 图表的过程。
$ helm package .\iaks
Successfully packaged chart and saved it to: C:\gh\Introducing-Azure-Kubernetes-Service\Helm\aks\iaks-0.1.0.tgz
Listing 8-30Packaging the iaks chart
文件的名称是图表名称和图表版本的组合。这两个值都可以在`Chart.yaml`文件中找到。
将图表存档上传到存储库的过程将取决于存储库的类型。上传图表时,必须更新存储库的 index.yaml 文件,以便将它包含在存储库搜索和列表中。Azure Container Registry (ACR)可以托管打包的 helm 图表。第一步是登录到一个现有的 ACR 存储库,并将其添加为 Helm 的存储库,如清单 8-31 所示。
az acr helm repo add "iaks0" has been added to your repositories
$ helm repo list NAME URL stable kubernetes-charts.storage.googleapis.com local http://127.0.0.1:8879/charts incubator storage.googleapis.com/kubernetes-… iaks0 iaks0.azurecr.io/helm/v1/rep…
Listing 8-31Adding the ACR repo to Helm
一旦存储库被添加到 Helm 中,将图表存档推送到 ACR 存储库就很简单了,如清单 8-32 所示。然后,必须更新存储库的本地索引,以便它将显示在搜索结果中。
$ az acr helm push .\iaks-0.1.0.tgz { "saved": true }
$helm repo update Hang tight while we grab the latest from your chart repositories... ...Skip local chart repository ...Successfully got an update from the "incubator" chart repository ...Successfully got an update from the "iaks0" chart repository ...Successfully got an update from the "stable" chart repository Update Complete.
$ helm search iaks0 NAME CHART VERSION APP VERSION DESCRIPTION iaks0/iaks 0.1.0 1.0 A Helm chart for deploying the IAKS Voting App
Listing 8-32Pushing a package to the ACR repo
图表存档现在可供任何其他具有访问权限的用户通过 ACR 存储库使用。
### 部署 Helm 图
使用`helm install`命令展开 Helm 图。该命令将获取图表、默认值和命令中提交的值,并将它们发送给 Tiller。Tiller 会将它们合成为一个版本,并在 Kubernetes 集群上实例化该版本。
#### Helm 安装
清单 8-33 显示了在 aks 集群的*默认*名称空间中安装 **iaks** 图表的过程。
$ helm install --tls --name iaksv1 ./iaks NAME: iaksv1 LAST DEPLOYED: Wed Jul 17 11:40:30 2019 NAMESPACE: default STATUS: DEPLOYED
RESOURCES: ==> v1/Pod(related) NAME READY STATUS RESTARTS AGE azure-vote-back-78d97d47df-2hjbr 0/1 ContainerCreating 0 0s azure-vote-front-948444d79-m2ms2 0/1 ContainerCreating 0 0s
==> v1/Service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE azure-vote-back ClusterIP 10.0.40.25 6379/TCP 1s azure-vote-front LoadBalancer 10.0.212.114 80:30829/TCP 0s
==> v1beta1/Deployment NAME READY UP-TO-DATE AVAILABLE AGE azure-vote-back 0/1 1 0 0s azure-vote-front 0/1 1 0 0s
NOTES: 1. Get the application URL by running these commands: NOTE: It may take a few minutes for the LoadBalancer IP to be available. You can watch the status of by running 'kubectl get --namespace default svc -w azure-vote-front' export SERVICE_IP=SERVICE_IP:80
Listing 8-33Installing the iaks chart
安装过程显示正在创建的资源,并打印出 templates 文件夹中呈现的`NOTES.txt`文件。`NOTES.txt`文件由模板引擎评估,可以为应用的开始提供简单的指导。
图 8-1 显示了负载均衡器的外部 IP 完成配置后可用的网页。

图 8-1
投票应用网页
#### 掌 Helm 状态
命令`helm` `status`将获得一个发布的当前状态。清单 8-34 显示了 *iaksv1* 版本的当前状态。
$ helm status --tls iaksv1 LAST DEPLOYED: Wed Jul 17 11:40:30 2019 NAMESPACE: default STATUS: DEPLOYED
RESOURCES: ==> v1/Pod(related) NAME READY STATUS RESTARTS AGE azure-vote-back-78d97d47df-2hjbr 1/1 Running 0 4m36s azure-vote-front-948444d79-m2ms2 1/1 Running 0 4m36s
==> v1/Service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE azure-vote-back ClusterIP 10.0.40.25 6379/TCP 4m37s azure-vote-front LoadBalancer 10.0.212.114 40.85.173.41 80:30829/TCP 4m36s
==> v1beta1/Deployment NAME READY UP-TO-DATE AVAILABLE AGE azure-vote-back 1/1 1 1 4m36s azure-vote-front 1/1 1 1 4m36s
NOTES: 1. Get the application URL by running these commands: NOTE: It may take a few minutes for the LoadBalancer IP to be available. You can watch the status of by running 'kubectl get --namespace default svc -w azure-vote-front' export SERVICE_IP=SERVICE_IP:80
Listing 8-34Status of the iaksv1 release
该状态提供了与初始安装基本相同的信息,包括`NOTES.txt`部分。
### 更新版本
在版本的生命周期中,可能需要更新图表、应用或设置。命令`helm upgrade`用于执行这样的更新。清单 8-35 显示了用投票按钮的新值更新 *iaksv1* 版本的过程。
$ helm upgrade --tls --set voteFront.vote1Value=Cats,voteFront.vote2Value=Dogs iaksv1 ./iaks Release "iaksv1" has been upgraded. LAST DEPLOYED: Wed Jul 17 11:50:14 2019
Listing 8-35Upgrade of the iaksv1 release
为简洁起见,输出被截断。通过运行清单 8-36 中的`helm ls`,我们可以检索发布的状态,并看到修订号已经增加。
$ helm ls --tls iaksv1 NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE iaksv1 2 Wed Jul 17 11:50:14 2019 DEPLOYED iaks-0.1.0 1.0 default
Listing 8-36Listing of the iaksv1 release
查看图 8-2 中更新的网页,显示按钮的更新内容。

图 8-2
投票应用网页已更新
也可以通过使用`helm rollback`命令回滚到先前版本。清单 8-37 显示了回滚一个发布的输出。
$ helm rollback --tls iaksv1 1 Rollback was a success.
$ helm ls --tls iaksv1
NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE iaksv1 3 Wed Jul 17 11:54:45 2019 DEPLOYED iaks-0.1.0 1.0 default
Listing 8-37Rollback of the iaksv1 release
通过查看版本的修订号,我们可以看到修订现在是在`3`而不是`1`。无论版本是升级还是回滚,版本号都会随着版本的改变而增加。
再次查看图 8-3 中的网站,我们可以看到投票按钮已经恢复到之前的值。

图 8-3
投票应用网页回滚
### 删除版本
在每个版本的生命周期中都有一个不再需要它的时候。删除发布的命令是`helm delete`。清单 8-38 显示了删除 iaksv1 的输出。
$ helm delete --tls iaksv1 release "iaksv1" deleted
Listing 8-38Delete of the iaksv1 release
Kubernetes 集群中的资源将被移除,但是发布版并没有完全消失。清单 8-39 显示了所有的版本,包括被删除的版本。
$ helm ls --tls --all NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE iaksv1 3 Wed Jul 17 11:54:45 2019 DELETED iaks-0.1.0 1.0 default
Listing 8-39Listing of all releases
可以使用`helm rollback`来撤销从 Kubernetes 集群中删除发布。
### 注意
Helm 不会从删除的版本中恢复确切的 pod 和卷。Helm 将只重新部署 rollback 命令中指定的版本。在删除一个版本的过程中,任何没有通过其他方式保存的数据都将丢失。
为了从 Helm 杆上永久移除释放,必须使用清单 8-40 中所示的`--purge`标志。
$ helm delete --tls iaksv1 --purge release "iaksv1" deleted
Listing 8-40Purge of the iaksv1 release
## CI/CD 集成
持续集成和持续交付——通常缩写为 CI/CD——是创建自动化流水线的实践,该流水线将代码从开发人员的提交移动到部署到一个或多个环境中。Helm 可以整合到 CI/CD 流程中,作为一种工具,用于向 Kubernetes 集群部署新版本或更新现有版本。
### 自动化部署
当代码被提交到存储库时,它可能会引发一系列事件。使用我们的 **iaks** 图表示例,该图表利用了容器映像 *iaks/azure-voting-app。*当开发人员提交构建该映像的`Dockerfile`的新版本时,可能会触发一个流水线。一旦映像被更新并通过流水线中的必要测试, **iaks** Helm 图可以用新的映像版本进行测试。假设所有的测试都通过了, **iaks** Helm chart 可以被更新以使用新的映像作为`values.yaml`文件中的默认标签。
图 8-4 展示了潜在的流水线。

图 8-4
潜在的 CI/CD 渠道
### 测试 Helm 图
Helm 图可以用几种方法测试。可以使用`helm lint`命令运行一个测试来验证图表在语法上是正确的。清单 8-41 显示了对照 **iaks** 图表运行`helm lint`的输出。
$ helm lint .\iaks
==> Linting .\iaks
[INFO] Chart.yaml: icon is recommended
1 chart(s) linted, no failures
Listing 8-41Linting the iaks chart
输出应该是人类可读的,但是在将图表转移到下一个测试阶段之前,它可以被机器解析以查看是否有任何错误或警告。
下一个测试步骤可能是用几个不同的可能值在本地呈现模板,并验证生成的 Kubernetes 定义是有效的。清单 8-42 显示了针对 iaks 图表中的模板运行`helm template`的输出。为简洁起见,输出被截断。
helm template .\iaks\
Source: iaks/templates/vote-back-service.yaml
apiVersion: v1 kind: Service metadata: name: azure-vote-back spec: ports: - port: 6379 selector: app: azure-vote-back
Listing 8-42Helm template rendering
这个命令的输出可以通过流水线传输到`kubectl`来验证内容。
$ helm template .\iaks | kubectl apply --dry-run --validate -f -
可以对输出进行错误扫描,以确定是否有任何 Kubernetes 定义无效。
一旦图表根据需求得到验证,就可以对其进行进一步的测试,以验证应用是否正常运行。一些测试可以使用本章前面提到的 Helm 测试功能嵌入到图表中。除了 Helm 执行的基本测试之外,大多数自动化流水线还会对应用执行额外的测试。Helm 图中包含的测试旨在测试基本功能,而不是更高级的场景。
有一个与 Helm 相关的开源项目,专门围绕测试 Helm 图。这个项目叫做*图表测试*,可以在 GitHub ( [`https://github.com/helm/chart-testing`](https://github.com/helm/chart-testing) )上找到。*图表测试*软件能够执行林挺、模板验证,甚至可以针对某个版本运行图表中包含的 Helm 测试。
### 无人值守 Helm 图安装
在 Kubernetes 集群上安装 Helm 图可以以自动化的方式执行。用于定制给定版本的值可以作为 CI/CD 流水线中的工件生成,然后作为文件或通过`--set`标志传递给 Helm 客户端。
相同的过程可用于执行现有版本的升级,包括随后运行 Helm 测试,并准备在测试失败或发现其他问题时运行回滚操作。流水线应在升级前记录 Helm 版本的当前修订号,以便在必要时协助回滚过程。
### 将 Helm 与 Azure DevOps 集成
Azure DevOps (ADO)有许多与 Helm 集成的服务来帮助自动化开发流水线。ADO 中的 Repos 可以作为 Helm 图开发时的源控件。*工件*可以用来存储生成的数值进行 Helm 释放。*流水线*可用于建立 CI/CD 流水线,该流水线使用 Helm 在 AKS 集群上部署发布。
Azure DevOps 的*流水线*部分包括多个任务,支持将 Helm 用于 AKS 服务。 *Helm 工具安装程序*任务将在运行作业的代理机器上安装 Helm 二进制文件。*打包和部署 Helm charts* 任务允许运行基本上任何 Helm 客户端命令,包括使用 TLS 认证的选项。该任务以 AKS 集群为目标,使得在 AKS 集群上安装 Helm 图表相对简单。清单 8-43 展示了 Azure DevOps 中的示例 *yaml* 构建流水线。
Helm deployment pipeline
trigger:
- master
pool: vmImage: 'ubuntu-latest'
steps:
-
task: HelmInstaller@1 inputs: helmVersionToInstall: 'latest'
-
task: DownloadSecureFile@1 inputs: secureFile: 'ca.cert.pem'
-
task: DownloadSecureFile@1 inputs: secureFile: 'helm.cert.pem'
-
task: DownloadSecureFile@1 inputs: secureFile: 'helm.key.pem'
-
task: HelmDeploy@0 inputs: connectionType: 'Azure Resource Manager' azureSubscription: 'MAS(4d8e572a-3214-40e9-a26f-8f71ecd24e0d)' azureResourceGroup: 'iaks' kubernetesCluster: 'iaks1' namespace: 'iaks' command: 'install' chartType: 'FilePath' chartPath: 'Helm/aks/iaks' releaseName: '$(releaseName)' enableTls: true caCert: 'ca.cert.pem' certificate: 'helm.cert.pem' privatekey: 'helm.key.pem'
Listing 8-43ADO Pipeline definition
流水线从构建库的安全文件部分提取 TLS 文件,在代理机器上安装 Helm,然后使用路径`Helm/aks/iaks`中的图表在命名的 AKS 集群上运行`helm install`。
## 摘要
Helm 是一个帮助管理 Kubernetes 上的应用的工具。通过提供图表,Helm 提高了应用的可重用性,并允许通过明确定义的配置值为不同的环境定制应用。Helm 基于 CLI,可以轻松融入现有的自动化流水线和源代码控制。本章是对头盔的介绍,也是在 AKS 上开始使用头盔的指南。
在本章中,您了解了什么是 Helm,以及它如何提供优于 Kubernetes 上的`kubectl`和传统应用部署的优势。我们回顾了准备 AKS 集群以使用 Helm 进行应用管理的过程。然后,我们讨论了 Helm 图的结构以及一个正常工作的 Helm 图包含的内容。借助功能图,您学习了在 Kubernetes 集群上部署和维护 Helm 版本的过程。最后,我们简要回顾了 Helm 如何融入自动化和 CI/CD 的世界。