该公司决定采用GitLab + GitLab CI + Harbor + Kubernetes
架构来构建CICD环境,以缩短新功能开发上线周期,及时满足客户的需求,实现DevOps的部分流程,来减轻部署运维的负担,实现可视化容器生命周期管理、应用发布和版本迭代更新,请完成CICD环境部署。CICD应用系统架构如下:
这里使用项目为2048游戏
项目地址: https://gitee.com/isicman/demo-2048.git
使用Docker或者使用Kubernetes集群环境,这里使用的是Kubernetes集群环境。
IP地址 | 主机名称 | 主机资源 | 节点名称 |
---|---|---|---|
10.11.121.111 | k8s-master | 12G/6VCPU | GitLab+GitLab-Runner |
10.11.121.112 | k8s-node1 | 8G/6VCPU | Harbor |
10.11.121.113 | k8s-node2 | 8G/6VCPU | node |
可以通过kubectl cluster-info
命令查看当前的集群信息。 通过 kubectl get node
查看当前节点数量。
[root@k8s-master ~]# kubectl cluster-info
Kubernetes control plane is running at https://10.11.121.111:6443
KubeDNS is running at https://10.11.121.111:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
[root@k8s-master ~]# kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master Ready control-plane,master 25h v1.20.0
k8s-node1 Ready <none> 25h v1.20.0
k8s-node2 Ready <none> 25h v1.20.0
GitLab 是利用 Ruby on Rails 一个开源的版本管理系统,实现一个自托管的 Git 项目仓库,可通过 Web 界面进行访问公开的或者私人项目。它拥有与 Github 类似的功能,能够浏览源代码,管理缺陷和注释。可以管理团队对仓库的访问,它非常易于浏览提交过的版本并提供一个文件历史库。团队成员可以利用内置的简单聊天程序 (Wall) 进行交流。它还提供一个代码片段收集功能可以轻松实现代码复用,便于日后有需要的时候进行查找。
GitLab 可以安装在大多数 GNU/Linux 发行版中,并与多个云提供商一起安装。要从 GitLab 获得最佳体验,您必须平衡性能、可靠性、易于管理(备份、升级和故障排除)以及托管成本。
目前比较常见的部署方式有如下三种:
Mac/Windows/Linux
Docker、Kubernetes
Chart包的方式
1.使用Docker命令部署Gitlab,由于Gitlab的镜像大概有几个G,所以需要等待很久的时间,直到完全启动。
参数解析:
hostname
域名 或 ip
publish 、-p
端口映射
restart
重启方式
volume、-v
目录挂载
[root@k8s-master ~]# docker run -d \
--hostname 10.11.121.111 \
-p 443:443 -p 80:80 -p 222:22 \
--name gitlab \
--restart always \
-v /srv/gitlab/config:/etc/gitlab \
-v /srv/gitlab/logs:/var/log/gitlab \
-v /srv/gitlab/data:/var/opt/gitlab \
gitlab/gitlab-ce:latest
2.查看当前的Docker进程。
[root@k8s-master ~]# docker ps | grep gitlab
686f123b649c gitlab/gitlab-ce:latest "/assets/wrapper" 25 hours ago Up 2 hours (healthy) 0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp, 0.0.0.0:222->22/tcp, :::222->22/tcp gitlab
3.通过浏览器访问GitLab的页面: http://10.11.121.111
4.这里默认的用户是 root
,默认的密码只有24h有效,所以我们需要更改一下密码。
先查出用户的id,例如下面用户是root id=1
[root@k8s-master ~]# docker exec -it gitlab /bin/bash
[{"id":1,"name":"Administrator","username":"root","state":"active","avatar_url":"https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon","web_url":"http://192.168.0.173/root"}]
root@10:/# gitlab-rails console -e production
--------------------------------------------------------------------------------
Ruby: ruby 2.7.4p191 (2021-07-07 revision a21a3b7d23) [x86_64-linux]
GitLab: 14.4.1 (1a23d731c9f) FOSS
GitLab Shell: 13.21.1
PostgreSQL: 12.7
--------------------------------------------------------------------------------
Loading production environment (Rails 6.1.4.1)
irb(main):001:0> u=User.where(id:1).first
=> #
irb(main):002:0> u.password='00000000'
=> "00000000"
irb(main):003:0> u.password_confirmation='00000000'
=> "00000000"
irb(main):004:0> u.save!
Enqueued ActionMailer::MailDeliveryJob (Job ID: d7bc1e90-4941-4125-bf90-b018c92b5d73) to Sidekiq(mailers) with arguments: "DeviseMailer", "password_change", "deliver_now", {:args=>[#>]}
=> true
irb(main):005:0> exit
2.登录Gitlab之后,需要创建一个项目名称叫做demo
。
3.首先我们拉取gitee上的源码到本地,再推送到Gitlab源码托管demo仓库的Master分支。
[root@k8s-master ~]# git clone https://gitee.com/isicman/demo-2048.git
Cloning into 'demo-2048'...
Username for 'https://gitee.com': isicman
Password for 'https://[email protected]':
remote: Enumerating objects: 71, done.
remote: Counting objects: 100% (71/71), done.
remote: Compressing objects: 100% (59/59), done.
remote: Total 71 (delta 21), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (71/71), done.
[root@k8s-master ~]# cd demo-2048/
[root@k8s-master demo]# ll
total 8
drwxr-xr-x 2 root root 24 Apr 23 13:28 Dockerfiles
-rw-r--r-- 1 root root 1491 Apr 23 13:28 pom.xml
-rw-r--r-- 1 root root 315 Apr 23 13:28 README.md
drwxr-xr-x 3 root root 18 Apr 23 13:28 src
drwxr-xr-x 2 root root 28 Apr 24 13:06 template
[root@k8s-master demo-2048]# git config --global user.name "Administrator"
[root@k8s-master demo-2048]# git config --global user.email "[email protected]"
[root@k8s-master demo-2048]# git init
Reinitialized existing Git repository in /opt/demo-2048/.git/
[root@k8s-master demo-2048]# git remote rename origin old-origin
[root@k8s-master demo-2048]# git remote add origin http://10.11.121.111/root/demo.git
[root@k8s-master demo-2048]# git add .
[root@k8s-master demo-2048]# git commit -m "Initial commit"
# On branch master
nothing to commit, working directory clean
[root@k8s-master demo-2048]# git push -u origin --all
Username for 'http://10.11.121.111': root
Password for 'http://[email protected]':
Counting objects: 71, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (59/59), done.
Writing objects: 100% (71/71), 82.04 KiB | 0 bytes/s, done.
Total 71 (delta 21), reused 0 (delta 0)
To http://10.11.121.111/root/demo2.git
* [new branch] master -> master
Branch master set up to track remote branch master from origin.
4.再次刷新仓库查看,源码已经推送成功。
5.需要记住这里的Runner的URL和Token
,因为后面的GitLab—Runner连接GitLab需要使用到。
此处我的URL: http://10.11.121.111/
此处我的Token:o4_NCTZViRE7iGxoi
GitLab Runner是一个开源项目,用于运行您的作业并将结果发送回GitLab。它与GitLab CI一起使用,GitLab CI是GitLab随附的开源持续集成服务,用于协调作业。
一般来说,gitlab上已由负责人配置好了gitlab-runner
,我们只需要编写好.gitlab.yml
文件提交代码即可触发runner进行工作。但对于初学者来说,你可能想能不能在提交代码前在本地先执行.gitlab.yml
文件的job,本地调试成功检查没有问题后再进行最终代码的提交,触发服务端的CI流程。答案当然也是可以的。.gitlab.yml
文件中定义的job其实是某个服务器中的gitlab-runner
在运行,那我们也可以在本地安装好gitlab-runner
手动的来执行本地.gitlab.yml
中的job
。
你几乎可以在任何机器上安装gitlab-runner
,安装的方式这里推荐如下几种:
如下我分别使用了两种不同的方式部署Gitlab-Runner,可以选择其中一种。
1.安装gitlab runner
[root@k8s-node1 ~]# docker run -d --name gitlab-runner --restart always \
-v /srv/gitlab-runner/config:/etc/gitlab-runner \
-v /var/run/docker.sock:/var/run/docker.sock \
gitlab/gitlab-runner:latest
2.注册gitlab runner
参数解析:
--url
--registration-token
--tag-list
--run-untagged
[root@k8s-node1 ~]# docker run --rm -v /srv/gitlab-runner/config:/etc/gitlab-runner gitlab/gitlab-runner register \
--non-interactive \
--executor "docker" \
--docker-image alpine:latest \
--url "http://10.11.121.111/" \
--registration-token "o4_NCTZViRE7iGxoi" \
--description "first-register-runner" \
--tag-list "k8s" \
--run-untagged="true" \
--locked="false" \
--access-level="not_protected"
[root@k8s-master ~]# docker ps | grep gitlab-runner
3e0a02917540 gitlab/gitlab-runner:latest "/usr/bin/dumb-init …" 26 hours ago Up 3 hours gitlab-runner
2.查看Gitlab连接情况
1.进入Gitlab的CICD配置中,找到Runner配置,刷新此页面。
2.或者在Menu的菜单栏中,找到 Admin
, 然后选择 Runner
,可以查看到当前的Runner连接情况。
什么是Helm?
就像 Java 使用 maven;node 使用 npm;python 使用 pip;Linux 使用 yum 或 Apt 一样,不管是什么样的工作,技术人员都会希望有一种资源管理器/包管理器,以此来方便得查找、下载、安装、使用和分发软件包。
Helm 使用的包格式称为 chart
,它是一个描述 Kubernetes 相关资源对象的文件集合。它的技术特点类似 jinja模版,以渲染模版的方式,生成运行一个服务实例所需的一系列资源对象文件,并以此进行服务的发布。通过这种方式,我们也可以十分简单的制作自定义的 chart。
所以 Helm 即可以说是 K8S的包管理器
,它使得我们对于 K8S 的操作不再需要细化到资源对象,而是可以作为一个实例进行管理。不再需要去写 deployment
、service
、ingress
的 yaml,而是可以直接通过 install
命令实现服务实例的安装。
1.拉取Gitlab-Runner的Chart包
项目地址:https://gitlab.com/gitlab-org/charts/gitlab-runner
[root@k8s-master gitlab-runner]# ll
total 12
-rw-r--r-- 1 root root 369 Feb 21 03:39 Chart.yaml
drwxr-xr-x 2 root root 236 Apr 24 05:48 templates
-rw-r--r-- 1 root root 6452 Apr 24 05:47 values.yaml
2.配置Chart的模板
修改Chart包的values.yaml配置如下:
gitlabUrl:
配置Gitlab的URLrunnerRegistrationToken:
配置Gitlab的Runner的Tokennamespace:
配置命名空间tags:
配置标签cachePath:
配置缓存路径image: gitlab/gitlab-runner:alpine-v11.7.0
imagePullPolicy: IfNotPresent
init:
image: busybox
tag: v1.0
gitlabUrl: "http://10.11.121.111"
runnerRegistrationToken: "o4_NCTZViRE7iGxoi"
unregisterRunners: true
concurrent: 10
checkInterval: 30
rbac:
create: true
clusterWideAccess: false
metrics:
enabled: true
image: ubuntu:16.04
tags: "k8s"
privileged: true
namespace: demo
cachePath: "/opt/cache"
cache: {}
builds: {}
services: {}
helpers: {}
resources: {}
3.Helm部署Gitlab-Runner
使用helm install
命令创建安装Gitlab—Runner。
[root@k8s-master gitlab-cicd]# helm install k8s-runner gitlab-runner/ -n demo
[root@k8s-master gitlab-cicd]# helm list -n demo
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
k8s-runner demo 1 2022-04-24 13:13:11.742949709 +0000 UTC deployed gitlab-runner-0.1.37
4.查看Gitlab连接情况
1.查看当前的资源是否创建成功。
[root@k8s-master ~]# kubectl get -n demo all
NAME READY STATUS RESTARTS AGE
pod/k8s-runner-gitlab-runner-544f469c44-9m7zw 1/1 Running 0 155m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/k8s-runner-gitlab-runner 1/1 1 1 155m
NAME DESIRED CURRENT READY AGE
replicaset.apps/k8s-runner-gitlab-runner-544f469c44 1 1 1 155m
2.回到Gitlab刷新CICD的Runner的配置,新的Gitlab-Runner连接成功。
3.测试GitLab的CICD流水线
1.进入demo的项目,点击 CI/CD
,然后找到Editor
,编写一个流水线脚本,运行job1,输出Hello Word。
如上的.gitlab-ci.yaml文件如下:
stages:
- .pre
- build
- test
- deploy
job1:
stage: .pre
script:
- echo "Hello Word"
job2:
stage: build
script:
- echo "This is build"
job3:
stage: test
script:
- echo "This is test"
job4:
stage: deploy
script:
- echo "This is deploy"
2.点击 Commit changes
提交流水线脚本。
3.构建完成之后,查看当前的部署情况,可以发现四个阶段的任务都正常部署,所以说明Gitlab-CI已经可以正常运行。
4.点击Job1,查看当前的Job1输出的日志,是否为Hello Word。
如上图可以看到Job1任务输出的内容正常。
Harbor 源于 2014 年 VMware中国研发中心云原生实验室的一个内部项目,旨在为容器的开发人员解决镜像管理的问题。随着 Kubernetes 和容器技术的流行,该项目于 2016 年开源,2018 年 7 月捐赠给 CNCF,在同年 11 月被正式接受为孵化项目,并在云原生技术路线与生态中演进。
2020年5月 Harbor 2.0 正式发布,增加了对 OCI 制品的支持,能够存储大量云原生制品,例如容器镜像、Helm Chart、CNAB、OPA 和 Singularity 等等。开发人员可依照 OCI 规范,通过 OCI 索引和 OCI 制品功能开拓更广泛的应用场景,包括策略、远程复制和基于角色的访问控制等。
[root@k8s-node1 harbor]# docker-compose version
Docker Compose version v2.2.1
[root@k8s-node1 opt]# tar zxvf harbor-offline.tar.gz
[root@k8s-node1 opt]# cd harbor/
[root@k8s-node1 opt]# vim harbor.yaml
hostname: 10.11.121.112
# http related config
http:
# port for http, default is 80. If https enabled, this port will redirect to https port
port: 80
# https related config
#https:
# https port for harbor, default is 443
# port: 443
# The path of cert and key files for nginx
# certificate: /your/certificate/path
# private_key: /your/private/key/path
执行命令安装Harbor,查看harbor的进程。
[root@k8s-node1 harbor]# ./install.sh
[Step 0]: checking if docker is installed ...
Note: docker version: 20.10.14
[Step 1]: checking docker-compose is installed ...
Note: docker-compose version: 2.2.1
[Step 2]: loading Harbor images ...
···
[Step 5]: starting Harbor ...
[+] Running 10/10
⠿ Network harbor_harbor Created 0.1s
⠿ Container harbor-log Started 1.6s
⠿ Container harbor-db Started 2.6s
⠿ Container registryctl Started 3.2s
⠿ Container harbor-portal Started 2.8s
⠿ Container registry Started 3.2s
⠿ Container redis Started 3.2s
⠿ Container harbor-core Started 4.0s
⠿ Container nginx Started 5.3s
⠿ Container harbor-jobservice Started 5.3s
✔ ----Harbor has been installed and started successfully.----
[root@k8s-node1 harbor]# docker-compose ps
NAME COMMAND SERVICE STATUS PORTS
harbor-core "/harbor/entrypoint.…" core running (healthy)
harbor-db "/docker-entrypoint.…" postgresql running (healthy)
harbor-jobservice "/harbor/entrypoint.…" jobservice running (healthy)
harbor-log "/bin/sh -c /usr/loc…" log running (healthy) 127.0.0.1:1514->10514/tcp
harbor-portal "nginx -g 'daemon of…" portal running (healthy)
nginx "nginx -g 'daemon of…" proxy running (healthy) 0.0.0.0:80->8080/tcp, :::80->8080/tcp
redis "redis-server /etc/r…" redis running (healthy)
registry "/home/harbor/entryp…" registry running (healthy)
registryctl "/home/harbor/start.…" registryctl running (healthy)
访问Harbor地址: http://10.11.121.112
点击 新建项目
,创建项目名称为 demo
,访问级别设置为 公开
。
配置.gitlab-ci.yaml的流水线配置文件内容如下:
docker:v1.0
的镜像作为基础镜像maven-build、docker-build、deploy
maven镜像
构建编译demo-2048项目docker镜像
build新的镜像,推送到Harbor仓库中kubelet镜像
部署demo-2048的yaml文件image: docker:v1.0
stages:
- maven-build
- docker-build
- deploy
# 这是定义的变量,是Harbor仓库登录的验证信息。
variables:
USERNAME: admin
PASSWORD: Harbor12345
HARBORIP: 10.11.121.112
maven-build:
image: maven:3.6-jdk-8
stage: maven-build
script:
- mkdir -p /root/.m2/repository
- cp -rvf /opt/repository/* /root/.m2/repository/
- mvn clean install -Dmaven.test.sktip=true
- cp -rvf /root/demo/target/demo-2048 /opt/cache
docker_build:
image: docker:v1.0
stage: docker-build
script:
- mv /opt/cache/* /root/demo/Dockerfiles/
- cd /root/demo/Dockerfiles/ && ls
- docker build -t $HARBORIP/demo/demo-2048:v1.0 -f /root/demo/Dockerfiles/Dockerfile .
- docker login -u $USERNAME -p $PASSWORD $HARBORIP
- docker push $HARBORIP/demo/demo-2048:v1.0
# 这里的kubectl是做的镜像,是在本地仓库,使用config连接Kubernetes集群
deploy:
image: kubectl:1.16.6
stage: deploy
script:
- mkdir $HOME/.kube && cat $K8S_CONFIG > $HOME/.kube/config
- cd $HOME/.kube && pwd
- sed -i 's/10.24.2.3/10.11.121.112/g' /root/demo/template/demo-2048.yaml
- sed -i 's/{{build_tag}}/v1.0/g' /root/demo/template/demo-2048.yaml
- sed -i 's/8889/30003/g' /root/demo/template/demo-2048.yaml
- kubectl apply -f /root/demo/template/demo-2048.yaml
点击 提交完成
构建CICD。
查看构建的输出日志内容。
如下是maven-build的输出内容:
如下是docker-build的输出内容:
如下是deploy的输出内容:
查看当前的demo命名空间下的资源,demo-2048应用程序部署完成。
[root@k8s-node1 ~]# kubectl get pods -n demo
NAME READY STATUS RESTARTS AGE
demo-2048-6858bb9f8d-522rn 1/1 Running 0 3m19s
k8s-runner-gitlab-runner-544f469c44-9m7zw 1/1 Running 0 3h23m
[root@k8s-node1 ~]# kubectl get svc -n demo
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
demo30003 NodePort 10.96.113.92 <none> 8080:30003/TCP 3m24s
访问页面: http://10.11.121.112:30003
存中…(img-kIcqLhwn-1680264915426)]
如下是deploy的输出内容:
[外链图片转存中…(img-kXR0rkwO-1680264915427)]
查看当前的demo命名空间下的资源,demo-2048应用程序部署完成。
[root@k8s-node1 ~]# kubectl get pods -n demo
NAME READY STATUS RESTARTS AGE
demo-2048-6858bb9f8d-522rn 1/1 Running 0 3m19s
k8s-runner-gitlab-runner-544f469c44-9m7zw 1/1 Running 0 3h23m
[root@k8s-node1 ~]# kubectl get svc -n demo
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
demo30003 NodePort 10.96.113.92 <none> 8080:30003/TCP 3m24s
访问页面: http://10.11.121.112:30003