Azure Kubernetes 服务 (AKS)是一种托管的 Kubernetes 服务,可让你快速部署和管理群集。 此快速入门介绍如何:
- 使用Azure CLI部署具有默认设置的 AKS 群集。
- 使用一组微服务和 Web 前端部署示例多容器应用程序,以模拟零售方案。
开始之前
本快速入门假设读者基本了解 Kubernetes 的概念。 有关详细信息,请参阅
- 如果没有Azure订阅,请在开始前创建一个 trial 帐户。
如需在本地运行 CLI 参考命令,请安装 Azure CLI。 如果在 Windows 或 macOS 上运行,请考虑在 Docker 容器中运行Azure CLI。 有关详细信息,请参阅 如何在 Docker 容器中运行Azure CLI。
如果使用本地安装,请使用 az login 命令登录到Azure CLI。 若要完成身份验证过程,请遵循终端中显示的步骤。 有关其他登录选项,请参阅Azure CLI登录。
出现提示时,请在首次使用时安装 Azure CLI 扩展。 有关扩展的详细信息,请参阅 使用 Azure CLI 的扩展。
运行 az version 以查找安装的版本和依赖库。 若要升级到最新版本,请运行 az upgrade。
- 本文需要 2.0.64 或更高版本的 Azure CLI。
- 确保用于创建群集的标识具有合适的的最低权限。 有关 AKS 的访问和标识的详细信息,请参阅 Azure Kubernetes 服务 (AKS) 的访问和标识选项。
- 如果您有多个 Azure 订阅,请选择用于计费资源的相应订阅 ID 并使用 az account set 命令进行设置。 有关详细信息,请参阅 如何管理Azure订阅 - Azure CLI。
注册资源提供程序
可能需要在你的Azure订阅中注册资源提供者。 例如,需要 Microsoft.ContainerService。
运行以下命令来检查注册状态。
az provider show --namespace Microsoft.ContainerService --query registrationState
如有必要,请注册资源提供程序。
az provider register --namespace Microsoft.ContainerService
定义环境变量
定义以下环境变量,以便在本快速入门中使用。
export RANDOM_STRING=$(printf '%05d%05d' "$RANDOM" "$RANDOM")
export RESOURCE_GROUP="myAKSResourceGroup$RANDOM_STRING"
export CLUSTER_NAME="myAKSCluster$RANDOM_STRING"
export USER_NP='userpool1'
export LOCATION="chinanorth3"
该 RANDOM_STRING 变量存储随机 10 位字符串。 变量RESOURCE_GROUPCLUSTER_NAME值与RANDOM_STRING值连接以创建唯一名称。
USER_NP 存储用户模式节点池的名称。 变量 LOCATION 具有 westus2 值。 可以使用这些变量值或创建自己的变量值。 使用echo命令查看变量值,例如echo $RANDOM_STRING。
创建资源组
Azure资源组是在其中部署和管理Azure资源的逻辑组。 创建资源组时,系统会提示你指定一个位置。 此位置是资源组元数据的存储位置,如果在创建资源期间未指定其他区域,则资源在Azure中运行的位置。
使用 az group create 命令创建资源组。 此命令使用你之前定义的 $RESOURCE_GROUP 和 $LOCATION 变量。
az group create --name $RESOURCE_GROUP --location $LOCATION
结果如以下示例所示。
{
"id": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/myAKSResourceGroup<randomStringValue>",
"location": "chinanorth3",
"managedBy": null,
"name": "myAKSResourceGroup<randomStringValue>",
"properties": {
"provisioningState": "Succeeded"
},
"tags": null,
"type": "Microsoft.Resources/resourceGroups"
}
创建 AKS 群集
使用 az aks create 命令创建 AKS 群集。 以下示例使用一个节点创建一个群集,并启用系统分配的托管标识。 此命令使用你之前定义的 $RESOURCE_GROUP 和 $CLUSTER_NAME 变量。
az aks create \
--resource-group $RESOURCE_GROUP \
--name $CLUSTER_NAME \
--node-count 1 \
--generate-ssh-keys
当你创建新群集时,AKS 会自动创建第二个资源组来存储 AKS 资源。 有关详细信息,请参阅为什么使用 AKS 创建两个资源组?
此示例中的群集指定一个节点计数,用于节省时间和资源。 在生产环境中,建议的节点计数为三个或多个节点。 如果未指定节点计数,则 az aks create 默认值为三个节点。
az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --query provisioningState --output tsv
添加用户模式节点池
应用程序应在用户模式节点池而不是默认系统模式节点池上运行。 用户节点池为应用程序工作负荷提供更好的隔离和灵活性。 使用 az aks nodepool add 命令将用户节点池添加到群集。
az aks nodepool add \
--resource-group $RESOURCE_GROUP \
--cluster-name $CLUSTER_NAME \
--name $USER_NP \
--node-count 1 \
--mode User
与群集一样,我们指定了一个节点,但如果未指定节点计数,则默认值为三个节点。
创建用户节点池后,可以使用命令验证群集是否具有系统节点池和用户节点池 az aks nodepool list 。
az aks nodepool list \
--resource-group $RESOURCE_GROUP \
--cluster-name $CLUSTER_NAME \
--query "[].{Count:count, Mode:mode, NodePool:name, ResourceGroup:resourceGroup}"
[
{
"Count": 1,
"Mode": "System",
"NodePool": "nodepool1",
"ResourceGroup": "myAKSResourceGroup1234554321"
},
{
"Count": 1,
"Mode": "User",
"NodePool": "userpool1",
"ResourceGroup": "myAKSResourceGroup1234554321"
}
]
连接到群集
若要管理 Kubernetes 群集,请使用 Kubernetes 命令行客户端 kubectl。 如果使用 Azure Power Shell,则已安装 kubectl。
使用
kubectl并运行 az aks get-credentials 命令,以配置为连接到你的 Kubernetes 群集。 此命令将下载凭据,并将 Kubernetes CLI 配置为使用这些凭据。az aks get-credentials --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME使用 kubectl get 命令验证与群集之间的连接。 此命令将返回群集节点的列表。
kubectl get nodesNAME STATUS ROLES AGE VERSION aks-nodepool1-123456789-vmss000000 Ready <none> 15m v1.34.4 aks-userpool1-123456789-vmss000000 Ready <none> 5m36s v1.34.4有两个节点,
nodepool1是使用群集创建的系统节点池,是userpool1添加到群集的用户节点池。
部署应用程序
若要部署应用程序,请使用清单文件创建运行 AKS Store 应用程序所需的所有对象。 Kubernetes 清单文件定义群集的所需状态,例如要运行的容器映像。 该清单包含以下 Kubernetes 部署和服务:
- 店面:客户查看产品和下单的 Web 应用程序。
- 产品服务:显示产品信息。
- 订单服务:下订单。
-
RabbitMQ:订单队列的消息队列。
注意
建议不要运行有状态容器,例如 RabbitMQ,在没有用于生产环境的持久性存储的情况下。 为了简单起见,我们建议使用托管服务,例如Azure Cosmos DB或Azure 服务总线。
创建名为 aks-store-quickstart.yaml 的文件,并将以下清单复制到其中。 将两个占位符
<defaultPassword>替换为自己的密码。 实例的默认用户RabbitMQ使用此密码。apiVersion: apps/v1 kind: StatefulSet metadata: name: rabbitmq spec: serviceName: rabbitmq replicas: 1 selector: matchLabels: app: rabbitmq template: metadata: labels: app: rabbitmq spec: nodeSelector: kubernetes.io/os: linux kubernetes.azure.com/mode: user containers: - name: rabbitmq image: mcr.microsoft.com/mirror/docker/library/rabbitmq:3.10-management-alpine ports: - containerPort: 5672 name: rabbitmq-amqp - containerPort: 15672 name: rabbitmq-http env: - name: RABBITMQ_DEFAULT_USER value: "username" - name: RABBITMQ_DEFAULT_PASS value: "<defaultPassword>" resources: requests: cpu: 10m memory: 128Mi limits: cpu: 250m memory: 256Mi volumeMounts: - name: rabbitmq-enabled-plugins mountPath: /etc/rabbitmq/enabled_plugins subPath: enabled_plugins volumes: - name: rabbitmq-enabled-plugins configMap: name: rabbitmq-enabled-plugins items: - key: rabbitmq_enabled_plugins path: enabled_plugins --- apiVersion: v1 data: rabbitmq_enabled_plugins: | [rabbitmq_management,rabbitmq_prometheus,rabbitmq_amqp1_0]. kind: ConfigMap metadata: name: rabbitmq-enabled-plugins --- apiVersion: v1 kind: Service metadata: name: rabbitmq spec: selector: app: rabbitmq ports: - name: rabbitmq-amqp port: 5672 targetPort: 5672 - name: rabbitmq-http port: 15672 targetPort: 15672 type: ClusterIP --- apiVersion: apps/v1 kind: Deployment metadata: name: order-service spec: replicas: 1 selector: matchLabels: app: order-service template: metadata: labels: app: order-service spec: nodeSelector: kubernetes.io/os: linux kubernetes.azure.com/mode: user containers: - name: order-service image: ghcr.io/azure-samples/aks-store-demo/order-service:latest ports: - containerPort: 3000 env: - name: ORDER_QUEUE_HOSTNAME value: "rabbitmq" - name: ORDER_QUEUE_PORT value: "5672" - name: ORDER_QUEUE_USERNAME value: "username" - name: ORDER_QUEUE_PASSWORD value: "<defaultPassword>" - name: ORDER_QUEUE_NAME value: "orders" - name: FASTIFY_ADDRESS value: "0.0.0.0" resources: requests: cpu: 1m memory: 50Mi limits: cpu: 75m memory: 128Mi startupProbe: httpGet: path: /health port: 3000 failureThreshold: 5 initialDelaySeconds: 20 periodSeconds: 10 readinessProbe: httpGet: path: /health port: 3000 failureThreshold: 3 initialDelaySeconds: 3 periodSeconds: 5 livenessProbe: httpGet: path: /health port: 3000 failureThreshold: 5 initialDelaySeconds: 3 periodSeconds: 3 initContainers: - name: wait-for-rabbitmq image: busybox command: ['sh', '-c', 'until nc -zv rabbitmq 5672; do echo waiting for rabbitmq; sleep 2; done;'] resources: requests: cpu: 1m memory: 50Mi limits: cpu: 75m memory: 128Mi --- apiVersion: v1 kind: Service metadata: name: order-service spec: type: ClusterIP ports: - name: http port: 3000 targetPort: 3000 selector: app: order-service --- apiVersion: apps/v1 kind: Deployment metadata: name: product-service spec: replicas: 1 selector: matchLabels: app: product-service template: metadata: labels: app: product-service spec: nodeSelector: kubernetes.io/os: linux kubernetes.azure.com/mode: user containers: - name: product-service image: ghcr.io/azure-samples/aks-store-demo/product-service:latest ports: - containerPort: 3002 env: - name: AI_SERVICE_URL value: "http://ai-service:5001/" resources: requests: cpu: 1m memory: 1Mi limits: cpu: 2m memory: 20Mi readinessProbe: httpGet: path: /health port: 3002 failureThreshold: 3 initialDelaySeconds: 3 periodSeconds: 5 livenessProbe: httpGet: path: /health port: 3002 failureThreshold: 5 initialDelaySeconds: 3 periodSeconds: 3 --- apiVersion: v1 kind: Service metadata: name: product-service spec: type: ClusterIP ports: - name: http port: 3002 targetPort: 3002 selector: app: product-service --- apiVersion: apps/v1 kind: Deployment metadata: name: store-front spec: replicas: 1 selector: matchLabels: app: store-front template: metadata: labels: app: store-front spec: nodeSelector: kubernetes.io/os: linux kubernetes.azure.com/mode: user containers: - name: store-front image: ghcr.io/azure-samples/aks-store-demo/store-front:latest ports: - containerPort: 8080 name: store-front env: - name: VUE_APP_ORDER_SERVICE_URL value: "http://order-service:3000/" - name: VUE_APP_PRODUCT_SERVICE_URL value: "http://product-service:3002/" resources: requests: cpu: 1m memory: 200Mi limits: cpu: 1000m memory: 512Mi startupProbe: httpGet: path: /health port: 8080 failureThreshold: 3 initialDelaySeconds: 5 periodSeconds: 5 readinessProbe: httpGet: path: /health port: 8080 failureThreshold: 3 initialDelaySeconds: 3 periodSeconds: 3 livenessProbe: httpGet: path: /health port: 8080 failureThreshold: 5 initialDelaySeconds: 3 periodSeconds: 3 --- apiVersion: v1 kind: Service metadata: name: store-front spec: ports: - port: 80 targetPort: 8080 selector: app: store-front type: LoadBalancer有关 YAML 清单文件的明细,请参阅部署和 YAML 清单。
如果在本地创建并保存 YAML 文件,则可以选择 Upload/Download files 按钮并从本地文件系统中选择文件,将清单文件上传到 Cloud Shell 的默认目录。
使用 kubectl apply 命令部署应用程序,并指定 YAML 清单的名称。
kubectl apply -f aks-store-quickstart.yaml运行以下命令,验证应用程序是否已部署在用户节点池上。
kubectl get pods -o wide输出显示 rabbitmq、order-service、product-service 和 store-front 的 Pod 正在用户节点池的一个节点上运行。
测试应用程序
可以通过访问公共 IP 地址或应用程序 URL 来验证应用程序是否正在运行。
运行以下命令以显示应用程序 URL:
runtime="5 minutes"
endtime=$(date -ud "$runtime" +%s)
while [[ $(date -u +%s) -le $endtime ]]
do
STATUS=$(kubectl get pods -l app=store-front -o 'jsonpath={..status.conditions[?(@.type=="Ready")].status}')
echo $STATUS
if [ "$STATUS" == 'True' ]
then
export IP_ADDRESS=$(kubectl get service store-front --output 'jsonpath={..status.loadBalancer.ingress[0].ip}')
echo "service IP address: $IP_ADDRESS"
break
else
sleep 10
fi
done
输出显示应用程序的公共 IP 地址在占位符 <applicationIPAddress> 中。 可以使用该 IP 地址在后续步骤中查看应用程序。
service IP Address: <applicationIPAddress>
运行以下命令,将请求发送到应用程序 URL。 用服务 IP 地址替换 <applicationIPAddress>。
curl <applicationIPAddress>
该命令返回显示应用程序响应请求的 HTML 输出。
<!doctype html>
<html lang="">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Contoso Pet Store</title>
<script type="module" crossorigin src="/assets/index-CLiaTzSi.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-Cv6jORyk.css">
</head>
<body>
<div id="app"></div>
</body>
</html>
若要查看应用程序网站,请打开浏览器并输入服务 IP 地址。 页面如以下示例所示。
删除群集
如果不打算执行 AKS 教程,请清理不必要的资源以避免Azure计费费用。 可以使用 az group delete 命令删除资源组、容器服务和所有相关资源。
az group delete --name $RESOURCE_GROUP --no-wait --yes
使用系统分配的托管标识创建了 AKS 群集,这是本快速入门中的默认标识选项。 平台负责管理此标识,因此你无需手动移除它。
后续步骤
在本快速入门中,你部署了 Kubernetes 群集,然后部署了一个简单的多容器应用程序。 此示例应用程序仅用于演示目的,并未展示出 Kubernetes 应用程序的所有最佳做法。
若要详细了解 AKS 并执行完整的代码到部署示例,请继续学习 Kubernetes 群集教程。