关于kubernetes:jenkinsgitlabk8s实现代码的自动发布手动发布

27次阅读

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

环境阐明

PS:本文档试验过程中并没有对权限做出严格束缚,比方间接在 jenkins 寄存管理员的 kubeconfig 文件、间接在 jenkins 用集群管理员角色对接 k8s 集群等操作,均有很大危险,须要依据理论状况束缚相应用户的权限。

规划设计:

角色 地址 域名
master 192.168.10.100
node 192.168.10.101
gitlab 192.168.10.110
jenkins 192.168.10.111 jenkins.snow.com
harbor 192.168.10.112 harbor.snow.com

试验之前集群曾经搭建结束,搭建教程可参考构建高可用 k8s 集群,jenkins 与 gitlab 别离应用安装包的形式装置在两台虚拟机上。harbor 以容器的形式独自部署在一台虚拟机。

策略设计

k8s 集群内的 pro 名称空间模仿生产环境,dev 名称空间模仿开发环境,开发环境下的代码只有推送到代码仓库会触发 jenkins 主动公布到 dev 名称空间的对应 POD,pro 名称空间的 POD 只有管理员手动按选定的 tag 构建进去的版本才能够公布到 k8s 环境。

增加 kubelet 认证,让 jenkins 能够有操作 k8s 集群的权限

在 Harbor 仓库别离增加两个新的我的项目,我的项目名别离为 pro 和 dev,用来寄存生产和测试的镜像。为了试验不便将我的项目都配置为了公开模式,如果想要配置为私密模式则须要增加仓库的认证信息,具体参考文章:[docker 配置 https 加密对接 k8s]

将 master 节点的.kube 文件和 kubectl 命令发送到 jenkins 所在的节点

root@master01:~# which kubectl
/opt/kube/bin/kubectl
root@master01:~# scp /opt/kube/bin/kubectl 192.168.10.111:/usr/local/bin/kubectl
root@192.168.10.111's password: 
kubectl                                                                                                                                              100%   45MB  29.0MB/s   00:01    
root@master01:~# scp -r .kube 192.168.10.111:/root/.kube
root@192.168.10.111's password: 
config                                                                                                                                               100% 6241     1.9MB/s   00:00    
9f754ca1a0545e7b871b81c83a185054                                                                                                                     100% 2460     1.6MB/s   00:00    
c4f8f2c14858bcf309490b8356533dde                                                                                                                     100%  642   219.8KB/s   00:00   

在 jenkins 验证是否有操作 k8s 集群的权限

root@jenkins:~# kubectl get no
NAME             STATUS   ROLES    AGE     VERSION
192.168.10.100   Ready    master   5d22h   v1.22.2
192.168.10.101   Ready    node     5d22h   v1.22.2

如果执行 get node 的时候报错网络超时须要查看.kube/config 文件中的 server 字段是否指定的是 apiserver 的地址及 apiserver 的 6443 端口是否监听在 127.0.0.1 地址。在 jenkins 增加拜访 k8s 集群的凭证登录 jenkins 后抉择 Dashboard-> 系统管理 -> 凭据 -> 零碎 -> 全局凭据,点击右上角创立一个新的凭据。

类型抉择 X.509 Client Certficate,Client Key 字段内容填写.kube/config 文件中的 client-key-data 字段数据 base64 解码后的值。Client Certificate 字段填写.kube/config 文件中的 client-certificate-data 字段数据 base64 解码后的值,Server CA Certificate 字段填写.kube/config 文件中的 certificate-authority-data 字段数据 base64 解码后的值。

增加 gitlab 认证,让 jenkins 能够有拉取代码的权限

持续依照上一步的操作新增加一个凭证

创立新仓库,别离创立 main 与 dev 分支并推送到 gitlab。

在 gitlab 新建一个空白我的项目

在 master 节点应用 git 命令创立分支并将代码推送到 gitlab

root@master01:~/dev/httpserver# git init 
Initialized empty Git repository in /root/dev/httpserver/.git/
root@master01:~/dev/httpserver# git remote add origin http://192.168.10.110/root/helloserver.git
root@master01:~/dev/httpserver# git checkout -b main
Switched to a new branch 'main'

筹备提前写好的 Dockerfile 文件与测试代码。PS: 这里的 dockerfile 写的很烂,只是能用。

root@master01:~/dev/httpserver# ls
Dockerfile  go.mod  main.go
root@master01:~/dev/httpserver# cat Dockerfile 
FROM golang:latest
ADD . /
WORKDIR /
RUN go build -o main.exe
EXPOSE 80
ENTRYPOINT ["./main.exe"]
root@master01:~/dev/httpserver# cat main.go 
package main

import ("net/http")
func main() {http.HandleFunc("/", func(resp http.ResponseWriter, req *http.Request) {resp.Write([]byte("Version=1.0"))
    })
    http.ListenAndServe(":80", nil)
}

将 main 分支的代码推送到仓库

root@master01:~/dev/httpserver# git add .
root@master01:~/dev/httpserver# git status
On branch main

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
    new file:   Dockerfile
    new file:   go.mod
    new file:   main.go

root@master01:~/dev/httpserver# git commit -m "v1.0"
[main (root-commit) 3b5d105] v1.0
 3 files changed, 21 insertions(+)
 create mode 100644 Dockerfile
 create mode 100644 go.mod
 create mode 100644 main.go
root@master01:~/dev/httpserver# git tag v1.0
root@master01:~/dev/httpserver# git push --tags
Username for 'http://192.168.10.110': root
Password for 'http://root@192.168.10.110': 
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 2 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (5/5), 584 bytes | 584.00 KiB/s, done.
Total 5 (delta 0), reused 0 (delta 0)
To http://192.168.10.110/root/helloserver.git
 * [new tag]         v1.0 -> v1.0
#将主分支的代码推送到仓库,在操作的时候有点失误,最初强制合并的。root@master01:~/dev/httpserver# git pull --allow-unrelated-histories origin main
Username for 'http://192.168.10.110': root
Password for 'http://root@192.168.10.110': 
From http://192.168.10.110/root/helloserver
 * branch            main       -> FETCH_HEAD
hint: Waiting for your editor to close the file... 
  GNU nano 4.8                           /root/dev/httpserver/.git/MERGE_MSG                                     
Merge branch 'main' of http://192.168.10.110/root/helloserver into main
# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.
Merge made by the 'recursive' strategy.
 README.md | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 92 insertions(+)
 create mode 100644 README.md
root@master01:~/dev/httpserver# 
root@master01:~/dev/httpserver# git push -u origin main
Username for 'http://192.168.10.110': root
Password for 'http://root@192.168.10.110': 
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 2 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 402 bytes | 402.00 KiB/s, done.
Total 2 (delta 0), reused 0 (delta 0)
To http://192.168.10.110/root/helloserver.git
   924f2d2..eeb98b1  main -> main
Branch 'main' set up to track remote branch 'main' from 'origin'.

在 Gitlab 查看推送到主分支的代码

创立开发分支,并将开发分支推送到 Gitlab

root@master01:~/dev/httpserver# git checkout -b dev
Switched to a new branch 'dev'
root@master01:~/dev/httpserver# git add .
root@master01:~/dev/httpserver# git commit -m "v1.0"
On branch dev
nothing to commit, working tree clean
root@master01:~/dev/httpserver# git tag v1.0
fatal: tag 'v1.0' already exists
root@master01:~/dev/httpserver# git push -u origin dev
Username for 'http://192.168.10.110': root
Password for 'http://root@192.168.10.110': 
Total 0 (delta 0), reused 0 (delta 0)
remote: 
remote: To create a merge request for dev, visit:
remote:   http://gitlab.example.com/root/helloserver/-/merge_requests/new?merge_request%5Bsource_branch%5D=dev
remote: 
To http://192.168.10.110/root/helloserver.git
 * [new branch]      dev -> dev
Branch 'dev' set up to track remote branch 'dev' from 'origin'.

推送实现后发现曾经多了一个名字为 dev 的分支

设置生产环境须要指定 tag 版本公布。

在 jenkins 创立一个自在格调的工作

配置参数化构建信息

在源码治理地位配置 gitlab 仓库信息,留神须要抉择之前创立的认证信息,不然会报权限有余。

在构建环境地位抉择 Setup Kubernetes CLI (kubectl),并配置集群相干信息,此处的 certificate 配置的数据为.kube/config 文件中 certificate-authority-data 字段的值通过 base64 解码后的值。凭据抉择之前创立的有操作 k8s 集群权限的凭据。

配置更新镜像须要执行的 shell 命令。曾经在每台主机配置了将 harbor.snow.com 解析为镜像仓库地址的条目,所以此处间接写了域名。

配置实现后单击保留,点击参数化构建能够看到之前推送到 Gitlab 仓库的代码的 tag,依据 tag 去拉取代码。

在 k8s 提前应用 yaml 文件创建出业务 deployment 控制器,将生产相干代码创立在 pro 名称空间。对其进行版本更新的操作就是对 yaml 文件中 image 字段的更新。

root@master01:~/pod# kubectl create ns pro
namespace/pro created
root@master01:~/pod# cat httpserver.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: httpserver
spec:
  replicas: 3
  selector:
    matchLabels:
      run: httpserver
  template:
    metadata:
      labels:
        run: httpserver
    spec:
      containers:
        - name: httpserver
          image: nginx
          imagePullPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
  name: httpserver-service
spec:
  type: NodePort
  selector:
    run: httpserver
  ports:
    - port: 80
      targetPort: 80

root@master01:~/pod# kubectl apply -f . -n pro
deployment.apps/httpserver created
service/httpserver-service created

配置实现后在 jenkins 点击参数化构建,抉择 v1.0 版本进行构建。

构建过程能够在控制台输入地位看到

当初去 k8s 拜访业务代码的地址查看其版本。

当初应用 git 命令将 v2.0 版本推送到代码仓库,2.0 版本只是在 main.go 文件中将版本号更改为 2.0. 以下是手动改完版本后的操作。

root@master01:~/dev/httpserver# git status
On branch main
Your branch is up to date with 'origin/main'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
    modified:   main.go

no changes added to commit (use "git add" and/or "git commit -a")
root@master01:~/dev/httpserver# git add .
root@master01:~/dev/httpserver# git commit -m "v2.0"
[main 3c7199e] v2.0
 1 file changed, 1 insertion(+), 1 deletion(-)
root@master01:~/dev/httpserver# git tag v2.0
root@master01:~/dev/httpserver# git push --tags
Username for 'http://192.168.10.110': root
Password for 'http://root@192.168.10.110': 
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 2 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 277 bytes | 277.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0)
To http://192.168.10.110/root/helloserver.git
 * [new tag]         v2.0 -> v2.0

操作实现去 gitlab 查看发现 2.0 版本曾经胜利推送上来了。

当初去 jenkins 抉择参数化构建,构建的时候 tag 选 2.0 版本。

构建实现后发现版本曾经成为最新 v2.0 版本。

设置 dev 分支能够主动公布

在 k8s 集群创立出 dev 名称空间,并创立出对应的业务 service 的 deployment,所用到的 yaml 与下面在 pro 名称空间创立资源时应用的对立个,这里就没有反复截图。

去 jenkins 创立一个新的自在格调的工作

在源码治理地位配置代码仓库相干信息,留神要拉取的分支改为开发分支。

抉择构建触发器中的 Build when a change is pushed to GitLab 选项,这个选项是须要装置 Gitlab Hook Plugin 和 Build Authorization Token Root Plugin 插件才能够看到。

配置 k8s 的连贯信息

此处在构建时应用了 $BUILD_NUMBER 变量作为镜像的 tag,确保每次构建 k8s 都能拉取到最新的镜像。

创立实现后先手动点击构建,看是否能失常构建胜利

在 k8s 平台测试手动构建胜利

此时在 jenkins 点击配置,在构建触发器取出此链接,须要配置到 Gitlab 平台。

同样在该选项卡下点击高级配置能够看到如下选项,点击生成一个新的 token

之后单击保留。

单击页面左上角抉择最上面的管理员

在设置选项卡找到网络。

在出站申请地位勾选 容许来自 web hooks 和服务对本地网络的申请,否则无奈增加本地须要调用的 webhook 地址。更改实现后保留。

进入我的项目配置信息,抉择设置,单击 WebHook。

在此处配置刚刚取出的地址和 token

配置实现后在此页面最下方会看到创立的 webhook

创立实现后能够去测试推送事件触发构建,发现在 jenkins 曾经胜利触发构建

此时用 git 向 dev 分支提交代码,手动将 main.go 的版本号批改为 2.0。批改文件过程不再演示。

root@master01:~/dev/httpserver# git add .
root@master01:~/dev/httpserver# git commit -m "v2.0"
[dev 9df58bd] v2.0
 1 file changed, 1 insertion(+), 1 deletion(-)
root@master01:~/dev/httpserver# git push -u origin dev
Username for 'http://192.168.10.110': root
Password for 'http://root@192.168.10.110': 
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 2 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 277 bytes | 277.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0)
remote: 
remote: To create a merge request for dev, visit:
remote:   http://gitlab.example.com/root/helloserver/-/merge_requests/new?merge_request%5Bsource_branch%5D=dev
remote: 
To http://192.168.10.110/root/helloserver.git
   eeb98b1..9df58bd  dev -> dev
Branch 'dev' set up to track remote branch 'dev' from 'origin'.

此时去 jenkins 平台查看发现曾经触发构建。

当初去 k8s 平台去验证 dev 名称空间的 POD 是否曾经自动更新。

root@master01:~/dev/httpserver# kubectl get svc -n dev
NAME                 TYPE       CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
httpserver-service   NodePort   10.100.53.6   <none>        80:30222/TCP   36m
root@master01:~/dev/httpserver# curl 10.100.53.6
Version=2.0root@master01:~/dev/httpserver# 

ps:以上内容在自己实现环境中已试验胜利,如发现有问题或表述不清的中央欢送斧正。

正文完
 0