暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Kubernetes中的GitOps:如何使用GitLab CI和Argo CD进行操作

云原生CTO 2020-11-06
1570

Kubernetes中的GitOps:如何使用GitLab CI和Argo CD进行操作


最近,Cloud Native一直在谈论GitOps。现在云原生圈里面基本上都会浮现以及说道gitops的话题,而实际上,这种持续交付模式是现代IT世界的一种革命。为什么这么说,前几天我在云原生CTO交流群发了一版高清的云原生布道图,图中描绘了整个云原生在各领域的路线map,在整合交付这块最引人注意的就是argo,当然后面我会通过示例教给你如何使用它,而这里我不会描述GitOps是什么,因为你可以在Internet上找到很多有关它的资源。

因为找到GitOps的definition是比较容易的事情,但是从另一方面找到这样的工作流程的例子是相当有难度。这也是我写这个博客的主要原因。我希望你可以在这里找到很多有用的信息,这些信息可以帮助你在当前基础架构设置中创建GitOps。

1 目录介绍

  • Argo CD安装
  • GitLab项目设置
  • GitLab项目 CI Pipeline
  • 这个怎么运作?
  • 概要

2 介绍

下图显示了此项目中演示的GitOps工作流程

             gitops工作流程

复制

GitLab和Argo CD在这里起主要作用,所以我现在想谈谈它们。

Argo CD 是用于Kubernetes的声明性GitOps连续交付工具。我喜欢它,因为它相对容易配置和使用(需要基本的Kubernetes知识)。它带有漂亮且易于理解的GUI。对我而言,重要的是Argo CD以多种方式支持清单(kustomize,helm,ksonnet甚至jsonnet文件)。可以以Argo CD添加的专用“自定义资源定义”的形式配置应用程序。它可以自动在指定的目标环境中部署所需的应用程序状态。有关体系结构的更多信息,请访问官方项目网站上的可用功能。

顾名思义,GitLab CI是GitLab的持续集成和持续交付工具。对我来说,与其他竞争对手相比,它是CI CD任务的很好选择。我喜欢它,因为与其他工具(例如Jenkins)相比,创建管道非常容易(简单的.gitlab-ci.yaml文件)。对于此演示,我将使用一个支持大多数必要功能的免费版本。因此,让我们开始吧!

3 Argo CD安装

我将在PC上托管的Minikube群集上设置GitOps 。第一步是确保我可以通过kubectl访问集群。我通常为此列出节点,另外现在Kubernetes还支持在线集群的调试,比如你使用Play with Kubernetes等,或者自建的kubeadm都可以尝试去使用

~> kubectl get nodes
NAME   STATUS   ROLES    AGE   VERSION
m01    Ready    master   42s   v1.17.3

复制

我还需要一个入口控制器来访问Argo CD GUI。在Minikube中,只需启用额外的附件即可。

~> minikube addons enable ingress

复制

接下来,我将使用Helm(首选版本3)安装Argo CD:

~> kubectl create namespace argocd
~> helm repo add argo https://argoproj.github.io/argo-helm
~> helm install argocd -n argocd argo/argocd --values values.yaml

复制

这是我在此示例中使用的values.yaml文件:

appVersion: "1.4.2"
version: 1.8.7
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.minikube.local

复制

之后,将安装我的Argo CD。要访问它,请获取入口地址,并将必要的条目添加到本地/ etc hosts中。

~> kubectl get ingress -n argocd
NAME            HOSTS                   ADDRESS          PORTS   AGE
argocd-server   argocd.minikube.local   192.168.99.105   80      15m
~> echo '192.168.99.105 argocd.minikube.local' | sudo tee -a /etc/hosts

复制

现在,我可以从浏览器访问Argo CD GUI。

默认用户名是admin,密码是pod的名称。例:

~> kubectl get pods -n argocd -l app.kubernetes.io/name=argocd-server -o name | cut -d'/' -f 2
argocd-server-5cbcf6864-587hr

复制

目前为止就这样了。下一步是使用示例代码创建GitLab项目。

4 GitLab项目设置

对于此演示,我有一个用Go编写的小应用程序。这是一个网络应用程序,在其旁边显示文本消息和窗格名称。

GitLab不仅随附CI CD,而且还为每个项目提供了容器注册表。我想在示例中使用它。还必须创建具有API范围的访问令牌。稍后将在管道中将其用于git commit。你可以在USER-> SETTINGS-> ACCESS TOKENS中创建自己的 接下来,将必要的环境变量添加到项目中(设置-> CI CD->变量):CI_PUSH_TOKEN-令牌 CI_USERNAME-令牌所有者的用户名

5 ArgoCD应用程序设置

是时候使用GitOps在Kubernetes中配置我们的应用程序了。如前所述,Argo CD带有一组CRD,可用于声明式配置。当然,这是推荐的方法,因为我们希望将基础结构保留为代码。以下是为开发人员和产品环境配置Web应用程序的清单:

---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: web-app-dev
  namespace: argocd
spec:
  project: default
  source
    repoURL: https://gitlab.com/andrew.kaczynski/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: https://gitlab.com/andrew.kaczynski/gitops-webapp.git
    targetRevision: HEAD
    path: deployment/prod
  destination:
    server: https://kubernetes.default.svc
    namespace: prod
  syncPolicy:
    automated:
      prune: true

复制

这里最重要的部分是:名称-Argo CD应用程序的名称 名称空间-必须与Argo CD实例相同 项目—将在其中配置应用程序的项目名称(这是在Argo CD中组织应用程序的方式) repoURL-我们的源代码存储库的URL targetRevision —你要使用的git分支 path-Kubernetes清单存储在存储库中的路径 destination — Kubernetes与目的地相关的事物(在这种情况下,群集与托管Argo CD的群集相同) 像使用kubectl的其他清单一样应用这些清单。在您的集群中将创建两个对象类型“ application”。

~> kubectl get application -n argocd
NAME           AGE
web-app-dev    20m
web-app-prod   17m

复制

当你访问Argo CD Web仪表板时,可以看到这两个应用程序。

Argo CD中的应用程序部署

单击其中之一以查看有关应用程序和已部署的Kubernetes对象的更多详细信息。你可以在gitops-webapp存储库中的deployment 目录中找到该对象。你可以看到在每个文件夹中,我创建了kustomization.yaml。Argo CD可以识别它,并且无需任何其他设置即可使用Kustomize 进行应用!我建议你看看可用的选项。GUI非常直观,因此理解它应该没有任何问题。

6 Gitlab CI Pipeline

下一步是创建管道,该管道将自动构建我们的应用程序,推送到容器注册表并在所需环境中更新Kubernetes清单。下面的示例远非完美(缺少测试等),但是它应该向你演示整个GitOps工作流程。基本上,想法是,开发人员在自己的分支上工作。对于分支的每次提交和推送,都会触发阶段构建。当他们将其更改与master分支合并时,将触发整个管道。它将构建应用程序,对其进行容器化,将镜像推送到镜像仓库并根据阶段自动更新Kubernetes清单。此外,部署到Prod需要DevOps手动操作。GitLab CI中的管道定义存储在项目根目录下的.gitlab-ci.yml文件中。文件的顶部是阶段的定义以及默认环境变量,镜像或脚本步骤之前。我的管道摘录:

  stages:
- build
- publish
- deploy-dev
- deploy-prod

复制

接下来是阶段定义和必需的任务。这里的构建过程非常简单。它仅在docker image golang中执行一个命令。然后将其保存为下一个阶段的工件。此步骤适用于任何分支中的任何新提交。

 build:
  stage: build
  image:
    name: golang:1.13.1
  script:
    - go build -o main main.go
  artifacts:
    paths:
      - main
  variables:
    CGO_ENABLED: 0

复制

下一步是将应用程序部署到开发环境。在GitOps中,这意味着要更新Kubernetes清单,以便Argo CD可以提取更新的版本并应用更改。在这里,我使用为项目定义的环境变量以及用户名和令牌,这些变量需要将更改推送到master分支。当GitLab CI收到带有消息[skip ci]的提交时,不会触发管道(在发布与kustomize清单相关的更改时,我们不想再次运行它)

  publish:
  stage: publish
  image:
    name: gcr.io/kaniko-project/executor:debug
    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可以提取更新的版本并应用更改。在这里,我使用为项目定义的环境变量以及用户名和令牌,这些变量需要将更改推送到master分支。当GitLab CI收到带有消息[skip ci]的提交时,不会触发管道(在发布与kustomize清单相关的更改时,我们不想再次运行它)

  deploy-dev:
  stage: deploy-dev
  image: alpine:3.8
  before_script:
    - apk add --no-cache git curl bash
    - curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh"  | bash
    - mv kustomize /usr/local/bin/
    - git remote set-url origin https://${CI_USERNAME}:${CI_PUSH_TOKEN}@gitlab.com/andrew.kaczynski/gitops-webapp.git
    - git config --global user.email "gitlab@gitlab.com"
    - 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_SHA
    - cat kustomization.yaml
    - git commit -am '[skip ci] DEV image update'
    - git push origin master
  only:
    - master

复制

最后,我们可以部署到生产环境。它与上一个非常相似,但是需要手动操作才能开始。

  deploy-prod:
  stage: deploy-prod
  image: alpine:3.8
  before_script:
    - apk add --no-cache git curl bash
    - curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh"  | bash
    - mv kustomize /usr/local/bin/
    - git remote set-url origin https://${CI_USERNAME}:${CI_PUSH_TOKEN}@gitlab.com/andrew.kaczynski/gitops-webapp.git
    - git config --global user.email "gitlab@gitlab.com"
    - 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_SHA
    - cat kustomization.yaml
    - git commit -am '[skip ci] PROD image update'
    - git push origin master
  only:
    - master
  when: manual

复制

这是完整的管道定义。我希望你看到与Jenkins相比在GitLab中创建管道是多么容易:)这就是为什么我喜欢它!

7 这个怎么运作?

现在,让我们看看它们如何协同工作。首先,获取应用程序入口的IP,并将必要的条目添加到本地/ etc hosts文件中。

~> kubectl get ingress --all-namespaces |grep gitops
dev         gitops-webapp   webapp.dev.minikube.local    192.168.99.105   80      25m
prod        gitops-webapp   webapp.prod.minikube.local   192.168.99.105   80      25m
~> echo "192.168.99.105 webapp.dev.minikube.local" | sudo tee -a /etc/hosts
~> echo "192.168.99.105 webapp.prod.minikube.local" | sudo tee -a /etc/hosts

复制

现在,你可以使用浏览器显示Web应用程序消息。让我们看一下dev webapp。

然后是时候进行一些小的更改并将其推送给主服务器了。只需编辑main.go文件,然后将变量ANDREW的名称ANDREW更改为GITOPS

func main() {
   welcome := Welcome{"GITOPS", time.Now().Format(time.Stamp), os.Getenv("HOSTNAME")}
  

复制

提交更改并将其推送给主服务器。然后转到GitLab项目-> CI / CD->管道。你将看到一条刚刚开始的新管道。

等待几分钟,当部署到开发阶段完成时,你将看到一条状态已跳过的新管道(该管道已经为dev更新了清单)。自动同步模式下的Argo CD将在不到一分钟的时间内更新Kubernetes状态。你可以在Argo GUI中查看进度。再次检查网络应用程序以查看更新的消息。

          GitLab CI / CD管道

复制
          更新了webapp消息

复制

最后,通过批准管道阶段来手动触发产品构建。之后,产品中的镜像也会被更新。

         GitLab CI / CD产品部署

复制

同步就绪后,这是Argo CD更新的仪表板。

至此,应用程序已使用GitOps成功部署到开发和生产环境中!

共勉

生命不是要超越别人,而是要超越自己。

如果喜欢😍文章的话,点点关注,就差你的关注了,更多好玩有趣的云原生前沿技术尽在云原生CTO,如果对你有帮助,欢迎分享给更多人


文章转载自云原生CTO,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论