环境阐明
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/kubectlroot@master01:~# scp /opt/kube/bin/kubectl 192.168.10.111:/usr/local/bin/kubectlroot@192.168.10.111's password: kubectl 100% 45MB 29.0MB/s 00:01 root@master01:~# scp -r .kube 192.168.10.111:/root/.kuberoot@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 noNAME STATUS ROLES AGE VERSION192.168.10.100 Ready master 5d22h v1.22.2192.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.gitroot@master01:~/dev/httpserver# git checkout -b mainSwitched to a new branch 'main'
筹备提前写好的Dockerfile文件与测试代码。PS:这里的dockerfile写的很烂,只是能用。
root@master01:~/dev/httpserver# lsDockerfile go.mod main.goroot@master01:~/dev/httpserver# cat Dockerfile FROM golang:latestADD . /WORKDIR /RUN go build -o main.exeEXPOSE 80ENTRYPOINT ["./main.exe"]root@master01:~/dev/httpserver# cat main.go package mainimport ( "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 statusOn branch mainNo commits yetChanges to be committed: (use "git rm --cached <file>..." to unstage) new file: Dockerfile new file: go.mod new file: main.goroot@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.goroot@master01:~/dev/httpserver# git tag v1.0root@master01:~/dev/httpserver# git push --tagsUsername for 'http://192.168.10.110': rootPassword for 'http://root@192.168.10.110': Enumerating objects: 5, done.Counting objects: 100% (5/5), done.Delta compression using up to 2 threadsCompressing 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 mainUsername for 'http://192.168.10.110': rootPassword for 'http://root@192.168.10.110': From http://192.168.10.110/root/helloserver * branch main -> FETCH_HEADhint: 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.mdroot@master01:~/dev/httpserver# root@master01:~/dev/httpserver# git push -u origin mainUsername for 'http://192.168.10.110': rootPassword for 'http://root@192.168.10.110': Enumerating objects: 4, done.Counting objects: 100% (4/4), done.Delta compression using up to 2 threadsCompressing 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 -> mainBranch 'main' set up to track remote branch 'main' from 'origin'.
在Gitlab查看推送到主分支的代码
创立开发分支,并将开发分支推送到Gitlab
root@master01:~/dev/httpserver# git checkout -b devSwitched to a new branch 'dev'root@master01:~/dev/httpserver# git add .root@master01:~/dev/httpserver# git commit -m "v1.0"On branch devnothing to commit, working tree cleanroot@master01:~/dev/httpserver# git tag v1.0fatal: tag 'v1.0' already existsroot@master01:~/dev/httpserver# git push -u origin devUsername for 'http://192.168.10.110': rootPassword 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=devremote: To http://192.168.10.110/root/helloserver.git * [new branch] dev -> devBranch '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 pronamespace/pro createdroot@master01:~/pod# cat httpserver.yaml apiVersion: apps/v1kind: Deploymentmetadata: name: httpserverspec: replicas: 3 selector: matchLabels: run: httpserver template: metadata: labels: run: httpserver spec: containers: - name: httpserver image: nginx imagePullPolicy: Always---apiVersion: v1kind: Servicemetadata: name: httpserver-servicespec: type: NodePort selector: run: httpserver ports: - port: 80 targetPort: 80root@master01:~/pod# kubectl apply -f . -n prodeployment.apps/httpserver createdservice/httpserver-service created
配置实现后在jenkins点击参数化构建,抉择v1.0版本进行构建。
构建过程能够在控制台输入地位看到
当初去k8s拜访业务代码的地址查看其版本。
当初应用git命令将v2.0版本推送到代码仓库,2.0版本只是在main.go文件中将版本号更改为2.0.以下是手动改完版本后的操作。
root@master01:~/dev/httpserver# git statusOn branch mainYour 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.gono 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.0root@master01:~/dev/httpserver# git push --tagsUsername for 'http://192.168.10.110': rootPassword for 'http://root@192.168.10.110': Enumerating objects: 5, done.Counting objects: 100% (5/5), done.Delta compression using up to 2 threadsCompressing 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 devUsername for 'http://192.168.10.110': rootPassword for 'http://root@192.168.10.110': Enumerating objects: 5, done.Counting objects: 100% (5/5), done.Delta compression using up to 2 threadsCompressing 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=devremote: To http://192.168.10.110/root/helloserver.git eeb98b1..9df58bd dev -> devBranch 'dev' set up to track remote branch 'dev' from 'origin'.
此时去jenkins平台查看发现曾经触发构建。
当初去k8s平台去验证dev名称空间的POD是否曾经自动更新。
root@master01:~/dev/httpserver# kubectl get svc -n devNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEhttpserver-service NodePort 10.100.53.6 <none> 80:30222/TCP 36mroot@master01:~/dev/httpserver# curl 10.100.53.6Version=2.0root@master01:~/dev/httpserver#
ps:以上内容在自己实现环境中已试验胜利,如发现有问题或表述不清的中央欢送斧正。