运行环境
1. 根据我头条《OpenShift 4 之 GitOps(2)》安装ArgoCD服务器环境。
2. 根据我头条《OpenShift 4.3 之新特性 - 使用Helm部署OpenShift应用》一文安装helm客户端即可。
用Helm创建样例Chart
1. 创建名为myapp的helm chart,然后可以查看chart中的deployment.yaml。
$ mkdir helmstuff$ cd helmstuff/ $ helm create myappCreating myapp$ find myapp/myapp/myapp/Chart.yamlmyapp/values.yamlmyapp/.helmignoremyapp/templatesmyapp/templates/ingress.yamlmyapp/templates/deployment.yamlmyapp/templates/service.yamlmyapp/templates/serviceaccount.yamlmyapp/templates/NOTES.txtmyapp/templates/_helpers.tplmyapp/templates/testsmyapp/templates/tests/test-connection.yamlmyapp/charts
# 根据Helm Chart安装OpenShift应用
1. 创建OpenShift的helmstuff项目,然后通过helm安装应用。
$ oc new-project helmstuff$ helm install adventure1 myapp/ -n helmstuffNAME: adventure1LAST DEPLOYED: Wed Mar 4 10:37:09 2020NAMESPACE: helmstuffSTATUS: deployedREVISION: 1NOTES:(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
2. 查看Helm列表。
$ helm listNAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSIONadventure1 helmstuff 1 2020-03-04 10:37:09.669437379 +0000 UTC deployed myapp-0.1.0 1.16.0
3. 查看pod状态为CrashLoopBackOff,然后helm中的adventure1,确认结果报错“Error: pod
adventure1-myapp-test-connection failed”。
```bash$ oc get podNAME READY STATUS RESTARTS AGEadventure1-myapp-5b64cf64cb-r65fk 0/1 CrashLoopBackOff 1 32s $ helm test adventure1Pod adventure1-myapp-test-connection pendingPod adventure1-myapp-test-connection pendingPod adventure1-myapp-test-connection pendingPod adventure1-myapp-test-connection pendingPod adventure1-myapp-test-connection runningNAME: adventure1LAST DEPLOYED: Wed Mar 4 10:37:09 2020NAMESPACE: helmstuffSTATUS: deployedREVISION: 1TEST SUITE: adventure1-myapp-test-connectionLast Started: Wed Mar 4 10:38:18 2020Last Completed: Wed Mar 4 10:38:29 2020Phase: FailedNOTES:(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:80Error: pod adventure1-myapp-test-connection failed```
4. 上面错误是由于权限问题。执行以下命令为容器中的操作用户提权。
$ oc adm policy add-scc-to-user anyuid -z adventure1-myappsecuritycontextconstraints.security.openshift.io/anyuid added to: ["system:serviceaccount:helmstuff:adventure1-myapp"]
5. 先从helm中删除adventure1,然后重新创建helm的adventure1,最后再用helm测试adventure1,确认这次可测通过。
$ helm uninstall adventure1release "adventure1" uninstalled $ helm install adventure1 myapp/NAME: adventure1LAST DEPLOYED: Wed Mar 4 10:45:21 2020NAMESPACE: helmstuffSTATUS: deployedREVISION: 1NOTES:(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 adventure1Pod adventure1-myapp-test-connection pendingPod adventure1-myapp-test-connection pendingPod adventure1-myapp-test-connection pendingPod adventure1-myapp-test-connection pendingPod adventure1-myapp-test-connection succeededNAME: adventure1LAST DEPLOYED: Wed Mar 4 10:45:21 2020NAMESPACE: helmstuffSTATUS: deployedREVISION: 1TEST SUITE: adventure1-myapp-test-connectionLast Started: Wed Mar 4 10:45:40 2020Last Completed: Wed Mar 4 10:45:50 2020Phase: SucceededNOTES:(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
2. 查看导出的manifest/adventure1.yaml文件内容。
$ cat manifest/adventure1.yaml
将应用资源配置文件推送至Github的Repo
1. 依次执行以下命令,将myapp应用资源推送的自己的Github账户中。
$ git initInitialized 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 Your name and email address were configured automatically basedon 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 you@example.com 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 masterUsername for 'https://github.com': liuxiaoyu-gitPassword for 'https://liuxiaoyu-git@github.com':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 -> masterBranch 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.gitrepository 'https://github.com/liuxiaoyu-git/gitops-helm-argocd.git' added$ argocd repo listTYPE NAME REPO INSECURE LFS CREDS STATUS MESSAGEgit https://github.com/liuxiaoyu-git/gitops-helm-argocd.git false false false Successful
2. 新建一个名为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 noneapplication 'adventure1' created
3. 进入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 svcNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEadventure1-myapp ClusterIP 172.30.12.170 80/TCP 3h38madventure1-mybad ClusterIP 172.30.225.179 80/TCP 10s
2. 此时可在ArgoCD控制台中的adventure1应用界面中看到已经是“OutOfSync”状态,且在名为adventure1-mybad的Service下方显示了黄色标记。
3. 修改ArgoCD中adventure1应用的配置,然后通过ArgoCD控制台确认名为adventure1-mybad的Service已经被删除。
$ argocd app set adventure1 --sync-policy automated --auto-prune --self-heal$ oc get svcNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEadventure1-myapp ClusterIP 172.30.12.170 80/TCP 3h59m
4. 删除本项目中OpenShift的Deployment对象,确认ArgoCD会自动根据Github的配置重新创建一个新的Deployment对象。
$ oc delete deployment adventure1-myapp && oc get pods -wdeployment.extensions "adventure1-myapp" deletedNAME READY STATUS RESTARTS AGEadventure1-myapp-5b64cf64cb-l9p5g 1/1 Terminating 1 3h47madventure1-myapp-test-connection 0/1 Completed 0 3h47mNAME READY STATUS RESTARTS AGEadventure1-myapp-5b64cf64cb-l9p5g 1/1 Terminating 1 3h47madventure1-myapp-5b64cf64cb-l9p5g 0/1 Terminating 1 3h47madventure1-myapp-5b64cf64cb-l9p5g 0/1 Terminating 1 3h47madventure1-myapp-5b64cf64cb-2kf2n 0/1 ContainerCreating 0 10sadventure1-myapp-5b64cf64cb-2kf2n 0/1 ContainerCreating 0 18sadventure1-myapp-5b64cf64cb-2kf2n 0/1 Running 0 18sadventure1-myapp-5b64cf64cb-2kf2n 1/1 Running 0 19s
将Github中的新版配置同步更新至OpenShift
1. 先设置ArogCD,关闭Github和OpenShift自动同步配置的功能。
$ argocd app set adventure1 --sync-policy none
2. 修改现有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
3. 更新Helm中的adventure1配置,并查看改配置修改前后的变化。
$ helm listNAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSIONadventure1 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: adventure1LAST DEPLOYED: Wed Mar 4 14:49:11 2020NAMESPACE: helmstuffSTATUS: deployedREVISION: 2NOTES:(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 listNAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSIONadventure1 helmstuff 2 2020-03-04 14:49:11.760250994 +0000 UTC deployed myapp-0.1.1 1.16.1
4. 通过命令和控制台查看ArgoCD的adventure1应用的同步状态,发现此时对于变化的配置,OpenShift和Github是没有同步的。
$ argocd app get adventure1Name: adventure1Project: defaultServer: https://kubernetes.default.svcNamespace: helmstuffURL: https://argocd-server-argocd.apps.cluster-beijing-b510.beijing-b510.example.opentlc.com/applications/adventure1Repo: https://github.com/liuxiaoyu-git/gitops-helm-argocd.gitTarget: masterPath: manifestSyncWindow: Sync AllowedSync Policy: 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 applyapps 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
7. 比较新旧版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 Your name and email address were configured automatically basedon 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 you@example.com 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 masterUsername for 'https://github.com': liuxiaoyu-gitPassword for 'https://liuxiaoyu-git@github.com':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
8. 再次打开ArgoCD的同步选项,然后在ArgoCD控制台中确认应用的状态应为“Synced”状态。
$ argocd app set adventure1 --sync-policy automated --auto-prune --self-heal