关于devops:GitLab-Jenkins-Harbor-工具链快速落地指南

7次阅读

共计 11530 个字符,预计需要花费 29 分钟才能阅读完成。

一、明天想干啥?

明天咱们来聊聊如何疾速落地“GitLab + Jenkins + Harbor 工具链”。

请留神这里的关键词:疾速(有多快呢?我心愿这个工夫是 5 分钟。)

我晓得你想要一条 闪闪亮 的工具链来撑持你的利用 CICD 流程,你想要“最佳实际”,你想要既 灵便 简略 易保护,你有一肚子的既要,又要,还要……

行,明天我就给你一个“既有,又有,还有”的《GitLab + Jenkins + Harbor 落地计划》。

二、明天干点啥?

明天咱们要搭建一条怎么的工具链呢?且看效果图:

  1. 首先咱们须要实现 GitLab、Jenkins 和 Harbor 三个工具的部署;
  2. 接着咱们须要在 GitLab 上创立一个代码库,并且在 Jenkins 上创立相应的流水线,这个流程最好也自动化(的确能够自动化);
  3. 而后适当地配置这三个工具,实现如下 CI 流程:

    1. 当用户推送代码到 GitLab,也就是 GitLab 上相应代码库产生 push 或者 merge 事件的时候,这个事件可能主动触发 Jenkins 上的流水线执行;
    2. Jenkins 上流水线执行的后果可能回显到 GitLab;
    3. Jenkins 上实现了编译、构建等等流程后,最终制品是一个容器镜像,这个镜像能够被推送到 Harbor 上。

三、明天怎么干?

我筹备应用云原生的形式来部署这三个工具,起因不赘述。

当然我也晓得少数状况下你并不需要思考 GitLab 如何部署,因为 95% 的概率你们公司曾经有可用的 GitLab 了,或者你们思考应用 SaaS 版的 GitLab。外加 Kubernetes 上部署 GitLab 的复杂度不低,运维老本高,所以,GitLab 的“高可用部署”不是本文重点,咱们把重点放在如何部署和配置好 Jenkins + Harbor,而后对接 GitLab,走通一个 CI 流程。

综上,明天我筹备 sale 的部署模式是:

  • GitLab:Docker
  • Jenkins:Helm(Kubernetes)
  • Harbor:Helm(Kubernetes)

3.1、惯例打法

如果依照常理出牌,这时候咱们应该是翻阅三个工具的官网,学习部署流程和配置步骤,而后总结最佳实际,一步步试错,一步步改良……

听起来就简单。

这个流程不应该让所有人都重头体验一遍,被折磨一遍。如果有人曾经钻研了一遍这些工具的部署模式,并且将这个流程代码化,做一个工具进去,并且开源收费,让大家“开箱即用”,那该多好!

3.2、不走寻常路

没错,你曾经猜到了,我不打算按常理出牌,我要找一个可能治理 DevOps 工具链的工具!

有这种工具?还真有!

DevStream 就干这事。DevStream 是啥?一句话:一个 DevOps 工具链管理器。

咱们看下 DevStream 如何实现这三个工具的落地:

DevStream 官网里有这么一个图。所以,这个花里胡哨的 DevStream 做了啥?

从下面的流程图,联合官网文档和源码,大抵我能够猜到它的工作流和原理:

  1. DevStream 首先将 GitLab、Jenkins、Harbor 等工具的部署流程代码化,通过插件的模式反对这些工具的装置部署;
  2. 工具部署实现后,DevStream 会从 SCM(GitHub 或者 GitLab 都能够)下载一个我的项目脚手架模板,模板源码在这里;这个模板反对高度自定义,实质就是将一些须要自定义的内容抽离成变量,供用户自在渲染,而后批量生产我的项目脚手架;
  3. 接着 DevStream 依据用户给定的配置文件渲染模板库,而后将其上传到 SCM(GitHub 或者 GitLab 都能够);
  4. 而后 DevStream 会配置 Jenkins,装置一些必要的插件等,用户反对最终的 Pipeline 顺利执行;
  5. DevStream 冀望 Pipeline 配置通过 Jenkinsfile 来定义,这个 Jenkinsfile 也是通过模板的形式保留,能够灵便渲染。比方官网示例中 Jenkinsfile 模板保留在这里;DevStream 执行的时候会下载这个 Jenkinsfile 模板(当然,这个模板也反对自定义,反对放到 GitLab 或者其余任何 web 服务器上),下载后渲染用户自定义变量,而后将其写入方才创立的我的项目脚手架对应的代码库里;
  6. 接着 DevStream 就能够调用 Jenkins api,实现 Pipeline 创立了。没错,创立 Pipeline 的时候,须要的 Jenkinsfile、我的项目地址等信息都有了,所以这里的 Pipeline 配置很轻量;
  7. 最初 DevStream 还须要调用 GitLab api 实现 webhook 的创立,这样 SCM(GitHub 或者 GitLab)上的事件(push、merge 等)能力顺利告诉到 Jenkins,从而触发 Pipeline 执行。

到这里 DevStream 根本就打完出工了,这时候如果你往这个代码库里的主分支 push 了一个 commit,GitLab 就会间接触发 Jenkins 上流水线运行;进而 Jenkins 上的流水线执行状态也会间接回显到 GitLab 上;当然,Jenkins 里构建的产物,比方 Docker container image(s) 也会被 push 到 Harbor(没错,这个过程是定义在 Jenkinsfile 里的,你能够灵便批改;同时 Harbor 也不肯定非得是 Harbor,你能够间接改成其余镜像仓库的地址,从而让 Jenkins 对接到云厂商提供的镜像仓库服务里也齐全 OK)。

四、开干吧!

思考到插件的依赖程序,外加 Jenkins、GitLab、Harbor 等工具的部署属于 ” 基础设施 ”,简直只须要执行一次,而 Repo Scaffolding 和 Jenkins Pipeline 的创立属于 ” 配置 ” 过程,可能要执行屡次(比方一直新增 Repo 和 Pipeline 等),所以咱们分 2 步来实现这条工具链的搭建过程。

4.1、工具链部署

先下载一个 DevStream 的 CLI,参考这个文档。有了 dtm 之后,咱们就该着手筹备配置文件了(上面配置保留到 config.yaml 里):

---
varFile: "" # If not empty, use the specified external variables config file
toolFile: "" # If not empty, use the specified external tools config file
pluginDir: "" # If empty, use the default value: ~/.devstream/plugins, or use -d flag to specify a directory
state: # state config, backend can be local, s3 or k8s
  backend: local
  options:
    stateFile: devstream-1.state
---
tools:
- name: gitlab-ce-docker
  instanceID: default
  dependsOn: [ ]
  options:
    hostname: gitlab.example.com
    gitlabHome: /srv/gitlab
    sshPort: 30022
    httpPort: 30080
    httpsPort: 30443
    rmDataAfterDelete: false
    imageTag: "rc"
- name: jenkins
  instanceID: default
  dependsOn: [ ]
  options:
    repo:
      name: jenkins
      url: https://charts.jenkins.io
    chart:
      chartPath: ""
      chartName: jenkins/jenkins
      namespace: jenkins
      wait: true
      timeout: 5m
      upgradeCRDs: true
      valuesYaml: |
        serviceAccount:
          create: true
          name: jenkins
        controller:
          adminUser: "admin"
          adminPassword: "changeme"
          ingress:
            enabled: true
            hostName: jenkins.example.com
          installPlugins:
            - kubernetes:3600.v144b_cd192ca_a_
            - workflow-aggregator:581.v0c46fa_697ffd
            - git:4.11.3
            - configuration-as-code:1512.vb_79d418d5fc8
          additionalPlugins:
            # install "GitHub Pull Request Builder" plugin, see https://plugins.jenkins.io/ghprb/ for more details
            - ghprb
            # install "OWASP Markup Formatter" plugin, see https://plugins.jenkins.io/antisamy-markup-formatter/ for more details
            - antisamy-markup-formatter
        # Enable HTML parsing using OWASP Markup Formatter Plugin (antisamy-markup-formatter), useful with ghprb plugin.
        enableRawHtmlMarkupFormatter: true
        # Jenkins Configuraction as Code, refer to https://plugins.jenkins.io/configuration-as-code/ for more details
        # notice: All configuration files that are discovered MUST be supplementary. They cannot overwrite each other's configuration values. This creates a conflict and raises a ConfiguratorException.
        JCasC:
          defaultConfig: true
- name: harbor
  instanceID: default
  dependsOn: [ ]
  options:
    chart:
      valuesYaml: |
        externalURL: http://harbor.example.com
        expose:
          type: ingress
          tls:
            enabled: false
          ingress:
            hosts:
              core: harbor.example.com
        chartmuseum:
          enabled: false
        notary:
          enabled: false
        trivy:
          enabled: false
        persistence:
          persistentVolumeClaim:
            registry:
              storageClass: ""
              accessMode: ReadWriteOnce
              size: 5Gi
            jobservice:
              storageClass: ""
              accessMode: ReadWriteOnce
              size: 1Gi
            database:
              storageClass: ""
              accessMode: ReadWriteOnce
              size: 1Gi
            redis:
              storageClass: ""
              accessMode: ReadWriteOnce
              size: 1Gi

这里的配置项并不难看懂,举荐大伙执行前面的命令前先认真看一遍这个配置文件,按需调整。比方外面配置了几个工具的域名啥的,这些都能够改。

而后就能够开始初始化了(次要是插件下载):

dtm init -f config.yaml

而后执行 apply 开始部署:

dtm apply -f config.yaml -y

这时候你会看到谐和的日志:

2022-10-08 09:43:13 ℹ [INFO]  Apply started.
2022-10-08 09:43:13 ℹ [INFO]  Using dir </root/.devstream/plugins> to store plugins.
2022-10-08 09:43:13 ℹ [INFO]  Using local backend. State file: devstream-1.state.
2022-10-08 09:43:13 ℹ [INFO]  Tool (gitlab-ce-docker/default) found in config but doesn't exist in the state, will be created.
2022-10-08 09:43:13 ℹ [INFO]  Tool (jenkins/default) found in config but doesn't exist in the state, will be created.
2022-10-08 09:43:13 ℹ [INFO]  Tool (harbor/default) found in config but doesn't exist in the state, will be created.
2022-10-08 09:43:13 ℹ [INFO]  Start executing the plan.
2022-10-08 09:43:13 ℹ [INFO]  Changes count: 3.
2022-10-08 09:43:13 ℹ [INFO]  -------------------- [Processing progress: 1/3.] --------------------
2022-10-08 09:43:13 ℹ [INFO]  Processing: (gitlab-ce-docker/default) -> Create ...
2022-10-08 09:43:13 ℹ [INFO]  Cmd: docker image ls gitlab/gitlab-ce:rc -q.
2022-10-08 09:43:13 ℹ [INFO]  Running container as the name <gitlab>
2022-10-08 09:43:13 ℹ [INFO]  Cmd: docker run --detach --hostname gitlab.example.com --publish 30022:22 --publish 30080:80 --publish 30443:443 --name gitlab --restart always --volume /srv/gitlab/config:/etc/gitlab --volume /srv/gitlab/data:/var/opt/gitlab --volume /srv/gitlab/logs:/var/log/gitlab gitlab/gitlab-ce:rc.
Stdout: 53e30ad85faf7e9d6d18764450bb8458db46b388b690b7c8b7a7cc6d0deb283a
2022-10-08 09:43:14 ℹ [INFO]  Cmd: docker inspect --format='{{json .Mounts}}' gitlab.
2022-10-08 09:43:14 ℹ [INFO]  GitLab access URL: http://gitlab.example.com:30080
2022-10-08 09:43:14 ℹ [INFO]  GitLab initial root password: execute the command -> docker exec -it gitlab grep 'Password:' /etc/gitlab/initial_root_password
2022-10-08 09:43:14 ✔ [SUCCESS]  Tool (gitlab-ce-docker/default) Create done.
2022-10-08 09:43:14 ℹ [INFO]  -------------------- [Processing progress: 2/3.] --------------------
2022-10-08 09:43:14 ℹ [INFO]  Processing: (jenkins/default) -> Create ...
2022-10-08 09:43:15 ℹ [INFO]  Creating or updating helm chart ...
2022/10/08 09:43:16 creating 13 resource(s)
2022/10/08 09:43:16 beginning wait for 13 resources with timeout of 5m0s
2022/10/08 09:43:16 StatefulSet is not ready: jenkins/jenkins. 0 out of 1 expected pods are ready
...
2022/10/08 09:44:18 StatefulSet is not ready: jenkins/jenkins. 0 out of 1 expected pods are ready
2022/10/08 09:44:20 release installed successfully: jenkins/jenkins-4.1.17
2022-10-08 09:44:20 ✔ [SUCCESS]  Tool (jenkins/default) Create done.
2022-10-08 09:44:20 ℹ [INFO]  -------------------- [Processing progress: 3/3.] --------------------
2022-10-08 09:44:20 ℹ [INFO]  Processing: (harbor/default) -> Create ...
2022-10-08 09:44:21 ℹ [INFO]  Creating or updating helm chart ...
2022/10/08 09:44:23 creating 28 resource(s)
2022/10/08 09:44:23 beginning wait for 28 resources with timeout of 10m0s
2022/10/08 09:44:24 Deployment is not ready: harbor/harbor-core. 0 out of 1 expected pods are ready
...
2022/10/08 09:46:16 Deployment is not ready: harbor/harbor-jobservice. 0 out of 1 expected pods are ready
2022/10/08 09:46:18 release installed successfully: harbor/harbor-1.10.0
2022-10-08 09:46:19 ✔ [SUCCESS]  Tool (harbor/default) Create done.
2022-10-08 09:46:19 ℹ [INFO]  -------------------- [Processing done.] --------------------
2022-10-08 09:46:19 ✔ [SUCCESS]  All plugins applied successfully.
2022-10-08 09:46:19 ✔ [SUCCESS]  Apply finished.

如果日志不够谐和,那就,那就,,,debug 吧。

4.2、网络配置

后面 GitLab + Jenkins + Harbor 三个工具的配置文件里咱们都设置了域名,如果是 kubeadm 间接部署的 k8s 集群,你能够间接将这些域名与 IP 的映射关系配置到 DNS 服务器里。

如果没有 DNS 服务器,你也能够间接将域名与 IP 的映射关系配置到 /etc/hosts 以及 CoreDNS 的 ConfigMap kube-system/coredns 里让域名失效。比方:

  1. 批改 /etc/hosts 文件,增加这条记录(记得替换成你本人的 IP):

    44.33.22.11 gitlab.example.com jenkins.example.com harbor.example.com
  2. 批改 CoreDNS 的配置,在 ConfigMap kube-system/coredns 中增加动态解析记录:

    1. 执行命令:kubectl edit cm coredns -n kube-system
    2. 在 hosts(第 20 行左右) 局部增加和 /etc/hosts 一样的记录。

这样 Jenkins 能力通过域名拜访到 GitLab。

4.3、验证工具链部署后果

来,看下新部署的 GitLab、Jenkins、Harbor 是不是都能拜访到。

4.3.1、GitLab

不出意外的话,你能够在本人的 PC 里配置 44.33.22.11 gitlab.example.com 动态域名解析记录,而后在浏览器里通过 http://gitlab.example.com:30080 拜访到 GitLab:

而后通过执行如下命令,你就能取得 GitLab 的初始 root 明码了:

docker exec gitlab cat /etc/gitlab/initial_root_password | grep Password:

拿到 root 明码后,你能够尝试用 root/YOUR_PASSWORD 来登录 GitLab。因为前面咱们须要用到 GitLab 的 token,所以这时候能够棘手创立一个 token:

4.3.2、Jenkins

在浏览器里通过 http://jenkins.example.com:32000 就能够拜访到 Jenkins 了:

Jenkins 的 admin 用户初始登录明码是 changeme,如果你认真看了后面 dtm 应用的配置文件,能够发现这是在配置文件里指定的。咱们尝试用 admin/changeme 登录 Jenkins 查看性能是否失常,不过这时不须要在 Jenkins 上进行任何额定的操作。

4.3.3、Harbor

咱们能够通过 docker login harbor.example.com:80 命令来尝试登录 Harbor,也能够间接通过 http://harbor.example.com:30180 拜访 Dashboard:

Harbor 的 admin 用户初始登录明码是 Harbor12345,咱们尝试用 admin/Harbor12345 登录 Harbor:

4.4、流水线配置

工具有了,下一步就是配置流水线了,咱持续筹备第二个配置文件(config-pipeline.yaml):

---
varFile: "" # If not empty, use the specified external variables config file
toolFile: "" # If not empty, use the specified external tools config file
pluginDir: "" # If empty, use the default value: ~/.devstream/plugins, or use -d flag to specify a directory
state: # state config, backend can be local, s3 or k8s
  backend: local
  options:
    stateFile: devstream-2.state
---
tools:
- name: repo-scaffolding
  instanceID: springboot
  dependsOn: [ ]
  options:
    destinationRepo:
      owner: root
      repo: spring-demo
      branch: master
      repoType: gitlab
      baseURL: http://gitlab.example.com:30080
    sourceRepo:
      owner:  devstream-io
      repo: dtm-repo-scaffolding-java-springboot
      repoType: github
- name: jenkins-pipeline
  instanceID: default
  dependsOn: [repo-scaffolding.springboot]
  options:
    jenkins:
      url: http://44.33.22.11:32000
      user: admin
      enableRestart: true
    scm:
      cloneURL: http://gitlab.example.com:30080/root/spring-demo
      branch: master
    pipeline:
      jobName: test-job
      jenkinsfilePath: https://raw.githubusercontent.com/devstream-io/dtm-jenkins-pipeline-example/main/springboot/Jenkinsfile
      imageRepo:
        url: http://harbor.example.com:80
        user: admin

同样我倡议你认真看一下这个配置文件,外面的一些拜访地址,比方 IP 和域名啥的,按需调整。

后面咱们增加了一个 GitLab 的 token,这个 token 须要被设置到环境变量里:

export GITLAB_TOKEN=YOUR_GITLAB_TOKEN

同时咱们须要将 Harbor 明码配置到环境变量里,如果你的 Harbor 没有去批改明码,这时候默认明码应该是 Harbor12345:

export IMAGE_REPO_PASSWORD=Harbor12345

接着就是相熟的 init 和 apply 命令了:

dtm init -f config-pipeline.yaml
dtm apply -f config-pipeline.yaml -y

后果日志仍旧应该谐和:

2022-10-08 13:19:27 ℹ [INFO]  Apply started.
2022-10-08 13:19:27 ℹ [INFO]  Using dir </root/.devstream/plugins> to store plugins.
2022-10-08 13:19:28 ℹ [INFO]  Using local backend. State file: devstream-2.state.
2022-10-08 13:19:28 ℹ [INFO]  Tool (jenkins-pipeline/default) found in config but doesn't exist in the state, will be created.
2022-10-08 13:19:28 ℹ [INFO]  Start executing the plan.
2022-10-08 13:19:28 ℹ [INFO]  Changes count: 1.
2022-10-08 13:19:28 ℹ [INFO]  -------------------- [Processing progress: 1/1.] --------------------
2022-10-08 13:19:28 ℹ [INFO]  Processing: (jenkins-pipeline/default) -> Create ...
2022-10-08 13:19:28 ℹ [INFO]  Secret jenkins/docker-config has been created.
2022-10-08 13:19:32 ✔ [SUCCESS]  Tool (jenkins-pipeline/default) Create done.
2022-10-08 13:19:32 ℹ [INFO]  -------------------- [Processing done.] --------------------
2022-10-08 13:19:32 ✔ [SUCCESS]  All plugins applied successfully.
2022-10-08 13:19:32 ✔ [SUCCESS]  Apply finished.

4.5、验证流水线配置后果

咱们上 GitLab 看下 dtm 筹备的 Java Spring Boot 我的项目脚手架:

接着登录 Jenkins,能够看到 dtm 创立的 Pipeline:

Pipeline 胜利执行实现后:

再回到 GitLab 看下回显的状态:

歌舞升平,一片祥和!

五、总结

此处应该有个总结,然而到饭点了。

不总结了吧。

就留一个问题:DevStream 部署 DevOps 工具链是不是最佳实际?

兴许是,兴许不是。不过我置信 DevStream 会逐渐会集业内最佳实际,最终变成一个规范。

再留个问题:DevStream 足够成熟稳固了不?

应该不够。不过 DevStream 在逐步走向成熟。如果大家违心应用 DevStream,多提 bug,甚至参加社区开发,DevStream 就会更快走向成熟稳固。


参考:

  • DevStream 我的项目仓库
  • DevStream 文档:本地部署 GitLab + Jenkins + Harbor 工具链
  • DevStream 文档:离线部署

完结。催吃饭了。

正文完
 0