CD 成功 一同窗习经常使用 GitOps Argo
Argo CD 是一个为 Kubernetes 而生的,遵照申明式 GitOps 理念的继续部署工具。Argo CD 可在 Git 存储库更改时智能同步和部署运行程序。
Argo CD 可在指定的目的环境中智能部署所需的运行程序形态,运行程序部署可以在 Git 提交时跟踪对分支、标签的更新,或固定到清单的指定版本。
ArgoCD架构
Argo CD 是经过 Kubernetes 控制器来成功的,它继续 watch 正在运转的运行程序并将的实时形态与所需的目的形态( Git 存储库中指定的)启动比拟。曾经部署的运行程序的实践形态与目的形态有差异,则被以为是形态,Argo CD 会报告显示这些差异,同时提供工具来智能或手动将形态同步到希冀的目的形态。在 Git 仓库中对希冀目的形态所做的任何修正都可以智能运行反应到指定的目的环境中去。
上方繁难引见下 Argo CD 中的几个重要组件:
API 服务 :API 服务是一个 gRPC/REST 服务,它暴露了 Web UI、CLI 和 CI/CD 系统经常使用的接口,重要有以下几特性能:
仓库服务 :存储仓库服务是一个外部服务,担任保养保留运行程序清单 Git 仓库的本地缓存。当提供以下输入时,它担任生成并前往 Kubernetes 清单:
运行控制器 :运行控制器是一个 Kubernetes 控制器,它继续 watch 正在运转的运行程序并将的实时形态与所希冀的目的形态(repo 中指定的)启动比拟。它检测运行程序的形态,并采取一些措施来同步形态,它担任调用任何用户定义的生命周期事情的钩子(PreSync、Sync、PostSync)。
当然前提是须要有一个 kubectl 可访问的 Kubernetes 的集群,间接经常使用上方的命令即可,这里咱们装置最新的 v2.8.4 版本:
$ kubectl create namespace argocd$ kubectl apply -n argocd -f
假设你要用在消费环境,则可以经常使用上方的命令部署一个 HA 高可用的版本:
$ kubectl create namespace argocd$ kubectl apply -n argocd -f
这将创立一个新的命名空间 argocd,Argo CD 的服务和运行资源都将部署到该命名空间。
$ kubectl get pods -n argocdNAMEREADYSTATUSRESTARTSAGEargocd-application-controller-01/1Running0103sargocd-applicationset-controller-68b9bdbd8b-jzcpf1/1Running0103sargocd-dex-server-6b7745757-6mxwk1/1Running0103sargocd-notifications-controller-5b56f6f7bb-jqpng1/1Running0103sargocd-redis-f4cdbff57-dr8jc1/1Running0103sargocd-repo-server-c4f79b4d6-7nh6n1/1Running0103sargocd-server-895675597-fr42g1/1Running0103s
而后咱们可以在本地(选用对应的版本)装置 CLI 工具繁难操作 Argo CD:
$ curl -sSL -o /usr/local/bin/argocd
为 argocd CLI 赋予可口头权限:
$ chmod +x /usr/local/bin/argocd
如今咱们就可以经常使用argocd命令了。假设你是 Mac,则可以间接经常使用brew install argocd启动装置。
Argo CD 会运转一个 gRPC 服务(由 CLI 经常使用)和 HTTP/HTTPS 服务(由 UI 经常使用),这两种协定都由argocd-server服务在以下端口启动暴露:
咱们可以经过性能 Ingress 的方式来对外暴露服务,其余 Ingress 控制器的性能可以参考官网文档启动性能。
Argo CD 在同一端口 (443) 上提供多个协定 (gRPC/HTTPS),所以当咱们为 argocd 服务定义单个 nginx ingress 对象和规定的时刻有点费事,由于nginx.ingress.kubernetes.io/backend-protocol这个 annotation 只能接受一个后端协定(例如 HTTP、HTTPS、GRPC、GRPCS)。
为了经常使用单个 ingress 规定和主机名来暴露 Argo CD APIServer,必定经常使用nginx.ingress.kubernetes.io/ssl-passthrough这个annotation来传递 TLS 衔接并校验 Argo CD APIServer 上的 TLS。
apiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: argocd-server-ingressnamespace: argocdannotations:nginx.ingress.kubernetes.io/force-ssl-redirect: "true"nginx.ingress.kubernetes.io/ssl-passthrough: "true"spec:ingressClassName: nginxrules:- host: argocd.k8s.localhttp:paths:- path: /pathType: Prefixbackend:service:name: argocd-serverport:name: https
上述规定在 Argo CD APIServer 上校验 TLS,该主机检测到正在经常使用的协定,并做出适当的照应。请留意,nginx.ingress.kubernetes.io/ssl-passthrough注解要求将--enable-ssl-passthrough标记减少到nginx-ingress-controller的命令行参数中。
由于ingress-nginx的每个 Ingress 对象仅支持一个协定,因此另一种方法是定义两个 Ingress 对象。一个用于 HTTP/HTTPS,另一个用于 gRPC。
如下所示为 HTTP/HTTPS 的 Ingress 对象:
apiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: argocd-server-http-ingressnamespace: argocdannotations:nginx.ingress.kubernetes.io/force-ssl-redirect: "true"nginx.ingress.kubernetes.io/backend-protocol: "HTTP"spec:ingressClassName: nginxrules:- http:paths:- path: /pathType: Prefixbackend:service:name: argocd-serverport:name: httphost: argocd.k8s.localtls:- hosts:- argocd.k8s.localsecretName: argocd-secret # do not change, this is provided by Argo CD
gRPC 协定对应的 Ingress 对象如下所示:
apiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: argocd-server-grpc-ingressnamespace: argocdannotations:nginx.ingress.kubernetes.io/backend-protocol: "GRPC"spec:ingressClassName: nginxrules:- http:paths:- path: /pathType: Prefixbackend:service:name: argocd-serverport:name: httpshost: grpc.argocd.k8s.localtls:- hosts:- grpc.argocd.k8s.localsecretName: argocd-secret # do not change, this is provided by Argo CD
而后咱们须要在禁用 TLS 的状况下运转 APIServer。编辑 argocd-server 这个 Deployment 以将--insecure标记减少到 argocd-server 命令,或许繁难地在argocd-cmd-params-cmConfigMap 中设置server.insecure: "true"即可。
创立成功后,咱们就可以经过argocd.k8s.local来访问 Argo CD 服务了,不过须要留意咱们这里性能的证书是自签名的,所以在第一次性访问的时刻会揭示不安保,强迫跳转即可。
安保揭示
自动状况下admin帐号的初始明码是智能生成的,会以明文的方式存储在 Argo CD 装置的命名空间中名为argocd-initial-admin-secret的 Secret 对象下的password字段下,咱们可以用上方的命令来失掉:
$ kubectl -n argocd get secret argocd-initial-admin-secret -o jsnotallow="{.data.password}" | base64 -d && echo
经常使用用户名admin和上方输入的明码即可登录 Dashboard。
自动的如下所示:
argocd
雷同咱们也可以经过 ArgoCD CLI 命令行工具启动登录:
$ argocd login grpc.argocd.k8s.localWARNING: server certificate had error: tls: failed to verify certificate: x509: certificate signed by unknown authority. Proceed insecurely (y/n)? yUsername: adminPassword:'admin:login' logged in successfullyContext 'grpc.argocd.k8s.local' updated
须要留意的是这里登录的地址为 gRPC 暴露的服务地址。
CLI 登录成功后,可以经常使用如下所示命令更改明码:
$ argocd account update-password*** Enter current password:*** Enter new password:*** Confirm new password:Password updatedContext 'argocd.k8s.local' updated$ argocd versionargocd: v2.12.3+6b9cd82BuildDate: 2024-08-27T15:31:43ZGitCommit: 6b9cd828c6e9807398869ad5ac44efd2c28422d6GitTreeState: cleanGoVersion: go1.23.0Compiler: gcPlatform: darwin/arm64argocd-server: v2.12.3+6b9cd82BuildDate: 2024-08-27T11:57:48ZGitCommit: 6b9cd828c6e9807398869ad5ac44efd2c28422d6GitTreeState: cleanGoVersion: go1.22.4Compiler: gcPlatform: linux/amd64Kustomize Version: v5.4.2 2024-05-22T15:19:38ZHelm Version: v3.15.2+g1a500d5Kubectl Version: v0.29.6Jsonnet Version: v0.20.0
由于 Argo CD 支持部署运行到多集群,所以假设你要将运行部署到外部集群的时刻,须要先将外部集群的认证信息注册到 Argo CD 中,假设是在外部部署(运转 Argo CD 的同一个集群,自动不须要性能),间接经常使用作为运行的 K8S APIServer 地址即可。
首先列出kubeconfig中的一切集群高低文:
$ kubectl config get-contexts -o namekubernetes-admin@kubernetesorbstack
从列表当选用一个高低文称号并将其提供应argocd cluster add CONTEXTNAME,比如关于orbstack高低文,运转:
$ argocd cluster listSERVERNAMEVERSIONSTATUSMESSAGEPROJECT$ argocd cluster add orbstack
Git 仓库是一个蕴含留言簿运行程序的示例库,咱们可以用该运行来演示 Argo CD 的上班原理。
咱们可以经过argocd app create xxx命令来创立一个运行:
$ argocd app create --helpCreate an applicationUsage:argocd app create APPNAME [flags]Examples:# Create a directory appargocd app create guestbook --repo--path guestbook --dest-namespace default --dest-server--directory-recurse# Create a Jsonnet appargocd app create jsonnet-guestbook --repo--path jsonnet-guestbook --dest-namespace default --dest-server--jsonnet-ext-str replicas=2# Create a Helm appargocd app create helm-guestbook --repo--path helm-guestbook --dest-namespace default --dest-server--helm-set replicaCount=2# Create a Helm app from a Helm repoargocd app create nginx-ingress --repo--helm-chart nginx-ingress --revision 1.24.3 --dest-namespace default --dest-serverCreate a Kustomize appargocd app create kustomize-guestbook --repo--path kustomize-guestbook --dest-namespace default --dest-server--kustomize-image gcr.io/heptio-images/ks-guestbook-demo:0.1# Create a app using a custom tool:argocd app create kasane --repo--path plugins/kasane --dest-namespace default --dest-server--config-management-plugin kasaneFlags:......
间接口头如下所示命令即可:
$ argocd app create guestbook --repo--path guestbook --dest-server--dest-namespace defaultapplication 'guestbook' created
除了可以经过 CLI 工具来创立运行,咱们也可以经过 UI 界面来创立,定位到argocd.k8s.local页面,登录后,点击+New App新建运行按钮。将运行命名为 guestbook,经常使用 default project,并将同步战略设置为Manual:
性能运行
而后在上方性能Repository URL为,由于某些要素咱们这里经常使用的是 Gitee 仓库地址,将 Revision 设置为 HEAD,并将门路设置为 guestbook。而后上方的 Destination 局部,将 cluster 设置为inCluster和 namespace 为 default:
性能集群
填写完以上信息后,点击页面上方的 Create 装置,即可创立 guestbook 运行,创立成功后可以看到运行的处于OutOfSync形态:
guestbook application
Argo CD 自动状况下每 3 分钟会检测 Git 仓库一次性,用于判别运行实践形态能否和 Git 中申明的希冀形态分歧,假设不分歧,形态就转换为OutOfSync。自动状况下并不会触发更新,除非经过syncPolicy性能了智能同步。
除了可以经过 CLI 和 Dashboard 可以创立 Application 之外,其实也可以间接经过申明一个
Application
的资源对象来创立一个运行,如下所示:
apiVersion: argoproj.io/v1alpha1kind: Applicationmetadata:name: guestbookspec:destination:namespace: defaultserver: "https://kubernetes.default.svc"source:path: guestbookrepoURL: "https://github.com/cnych/argocd-example-apps"targetRevision: HEADproject: defaultsyncPolicy:automated: null
由于上方咱们在创立运行的时刻经常使用的同步战略为Manual,所以运行创立成功后没有智能部署,须要咱们手动去部署运行。雷同可以经过 CLI 和 UI 界面两种同步方式。
运行创立成功后,咱们可以经过如下所示命令检查其形态:
$ argocd app get argocd/guestbookName:argocd/guestbookProject:defaultServer:Repo:AllowedSync Policy:ManualSync Status:OutOfSync from HEAD (3b08dd4)Health Status:MissingGROUPKINDNAMESPACENAMESTATUSHEALTHHOOKMESSAGEServicedefaultguestbook-uiOutOfSyncMissingappsDeploymentdefaultguestbook-uiOutOfSyncMissing
运行程序形态为初始OutOfSync形态,由于运行程序尚未部署,并且尚未创立任何 Kubernetes 资源。要同步(部署)运行程序,可以口头如下所示命令:
$ argocd app sync argocd/guestbookTIMESTAMPGROUPKINDNAMESPACENAMESTATUSHEALTHHOOKMESSAGE2024-09-08T10:42:02+08:00Servicedefaultguestbook-uiOutOfSyncMissing2024-09-08T10:42:02+08:00appsDeploymentdefaultguestbook-uiOutOfSyncMissing2024-09-08T10:42:03+08:00Servicedefaultguestbook-uiOutOfSyncMissingservice/guestbook-ui created2024-09-08T10:42:03+08:00appsDeploymentdefaultguestbook-uiOutOfSyncMissingdeployment.apps/guestbook-ui created2024-09-08T10:42:03+08:00Servicedefaultguestbook-uiSyncedHealthyservice/guestbook-ui created2024-09-08T10:42:03+08:00appsDeploymentdefaultguestbook-uiSyncedProgressingdeployment.apps/guestbook-ui createdName:argocd/guestbookProject:defaultServer:Repo:AllowedSync Policy:ManualSync Status:Synced to HEAD (3b08dd4)Health Status:ProgressingOperation:SyncSync Revision:3b08dd4969319e053d9cab2a02f949abc9f4aa45Phase:SucceededStart:2024-09-08 10:42:02 +0800 CSTFinished:2024-09-08 10:42:03 +0800 CSTDuration:1sMessage:successfully synced (all tasks run)GROUPKINDNAMESPACENAMESTATUSHEALTHHOOKMESSAGEServicedefaultguestbook-uiSyncedHealthyservice/guestbook-ui createdappsDeploymentdefaultguestbook-uiSyncedProgressingdeployment.apps/guestbook-ui created
此命令从 Git 仓库中检索资源清单并口头kubectl apply部署运行,口头上方命令后 guestbook 运行便会运转在集群中了,如今咱们就可以检查其资源组件、日志、事情和评价其肥壮形态了。
间接减少 UI 界面上运行的Sync按钮即可开局同步:
sync 操作
同步成功后可以看到咱们的资源形态,甚至还可以间接检查运行的日志信息:
Sync 成功
也可以经过 kubectl 检查到咱们部署的资源:
$ kubectl get podsNAMEREADYSTATUSRESTARTSAGEguestbook-ui-6c96fb4bdc-bdwh91/1Running03m3s➜~ kubectl get svcNAMETYPECLUSTER-IPEXTERNAL-IPPORT(S)AGEguestbook-uiClusterIP10.100.170.117<none>80/TCP3m16skubernetesClusterIP10.96.0.1<none>443/TCP42d
和咱们从 Git 仓库中同步guestbook目录上方的资源形态也是同步的,证实同步成功了。
假设有多个团队,每个团队都要保养少量的运行,就须要用到 Argo CD 的另一个概念:名目(Project)。Argo CD 中的名目(Project)可以用来对 Application 启动分组,不同的团队经常使用不同的名目,这样就成功了多租户环境。名目还支持更细粒度的访问权限控制:
比如咱们这里创立一个名为demo的名目,将该运行创立到该名目下,只有创立一个如下所示的AppProject对象即可:
apiVersion: argoproj.io/v1alpha1kind: AppProjectmetadata:# 名目名name: demonamespace: argocdspec:# 目的destinations:# 此名目的服务准许部署的 namespace,这里为所有- namespace: "*"# 此名目准许部署的集群,这里为自动集群,即为Argo CD部署的集群server:准许的数据源sourceRepos:-
该对象中有几个外围的属性:
间接创立该对象即可:
$ kubectl get appproject -n argocdNAMEAGEdefault47hdemo6s
更多性能信息可以前往文档检查,名目创立成功后,在该名目下创立一个 Application,代表环境中部署的运行程序实例。
apiVersion: argoproj.io/v1alpha1kind: Applicationmetadata:name: gitops-demonamespace: argocdspec:destination:namespace: defaultserver: "https://kubernetes.default.svc"project: demosyncPolicy:automated:prune: trueselfHeal: truesource:path: helm-guestbook # 从 Helm 存储库创立运行程序时,chart 必定指定 pathrepoURL: "https://gitee.com/cnych/argocd-example-apps.git"targetRevision: HEADhelm:parameters:- name: replicaCountvalue: "2"valueFiles:- values.yaml
这里咱们定义了一个名为gitop-demo的运行,运行源来自于 helm 门路,经常使用的是values.yaml文件,此外还可以经过source.helm.parameters来性能参数。
同步战略可以选用经常使用智能的方式,该战略上方还有两个属性可以性能:
删除资源
智能康复
反常创立后这个运行就会智能部署了,依据咱们性能会生成两个正本。
由于 Argo CD 自动并不是实时去监测 Config Repo 的变动的,假设要更快的检测到变动咱们可以经常使用 Git Webhook 的方式。
自动状况下 Argo CD 每三分钟轮询一次性 Git 存储库,以检测清单的更改。为了消弭轮询提前,可以将 API 主机性能为接纳 Webhook 事情。Argo CD 支持来自 GitHub、GitLab、Bitbucket、Bitbucket Server 和 Gogs 的 Git webhook 通知。
而后在argocd-secret这个 Kubernetes Secret 中,经常使用上方性能的 Git 提供商的 Webhook 密钥性能以下密钥之一。
gitlab token
$ kubectl edit secret argocd-secret -n argocdapiVersion: v1kind: Secretmetadata:name: argocd-secretnamespace: argocdtype: Opaquedata:...stringData:# github webhook secretwebhook.github.secret: shhhh! it's a GitHub secret# gitlab webhook secretwebhook.gitlab.secret: shhhh! it's a GitLab secret# bitbucket webhook secretwebhook.bitbucket.uuid: your-bitbucket-uuid# bitbucket server webhook secretwebhook.bitbucketserver.secret: shhhh! it's a Bitbucket server secret# gogs server webhook secretwebhook.gogs.secret: shhhh! it's a gogs server secret
可以间接经常使用stringData来性能 secret,这样就不用去手动编码了。
由于 GitOps 的外围是 Git,所以咱们必定要将部署到集群中的资源清单文件全都托管到 Git 仓库中,这样能力成功 GitOps 的智能同步部署。上方咱们是在 CI 流水线中去修正 Git 仓库中的资源清单文件,其实咱们也可以经过其余方式去修正,比如 Argo CD 也提供了一个新的工具 Argo CD Image Updater。
ApplicationSet用于简化多集群运行编排,它可以基于繁多运行编排并依据用户的编排内容智能生成一个或多个Application。
比如如今咱们创立一个如下所示的ApplicationSet资源对象:
# applicationset.yamlapiVersion: argoproj.io/v1alpha1kind: ApplicationSetmetadata:name: guestbookspec:goTemplate: true # 经常使用 go template 模板goTemplateOptions: ["missingkey=error"] # 当模板中缺少键时,抛出失误generators: # 生成器,用于生成参数- list: # 列表生成器elements: # 元素- cluster: devurl:cluster: stagingurl:cluster: produrl:"{{.cluster}}-guestbook"spec:project: demosource:repoURL:HEADpath: helm-guestbookhelm:valueFiles:- "{{.cluster}}.yaml"syncPolicy:syncOptions:- CreateNamespace=truedestination:server: "{{.url}}"namespace: guestbook
在上方的资源对象中,咱们定义了一个ApplicationSet资源对象,其中经常使用了模板和生成器:
这里咱们经过列表生成器定义了多个生成器元素,外面蕴含cluster和url两个参数,ApplicationSet控制器会依据这些参数生成多个Application资源对象,每个Application资源对象都会部署到对应的集群和命名空间中,每个Application资源就是经过这些参数将模板中的内容渲染生成。
无论经常使用哪个生成器,生成器生成的参数都会交流为ApplicationSet资源的 template: 局部中的{{parameter name}}值。咱们这里列表生成器定义了cluster和url参数,而后将它们区分交流为模板的{{cluster}}和{{url}}值。
咱们可以间接经常使用argocd appset命令来创立:
$ argocd appset create applicationset.yamlApplicationSet 'guestbook' created$ argocd appset listNAMEPROJECTSYNCPOLICYCONDITIONSREPOPATHTARGETargocd/guestbookdemonil[{ParametersGenerated Successfully generated parameters for all Applications 2024-09-08 11:48:52 +0800 CST True ParametersGenerated} {ResourcesUpToDate ApplicationSet up to date 2024-09-08 11:48:52 +0800 CST True ApplicationSetUpToDate}]
创立成功后可以经过argocd appset list检查ApplicationSet资源对象的形态,从上方输入可以看到ApplicationSet资源对象的形态为ParametersGenerated,示意参数曾经生成成功,也就是曾经将ApplicationSet资源对象中的内容渲染生成多个Application资源对象了。检查下Application资源对象的形态即可:
$ argocd argocd app listNAMECLUSTERNAMESPACEPROJECTSTATUSHEALTHSYNCPOLICYCONDITIONSREPOPATHTARGETargocd/dev-guestbook
可以看到如今渲染了 3 个Application资源对象,和咱们前面在ApplicationSet资源对象中定义的集群和 URL 是逐一对应的,当然咱们也可以在 Dashboard 界面中检查:
app list status