---
# System prepended metadata

title: 'Hands-on : Azure Kubernetes Service and CI/CD with Azure DevOps'
tags: [Azure DevOps, 台新, Azure Kubernetes Service, Workshop, Container Registry]

---

# Hands-on : Azure Kubernetes Service and CI/CD with Azure DevOps
###### tags: `台新` `Workshop` `Azure Kubernetes Service` `Container Registry` `Azure DevOps`

[ToC]
## 1/ 使用 Azure Kubernetes Service 部署 Kubernetes
### 使用 Azure Cloud Shell
- 開啟 [Azure Portal](https://ms.portal.azure.com/#home) 上的 Azure Cloud Shell
    ![](https://i.imgur.com/9gmLo69.png)
- 首次使用會建立 Azure Blob Storage，選擇要使用的訂閱，點選建立即可
- 確定切換置 bash
    ![](https://i.imgur.com/jAyqBbV.png)
    
    :::info
    :bulb: **Hint :** 使用 Azure Cloud Shell 時需使用 `ctrl` + `c` 複製 及 `shift` + `ctrl` + `v` 貼上 
    :::
### 建立新的資源群組
- 在整個部署指令碼中會重複使用某些值。舉例來說，須選擇要建立資源群組的區域，例如 `East US`，可自行修改參數值。
    ```azurecli-interactive
    REGION_NAME=southeastasia
    RESOURCE_GROUP=cicdworkshop
    SUBNET_NAME=cicd-subnet
    VNET_NAME=cicd-vnet
    ```
    - 地區也可使用 `REGION_NAME=eastus`
- 可透過 `echo $REGION_NAME` 顯示參數是否確定被輸入正確的值
- 使用 `aksworkshop` 作為名稱來建立新的資源群組。 於此資源群組中部署練習中建立的所有資源
    ```azurecli-interactive
    az group create \
        --name $RESOURCE_GROUP \
        --location $REGION_NAME
    ```

### 建立 AKS Cluster
<!-- - 註冊 Monitoring
    ```
    az provider register --namespace Microsoft.OperationsManagement
    az provider register --namespace Microsoft.OperationalInsights
    az provider register --namespace Microsoft.Insights
    ``` -->
- 設定 AKS cluster 名稱，此名稱在使用的訂閱中需為唯一
    ```azurecli-interactive
    AKS_CLUSTER_NAME=aks-cicd-$RANDOM
    ```
- 取得隨機產生的 AKS Cluster 名稱，並將此值記下
    ```azurecli-interactive
    echo $AKS_CLUSTER_NAME
    ```
- 執行以下命令來建立最新版本的 AKS Cluster，此需花費幾分鐘的時間才能完成 
    ```
    az aks create \
        --resource-group $RESOURCE_GROUP \
        --name $AKS_CLUSTER_NAME \
        --location $REGION_NAME \
        --enable-managed-identity \
        --node-count 1 \
        --node-vm-size Standard_D2s_v3 \
        --generate-ssh-keys
    ```
<!-- - 執行以下命令來建立最新版本的 AKS Cluster，此需花費幾分鐘的時間才能完成 
    ```
    az aks create \
        --resource-group $RESOURCE_GROUP \
        --name $AKS_CLUSTER_NAME \
        --location $REGION_NAME \
        --enable-managed-identity \
        --node-count 1 \
        --node-vm-size Standard_D2s_v3 \
        --enable-addons monitoring \
        --enable-msi-auth-for-monitoring  \
        --generate-ssh-keys
    ``` -->
### 使用 ```kubectl``` 測試叢集連線能力
kubectl 是用來與 Cluster 互動並可在 Cloud Shell 中使用
- 使用 `az aks get-credentials` 命令來設定 kubectl 的執行個體
    ```azurecli-interactive
    az aks get-credentials \
        --resource-group $RESOURCE_GROUP \
        --name $AKS_CLUSTER_NAME
    ```
- 列出所有節點
    ```azurecli-interactive
    kubectl get nodes
    ```
- 建立 `voting` 的 Namespace
    ```azurecli-interactive
    kubectl create namespace voting
    ```
## 2/ 建立私人容器登錄 Azure Container Registry
- 設定 ACR 的名稱，在 Azure 中須為唯一，這裡使用 random 的方式為 ACR 命名
    ```azurecli-interactive
    ACR_NAME=acrcicd$RANDOM
    ```
- 輸出 ACR_NAME 並記錄下來
    ```azurecli-interactive
    echo $ACR_NAME
    ```
- 透過 `az acr create` 建立與 AKS 資源位於相同資源群組及區域中的 ACR
    ```azurecli-interactive
    az acr create \
    --resource-group $RESOURCE_GROUP \
    --location $REGION_NAME \
    --name $ACR_NAME \
    --sku Standard
    ```
## 3/ 使用 Azure Container Registry 工作建立容器映像
Fruit Smoothies 評等應用程式使用兩個容器映像，一個用於前端網站，另一個用於 RESTful API Web 服務，接下來會使用 Azure Container Registry 以透過標準 Dockerfile 提供建置指示來建置這些容器映像

### 建立 Ratings API 映像
- 先建立一個資料夾提供給今天練習的範例程式碼使用
    ```azurecli-interactive
    mkdir aks-cicd-lab
    ```
- 索引到 `aks-cicd-lab` 底下
    ```azurecli-interactive
    cd aks-cicd-lab
    ```
- 下載範例 API 程式碼
    ```azurecli-interactive
    git clone https://github.com/Azure-Samples/azure-voting-app-redis.git
    ```
- 索引至範例程式碼目錄下
    ```azurecli-interactive
    cd azure-voting-app-redis/azure-vote
    ```
- 執行 `az acr build`，此指令會使用 Dockerfile 來建置容器映像，完成後將其推送至 ACR 中存放
    ```azurecli-interactive
    az acr build \
        --resource-group $RESOURCE_GROUP \
        --registry $ACR_NAME \
        --image azure-voting-app-redis:v1 .
    ```
    :::info
    :bulb: **注意:** 不要忘記上述命令結尾的句點 `.`， 其代表包含 Dockerfile 的來源目錄
    :::

### 驗證映像
- 執行以下命令確認映像已建立於 ACR 中
    ```azurecli-interactive
    az acr repository list \
        --name $ACR_NAME \
        --output table
    ```
- 輸出
    ```azurecli-interactive
    Result
    ----------------------
    azure-voting-app-redis
    ```

### 設定 AKS Cluster 與 ACR 間的驗證及身分授權
- 透過自動產生驗證方式 (需為 subscription owner)
    需要在容器登錄與 Kubernetes 叢集之間設定驗證，以允許服務之間的通訊
    - 執行 `az aks update` 命令來自動設定兩個資源間的必要服務主體驗證，此步驟會花費一些時間做 AKS 設定的更新
        ```azurecli-interactive
        az aks update \
            --name $AKS_CLUSTER_NAME \
            --resource-group $RESOURCE_GROUP \
            --attach-acr $ACR_NAME
        ```
- **(OPTION)** 自行設定連線 Container Registry secret 方式
    - 將 ACR 啟用 admin account
        ```azurecli-interactive
        az acr update -n $ACR_NAME --admin-enabled true
        ```
    - 取得 ACR 連線資訊
        ```azurecli-interactive
        ACR_UNAME=$(az acr credential show -n $ACR_NAME --query="username" -o tsv)
        ACR_PASSWD=$(az acr credential show -n $ACR_NAME --query="passwords[0].value" -o tsv)
        ```
    - 將 ACR 連線資訊設定於 K8S
        ```azurecli-interactive
        kubectl create secret docker-registry acr-secret \
                              --docker-server=$ACR_NAME \
                              --docker-username=$ACR_UNAME \
                              --docker-password=$ACR_PASSWD
        ```
    - Assign K8S secret to default service account
        ```azurecli-interactive
        kubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name": "acr-secret"}]}'
        ```
## 4/ 手動部屬服務
- 索引到程式碼目錄下
    ```azurecli-interactive
    cd ~/aks-cicd-lab/azure-voting-app-redis/
    ```
- 新增後端部屬設定 `azure-vote-back.yaml`，並部屬
    - 新增
        ```azurecli-interactive
        code azure-vote-back.yaml
        ```
    - 將以下貼入
        ```yaml
        apiVersion: apps/v1
        kind: Deployment
        metadata:
          name: azure-vote-back
        spec:
          replicas: 1
          selector:
            matchLabels:
              app: azure-vote-back
          template:
            metadata:
              labels:
                app: azure-vote-back
            spec:
              nodeSelector:
                "beta.kubernetes.io/os": linux
              containers:
              - name: azure-vote-back
                image: mcr.microsoft.com/oss/bitnami/redis:6.0.8
                env:
                - name: ALLOW_EMPTY_PASSWORD
                  value: "yes"
                ports:
                - containerPort: 6379
                  name: redis
        ---
        apiVersion: v1
        kind: Service
        metadata:
          name: azure-vote-back
        spec:
          ports:
          - port: 6379
          selector:
            app: azure-vote-back
        ```
    - 部屬至 AKS
        ```azurecli-interactive
        kubectl apply -f azure-vote-back.yaml -n voting
        ```
<!-- - 透過 `azure-vote-all-in-one-redis.yaml` 一次性的部屬所有服務
    ```azurecli-interactive
    kubectl apply -f azure-vote-all-in-one-redis.yaml -n voting
    ``` -->
- 建立並部屬前端 deployment 檔案
    - 新增  `azure-vote-front-deployment.yaml`
        ```azurecli-interactive
        code azure-vote-front-deployment.yaml
        ```
    - 將以下檔案貼上，完成後儲存
        ```yaml
        apiVersion: apps/v1
        kind: Deployment
        metadata:
          name: azure-vote-front
        spec:
          replicas: 1
          selector:
            matchLabels:
              app: azure-vote-front
          strategy:
            rollingUpdate:
              maxSurge: 1
              maxUnavailable: 1
          minReadySeconds: 5 
          template:
            metadata:
              labels:
                app: azure-vote-front
            spec:
              nodeSelector:
                "beta.kubernetes.io/os": linux
              containers:
              - name: azure-vote-front
                image: <acrname>.azurecr.io/azure-voting-app-redis:v1
                ports:
                - containerPort: 80
                resources:
                  requests:
                    cpu: 250m
                  limits:
                    cpu: 500m
                env:
                - name: REDIS
                  value: "azure-vote-back"
        ```
    - 將 `<acrname>` 取代為先前建立的 ACR 名稱
        ![](https://i.imgur.com/VCfc4ib.png)
    - 部屬至 AKS
        ```azurecli-interactive
        kubectl apply -f azure-vote-front-deployment.yaml -n voting
        ```
- 新增前端 service 設定並部屬
    - 新增  `azure-vote-front-service.yaml`
        ```azurecli-interactive
        code azure-vote-front-service.yaml
        ```
    - 將以下檔案貼上，完成後儲存
        ```yaml
        apiVersion: v1
        kind: Service
        metadata:
          name: azure-vote-front
        spec:
          type: LoadBalancer
          ports:
          - port: 80
          selector:
            app: azure-vote-front
        ```
    - 部屬至 AKS
        ```azurecli-interactive
        kubectl apply -f azure-vote-front-service.yaml -n voting
        ```
- 取得 External IP，並驗證網頁正常運行
    ```
    kubectl get service -n voting -w
    ```

## 5/ AKS with Azure DevOps CI/CD
### 版本控制
#### 匯入範例程式碼
- 至 [Azure DevOps](https://dev.azure.com/) 連結至先前建立的 Project，或新增一個
- 點選左方欄位 Repo 底下的 **[Files]**，選擇上方的repo name，點選 **[+New repository]**
![](https://i.imgur.com/Bvyk9We.png)
- 將 **Repository Name** 填寫成 `azure-voting-app-redis`，並將 **[Add a README]** 的勾取消，再點選 **[Create]**
![](https://i.imgur.com/183usQQ.png =350x)

- 複製該 repo 連結
![](https://i.imgur.com/pLm2DSW.png)

<!-- - 點選畫面中 **[Import]** 的按鈕，並複製以下連結貼到 **[Clone URL]** 中，完成後點選 **[Import]**
    ```
    https://github.com/MicrosoftDocs/mslearn-aks-workshop-ratings-api.git
    ```
    ![](https://i.imgur.com/lXX4IVf.png)
- 顯示正在進行匯入
    ![](https://i.imgur.com/GGBJlzi.png) -->

- 回到 Azure Cloud Shell，索引到程式碼目錄
    ```
    cd ~/aks-cicd-lab/azure-voting-app-redis/
    ```
- 環境中第一次設置 git (# 置換成編號)
    ```
    git config --global user.email "workshop-user-tw2023-#@huier23outlook.onmicrosoft.com"
    git config --global user.name "workshop-user-tw2023-#"
    ```
- 將新的檔案加入版控中
    ```
    git add .
    git commit -m "add k8s config"
    ```
- 將遠端儲存庫設定到本機 git 中
    ```
    git remote add devops https://<organization name>@dev.azure.com/<organization name>/<project name>/_git/azure-voting-app-redis
    ```
- 輸入以下指令可確認已成功設定
    ```
    git remote -v
    ```
    ![](https://i.imgur.com/7rV9pfY.png)
- 開始推送至 Azure Repo
    ```
    git push devops master
    ```
- 視窗會顯示詢問密碼，選擇下方兩種方式之一取得 PAT
    ```
    Password for 'https://huier-teamservice@dev.azure.com':
    ```
    1. 使用 PAT
        - 回到 Azure DevOps Service，點選右上角的圖示，並選擇 Personal Access Token
            ![](https://i.imgur.com/ncvLG8S.png =300x)
        - 點選 **[+New Token]**，完成資訊的填寫
            ![](https://i.imgur.com/I9EwWuD.png)
        - 將 token 複製起來，並記在記事本中(一旦關閉則會消失)
            ![](https://i.imgur.com/MEy9Gt9.png =400x)
    2. 使用 Generate Git Credentials
        - 點選 ![](https://i.imgur.com/PzNAX3B.png =160x)
            ![](https://i.imgur.com/6hOOj3W.png)
        - 將 token 複製起來，並記在記事本中
- 回到 Azure Cloud Shell 並將 token 貼上 (貼上後不會顯示任何東西)
    ![](https://i.imgur.com/FsXp2wN.png)

### 建立 Build Pipeline
- 選擇左方選單列中 Pipelines 下的 **[Pipelines]**，點選 **[Create Pipeline]**
    ![](https://i.imgur.com/5RQojNb.png)
- 選擇畫面下方說明文字中的 **[Use the classic editor]**
    ![](https://i.imgur.com/9FycaSt.png =400x)
- 選擇 `azure-voting-app-redis` 的 repository
    ![](https://i.imgur.com/GW3ourU.png)

- 在右上方的搜尋欄位尋找 `docker`，找到 **Docker Container**，點選 **[Apply]**
    ![](https://i.imgur.com/MWxKFga.png)
- 選到 Build an image，完成內容
    - **Azure Subscription** : **<建立 ACR 資源時使用的訂閱>**
    - **Azure Container Registry** : 選擇當初建立的 ACR 名稱
    - **Docker File** : `**/azure-vote/Dockerfile`
    - **Image Name** : `$(Build.Repository.Name):$(Build.BuildId)`
    ![](https://i.imgur.com/CzCJWrv.png)
<!--     - **Image Name** : `$(REPO)-api:$(Build.BuildNumber)` -->
<!--     ![](https://i.imgur.com/QwNgMbr.png) -->
- 選到 Push an image，完成內容
    - **Azure Subscription** : **<建立 ACR 資源時使用的訂閱>**
    - **Azure Container Registry** : 選擇當初建立的 ACR 名稱
    - **Docker File** : `**/azure-vote/Dockerfile`
    - **Image Name** : `$(Build.Repository.Name):$(Build.BuildId)`
    ![](https://i.imgur.com/ruew1bz.png)
<!--     ![](https://i.imgur.com/QLGze24.png) -->
- 點選 agent job 的 + 添加一個 task，在搜尋欄搜尋 `copy`，選擇 **Copy files**
    ![](https://i.imgur.com/9U2dgTW.png)
- 設定 Copy files
    - **Source Folder** : `$(Build.Repository.LocalPath)`
    - **Contents** : `**.yaml`
    - **Target Folder** : `$(Build.ArtifactStagingDirectory)`
    ![](https://i.imgur.com/3kTBIxD.png)
- 再添加一個 task，搜尋 `publish`，選擇 **Publish build artifacts**
    ![](https://i.imgur.com/BONhx5i.png)
- 設定 Publish build artifacts
    - **Path to publish** : `$(Build.ArtifactStagingDirectory)`
    - **Artifact name** : `drop-$(Build.BuildNumber)`
    ![](https://i.imgur.com/pgtV0RY.png)
<!-- - 設定 Variable，選擇 Variables > Variable groups > Manage variable groups
![](https://i.imgur.com/ngJKu01.png =500x)
- 點選 ![](https://i.imgur.com/C06uZa9.png =130x)，設定變數，完成後點選 ![](https://i.imgur.com/MH12mhk.png =70x)

    - **Variable group name**: `aks-lab` (或任意命名)
    - ***Variables***
        | **Name** | **Value**   |
        | -------- | --------    | 
        |  `ACR`   |   `acrxxxx.azurecr.io` |
        | `REPO`   |   `ratings` |
    ![](https://i.imgur.com/wdZhcRa.png)
- 回到 Pipeline > Variables > Variable groups > ![](https://i.imgur.com/kFMiDNM.png =150x) > 剛剛建立的 variable group > Link
![](https://i.imgur.com/pEtXIfh.png) -->
- 選擇 Pipeline > Agent Specification > ubuntu-latest
![](https://i.imgur.com/z9pTdOn.png)
- 選擇上方列表的 **[Triggers]** tab，將畫面右方的 **[Enable continuous integration]** 打勾
    ![](https://i.imgur.com/LfSoWnh.png)
- 在 Path filters 下選擇 **+Add**，選擇 **Exclude**，並在後方欄位填上 `**.yaml`
    ![](https://i.imgur.com/cYNLakF.png =400x)

- 完成後修改 pipeline 名稱為 `azure-voting-CI`，點選上方的 **[Save & queue]** ，選擇 **[Save & queue]** 後在跳出的視窗點選 **[Save and run]**
    ![](https://i.imgur.com/OMHwqUH.png)
    ![](https://i.imgur.com/FoX0mX6.png)
- 回到 Azure Portal 上確認有新的 Repository 及 Image
    ![](https://i.imgur.com/L5D92e2.png)
<!-- #### 建立 **mslearn-aks-workshop-ratings-web** 的 Build Pipeline
- 點選右上角 ![](https://i.imgur.com/V58Hac2.png =100x) 再新增一條提供 web 建置，同樣的步驟再重複一遍完成
- 選擇畫面下方說明文字中的 **[Use the classic editor]**
- 選擇 `mslearn-aks-workshop-ratings-web` 的 repository
![](https://i.imgur.com/AotCfSo.png =500x)
- 在右上方的搜尋欄位尋找 `docker`，找到 **Docker Container**，點選 **[Apply]**
- 選到 Build an image，完成內容
    - **Azure Subscription** : **<建立 ACR 資源時使用的訂閱>**
    - **Azure Container Registry** : `$(ACR)`
    - **Image Name** : `$(REPO)-web:$(Build.BuildNumber)`
    ![](https://i.imgur.com/b1hnzdY.png)
- 選到 Push an image，完成內容
    - **Azure Subscription** : **<建立 ACR 資源時使用的訂閱>**
    - **Azure Container Registry** : `$(ACR)`
    - **Image Name** : `$(REPO)-web:$(Build.BuildNumber)`
    ![](https://i.imgur.com/ipZ5dSn.png)
- 點選 agent job 的 + 添加一個 task，在搜尋欄搜尋 `copy`，選擇 **Copy files**
- 設定 Copy files
    - **Source Folder** : `$(Build.Repository.LocalPath)`
    - **Contents** : `**.yaml`
    - **Target Folder** : `$(Build.ArtifactStagingDirectory)`
    ![](https://i.imgur.com/fXbx5xc.png)
- 再添加一個 task，搜尋 `publish`，選擇 **Publish build artifacts**
- 設定 Publish build artifacts
    - **Path to publish** : `$(Build.ArtifactStagingDirectory)`
    - **Artifact name** : `drop-$(Build.BuildNumber)`
    ![](https://i.imgur.com/tGPddY6.png)
- 設定 Variable，選擇 Variables > Variable groups > ![](https://i.imgur.com/kFMiDNM.png =150x) > 剛剛建立的 variable group > Link
    ![](https://i.imgur.com/VlF2xlb.png)
- 選擇 Task > Pipeline > Agent Specification > ubuntu-latest
- 選擇上方列表的 **[Triggers]** tab，將畫面右方的 **[Enable continuous integration]** 打勾
- 在 Path filters 下選擇 **+Add**，選擇 **Include**，並在後方欄位填上 `src/`
    ![](https://i.imgur.com/88aZ297.png =400x)
- 完成後修改 pipeline 名稱為 `ratings-web-CI`，點選上方的 **[Save & queue]** ，選擇 **[Save & queue]** 後在跳出的視窗點選 **[Save and run]**
 -->

### 建立 Azure DevOps 對 AKS 的 Service Connection
- 點選 **Project Setting**
- 選擇 **Service Connections**
- 點選 ![](https://i.imgur.com/T3j0PEY.png =180x)
- 選擇 **Kubernetes** 並點選 **Next**
    ![](https://i.imgur.com/aaXHNo7.png =500x)
- 設定連線有兩種方式：
    - **Authentication method 選擇 Azure Subscription**
        1. Azure Subscription 選擇建立 AKS 的訂閱
        2. Cluster 選擇建立的 AKS
        3. Namespace 設定 `voting`
        4. 將 **Use cluster admin credentials** 做勾選
        5. Service connection name 自行設定
        ![](https://i.imgur.com/nO2NcZO.png =450x)
    - **Authentication method 選擇 KubeConfig**
        1. 到 Cloud Shell 上，使用以下指令開啟 KubeConfig
            ```
            code /home/workshop-user-tw2023-#/.kube/config
            ```
        2. 複製所有內容並貼到 Azure DevOps 中的 KubeCofig 欄位
        3. 點選 ![](https://i.imgur.com/W2drMIj.png =50x)，確認出現 ![](https://i.imgur.com/in5Zgom.png =180x)
        4. 輸入 Service Connection name 後點選 ![](https://i.imgur.com/GsZPWrS.png =100x)
        ![](https://i.imgur.com/tALC0L3.png =450x)

### 建立 Release Pipeline
- 在左方選單列選擇 Pipelines 下的 **[Release]**，進入後點選 **[New Pipeline]**
    ![](https://i.imgur.com/WgaXG4O.png)
- 選擇 ![](https://i.imgur.com/cMueEbe.png =100x)
    ![](https://i.imgur.com/iSGXH81.png =400x)
- 將 Stage name 更改為 `Prod`，完成後點選 **[X]** 關閉視窗
    ![](https://i.imgur.com/2oAPXgQ.png =400x)
- 選擇 Source Type 為 **Build**，Source (build pipeline) 為先前建立的 Pipeline，記下 Source alias 的資料，完成後點選 **[Add]**
![](https://i.imgur.com/mcTwx2v.png)
    - 記下 source alias 資訊
    ![](https://i.imgur.com/QO3Ud7O.png =400x)
- 點選 artifact 右上方的 ![](https://i.imgur.com/RAfgToy.png =40x) 設定 Continuous deployment trigger，設置為 Enabled
![](https://i.imgur.com/KPXqz7g.png)
- 選擇 `Prod` stage 內的 **[1 job, 0 task]**
    ![](https://i.imgur.com/6ilJKlD.png =500x)
- 點選 Agent Job 的 **[+]**，搜尋 `kube`，找到 **Deploy to Kubernetes** 點選 **[Add]**
    ![](https://i.imgur.com/2PHTATD.png)
- 點選 ![](https://i.imgur.com/AkLxJhJ.png =200x) task 進行設定
    - **Kubernetes service connection**：先前建立的 service connection
    - **Namespace**: `voting`
    - **Manifests**: `$(System.DefaultWorkingDirectory)/**/**/azure-vote-front-deployment.yaml`
    - **Containers**: `<ACR 名稱>/<ACR 中 repository 的名稱>:$(Release.Artifacts._azure-voting-CI.BuildId)`
    (`_azure-voting-CI` 的部份確認與你的 Source alias 一致)
    - **Timeout for rollout status**: `60`
    ![](https://i.imgur.com/sSiIbFL.png)

<!-- - 設定變數，Variables > variable groups > ![](https://i.imgur.com/N8I9N64.png =150x) > 先前建立的 variable group > Link
    ![](https://i.imgur.com/W6ZBoi4.png) -->
- 點選上方 Pipeline，在 Prod 的 stage 中點選![](https://i.imgur.com/yMs6J4t.png =35x)，在出的視窗中將 **[Pre-deployment approvals]** 改為 **[Enabled]**，並在 **[Approvers]** 欄位中選擇自己，完成後點選 **[X]** 關閉視窗
    ![](https://i.imgur.com/rLMjwFj.png)
- 將上方 All Pipelines > **[New release pipeline]** 修改為 `Release web to AKS`
    ![](https://i.imgur.com/P4CHXvg.png =400x)
- 點選右上角 Save
    ![](https://i.imgur.com/hssFc8S.png)
- 接著選擇 **[Create Release]**
- 在跳出的視窗中點選 **[Create]**
- 視窗上方會有一則訊息，點選 **[release 1]**，可以查看目前部屬進度
    ![](https://i.imgur.com/vVhOk6B.png)
- 點選 ![](https://i.imgur.com/4W3tqzW.png =80x) 允許部屬
    ![](https://i.imgur.com/PsNvtjf.png)
- 點選 Logs 查看部屬狀況
    ![](https://i.imgur.com/Jkw0cb1.png)
- 完成後瀏覽到你既有的網站確認網站依然顯示正常
- 回到 Azure Cloud Shell
    - 輸入以下命令查看目前的 pods
        ```
        kubectl describe pods azure-vote-front-xxxx -n voting
        ```
    - 查看前端 Pod 的 tag 已有異動
        ```
        kubectl 
        ```
        ![](https://i.imgur.com/6whK4sd.png)

## 6/ 驗證流程
#### 將首頁加上今天日期
- Azure Repo > azure-voting-app-redis > `azure-vote/azure-vote/config_file.cfg`
    ```cfg
    # UI Configurations
    TITLE = 'Azure Voting App - <今天日期>'
    VOTE1VALUE = 'Cats'
    VOTE2VALUE = 'Dogs'
    SHOWHOST = 'false'
    ```
    ![](https://i.imgur.com/ftkxsTY.png)
- 完成後 commit 確認 Pipeline 有自動啟動
- 可透過 `describe` 指令確認 image 版本
    ```
    kubectl describe pod azure-vote-front-xxxxx -n voting
    ```
    ![](https://i.imgur.com/IihlJRc.png)
