刘劲男, Azure 资深云架构师

中国区 Azure 的 Kubernetes Service(简称AKS)已经于2018年11月13日宣布 Private Preview,很多用户对此功能向往已久,AKS 是 Azure 管理的 Kubernetes(简称 K8S )服务,提供了完整的 K8S 服务而不需要用户自己配置和管理,还可以集成 Azure AD 完善权限管理,在 Global 环境中还有 Container Monitor 的监控管理来简化 K8S 运行管理,笔者尝试在 AKS 上发布一个小程序,来看看AKS如何帮助用户简化K8S的搭建工作。为了让实验更完整,也引入了 Azure Container Registry 容器注册表(简称ACR)来让用户拥有自己的容器注册表而不是使用公共的。完整版请参照AKS的自学教程 https://docs.microsoft.com/zh-cn/azure/aks/tutorial-kubernetes-prepare-app,这里只是记录了简单的实验过程:

一、 本地准备应用 image

此步骤是为了获取一个部署的样例应用并进行 Docker image 打包,如果你已经有了,可以忽略此步骤。

1.执行 git clone 把样例应用 Vote App 拷贝到本地

如果没有 git,可以从这里安装 https://git-scm.com/downloads

git clone https://github.com/Azure-Samples/azure-voting-app-redis.git

2.安装 Docker for Windows

https://docs.docker.com/docker-for-windows/install/

安装完成后,本地 CMD 里面就可以有 docker 指令集

3.在本地 Docker 打包 image

cd azure-voting-app-redis

进入 git 目录执行 docker-compose 命令

docker-compose up -d

通过 docker-compose.yaml 配置文件:

version: '3'
services:
  azure-vote-back:
    image: redis
    container_name: azure-vote-back
    ports:
        - "6379:6379"

  azure-vote-front:
    build: ./azure-vote
    image: azure-vote-front
    container_name: azure-vote-front
    environment:
      REDIS: azure-vote-back
    ports:
        - "8080:80"

以及 ./azure-vote/Dockerfile

FROM    tiangolo/uwsgi-nginx-flask:python3.6
RUN     pip install redis
ADD     /azure-vote /app

在本地 windows 的 Docker 中自动完成如下工作:

1. 完成下载 redis image 并创建 azure-vote-back 容器

2. 创建 azure-vote-front 容器,通过 ./azure-vote下的 Dockerfile 定义安装脚本,完成了 tiangolo/uwsgi-nginx-flask 的 image 下载、redis 安装、加上程序打包成 azure-vote-front 的 image, 并生成了 azure-vote-front 的容器

本地查看 image 和容器:

docker images
docker ps

Docker 中容器已经安装完成 http://localhost:8080/

二、把应用 image 上传至 Azure 容器注册表

如果是一次性部署,也许你可以直接把本地的 docker image 推送到 AKS 集群上,ACR 提供了一个组织的管理,一个租户可以统一管理它的 image,便于实施组织的 Devops。

1.安装 Azure CLI

https://docs.microsoft.com/en-us/cli/azure/install-azure-cli-windows?view=azure-cli-latest

安装完成后,可以直接使用 Windows CMD 来敲打 cli 命令行

请确保版本至少要 2.0.46 以上

az --version

如果登陆 Global Azure:

az cloud set -n AzureCloud

默认是 Global Azure,但是若以前用过其他 cloud,要重新把环境 set 回来

如果登陆中国 Azure:

az cloud set -n AzureChinaCloud
az login
az account set --subscription="${SUBSCRIPTION_ID}" 

最后一步是 optional,如果此用户下有多个订阅,那如果你需要的不是默认的,需要指定订阅 ID。

虽然 AKS 和 ACR 都有 Portal 的图形化界面,但是 docker 和 K8S 都是使用命令行,所以使用 CLI 的命令行会更容易部署也更快速。

2.创建资源组

az group create -n K8Seusrg -l eastus

资源组是 Azure 逻辑集合,便于把相关 service 放在一起便于部署、权限管理

3.创建 Azure Container Registry(ACR)

az acr create -g K8Seusrg -n ljnacr --sku Basic 

4.上传 Vote App 的 image 到 ACR

登陆 acr

az acr login -n ljnacr

取得 ACR login Server

az acr list -g k8seusrg --query "[].{acrLoginServer:loginServer}" -o table

也可以在前面创建时记录 login server:ljnacr.azurecr.io

若要将 azure-vote-front 容器 image 与 ACR 配合使用,首先需使用注册表的登录服务器地址对 image 进行标记。

docker tag azure-vote-front ljnacr.azurecr.io/azure-vote-front:v1

然后

docker images

Push 到 ACR 中:

docker push ljnacr.azurecr.io/azure-vote-front:v1

等几分钟后显示 sha256 密钥后表示完成

列出 acr 的image

az acr repository list -n ljnacr -o table

三、创建 Azure Kubernetes 集群

1.为 K8S 准备Service Principle

Service Principle(简称SP)是 Azure AD 里面的概念,AD 主要就是管理用户和应用或 service 以及之间的权限关系,而 SP 简单说就是应用的权限代表,这里创建的 SP 是为将要创建的 Kubernetes 集群这个 Service 的权限代表,为以后赋权限而设置的。

az ad sp create-for-rbac -n ljnk8ssp -p xxxx --skip-assignment

这里 -p 代表 password 此 SP 的使用密码,如果不指定,系统自动产生,请务必记录密码

记录 SP 的 appid 和密码 (忘记 appid 可以在 portal 的 Azure Active Directory->App registrations 里面找到相应的 SP,里面有 Application ID;但是如果密码忘了,就没办法查到了,只有删除重建、或者通过

az ad sp credential reset -n ljnk8ssp -p XXX
来重新设置密码)

2.给 SP 赋予 ACR 的读取权限

取得ACR的ID

az acr show -g k8seusrg -n ljnacr --query "id" -o tsv

给前面SP授予ACR的读权限

az role assignment create --assignee 8fc1b60a-aed4-4277-8d26-86b470933102 --scope /subscriptions/"${SUBSCRIPTION_ID}" /resourceGroups/K8Seusrg/providers/Microsoft.ContainerRegistry/registries/ljnacr --role Reader

此过程为后面K8S cluster能够读取ACR的image做准备

3.创建 AKS 集群

可以在 portal 中创建,也可以用 CLI 创建:

https://docs.microsoft.com/en-us/cli/azure/aks?view=azure-cli-latest#az-aks-create

az aks create -g k8seusrg -n ljnk8s --node-count 1 --service-principal 8fc1b60a-aed4-4277-8d26-86b470933102  --client-secret XXX  --generate-ssh-keys

因为是实验 node 只用了1个,一般最少3个。等了几分钟后完成。

Azure K8s Version 最新为1.11.4,Node 虚机大小默认 Standard DS2v2 但可设定,Node 数量也可以配置或以后扩充,可以启用 RBAC(此功能对精细化管理很有用),可以直接增加 Http的router, vNet 可以新建也可以使用已有的,但是 subnet 最好是独占的。创建完成后在创建的资源组里面多了 AKS 的 service,另外多了一个 AKS 实际资源的资源组,我的实验里面是 MC_k8seusrg_ljnk8s_eastus 资源组,内容如下:

4.安装 K8S cli

若要从本地计算机管理 Kubernetes 群集,需要安装 kubectl(Kubernetes 命令行客户端)

如果你已经安装过可以忽略

az aks install-cli

5.连接 AKS 集群并查看

获取集群的登陆凭据:

az aks get-credentials -g K8Seusrg -n ljnk8s

系统返回错误:

A different object named ljnk8s already exists in clusters

因为我前面创建过一个同名的 K8S 集群但在 Azure 端删除、本地未删除,所以已经在 ~/.kube/config 已经有了前个集群信息,所以 kubectrl 脑裂,需要把这个 cluster 信息删除,我是直接删除此文件的(比较野蛮,应该是删除此文件里面的这个集群的 cluster、context、user,这样可以保留其他 cluster 的信息)再次get,成功验证连接:

kubectl get nodes

返回:

我们还可以登陆到 K8S 的 dashboard:

az aks browse -g k8seusrg -n ljnk8s

这时候浏览器会自动打开http://127.0.0.1:8001

这个命令创建了本地 proxy 来调用 k8s API。如果本地计算机开了 VPN 会导致不通,关闭重新执行命令即可。

后记:但是虽然进去了,啥也看不到,原来默认开启了 RBAC,但是这个 kubernetes-dashboard 的 service account 默认是最小权限即没啥权限(by the way, 如果用 portal 来创建,可以选择不开启 RBAC,这个就直接ready了),查看 https://docs.microsoft.com/en-us/azure/aks/kubernetes-dashboard 后使用命令:

kubectl create clusterrolebinding kubernetes-dashboard --clusterrole=cluster-admin --serviceaccount=kube-system:kubernetes-dashboard

把 cluster-admin 权限给与 kubernetes-dashboard

再来一次

az aks browse -g k8seusrg -n ljnk8s

哈哈啥都有啦;这个问题是我实验最后解决的,所以这时候的状态已经是部署完应用的了。

又创建了一个 AKS,做了个截图,这才是刚刚创建完 AKS 的 K8S web ui 界面

四、部署应用程序

1.修改 K8S 部署清单文件为 ACR image

前面我们已经知道 ACR 的 login Server 是 ljnacr.azurecr.io,如果忘记了也可以由前面命令取得。

然后需要把清单文件(指第一步从git clone下来的目录中有个azure-vote-all-in-one-redis.yaml文件)的image更改为 ACR 中的 image,我是用 VS Code,也可以使用文本编辑器修改:

containers:
      - name: azure-vote-front
        image: ljnacr.azurecr.io/azure-vote-front:v1

这样以后部署到 Azure Kubernetes Cluster 以后就会去 pull ACR中的 image 了。

2.在 AKS 上部署应用程序

前面我们在第三步中已经生成本地凭据,可以通过 kubectl get nodes 来查看联通状态,确认联通后可以直接进行部署:

kubectl apply -f azure-vote-all-in-one-redis.yaml

两个 service 已经生成,这个过程比前面 docker-compose 快很多,因为前面需要把原始 redis,nginx 的 image pull 下来并安装程序,而这个是把已经安装好 nginx、redis 和 vote 应用的 image 直接推到 K8S 的cluster 中生成 pod。当然还需要等待系统自动配置网络、对外接口等,所以我们用:

kubectl get service azure-vote-front --watch

来查看网络部署进程

等待外部 IP 生成后,就可以访问应用了:

而在 AKS 的使用的实际资源组里面又多了 Load Balance 和 Public IP 两个 service

然后我们看一下 AKS 所有 service:

kubectl get services

至此 AKS 部署应用完成。

五、其他事项

AKS 还可以实现手工缩放Pod

kubectl scale --replicas=3 deployment/azure-vote-front

也可以根据 CPU、内存指标自动缩放 Pod,自动缩放 Pod 需要 K8S version 1.10 以上才支持,1.10 以下要加些 metrics 才能实施:

kubectl autoscale deployment azure-vote-front --cpu-percent=50 --min=3 --max=10

成功后,检查

kubectl get hpa

目前仅支持手动缩放 Node

az aks scale -g K8Seusrg -n ljnk8s --node-count 3

需要注意的是,对 AKS 集群的操作基于本地的凭据文件,所以会自动登陆,但是对 ACR 的操作都是基于 azure 登陆session,如果过期需要重新登陆。

更新应用可以直接在 pod 更新,用 set image 命令推送

kubectl set image deployment azure-vote-front azure-vote-front=ljnacr.azurecr.io/azure-vote-front:v2

这个会直接把 Pod 的 image 改掉会引起短暂停顿;如果在生产环境中建议另外部署一个 cluster,前面用Traffic Manager 做 DNS 重定向,正常以后再切过来,类似灰度发布。

升级 K8S 的版本也可以用命令完成

az aks upgrade -g K8Seusrg -n ljnk8s --kubernetes-version 1.10.9

注意不是都能直接升到最新版,如我的实验环境原来 1.9.11,需要升级到 1.10.9,再升级到 1.11.4,可以使用命令查看可以升级的版本

az aks get-upgrades -g K8Seusrg -n ljnk8s --output table

删除 AKS 和它的实际资源组可以使用:

az group delete --name k8seusrg --yes --no-wait

AKS 会自动删除相关联的的实际资源组,另外还需要删除 SP:

az ad sp delete --id 8fc1b60a-aed4-4277-8d26-86b470933102

这样整个环境就干净了。

六、总结

过程其实很简单,因为我比较啰嗦,所以有点冗长,如果你有了 Image 只要3条命令就能完成 AKS 创建和应用部署:

az aks create 
az aks get-credentials
kubectl apply -f 

使用

kubectl get service  --watch 
查看部署结果。

心动不如行动,快来申请个 Azure 的账户试试吧。