OpenShift 4 之 GitOps(3)用Helm+ArgoCD部署應用,並保持配置同步

運行環境

  1. 安裝ArgoCD服務器環境。
  2. 根據《OpenShift 4.3 之新特性 - 使用Helm部署OpenShift應用》安裝helm客戶端即可。

用Helm創建樣例Chart

  1. 創建名爲myapp的helm chart,然後可以查看chart中的deployment.yaml。
$ mkdir helmstuff
$ cd helmstuff/
$ helm create myapp
Creating myapp
$ find myapp/
myapp/
myapp/Chart.yaml
myapp/values.yaml
myapp/.helmignore
myapp/templates
myapp/templates/ingress.yaml
myapp/templates/deployment.yaml
myapp/templates/service.yaml
myapp/templates/serviceaccount.yaml
myapp/templates/NOTES.txt
myapp/templates/_helpers.tpl
myapp/templates/tests
myapp/templates/tests/test-connection.yaml
myapp/charts

根據Helm Chart安裝OpenShift應用

  1. 創建OpenShift的helmstuff項目,然後通過helm安裝應用。
$ oc new-project helmstuff
$ helm install adventure1 myapp/ -n helmstuff
NAME: adventure1
LAST DEPLOYED: Wed Mar  4 10:37:09 2020
NAMESPACE: helmstuff
STATUS: deployed
REVISION: 1
NOTES:
(1). Get the application URL by running these commands:
  export POD_NAME=$(kubectl get pods --namespace helmstuff -l "app.kubernetes.io/name=myapp,app.kubernetes.io/instance=adventure1" -o jsonpath="{.items[0].metadata.name}")
  echo "Visit http://127.0.0.1:8080 to use your application"
  kubectl --namespace helmstuff port-forward $POD_NAME 8080:80
  1. 查看Helm列表。
$ helm list
NAME            NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
adventure1      helmstuff       1               2020-03-04 10:37:09.669437379 +0000 UTC deployed        myapp-0.1.0     1.16.0
  1. 查看pod狀態爲CrashLoopBackOff,然後helm中的adventure1,確認結果報錯“Error: pod
    adventure1-myapp-test-connection failed”。
$ oc get pod
NAME                                READY   STATUS             RESTARTS   AGE
adventure1-myapp-5b64cf64cb-r65fk   0/1     CrashLoopBackOff   1          32s
 
$ helm test adventure1
Pod adventure1-myapp-test-connection pending
Pod adventure1-myapp-test-connection pending
Pod adventure1-myapp-test-connection pending
Pod adventure1-myapp-test-connection pending
Pod adventure1-myapp-test-connection running
NAME: adventure1
LAST DEPLOYED: Wed Mar  4 10:37:09 2020
NAMESPACE: helmstuff
STATUS: deployed
REVISION: 1
TEST SUITE:     adventure1-myapp-test-connection
Last Started:   Wed Mar  4 10:38:18 2020
Last Completed: Wed Mar  4 10:38:29 2020
Phase:          Failed
NOTES:
(1). Get the application URL by running these commands:
  export POD_NAME=$(kubectl get pods --namespace helmstuff -l "app.kubernetes.io/name=myapp,app.kubernetes.io/instance=adventure1" -o jsonpath="{.items[0].metadata.name}")
  echo "Visit http://127.0.0.1:8080 to use your application"
  kubectl --namespace helmstuff port-forward $POD_NAME 8080:80
Error: pod adventure1-myapp-test-connection failed
  1. 上面錯誤是由於權限問題。執行以下命令爲容器中的操作用戶提權。
$ oc adm policy add-scc-to-user anyuid -z adventure1-myapp
securitycontextconstraints.security.openshift.io/anyuid added to: ["system:serviceaccount:helmstuff:adventure1-myapp"]
  1. 先從helm中刪除adventure1,然後重新創建helm的adventure1,最後再用helm測試adventure1,確認這次可測通過。
$ helm uninstall adventure1
release "adventure1" uninstalled
 
$ helm install adventure1 myapp/
NAME: adventure1
LAST DEPLOYED: Wed Mar  4 10:45:21 2020
NAMESPACE: helmstuff
STATUS: deployed
REVISION: 1
NOTES:
(1). Get the application URL by running these commands:
  export POD_NAME=$(kubectl get pods --namespace helmstuff -l "app.kubernetes.io/name=myapp,app.kubernetes.io/instance=adventure1" -o jsonpath="{.items[0].metadata.name}")
  echo "Visit http://127.0.0.1:8080 to use your application"
  kubectl --namespace helmstuff port-forward $POD_NAME 8080:80
 
$ helm test adventure1
Pod adventure1-myapp-test-connection pending
Pod adventure1-myapp-test-connection pending
Pod adventure1-myapp-test-connection pending
Pod adventure1-myapp-test-connection pending
Pod adventure1-myapp-test-connection succeeded
NAME: adventure1
LAST DEPLOYED: Wed Mar  4 10:45:21 2020
NAMESPACE: helmstuff
STATUS: deployed
REVISION: 1
TEST SUITE:     adventure1-myapp-test-connection
Last Started:   Wed Mar  4 10:45:40 2020
Last Completed: Wed Mar  4 10:45:50 2020
Phase:          Succeeded
NOTES:
(1). Get the application URL by running these commands:
  export POD_NAME=$(kubectl get pods --namespace helmstuff -l "app.kubernetes.io/name=myapp,app.kubernetes.io/instance=adventure1" -o jsonpath="{.items[0].metadata.name}")
  echo "Visit http://127.0.0.1:8080 to use your application"
  kubectl --namespace helmstuff port-forward $POD_NAME 8080:80

從Helm Chat導出要部署的應用對象

  1. 創建manifest目錄,讓後將helm中名爲adventure1的manifest導出到manifest/adventure1.yaml。
$ mkdir manifest
$ helm get manifest adventure1 > manifest/adventure1.yaml
  1. 查看導出的manifest/adventure1.yaml文件內容。
$ cat manifest/adventure1.yaml
---
# Source: myapp/templates/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: adventure1-myapp
  labels:
    helm.sh/chart: myapp-0.1.0
    app.kubernetes.io/name: myapp
    app.kubernetes.io/instance: adventure1
    app.kubernetes.io/version: "1.16.0"
    app.kubernetes.io/managed-by: Helm
---
# Source: myapp/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: adventure1-myapp
  labels:
    helm.sh/chart: myapp-0.1.0
    app.kubernetes.io/name: myapp
    app.kubernetes.io/instance: adventure1
    app.kubernetes.io/version: "1.16.0"
    app.kubernetes.io/managed-by: Helm
spec:
  type: ClusterIP
  ports:
    - port: 80
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app.kubernetes.io/name: myapp
    app.kubernetes.io/instance: adventure1
---
# Source: myapp/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: adventure1-myapp
  labels:
    helm.sh/chart: myapp-0.1.0
    app.kubernetes.io/name: myapp
    app.kubernetes.io/instance: adventure1
    app.kubernetes.io/version: "1.16.0"
    app.kubernetes.io/managed-by: Helm
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: myapp
      app.kubernetes.io/instance: adventure1
  template:
    metadata:
      labels:
        app.kubernetes.io/name: myapp
        app.kubernetes.io/instance: adventure1
    spec:
      serviceAccountName: adventure1-myapp
      securityContext:
        {}
      containers:
        - name: myapp
          securityContext:
            {}
          image: "nginx:1.16.0"
          imagePullPolicy: IfNotPresent
          ports:
            - name: http
              containerPort: 80
              protocol: TCP
          livenessProbe:
            httpGet:
              path: /
              port: http
          readinessProbe:
            httpGet:
              path: /
              port: http
          resources:
            {}

將應用資源配置文件推送至Github的Repo

  1. 依次執行以下命令,將myapp應用資源推送的自己的Github賬戶中。
$ git init
Initialized empty Git repository in /home/xiaoyliu-redhat.com/helmstuff/.git/
$ git add *
$ git commit -m "initial commit of helm chart and working manifest"
[master (root-commit) c03cd60] initial commit of helm chart and working manifest
 Committer: GTPE Student <[email protected]>
Your name and email address were configured automatically based
on your username and hostname. Please check that they are accurate.
You can suppress this message by setting them explicitly:
  
    git config --global user.name "Your Name"
    git config --global user.email [email protected]
 
After doing this, you may fix the identity used for this commit with:
  
    git commit --amend --reset-author
   
 11 files changed, 416 insertions(+)
 create mode 100644 manifest/adventure1.yaml
 create mode 100644 myapp/.helmignore
 create mode 100644 myapp/Chart.yaml
 create mode 100644 myapp/templates/NOTES.txt
 create mode 100644 myapp/templates/_helpers.tpl
 create mode 100644 myapp/templates/deployment.yaml
 create mode 100644 myapp/templates/ingress.yaml
 create mode 100644 myapp/templates/service.yaml
 create mode 100644 myapp/templates/serviceaccount.yaml
 create mode 100644 myapp/templates/tests/test-connection.yaml
 create mode 100644 myapp/values.yaml

$ git remote add origin https://github.com/YOUR-GITHUB/gitops-helm-argocd.git
$ git push -u origin master
Username for 'https://github.com': liuxiaoyu-git
Password for 'https://[email protected]':
Counting objects: 17, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (15/15), done.
Writing objects: 100% (17/17), 5.30 KiB | 0 bytes/s, done.
Total 17 (delta 0), reused 0 (delta 0)
To https://github.com/liuxiaoyu-git/gitops-helm-argocd.git
 * [new branch]      master -> master
Branch master set up to track remote branch master from origin.

根據Github的配置創建OpenShift的應用資源

  1. 將Github資源加到ArgoCD中的Repo。
$ argocd repo add https://github.com/YOUR-GITHUB/gitops-helm-argocd.git
repository 'https://github.com/liuxiaoyu-git/gitops-helm-argocd.git' added
$ argocd repo list
TYPE  NAME  REPO                                                     INSECURE  LFS    CREDS  STATUS      MESSAGE
git         https://github.com/liuxiaoyu-git/gitops-helm-argocd.git  false     false  false  Successful
  1. 新建一個名爲adventure1的ArgoCD應用,用它在github中的配置資源與OpenShift中的helmstuff項目建立關聯。
$ argocd app create --project default --name adventure1 --repo https://github.com/liuxiaoyu-git/gitops-helm-argocd.git --path manifest --dest-server https://kubernetes.default.svc --dest-namespace helmstuff --revision master --sync-policy none
application 'adventure1' created
  1. 進入ArgoCD的控制檯,查看adventure1應用。確認當前OpenShift的用資源和Github Repo中的資源是“Synced”的。
    在這裏插入圖片描述

自動調整OpenShift的配置,以保持和Github中的配置同步

  1. 根據名爲adventure1-myapp的OpenShift Service對象市場一個新的對象:adventure1-mybad。
$ oc get svc adventure1-myapp -o json | jq 'del(.spec.clusterIP)' | sed "s/adventure1-myapp/adventure1-mybad/g" | oc create -f -
service/adventure1-mybad created
$ oc get svc
NAME               TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
adventure1-myapp   ClusterIP   172.30.12.170    <none>        80/TCP    3h38m
adventure1-mybad   ClusterIP   172.30.225.179   <none>        80/TCP    10s
  1. 此時可在ArgoCD控制檯中的adventure1應用界面中看到已經是“OutOfSync”狀態,且在名爲adventure1-mybad的Service下方顯示了黃色標記。
    在這裏插入圖片描述
  2. 修改ArgoCD中adventure1應用的配置,然後通過ArgoCD控制檯確認名爲adventure1-mybad的Service已經被刪除。
$ argocd app set adventure1 --sync-policy automated --auto-prune --self-heal
$ oc get svc
NAME               TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
adventure1-myapp   ClusterIP   172.30.12.170   <none>        80/TCP    3h59m
  1. 刪除本項目中OpenShift的Deployment對象,確認ArgoCD會自動根據Github的配置重新創建一個新的Deployment對象。
$ oc delete deployment adventure1-myapp && oc get pods -w
deployment.extensions "adventure1-myapp" deleted
NAME                                READY   STATUS              RESTARTS   AGE
adventure1-myapp-5b64cf64cb-l9p5g   1/1     Terminating         1          3h47m
adventure1-myapp-test-connection    0/1     Completed           0          3h47m
NAME                                READY   STATUS              RESTARTS   AGE
adventure1-myapp-5b64cf64cb-l9p5g   1/1     Terminating         1          3h47m
adventure1-myapp-5b64cf64cb-l9p5g   0/1     Terminating         1          3h47m
adventure1-myapp-5b64cf64cb-l9p5g   0/1     Terminating         1          3h47m
adventure1-myapp-5b64cf64cb-2kf2n   0/1     ContainerCreating   0          10s
adventure1-myapp-5b64cf64cb-2kf2n   0/1     ContainerCreating   0          18s
adventure1-myapp-5b64cf64cb-2kf2n   0/1     Running             0          18s
adventure1-myapp-5b64cf64cb-2kf2n   1/1     Running             0          19s

將Github中的新版配置同步更新至OpenShift

  1. 先設置ArogCD,關閉Github和OpenShift自動同步配置的功能。
$ argocd app set adventure1 --sync-policy none
  1. 修改現有Helm Chart,將version從“0.1.0”改爲“0.1.1”,將appVersion從“1.16.0”改爲“1.16.1”.
$ sed -i 's/1.16.0/1.16.1/g' myapp/Chart.yaml
$ sed -i 's/0.1.0/0.1.1/g' myapp/Chart.yaml
$ cat myapp/Chart.yaml
apiVersion: v2
name: myapp
description: A Helm chart for Kubernetes
 
# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application
  
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
version: 0.1.1
 
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application.
appVersion: 1.16.1
  1. 更新Helm中的adventure1配置,並查看改配置修改前後的變化。
$ helm list
NAME            NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
adventure1      helmstuff       1               2020-03-04 10:45:21.981629148 +0000 UTC deployed        myapp-0.1.0     1.16.0
 
$ helm upgrade adventure1 myapp/
Release "adventure1" has been upgraded. Happy Helming!
NAME: adventure1
LAST DEPLOYED: Wed Mar  4 14:49:11 2020
NAMESPACE: helmstuff
STATUS: deployed
REVISION: 2
NOTES:
(1). Get the application URL by running these commands:
  export POD_NAME=$(kubectl get pods --namespace helmstuff -l "app.kubernetes.io/name=myapp,app.kubernetes.io/instance=adventure1" -o jsonpath="{.items[0].metadata.name}")
  echo "Visit http://127.0.0.1:8080 to use your application"
  kubectl --namespace helmstuff port-forward $POD_NAME 8080:80
 
$ helm list
NAME            NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
adventure1      helmstuff       2               2020-03-04 14:49:11.760250994 +0000 UTC deployed        myapp-0.1.1     1.16.1
  1. 通過命令和控制檯查看ArgoCD的adventure1應用的同步狀態,發現此時對於變化的配置,OpenShift和Github是沒有同步的。
$ argocd app get adventure1
Name:               adventure1
Project:            default
Server:             https://kubernetes.default.svc
Namespace:          helmstuff
URL:                https://argocd-server-argocd.apps.cluster-beijing-b510.beijing-b510.example.opentlc.com/applications/adventure1
Repo:               https://github.com/liuxiaoyu-git/gitops-helm-argocd.git
Target:             master
Path:               manifest
SyncWindow:         Sync Allowed
Sync Policy:        <none>
Sync Status:        OutOfSync from master (c03cd60)
Health Status:      Healthy
 
GROUP  KIND            NAMESPACE  NAME                              STATUS     HEALTH   HOOK  MESSAGE
       Service         helmstuff  adventure1-mybad                  Succeeded  Pruned         pruned
       ServiceAccount  helmstuff  adventure1-myapp                  OutOfSync                 serviceaccount/adventure1-myapp configured. Warning:  apply should be used on resource created by either  create --save-config or  apply
       Service         helmstuff  adventure1-myapp                  OutOfSync  Healthy        service/adventure1-myapp configured. Warning:  apply should be used on resource created by either  create --save-config or  apply
apps   Deployment      helmstuff  adventure1-myapp                  OutOfSync  Healthy        deployment.apps/adventure1-myapp created
       Pod             helmstuff  adventure1-myapp-test-connection             Healthy

在這裏插入圖片描述
5. 在ArdoCD控制檯中查看Service的詳細配置,其中在DIFF中顯示了這個服務在OpenShift和Github的配置差異。
在這裏插入圖片描述
6. 用helm重新生成manifest/adventure1.yaml文件

$ helm get manifest adventure1 > manifest/adventure1.yaml
  1. 比較新舊版adventure1.yaml文件後,將本地變化的配置文件提交到Github。
$ git diff manifest/adventure1.yaml
$ git add *
$ git commit -m "updated app version and manifests"
[master b844df1] updated app version and manifests
 Committer: GTPE Student <[email protected]>
Your name and email address were configured automatically based
on your username and hostname. Please check that they are accurate.
You can suppress this message by setting them explicitly:
 
    git config --global user.name "Your Name"
    git config --global user.email [email protected]
 
After doing this, you may fix the identity used for this commit with:
 
    git commit --amend --reset-author
 
 2 files changed, 9 insertions(+), 9 deletions(-)
 
$ git push origin master
Username for 'https://github.com': liuxiaoyu-git
Password for 'https://[email protected]':
Counting objects: 11, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (6/6), 534 bytes | 0 bytes/s, done.
Total 6 (delta 3), reused 0 (delta 0)
remote: Resolving deltas: 100% (3/3), completed with 3 local objects.
To https://github.com/liuxiaoyu-git/gitops-helm-argocd.git
   c03cd60..b844df1  master -> master
  1. 再次打開ArgoCD的同步選項,然後在ArgoCD控制檯中確認應用的狀態應爲“Synced”狀態。
$ argocd app set adventure1 --sync-policy automated --auto-prune --self-heal

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章