环境变量和构建参数
环境变量基础
Jenkins支持在流水线中使用环境变量和参数,进而让流水线的定义和运行更具灵活性
环境变量可分为Jenkins内置变量和用户自定义变量两类
◼ Jenkins提供了多个内置的变量
◼ Jenkins内置的全局环境变量可被所有的pipeline引用,它们以“env.”为前缀
◼ 我们可将环境变量视作pipeline与Jenkins系统交互的媒介
◼ 引用全局环境变量格式有三种:
◆ ${env.}、$env.和${ENV_VAR_NAME}
下面是Jenkins内置的几个常用的环境变量
◼ BUILD_NUMBER:构建号,递增的整数值;打包时,经常用作制品名称的一部分
◼ BRANCH_NAME:在多分支pipeline中,需要根据不同的分支施加不同的操作时较为常用
◼ BUILD_URL:当前构建页面的URL,常用于邮件通知中
◼ GIT_BRANCH:基于git拉取的源码进行构建时使用该变量
◼ JENKINS_HOME:Jenkins的家目录
◼ JENKINS_URL:Jenkins服务的URL
◼ JOB_NAME:当前作业的名称
◼ ……
获取可用的内置环境变量
Jenkins在不同作业类型通常都提供了获取系统内置环境变量的方法,下面的来自于自由风格作业中
Build Steps中“运行shell脚本”中的链接;
自定义全局环境变量
自定义环境变量的功能与内置环境变量相同
◼ 系统管理 → 系统配置 → 全局属性 → 环境变量
新建任务,引用全局变量
在代码仓选择代码,并指定用户
选择全局变量
应用保存立即构建
参数化构建
参数化构建的目标在于为流水线提供基于参数值的灵活构建机制,从而让一个流水线的定义可以适
用于多种需求情形
◼ 其功能与引用方式与环境变量类似
◼ 在触发作业运行之时,需要向各参数赋值
常用的参数类型
◼ 凭据参数
◼ 字符参数
◼ 密码参数
◼ 布尔值参数
◼ 文件参数
◼ 文本参数
◼ 运行时参数
◼ 选项参数
◼ 由其它插件引入的参数类型
参数示例:
字符参数
布尔值参数
选项参数
凭据参数
运行参数化构建作业(在freestyle-job-004作业上配置)
字符参数,imageTag,latest。
布尔值参数,isPbulish,是否发布应用。
选项参数,environment
选择全局变量(最后一个参数为哪一个私有镜像服务之上的哪个仓库中的标签名是什么)
应用保存基于参数构建(参数可选择)
自由风格的CI流水线示例—参数化构建
在作业freestyle-job-004上进行配置
1、添加参数branchName,定义在执行构建时要构建哪一个目标分支
选择的分支在git仓库中要有,负责会失败
2、安装Git Parameter插件与Extensible Choice Parameter插件,用于使用其相关的参数
Extensible Choice Parameter
可扩展的选择参数之文件选择参数示例
◼ Base Director:文件搜索起始路径
◼ File Name Pattern:文件名称模式
◆*:通配符
◆**:多级路径通配符
◼ Exclude Pattern:用于排除文件的模式
◼ Type:搜索的文件类型
示例图:
配置示例:在freestyle-job-004工作上配置
Name: resourceManifest(资源清单)
Base Directory .当前目录(JENKINS_HOME)
**/*.yaml 任意递归目录下以*.yaml结尾的文件
Reverse Order:搜索完之后的排序格式
Editable:搜索完结果是否可编辑(所有的或仅匹配的),不被编辑,搜索到什么,编辑什么
构建和推送Docker Image
在流水线中构建和推送Docker Image
现如今,越来越多的组织以容器形式运行应用
◼ 应用交付形式统一为Container Image
◼ 交付的Container Image由Registry存储和分发
◼ 应用以容器化形式由Kubernetes编排运行
Jenkins的多款插件都能实现Image构建和推送
◼ docker-build-step Plugin
◼ Docker Plugin
◼ CloudBees Docker Build and Publish Plugin
1、安装docker-build-step插件
2、新建任务
构建参数–选择choice parameter(选项参数)
为选项参数提供变量
查看前边构建任务的结果
应用保存构建
控制台输出
在系统管理系统配置中管理docker build
(docker Url指明使用哪个docker主机完成后续的构建操作,需要事先在部署jenkins的主机上准备好docker环境,docker会监听var/run/docker.sock文件,此文件用于jenkins与docker的通信)
可远程链接编辑docker,docker默认只监听本地路径
[root@ubuntu2004 ~]#vim /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2379 --containerd=/run/containerd/containerd.sock
[root@ubuntu2004 ~]#systemctl daemon-reload && systemctl restart docker
把docker Url换成 tcp://localhost:2379
[root@ubuntu2004 ~]#usermod -G docker jenkins
[root@ubuntu2004 ~]#cat /etc/group | grep docker
docker:x:118:jenkins
回到流水线再次进行配置(到build steps处删除执行的shell命令,选择执行docker命令)
Build context folder(默认加载dockerfile文件的路径时WORKSPACE/docker)
Tag of the resulting docker image(在docker之上使用的docker的镜像文件tag默认使用${BUILD_NUMBER})
使用自己的镜像标签:{JOB_NAME}:${imageTag}
向私有仓库的ikubernetes/路径下推镜像,镜像仓库的名字是当前作业名字,标签使用参数构建所定义的标签
添加文本参数
应用保存构建
查看打好的镜像
[root@ubuntu2004 ~]#docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
hub.mengfanchao.com/ikubernetes/spring-boot-helloworld latest 1c52c01b9ea3 32 seconds ago 368MB
eclipse-temurin 11-jdk-alpine ba805081c350 10 days ago 352MB
推镜像到harbor镜像仓库
构建出现错误,因为没有部署harbor仓库(可自建harbor或者公共服务之上)
此时选择部署kubernetes集群,把haobor部署到集群之上并暴露到集群外部
1、部署k8s
2、部署ingress nginx
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.5.1/deploy/static/provider/cloud/deploy.yaml
查看部署状态:kubectl get pods -n ingress-nginx
3、增加外部IP(在node节点上增加IP,作为ingress-nginx的外部IP使用)
添加外部IP地址后调整流量策略,从local调整为ClusterIP
kubectl get svc 0n ingress-nginx得到ingress-nginx-contruller
对ingress-nginx-contruller进行修改流量策略
kubectl edit scv ingress-nginx-contruller -n ingress-nginx
调整内容:externalTrafficPolicy: ClusterIP
clusternalIPs:
- 10.0.0.200
4、部署nfs-csi
①kubectl create namespace nfs
②kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/csi-driver-nfs/master/deploy/example/nfs-provisioner/nfs-server.yaml --namespace nfs
③curl -skSL https://raw.githubusercontent.com/kubernetes-csi/csi-driver-nfs/v4.1.0/deploy/install-driver.sh | bash -s v4.1.0 --
④创建storage class
vim csi-nfs.yaml
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-csi
provisioner: nfs.csi.k8s.io
parameters:
#server: nfs-server.default.svc.cluster.local
server: nfs-server.nfs.svc.cluster.local
share: /
reclaimPolicy: Delete #当删除PVC时,会自动删除PV
volumeBindingMode: Immediate
mountOptions:
- hard
- nfsvers=4.1
kubectl apply -f csi-nfs.yaml
做动态制备测试
kubectl create -f https://raw.githubusercontent.com/kubernetes-csi/csi-driver-nfs/master/deploy/example/pvc-nfs-csi-dynamic.yaml
删除测试的PV和PVC
kubectl delete pvc --all
5、部署harbor
①创建名称空间
kubectl create namespace -n harbor
②下载helm,用helm部署harbor
③添加helm repo仓库
helm repo add harbor https://helm.goharbor.io
④部署harbor
helm install harbor -f harbor-values.yaml harbor/harbor -n harbor
vim harbor-values.yaml
expose:
type: ingress
tls:
enabled: true
certSource: auto
ingress:
hosts:
core: hub.magedu.com
notary: notary.magedu.com
controller: default
annotations:
kubernetes.io/ingress.class: "nginx"
ipFamily:
ipv4:
enabled: true
ipv6:
enabled: false
externalURL: https://hub.magedu.com
# 持久化存储配置部分
persistence:
enabled: true
resourcePolicy: "keep"
persistentVolumeClaim: # 定义Harbor各个组件的PVC持久卷
registry: # registry组件(持久卷)
storageClass: "nfs-csi" # 前面创建的StorageClass,其它组件同样配置
accessMode: ReadWriteMany # 卷的访问模式,需要修改为ReadWriteMany
size: 5Gi
chartmuseum: # chartmuseum组件(持久卷)
storageClass: "nfs-csi"
accessMode: ReadWriteMany
size: 5Gi
jobservice:
jobLog:
storageClass: "nfs-csi"
accessMode: ReadWriteOnce
size: 1Gi
scanDataExports:
storageClass: "nfs-csi"
accessMode: ReadWriteOnce
size: 1Gi
database: # PostgreSQl数据库组件
storageClass: "nfs-csi"
accessMode: ReadWriteMany
size: 2Gi
redis: # Redis缓存组件
storageClass: "nfs-csi"
accessMode: ReadWriteMany
size: 2Gi
trivy: # Trity漏洞扫描
storageClass: "nfs-csi"
accessMode: ReadWriteMany
size: 5Gi
harborAdminPassword: "magedu.com"
⑤部署好后,查看
helm list -n harbor
⑥进行解析
10.0.0.200 hub.magedu.com
访问harbor
添加用户(和jenkins里面创建的一致)
用户管理-添加账号
用户名:mengfanchao
邮箱:mfc@qq.com
全名:MengFanchao
密码:meng121104
由于jenkins上的docker无法识别对应的证书,编辑docker配置文件
vim /etc/docker/daemon.json
systemctl daemon-reload
systemctl restart docker
在jenkins上对huabor仓库进行解析
vim /etc/hosts
10.0.0.200 hub.magedu.com
在jenkins主机输入用户名和密码进行登录
docker login -u mengfanchao hub.magedu.com
在jenkins主机查看自己打的镜像并推送到harbor仓库
docker image ls
hub.mengfanchao.com/ikubernetes/spring-boot-helloworld
推送
docker image push hub.mengfanchao.com/ikubernetes/spring-boot-helloworld
在流水线执行构建,让其自己推送到haobor仓库
推完镜像之后,把镜像应用部署到k8s集群上
为了完成应用的部署,首先得确保
第一:jenkins主机得有kubectl命令
第二:kubectl命令基于jenkins主机访问k8s的时候,能成功认证到k8s集群上
第三:有权限去做部署操作
一:在k8s主机上操作
创建名称空间
kubectl create namespace hello
在hello名称空间下创建serviceaccount,
kubectl create serviceaccount hello -n hello
绑定到集群角色上
kubectl create rolebinding hello-admin --clusterrole=cluster-admin
--serviceaccount=hello:hello-admin -n hello
创建pod,生成TOKEN信息
vim hello-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: test
namespace: hello
spec:
containers:
- image: ikubernetes/admin-box:v1.2
name: sleep
command: ["/bin/sh","-c","sleep 99999"]
serviceAccountName: hello-admin
完成创建
kubectl apply -f hello-pod.yaml
查看TOKEN
kubectl exec -it test -n hello -- /bin/sh
cat /var/run/secrets/kubernetes.io/serviceaccount/token
把TOKEN复制到jenkins上,作为认证凭据使用
二、在jenkins主机上安装kubectl
curl -LO https://dl.k8s.io/v1.26.1/kubernetes-client-linux-amd64.tar.gz
tar xf kubernetes-client-linux-amd64.tar.gz
cd kubernetes/client/bin/
ls
kubectl kubectl-convert
cp kubectl /usr/bin/
三、把k8s集群在jenkins上定义为全局参数
系统管理-系统配置-全局属性 新增
设置认证凭据
系统管理-管理凭据(manager credentials)
对流水线进行配置两个参数
#!/bin/bash
sed -i "s@_IMAGE_@${registry}/ikubernetes/${JOB_NAME}:${imageTag}@" deploy/all-in-one.yaml
kubectl --server ${kuberApiServer} --insecure-skip-tls-verify=${skipTLSCertVerify} --token=${serviceAccountToken} apply -f deploy/all-in-one.yaml
指定server,要不要跳过证书验证,认证到集群上的选项是什么
在jenkins主机上对kubeapi server进行域名解析
vim /etc/hosts
10.0.0.1 kubeapi.magedu.com
部署成功之后,在k8s集群上查看pod以及svc
kubectl get pods -n hello
kubectl get svc -n hello
在集群外部进行访问
总结:部署到kubernetes上
第一:通过环境变量kubeApiServer指定服务器地址 https://kubeapi.magedu.com:6443
如果通过https进行通信,客户端要去校验server端证书,也可跳过校验 默认不跳过--insecure-skip-tls-verify=false 改成true
第二:在jenkins主机之上部署kubectl命令,因为需要在jenkins主机上调用执行shell命令的形式完成向集群部署程序
第三:把jenkins的kubectl命令认证到kubeapi-server上,需要在kubeapi-server上
创建名称空间、创建serviceaccount账户、利用rolebind把账户与系统内置的Cluster-Admin建立绑定关系
第四:如果harbor没有部署到k8s集群之上,就需要k8s集群解析haobor仓库的域名(每个节点都需解析)
第五:k8s的deployment控制器自身具有滚动跟新的能力,可以确保服务不中断的情况下完成滚动更新操作
服务器租用托管,机房租用托管,主机租用托管,https://www.e1idc.com