轉載請注明出處:http://www.cnblogs.com/wayneiscoming/p/7649642.html
1. acs-engine簡介
ACS是微軟在2015年12月推出的一項基於容器的雲端PaaS服務。說簡單點,acs-engine就是一個ARM模板生成器,用戶只需要配置幾個簡單的參數來描述容器集群的規格,然后acs-engine將這個容器集群描述文件轉化成一組ARM(Azure Resource Manager)模板,然后用戶可以使用azure的cli命令來自動化地在Azure公有雲上生成容器集群。
ACS完全基於開源組件,目前ACS支持主流的編排框架有:DC/OS,Swarm,Kubernetes。acs-engine也已經在GitHub上開源(https://github.com/azure/acs-engine)。
目前有人說無法在中國區使用acs-engine,但是實測acs-engine可以在中國區部署k8s集群了,下面將對部署過程進行詳細介紹。至於k8s集群這里先不進行詳細介紹,請參考其他資料,后續我也將介紹一些關於k8s的相關內容。
2. acs-engine部署
環境: CentOS7,acs-enginev0.8.0
1. 首先獲取acs-engine源碼包,由於官方已經提供編譯好的acs-engine,所以懶人可以直接下載解壓,不用通過源碼編譯。但是源碼包中包含了模板文件,建議一起下載:
# wget https://github.com/Azure/acs-engine/releases/download/v0.8.0/acs-engine-v0.8.0-linux-amd64.zip # wget https://github.com/Azure/acs-engine/archive/v0.8.0.zip
2. 安裝依賴軟件:
# yum install golang
# yum install git
3. 運行go get all命令安裝ACS引擎需要的依賴組件
4. 解壓源碼包和編譯好的acs-engine:
# cd ~ # unzip acs-engine-v0.8.0-linux-amd64.zip # unzip v0.8.0.zip
5. 運行acs-engine命令:

# echo "export PATH=$PATH:$HOME/v0.8.0" >> ~/.bash_profile # source ~/.bash_profile # acs-engine ACS-Engine deploys and manages Kubernetes, Swarm Mode, and DC/OS clusters in Azure Usage: acs-engine [command] Available Commands: generate Generate an Azure Resource Manager template help Help about any command version Print the version of ACS-Engine Flags: --debug enable verbose debug logs -h, --help help for acs-engine Use "acs-engine [command] --help" for more information about a command.
3. Kubernetes集群搭建
由於目前acs-engine源碼中已經加入了Azure中國區,所以我們無需修改源碼,只需要在第三步編輯集群定義文件時中指定微軟雲中國區,acs-engine會在生成的ARM模板中將Kubernetes的鏡像源替換成國內可以訪問的地址。
Ⅰ. 集群說明
我創建的是1個master節點2個node節點的集群,創建后的集群架構如下:
使用ARM模板創建的集群會在Azure中為master節點創建LoadBalancer,而至於node節點,則會在當你在k8s中將一個服務的訪問方式設置為LoadBalancer后,k8s集群會訪問Azure的API為node節點創建一個LoadBalancer,並且添加上Public IP,k8s集群服務訪問方式這里暫不詳細說明。
Ⅱ. 生成SSH密鑰
創建的k8s集群默認是通過SSH密鑰登錄的,因此我們要首先生成SSH密鑰,這里只做Linux舉例,windows/mac請自行查閱相關資料。
# mkdir ~/.ssh # chmod 700 ~/.ssh # ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/home/b/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/b/.ssh/id_rsa. Your public key has been saved in /home/b/.ssh/id_rsa.pub.
Ⅲ. 創建服務主體賬號密碼
k8s集群需要能夠訪問你的微軟雲並創建刪除相關資源,因此需要給k8s集群配置服務主體賬號密碼。你可以選擇Azure CLI、Powershell、或者在Portal中直接創建,當然,你的Azure賬號必須有應用程序注冊的權限。這里介紹下Azure CLI和Portal中創建的方式。
1> Azure CLI 2.0
# az cloud set -n AzureChinaCloud # az login # az account set --subscription="${SUBSCRIPTION_ID}" # az ad sp create-for-rbac --role="Contributor" --scopes="/subscriptions/${SUBSCRIPTION_ID}"
之后你將得到一個json格式的tenant賬號密碼等信息: (需要注意的是以上命令生成的密碼有效期只有一年,而Azure應用程序賬號密碼有效期可以選擇一年/三年/永久,需要指定密碼有效期要在后面加 --years 參數。你可以在Portal - Azure Active Directory - 應用程序注冊 中找到名字為以下displayName的賬號)
{ "appId": "xxxxx-xxxxxxx-xxxxxxx-xxxxxx-xxxxxx", "displayName": "azure-cli-2017-10-13-08-20-35", "name": "http://azure-cli-2017-10-13-08-20-35", "password": "87ads6f7s6d7f87ad6sf78a6s7df7asf", "tenant": "xxxxxx-xxxxxx-xxxxxx-xxxxxx-xxxxxxx" }
你可以登錄來驗證下你的應用程序賬號:
# az login --service-principal -u NAME -p PASSWORD --tenant TENANT # az vm list-sizes --location chinaeast
2> Portal
Ⅳ. 編輯集群定義文件
在你下載的源碼包中有最簡單的集群定義文件舉例,文件位置在 examples/kubernetes.json,修改這個文件以滿足你的集群要求,關於集群定義文件詳細信息請參考官方說明,這里給出我使用的配置舉例:{ "apiVersion": "vlabs",
"location": "chinaeast", #這里一定要指定location為中國區,否則生成的ARM模板中k8s鏡像的地址為azureedge域名的地址,國內無法訪問。 "properties": { "orchestratorProfile": { "orchestratorType": "Kubernetes", "kubernetesConfig": {
"clusterSubnet": "10.244.0.0/16", #pod使用的地址空間 "dnsServiceIP": "10.4.0.10", "serviceCidr": "10.4.0.0/16" #service使用的地址空間 } }, "masterProfile": { #master節點配置 "count": 1, #master主機數量 "dnsPrefix": "k8s-preproduction", #生成的k8s集群可以通過dnsPrefix.chinaeast.cloudapp.chinacloudapi.cn來訪問 "vnetSubnetID": "/subscriptions/xxxxxxxxxxx/resourceGroups/Pre-Production/providers/Microsoft.Network/virtualNetworks/XXXVNET/subnets/default", #指定部署到現有的subnet,否則會生成一個新的subnet "firstConsecutiveStaticIP": "10.0.0.7", #master的起始IP "storageProfile": "ManagedDisks", #指定使用托管磁盤 "distro": "ubuntu", #使用ubuntu鏡像,對於k8s集群,acs-engine目前只支持ubuntu鏡像。對於Swarm集群可以指定rhel鏡像 "vmSize": "Standard_DS2_v2" #虛擬機規模 }, "agentPoolProfiles": [ #node節點配置 { "name": "preagpool1", "count": 2, "vmSize": "Standard_DS2_v2", "vnetSubnetID": "/subscriptions/xxxxxxxxxxx/resourceGroups/Pre-Production/providers/Microsoft.Network/virtualNetworks/XXXVNET/subnets/default", "storageProfile": "ManagedDisks", #node節點默認不使用托管磁盤,需要使用這里必須指定 "distro": "ubuntu", "availabilityProfile": "AvailabilitySet" } ], "linuxProfile": { "adminUsername": "sshuser", "ssh": { "publicKeys": [ #這里給出步驟Ⅰ生成的ssh密鑰 { "keyData": "ssh-rsa xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx sshuser@acs-engine-test" } ] } }, "servicePrincipalProfile": { #這里給步驟Ⅱ生成的appID和password "clientId": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "secret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" } } }
Ⅴ. 生成ARM模板
使用剛編輯好的kubernetes.json作為輸入參數,執行以下命令生成ARM模板:
# acs-engine generate examples/kubernetes.json
生成的模板位於_output/"dnsPrefix"路徑下,將會生成3個或者多個類似如下的模板:
- apimodel.json - 集群配置文件
- azuredeploy.json - 核心的ARM (Azure Resource Model)模板,用來部署k8s集群
- azuredeploy.parameters.json - 部署參數文件,其中的參數可以自定義
- certificate and access config files - kubernetes需要的一些證書,這些證書文件和它依賴的kube config配置文件也存放在和ARM模板同級目錄下面
需要注意的是,當修改已有的Docker容器集群的時候,應該修改apimodel.json文件來保證最新的部署不會影響到目前集群中已有的資源。舉個例子,如果一個容器集群中的節點數量不夠的時候,可以修改apimodel.json中的集群節點數量,然后重新運行acs-engine命令並將apimodel.json作為輸入參數來生成新的ARM模板。這樣部署以后,集群中的舊的節點就不會有變化,新的節點會自動加入。
可以看到apimodel以及parameters文件中k8s的鏡像地址已經換成crproxy.trafficmanager.net,這個地址國內可以訪問的到,這里我們還需要修改parameters文件中的兩個參數:
"dockerEngineDownloadRepo": { "value": "https://mirror.kaiyuanshe.cn/docker-engine/apt/repo/" #由於當前mirror.azure.cn有證書問題,我們這里把docker-engine源替換到其他源 }, "kubernetesTillerSpec": { "value": "crproxy.trafficmanager.net:6000/kubernetes-helm/tiller:v2.6.1" #這里沒有自動替換到trafficmanager地址而扔使用的azureedge地址,手動將其替換 }
Ⅵ. 部署ARM模板
1> Azure CLI 2.0
$ az cloud set -n AzureChinaCloud $ az login $ az account set --subscription "<SUBSCRIPTION NAME OR ID>" $ az group create \ --name "<RESOURCE_GROUP_NAME>" \ --location "<LOCATION>" $ az group deployment create \ --name "<DEPLOYMENT NAME>" \ --resource-group "<RESOURCE_GROUP_NAME>" \ --template-file "./_output/<INSTANCE>/azuredeploy.json" \ --parameters "./_output/<INSTANCE>/azuredeploy.parameters.json"
2> Powershell
Add-AzureRmAccount Select-AzureRmSubscription -SubscriptionID <SUBSCRIPTION_ID> New-AzureRmResourceGroup ` -Name <RESOURCE_GROUP_NAME> ` -Location <LOCATION> New-AzureRmResourceGroupDeployment ` -Name <DEPLOYMENT_NAME> ` -ResourceGroupName <RESOURCE_GROUP_NAME> ` -TemplateFile _output\<INSTANCE>\azuredeploy.json ` -TemplateParameterFile _output\<INSTANCE>\azuredeploy.parameters.json
不出意外你將在resource group里看到k8s集群被創建起來,在部署中可以看到詳細部署的進度:
若kube-dns以及kubernetes-dashboard服務無法正常啟動,需要安裝網絡組建(flannel、calico等),這里給出flannel部署方式,calico可以在cluster文件kubernetesConfig中配置networkPolicy: "calico"。

---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: flannel
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- apiGroups:
- ""
resources:
- nodes
verbs:
- list
- watch
- apiGroups:
- ""
resources:
- nodes/status
verbs:
- patch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: flannel
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: flannel
subjects:
- kind: ServiceAccount
name: flannel
namespace: kube-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: flannel
namespace: kube-system
---
kind: ConfigMap
apiVersion: v1
metadata:
name: kube-flannel-cfg
namespace: kube-system
labels:
tier: node
app: flannel
data:
cni-conf.json: |
{
"name": "cbr0",
"type": "flannel",
"delegate": {
"hairpinMode": true,
"isDefaultGateway": true
}
}
net-conf.json: |
{
"Network": "10.244.0.0/16",
"Backend": {
"Type": "vxlan"
}
}
---
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
name: kube-flannel-ds
namespace: kube-system
labels:
tier: node
app: flannel
spec:
template:
metadata:
labels:
tier: node
app: flannel
spec:
hostNetwork: true
nodeSelector:
beta.kubernetes.io/arch: amd64
tolerations:
- key: node-role.kubernetes.io/master
operator: Exists
effect: NoSchedule
serviceAccountName: flannel
initContainers:
- name: install-cni
image: quay.io/coreos/flannel:v0.9.0-amd64
command:
- cp
args:
- -f
- /etc/kube-flannel/cni-conf.json
- /etc/cni/net.d/10-flannel.conf
volumeMounts:
- name: cni
mountPath: /etc/cni/net.d
- name: flannel-cfg
mountPath: /etc/kube-flannel/
containers:
- name: kube-flannel
image: quay.io/coreos/flannel:v0.9.0-amd64
command: [ "/opt/bin/flanneld", "--ip-masq", "--kube-subnet-mgr" ]
securityContext:
privileged: true
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
volumeMounts:
- name: run
mountPath: /run
- name: flannel-cfg
mountPath: /etc/kube-flannel/
volumes:
- name: run
hostPath:
path: /run
- name: cni
hostPath:
path: /etc/cni/net.d
- name: flannel-cfg
configMap:
name: kube-flannel-cfg
Ⅶ. 創建一個測試服務
1> 使用SSH密鑰通過master IP或者FQDN連接到k8s集群中
2> 查看集群狀態,正常的話node都應該為ready狀態,pods為running
# kubectl get nodes
# kubectl get pods --all-namespaces
3> 創建一個nginx deployment,成功后你將看到一個running的nginx pod
# kubectl run nginx --image nginx
# kubectl get pods -o yaml
# curl curl 10.244.1.4 (pod IP)
4> 創建nginx服務
# kubectl expose deployment nginx --port=80 # kubectl get service
# curl 10.0.105.199 (service IP)
5> 設置服務可以通過外部訪問
k8s的服務外部訪問方式有LoadBalancer、NodePort、Ingress,這里暫不進行過多贅述,我們使用LoadBalancer方式。
# kubectl edit svc nginx
將type從ClusterIP改為LoadBalancer,保存退出。之后k8s集群將會自動為node節點創建一個Azure LoadBalancer和一個public IP
6> 訪問服務
當EXTERNAL-IP從Pending狀態變為一個public IP時,則可以通過瀏覽器進行服務訪問了。
# kubectl get svc
至此,通過acs-engine搭建k8s集群結束。
Ⅶ. 一些關於acs-engine的問題
上周與acs的開發人員進行了交流,以下是一些咨詢的問題以及答案:
1. Scale up/down master with acs-engine? -> Not supported
2. Scale down nodes with acs-engine? -> Not supported
3. CentOS supported? -> Maybe later
4. How to roll back if scale up failed? -> Don't know
5. When is AKS available in China? -> 2018 Q2
官方鏈接:
https://github.com/Azure/acs-engine