# OpenShift CICD-II Labs 本文件描述 CAJ 工作坊 OpenShift GitOps 基礎操作之練習步驟,讓學員熟悉基本 OpenShift GitOPS 操作,瞭解如何一套設計應用程式 CI/CD 自動化流程。 ## 事前準備 * 需要具備一台有網路的電腦,且有安裝好 Google Chrome。 * 建立 GitHub/Quay 帳號,在 CI/CD 流程會需要用到。 ## Labs 說明 在本次工作坊 Lab 透過微服物架構開發一套自動售票機(Ticket Vending Machines)應用程式,並利用 OpenShift Pipeline 與 OpenShift GitOps 實踐 CI/CD 流程,並最終將應用程式部署到 OpenShift 叢集上。 在本次工作坊將會分成兩個 Labs: * Lab 1: Mock TVM CI Pipeline 建立與執行 * 事前準備 * 建立 Masterfile CI Pipeline * 透過 PipelineRun 驗證流程 * 新增、設定與觸發 GitHub Webhook * Lab 2: Mock TVM CD Pipeline 建立與執行 * 事前準備 * 建立 CD Pipeline(ArgoCD Application) * 同步 Mock TVM 應用 API 資源 在此 Lab 中主要會使用到以下 Kubernetes/OpenShift API資源: * Kubernetes/OpenShift原生 * Pod * Service * ConfigMap & Secret * PV & PVC & SC * Route * OpenShift Pipelines * Task & TaskRun * Pipeline & PipelineRun * Trigger * TriggerBinding, EventListener, TriggerTemplate * ArgoCD * Application ### TVM 系統服務介紹 ![](https://hackmd.io/_uploads/SkT4NpIfT.png) ![](https://hackmd.io/_uploads/Hk2rE6UM6.png) ![](https://hackmd.io/_uploads/SJqh1xaZp.gif) ### Pipeline 目標 在 CICD 課程中,最終目標是將 TVM 透過 OpenShift Pipeline 完成 CI 流程,再由 GitOps 來執行後續 CD 流程。 CI Pipeline: ![](https://hackmd.io/_uploads/BJjWPxTza.png) CD Pipeline: ![](https://hackmd.io/_uploads/SkZbDgTMT.png) ### 相關資訊 * OpenShift 叢集 * [OpenShift Console](https://console-openshift-console.apps.cluster-w97m7.w97m7.sandbox753.opentlc.com/) * [Tekton Dashboard](https://dashboard-openshift-pipelines.apps.cluster-w97m7.w97m7.sandbox753.opentlc.com/) * [ArgoCD Dashboard](https://openshift-gitops-server-openshift-gitops.apps.cluster-w97m7.w97m7.sandbox753.opentlc.com/) * [GitHub CAJ Source Repo](https://github.com/redhat-tw/2023-m-caj) * [GitHub CAJ Config Repo](https://github.com/redhat-tw/2023-m-caj-config) * [Container Registry](https://quay.io/) * [SonarQube](https://sonarqube-caj-common.apps.cluster-w97m7.w97m7.sandbox753.opentlc.com/) * 帳密: admin/admin123 ## Lab 1: Mock TVM CI Pipeline 建立 本 Lab 說明如何建立 Mock TVM 的 CI Pipeline,這邊將以 Masterfile 應用為例進行設定。 ### 事前準備 * 首先 Fork CAJ source repo 到自己的 GitHub 帳號: ![](https://hackmd.io/_uploads/r14iG4TGp.png) ![](https://hackmd.io/_uploads/S1Ipz46f6.png) * 建立 SonarQube Project 與 Token。 ![](https://hackmd.io/_uploads/H1BohE6fT.png) Project 名稱用 `<STUDENT_ID>-<APP_NAME>`,如 `speaker01-masterfile`。 ![](https://hackmd.io/_uploads/HyNa3NTfa.png) ![](https://hackmd.io/_uploads/rky-RN6Ga.png) ![](https://hackmd.io/_uploads/ByZzR4pGp.png) ![](https://hackmd.io/_uploads/B14QCETz6.png) * 建立 Quay/DockerHub repo 與取得 Robot account 資訊 1. 登入帳號,並建立 Repo。 ![](https://hackmd.io/_uploads/r1V0cH6fT.png) 2. 建立 Robot Account ![](https://hackmd.io/_uploads/Skp48R8M6.png) 3. 給予此 Robot Account repo 權限 ![](https://hackmd.io/_uploads/S1igjBTf6.png) 4. 點選齒輪圖示取得帳號與密碼,用於登入用 ![](https://hackmd.io/_uploads/SyFyLCUfa.png) ![](https://hackmd.io/_uploads/BytZIALMT.png) ### 建立 Masterfile CI Pipeline 完成後,接著進入 Web Ternimal 頁面,取得 Forked 的原始碼以及建立相關檔案: ```shell= $ git clone https://github.com/redhat-tw/2023-m-caj # 新增 Helm value 檔案 $ cp -rp 2023-m-caj/charts/caj-ci-pipelines/values.yaml ./masterfile-values.yaml $ vim masterfile-values.yaml ``` 編輯 `masterfile-values.yaml` 檔案,修改以下內容: ```yaml= # Basic Config fullnameOverride: caj-ci appName: masterfile # Secret configs serviceAccount: name: pipeline git: url: https://github.com # 若使用 Private GitHub repos 的話,則需要反註解以下兩行。 # username: "<YOUR_GITHUB_ID>" # accessToken: "<YOUR_GITHUB_TOKEN>" registry: url: quay.io repository: "<YOU_QUAY_ID>/masterfile" username: "<YOUR_QUAY_ROBIT_ID>" accessToken: "<YOUR_QUAY_ROBIT_PASSWORD>" # Trigger configs trigger: webhook: secretToken: "1qaz2wsx3edc" workspaces: - name: shared volumeClaimTemplate: spec: accessModes: - ReadWriteOnce resources: requests: storage: 5Gi storageClassName: gp3-csi # SonarQube configs sonar: projectKey: "<YOUR_SONAR_PROJECT_KEY>" projectName: "<YOUR_SONAR_PROJECT_NAME>" hostURL: "https://sonarqube-caj-common.apps.cluster-w97m7.w97m7.sandbox753.opentlc.com" token: "<YOUR_SONAR_PROJECT_TOKEN>" ``` 完成後,透過 helm + oc 建立 Masterfile CI Pipeline: ```shell= # 先查看產生內容是否有誤 $ helm template caj-ci 2023-m-caj/charts/caj-ci-pipelines/ --values masterfile-values.yaml | less # 透過 oc apply -f 進行部署 $ oc project <YOUR_PROJECT> $ helm template caj-ci 2023-m-caj/charts/caj-ci-pipelines/ --values masterfile-values.yaml | oc apply -f - ``` ### 手動執行 PipelineRun 驗證流程 透過手動方式建立 PipelineRun 來驗證流程是否正常。 1. 首先建立一個`caj-ci-pr-pvc.yml` PVC 用於共享資料 ```yaml= kind: PersistentVolumeClaim apiVersion: v1 metadata: name: caj-ci-pr-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 5Gi storageClassName: gp3-csi ``` 2. 建立 `caj-ci-pr.yml` PipelineRun 設定 ```yaml= apiVersion: tekton.dev/v1beta1 kind: PipelineRun metadata: generateName: caj-ci-pr- spec: params: - name: appName value: masterfile - name: gitURL value: 'https://github.com/<YOU_GITHUB_ID>/2023-m-caj' - name: gitRevision value: 'main' - name: imageRepo value: '<YOU_QUAY_ID>/masterfile' - name: imageTag value: v0.0.1 - name: registryURL value: quay.io - name: sonarProjectKey value: '<YOUR_SONAR_PROJECT_ID>' - name: sonarProjectName value: '<YOUR_SONAR_PROJECT_NAME>' - name: sonarURL value: >- https://sonarqube-caj-common.apps.cluster-w97m7.w97m7.sandbox753.opentlc.com - name: sonarToken value: '<YOUR_SONAR_PROJECT_TOKEN>' pipelineRef: name: caj-ci-pipeline serviceAccountName: pipeline workspaces: - name: shared persistentVolumeClaim: claimName: caj-ci-pr-pvc ``` 3. 透過 oc 建立資源: ```shell= $ oc apply -f caj-ci-pr-pvc.yml # 執行 PipelineRun $ oc create -f caj-ci-pr.yml ``` 透過 tkn 來查看狀況: ```shell= # 查看 Tasks $ tkn t list $ tkn t describe <TASK_NAME> $ tkn t logs <TASK_NAME> # 查看 Pipelines $ tkn p list $ tkn p describe <PIPELINE_NAME> $ tkn p logs <PIPELINE_NAME> # 查看 PipelineRuns $ tkn pr list $ tkn pr describe <PIPELINERUN_NAME> # 查看其他資源 $ tkn <API_RES> <ACTION> $ tkn el list ``` ![](https://hackmd.io/_uploads/ryN4yHaMp.png) ![](https://hackmd.io/_uploads/B1dMkrTza.png) PipelineRun in Dashboard: ![](https://hackmd.io/_uploads/SyNgkH6G6.png) ![](https://hackmd.io/_uploads/HyTT2Hafa.png) ![](https://hackmd.io/_uploads/ryc8evTfa.png) SonarQube 執行結果: ![](https://hackmd.io/_uploads/SJDMpNTGT.png) Quay.io 執行結果: ![](https://hackmd.io/_uploads/B1zbpBpz6.png) ### 新增、設定與觸發 GitHub Webhook 首先建立 EventListener 來提供 Webhook 給 GitHub 呼叫。然後建立 Route 來提供對外存取。 ```shell= $ tkn eventlistener list NAME AGE URL AVAILABLE caj-ci-event-listener 1 hour ago http://el-caj-ci-event-listener.speaker01-green.svc.cluster.local:8080 True $ tkn eventlistener describe caj-ci-event-listener ``` ![](https://hackmd.io/_uploads/r1FuTBpza.png) Create Route in OpenShit Console: ![](https://hackmd.io/_uploads/BJQRTBTza.png) 在 GitHub repo 頁面新增 Webhook ![](https://hackmd.io/_uploads/BJ_P0Hazp.png) 輸入 Helm value 的 webhook.secretToken 值 ![](https://hackmd.io/_uploads/r1m20HTMp.png) ![](https://hackmd.io/_uploads/S1CTAB6GT.png) 最後嘗試修改程式碼內容,並推送 Commit 到 GitHub 來嘗試查觸發。 ![](https://hackmd.io/_uploads/Sy_fzIaza.png) 修改 [masterfile code](https://github.com/redhat-tw/2023-m-caj/blob/main/masterfile/src/main/java/com/caj/infra/repository/PassengerTypeRepositoryImpl.java#L36-L42) 來修復 SonarQube 掃瞄出來的 Bugs。 ```java= // 在最上面先 import package import java.util.Optional; import com.caj.infra.repository.po.PassengerTypePo; // 將下面這段整個修改掉 /** * 取得折扣率 */ @Override public BigDecimal findPassengerDiscount(String passengerType) { Optional<PassengerTypePo> result = passengerTypeDao.findById(passengerType); if (result.isPresent()) { return result.get().getDiscount(); }; return null; } ``` ## Lab 2: Mock TVM CD Pipeline 建立 本 Lab 說明如何建立 Mock TVM 的 CD Pipeline,這邊將以 Masterfile 應用為例進行設定。 ### 事前準備 * 首先 Fork CAJ Config repo 到自己的 GitHub 帳號: ![](https://hackmd.io/_uploads/H1W7lwTMT.png) ![](https://hackmd.io/_uploads/SkgrlwTfa.png) * 登入 ArgoCD Admin 頁面 ![](https://hackmd.io/_uploads/SJzA5Dpfa.png) ![](https://hackmd.io/_uploads/BJFjqwaG6.png) ![](https://hackmd.io/_uploads/rJHksP6G6.png) * 登入 ArgoCD User 頁面 ![](https://hackmd.io/_uploads/ryfZiDpMT.png) 第一次登入需要點選 [Allow selected permissions],才能正常進入 Dashboard。 ![](https://hackmd.io/_uploads/HJKQ1-Cfp.png) ### 建立 CD Pipeline 完成後,接著進入 Web Ternimal 頁面,取得 Forked 的原始碼以及建立相關檔案: ```shell= $ git clone https://github.com/redhat-tw/2023-m-caj # 新增 Helm value 檔案 $ cp -rp 2023-m-caj/charts/caj-cd-pipelines/values.yaml ./argocd-app-values.yaml $ vim argocd-app-values.yaml ``` 編輯 `argocd-app-values.yaml` 檔案,修改以下內容: ```yaml= fullnameOverride: mock-tvm # Basic Config studentId: <YOUR_OCP_ID> project: <YOUR_OCP_PROJECT> argoProject: student clusterAppsDomain: apps.cluster-w97m7.w97m7.sandbox753.opentlc.com cluster: name: "" server: https://kubernetes.default.svc source: repoURL: https://github.com/<YOUR_GITHUB_ID>/2023-m-caj-config path: charts/caj-apps targetRevision: main helm: parameters: - name: version value: v0.1.0 valueFiles: - ../../envs/prod/values.yaml ``` 透過 helm 產生 ArgoCD application 內容,並複製產生的 Application 內容: ```shell= # 查看產生內容是否有誤 $ helm template caj-cd 2023-m-caj/charts/caj-cd-pipelines/ --values argocd-app-values.yaml | less --- # Source: caj-cd-pipelines/templates/application.yml apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: speaker01-mock-tvm spec: destination: namespace: speaker01-green name: "" server: https://kubernetes.default.svc source: repoURL: https://github.com/kairen/2023-m-caj-config path: charts/caj-apps targetRevision: main helm: parameters: - name: version value: v0.1.0 valueFiles: - ../../envs/prod/values.yaml project: student ``` ![](https://hackmd.io/_uploads/BJu2GFTfT.png) 接著進入 ArgoCD Dashboard,在 Applications 頁面點選新增一個 Application: ![](https://hackmd.io/_uploads/rJHgvOTfT.png) 點選 `[EDIT AS YAML]` 按鈕進入 YAML 編輯頁面,然後貼上上面複製的內容: ![](https://hackmd.io/_uploads/rkR-Dd6Mp.png) 這邊 SYNC Policy 可以選擇 Manual 或 Automatic,這邊先選擇`Manual`模式。完成後點選 [CREATE] 按鈕來建立: ![](https://hackmd.io/_uploads/Sy1OwOTG6.png) 成功建立的話,就可以在 Application List 看到新建的 Application。 ![](https://hackmd.io/_uploads/r1CiFOpzT.png) 點選 Application 可進入查看細節資訊 ![](https://hackmd.io/_uploads/rJJpKd6G6.png) 點選 [APP DETAILS] 可以編輯與調整設定。 ![](https://hackmd.io/_uploads/ryvW5_TGa.png) 點選 [APP DIFF] 可以看到目前 Git repo 狀態與環境差異。 ![](https://hackmd.io/_uploads/H1X45Oazp.png) 修改自己的 `2023-m-caj-config/envs/prod /values.yaml` repo 檔案,將設定改成自己的資訊: ```yaml= studentId: <YOUR_OCP_ID> project: <YOUR_OCP_PROJECT> clusterAppsDomain: apps.cluster-w97m7.w97m7.sandbox753.opentlc.com image: masterfile: repo: quay.io/<YOUR_QUAY_ID>/m-caj-masterfile tag: v0.0.1 ``` ### 同步 Mock TVM 應用 API 資源 若為手動同步,則可以點選 [SYNC] 來同步 API 資源。 ![](https://hackmd.io/_uploads/B14scuTfa.png) ![](https://hackmd.io/_uploads/r1SYGFTGa.png) 如果出錯可以看第三張圖片,透過 Force Replace 方式來重新部署與替換 API 資源。 ![](https://hackmd.io/_uploads/B1ICh4RG6.png) 當同步完成後,且處於 `Healthy` 狀態時,表示 API 資源都部署完成。這時可以利用 oc 查看狀態: ```shell= $ oc -n <YOUR_PROJECT> get po,svc,route ``` 最後嘗試修改 Config repo 的 values 內容,將 CI Pipeline 建構出來的 image tag 更新,然後透過 git 推送 Commit 到 Config repo 來嘗試查觸發比較與同步。 若是手動同步的話,可以透過按 [REFRESH] 按鈕來重新比較內容。 ![](https://hackmd.io/_uploads/SkVVmYTfT.png) 最後在點選 [SYNC] 再做一次應用同步。 > 這邊也可以嘗試手動修改 OpenShift 已經部署的 API 資源,會看到 ArgoCD Application 也會檢查到環境與 Git 有差異。 另外使用者也可以點選不同應用呈現方式,來查看應用部署狀態。比如看相關 Pod 部署到哪些節點上,並查看 Logs 或進入容器操作。 ![](https://hackmd.io/_uploads/S11RTVRMp.png) ![](https://hackmd.io/_uploads/Bys-ANRMp.png)