前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用 GitLab CI 与 Argo CD 进行 GitOps 实践

使用 GitLab CI 与 Argo CD 进行 GitOps 实践

作者头像
我是阳明
发布2020-07-17 15:20:48
5.4K0
发布2020-07-17 15:20:48
举报
文章被收录于专栏:k8s技术圈

在现在的云原生世界里面 GitOps 不断的被提及,这种持续交付的模式越来越受到了大家的青睐,在网上也可以找到很多关于它的资源,但是关于 GitOps 相关的工作流实践的示例却并不多见,我们这里就将详细介绍一个使用示例,希望对大家实践 GitOps 有所帮助。

介绍

GitOps Workflow

上图是当前示例中的 GitOps 工作流程。GitLab 和 Argo CD 是两个主要的核心组件:

Argo CD 是一个声明式、GitOps 持续交付的 Kubernetes 工具,它的配置和使用非常简单,并且自带一个简单易用的 Dashboard 页面,更重要的是 Argo CD 支持 kustomzie、helm、ksonnet 等多种工具。应用程序可以通过 Argo CD 提供的 CRD 资源对象进行配置,可以在指定的目标环境中自动部署所需的应用程序。关于 Argo CD 更多的信息可以查看官方文档了解更多。

GitLab CI 是 GitLab 的持续集成和持续交付的工具,也是非常流行的 CI/CD 工具,相比 Jenkins 更加轻量级,更重要的是和 GitLab 天然集成在一起的,所以非常方便。

Argo CD 安装

当前前提条件是有一个可用的 Kubernetes 集群,通过 kubectl 可以正常访问集群,为了访问 Argo CD 的 Dashboard 页面,我们可以通过 Ingress 来暴露服务,为此需要在 Kubernetes 中安装一个 Ingress Controller,我这里已经提前安装了 ingress-nginx,接下来我们将 Helm3 来安装 Argo CD,关于 Helm 以及 ingress-nginx 的使用我们前面的文章中已经多次提到,这里就不再详细介绍他们的使用了。

首先创建一个 argocd 的命名空间:

代码语言:javascript
复制
$ kubectl create ns argocd

然后添加 argocd 的 chart 仓库地址:

代码语言:javascript
复制
$ helm repo add argo https://argoproj.github.io/argo-helm

接下来我们就可以使用 Helm 安装 Argo CD 了:

代码语言:javascript
复制
$ helm install argocd -n argocd argo/argo-cd --values values.yaml

其中 values.yaml 文件如下所示,用来定制安装的 Argo CD:

代码语言:javascript
复制
server:
  ingress:
    enabled: true
    annotations:
      kubernetes.io/ingress.class: "nginx"
      nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
      nginx.ingress.kubernetes.io/ssl-passthrough: "true"
      nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
    hosts:
    - argocd.k8s.local

执行上面的安装命令后,Argo CD 就会被安装在 argocd 命名空间之下,可以在本地 /etc/hosts 中添加一个映射,将 argocd.k8s.local 映射到 ingress-nginx 所在的节点即可:

代码语言:javascript
复制
$ helm ls -n argocd
NAME    NAMESPACE       REVISION        UPDATED                                 STATUS    CHART            APP VERSION
argocd  argocd          2               2020-07-10 15:26:38.259258 +0800 CST    deployed  argo-cd-2.5.0    1.6.1
$ kubectl get pods -n argocd
NAME                                             READY   STATUS    RESTARTS   AGE
argocd-application-controller-85c4788ffc-p2m4c   1/1     Running   0          49m
argocd-dex-server-cc65c7546-x78bj                1/1     Running   0          49m
argocd-redis-5f45875bc7-mnx8b                    1/1     Running   0          49m
argocd-repo-server-7bcf647588-h8gtq              1/1     Running   0          49m
argocd-server-7877ff8889-zp7tq                   1/1     Running   0          49m

当所有 Pod 变成 Running 状态后,我们就可以通过浏览器访问 Argo CD 的 Dashboard 页面了:

默认的用户名为 admin,密码为 server Pod 的名称,可以通过如下所示的命令来获取:

代码语言:javascript
复制
$ kubectl get pods -n argocd -l app.kubernetes.io/name=argocd-server -o name | cut -d'/' -f 2
argocd-server-7877ff8889-zp7tq

用上面的用户名和密码即可登录成功,接下来我们在 GitLab 中来创建示例项目。

GitLab 项目配置

我们这里使用的示例项目是一个 Golang 程序,在页面上显示一个文本信息和 Pod 名称,代码地址:https://github.com/cnych/gitops-webapp-demo。我们可以将该项目代码上传到我们自己的 GitLab 上面去,我这里的 GitLab 安装在 Kubernetes 之上,通过配置域名 git.k8s.local 进行访问,调整过后我们本地的代码仓库地址为:http://git.k8s.local/course/gitops-webapp 。

接下来需要添加一些在 GitLab CI 流水线中用到的环境变量(Settings → CI/CD → Variables):

  • CI_REGISTRY - 镜像仓库地址,值为:https://index.docker.io/v1/
  • CI_REGISTRY_IMAGE - 镜像名称,值为:cnych/gitops-webapp
  • CI_REGISTRY_USER - Docker Hub 仓库用户名,值为 cnych
  • CI_REGISTRY_PASSWORD - Docker Hub 仓库密码
  • CI_PASSWORD - Git 仓库访问密码
  • CI_USERNAME - Git 仓库访问用户名

Argo CD 配置

现在我们可以开始使用 GitOps 来配置我们的 Kubernetes 中的应用了。Argo CD 自带了一套 CRD 对象,可以用来进行声明式配置,这当然也是推荐的方式,把我们的基础设施作为代码来进行托管,下面是我们为开发和生产两套环境配置的资源清单:

代码语言:javascript
复制
# gitops-demo-app.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: web-app-dev
  namespace: argocd
spec:
  project: default
  source:
    repoURL: http://git.k8s.local/course/gitops-webapp.git
    targetRevision: HEAD
    path: deployment/dev
  destination:
    server: https://kubernetes.default.svc
    namespace: dev
  syncPolicy:
    automated:
      prune: true
---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: web-app-prod
  namespace: argocd
spec:
  project: default
  source:
    repoURL: http://git.k8s.local/course/gitops-webapp.git
    targetRevision: HEAD
    path: deployment/prod
  destination:
    server: https://kubernetes.default.svc
    namespace: prod
  syncPolicy:
    automated:
      prune: true

上面定义的 Application 这个资源,就是 Argo CD 用于描述应用的 CRD 对象:

  • name:Argo CD 应用程序的名称
  • project:应用程序将被配置的项目名称,这是在 Argo CD 中应用程序的一种组织方式
  • repoURL:源代码的仓库地址
  • targetRevision:想要使用的 git 分支
  • path:Kubernetes 资源清单在仓库中的路径
  • destination:Kubernetes 集群中的目标

然后同样使用 kubectl 工具直接部署上面的资源对象即可,将会创建两个 Application 类型的对象:

代码语言:javascript
复制
$ kubectl apply -f gitops-demo-app.yaml
application.argoproj.io/web-app-dev created
application.argoproj.io/web-app-prod created
$ kubectl get application -n argocd
NAME           AGE
web-app-dev    25s
web-app-prod   24s

此时我们再去 Argo CD 的 Dashboard 首页同样将会看到两个 Application 的信息:

点击其中一个就可以看到关于应用的详细信息,我们可以在 gitops-webapp 代码仓库的 deployment/<env> 目录里面找到资源对象。我们可以看到,在每个文件夹下面都有一个 kustomization.yaml 文件,Argo CD 可以识别它,不需要任何其他的设置就可以使用。

由于我们这里的代码仓库是私有的 GitLab,所以我们还需要配置对应的仓库地址,在页面上 Settings → Repositories,点击 Connect Repo using HTTPS 按钮:

添加我们的代码仓库认证信息:

需要注意的是这里默认使用的是 HTTPS,所以我们需要勾选下方的 Skip server verification,然后点击上方的 CONNECT 按钮添加即可。然后重新同步上面的两个 Application,就可以看到正常的状态了。

GitLab CI 流水线

接下来我们需要为应用程序创建流水线,自动构建我们的应用程序,推送到镜像仓库,然后更新 Kubernetes 的资源清单文件。

下面的示例并不是一个多么完美的流水线,但是基本上可以展示整个 GitOps 的工作流。开发人员在自己的分支上开发代码,他们分支的每一次提交都会触发一个阶段性的构建,当他们将自己的修改和主分支合并时,完整的流水线就被触发。将构建应用程序,打包成 Docker 镜像,将镜推送到 Docker 仓库,并自动更新 Kubernetes 资源清单,此外,一般情况下将应用部署到生产环境需要手动操作。

GitLab CI 中的流水线默认定义在代码仓库根目录下的 .gitlab-ci.yml 文件中,在该文件的最上面定义了一些构建阶段和环境变量、镜像以及一些前置脚本:

代码语言:javascript
复制
stages:
- build
- publish
- deploy-dev
- deploy-prod

接下来是阶段的定义和所需的任务声明。我们这里的构建过程比较简单,只需要在一个 golang 镜像中执行一个构建命令即可,然后将编译好的二进制文件保存到下一个阶段处理,这一个阶段适合分支的任何变更:

代码语言:javascript
复制
build:
  stage: build
  image:
    name: golang:1.13.1
  script:
    - go build -o main main.go
  artifacts:
    paths:
      - main
  variables:
    CGO_ENABLED: 0

然后就是构建镜像并推送到镜像仓库,这里我们使用 Kaniko,当然也可以使用 DinD 模式进行构建,只是安全性不高,这里我们可以使用 GIT 提交的 commit 哈希值作为镜像 tag,关于 Docker 镜像仓库的认证和镜像地址信息可以通过项目的参数来进行传递,不过这个阶段只在主分支发生变化时才会触发:

代码语言:javascript
复制
publish:
  stage: publish
  image:
    name: cnych/kaniko-executor:v0.22.0
    entrypoint: [""]
  script:
    - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json
    - /kaniko/executor --context $CI_PROJECT_DIR --dockerfile ./Dockerfile --destination $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
  dependencies:
    - build
  only:
    - master

下一个阶段就是将应用程序部署到开发环境中,在 GitOps 中就意味着需要更新 Kubernetes 的资源清单,这样 Argo CD 就可以拉取更新的版本来部署应用。这里我们使用了为项目定义的环境变量,包括用户名和 TOKEN,此外在提交消息里面增加 [skip ci] 这样的关键字,这样流水线就不会被触发:

代码语言:javascript
复制
deploy-dev:
  stage: deploy-dev
  image: cnych/kustomize:v1.0
  before_script:
    - git remote set-url origin http://${CI_USERNAME}:${CI_PASSWORD}@git.k8s.local/course/gitops-webapp.git
    - git config --global user.email "gitlab@git.k8s.local"
    - git config --global user.name "GitLab CI/CD"
  script:
    - git checkout -B master
    - cd deployment/dev
    - kustomize edit set image $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
    - cat kustomization.yaml
    - git commit -am '[skip ci] DEV image update'
    - git push origin master
  only:
    - master

最后添加一个部署到 prod 环境的阶段,和前面非常类似,只是添加了一个手动操作的流程:

代码语言:javascript
复制
deploy-prod:
  stage: deploy-prod
  image: cnych/kustomize:v1.0
  before_script:
    - git remote set-url origin http://${CI_USERNAME}:${CI_PASSWORD}@git.k8s.local/course/gitops-webapp.git
    - git config --global user.email "gitlab@git.k8s.local"
    - git config --global user.name "GitLab CI/CD"
  script:
    - git checkout -B master
    - git pull origin master
    - cd deployment/prod
    - kustomize edit set image $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
    - cat kustomization.yaml
    - git commit -am '[skip ci] PROD image update'
    - git push origin master
  only:
    - master
  when: manual

这样我们就完成了整个流水线的定义。

使用

接下来我们来看看它们是如何一起工作的。我们将开发和线上两个环境的应用分别部署在了 dev 和 prod 命名空间之下,通过 Ingress 暴露服务,同样需要将两个应用的域名 http://webapp.dev.k8s.local/ 与 http://webapp.prod.k8s.local/ 在本地 /etc/hosts 中添加映射。

如果一切正常的话现在我们可以在浏览器中来查看我们部署的 web 应用程序了。

Dev web app

然后我们来尝试修改下代码,编辑 main.go 文件,将变量 welcome 中的 GITOPS 修改为 GITOPS-K8S:

代码语言:javascript
复制
func main() {
   welcome := Welcome{"GITOPS-K8S", time.Now().Format(time.Stamp), os.Getenv("HOSTNAME")
    ......
}

然后提交代码到 master 分支,然后进入 GitLab 项目 -> CI/CD -> Pipelines,就可以看到一个新的流水线开始构建了。

等待一会儿,正常情况下会执行到 dev 的部署阶段,然后变成 skipped 的状态,此时流水线已经将代码中的 dev 下的资源清单文件已经更新了。

GitLab CI/CD Pipeline

然后 Argo CD 在自动同步模式下在一分钟内变会更新 Kubernetes 的资源对象,我们也可以在 Argo CD 的页面中看到进度。当 Argo CD 中同步完成后我们再去查看 DEV 环境的应用,就可以看到页面上面的信息已经变成了 GITOPS-K8S 了。

Update Dev Web APP

最后如果需要部署到 prod 环境,我们只需要在 GitLab 的流水线中手动触发即可,之后,prod 中的镜像也会被更新。

GitLab CI/CD Prod deployment

下面是同步时 Argo CD 更新的页面状态变化图。

Argo CD Sync Workflow

到这里,我们就使用 GitOps 成功的将我们的应用部署到了开发和生产环境之中了。

参考链接

  • https://www.weave.works/technologies/gitops/
  • https://argoproj.github.io/argo-cd/
  • https://docs.gitlab.com/ee/ci/yaml/
  • https://medium.com/@andrew.kaczynski/gitops-in-kubernetes-argo-cd-and-gitlab-ci-cd-5828c8eb34d6
  • https://github.com/cnych/gitops-webapp-demo
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-07-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 k8s技术圈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 介绍
  • Argo CD 安装
  • GitLab 项目配置
  • Argo CD 配置
  • GitLab CI 流水线
  • 使用
  • 参考链接
相关产品与服务
容器镜像服务
容器镜像服务(Tencent Container Registry,TCR)为您提供安全独享、高性能的容器镜像托管分发服务。您可同时在全球多个地域创建独享实例,以实现容器镜像的就近拉取,降低拉取时间,节约带宽成本。TCR 提供细颗粒度的权限管理及访问控制,保障您的数据安全。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档