Argocd核心概念及高可用部署

本文最后更新于:June 7, 2024 pm

Argo CD是一个开源的GitOps工具,用于自动化部署、操作和观察基于Kubernetes的应用程序和配置,提供声明式应用程序定义、多环境支持、应用程序状态监控、RBAC和安全性、插件和扩展性等功能。通过与Git集成,它实现了将应用程序和配置定义存储在Git存储库中,并将其自动同步到Kubernetes环境,实现应用程序的自动化部署和更新。

本文主要介绍argocd的基础架构和核心概念,同时会手把手进行高可用部署并进行初始化配置和应用部署,文章较长,有兴趣的同学可以根据目录进行跳转阅读。

1、部署argocd

我们可以参考argocd官网的快速开始指南,在开始之前我们需要先准备一个能够正常使用的K8S集群,我们这里使用的是1.27.0版本的社区原生K8S进行部署。

1
2
3
4
5
6
7
8
$ kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
k8s-10-31-90-1.tinychen.io Ready control-plane 96d v1.27.0 10.31.90.1 <none> CentOS Linux 7 (Core) 6.1.4-1.el7.elrepo.x86_64 containerd://1.6.14
k8s-10-31-90-2.tinychen.io Ready control-plane 96d v1.27.0 10.31.90.2 <none> CentOS Linux 7 (Core) 6.1.4-1.el7.elrepo.x86_64 containerd://1.6.14
k8s-10-31-90-3.tinychen.io Ready control-plane 96d v1.27.0 10.31.90.3 <none> CentOS Linux 7 (Core) 6.1.4-1.el7.elrepo.x86_64 containerd://1.6.14
k8s-10-31-90-4.tinychen.io Ready <none> 96d v1.27.0 10.31.90.4 <none> CentOS Linux 7 (Core) 6.1.4-1.el7.elrepo.x86_64 containerd://1.6.14
k8s-10-31-90-5.tinychen.io Ready <none> 96d v1.27.0 10.31.90.5 <none> CentOS Linux 7 (Core) 6.1.4-1.el7.elrepo.x86_64 containerd://1.6.14
k8s-10-31-90-6.tinychen.io Ready <none> 96d v1.27.0 10.31.90.6 <none> CentOS Linux 7 (Core) 6.1.4-1.el7.elrepo.x86_64 containerd://1.6.14

该集群使用cilium作为CNI,containerd作为CRI,注意部署argocd并不需要用到持久化存储,但是最好能有一种手段用来暴露argocd的api接口(如四层的loadbalance或者七层的ingress/apigateway等)。

2、架构组件

先来看一下官方提供的这个架构图,注意默认情况下Argo CD部署时会配置多种组件和Kubernetes controllers。这些Kubernetes controllers更倾向于CRD而不是模块化的组件,因此在架构图中并没有将其表现出来,与此相似的还有一些如configmap、service、secret的配置。

官方的架构图中将整个Argo CD系统分为四个逻辑层级:UI、Application、Core和Infra。逻辑层还有助于使图表更易于理解,因为依赖关系以自上而下的关系表示。这意味着来自顶层的组件将被允许依赖于来自任何底层的任何组件。然而,来自底层的组件永远不会依赖于来自上层的任何组件。

  • UI:这是表示层。用户主要通过这一层的组件与 Argo CD 进行交互(包括WebUI和CLI)。
  • Application:支持来自 UI 层的组件所需的功能。
  • Core:主要的 Argo CD gitops 功能由核心层的组件和 Kubernetes 控制器实现。
  • Infra:表示 Argo CD 作为其基础设施的一部分所依赖的工具。

以下是各个组件的主要职责,我们在平时维护的时候可以根据这些信息来快速定位故障:

  • Webapp:Argo CD 附带一个强大的 Web 界面,允许管理部署在给定 Kubernetes 集群中的应用程序;
  • CLI:Argo CD 提供了一个 CLI,用户可以使用它与 Argo CD API 进行交互。 CLI 还可用于自动化和脚本编写;
  • API Server:定义由 Argo CD 公开的专有 API,该 API 为 Web 应用程序和 CLI 功能提供支持;
  • Application Controller:应用程序控制器负责协调 Kubernetes 中的应用程序资源和项目资源,并将所需的应用程序状态(在 Git 中提供)与实时状态(在 Kubernetes 中)同步;
  • ApplicationSet Controller:ApplicationSet Controller 负责协调 ApplicationSet 资源,applicationset是argo创建的一个CRD;
  • Repo Server:Repo Server 在 Argo CD 架构中起着重要作用,因为它负责与 Git 存储库交互,为属于给定 application 的所有 Kubernetes 资源生成所需的状态;
  • Redis:Argo CD 使用 Redis 来提供缓存层,减少发送到K8S的API Server和Git服务器的请求。它还支持一些 UI 操作;
  • Kube API:Argo CD 控制器将连接到K8S的API Server以执行操作。因此如果需要管理多个集群时,在部署了argocd之外的集群是不需要部署任何argocd的客户端程序的,只需要创建一个ServiceAccount用于管理权限;
  • Git:作为 gitops 工具,Argo CD 要求在 Git 存储库中提供所需的 Kubernetes 资源状态。 我们在这里使用git来代表实际的 git 存储库、Helm 存储库或 OCI 工件存储库。 Argo CD 支持所有这些选项;
  • Dex:Argo CD 依赖于 Dex 来提供与外部 OIDC 提供商的身份验证。当然,可以使用其他工具代替 Dex;

3、核心概念

官方文档假定我们熟悉核心 Git、Docker、Kubernetes、持续交付(Continuous Delivery)和 GitOps 概念,对一些特定于 Argo CD 的概念进行了介绍,这里摘取了一些个人认为比较重要且基础的概念进行二次阐述。

  • Application:Argocd中的核心概念之一,在K8S中以CRD的形式存在,用来表示一组由manifest定义的K8S资源集合。例如我们需要部署一个服务,该服务涉及的K8S资源可能包括若干个deployment、svc以及configmap等多种类型,在argocd中将其统一按照Application的概念进行划分,这些资源都归属于同一个Application下进行配置。

  • Target state:期望该Application下的各种资源类型的运行状态,由对应Git仓库中的文件进行定义。

  • Live state:目前该Application下的各种资源类型的运行状态。

  • Sync status:实时状态是否与目标状态匹配,部署的应用程序是否与Git仓库中定义的状态一致。正常情况下应是Synced并且指向该Git的最新版本分支。

  • Sync:将 Git 中的最新代码与实时状态进行对比并将变更同步到K8S集群中,将其可以视为主动触发同步git状态的操作。

  • Sync operation status:同步是否成功。

  • Refresh:将Git中的最新代码与实时状态进行对比。

  • Health:应用程序的健康状况,如是否正常运行,能否接收并处理外部请求等。

4、高可用部署argocd

高可用部署的yaml文件可以在github上面获取

1
https://github.com/argoproj/argo-cd/blob/master/manifests/ha/namespace-install.yaml

同时需要注意对应的CRD资源需要单独部署

1
https://github.com/argoproj/argo-cd/tree/master/manifests/crds

部署的文档可以参考官方的latest版本

1
https://argo-cd.readthedocs.io/en/latest/operator-manual/installation/

我们来看一下部署文件的结构:

1
2
3
4
5
6
7
8
9
10
11
$ tree argocd/
argocd/
|-- crds
| |-- application-crd.yaml
| |-- applicationset-crd.yaml
| |-- appproject-crd.yaml
| `-- kustomization.yaml
`-- ha
`-- namespace-install.yaml

2 directories, 5 files

部署环节我们可以分为三步,部署CRD资源、创建namespace、部署workload及相关配置。

首先我们定位到crds目录下面,直接部署对应的三个crd文件用于创建对应的crd资源。

1
2
3
4
$ kubectl apply -f application-crd.yaml -f applicationset-crd.yaml -f appproject-crd.yaml
customresourcedefinition.apiextensions.k8s.io/applications.argoproj.io created
customresourcedefinition.apiextensions.k8s.io/applicationsets.argoproj.io created
customresourcedefinition.apiextensions.k8s.io/appprojects.argoproj.io created

接着手动创建一个namespace,名字不一定为argocd,可以是你喜欢的任意值,但是注意后面指定的namespace要和这里相同。

1
2
$ kubectl create ns argocd
namespace/argocd created

最后定位到ha目录下,直接部署argocd对应的全部工作负载,注意部署的时候指定namespace,否则会部署到默认的default namespace下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
$ kubectl apply -f namespace-install.yaml -n argocd
serviceaccount/argocd-application-controller created
serviceaccount/argocd-applicationset-controller created
serviceaccount/argocd-dex-server created
serviceaccount/argocd-notifications-controller created
serviceaccount/argocd-redis-ha created
serviceaccount/argocd-redis-ha-haproxy created
serviceaccount/argocd-repo-server created
serviceaccount/argocd-server created
role.rbac.authorization.k8s.io/argocd-application-controller created
role.rbac.authorization.k8s.io/argocd-applicationset-controller created
role.rbac.authorization.k8s.io/argocd-dex-server created
role.rbac.authorization.k8s.io/argocd-notifications-controller created
role.rbac.authorization.k8s.io/argocd-redis-ha created
role.rbac.authorization.k8s.io/argocd-redis-ha-haproxy created
role.rbac.authorization.k8s.io/argocd-server created
rolebinding.rbac.authorization.k8s.io/argocd-application-controller created
rolebinding.rbac.authorization.k8s.io/argocd-applicationset-controller created
rolebinding.rbac.authorization.k8s.io/argocd-dex-server created
rolebinding.rbac.authorization.k8s.io/argocd-notifications-controller created
rolebinding.rbac.authorization.k8s.io/argocd-redis-ha created
rolebinding.rbac.authorization.k8s.io/argocd-redis-ha-haproxy created
rolebinding.rbac.authorization.k8s.io/argocd-server created
configmap/argocd-cm created
configmap/argocd-cmd-params-cm created
configmap/argocd-gpg-keys-cm created
configmap/argocd-notifications-cm created
configmap/argocd-rbac-cm created
configmap/argocd-redis-ha-configmap created
configmap/argocd-redis-ha-health-configmap created
configmap/argocd-ssh-known-hosts-cm created
configmap/argocd-tls-certs-cm created
secret/argocd-notifications-secret created
secret/argocd-secret created
service/argocd-applicationset-controller created
service/argocd-dex-server created
service/argocd-metrics created
service/argocd-notifications-controller-metrics created
service/argocd-redis-ha created
service/argocd-redis-ha-announce-0 created
service/argocd-redis-ha-announce-1 created
service/argocd-redis-ha-announce-2 created
service/argocd-redis-ha-haproxy created
service/argocd-repo-server created
service/argocd-server created
service/argocd-server-metrics created
deployment.apps/argocd-applicationset-controller created
deployment.apps/argocd-dex-server created
deployment.apps/argocd-notifications-controller created
deployment.apps/argocd-redis-ha-haproxy created
deployment.apps/argocd-repo-server created
deployment.apps/argocd-server created
statefulset.apps/argocd-application-controller created
statefulset.apps/argocd-redis-ha-server created
networkpolicy.networking.k8s.io/argocd-application-controller-network-policy created
networkpolicy.networking.k8s.io/argocd-applicationset-controller-network-policy created
networkpolicy.networking.k8s.io/argocd-dex-server-network-policy created
networkpolicy.networking.k8s.io/argocd-notifications-controller-network-policy created
networkpolicy.networking.k8s.io/argocd-redis-ha-proxy-network-policy created
networkpolicy.networking.k8s.io/argocd-redis-ha-server-network-policy created
networkpolicy.networking.k8s.io/argocd-repo-server-network-policy created
networkpolicy.networking.k8s.io/argocd-server-network-policy created

部署完成后检查部署的pod是否正常运行,此时所有的pod应该都在argocd这个namespace下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ kubectl get pods -n argocd -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
argocd-application-controller-0 1/1 Running 0 5m42s 10.33.4.166 k8s-10-31-90-5.tinychen.io <none> <none>
argocd-applicationset-controller-559cc454d9-wx5vf 1/1 Running 0 5m43s 10.33.4.217 k8s-10-31-90-5.tinychen.io <none> <none>
argocd-dex-server-76487b6695-vvkwr 1/1 Running 0 5m43s 10.33.4.133 k8s-10-31-90-5.tinychen.io <none> <none>
argocd-notifications-controller-65b795c756-mtxb5 1/1 Running 0 5m43s 10.33.3.18 k8s-10-31-90-4.tinychen.io <none> <none>
argocd-redis-ha-haproxy-6745ff898d-6rb2n 1/1 Running 0 5m43s 10.33.4.85 k8s-10-31-90-5.tinychen.io <none> <none>
argocd-redis-ha-haproxy-6745ff898d-dbn58 1/1 Running 0 5m43s 10.33.3.212 k8s-10-31-90-4.tinychen.io <none> <none>
argocd-redis-ha-haproxy-6745ff898d-w2hlh 1/1 Running 0 5m43s 10.33.5.211 k8s-10-31-90-6.tinychen.io <none> <none>
argocd-redis-ha-server-0 3/3 Running 0 5m42s 10.33.5.163 k8s-10-31-90-6.tinychen.io <none> <none>
argocd-redis-ha-server-1 3/3 Running 0 2m41s 10.33.4.188 k8s-10-31-90-5.tinychen.io <none> <none>
argocd-redis-ha-server-2 3/3 Running 0 86s 10.33.3.113 k8s-10-31-90-4.tinychen.io <none> <none>
argocd-repo-server-5c8f8d4fbd-fp9jt 1/1 Running 0 5m42s 10.33.4.230 k8s-10-31-90-5.tinychen.io <none> <none>
argocd-repo-server-5c8f8d4fbd-gchwd 1/1 Running 0 5m42s 10.33.3.213 k8s-10-31-90-4.tinychen.io <none> <none>
argocd-server-5684688df7-7grxl 1/1 Running 0 5m42s 10.33.5.55 k8s-10-31-90-6.tinychen.io <none> <none>
argocd-server-5684688df7-gxbsf 1/1 Running 0 5m42s 10.33.3.226 k8s-10-31-90-4.tinychen.io <none> <none>

最后检查对应的svc是否存在,同理此时所有的svc应该也都在argocd这个namespace下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ kubectl get svc -n argocd
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
argocd-applicationset-controller ClusterIP 10.33.182.73 <none> 7000/TCP,8080/TCP 12m
argocd-dex-server ClusterIP 10.33.130.105 <none> 5556/TCP,5557/TCP,5558/TCP 12m
argocd-metrics ClusterIP 10.33.167.226 <none> 8082/TCP 12m
argocd-notifications-controller-metrics ClusterIP 10.33.191.67 <none> 9001/TCP 12m
argocd-redis-ha ClusterIP None <none> 6379/TCP,26379/TCP 12m
argocd-redis-ha-announce-0 ClusterIP 10.33.182.204 <none> 6379/TCP,26379/TCP 12m
argocd-redis-ha-announce-1 ClusterIP 10.33.158.122 <none> 6379/TCP,26379/TCP 12m
argocd-redis-ha-announce-2 ClusterIP 10.33.147.25 <none> 6379/TCP,26379/TCP 12m
argocd-redis-ha-haproxy ClusterIP 10.33.190.134 <none> 6379/TCP 12m
argocd-repo-server ClusterIP 10.33.187.87 <none> 8081/TCP,8084/TCP 12m
argocd-server ClusterIP 10.33.160.176 <none> 80/TCP,443/TCP 12m
argocd-server-metrics ClusterIP 10.33.177.208 <none> 8083/TCP 12m

需要注意的是,在较新版本的namespace-install.yaml文件中,因为默认开启了redis的认证功能,还需要我们自己手动创建一个对应的secret

1
2
3
4
5
6
7
8
9
10
11
apiVersion: v1
kind: Secret
metadata:
labels:
app.kubernetes.io/name: argocd-redis
app.kubernetes.io/part-of: argocd
name: argocd-redis
namespace: argocd
type: Opaque
data:
auth: dGlueWNoZW4uY29tCg==

注意上面的auth值应该是原密码经过base64编码后的值,例如

1
2
# echo tinychen.com | base64
dGlueWNoZW4uY29tCg==

5、部署CLI

CLI的部署可以参考文档

1
https://argo-cd.readthedocs.io/en/latest/cli_installation/

我们直接下载对应系统版本的二进制文件即可。

1
2
3
$ curl -sSL -o argocd-linux-amd64 https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64
$ sudo install -m 555 argocd-linux-amd64 /usr/local/bin/argocd
$ rm argocd-linux-amd64

安装完成之后输入argocd --help查看CLI是否能够正常运行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
$ argocd --help
argocd controls a Argo CD server

Usage:
argocd [flags]
argocd [command]

Available Commands:
account Manage account settings
admin Contains a set of commands useful for Argo CD administrators and requires direct Kubernetes access
app Manage applications
appset Manage ApplicationSets
cert Manage repository certificates and SSH known hosts entries
cluster Manage cluster credentials
completion output shell completion code for the specified shell (bash or zsh)
context Switch between contexts
gpg Manage GPG keys used for signature verification
help Help about any command
login Log in to Argo CD
logout Log out from Argo CD
proj Manage projects
relogin Refresh an expired authenticate token
repo Manage repository connection parameters
repocreds Manage repository connection parameters
version Print version information

Flags:
--auth-token string Authentication token
--client-crt string Client certificate file
--client-crt-key string Client certificate key file
--config string Path to Argo CD config (default "/root/.config/argocd/config")
--core If set to true then CLI talks directly to Kubernetes instead of talking to Argo CD API server
--grpc-web Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2.
--grpc-web-root-path string Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. Set web root.
-H, --header strings Sets additional header to all requests made by Argo CD CLI. (Can be repeated multiple times to add multiple headers, also supports comma separated headers)
-h, --help help for argocd
--http-retry-max int Maximum number of retries to establish http connection to Argo CD server
--insecure Skip server certificate and domain verification
--kube-context string Directs the command to the given kube-context
--logformat string Set the logging format. One of: text|json (default "text")
--loglevel string Set the logging level. One of: debug|info|warn|error (default "info")
--plaintext Disable TLS
--port-forward Connect to a random argocd-server port using port forwarding
--port-forward-namespace string Namespace name which should be used for port forwarding
--server string Argo CD server address
--server-crt string Server certificate file

Use "argocd [command] --help" for more information about a command.

argocd CLI的默认配置文件会放置在~/.config/argocd/config目录下,当然也可以像kubectl一样使用--config手动指定。

6、暴露argocd

6.1 配置argocd-server

想要使用集群外的argocd cli来操控集群内的argocd,比较优雅的方式是通过LoadBalancer暴露一个EXTERNAL-IP给集群外的服务访问

如果你的集群支持LoadBalancer类型的服务,可以参考下面的配置:

1
$ kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'

这里使用的测试集群部署了purelb,因此还可以精细化操作一下,指定特定的VIP方便我们后续配置

1
2
# 我们直接一步到位,直接添加注解、设置svc的类型为LoadBalancer并手动指定loadBalancerIP
$ kubectl patch svc argocd-server -n argocd -p '{"metadata":{"annotations":{"purelb.io/service-group":"bgp-ippool"}},"spec": {"type": "LoadBalancer","loadBalancerIP":"10.33.192.2"}}'

随后我们检查一下服务是否暴露成功

1
2
3
$ kubectl get svc -n argocd argocd-server
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
argocd-server LoadBalancer 10.33.160.176 10.33.192.2 80:30149/TCP,443:31991/TCP 88m

正常情况下我们通过这里暴露出来的VIP 10.33.192.2可以访问对应的web界面,同时CLI工具也可以直接连接10.33.192.2进行操作。

当然我们也可以通过ingress来进行配置,具体可以参考官方的文档,上面提供了多种ingress的配置案例。

我们这里为了方便用户访问webUI,使用NGX做一层反向代理,配置域名为argocd.tinychen.com,转发到10.33.192.2443端口。

默认情况下argocd会暴露两个端口,其中80端口会自动重定向到443端口,因为我们配置反向代理的需要需要额外注意。

  • 443 - gRPC/HTTPS
  • 80 - HTTP (redirects to HTTPS)

如果配置的反向代理服务器不支持HTTP2可以考虑使用–grpc-web参数

–grpc-web Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2.

6.2 修改初始账号密码

argocd的初始密码是使用secrets明文存储在k8s的argocd-initial-admin-secret中,我们可以直接获取并进行base64解码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ kubectl get secrets -n argocd argocd-initial-admin-secret -o yaml
apiVersion: v1
data:
password: UUFkdDFNRGZsaXFhZjVtUQ==
kind: Secret
metadata:
creationTimestamp: "2023-05-04T07:50:34Z"
name: argocd-initial-admin-secret
namespace: argocd
resourceVersion: "23555422"
uid: 9c0db11e-7db0-4432-9bf4-da7c5668b4e5
type: Opaque

$ echo UUFkdDFNRGZsaXFhZjVtUQ== | base64 -d
QAdt1MDfliqaf5mQ

当然也可以通过CLI工具来快速获取初始密码

1
2
3
4
$ argocd admin initial-password -n argocd
QAdt1MDfliqaf5mQ

This password must be only used for first time login. We strongly recommend you update the password using `argocd account update-password`.

获取初始密码之后,我们可以使用初始账号admin和初始密码进行登录,然后进行密码的修改。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 先使用初始密码登录
$ argocd login argocd.tinychen.com
Username: admin
Password:
'admin:login' logged in successfully
Context 'argocd.tinychen.com' updated

# 随即修改密码
$ argocd account update-password
*** Enter password of currently logged in user (admin):
*** Enter new password for user admin:
*** Confirm new password for user admin:
Password updated
Context 'argocd.tinychen.com' updated

# 随后再次退出然后即可使用新密码进行重新登录
$ argocd logout argocd.tinychen.com
Logged out from 'argocd.tinychen.com'

argocd cli的配置文件默认存储在~/.config/argocd/config目录下

7、集群配置

argocd原生是支持同时管理多个集群的,同时因为argocd是部署在K8S集群中,所以argocd本身所处的集群默认是存在配置中的。我们可以通过CLI或者webUI来查看默认的集群,需要注意的是如果还没有在集群中部署应用的话,argocd是不会主动去探测集群的状态的。

1
2
3
$ argocd cluster list
SERVER NAME VERSION STATUS MESSAGE PROJECT
https://kubernetes.default.svc in-cluster Unknown Cluster has no applications and is not being monitored.

添加新集群只能通过CLI来进行操作,webUI可以对集群进行重命名和删除等操作。

1
2
$ kubectl config get-contexts -o name --kubeconfig /root/k8s-90-config
kubernetes-admin@kubernetes

将集群添加到argocd之后会在集群中添加一个名为argocd-managerServiceAccount

1
2
3
4
5
6
7
$ argocd cluster add kubernetes-admin@kubernetes --kubeconfig /root/k8s-90-config --name k8s-90-cluster
WARNING: This will create a service account `argocd-manager` on the cluster referenced by context `kubernetes-admin@kubernetes` with full cluster level privileges. Do you want to continue [y/N]? y
INFO[0003] ServiceAccount "argocd-manager" created in namespace "kube-system"
INFO[0003] ClusterRole "argocd-manager-role" created
INFO[0003] ClusterRoleBinding "argocd-manager-role-binding" created
INFO[0008] Created bearer token secret for ServiceAccount "argocd-manager"
Cluster 'https://10.31.90.0:8443' added

大部分k8s默认生成的kubeconfig文件中的集群名都是kubernetes-admin@kubernetes,这对多集群管理稍有不便,如果想要单独指定在argocd中的集群名称可以在导入的时候使用–name 参数

添加完成后可以查看到集群,但是由于尚未部署app,所以目前状态也并未同步

1
2
3
4
$ argocd cluster list
SERVER NAME VERSION STATUS MESSAGE PROJECT
https://10.31.90.0:8443 k8s-90-cluster
https://kubernetes.default.svc in-cluster

8、配置git仓库

argocd中的git仓库和repo是一对多的关系,也就是说一个git仓库可以用于创建多个app,所以这里我们需要先配置git仓库。

特别注意,Project在创建成功之后是无法修改的。如果想要使用project对多个项目进行管理,建议先创建project,再配置git仓库,最后配置apps

如果有比较大量的git仓库存储需求,建议考虑自行搭建一个gitlab服务器,当然使用公共的gitlab、github和helm仓库等都是可以的。

argocd支持多种拉取仓库的方式,下面我们主要介绍https和ssh这两种较为常见的方式。

8.1 通过https连接仓库

https方式连接一般比较简单,常用于拉取一些公共git仓库。如下面示范的拉取argocd官方的git仓库作为示例:

创建成功后我们可以在UI中看到该仓库的状态为Successful。

在CLI中也能看到详细的状态信息。

1
2
3
$ argocd repo list
TYPE NAME REPO INSECURE OCI LFS CREDS STATUS MESSAGE PROJECT
git https://github.com/argoproj/argocd-example-apps false false false false Successful default

当然https的拉取方式也是可以配置用户名密码已经TLS双向认证等多种限制手段的。

8.2 通过ssh连接仓库

首先我们生成一个密钥对,这个密钥对用来给git仓库添加权限

1
$ ssh-keygen -C argocd@argocd.tinychen.com -f ~/.ssh/argocd

接着我们为对应的git仓库创建对应的depoly keysdepoly keys的详细说明可以参考gitlab的官方文档depoly keys可以在gitlab的仓库的Settings -> Repository -> Deploy keys找到,然后把刚刚生成的key里面的公钥放进去即可,至于过期时间(Expiration date)则根据自己的实际需要进行配置,留空则为无限制。

随后我们在argocd的webui节面创建一个repo,这里需要注意如果使用的是ssh并且端口不是默认的22,需要在URL中带上具体的端口信息。如图所示就指定了SSH的端口为9022。

argocd在部署的时候自带了常用的几个网站的ssh-known-hosts并存储在argocd-ssh-known-hosts-cm这个configmap

1
2
3
$ kubectl get cm -n argocd argocd-ssh-known-hosts-cm
NAME DATA AGE
argocd-ssh-known-hosts-cm 1 25h

如果我们使用的是自建的gitlab服务器,建议勾选Skip server verification这个参数,或者将对应的ssh-known-hosts添加到argocd-ssh-known-hosts-cm这个configmap中,否则在同步git仓库的时候容易出现报错。

也可以在webUI中的Settings->Repository certificates and known hosts中配置ssh-known-hostsTLS Certificate

1
2
3
4
$ argocd repo list
TYPE NAME REPO INSECURE OCI LFS CREDS STATUS MESSAGE PROJECT
git https://github.com/argoproj/argocd-example-apps false false false false Successful default
git k8s-90-manifests git@gitlab.tinychen.com:9022:tinychen/k8s-90-manifests.git true false true false Successful default

9、配置app

完成上面的所有步骤之后,我们可以开始配置最终的应用了。

  • 先来看基础配置Application NameProject Name都是对应argocd中的参数,也是对应我们前面部署的两个crd
  • SYNC POLICY可以选择自动同步还是手动同步
  • PRUNE RESOURCES可以选择是否删除在git中移除的资源,如某个git版本中创建了一个svc,随后又删除了,如果不勾选该选项,则argocd不会自动删除该svc
  • SELF HEAL可以理解为自愈,即检测到定义的资源状态和git中不一致的时候,是否自动同步为一致;如git中定义副本数为10,随后手动扩容至20但并未修改git中的配置文件,勾选这一项则会触发argocd自动将副本数缩减回10
  • SKIP SCHEMA VALIDATION跳过语法检查,个人不建议开启
  • AUTO-CREATE NAMESPACE可以设置如果对应的namespace不存在的话是否自动创建
  • APPLY OUT OF SYNC ONLY类似于增量部署而不是全量部署,仅部署和git版本中不一样的资源,而不是全部重新部署一次,可以降低K8S集群的压力
  • REPLACE会将部署的命令从默认的kubectl apply变更为kubectl replace/create,可以解决部分资源修改之后无法直接apply部署的问题,同时也有可能会导致资源的重复创建
  • RETRY可以设定部署失败后重试的次数和频率

关于sync options的完整参数解析可以查看官方的文档https://argo-cd.readthedocs.io/en/latest/user-guide/sync-options/,这里只挑了一些个人常用且熟悉的参数进行介绍,如果不知道一个参数的作用是什么,建议保持默认值。

SOURCE这里主要用于指定git仓库、对应的分支及具体的子目录

DESTINATION这里用来指定部署的K8S集群和namespace。

Directory这一栏里面有个DIRECTORY RECURSE参数,勾选之后会递归识别子目录下面的文件。

这里还可以下拉变更为helm、Kustomize、Plugin等其他配置

部署完成之后我们就可以使用argocd来管理对应的应用了

10、配置git webhooks

ArgoCD每三分钟会拉取一次git仓库的内容以检测manifests的变化。如果想要消除这个由轮询机制带来的三分钟延迟,我们可以考虑使用webhook来进行通知。Argo CD 支持来自 GitHub、GitLab、Bitbucket、Bitbucket Server 和 Gogs 的 Git webhook 通知,官方提供了基于Github配置webhook事件的教程,我们这里使用自建的gitlab来进行配置。

首先我们找到用来测试的git仓库,在gitlab界面中找到Settings->Webhooks,然后按照下面红框所示的进行操作。

  • URL这里一般都是配置自己argocd的访问域名再加上/api/webhook后缀,注意需要配置https访问
  • 注意这里面的Secret token可以用来增强webhook接口的安全性,大家可以根据自己的实际需求来进行配置。token这里我配置了一串字符串,注意要保存下来,后面还需要在argocd侧进行配置
  • Trigger这里只需要勾选Push events即可,因为我们只需要在有人push变更到git仓库之后,gitlab自动去触发webhook接口调用argocd来完成更新

SSL认证这里建议默认勾选,argocd默认都是走https请求的。

添加完成之后可以看到这个project里面就新增了一个Project Hooks,这时候还不能正常调用,我们还需要到argocd里面配置前面提到的Secret token

argocd使用的secret都以secrets的形式存储在K8S中,我们这里主要用到的是argocd-secret

1
$ kubectl edit secrets -n argocd argocd-secret -o yaml

我们在里面手动添加一个stringData,然后把前面的Secret token贴进去,格式类似下面的示范即可。

1
2
3
4
5
6
7
8
9
10
11
apiVersion: v1
kind: Secret
metadata:
labels:
app.kubernetes.io/name: argocd-secret
app.kubernetes.io/part-of: argocd
name: argocd-secret
type: Opaque
stringData:
# gitlab webhook secret
webhook.gitlab.secret: vbdUUDkHszh35VZ6

完成之后我们再回到gitlab上面,点击Test,选择Push events,如果这时候有下图所示的返回信息则说明已经配置成功且webhook可以正常工作。

最后我们可以手动测试一下webhook的效果:随意编辑一个yaml文件,更改其中的副本数,git push之后查看argocd的webUI界面确定是否会即可生效即可完成测试。

这里不一定需要修改副本数,也可以修改资源配额等其他比较明显能触发pod重建之类的参数,确保我们能比较轻松明显地在argocd上面查看到变化的内容。

最后要提到的是:不太建议通过校对git的版本号来进确定argocd的同步状态,因为不管是SYNC STATUS还是LAST SYNC里面的版本号都不一定是该git仓库对应分支的最新版本号,正常情况下的版本号应该是涉及到这个argocd的app里面所需要用到的文件的最新的版本号;当然我们也可以通过手动点击sync按钮来触发同步操作,这时候SYNC STATUSLAST SYNC里面的版本号就都同步到最新的git版本(尽管这时候可能并不需要进行K8S的同步操作)。