当前位置: 首页 > news >正文

ArgoCD 与 GitOps:K8S 原生持续部署的实操指南

容器技术的爆发让 Kubernetes(K8s)成为了「云原生时代的操作系统」—— 它能高效编排成千上万的容器,解决弹性伸缩、资源调度等核心问题。但随着企业应用规模扩大,K8s 的「部署与管理」逐渐暴露新的挑战:

  • 多环境(开发、测试、生产)配置不一致,手动执行 kubectl apply 容易出错;
  • 应用配置散落在各种 YAML 文件、脚本或工程师的本地环境中,「配置漂移」成为常态(实际运行状态与预期状态偏离);
  • 回滚、版本管理依赖人工记录,出问题时难以快速定位根源;
  • 跨团队协作时,开发、运维对「应用状态」的认知不同步,沟通成本高。

这些问题的核心,本质是「如何让 K8s 中的应用状态与「预期配置」保持一致」。此时,「GitOps」理念应运而生:它将 Git 仓库作为应用配置的「单一可信数据源」,用声明式语法定义应用的「最终状态」,再通过工具自动将「预期状态」同步到 K8s 集群中。

而 ArgoCD 正是 GitOps 理念在 K8s 中的「最佳实践工具」—— 它以 Git 仓库为核心,持续监控 K8s 集群状态与 Git 配置的差异,自动触发同步,甚至能在配置被意外修改时「自动纠偏」。

本文将深入探讨:ArgoCD 如何与 K8s 深度结合?它能解决哪些实际问题?以及如何通过 ArgoCD 在 K8s 中落地 GitOps,让应用部署从「手动运维」升级为「自动化、可追溯、一致性」的闭环?

一、 部署ArgoCD

参考链接

Argo CD - Declarative GitOps CD for Kubernetes

argoproj/argo-cd: Declarative Continuous Deployment for Kubernetes

1. 快速入门

kubectl 创建命名空间 argocd

kubectl create namespace argocd

使用 kubectl 命令,在 argocd 命名空间下,应用以下配置文件:

kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

2. 查看资源

root@k8s-master:~# kubectl get deploy,po,svc -n argocd
NAME                                               READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/argocd-applicationset-controller   1/1     1            1           18m
deployment.apps/argocd-dex-server                  1/1     1            1           18m
deployment.apps/argocd-notifications-controller    1/1     1            1           18m
deployment.apps/argocd-redis                       1/1     1            1           18m
deployment.apps/argocd-repo-server                 1/1     1            1           18m
deployment.apps/argocd-server                      1/1     1            1           18mNAME                                                    READY   STATUS    RESTARTS   AGE
pod/argocd-application-controller-0                     1/1     Running   0          18m
pod/argocd-applicationset-controller-655cc58ff8-4b7bj   1/1     Running   0          18m
pod/argocd-dex-server-7d9dfb4fb8-447zb                  1/1     Running   0          18m
pod/argocd-notifications-controller-6c6848bc4c-gmms8    1/1     Running   0          18m
pod/argocd-redis-656c79549c-2zbc9                       1/1     Running   0          18m
pod/argocd-repo-server-856b768fd9-br979                 1/1     Running   0          18m
pod/argocd-server-99c485944-rqznp                       1/1     Running   0          18mNAME                                              TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
service/argocd-applicationset-controller          ClusterIP   10.200.150.131   <none>        7000/TCP,8080/TCP            18m
service/argocd-dex-server                         ClusterIP   10.200.116.20    <none>        5556/TCP,5557/TCP,5558/TCP   18m
service/argocd-metrics                            ClusterIP   10.200.183.3     <none>        8082/TCP                     18m
service/argocd-notifications-controller-metrics   ClusterIP   10.200.183.138   <none>        9001/TCP                     18m
service/argocd-redis                              ClusterIP   10.200.101.160   <none>        6379/TCP                     18m
service/argocd-repo-server                        ClusterIP   10.200.167.8     <none>        8081/TCP,8084/TCP            18m
service/argocd-server                             NodePort    10.200.105.205   <none>        80:30080/TCP,443:32076/TCP   18m
service/argocd-server-metrics                     ClusterIP   10.200.182.238   <none>        8083/TCP                     18m
root@k8s-master:~# 

注意,这里的SVC类型默认是ClusterIP类型,需要手动去修改我们想要的类型。

root@k8s-master:~# kubectl edit svc argocd-server -n argocd
apiVersion: v1
kind: Service
metadata:annotations:kubectl.kubernetes.io/last-applied-configuration: |{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"app.kubernetes.io/component":"server","app.kubernetes.io/name":"argocd-server","app.kubernetes.io/part-of":"argocd"},"name":"argocd-server","namespace":"argocd"},"spec":{"ports":[{"name":"http","port":80,"protocol":"TCP","targetPort":8080},{"name":"https","port":443,"protocol":"TCP","targetPort":8080}],"selector":{"app.kubernetes.io/name":"argocd-server"}}}creationTimestamp: "2025-08-08T01:32:09Z"labels:app.kubernetes.io/component: serverapp.kubernetes.io/name: argocd-serverapp.kubernetes.io/part-of: argocdname: argocd-servernamespace: argocdresourceVersion: "7618"uid: 800b750f-1597-4eb4-82f3-2be8cf2d8768
spec:clusterIP: 10.200.105.205clusterIPs:- 10.200.105.205externalTrafficPolicy: ClusterinternalTrafficPolicy: ClusteripFamilies:- IPv4ipFamilyPolicy: SingleStackports:- name: httpnodePort: 30080  ## 第一处修改port: 80protocol: TCPtargetPort: 8080- name: httpsnodePort: 32076port: 443protocol: TCPtargetPort: 8080selector:app.kubernetes.io/name: argocd-serversessionAffinity: Nonetype: NodePort    ## 第二处修改
status:loadBalancer: {}

更新一下资源清单即可。

root@k8s-master:~# kubectl apply -f install.yaml 

3. 访问测试

https://[your_ip]:port(以各自环境为准!)

用户名: admin
密  码: 
# 使用以下命令可以得到
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo

成功登入,就代表部署没有问题!

4. 安装argocd客户端命令行工具修改密码

# 下载
wget https://github.com/argoproj/argo-cd/releases/download/v3.0.12/argocd-linux-amd64root@k8s-master:~# mv argocd-linux-amd64 /usr/bin/argocd
root@k8s-master:~# chmod a+x /usr/bin/argocd
root@k8s-master:~# argocd version
argocd: v3.0.12+ed1e239BuildDate: 2025-07-25T20:01:42ZGitCommit: ed1e2397ef9af6d23b284e39d504308cdda1957bGitTreeState: cleanGoVersion: go1.24.4Compiler: gcPlatform: linux/amd64
{"level":"fatal","msg":"Argo CD server address unspecified","time":"2025-08-08T10:02:29+08:00"}root@k8s-master:~# argocd login 10.0.0.6:30080
WARNING: server certificate had error: tls: failed to verify certificate: x509: cannot validate certificate for 10.0.0.6 because it doesn't contain any IP SANs. Proceed insecurely (y/n)? y
Username: admin
Password: 
'admin:login' logged in successfully
Context '10.0.0.6:30080' updatedroot@k8s-master:~# 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 '10.0.0.6:30080' updated
注意密码是有复杂度要求的:
{"level":"fatal","msg":"rpc error: code = Unknown desc = New password does not match the following expression: ^.{8,32}$.","time":"2025-08-08T10:06:30+08:00"}# 验证一下我们的密码
root@k8s-master:~# argocd logout 10.0.0.6:30080
Logged out from '10.0.0.6:30080'
root@k8s-master:~# argocd login 10.0.0.6:30080
WARNING: server certificate had error: tls: failed to verify certificate: x509: cannot validate certificate for 10.0.0.6 because it doesn't contain any IP SANs. Proceed insecurely (y/n)? y
Username: admin
Password: 
'admin:login' logged in successfully
Context '10.0.0.6:30080' updated
root@k8s-master:~# 

二、了解ArgoCD

1. ArgoCD设置介绍

2. 准备Git仓库

这里我们用的是Gitee的公开库,自行创建即可。

root@k8s-master:~# mkdir argocd-repo
root@k8s-master:~# cd argocd-reporoot@k8s-master:~/argocd-repo# ll
total 8
drwxr-xr-x  2 root root 4096 Aug  8 10:31 ./
drwx------ 10 root root 4096 Aug  8 10:31 ../
root@k8s-master:~/argocd-repo# git init 
hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint: 
hint: 	git config --global init.defaultBranch <name>
hint: 
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint: 
hint: 	git branch -m <name>
Initialized empty Git repository in /root/argocd-repo/.git/
root@k8s-master:~/argocd-repo# ll -a
total 12
drwxr-xr-x  3 root root 4096 Aug  8 10:31 ./
drwx------ 10 root root 4096 Aug  8 10:31 ../
drwxr-xr-x  7 root root 4096 Aug  8 10:31 .git/
root@k8s-master:~/argocd-repo# touch README.md
root@k8s-master:~/argocd-repo# git add README.md
root@k8s-master:~/argocd-repo# git commit -m "first commit"
[master (root-commit) 9576f67] first commit1 file changed, 0 insertions(+), 0 deletions(-)create mode 100644 README.md
root@k8s-master:~/argocd-repo# git remote add origin https://gitee.com/cao-facan/argocd-repo.git
root@k8s-master:~/argocd-repo# git push -u origin "master"
Username for 'https://gitee.com': 1951
Password for 'https://1951@gitee.com': 
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 225 bytes | 225.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
remote: Powered by GITEE.COM [1.1.5]
remote: Set trace flag d1477e9f
To https://gitee.com/cao-facan/argocd-repo.git* [new branch]      master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.
root@k8s-master:~/argocd-repo# 

3. 上传我们的代码

此步骤和和README.md一样就是为了测试是否可以正常使用Gitee仓库,可以跳过第四步配置Git仓库。

root@k8s-master:~/argocd-repo# ll
total 228
drwxr-xr-x  6 root root  4096 Aug  8 10:35 ./
drwx------ 10 root root  4096 Aug  8 10:34 ../
drwxr-xr-x  2 root root  4096 Sep 19  2022 css/
drwxr-xr-x  8 root root  4096 Aug  8 10:36 .git/
-rw-r--r--  1 root root 29627 Jun 29  2019 index.html
-rw-r--r--  1 root root     0 Aug  8 10:31 README.mdroot@k8s-master:~/argocd-repo# git push -u origin "master"
Username for 'https://gitee.com': Nova    
Password for 'https://Nova@gitee.com': 
remote: [session-424d36a0] Nova: Incorrect username or password (access token)
fatal: Authentication failed for 'https://gitee.com/cao-facan/argocd-repo.git/'
root@k8s-master:~/argocd-repo# git push -u origin "master"
Username for 'https://gitee.com': 1951
Password for 'https://1951@gitee.com': 
Enumerating objects: 91, done.
Counting objects: 100% (91/91), done.
Delta compression using up to 4 threads
Compressing objects: 100% (90/90), done.
Writing objects: 100% (90/90), 1.48 MiB | 2.17 MiB/s, done.
Total 90 (delta 10), reused 0 (delta 0), pack-reused 0
remote: Powered by GITEE.COM [1.1.5]
remote: Set trace flag f84085b7
To https://gitee.com/cao-facan/argocd-repo.git9576f67..495df2c  master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.

4. 配置Git仓库

然后点击上方CONNECT连接,出现successful代表成功连接。

三、使用ArgoCD

1. 创建K8S资源清单

root@k8s-master:~/argocd-repo# cat myapp-deploy-svc.yml
apiVersion: apps/v1
kind: Deployment
metadata:name: myapp
spec:replicas: 1selector:matchLabels:app: myapptemplate:metadata:labels:app: myappspec:containers:- image: wangyanglinux/myapp:v1  # 容器镜像name: myapp                     # 容器名称(与 image 同层级缩进)ports:- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:name: myapp-svc
spec:type: NodePortselector:app: myappports:- port: 8080               # Service 集群内部端口(可自定义)targetPort: 80           # 映射到 Pod 的端口(需与上面 containerPort 一致)nodePort: 30088          # 节点暴露端口(可选,范围 30000-32767,不指定则自动分配)

同步到代码仓库

2. 使用ArgoCD创建应用

3. 验证连接并执行同步

root@k8s-master:~/argocd-repo# kubectl config get-contexts
CURRENT   NAME                          CLUSTER      AUTHINFO           NAMESPACE
*         kubernetes-admin@kubernetes   kubernetes   kubernetes-admin   
root@k8s-master:~/argocd-repo# argocd cluster list
SERVER                          NAME        VERSION  STATUS      MESSAGE  PROJECT
https://kubernetes.default.svc  in-cluster  1.32     Successful           
root@k8s-master:~/argocd-repo# 

点击上方CREATE 

进行同步

4.查看同步状态

可以看到每一步的详情

root@k8s-master:~/argocd-repo# kubectl get ns
NAME               STATUS   AGE
argocd             Active   129m
calico-apiserver   Active   28d
calico-system      Active   28d
default            Active   28d
kube-node-lease    Active   28d
kube-public        Active   28d
kube-system        Active   28d
myapp              Active   111m
tigera-operator    Active   28d
root@k8s-master:~/argocd-repo# kubectl get po -n myapp
NAME                     READY   STATUS    RESTARTS   AGE
myapp-7c4fb5f6fc-qbg27   1/1     Running   0          111m

5.验证pod

root@k8s-master:~/argocd-repo# kubectl get po,svc -n myapp -o wide
NAME                         READY   STATUS    RESTARTS   AGE    IP             NODE        NOMINATED NODE   READINESS GATES
pod/myapp-7c4fb5f6fc-qbg27   1/1     Running   0          112m   10.100.36.70   k8s-node1   <none>           <none>NAME                TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE    SELECTOR
service/myapp-svc   NodePort   10.200.91.180   <none>        8080:30088/TCP   112m   app=myapp
root@k8s-master:~/argocd-repo# curl 10.100.36.70
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>

没有问题.

四、使用ArgoCD更新应用

1. 修改代码

root@k8s-master:~/argocd-repo# cat myapp-deploy-svc.yml 
apiVersion: apps/v1
kind: Deployment
metadata:name: myapp
spec:replicas: 1selector:matchLabels:app: myapptemplate:metadata:labels:app: myappspec:containers:- image: wangyanglinux/myapp:v1  # 容器镜像name: myapp                     # 容器名称(与 image 同层级缩进)ports:- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:name: myapp-svc
spec:type: NodePortselector:app: myappports:- port: 8080               # Service 集群内部端口(可自定义)targetPort: 80           # 映射到 Pod 的端口(需与上面 containerPort 一致)nodePort: 30088          # 节点暴露端口(可选,范围 30000-32767,不指定则自动分配)root@k8s-master:~/argocd-repo# sed -i '/myapp:v1/s/v1/v2/' myapp-deploy-svc.yml 
root@k8s-master:~/argocd-repo# grep 'image' myapp-deploy-svc.yml- image: wangyanglinux/myapp:v2  # 容器镜像name: myapp                     # 容器名称(与 image 同层级缩进)

2. 提交到仓库

root@k8s-master:~/argocd-repo# git add .
root@k8s-master:~/argocd-repo# git commit -m "update image versio--->v2"
[master 8cd1683] update image versio--->v21 file changed, 1 insertion(+), 1 deletion(-)
root@k8s-master:~/argocd-repo# !305
git push -u origin master
Username for 'https://gitee.com': 1951
Password for 'https://19519921098@gitee.com': 
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 4 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 313 bytes | 313.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Powered by GITEE.COM [1.1.5]
remote: Set trace flag ce4cf793
To https://gitee.com/cao-facan/argocd-repo.git8130696..8cd1683  master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.

3. 使用ArgoCD同步

好了,那直接刷新页面查看版本是否变成了v2

没有问题,在K8S中之前的Podv1也会被清理掉,这是毋庸置疑的。

五、使用ArgoCD回滚版本

1. 使用ArgoCD进行回滚版本

2. 注意辨别

这时候就体现了我们commit代码的时候,写注解的好处了,我们可以通过注解来分辨我们提交代码更新了什么,从而更精准的回滚版本。

那我们回滚到我们V1版本

然后点击OK即可,等待同步完成。

刷新页面,没有任何问题。

六、总结与感想

1. K8S 的 CI/CD 中 Argo 与 Jenkins 的优劣势

Argo(以 ArgoCD 为核心,含 Argo Workflows 等)

优势

  • 云原生深度集成:专为 K8S 设计,通过 CRD(自定义资源)与 K8S 无缝对接,天然支持容器化部署流程。
  • GitOps 理念落地:以 Git 仓库为 “单一可信源”,通过声明式配置定义应用最终状态,自动同步集群状态与 Git 配置,解决 “配置漂移” 问题。
  • 自动化与自愈能力:持续监控集群状态,发现偏差时自动纠偏;支持自动同步(Git 变更后自动部署),减少人工干预。
  • 审计与回滚便捷:所有操作基于 Git 提交记录,可追溯性强;通过 Git 版本直接回滚,操作简单。
  • 轻量化与可扩展性:组件精简(如 repo-server、application-controller),适合大规模 K8S 集群部署。

劣势

  • CI 能力薄弱:核心聚焦 CD(持续部署),CI(构建、测试等)需依赖外部工具(如 GitLab CI、Tekton)。
  • 学习成本:需理解 GitOps 理念和 K8S 声明式配置,对新手有一定门槛。
Jenkins

优势

  • 全流程覆盖:CI/CD 一体化,支持从代码拉取、构建、测试到部署的全链路,插件生态丰富(超过 1800 个),适配多语言、多工具。
  • 灵活性高:支持自由风格、流水线(Pipeline)等多种配置方式,可通过脚本定制复杂流程(如条件判断、并行任务)。
  • 兼容性强:不仅适用于 K8S,还支持物理机、虚拟机等混合环境,适合企业多环境并存的场景。

劣势

  • 非云原生原生设计:基于传统架构,在 K8S 中部署需额外适配(如通过 Jenkins Agent 容器化),复杂度高。
  • 状态一致性难保证:依赖命令式脚本(如kubectl apply),配置分散在流水线脚本中,易出现 “实际状态与预期不符” 的漂移问题。
  • 维护成本高:插件版本兼容、节点管理(如 Agent 扩容)在大规模场景下易出问题,需专人维护。

2. 使用场景

  • Argo 适用场景

    • 纯 K8S 环境,需严格遵循 GitOps 理念,强调 “配置即代码” 和状态一致性;
    • 大规模集群部署(如多环境、多团队协作),需要自动化纠偏、审计和快速回滚;
    • 以 “部署一致性” 为核心诉求,CI 流程可依赖其他工具(如 Tekton)配合。
  • Jenkins 适用场景

    • 需复杂 CI 流程(如多语言构建、多轮测试、跨平台打包),依赖丰富插件生态;
    • 混合部署环境(K8S + 物理机 / 虚拟机),需统一流程管理;
    • 需高度定制化流水线(如条件分支、第三方系统集成),对灵活性要求高于 “状态一致性”。

3. 总结

Argo CD 是 “当下主流”,Kargo CD 是 “未来选项”

  • 当前选择:90% 以上的场景应优先采用 Argo CD,因其成熟、易用且能快速解决核心问题。

  • 何时考虑 Kargo CD

    1. 已全面落地 Argo CD 管理单集群;
    2. 需自动化多环境递进式交付(如灰度→生产);
    3. 团队规模较大(如管理超过 50 个应用或 10 个环境)。
  • 类比关系:Argo CD 如同 “智能手机”(普及度高),Kargo CD 类似 “专业相机”(特定场景刚需)。二者结合可形成完整的 GitOps 解决方案,但现阶段 Argo CD 仍是绝大多数用户的首选。

http://www.lryc.cn/news/613692.html

相关文章:

  • hive-日期拆分为多行
  • 二、k8s 1.29 之 网络
  • 2025年城市建设与智慧交通国际会议(ICUCIT 2025)
  • Vue复习
  • 暴力解决MySQL连接失败
  • 协同进化:AIGC、Agent和MCP如何相互促进共同发展
  • 内容分发机制研究:实测一款多源短视频聚合App
  • 医防融合中心-智慧化慢病全程管理医疗AI系统开发(上)
  • C++程序库选择:权衡与取舍的艺术——以iostream和stdio为例
  • 低压电工-------元器件认识
  • react+echarts实现个性化评分展示(类进度条)
  • AR眼镜:能源行业设备维护的“安全守护者”
  • Java 虚拟机之双亲委派机制
  • 接口自动化-pytest
  • 使用winsw把SpringBoot项目注册成window服务
  • Linux怎么查看时区信息?(Linux时区)(tzselect)
  • Xvfb虚拟屏幕(Linux)中文入门篇1:(wikipedia摘要,适当改写)
  • 容器 vs 虚拟机
  • 技法笔记3 | 验证交互式shell连接
  • 数据结构(五):顺序循环队列与哈希表
  • SkyWalking-1--SkyWalking是什么?
  • Kubernetes学习
  • 嵌入式开发学习———Linux环境下IO进程线程学习(六)
  • Qwen系列模型
  • 对比学习(Contrastive Learning)面试基础
  • STM32——STM32CubeMX
  • 4G/5G无线电单元系统
  • C语言:单链表学习
  • 北京-4年功能测试2年空窗-报培训班学测开-第七十天-面试第一天
  • rebase 和pull的通俗区别是什么