什么是 ArgoCD
Argo CD is a declarative, GitOps continuous delivery tool for Kubernetes.
Argo CD 是一个基于 Kubernetes 的声明式的 GitOps 工具。
在说 Argo CD 之前,我们先来了解一下什么是 GitOps。
什么是 GitOps
GitOps 是以 Git 为基础,使用 CI/CD 来更新运行在云原生环境的应用,它秉承了 DevOps 的核心理念–“构建它并交付它 (you built it you ship it)”。
概念说起来有点虚,我画了张图,看了你就明白了。
- 当开发人员将开发完成的代码推送到 git 仓库会触发 CI 制作镜像并推送到镜像仓库
- CI 处理完成后,可以手动或者自动修改应用配置,再将其推送到 git 仓库
- GitOps 会同时对比目标状态和当前状态,如果两者不一致会触发 CD 将新的配置部署到集群中
其中,目标状态是 Git 中的状态,现有状态是集群的里的应用状态。
不用 GitOps 可以么?
当然可以,我们可以使用 kubectl、helm 等工具直接发布配置,但这会存在一个很严重的安全问题,那就是密钥共享。
为了让 CI 系统能够自动的部署应用,我们需要将集群的访问密钥共享给它,这会带来潜在的安全问题。
ArgoCD
Argo CD 遵循 GitOps 模式,使用 Git 存储库存储所需应用程序的配置。
Kubernetes 清单可以通过以下几种方式指定:
- kustomize 应用程序
- helm 图表
- ksonnet 应用程序
- jsonnet 文件
- 基于 YAML/json 配置
- 配置管理插件配置的任何自定义配置管理工具
Argo CD 实现为 kubernetes 控制器,它持续监视运行中的应用程序,并将当前的活动状态与期望的目标状态进行比较 (如 Git repo 中指定的那样)。如果已部署的应用程序的活动状态偏离了目标状态,则认为是 OutOfSync。Argo CD 报告和可视化这些差异,同时提供了方法,可以自动或手动将活动状态同步回所需的目标状态。在 Git repo 中对所需目标状态所做的任何修改都可以自动应用并反映到指定的目标环境中。
Argo CD 就处在如下位置:
它的优势总结如下:
- 应用定义、配置和环境信息是声明式的,并且可以进行版本控制;
- 应用部署和生命周期管理是全自动化的,是可审计的,清晰易懂;
- Argo CD 是一个独立的部署工具,支持对多个环境、多个 Kubernetes 集群上的应用进行统一部署和管理
实践
前提:有一个可用的 Kubernetes 集群。
实验环境:
- kubernetes:1.17.2
- argo cd:latest
安装 Argo CD
安装很简单,不过在实际使用中需要对数据进行持久化。
我这里直接使用官方文档的安装命令:
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
执行成功后会在 argocd
的 namespace 下创建如下资源。
# kubectl get all -n argocd
NAME READY STATUS RESTARTS AGE
pod/argocd-application-controller-0 1/1 Running 0 16h
pod/argocd-dex-server-74d9998fdb-mvpmh 1/1 Running 0 16h
pod/argocd-redis-59dbdbb8f9-msxrp 1/1 Running 0 16h
pod/argocd-repo-server-599bdc7cf5-ccv8l 1/1 Running 0 16h
pod/argocd-server-576b4c7ff4-cnp9d 1/1 Running 0 16h
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/argocd-dex-server ClusterIP 10.105.217.139 <none> 5556/TCP,5557/TCP,5558/TCP 16h
service/argocd-metrics ClusterIP 10.97.116.36 <none> 8082/TCP 16h
service/argocd-redis ClusterIP 10.105.63.34 <none> 6379/TCP 16h
service/argocd-repo-server ClusterIP 10.111.153.131 <none> 8081/TCP,8084/TCP 16h
service/argocd-server ClusterIP 10.105.229.250 <none> 80/TCP,443/TCP 16h
service/argocd-server-metrics ClusterIP 10.104.8.45 <none> 8083/TCP 16h
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/argocd-dex-server 1/1 1 1 16h
deployment.apps/argocd-redis 1/1 1 1 16h
deployment.apps/argocd-repo-server 1/1 1 1 16h
deployment.apps/argocd-server 1/1 1 1 16h
NAME DESIRED CURRENT READY AGE
replicaset.apps/argocd-dex-server-74d9998fdb 1 1 1 16h
replicaset.apps/argocd-redis-59dbdbb8f9 1 1 1 16h
replicaset.apps/argocd-repo-server-599bdc7cf5 1 1 1 16h
replicaset.apps/argocd-server-576b4c7ff4 1 1 1 16h
NAME READY AGE
statefulset.apps/argocd-application-controller 1/1 16h
访问 Argo server 的方式有两种:
- 通过 web ui
- 使用 argocd 客户端工具
我这里直接使用 web ui 进行管理。
通过 kubectl edit -n argocd svc argocd-server
将 service 的 type 类型改为 NodePort。改完后通过以下命令查看端口:
# kubectl get svc -n argocd
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
argocd-dex-server ClusterIP 10.105.217.139 <none> 5556/TCP,5557/TCP,5558/TCP 17h
argocd-metrics ClusterIP 10.97.116.36 <none> 8082/TCP 17h
argocd-redis ClusterIP 10.105.63.34 <none> 6379/TCP 17h
argocd-repo-server ClusterIP 10.111.153.131 <none> 8081/TCP,8084/TCP 17h
argocd-server NodePort 10.105.229.250 <none> 80:32109/TCP,443:30149/TCP 17h
argocd-server-metrics ClusterIP 10.104.8.45 <none> 8083/TCP 17h
然后通过 http://IP:32109 访问页面,如下:
登录账号为 admin,密码通过以下命令获取。
kubectl get pods -n argocd -l app.kubernetes.io/name=argocd-server -o name | cut -d'/' -f 2
然后进入如下界面。
更改密码
默认密码是 pod 的名字,使用客户端修改密码。
(1)下载客户端,在 github 上下载即可,https://github.com/argoproj/argo-cd/releases
(2)用客户端登录
# argocd login 172.17.100.50:32109
WARNING: server certificate had error: x509: cannot validate certificate for 172.17.100.50 because it doesn't contain any IP SANs. Proceed insecurely (y/n)? y
Username: admin
Password:
'admin' logged in successfully
Context '172.17.100.50:32109' updated
(3)修改密码
# argocd account update-password \
--account admin \
--current-password argocd-server-5dcc6878cf-75j94 \
--new-password admin
Password updated
Context '172.17.100.50:32109' updated
创建应用
这里仅仅是为了测试 argo,所以并没有做 ci 部分。
我在 gitlab 上准备了一个仓库,仓库里的文件很简单,如下:
其中 manifests 下就是一个 deployment 文件,内容如下:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: devops-argocd-test
name: devops-argocd-test
namespace: default
spec:
minReadySeconds: 60
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: devops-argocd-test
template:
metadata:
labels:
app: devops-argocd-test
spec:
containers:
- name: devops-argocd-test
image: registry.cn-hangzhou.aliyuncs.com/rookieops/argocd-test-app:v1
imagePullPolicy: Always
ports:
- containerPort: 8080
name: tcp-8080
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
labels:
app: devops-argocd-test
name: devops-argocd-test
namespace: default
spec:
ports:
- name: tcp-8080
port: 8080
protocol: TCP
targetPort: 8080
selector:
app: devops-argocd-test
sessionAffinity: None
type: NodePort
现在我们在 Argo 里创建应用,步骤如下:
(1)添加仓库地址,Settings → Repositories,点击 Connect Repo using HTTPS
按钮:
填入以下信息。
验证通过后显示如下:
(2)创建应用
创建完成后如下所示:
由于我设置的是手动 SYNC,所以需要点以下下面的 SYNC 进行同步。
然后可以看到状态都变成正常。
这时候我们在集群里可以看到创建了 v1 版本的应用了。
# kubectl get pod | grep devops-argocd-test
devops-argocd-test-7f5fdd9fcf-xbzmp 1/1 Running 0 118s
# kubectl get svc | grep devops-argocd-test
devops-argocd-test NodePort 10.97.159.140 <none> 8080:31980/TCP 2m6s
这时候访问应用,如下:
配置变更
接下来我手动进行配置变更,修改 manifests 下的 deploymeny.yaml 文件中的镜像为 v2 版本,如下:
然后提交到仓库。
这是到 ArgoCD 中可以看到状态变成了 OutOfSync
这时候再手动 sync 以下,直到状态都变正常。再访问上面的应用。
可以看到应用已经更新部署了。
我们可以看到整个应用的关系状态,如下:
还可以看到部署历史。
也可以通过这个界面进行回滚。
不过这个回滚并不会回改 gitlab 上的代码哈。
我上面设置的是手动,你可以设置为自动,自己动手测试一番吧。