|
| 1 | +# 快速部署 GitLab + Jenkins + Harbor 工具链 |
| 2 | + |
| 3 | +## 1、概述 |
| 4 | + |
| 5 | +本文将介绍如何通过 DevStream 在本地快速部署 `GitLab + Jenkins + Harbor` 工具链。 |
| 6 | + |
| 7 | +!!! hint "提示" |
| 8 | + |
| 9 | + 本文基于 kubeadm 部署的单节点 k8s 环境,不适用于 minikube 和 kind 等 docker-in-docker 类型的 k8s 集群。 |
| 10 | + |
| 11 | +## 2、准备配置文件 |
| 12 | + |
| 13 | +DevStream 可以简单地以 **local** 作为[状态](../../core-concepts/state.zh.md) Backend,也就是将状态保存到本地文件。如果你在本地测试,可以选择使用这种方式; |
| 14 | +而企业 On premise 环境部署可能需要使用 **k8s** Backend 将状态通过 `kube-apiserver` 存入 etcd,两种方式配置分别如下: |
| 15 | + |
| 16 | +=== "DevStream with 'local' Backend" |
| 17 | + |
| 18 | + ```yaml title="local Backend" |
| 19 | + config: |
| 20 | + state: |
| 21 | + backend: local |
| 22 | + options: |
| 23 | + stateFile: devstream.state |
| 24 | + ``` |
| 25 | + |
| 26 | +=== "DevStream with 'k8s' Backend" |
| 27 | + |
| 28 | + ```yaml title="k8s Backend" |
| 29 | + config: |
| 30 | + state: |
| 31 | + backend: k8s |
| 32 | + options: |
| 33 | + namespace: devstream |
| 34 | + configmap: state |
| 35 | + ``` |
| 36 | + |
| 37 | +下文将以 `local` Backend 为例演示。 |
| 38 | + |
| 39 | +在编写 `gitlab-ce-docker` 和 `helm-installer`(用于安装 Jenkins 和 Harbor)这两个插件的配置文件之前,你需要先定义一些变量,这会让后续的配置和维护工作变得更加简单: |
| 40 | + |
| 41 | +```yaml title="config-tools.yaml" |
| 42 | +config: |
| 43 | + state: |
| 44 | + backend: local |
| 45 | + options: |
| 46 | + stateFile: devstream.state |
| 47 | +vars: |
| 48 | + gitlabHostname: gitlab.example.com |
| 49 | + jenkinsHostname: jenkins.example.com |
| 50 | + harborHostname: harbor.example.com |
| 51 | + harborURL: http://harbor.example.com |
| 52 | + jenkinsAdminUser: admin |
| 53 | + jenkinsAdminPassword: changeme |
| 54 | + gitlabSSHPort: 30022 |
| 55 | + gitlabHttpPort: 30080 |
| 56 | + gitlabHttpsPort: 30443 |
| 57 | +``` |
| 58 | +
|
| 59 | +你可以根据自己的需要,选择性自定义上述 vars 配置的值,这些变量内容主要是域名、端口号等可修改配置项。 |
| 60 | +
|
| 61 | +继续往里面追加工具链相关插件的配置,你的配置文件会扩充成这样: |
| 62 | +
|
| 63 | +```yaml title="config-tools.yaml" |
| 64 | +config: |
| 65 | + state: |
| 66 | + backend: local |
| 67 | + options: |
| 68 | + stateFile: devstream.state |
| 69 | +vars: |
| 70 | + gitlabHostname: gitlab.example.com |
| 71 | + jenkinsHostname: jenkins.example.com |
| 72 | + harborHostname: harbor.example.com |
| 73 | + harborURL: http://harbor.example.com |
| 74 | + jenkinsAdminUser: admin |
| 75 | + jenkinsAdminPassword: changeme |
| 76 | + gitlabSSHPort: 30022 |
| 77 | + gitlabHttpPort: 30080 |
| 78 | + gitlabHttpsPort: 30443 |
| 79 | +tools: |
| 80 | +- name: gitlab-ce-docker |
| 81 | + instanceID: default |
| 82 | + dependsOn: [] |
| 83 | + options: |
| 84 | + hostname: [[ gitlabHostname ]] |
| 85 | + gitlabHome: /srv/gitlab |
| 86 | + sshPort: [[ gitlabSSHPort ]] |
| 87 | + httpPort: [[ gitlabHttpPort ]] |
| 88 | + httpsPort: [[ gitlabHttpsPort ]] |
| 89 | + rmDataAfterDelete: false |
| 90 | + imageTag: "rc" |
| 91 | +- name: helm-installer |
| 92 | + instanceID: jenkins-001 |
| 93 | + dependsOn: [] |
| 94 | + options: |
| 95 | + valuesYaml: | |
| 96 | + serviceAccount: |
| 97 | + create: true |
| 98 | + name: jenkins |
| 99 | + controller: |
| 100 | + adminUser: [[ jenkinsAdminUser ]] |
| 101 | + adminPassword: [[ jenkinsAdminPassword ]] |
| 102 | + ingress: |
| 103 | + enabled: true |
| 104 | + hostName: [[ jenkinsHostname ]] |
| 105 | + enableRawHtmlMarkupFormatter: true |
| 106 | + JCasC: |
| 107 | + defaultConfig: true |
| 108 | +- name: helm-installer |
| 109 | + instanceID: harbor-001 |
| 110 | + dependsOn: [] |
| 111 | + options: |
| 112 | + valuesYaml: | |
| 113 | + externalURL: [[ harborURL ]] |
| 114 | + expose: |
| 115 | + type: ingress |
| 116 | + tls: |
| 117 | + enabled: false |
| 118 | + ingress: |
| 119 | + hosts: |
| 120 | + core: [[ harborHostname ]] |
| 121 | + chartmuseum: |
| 122 | + enabled: false |
| 123 | + notary: |
| 124 | + enabled: false |
| 125 | + trivy: |
| 126 | + enabled: false |
| 127 | + persistence: |
| 128 | + persistentVolumeClaim: |
| 129 | + registry: |
| 130 | + storageClass: "" |
| 131 | + accessMode: ReadWriteOnce |
| 132 | + size: 5Gi |
| 133 | + jobservice: |
| 134 | + storageClass: "" |
| 135 | + accessMode: ReadWriteOnce |
| 136 | + size: 1Gi |
| 137 | + database: |
| 138 | + storageClass: "" |
| 139 | + accessMode: ReadWriteOnce |
| 140 | + size: 1Gi |
| 141 | + redis: |
| 142 | + storageClass: "" |
| 143 | + accessMode: ReadWriteOnce |
| 144 | + size: 1Gi |
| 145 | +``` |
| 146 | +
|
| 147 | +## 3、初始化 |
| 148 | +
|
| 149 | +你可以将上面这个配置文件(config-tools.yaml)放到服务器上任意一个合适的目录,比如 `~/devstream-test/`,然后在该目录下执行: |
| 150 | + |
| 151 | +```shell title="初始化命令" |
| 152 | +dtm init -f config-tools.yaml |
| 153 | +``` |
| 154 | + |
| 155 | +这个命令会帮助你下载所有需要的 DevStream 插件。 |
| 156 | + |
| 157 | +## 4、开始部署 |
| 158 | + |
| 159 | +接着你就可以执行 apply 命令了: |
| 160 | + |
| 161 | +```shell title="开始部署" |
| 162 | +dtm apply -f config-tools.yaml -y |
| 163 | +``` |
| 164 | + |
| 165 | +这个命令执行成功的话,你可以大致看到如下日志: |
| 166 | + |
| 167 | +```shell title="部署日志" |
| 168 | +2022-11-30 08:14:05 ℹ [INFO] Apply started. |
| 169 | +2022-11-30 08:14:06 ℹ [INFO] Using local backend. State file: devstream.state. |
| 170 | +2022-11-30 08:14:06 ℹ [INFO] Tool (gitlab-ce-docker/default) found in config but doesn't exist in the state, will be created. |
| 171 | +2022-11-30 08:14:06 ℹ [INFO] Tool (helm-installer/jenkins-001) found in config but doesn't exist in the state, will be created. |
| 172 | +2022-11-30 08:14:06 ℹ [INFO] Tool (helm-installer/harbor-001) found in config but doesn't exist in the state, will be created. |
| 173 | +2022-11-30 08:14:06 ℹ [INFO] Start executing the plan. |
| 174 | +2022-11-30 08:14:06 ℹ [INFO] Changes count: 3. |
| 175 | +2022-11-30 08:14:06 ℹ [INFO] -------------------- [ Processing progress: 1/3. ] -------------------- |
| 176 | +2022-11-30 08:14:06 ℹ [INFO] Processing: (gitlab-ce-docker/default) -> Create ... |
| 177 | +2022-11-30 08:14:06 ℹ [INFO] Cmd: docker image ls gitlab/gitlab-ce:rc -q. |
| 178 | +2022-11-30 08:14:06 ℹ [INFO] Running container as the name <gitlab> |
| 179 | +2022-11-30 08:14:06 ℹ [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. |
| 180 | +Stdout: 34cdd2a834a1c21be192064eacf1e29536ff45c52562956b97d6d376a5dae11b |
| 181 | +2022-11-30 08:14:07 ℹ [INFO] Cmd: docker inspect --format='{{json .Mounts}}' gitlab. |
| 182 | +2022-11-30 08:14:07 ℹ [INFO] GitLab access URL: http://gitlab.example.com:30080 |
| 183 | +2022-11-30 08:14:07 ℹ [INFO] GitLab initial root password: execute the command -> docker exec -it gitlab grep 'Password:' /etc/gitlab/initial_root_password |
| 184 | +2022-11-30 08:14:07 ✔ [SUCCESS] Tool (gitlab-ce-docker/default) Create done. |
| 185 | +2022-11-30 08:14:07 ℹ [INFO] -------------------- [ Processing progress: 2/3. ] -------------------- |
| 186 | +2022-11-30 08:14:07 ℹ [INFO] Processing: (helm-installer/jenkins-001) -> Create ... |
| 187 | +2022-11-30 08:14:07 ℹ [INFO] Filling default config with instance: jenkins-001. |
| 188 | +2022-11-30 08:14:07 ℹ [INFO] Creating or updating helm chart ... |
| 189 | +2022/11/30 08:14:09 creating 13 resource(s) |
| 190 | +2022/11/30 08:14:09 beginning wait for 13 resources with timeout of 10m0s |
| 191 | +2022/11/30 08:14:09 StatefulSet is not ready: jenkins/jenkins. 0 out of 1 expected pods are ready |
| 192 | +... |
| 193 | +2022/11/30 08:14:49 StatefulSet is not ready: jenkins/jenkins. 0 out of 1 expected pods are ready |
| 194 | +2022/11/30 08:14:51 release installed successfully: jenkins/jenkins-4.2.15 |
| 195 | +2022-11-30 08:14:51 ✔ [SUCCESS] Tool (helm-installer/jenkins-001) Create done. |
| 196 | +2022-11-30 08:14:51 ℹ [INFO] -------------------- [ Processing progress: 3/3. ] -------------------- |
| 197 | +2022-11-30 08:14:51 ℹ [INFO] Processing: (helm-installer/harbor-001) -> Create ... |
| 198 | +2022-11-30 08:14:51 ℹ [INFO] Filling default config with instance: harbor-001. |
| 199 | +2022-11-30 08:14:51 ℹ [INFO] Creating or updating helm chart ... |
| 200 | +2022/11/30 08:14:52 checking 28 resources for changes |
| 201 | +2022/11/30 08:14:52 Created a new Secret called "harbor-core" in harbor |
| 202 | +... |
| 203 | +2022/11/30 08:14:52 Created a new Ingress called "harbor-ingress" in harbor |
| 204 | +2022/11/30 08:14:52 beginning wait for 28 resources with timeout of 10m0s |
| 205 | +2022/11/30 08:14:52 Deployment is not ready: harbor/harbor-core. 0 out of 1 expected pods are ready |
| 206 | +... |
| 207 | +2022/11/30 08:15:50 Deployment is not ready: harbor/harbor-jobservice. 0 out of 1 expected pods are ready |
| 208 | +2022/11/30 08:15:52 release installed successfully: harbor/harbor-1.10.2 |
| 209 | +2022-11-30 08:15:52 ✔ [SUCCESS] Tool (helm-installer/harbor-001) Create done. |
| 210 | +2022-11-30 08:15:52 ℹ [INFO] -------------------- [ Processing done. ] -------------------- |
| 211 | +2022-11-30 08:15:52 ✔ [SUCCESS] All plugins applied successfully. |
| 212 | +2022-11-30 08:15:52 ✔ [SUCCESS] Apply finished. |
| 213 | +``` |
| 214 | + |
| 215 | +从日志里你可以看到,这时候 GitLab、Jenkins 和 Harbor 就已经部署完成了。 |
| 216 | + |
| 217 | +## 5、验证部署结果 |
| 218 | + |
| 219 | +你可以通过如下方式验证 GitLab + Jenkins + Harbor 三个工具的部署结果。 |
| 220 | + |
| 221 | +### 5.1、DNS 配置 |
| 222 | + |
| 223 | +前面你给 GitLab + Jenkins + Harbor 三个工具的配置文件里都设置了域名,然后你可以直接将这些域名与 IP 的映射关系配置到 DNS 服务器里。 |
| 224 | + |
| 225 | +如果没有 DNS 服务器,你也可以直接将域名与 IP 的映射关系配置到 `/etc/hosts` 以及 `CoreDNS` 的 ConfigMap `kube-system/coredns` 里让域名生效。比如我的主机 IP 是 44.33.22.11,这时候可以这样配置: |
| 226 | + |
| 227 | +1. 修改 `/etc/hosts` 文件,添加这条记录: |
| 228 | + |
| 229 | + ```shell title="dns record" |
| 230 | + 44.33.22.11 gitlab.example.com jenkins.example.com harbor.example.com |
| 231 | + ``` |
| 232 | + |
| 233 | +2. 修改 `CoreDNS` 的配置,在 ConfigMap `kube-system/coredns` 中添加静态解析记录,执行命令:`kubectl edit cm coredns -n kube-system`,在 hosts(第20行左右) 部分添加: |
| 234 | + |
| 235 | + ```shell title="dns record" |
| 236 | + 44.33.22.11 gitlab.example.com jenkins.example.com harbor.example.com |
| 237 | + ``` |
| 238 | + |
| 239 | + 这时候在当前主机上,就可以分别通过如下地址访问到 GitLab、Jenkins 和 Harbor 了,同时 Jenkins 也能顺利地通过域名访问到 GitLab 和 Harbor: |
| 240 | + |
| 241 | + - `GitLab`: http://gitlab.example.com:30080 |
| 242 | + - `Jenkins`: http://jenkins.example.com |
| 243 | + - `Harbor`: http://harbor.example.com |
| 244 | + |
| 245 | +最后由于当前刚才 DevStream 使用了 Docker 的方式直接运行的 GitLab,所以不管是主机的 /etc/hosts 还是 CoreDNS 的配置都无法让 GitLab 解析到 Jenkins 的域名,因此你还需要在 GitLab 容器内加一行配置: |
| 246 | + |
| 247 | +```sh |
| 248 | +docker exec -it gitlab bash |
| 249 | +echo "44.33.22.11 jenkins.example.com" >> /etc/hosts |
| 250 | +exit |
| 251 | +``` |
| 252 | + |
| 253 | +### 5.2、访问 GitLab |
| 254 | + |
| 255 | +你可以在自己的 PC 里配置 `44.33.22.11 gitlab.example.com` 静态域名解析记录,然后在浏览器里通过 `http://gitlab.example.com:30080` 访问到 GitLab: |
| 256 | + |
| 257 | +<figure markdown> |
| 258 | + { width="1000" } |
| 259 | + <figcaption>GitLab login page</figcaption> |
| 260 | +</figure> |
| 261 | + |
| 262 | +通过执行如下命令,你可以设置 GitLab 的 root 密码: |
| 263 | + |
| 264 | +```shell title="get GitLab root Password" |
| 265 | +docker exec -it gitlab bash # 进入容器 |
| 266 | +gitlab-rake "gitlab:password:reset" # 执行后按照提示输入用户名 root,回车后输入密码 |
| 267 | +``` |
| 268 | + |
| 269 | +拿到 root 密码后,你可以尝试用 root/YOUR_PASSWORD 来登录 GitLab。 |
| 270 | + |
| 271 | +### 5.3、访问 Jenkins |
| 272 | + |
| 273 | +前面你可能已经通过 `curl http://jenkins.example.com` 在主机内验证了 Jenkins 的网络连通性,想要远程通过域名访问 Jenkins,你还需要在自己的 PC 里配置 `44.33.22.11 jenkins.example.com` 静态域名解析记录。 |
| 274 | + |
| 275 | +接着在浏览器里通过 `http://jenkins.example.com` 就可以访问到 Jenkins 了: |
| 276 | + |
| 277 | +<figure markdown> |
| 278 | + { width="1000" } |
| 279 | + <figcaption>Jenkins login page</figcaption> |
| 280 | +</figure> |
| 281 | + |
| 282 | +Jenkins 的 admin 用户初始登录密码是 `changeme`,如果你仔细看了前面 dtm 使用的配置文件,可以发现这是在配置文件里指定的。你可以尝试用 `admin/changeme` 登录 Jenkins 检查功能是否正常,不过当前你不需要在 Jenkins 上进行任何额外的操作。 |
| 283 | + |
| 284 | +<figure markdown> |
| 285 | + { width="1000" } |
| 286 | + <figcaption>Jenkins dashboard</figcaption> |
| 287 | +</figure> |
| 288 | + |
| 289 | +### 5.4、访问 Harbor |
| 290 | + |
| 291 | +前面你可能也已经通过 `curl http://harbor.example.com` 在主机内验证了 Harbor 的网络连通性,同样你可以通过 `docker login harbor.example.com:80` 命令来尝试登录 Harbor。 |
| 292 | + |
| 293 | +现在你需要在自己的 PC 里配置 `44.33.22.11 harbor.example.com` 静态域名解析记录。 |
| 294 | + |
| 295 | +接着你可以在浏览器里通过 `http://harbor.example.com` 访问到 Harbor: |
| 296 | + |
| 297 | +<figure markdown> |
| 298 | + { width="1000" } |
| 299 | + <figcaption>Harbor login page</figcaption> |
| 300 | +</figure> |
| 301 | + |
| 302 | +Harbor 的 admin 用户初始登录密码是 `Harbor12345`,你可以尝试用 `admin/Harbor12345` 登录 Harbor 检查功能是否正常,不过当前你同样也不需要在 Harbor 上进行任何额外的操作。 |
| 303 | + |
| 304 | +<figure markdown> |
| 305 | + { width="1000" } |
| 306 | + <figcaption>Harbor dashboard</figcaption> |
| 307 | +</figure> |
| 308 | + |
| 309 | +## 6、环境清理 |
| 310 | + |
| 311 | +你可以通过如下命令清理环境: |
| 312 | + |
| 313 | +```shell title="环境清理命令" |
| 314 | +dtm delete -f config-tools.yaml -y |
| 315 | +``` |
0 commit comments