Share via


教學課程:使用 Ansible 在 Azure Kubernetes Service 中設定 kubenet 網路功能

重要

本文中需要 Ansible 2.8 (或更新版本)才能執行範例劇本。

Azure Kubernetes Service (AKS) 可讓您輕鬆地在 Azure 中部署受控 Kubernetes 叢集。 AKS 可降低管理 Kubernetes 的複雜性和作業負荷,因為是由 Azure 負責大部分的工作。 以主控的 Kubernetes 服務形式,Azure 會為您處理像是健康狀態監視和維護等重要工作。 Kubernetes 主機是由 Azure 管理。 您只需要管理及維護代理程式節點。 作為受控 Kubernetes 服務,AKS 是免費的 - 您只需支付叢集中的代理程式節點費用;不適用於主圖形。

使用 AKS,您可以使用下列網路模型來部署叢集:

如需 AKS 中應用程式網路功能的詳細資訊,請參閱 AKS 中應用程式的網路概念。

在本文中,您將學會如何:

  • 建立 AKS 叢集
  • 設定 Azure kubenet 網路功能

必要條件

  • Azure 訂用帳戶:如果您沒有 Azure 訂用帳戶,請在開始前建立免費帳戶
  • Azure 服務主體: 建立服務主體 ,並記下下列值: appId displayName 密碼 租使用者

建立虛擬網路和子網路

本節中的劇本程式碼會建立下列 Azure 資源:

  • 虛擬網路
  • 虛擬網路內的子網

將下列劇本儲存為 vnet.yml

- name: Create vnet
  azure_rm_virtualnetwork:
      resource_group: "{{ resource_group }}"
      name: "{{ name }}"
      address_prefixes_cidr:
          - 10.0.0.0/8

- name: Create subnet
  azure_rm_subnet:
      resource_group: "{{ resource_group }}"
      name: "{{ name }}"
      address_prefix_cidr: 10.240.0.0/16
      virtual_network_name: "{{ name }}"
  register: subnet

在虛擬網路中建立 AKS 叢集

本節中的劇本程式碼會在虛擬網路內建立 AKS 叢集。

將下列劇本儲存為 aks.yml

- name: List supported kubernetes version from Azure
  azure_rm_aks_version:
      location: "{{ location }}"
  register: versions

- name: Create AKS cluster with vnet
  azure_rm_aks:
      resource_group: "{{ resource_group }}"
      name: "{{ name }}"
      dns_prefix: "{{ name }}"
      kubernetes_version: "{{ versions.azure_aks_versions[-1] }}"
      agent_pool_profiles:
        - count: 3
          name: nodepool1
          vm_size: Standard_D2_v2
          vnet_subnet_id: "{{ vnet_subnet_id }}"
      linux_profile:
          admin_username: azureuser
          ssh_key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
      service_principal:
          client_id: "{{ lookup('ini', 'client_id section=default file=~/.azure/credentials') }}"
          client_secret: "{{ lookup('ini', 'secret section=default file=~/.azure/credentials') }}"
      network_profile:
          network_plugin: kubenet
          pod_cidr: 192.168.0.0/16
          docker_bridge_cidr: 172.17.0.1/16
          dns_service_ip: 10.0.0.10
          service_cidr: 10.0.0.0/16
  register: aks

以下是使用範例劇本時要考慮的一些重要注意事項:

  • 使用 azure_rm_aks_version 模組來尋找支援的版本。

  • vnet_subnet_id是上一節中建立的子網。

  • network_profile定義 kubenet 網路外掛程式的屬性。

  • service_cidr用來將 AKS 叢集中的內部服務指派給 IP 位址。 此 IP 位址範圍應該是不在 AKS 叢集外部使用的位址空間。 不過,您可以針對多個 AKS 叢集重複使用相同的服務 CIDR。

  • 位址 dns_service_ip 應該是服務 IP 位址範圍的 「.10」 位址。

  • pod_cidr應該是不在網路環境中其他地方使用的大型位址空間。 位址範圍必須夠大,才能容納您預期相應增加的節點數目。 部署叢集之後,您無法變更此位址範圍。 如同服務 CIDR,此 IP 範圍不應該存在於 AKS 叢集之外,但可以安全地跨叢集重複使用。

  • Pod IP 位址範圍可用來將 /24 位址空間指派給叢集中的每個節點。 在下列範例中, pod_cidr 192.168.0.0/16 的 會指派第一個節點 192.168.0.0/24、第二個節點 192.168.1.0/24,以及第三個節點 192.168.2.0/24。

  • 當叢集調整或升級時,Azure 會繼續將 Pod IP 位址範圍指派給每個新節點。

  • 劇本會從 ~/.ssh/id_rsa.pub 載入 ssh_key 。 如果您修改它,請使用單行格式 - 從 「ssh-rsa」 開始 (不含引號)。

  • client_idclient_secret 值會從 ~/.azure/credentials 載入,這是預設認證檔。 您可以將這些值設定為服務主體,或從環境變數載入這些值:

    client_id: "{{ lookup('env', 'AZURE_CLIENT_ID') }}"
    client_secret: "{{ lookup('env', 'AZURE_SECRET') }}"
    

建立網路資源的關聯

當您建立 AKS 叢集時,會建立網路安全性群組和路由表。 這些資源是由 AKS 管理,並在您建立和公開服務時更新。 將網路安全性群組和路由表與您的虛擬網路子網產生關聯,如下所示。

將下列劇本儲存為 associate.yml

- name: Get route table
  azure_rm_routetable_facts:
      resource_group: "{{ node_resource_group }}"
  register: routetable

- name: Get network security group
  azure_rm_securitygroup_facts:
      resource_group: "{{ node_resource_group }}"
  register: nsg

- name: Parse subnet id
  set_fact:
      subnet_name: "{{ vnet_subnet_id | regex_search(subnet_regex, '\\1') }}"
      subnet_rg: "{{ vnet_subnet_id | regex_search(rg_regex, '\\1') }}"
      subnet_vn: "{{ vnet_subnet_id | regex_search(vn_regex, '\\1') }}"
  vars:
      subnet_regex: '/subnets/(.+)'
      rg_regex: '/resourceGroups/(.+?)/'
      vn_regex: '/virtualNetworks/(.+?)/'

- name: Associate network resources with the node subnet
  azure_rm_subnet:
      name: "{{ subnet_name[0] }}"
      resource_group: "{{  subnet_rg[0] }}"
      virtual_network_name: "{{ subnet_vn[0] }}"
      security_group: "{{ nsg.ansible_facts.azure_securitygroups[0].id }}"
      route_table: "{{ routetable.route_tables[0].id }}"

以下是使用範例劇本時要考慮的一些重要注意事項:

  • node_resource_group是建立 AKS 節點的資源組名。
  • vnet_subnet_id是上一節中建立的子網。

執行範例劇本

本節列出呼叫本文中建立之工作的完整範例劇本。

將下列劇本儲存為 aks-kubenet.yml

---
- hosts: localhost
  vars:
      resource_group: aksansibletest
      name: aksansibletest
      location: eastus
  tasks:
     - name: Ensure resource group exist
       azure_rm_resourcegroup:
           name: "{{ resource_group }}"
           location: "{{ location }}"

     - name: Create vnet
       include_tasks: vnet.yml

     - name: Create AKS
       vars:
           vnet_subnet_id: "{{ subnet.state.id }}"
       include_tasks: aks.yml

     - name: Associate network resources with the node subnet
       vars:
           vnet_subnet_id: "{{ subnet.state.id }}"
           node_resource_group: "{{ aks.node_resource_group }}"
       include_tasks: associate.yml

     - name: Get details of the AKS
       azure_rm_aks_facts:
           name: "{{ name }}"
           resource_group: "{{ resource_group }}"
           show_kubeconfig: user
       register: output

     - name: Show AKS cluster detail
       debug:
           var: output.aks[0]

在 區 vars 段中,進行下列變更:

  • resource_group針對索引鍵,將 aksansibletest 值變更為您的資源組名。
  • name針對索引鍵,將 aksansibletest 值變更為您的 AKS 名稱。
  • Location針對索引鍵,將 eastus 值變更為您的資源群組位置。

使用 ansible-playbook 命令執行完整的劇本:

ansible-playbook aks-kubenet.yml

執行劇本會顯示類似下列輸出的結果:

PLAY [localhost] 

TASK [Gathering Facts] 
ok: [localhost]

TASK [Ensure resource group exist] 
ok: [localhost]

TASK [Create vnet] 
included: /home/devops/aks-kubenet/vnet.yml for localhost

TASK [Create vnet] 
ok: [localhost]

TASK [Create subnet] 
ok: [localhost]

TASK [Create AKS] 
included: /home/devops/aks-kubenet/aks.yml for localhost

TASK [List supported kubernetes version from Azure] 
 [WARNING]: Azure API profile latest does not define an entry for
ContainerServiceClient

ok: [localhost]

TASK [Create AKS cluster with vnet] 
changed: [localhost]

TASK [Associate network resources with the node subnet] 
included: /home/devops/aks-kubenet/associate.yml for localhost

TASK [Get route table] 
ok: [localhost]

TASK [Get network security group] 
ok: [localhost]

TASK [Parse subnet id] 
ok: [localhost]

TASK [Associate network resources with the node subnet] 
changed: [localhost]

TASK [Get details of the AKS] 
ok: [localhost]

TASK [Show AKS cluster detail] 
ok: [localhost] => {
    "output.aks[0]": {
        "id": /subscriptions/BBBBBBBB-BBBB-BBBB-BBBB-BBBBBBBBBBBB/resourcegroups/aksansibletest/providers/Microsoft.ContainerService/managedClusters/aksansibletest",
        "kube_config": "apiVersion: ...",
        "location": "eastus",
        "name": "aksansibletest",
        "properties": {
            "agentPoolProfiles": [
                {
                    "count": 3,
                    "maxPods": 110,
                    "name": "nodepool1",
                    "osDiskSizeGB": 100,
                    "osType": "Linux",
                    "storageProfile": "ManagedDisks",
                    "vmSize": "Standard_D2_v2",
                    "vnetSubnetID": "/subscriptions/BBBBBBBB-BBBB-BBBB-BBBB-BBBBBBBBBBBB/resourceGroups/aksansibletest/providers/Microsoft.Network/virtualNetworks/aksansibletest/subnets/aksansibletest"
                }
            ],
            "dnsPrefix": "aksansibletest",
            "enableRBAC": false,
            "fqdn": "aksansibletest-cda2b56c.hcp.eastus.azmk8s.io",
            "kubernetesVersion": "1.12.6",
            "linuxProfile": {
                "adminUsername": "azureuser",
                "ssh": {
                    "publicKeys": [
                        {
                            "keyData": "ssh-rsa ..."
                        }
                    ]
                }
            },
            "networkProfile": {
                "dnsServiceIP": "10.0.0.10",
                "dockerBridgeCidr": "172.17.0.1/16",
                "networkPlugin": "kubenet",
                "podCidr": "192.168.0.0/16",
                "serviceCidr": "10.0.0.0/16"
            },
            "nodeResourceGroup": "MC_aksansibletest_pcaksansibletest_eastus",
            "provisioningState": "Succeeded",
            "servicePrincipalProfile": {
                "clientId": "AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA"
            }
        },
        "type": "Microsoft.ContainerService/ManagedClusters"
    }
}

PLAY RECAP 
localhost                  : ok=15   changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

清除資源

  1. 將下列程式碼儲存為 delete_rg.yml

    ---
    - hosts: localhost
      tasks:
        - name: Deleting resource group - "{{ name }}"
          azure_rm_resourcegroup:
            name: "{{ name }}"
            state: absent
          register: rg
        - debug:
            var: rg
    
  2. 使用 ansible-playbook 命令執行劇本 。 將預留位置取代為要刪除的資源群組名稱。 將會刪除資源群組中的所有資源。

    ansible-playbook delete_rg.yml --extra-vars "name=<resource_group>"
    

    重點︰

    • register由於劇本的變數和 debug 區段,因此命令完成時會顯示結果。

下一步