快速搭建 Windows Kubernetes

背景

接上一篇 Windows 應用容器 後,想要快速且便利的部署與管理它們,能夠藉助容器編排工具。對於 Windows 容器,在今天 Service Fabric 會是個更爲成熟的選擇,在業界有更多的實踐案例。筆者將來可能會寫幾篇關於如何使用 Service Fabric 來實現 Windows 平臺下的微服務實踐。這次咱們接着上篇的內容往下去快速搭建 Windows Kubernetes 環境。html

ACS-Engine

Azure 團隊爲容器編排引擎提供了一個開源的部署工具 acs-engine , 它能夠支持在 Azure 上快速部署 Swarm、DC\OS、 Kubernetes 集羣,同時具有擴縮 Worker 節點、升級等等。這套工具的大致思路是,利用 Azure Infrastructure 服務的可描述性,聲明計算 、存儲、網絡等服務,同時實現 Kubernetes 與 Azure 整合,從而達到利用一個工具快速部署管理 Kubernetes。和咱們使用 Terraform 相似,只是 acs-engine 是一個和 Azure 集成更爲緊密的一個工具,使得這個 Kubernetes 能夠利用 Azure CNI 、LoadBalancer 以及雲磁盤存儲以及雲文件存儲。下圖來源於 ACS-engine 官方說明:再提一提 Azure CNI,它是由 Azure 團隊針基於 CNI 實現的容器網絡技術,利用 Azure SDN 的能力,使得容器網絡能夠鏈接 Azure VNET。所以使用 Azure CNI 能夠:node

  • Kubernetes 的容器網絡和 Azure VNet 在一個平面之上,不須要有 Overlay。
  • 同一 Azure VNet 下的虛機也能夠直接與 Kubernetes 容器互通,不須要通過負載經衡器。這個能夠解決咱們在微服務場景下, K8S 裏的容器要與 此K8S 集羣以外的服務實例之間的通信,例如咱們有 dubbo 或 spring cloud 混合部署的場景。
  • 在網絡傳輸效率和資源消耗上會比本身在 Azure 上搭一套使用 Flannel 的 Kubernetes 要好,按照筆者的測試能提高 20%~30%。

對於 acs-engine 除了能支持原生 Kubernetes 具有的特性,更多特性能夠參考 [6] , 固然能也能支持 GPU 的機器linux

前提

步驟

  • 經過 Azure CLI 登陸 Azure 中國,而且生成一個 Contributor 的操做身份給後續部署 K8S 時創建相關資源使用
az cloud set --name AzureChinaCloud
az login
az account set --subscription="${SUBSCRIPTION_ID}"
#下一行命令會生成一個 service principal, 須要記錄 appId 以及 password 留作後續使用
az ad sp create-for-rbac --role="Contributor" --scopes="/subscriptions/${SUBSCRIPTION_ID}"
  • 準備 acs-engine 的集羣部署描述文件, 因爲 json 文件不包含註釋的語法,爲了能更好的理解下面的某些字段信息,我仍是用 # 做爲註釋符用於解釋。當實際操做時請刪除相關 # 行目。
{
  "apiVersion": "vlabs",
  # 部署區域
  "location": "chinanorth2",
  "properties": {
    "orchestratorProfile": {
    #指定編排引擎類型爲 kubernetes 
      "orchestratorType": "Kubernetes",
      # 指定版本
      "orchestratorRelease": "1.11",
      "kubernetesConfig": {
        # 該 kubernetes 集羣將激活 rbac
        "enableRbac": true,
        # 該 kubernetes 集羣將使用 Azure CNI 做爲容器網絡實現
        "networkPolicy": "azure"
      }
    },
    #指定 master 節點信息
    "masterProfile": {
    # 此處爲 1 個 master 節點,也能夠聲明爲 3, 或者其奇數
      "count": 1,
      # 給定一個 DNS 前綴,用於聲明此 K8S 服務在 azure 中國北二區的子域名。例如此處爲: burn-k8s-11.chinanorth2.cloudapp.chinacloudapi.cn
      "dnsPrefix": "burn-k8s-11",
      # master 節點的型號
      "vmSize": "Standard_D3_v2"
    },
    # 指定 Node 節點列表,能夠聲明多個, 不一樣機型分別是多少臺,分別用什麼操做系統。包括使用可用性集來作高可用性保證,也能使用虛機擴展集
    "agentPoolProfiles": [
      {
        "name": "windowspool2",
        "count": 3,
        "vmSize": "Standard_D3_v2",
        "availabilityProfile": "AvailabilitySet",
        "osType": "Windows"
      }
    ],
    # 在 Windows Kubernetes 的環境裏須要 master 仍爲 Linux, 在 masterProfile 中未聲明使用什麼 OS, 默認是 Linux
    "linuxProfile": {
    #虛機登陸用戶名
      "adminUsername": "zhaw",
      "ssh": {
        "publicKeys": [
          {
          # 虛機登陸使用的公鑰
            "keyData": "ssh-rsa XXX"
          }
        ]
      }
    },
    # node 節點使用的 windows 登錄信息
    "windowsProfile": {
      "adminUsername": "azureuser",
      "adminPassword": "XXX",
      "windowsPublisher": "MicrosoftWindowsServer",
                        "windowsOffer": "WindowsServerSemiAnnual",
                        "windowsSku": "Datacenter-Core-1803-with-Containers-smalldisk"
    },
    "servicePrincipalProfile": {
    #前面生成 service principal 的 appID
      "clientId": "XXX",
      #前面生成 service principal 的 password
      "secret": "XXX"
    }
  }
}
  • 使用 acs-engine 根據上述描述文件生成 ARM 的部署文件
# 下面的命令將生成文件目錄: _output/<dns_prefix>
acs-engine generate kubernetes.json
  • output/<dnsprefix>/kubeconfig 目錄下會生成鏈接到此 k8s 的 kubeconfig 文件,咱們只須要在本地安裝 kubectl 就能夠操做此集羣,不須要連到 Master 節點上操做
  • 經過 azure CLI 建立一個資源管理庫並在其中部署出 k8s
# 進入到生成的文件目錄
cd _output/<dns_prefix>
# 建立資源管理庫
az group create --name <GROUP_NAME> --location chinanorth2 
# 部署 k8s
az group deployment create -g <GROUP_NAME> --template-file azuredeploy.json --parameters azuredeploy.parameters.json --verbose
  • 部署完畢之後能夠查看節點信息
$ kubectl --kubeconfig=kubeconfig.chinanorth2.json get node --show-labels
NAME                    STATUS    ROLES     AGE       VERSION   LABELS
35598k8s9000            Ready     <none>    1h        v1.11.2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=Standard_D3_v2,beta.kubernetes.io/os=windows,failure-domain.beta.kubernetes.io/region=chinanorth2,failure-domain.beta.kubernetes.io/zone=0,kubernetes.io/hostname=35598k8s9000
35598k8s9001            Ready     <none>    1h        v1.11.2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=Standard_D3_v2,beta.kubernetes.io/os=windows,failure-domain.beta.kubernetes.io/region=chinanorth2,failure-domain.beta.kubernetes.io/zone=0,kubernetes.io/hostname=35598k8s9001
35598k8s9002            Ready     <none>    1h        v1.11.2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=Standard_D3_v2,beta.kubernetes.io/os=windows,failure-domain.beta.kubernetes.io/region=chinanorth2,failure-domain.beta.kubernetes.io/zone=1,kubernetes.io/hostname=35598k8s9002
k8s-master-35598902-0   Ready     master    1h        v1.11.2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=Standard_D3_v2,beta.kubernetes.io/os=linux,failure-domain.beta.kubernetes.io/region=chinanorth2,failure-domain.beta.kubernetes.io/zone=0,kubernetes.azure.com/cluster=wink8s,kubernetes.io/hostname=k8s-master-35598902-0,kubernetes.io/role=master
  • 由於這個環境是一個 Linux 混合 windows 的集羣,因此在部署 container 的時候須要指定節點類型,好在 acs-engine 部署出來的集羣節點上攜帶操做系統相關的 label beta.kubernetes.io/os=windows ,咱們能夠經過 yaml 文件中使用 nodeSelector來指定節點信息
apiVersion: v1
kind: Service
metadata:
  name: stdlogclientwin
  labels:
    app: stdlogclientwin
spec:
  ports:
  - port: 80
    name: http
  selector:
    app: stdlogclientwin
  type: LoadBalancer
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: stdlogclientwin
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: stdlogclientwin
        version: v1
    spec:
      containers:
      - name: stdlogclientwin
        image: burning1docker/stdlogclientwin:1803
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
        volumeMounts:
        - name: hostsdir
          mountPath: "C:/Windows/System32/drivers/etc"
      nodeSelector:
        beta.kubernetes.io/os: windows
      initContainers:
      - name: init
        image: microsoft/windowsservercore:1803
        command:
        - powershell
        - "Add-Content"
        - "-Path"
        - "C:/Windows/System32/drivers/etc/hosts"
        - "-Value"
        - "\"127.0.0.1 foo.local\""
        volumeMounts:
        - name: hostsdir
          mountPath: "C:/Windows/System32/drivers/etc"
      volumes:
      - name: hostsdir
        emptyDir: {}
  • 從上面的示例文件中,咱們發現有一個經過 init container + emptyDir 來替換 hosts 的一個作法,在 Linux 下能夠用 HostAliases來實現,目前 Kubernetes Windows 上還不支持。因此能夠經過這種方式來實現。
  • 另外咱們還發現節點還攜帶了關於可用性集相關的信息,因此咱們還能夠使用 pod anti-affinity 來把同一容器應用 Pod 平均部署到不一樣容錯域,以防 Azure 物理故障時致使容器在某一時刻不可用,可參考以下示例:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: cpuloadv1
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: cpuload
        version: v1
    spec:
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - cpuload
              topologyKey: failure-domain.beta.kubernetes.io/zone
      containers:
      - name: cpuload
        image: burning1docker/cpuload:V1  
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080
        resources:
          limits:
            cpu: "1"
          requests:
            cpu: 500m

提問😂

  • 如何對 acs-engine 部署好的 k8s 集羣擴 node 節點?
  • 是否能夠對 acs-engine 部署好的 k8s 降級?
  • 對 acs-engine 部署好的 k8s 使用 Service Type 爲 ·LoadBalancer· 時, Azure LoadBalancer 的負載規則須要手動定義麼?

下一篇: 解決 Prometheus 不能獲取 Kubernetes 集羣上 Windows 節點的 Metricsgit

Ref:github

相關文章
相關標籤/搜索