ArgoCD工具

TOC

认识ArgoCD

初识ArgoCD

ArgoCD简介

什么是ArgoCD?
ArgoCD是一个为 Kubernetes 而生的,遵循声明式 GitOps 理念的持续部署工具。ArgoCD可在 Git 存储库更改时自动同步和部署应用程序。
ArgoCD遵循 GitOps 模式,使用 Git 仓库作为定义所需应用程序状态的真实来源。

ArgoCD作用

为什么使用ArgoCD?
ArgoCD可在指定的目标环境中自动部署所需的应用程序状态,应用程序部署可以在 Git 提交时跟踪对分支,标签的更新,或固定到清单的特定版本。

ArgoCD功能

1.支持多种配置管理/模板工具,以git作为应用唯一真实来源
所有项目的声明配置文件都存放在Git中,并把Git作为应用的唯一事实来源,我们不再需要手动更新应用(比如执行脚本,执行kubectl apply或者helm install命令),只需要通过统一的接口(Git)来更新应用。

2.快速回滚,管理群集
ArgoCD可以设置定期同步最新配置在群集中部署更新,一旦最新的配置导致部署失败或者出现故障,我们可以快速通过Git History将应用状态快速恢复到上一个可用的状态。
我们还能通过一个Git之类的仓库来管理多个集群,我们在回滚中不用每个集群都进行操作,我们只需要管理Git里面的配置清单即可。

3.群集灾备
使用ArgoCD,可以在某个区域的集群出现故障的时候,快速创建集群并通过ArgoCD连接Git仓库进行快速部署,因为该仓库包含了所有的配置声明。达到群集状态和服务状态恢复到原来状态一致的效果。

4.Git实现访问控制管理
使用ArgoCD可以控制所有人对于Kubernetes集群的访问,不需要直接访问Kubernetes集群,开发人员可以通过Git仓库来控制服务的部署流程和交付,这样就可以通过Git的访问权限控制来管理,所有人(DevOps 团队,运维团队,研发团队,等等)都可以向仓库中提交 Pull Request。
这样做的好处是除了集群管理员和少数人员之外,其他人不再需要直接访问 Kubernetes 集群,只需访问 Git 仓库即可。可以避免使用复杂的 RBAC 规则,因为只有 Argo CD 才可以 apply 配置清单,而且 Argo CD 已经部署在 Kubernetes 集群中,必要的访问权限已经配置妥当,这样就不需要给集群外的任意人或工具提供访问的证书,可以提供更强大的安全保障。

5.群集检测和可视化
ArgoCD巧妙地利用了Kubernetes集群中的很多功能来实现自己的目的,例如所有的资源都存储在 Etcd 集群中,利用Kubernetes的控制器来监控应用的实际状态并与期望状态进行对比,等等。
这样做最直观的好处就是可以实时感知应用的部署状态。例如,当你在Git仓库中更新配置清单中的镜像版本后,ArgoCD 会将集群中的应用更新到最新版本,你可以在ArgoCD的可视化界面中实时查看更新状态(比如 Pod 创建成功,应用成功运行并且处于健康状态,或者应用运行失败需要进行回滚操作)。这些状态都可以在UI界面进行展示。

ArgoCD的核心概念

如果已经熟悉核心 Git、Docker、Kubernetes、持续交付和 GitOps 概念。以下是一些特定于 Argo CD 的概念。

  • Application:应用,一组由资源清单定义的 Kubernetes 资源,这是一个 CRD 资源对象
  • Application source type:用来构建应用的工具
  • Target state:目标状态,指应用程序所需的期望状态,由 Git 存储库中的文件表示
  • Live state:实时状态,指应用程序实时的状态,比如部署了哪些 Pods 等真实状态
  • Sync status:同步状态表示实时状态是否与目标状态一致,部署的应用是否与 Git 所描述的一样?
  • Sync:同步指将应用程序迁移到其目标状态的过程,比如通过对 Kubernetes 集群应用变更
  • Sync operation status:同步操作状态指的是同步是否成功
  • Refresh:刷新是指将 Git 中的最新代码与实时状态进行比较,弄清楚有什么不同
  • Health:应用程序的健康状况,它是否正常运行?能否为请求提供服务?
  • Tool:工具指从文件目录创建清单的工具,例如 Kustomize 或 Ksonnet 等
  • Configuration management tool:配置管理工具
  • Configuration management plugin:配置管理插件

ArgoCD Application
Application定义了Kubernetes资源的来源(Source)和目标(Destination)。来源指的是Git仓库中Kubernetes资源配置清单所在的位置,而目标是指资源在 Kubernetes 集群中的部署位置。
来源可以是原生的Kubernetes配置清单,也可以是Helm Chart或者Kustomize部署清单。
ArgoCD Project
如果有多个团队,每个团队都要维护大量的应用,就需要用到ArgoCD的另一个概念:项目(Project)。
项目(Project)可以用来对Application进行分组,不同的团队使用不同的项目,这样就实现了多租户环境。

项目还支持更细粒度的访问权限控制:

  • 限制部署内容(受信任的 Git 仓库);
  • 限制目标部署环境(目标集群和 namespace);
  • 限制部署的资源类型(例如 RBAC、CRD、DaemonSets、NetworkPolicy 等);
  • 定义项目角色,为 Application 提供 RBAC(与 OIDC group 或者 JWT 令牌绑定)。

传统CD工作流和ArgoCD

传统的CD工作流

目前大多数 CI/CD 工具都使用基于Push的部署模式,例如 Jenkins、gitlabCI 等。这种模式一般都会在 CI 流水线运行完成后执行一个命令(比如 kubectl)将应用部署到目标环境中。

CD模式缺陷:

  • 需要安装配置额外工具(比如 kubectl);
  • 需要 Kubernetes 对其进行授权;
  • 需要云平台授权;
  • 无法感知部署状态。也就无法感知期望状态与实际状态的偏差,需要借助额外的方案来保障一致性。

ArgoCD工作流

和传统 CI/CD 工具一样,CI 部分并没有什么区别,重点在于 CD 部分。
ArgoCD会被部署在Kubernetes集群中,使用的是基于Pull的部署模式,它会周期性地监控应用的实际状态,也会周期性地拉取Git仓库中的配置清单,并将实际状态与期望状态进行比较,如果实际状态不符合期望状态,就会更新应用的实际状态以匹配期望状态。

最大区别: 这种模式会得到一个相互隔离的CI与CD流水线,CI 流水线通常由研发人员(或者 DevOps 团队)控制,CD 流水线通常由集群管理员(或者 DevOps 团队)控制。

ArgoCD安装

服务端安装

使用官网的yaml文件直接安装,里面有的镜像是用的官方镜像,拉取过程中没有代理的话会拉取失败,可以替换成适用的镜像。

# 创建所需命名空间
kubectl create namespace argocd
# 安装最新版本
kubectl -n argocd apply -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
# 安装指定版本
kubectl -n argocd apply -f  https://raw.githubusercontent.com/argoproj/argo-cd/v3.0.11/manifests/install.yaml
# 安装HA高可用版本
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/v3.0.11/manifests/ha/install.yaml

安装完成后查看ArgoCD的部署情况:

$ kubectl -n argocd get pods
NAME                                                READY   STATUS    RESTARTS   AGE
argocd-application-controller-0                     1/1     Running   0          1h
argocd-applicationset-controller-6d569f7895-4kgb8   1/1     Running   0          1h
argocd-dex-server-5b44d67df9-bsnjb                  1/1     Running   0          1h
argocd-notifications-controller-5865dfbc8-2f8fs     1/1     Running   0          1h
argocd-redis-766557855b-2g2d7                       1/1     Running   0          1h
argocd-repo-server-df8b9fd78-q85qj                  1/1     Running   0          1h
argocd-server-6d896f6785-bh2v5                      1/1     Running   0          1h

这里使用以下命令通过 NodePort 服务的方式暴露 Argo CD 到集群外部方便访问,如下所示:

kubectl -n argocd patch svc argocd-server -p '{"spec": {"type": "NodePort"}}'

也可以通过修改yaml的方式进行修改,以及指定NodePort的端口号。界面如下图所示:
argocd
用户名默认为:admin,密码通过下面解密secret方式查询:

kubectl -n argocd get secret \
argocd-initial-admin-secret \
-o jsonpath="{.data.password}" | base64 -d
9W7ff3F-Su3R5viP

登录进去界面如下图所示:
argocd

禁用UI和SSO等

如果你对 UI、SSO、多集群管理这些特性不感兴趣,只想把应用变更同步到集群中,那么你可以使用 --disable-auth 标志来禁用认证。命令如下所示:

kubectl -n argocd patch deploy argocd-server -p '[{"op": "add", "path": "/spec/template/spec/containers/0/command/-", "value": "--disable-auth"}]' --type json

客户端安装

也就是安装CLI工具,方便使用命令操作ArgoCD。

Linux安装

# 这里查询最新的版本
VERSION=$(curl --silent "https://api.github.com/repos/argoproj/argo-cd/releases/latest" | grep '"tag_name"' | sed -E 's/.*"([^"]+)".*/\1/')
curl -sSL -o /usr/local/bin/argocd https://github.com/argoproj/argo-cd/releases/download/$VERSION/argocd-linux-amd64
chmod +x /usr/local/bin/argocd

MacOS安装

Mac系统可以直接使用brew install进行安装,或者官网下载

# brew工具下载
brew intsall argocd
# 官网下载
VERSION=$(curl --silent "https://api.github.com/repos/argoproj/argo-cd/releases/latest" | grep '"tag_name"' | sed -E 's/.*"([^"]+)".*/\1/')
sudo curl -sSL -o /usr/local/bin/argocd https://github.com/argoproj/argo-cd/releases/download/$VERSION/argocd-darwin-arm64
chmod +x /usr/local/bin/argocd

ArgoCD工具使用

使用UI创建应用

第1步:首先我们需要准备git仓库创建项目,然后创建myapp目录

tree myapp
myapp
├── myapp-svc.yaml
└── myapp.yml

两个文件内容如下:

# myapp.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-app
  namespace: default
spec:
  progressDeadlineSeconds: 600
  replicas: 2
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: nginx-app
      version: v1
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: nginx-app
        version: v1
    spec:
      containers:
        - name: nginx-app
          image: test/nginx-app:v1
          imagePullPolicy: IfNotPresent
      dnsPolicy: ClusterFirst
      imagePullSecrets:
        - name: default-secret
      restartPolicy: Always
      schedulerName: default-scheduler
      terminationGracePeriodSeconds: 30
---
# myapp-svc.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    app: nginx-app
    name: nginx-app
  name: nginx-app
  namespace: default
spec:
  ports:
    - port: 80
      protocol: TCP
      targetPort: 80
      nodePort: 30808
  selector:
    app: nginx-app
    version: v1
  sessionAffinity: None
  type: NodePort

第2步:我们在ArgoCD的UI界面创建app
需要填写应用名称、项目名称、同步方式,如下图所示:
argocd
然后我们再填写Git仓库地址、项目分支名、资源文件目录路径,如下图所示:
argocd
最后我们需要填写K8S API地址和应用要部署的命名空间,如下图所示:
argocd
第3步:创建好了app之后我们看到应用状态为OutOfSync,我们点击同步,如下图所示:
argocd
等待同步完成之后,我们可以点击应用进入查看详情,如下图所示:
argocd
这里我们可以看到应用状态部署成功,起了两个副本起来。我们使用命令查看服务状态,命令如下:

$ kubectl get pods |grep nginx-app
nginx-app-869757c57c-5szwk                                     1/1     Running            0                1h
nginx-app-869757c57c-wdgcj                                     1/1     Running            0                1h

使用CLI创建应用

首先要先远程登录ArgoCD,命令如下:

argocd login <server address>:<port> --username admin --password <password> --insecure

使用argocd app create命令来进行创建,命令如下:

$ argocd app create myapp \
--repo https://gitlab.example.com/test/app.git \
--path devops/myapp \
--dest-server https://kubernetes.default.svc \
--dest-namespace default
application 'myapp' created

查看应用列表:

$ argocd app list
NAME          CLUSTER                         NAMESPACE  PROJECT  STATUS     HEALTH   SYNCPOLICY  CONDITIONS  REPO                                                         PATH          TARGET
argocd/myapp  https://kubernetes.default.svc  default    default  OutOfSync  Healthy  Manual      <none>      https://gitlab.example.com/test/app.git  devops/myapp  master

查看应用详情:

$ argocd app get myapp
Name:               argocd/myapp
Project:            default
Server:             https://kubernetes.default.svc
Namespace:          default
URL:                https://192.168.100.101:31318/applications/myapp
Source:
- Repo:             https://gitlab.example.com/test/app.git
  Target:           master
  Path:             devops/myapp
SyncWindow:         Sync Allowed
Sync Policy:        Manual
Sync Status:        OutOfSync from master (b8fbbb4)
Health Status:      Healthy

GROUP  KIND        NAMESPACE  NAME       STATUS     HEALTH   HOOK  MESSAGE
       Service     default    nginx-app  Synced     Healthy        service/nginx-app unchanged
apps   Deployment  default    nginx-app  OutOfSync  Healthy        deployment.apps/nginx-app configured

使用YAML创建应用

YAML文件内容如下:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: myapp   # 应用名
spec:
  destination:
    name: ''
    namespace: default    # 部署的命名空间
    server: 'https://kubernetes.default.svc'  # K8S API地址
  source:
    path: devops/myapp  # 资源文件路径
    repoURL: 'https://gitlab.example.com/test/app.git' # Git仓库地址
    targetRevision: master   # 分支名
  project: default   # 项目名
  syncPolicy:
    automated: null   # 同步方式

版本升级

先将自动同步开启,如下图所示:
argocd
修改Git仓库里面的资源文件,将镜像版本修改,如下所示:

# myapp.yml
......
spec:
  ......
    spec:
      containers:
        - name: nginx-app
          image: test/nginx-app:v2  # 修改镜像版本版本
    ......

等待一会ArgoCD会自动更新应用,我们也可以点击REFRESH刷新状态,ArgoCD会立即获取最新的资源文件。可以看到此时 myapp Deployment 会新创建 v2 版本的 Replicaset,v2 版本的 Replicaset 会创建并管理 v2 版本的 Pod。
argocd

版本回滚

升级到 v2 版本以后, v1 版本的Replicaset并没有被删除,而是继续保留,这是为了方便我们回滚应用。在 myapp 应用中点击HISTORY AND ROLLBACK查看历史记录,如下图所示:
argocd
可以看到有 2 个历史记录,如果版本出现问题,我们可以进行点击回滚( 在回滚的时候需要禁用 AUTO-SYNC 自动同步),如下图所示:
argocd
回滚了版本之后我们可以看到此时Pod是v1版本的,并且由于此时线上的版本并不是Git仓库中最新的版本,因此此时同步状态是OutOfSync,如下图所示:
argocd

webhook配置

ArgoCD会自动检查到配置的应用变化,这是因为ArgoCD会每个三分钟去轮询一次Git存储库来检测清单的变化。这种轮询延迟对于我们平时交互流程中还是太慢了,所以我们可以通过webhook方式像Jenkins一样来触发API进行同步部署。
Argo CD 支持来着 GitHub、GitLab、Bitbucket、Bitbucket Server和Gogs的Git webhook事件。
Webhook的地址就是ArgoCD的API接口地址,ArgoCD地址:端口/api/webhook
注意Secret token可以选择添加,我们使用的是自签名的https证书,所以需要在下方去掉启用SSL验证

$ kubectl edit secret argocd-secret -n argocd
apiVersion: v1
kind: Secret
metadata:
  name: argocd-secret
  namespace: argocd
type: Opaque
data:
...
stringData:
  # gitlab webhook secret
  webhook.gitlab.secret: 7018c7f7ee0099296f8c84caad8317df