软件说明:
- kustomize v3.8.6:yaml 管理
- argocdv1.7.8 : 软件发布
- Jenkins:流水线提供给研发操作页面
架构图:
https://github.com/yehecarry/EKS-Doc/blob/master/picture/Gitops.png
说明文档:
==注意:如下是Dev环境的说明==
首先我使用了argocd官方推荐的App in Apps 的管理方式(下面有些套娃)
首先我用一个yaml声明文件维护了一个父App,这个父App的作用是声明Git仓库中的一个App环境(Helm)这个Helm里编写的创建一堆ArgoApp,而这些App是通过GIt仓库中另一个目录里编写的Kustomize生成的(是不是很绕,没错,是挺绕的,多读几遍)
声明式文件如下:
父APP:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: dev-nicee-as1-test
namespace: argocd
spec:
project: ap-southeast-1-eks-test
source:
repoURL: https://git.xxx.xxx/devops/argocd-gitops.git
targetRevision: master
# 这里是Helm仓库的地址,存的是一个业务所有的argocd app 声明文件
path: apps/eks-test/dev/dev-server
destination:
server: https://kubernetes.default.svc
namespace: argocd
# Sync policy
syncPolicy:
automated:
prune: true
selfHeal: true
allowEmpty: false
syncOptions:
- Validate=false
- CreateNamespace=true
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3m
子App:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: dev-server-api
namespace: argocd
spec:
project: ap-southeast-1-eks-test
source:
repoURL: http://git.xxx.xxx/devops/argocd-gitops.git
targetRevision: master
# 这里存的是真正业务的Yaml文件我是使用Kustomize 去编写的
path: eks-test/server/overlays/dev/server-1
destination:
server: {{ .Values.spec.destination.server }}
namespace: dev-nicee
# Sync policy
syncPolicy: automated:
prune: true selfHeal: true
allowEmpty: false
syncOptions:
- Validate=false
- CreateNamespace=true
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3m
当我们创建成功之后就会看到如下的逻辑,首先我们生成了一个父App,父App会自动创建所有的子App
之后在我们定义的namespace中我们看到了另一个Namespace中就创建了一堆子App,因为是Dev环境,所以我们是自动同步的,这样就在瞬间会拉起所有的Dev环境
这样我们就使用Gitops的方式维护了整套的Dev环境,当然既然是Dev环境我们肯定会有这种需求,晚上下班后关闭集群这样就可以使用一个脚本+计划任务的方式设置自动关闭,手动就使用Jenkins 操作脚本给研发提供一个页面的方式让研发可以在紧急的时候拉起Dev环境,脚本如下
import os
import subprocess
import json
def exec_shell(cmd):
sub2 = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
stdout, stderr = sub2.communicate()
ret = sub2.returncode
return ret, stdout.decode('utf-8').strip()
def remove_apps(apps_name):
ret = exec_shell("kubectl get app %s -n argocd -o json" % apps_name)[1]
app_dict = json.loads(ret)["status"]["resources"]
for app_name in app_dict:
app_name = app_name["name"].encode('utf-8')
exec_shell("kubectl patch app %s -n argocd -p '{\"metadata\": {\"finalizers\": [\"resources-finalizer.argocd.argoproj.io\"]}}' --type merge" % app_name)
exec_shell("kubectl patch app %s -n argocd -p '{\"metadata\": {\"finalizers\": [\"resources-finalizer.argocd.argoproj.io\"]}}' --type merge" % apps_name)
exec_shell("kubectl delete app %s -n argocd" % apps_name)
if __name__ == '__main__':
remove_apps("dev-xxx-as1-test")
在多说一嘴如果你跟我一样是在AWS上使用的EKS集群,那么Dev与Test环境完全可以跑在Spot实例上,很便宜