当前位置: > 投稿>正文

jenkins远程部署,jenkins和docker实现自动化构建部署

04-23 互联网 未知 投稿

关于【jenkins远程部署】,今天犇犇小编给您分享一下,如果对您有所帮助别忘了关注本站哦。

1、jenkins远程部署:jenkins和docker实现自动化构建部署

前言:

程序员开发应用,开发后需要提交svn,然后从svn拉取代码,进行构建,发布到tomcat中,发布,然后看呈现效果,这样的工作是频繁反复的在进行的,浪费了程序员的大量时间,那么能不能把这些工作自动化呢,只需要程序员更新代码到svn,然后自动的构建,发布,呈现效果,当然是可以的,通过jenkins和docker来实现。本文将主要介绍下基于Jenkins+docker 实现自动化部署。

jenkins远程部署,jenkins和docker实现自动化构建部署

构想的网络结构图:

jenkins远程部署,jenkins和docker实现自动化构建部署

  • 大体结构流程:
  1. 开发人员在gitLab上打了一个tag
  2. gitLab把tag事件推送到Jenkins
  3. Jenkins 获取tag源码,编译,打包,构建镜像
  4. Jenkins push 镜像到阿里云仓库
  5. Jenkins 执行远程脚本
  6. 5-1. 远程服务器 pull 指定镜像
  7. 5-2. 停止老版本容器,启动新版本容器
  8. 通知测试人员部署结果

基于maven构建镜像,上传阿里云docker仓库

maven 构建镜像配置

  • pom.xml 文件添加docker插件:

jenkins远程部署,jenkins和docker实现自动化构建部署

  • 注意:

1、${docker.image.prefix} 是镜像的前缀

2、${project.artifactId} 是镜像名字

3、${project.version} 版本号,此处也用来当做镜像的版本号

4、docker-maven-plugin 使用可自行百度。

  • src/main/docker 目录下新增文件 Dockerfile,内容如下:

jenkins远程部署,jenkins和docker实现自动化构建部署

以上的配置可以把一个服务打包成镜像,只需要执行:

jenkins远程部署,jenkins和docker实现自动化构建部署

阿里云docker仓库使用:

注册或者启用阿里云docker仓库就不赘述。下面简单介绍上传拉取docker镜像

  • 登录:

jenkins远程部署,jenkins和docker实现自动化构建部署

  • push 之前生成的镜像:

jenkins远程部署,jenkins和docker实现自动化构建部署

  • 注意:

1、xxx : 是你镜像仓库的namespace

2、在一堆push后,你就可以在阿里云的Docker镜像仓库里面看到你对应的镜像了。

镜像列表:

  • pull 镜像

登录操作同上

jenkins远程部署,jenkins和docker实现自动化构建部署

jenkins 部署配置:

  • 构建Jenkins镜像:

jenkins远程部署,jenkins和docker实现自动化构建部署

一开始使用官方的镜像直接启用,一些插件和配置多少都有点问题,比如不能使用sudo,等等。因此基于官方镜像构建一个更符合我们需要的镜像。

  • 构建命令:

jenkins远程部署,jenkins和docker实现自动化构建部署

  • 启动Jenkins容器

jenkins远程部署,jenkins和docker实现自动化构建部署

  • 注意:

1、-v /var/run/docker.sock:/var/run/docker.sock 与 -v /usr/bin/docker:/usr/bin/docker是把宿主机docker 映射到容器内。

2、-v /home/buxiaoxia/software/jenkins:/var/jenkins_home 指定Jenkins的宿主机存储路径

3、-v /usr/lib64/libltdl.so.7:/usr/lib/x86_64-linux-gnu/libltdl.so.7 在centos7 系统下会出现个别的包丢失,对应的引下宿主机的包就可以。

docker在容器内构建的时候,如果出现权限不够什么的。可以在宿主机中使用以下两种方式:

jenkins远程部署,jenkins和docker实现自动化构建部署

或者

jenkins远程部署,jenkins和docker实现自动化构建部署

jenkins 启动后,访问对应的Jenkins页面,初始化只要一步步跟着走就可以了。

  • Jenkins配置:

所需插件下载

  • Maven Integration plugin
  • docker-build-step
  • Docker plugin
  • Gitlab Hook Plugin
  • GitLab Plugin

因为使用的是gitlab,对应的插件也是必须的。下载完插件后,maven等相关插件配置好(此处省略...)

maven 镜像地址配置

可以直接在宿主机修改,路径在:/home/buxiaoxia/software/jenkins/tools/hudson.tasks.Maven_MavenInstallation/maven3-1/conf 下的settings.xml

setting.xml 镜像改成阿里云的就OK啦。

  • 新建一个maven job:

源码配置

构建

构建后执行特定脚本

jenkins远程部署,jenkins和docker实现自动化构建部署

  • 注意

1.首先要ssh上去注意这里的<< remotessh,需要做公钥密钥2.#从这里开始都是在远程机器上执行命令

jenkins远程部署,jenkins和docker实现自动化构建部署

jenkins.sh 脚本内容:

jenkins远程部署,jenkins和docker实现自动化构建部署

以上就完成了一个简单的自动化构建啦!

gitlab配置webhook:

Jenkins安装完对应的gitlab插件,配置中的构建触发选择如下

复制红框中的url,再在gitlab的对应项目中webhooks页面中的url填入前面复制的url,保存即可。

配置完成后,每次该项目有个tag push event ,都会触发Jenkins的自动构建。接着,Jenkins就执行 拉取源码 -> 编译 -> 构建镜像 -> 推送镜像 -> 执行远程启动脚本完成部署。

最后:

一步步的配置,基本就跑通了我们基于Jenkins,docker实现自动化部署的初始版本。开发人员完成功能开发后,需要交互一个测试版本,只需要推送一个tag到git仓库,就能够将代码自动部署到特定的服务器上。可喜可贺~ 可以省去一堆的从一个服务器跑到另一个服务器,然后执行各种命令的琐碎操作。。。

关于配置

目前我是使用了consul的配置共享,把不同环境的配置放在了consul上,镜像中没有保留可变的配置,而是根据启动的参数就可以自由切换环境配置。

当然,consul的配置共享可以看看我git上关于consul的项目:http://git.oschina.net/buxiaoxia/spring-demo

存在问题

  • docker未使用编排,较为独立,需要知道特定的服务器网络位置
  • docker镜像的push与pull,都需要明文执行阿里云账号密码,可进一步改进
  • 未构建版本回退流程
  • shell脚本健壮性不够,异常未处理

本文提供的方法是作者认为比较简单的方式,难免存在不足,大家可通过docker 使用swarm,让swarm管理docker 容器等方式对流程进行不断优化哦。

4、jenkins远程部署,jenkins在Kubernetes中持续部署完整版

小编花了一个星期时间整理了Jenkins 在Kubernetes中持续部署,其中包含 gitlab,harbor,jenkins,jenkins-slave部署以及提供一个项目源代码,方便大家学习。

本文中的所有代码,yaml 文件都可以在 我的github 中找到:

https://github.com/fxkjnj/kubernetes/tree/main/jenkins-for_kubernetes

资产信息:

主机名(IP)

用途

版本

192.168.31.100

Harbor镜像仓库,NFS 服务器

v2.1.0

192.168.31.200

Gitlab 代码仓库

latest

192.168.31.61

K8s-master 节点

v1.18

192.168.31.62

node-1节点

v1.18

192.168.31.63

node-2节点

v1.18

一、了解发布流程

jenkins远程部署,jenkins和docker实现自动化构建部署

流程:

  • 拉取代码 git checkout
  • 编译代码 mvn clean
  • 打包镜像 并上传镜像仓库
  • 使用yaml 模板文件部署用镜像仓库中的镜像,kubectl 命令部署Pod
  • 开发测试
二、使用 Gitlab 作为代码仓库 & 使用 Harbor 作为镜像仓库2.1 部署Harbor作为镜像仓库

部署方式: 采用方式docker-compose部署docker容器

下载地址: https://github.com/goharbor/harbor/releases/tag/v2.1.0

[root@harbor ~]# wget https://github.com/goharbor/harbor/releases/download/v2.1.0/harbor-offline-installer-v2.1.0.tgz[root@harbor ~]# tar -zxf harbor-offline-installer-v2.1.0.tgz -C /opt/

编辑harbor配置文件:

先备份:

[root@harbor ~]# cp /opt/harbor/harbor.yml /opt/harbor/harbor.yml-bak

[root@harbor ~]# vim /opt/harbor/harbor.yml

# https related config #不做HTTPS 可以把Https 那几行给注释掉#https:# https port for harbor, default is 443# port: 443hostname: 192.168.31.100 #直接用IP地址访问port: 80 #nginx服务端口harbor_admin_password: Harbor12345 #harbor管理员密码data_volume: /opt/harbor/data #harbor 数据目录,需提前创建好该目录location: /opt/harbor/logs #harbor 日志存放路径,需提前创建好该目录

#创建Harbor数据目录和日志目录:[root@harbor ~]# mkdir -p /opt/harbor/data [root@harbor ~]# mkdir -p /opt/harbor/logs

安装docker-compose:

Docker Compose是 docker 提供的一个命令行工具,用来定义和运行由多个容器组成的应用。使用 compose,我们可以通过 YAML 文件声明式的定义应用程序的各个服务,并由单个命令完成应用的创建和启动。

[root@harbor ~]# yum install docker-compose -y

执行harbor脚本:

备注: 在部署harbor 厂库的时候,记得启用Harbor的Chart仓库服务(--with-chartmuseum),Helm 可以把打包好的chart 放入到harbor 中。

[root@harbor ~]# bash /opt/harbor/install.sh --with-chartmuseum安装输出过程省略........Creating registry ... doneCreating harbor-core ... done[Step 3]: starting Harbor ...Creating harbor-portal ... doneCreating nginx ... doneCreating harbor-db ... Creating registryctl ... Creating registry ... Creating redis ... Creating harbor-core ... Creating harbor-portal ... Creating harbor-jobservice ... Creating nginx ... ✔ ----Harbor has been installed and started successfully.----

当看到successfully 的时候 表示harbor 镜像仓库安装成功

docker-compose ps 可以看到正在运行的容器

[root@ansible harbor]# docker-compose ps Name Command State Ports --------------------------------------------------------------------------------------chartmuseum ./docker-entrypoint.sh Up harbor-core /harbor/entrypoint.sh Up harbor-db /docker-entrypoint.sh Up harbor-jobservice /harbor/entrypoint.sh Up harbor-log /bin/sh -c /usr/local/bin/ ... Up 127.0.0.1:1514->10514/tcpharbor-portal nginx -g daemon off; Up nginx nginx -g daemon off; Up 0.0.0.0:80->8080/tcp redis redis-server /etc/redis.conf Up registry /home/harbor/entrypoint.sh Up registryctl /home/harbor/start.sh Up

访问Harbor 的web 控制台

jenkins远程部署,jenkins和docker实现自动化构建部署

新建项目:

​ 项目名称: fxkj

​ 访问级别: 公开

jenkins远程部署,jenkins和docker实现自动化构建部署

可以看到 harbor 仓库中 fxkj 项目已经创建好了

jenkins远程部署,jenkins和docker实现自动化构建部署

2.2 部署Gitlab作为代码仓库

部署方式:

​ 官网上docker 的部署gitlab-ce的方式

[root@gitlab ~]# export GITLAB_HOME=/opt/gitlab[root@gitlab ~]# docker run --detach \ --publish 443:443 \ --publish 80:80 \ --publish 2222:22 \ --name gitlab \ --restart always \ --volume $GITLAB_HOME/config:/etc/gitlab \ --volume $GITLAB_HOME/logs:/var/log/gitlab \ --volume $GITLAB_HOME/data:/var/opt/gitlab \ gitlab/gitlab-ce:latest [root@gitlab ~]# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES5df8d498914a gitlab/gitlab-ce:latest "/assets/wrapper" 2 weeks ago Up 3 hours (unhealthy) 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp, 0.0.0.0:2222->22/tcp gitlab

打开浏览器,访问gitlab :

登陆后会提示让你修改密码

jenkins远程部署,jenkins和docker实现自动化构建部署

新建群组

jenkins远程部署,jenkins和docker实现自动化构建部署

输入 群组名称: fxkj

可见性级别: 私有(也就是群组及其项目只能由成员查看)

jenkins远程部署,jenkins和docker实现自动化构建部署

新建项目

jenkins远程部署,jenkins和docker实现自动化构建部署

创建空白项目

jenkins远程部署,jenkins和docker实现自动化构建部署

输入项目名称: app

可见性级别: 私有

jenkins远程部署,jenkins和docker实现自动化构建部署

可以看到一个新的空仓库就创建成功了

jenkins远程部署,jenkins和docker实现自动化构建部署

三、在 kubernetes 中部署 Jenkins3.1 在 Kubernetes 中部署jenkins

jenkins远程部署,jenkins和docker实现自动化构建部署

3.1.1 给jenkins创建动态PVC卷

使用NFS 作为后端的存储,使用动态PV 的自动供给 为Jenkins持久化数据。

部署NFS 服务( 192.168.31.100 主机上 )

# 创建 NFS 存储目录mkdir -p /home/cicd# 安装nfs服务yum -y install nfs-utils rpcbind# 修改配置文件echo "/home/cicd *(rw,sync,no_root_squash,no_subtree_check)" >> /etc/exports# 启动服务systemctl start nfs && systemctl start rpcbind# 设置开机启动systemctl enable nfs-server && systemctl enable rpcbind

K8S集群所有节点都要安装nfs-utils

yum -y install nfs-utils#记住,所有节点都要安装nfs-utils,否则无法使用pv

部署动态PV

创建NFS 动态PV专属命名空间

[root@master-1 ~]# kubectl create ns nfsnamespace/nfs created

使用Helm 部署nfs-client-provisioner

注意事项:(1)、nfs-client-provisioner部署到刚刚创建的nfs命名空间下(2)、storageClass.name #指定storageClassName名称,用于 PVC 自动绑定专属动态 PV 上(3)、需要指定NFS服务器的IP 地址(192.168.31.100),以及共享名称路径(/home/cicd)

#添加helm charts repo[root@master-1 ~]# helm repo add helm-stable https://charts.helm.sh/stable [root@master-1 ~]# helm repo updatecat > jenkins-client-nfs.yaml << EOF# NFS 设置nfs: server: 192.168.31.100 path: /home/cicdstorageClass: # 此配置用于绑定 PVC 和 PV name: jenkins-nfs-client # 资源回收策略#主要用于绑定的PVC删除后,资源释放后如何处理该PVC在存储设备上写入的数据。#Retain:保留,删除PVC后,PV保留数据;#Recycle:回收空间,删除PVC后,简单的清除文件;(NFS和HostPath存储支持)#Delete:删除,删除PVC后,与PV相连接的后端存储会删除数据;(AWS EBS、Azure Disk、Cinder volumes、GCE PD支持) reclaimPolicy: Retain# 使用镜像image: repository: kubesphere/nfs-client-provisioner# 副本数量replicaCount: 1EOF#helm 部署 nfs-client-provisioner[root@master-1 ~]# helm install jenkins-nfs-storage -n nfs --values jenkins-client-nfs.yaml helm-stable/nfs-client-provisioner --version 1.2.8

查看 nfs-client-provisioner Pod 运行状态,查看storageclass状态

[root@master-1 ~]# kubectl get pods -n nfsNAME READY STATUS RESTARTS AGEjenkins-nfs-storage-nfs-client-provisioner-6db6c5cb9-l7rm5 1/1 Running 0 12s[root@master-1 ~]# kubectl get storageclassNAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGEjenkins-nfs-client cluster.local/jenkins-nfs-storage-nfs-client-provisioner Retain Immediate true 15s

3.1.2 编写jenkins.yaml

yaml文件在https://github.com/fxkjnj/kubernetes/tree/main/jenkins-for_kubernetes/jenkins 目录下

[root@master-1 jenkins]# cat > jenkins.yml << EOFapiVersion: apps/v1kind: Deploymentmetadata: name: jenkins namespace: ops labels: name: jenkinsspec: replicas: 1 selector: matchLabels: name: jenkins template: metadata: name: jenkins labels: name: jenkins spec: serviceAccountName: jenkins containers: - name: jenkins image: jenkins/jenkins ports: - containerPort: 8080 - containerPort: 50000 resources: limits: cpu: 2 memory: 4Gi requests: cpu: 1 memory: 1Gi env: - name: LIMITS_MEMORY valueFrom: resourceFieldRef: resource: limits.memory divisor: 1Mi - name: JAVA_OPTS value: -Xmx$(LIMITS_MEMORY)m -XshowSettings:vm -Dhudson.slaves.NodeProvisioner.initialDelay=0 -Dhudson.slaves.NodeProvisioner.MARGIN=50 -Dhudson.slaves.NodeProvisioner.MARGIN0=0.85 volumeMounts: - name: jenkins-home mountPath: /var/jenkins_home securityContext: fsGroup: 1000 volumes: - name: jenkins-home persistentVolumeClaim: claimName: jenkins---apiVersion: v1kind: PersistentVolumeClaimmetadata: name: jenkins namespace: opsspec: storageClassName: "jenkins-nfs-client" accessModes: - ReadWriteMany resources: requests: storage: 10Gi---apiVersion: v1kind: Servicemetadata: name: jenkins namespace: opsspec: selector: name: jenkins type: NodePort ports: - name: http port: 80 targetPort: 8080 protocol: TCP nodePort: 30008 - name: agent port: 50000 protocol: TCP------apiVersion: v1kind: ServiceAccountmetadata: name: jenkins namespace: ops---kind: RoleapiVersion: rbac.authorization.k8s.io/v1metadata: name: jenkins namespace: opsrules:- apiGroups: [""] resources: ["pods","events"] verbs: ["create","delete","get","list","patch","update","watch"]- apiGroups: [""] resources: ["pods/exec"] verbs: ["create","delete","get","list","patch","update","watch"]- apiGroups: [""] resources: ["pods/log"] verbs: ["get","list","watch"]- apiGroups: [""] resources: ["secrets","events"] verbs: ["get"]---apiVersion: rbac.authorization.k8s.io/v1kind: RoleBindingmetadata: name: jenkins namespace: opsroleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: jenkinssubjects:- kind: ServiceAccount name: jenkinsEOF[root@master-1 jenkins]# kubectl apply -f jenkins.yaml[root@master-1 jenkins]# kubectl get pvc,pods,svc -n ops -o wideNAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE VOLUMEMODEpersistentvolumeclaim/jenkins Bound pvc-368e554e-343d-40d2-9bb1-28368582b652 5Gi RWX jenkins-nfs-client 8d FilesystemNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATESpod/jenkins-dccd449c7-nxfhk 1/1 Running 0 176m 10.244.1.252 node-2 <none> <none>NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTORservice/jenkins NodePort 10.0.0.180 <none> 80:30008/TCP,50000:30002/TCP 8d name=jenkins

3.1.3 访问jenkins控制台,初始化环境

访问地址:http://NodePort:30008

例如: http://192.168.31.61:30008

第一次部署会进行初始化:

查看密码,可以去查看jenkins 的启动日志

[root@master-1 jenkins]# kubectl logs -n ops jenkins-dccd449c7-nxfhk

jenkins远程部署,jenkins和docker实现自动化构建部署

部署插件这块,选择插件来安装

jenkins远程部署,jenkins和docker实现自动化构建部署

点击“无”,不安装任何插件

jenkins远程部署,jenkins和docker实现自动化构建部署

创建管理员账号

jenkins远程部署,jenkins和docker实现自动化构建部署

3.1.4 安装插件

默认从国外网络下载插件,会比较慢,建议修改成国内源:

只需要到nfs上,修改PVC挂载的内容即可

# 进入到nfs共享目录[root@nfs-server ~]# cd /home/cicd/ops-jenkins-pvc-368e554e-343d-40d2-9bb1-28368582b652[root@nfs-server ops-jenkins-pvc-368e554e-343d-40d2-9bb1-28368582b652]# cd updates#先备份好配置文件[root@nfs-server updates]# cp default.json default.json-bak#修改插件的下载地址为国内的地址sed -i 's/https:\/\/updates.jenkins.io\/download/https:\/\/mirrors.tuna.tsinghua.edu.cn\/jenkins/g'default.json#修改jenkins启动时检测的URL网址,改为国内baidu的地址sed -i 's/http:\/\/www.google.com/https:\/\/www.baidu.com/g' default.json

删除pod重建(pod名称改成你实际的)

[root@master-1 jenkins]# kubectl delete pod jenkins-dccd449c7-nxfhk -n ops

修改完后,jenkins 会重建,打开浏览器访问: http://NodePort:30008

输入账户密码从新登陆jenkins控制台

jenkins远程部署,jenkins和docker实现自动化构建部署

依次点击 管理Jenkins(Manage Jenkins)->系统配置(System Configuration)-->管理插件(Manage Pluglns)-->

jenkins远程部署,jenkins和docker实现自动化构建部署

分别搜索 Git/Git Parameter/Pipeline/kubernetes/Config File Provider,选中点击安装。

安装插件可能会失败,多试几次就好了,安装完记得重启Pod

插件名称

用途

Git

用于拉取代码

Git Parameter

用于Git参数化构建

Pipeline

用于流水线

kubernetes

用于连接Kubernetes动态创建Slave代理

Config File Provider

用于存储kubectl用于连接k8s集群的kubeconfig配置文件

jenkins远程部署,jenkins和docker实现自动化构建部署

3.2 jenkins在K8S中动态创建代理

jenkins远程部署,jenkins和docker实现自动化构建部署

jenkins远程部署,jenkins和docker实现自动化构建部署

3.2.1 在jenkins中添加kubernetes云

管理Jenkins->Manage Nodes and Clouds->configureClouds->Add

输入Kubernetes 地址: https://kubernetes.default ,点击连接测试,测试通过的话,会显示k8s的版本信息

输入Jenkins 地址: http://jenkins.ops

jenkins远程部署,jenkins和docker实现自动化构建部署

3.2.2 构建Jenkins-Slave镜像

PS: jenkins 官方有jenkins-slave 制作好的镜像,可以直接 docker pull jenkins/jnlp-slave 下载到本地并上传本地私有镜像厂库。官方的镜像好处就是不需要再单独安装maven,kubectl 这样的命令了,可以直接使用。

构建镜像所需要的文件:

#在https://github.com/fxkjnj/kubernetes/tree/main/jenkins-for_kubernetes/jenkins-slave 目录下

  • Dockerfile:构建镜像文件
  • jenkins-slave:shell脚本,用于启动slave.jar
  • settings.xml: 修改maven官方源为阿里云源
  • slave.jar:agent程序,接受master下发的任务(slave.jar jar 包文件 可以在jenkins 添加slave-node 节点,获取到 jar 包文件)

这里主要看下 Dockerfile 文件的内容:

[root@master-1 jenkins-slave]# cat > Dockerfile << EOFFROM centos:7LABEL fxkjnj.com fxkjRUN yum install -y java-1.8.0-openjdk maven curl git libtool-ltdl-devel && \ yum clean all && \ rm -rf /var/cache/yummaster']], extensions: [], userRemoteConfigs: [[credentialsId: 'bcf76dc6-d1d0-4611-a50c-e462eede257a', url: 'http://192.168.31.200/fxkj/app.git']]])

4.2 编译代码 mvn clean

在上面构建Jenkins-Slave镜像的时候,我们已经在镜像里安装了maven 编译代码的软件

只需要代码的路径下执行一条命令即可

mvn clean package -Dmaven.skip.test=true

4.3 docker 打包镜像 并上传镜像仓库4.3.1 编写dockerfile,创建 一个标准的tomcat8 基础镜像

当然如果不想自己制作镜像,也可以使用我制作好的tomcat8 镜像 docker pull feixiangkeji974907/tomcat-test:v8

创建软件目录,下载tomcat8, jdk1.8

[root@master-1 tmp]# mkdir app-tomcat-filebeat-log

[root@master-1 tmp]# cd app-tomcat-filebeat-log[root@master-1 app-tomcat-filebeat-log]# wget http://jpg.fxkjnj.com/ruanjian/apache-tomcat-8.5.39.tar.gz[root@master-1 app-tomcat-filebeat-log]# wget http://jpg.fxkjnj.com/ruanjian/jdk1.8.0_66.tar.gz

编写dockerfile

cat > Dockerfile << EOFFROM centosMAINTAINER fxkjnj.com fxkjEXPOSE 8080WORKDIR /opt#ADD jdk1.8 COPY jdk1.8.0_66.tar.gz /opt RUN tar zxf /opt/jdk1.8.0_66.tar.gz -C /usr/local/ && rm -rf /opt/jdk1.8.0_66.tar.gz RUN ln -s /usr/local/jdk1.8.0_66 /usr/local/jdk#环境变量/etc/profile ENV JAVA_HOME /usr/local/jdk ENV CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ENV PATH $PATH:$JAVA_HOME/bin#ADD tomcat8 COPY apache-tomcat-8.5.39.tar.gz /opt RUN tar zxf apache-tomcat-8.5.39.tar.gz -C /usr/local && rm -rf apache-tomcat-8.5.39.tar.gz RUN mv /usr/local/apache-tomcat-8.5.39 /usr/local/tomcat#CMDENTRYPOINT /usr/local/tomcat/bin/startup.sh && tail -f /usr/local/tomcat/logs/catalina.outEOF

构建镜像

[root@master-1 app-tomcat-filebeat-log]# docker build -t 192.168.31.100/library/tomcat8:latest .Sending build context to Docker daemon 191.2MBStep 1/14 : FROM centoslatest: Pulling from library/centos7a0437f04f83: Pull complete Digest: sha256:5528e8b1b1719d34604c87e11dcd1c0a20bedf46e83b5632cdeac91b8c04efc1Status: Downloaded newer image for centos:latest ---> 300e315adb2fStep 2/14 : MAINTAINER fxkjnj.com fxkj ---> Running in c6960bcfe61fRemoving intermediate container c6960bcfe61f ---> 4d90c5f058e4Step 3/14 : EXPOSE 8080 ---> Running in 4b74564852a6Removing intermediate container 4b74564852a6 ---> 1d513bed4b8aStep 4/14 : WORKDIR /opt ---> Running in ba66ad1e1f2bRemoving intermediate container ba66ad1e1f2b ---> af3d2848cd2aStep 5/14 : COPY jdk1.8.0_66.tar.gz /opt ---> 5407bdfd840eStep 6/14 : RUN tar zxf /opt/jdk1.8.0_66.tar.gz -C /usr/local/ && rm -rf /opt/jdk1.8.0_66.tar.gz ---> Running in 969ef89b2a29Removing intermediate container 969ef89b2a29 ---> 84717736fc66Step 7/14 : RUN ln -s /usr/local/jdk1.8.0_66 /usr/local/jdk ---> Running in 3e2a24de56fdRemoving intermediate container 3e2a24de56fd ---> 807c98672e7fStep 8/14 : ENV JAVA_HOME /usr/local/jdk ---> Running in c1f21968d26cRemoving intermediate container c1f21968d26c ---> a24e93067d43Step 9/14 : ENV CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ---> Running in 1bc184124271Removing intermediate container 1bc184124271 ---> 50e6aa9d66f9Step 10/14 : ENV PATH $PATH:$JAVA_HOME/bin ---> Running in 104d6ee96bfbRemoving intermediate container 104d6ee96bfb ---> 7ff4d81f456cStep 11/14 : COPY apache-tomcat-8.5.39.tar.gz /opt ---> 4815155b0c9fStep 12/14 : RUN tar zxf apache-tomcat-8.5.39.tar.gz -C /usr/local && rm -rf /opt/apache-tomcat-8.5.39.zip ---> Running in b5d13adfbf93Removing intermediate container b5d13adfbf93 ---> 49413a5efaedStep 13/14 : RUN mv /usr/local/apache-tomcat-8.5.39 /usr/local/tomcat ---> Running in a2ea891bb8b2Removing intermediate container a2ea891bb8b2 ---> 6c71db7365e9Step 14/14 : ENTRYPOINT /usr/local/tomcat/bin/startup.sh && tail -f /usr/local/tomcat/logs/catalina.out ---> Running in f01fa6926b74Removing intermediate container f01fa6926b74 ---> 0686065360e3Successfully built 0686065360e3Successfully tagged feixiangkeji974907/tomcat-test:v8

测试下镜像,启动容器

[root@master-1 app-tomcat-filebeat-log]# docker run --name tomcat -itd -p 80:8080 192.168.31.100/library/tomcat8:latest

访问tomcat: http://192.168.31.61 可以看到首页效果

jenkins远程部署,jenkins和docker实现自动化构建部署

4.3.2 制作项目镜像,上传镜像至Harbor仓库

有了上面的tomcat8 基础镜像,我们 就可以把打包好的war 包直接放入到基础镜像中,打包生成项目镜像

注意: Dockerfile 文件必须和 项目的代码 在同一个路径下(否则无法把打包好的war 包放入镜像中)

Dockerfile 文件在 https://github.com/fxkjnj/kubernetes/tree/main/jenkins-for_kubernetes/app 目录下

编写Dockerfile

cat > Dockerfile << EOFFROM 192.168.31.100/library/tomcat8:latestLABEL fxkjnj fxkjnj.comRUN rm -rf /usr/local/tomcat/webapps/*ADD target/*.war /usr/local/tomcat/webapps/ROOT.war

构建镜像 : docker build -t ${image_name} . 登陆Harbor仓库: docker login -u ${username} -p '${password}' ${registry} 上次镜像至仓库: docker push ${image_name}

变量解释:

${image_name} 表示构建后的镜像名称(这里的镜像名称的标签名,每次都是不一样的,BUILD_NUMBER 为 jenkins 内置变量,jenkins 构建编号)

${username} 表示登陆Harbor的用户名

${password} 表示登陆Harbor的密码

${registry} 表示Harbor镜像仓库地址

在Jenkins pipeline中,有时需要带用户名密码执行命令,如docker login,将用户名密码以明文方式放到pipeline中显然是不安全的。这时可以通过credential插件实现。下面介绍具体方法:

第一步 安装Jenkins插件 在Jenkins中安装 ‘Credentials Plugin’插件

jenkins远程部署,jenkins和docker实现自动化构建部署

第二步 在凭证中配置docker 连接harbor 的用户名密码, 用于docker 从Harbor 镜像仓库中 上传,下载 镜像

Manage Jenkins -> Manage Credentials -> 全局凭据 (unrestricted) -> Add Credentials

jenkins远程部署,jenkins和docker实现自动化构建部署

选择Kind 类型 为 username with passwd

输入账户名,密码

添加一个描述信息

jenkins远程部署,jenkins和docker实现自动化构建部署

第三步 pipeline中引用示例

steps { withCredentials([usernamePassword(credentialsId: "${docker_registry_auth}", passwordVariable: 'password', usernameVariable: 'username')]) { sh """ docker build -t ${image_name} . docker login -u ${username} -p '${password}' ${registry} docker push ${image_name} """ } }

4.4 创建kubeconfig 文件,编写deploy.yaml pod模板文件

在上面构建Jenkins-Slave镜像的时候,我们已经在镜像里安装了kubectl 命令,只需要再添加一个kubeconfig 文件去连接K8S 集群,创建标准的 deployment.yaml ,servies.yaml 文件 就可以使用 kubectl apply XXX.yaml 文件从而生成pod

4.4.1 第一步: 授权创建kubeconfig 文件,并保存在jenkins 中

#准备好创建K8S 集群的那一套 ca证书

[root@node1 ssl]# ls ca*ca-config.json ca.csr ca-csr.json ca-key.pem ca.pem

#创建生成请求证书文件

[root@node1 ssl]# vim admin-csr.json{"CN": "admin","hosts": [],"key": {"algo": "rsa","size": 2048},"names": [{"C": "CN","L": "BeiJing","ST": "BeiJing","O": "system:masters","OU": "System"}]}

注意:"O": "system:masters" 指定该证书的 Group 为 system:masters,kubelet 使用该证书访问 kube-apiserver 时 ,由于证书被 CA 签名,所以认证通过,同时由于证书用户组为经过预授权的 system:masters,所以被授予访问所有 API 的权限;

注:这个admin 证书,是将来生成管理员用的kube config 配置文件用的,现在我们一般建议使用RBAC 来对kubernetes 进行角色权限控制, kubernetes 将证书中的CN 字段 作为User, O 字段作为 Group

#生成证书

ps: 安装生成证书的工具

[root@node1 ~ ]# curl -L https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -o /usr/local/bin/cfssl[root@node1 ~ ]# curl -L https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -o /usr/local/bin/cfssljson[root@node1 ~ ]# curl -L https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 -o /usr/local/bin/cfssl-certinfo[root@node1 ~ ]# chmod x /usr/local/bin/cfssl*

签发证书:

[root@node1 ssl]# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes admin-csr.json | cfssljson -bare admin2020/07/23 12:06:24 [INFO] generate received request2020/07/23 12:06:24 [INFO] received CSR2020/07/23 12:06:24 [INFO] generating key: rsa-20482020/07/23 12:06:24 [INFO] encoded CSR2020/07/23 12:06:24 [INFO] signed certificate with serial number 3468344386879568837503564255673910014857578647492020/07/23 12:06:24 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable forwebsites. For more information see the Baseline Requirements for the Issuance and Managementof Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);specifically, section 10.2.3 ("Information Requirements").

查看生成的证书:

[root@node1 ssl]# ls admin*admin.csr admin-csr.json admin-key.pem admin.pem

生成kubeconfig授权文件:

[root@node1 ssl]# kubectl config set-cluster kubernetes --certificate-authority=ca.pem --embed-certs=true --server=https://192.168.31.61:6443#设置用户项中cluster-admin用户证书认证字段[root@node1 ssl]# kubectl config set-credentials cluster-admin --client-key=admin-key.pem --client-certificate=admin.pem --embed-certs=true#设置默认上下文[root@node1 ssl]# kubectl config set-context kubernetes --cluster=kubernetes --user=cluster-admin#设置当前环境的default[root@node1 ssl]# kubectl config use-context kubernetes

查看生成的config文件

[root@node1 ssl]# cat /root/.kube/config apiVersion: v1clusters:- cluster: certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUR2akNDQXFhZ0F3SUJBZ0lVVWhMMFhHZ2pLV3FkcVl3cndJUU51UEZZNDlJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd1pURUxNQWtHQTFVRUJoTUNRMDR4RURBT0JnTlZCQWdUQjBKbGFXcHBibWN4RURBT0JnTlZCQWNUQjBKbAphV3BwYm1jeEREQUtCZ05WQkFvVEEyczRjekVQTUEwR0ExVUVDeE1HVTNsemRHVnRNUk13RVFZRFZRUURFd3ByCmRXSmxjbTVsZEdWek1CNFhEVEl4TURNd05URXlOREV3TUZvWERUSTJNRE13TkRFeU5ERXdNRm93WlRFTE1Ba0cKQTFVRUJoTUNRMDR4RURBT0JnTlZCQWdUQjBKbGFXcHBibWN4RURBT0JnTlZCQWNUQjBKbGFXcHBibWN4RERBSwpCZ05WQkFvVEEyczRjekVQTUEwR0ExVUVDeE1HVTNsemRHVnRNUk13RVFZRFZRUURFd3ByZFdKbGNtNWxkR1Z6Ck1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBNUEvY3RMb2JIMHpuMHpsbXhBUmEKTDhsaDh6ZERsNCtBb1p2RE1pemJjMVpmYm9iUXJpalN6QzQzZ085MnNHTmhUMjVpb2tmakJBZExTYlR3emd4TgpMUTVockUrcXN6bGFXMWtMbTdpRGRGYlBLVTlGbC9VeFhBczRwOFdXZzNpUEYyM0ZNamFsbzh2MGNHTTBieFJoCmNnVlRQZjEyK3c1MGVBRS9RSnNlY3phMElyUzZnUGpVMDRxMG5jT0pENFZsRFJaU3grVUpTZ3M5aTBIZjlvRXAKWWQyTElXUzg2QWExcEg3ODVYS3Q5YkJlWjdReGxKVzN6WVlxMytORTU1eFFQdmxNNkVDbGZWeTJUcnlETTAwZQpkZXZ2eFFHOTVibHhta0c5ak9xWHhVZEN1YWpXbnRqOWZYRGNiMUdOZnF1cWhjaHlRa2dpQ05uMGpiRnVSeDdSCnB3SURBUUFCbzJZd1pEQU9CZ05WSFE4QkFmOEVCQU1DQVFZd0VnWURWUjBUQVFIL0JBZ3dCZ0VCL3dJQkFqQWQKQmdOVkhRNEVGZ1FVSGNBSTQvQm92QWp1dktiOW84UHFjM2JHR0tFd0h3WURWUjBqQkJnd0ZvQVVIY0FJNC9Cbwp2QWp1dktiOW84UHFjM2JHR0tFd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFBbmhRRVQrUnF6NFJpc2lHYm5rCjVPakl3aXh2TzJlQTc2Y3Y5SXl1OVp6TFZ6d29aK0xaWUduVGJTWVVIVzQ3elhrQWxMMUNSTVpwVDVjd3YzTXEKZjVYdFFuT2FnbnllcmFpdytXT3JNQXF2OVlyZ0lqdDhtTXFkU1o2YjhFUm1jblZaQ1BOd241THZHN1B4MkhURApYb1M0cjBIMllrc1RWR0dWZE9LZVdKMlFjVzlwYTFQbDRBZXFpN2xnY2JTUGVzcFJSbkJscXFvelJXb1Jma3VtCmdQSnZhS1VqWEdvNWc0eGYralM3YklITzJCQ0cyQzhDay9tanJkMS8zQzN2UW1wN1ZHTjQvU21ESzFkc0U2RlQKcXlrVHR5TXVOZDBZaXF4Q0JqNzZXbXpLZTJubXh3ZkhHOUZXK2gwMkI2MG8zSGVXRlFCRG54TUhDTEFVTjJKago1NzA9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K server: https://192.168.31.61:6443 name: kubernetescontexts:- context: cluster: kubernetes user: cluster-admin name: kubernetescurrent-context: kuberneteskind: Configpreferences: {}users:- name: cluster-admin user: client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUQzVENDQXNXZ0F3SUJBZ0lVVEl4cU96NUhWNnNUNHpxZXdIb1ljODVZOFowd0RRWUpLb1pJaHZjTkFRRUwKQlFBd1pURUxNQWtHQTFVRUJoTUNRMDR4RURBTgvdfgfsKbGFXcHBibWN4RURBT0JnTlZCQWNUQjBKbAphV3BwYm1jeEREQUtCZ05WQkFvVEEyczRjekVQTUEwR0ExVUVDeE1HVTNsemRHVnRNUk13RVFZRFZRUURFd3ByCmRXSmxjbTVsZEdWek1CNFhEVEl4TURNeU16QXhNakV3TUZvWERUTXhNRE15TVRBeE1qRXdNRm93YXpFTE1Ba0cKQTFVRUJoTUNRMDR4RURBT0JnTlZCQWdUQjBKbGFVcHBibWN4RURBT0JnTlZCQWNUQjBKbGFVcHBibWN4RnpBVgpCZ05WQkFvVERuTjVjM1JsYlRwdFlYTjBaWEp6TVE4d0RRWURWUVFMRXdaVGVYTjBaVzB4RGpBTUJnTlZCQU1UCkJXRmtiV2x1TUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUF4RWVKbjc0fdsgfsdd1pQTSsya3lIOSt3dUFmS2R1K2U5VTg2cjg3YWZoK2hZYnUrM2gzOVlBUk56N1RNMSt5Mzh6MCt6bAp3bXEzMGNRYU9lR1lRNTB4eFZFWnpIZDhqSE5lWjY2eEsrVmpmd1BhUHhUNkQ0NS90VGJBeE8yY0gfdsgsdfvcjA0ODFKRmR5OXRzbW5ic3BWWnRVNlV3bVJlUXNwVlRud1RDeTNFRjIzL2ZDbEFZaFZSMUMKcHZidzFtL3dIV0ZGT3lieVB0dkhERC96K2l3dUNsRmQzQ1RWTnB2QTkxRm05b0FFVkUvNWpzRXQxVjAzUCttSgpJTkZvbE5kc3dBaHNNa1MzNjNTbHFndXB3bmhQemVwVUFoTWVuenkxeXZlakR1elRoS1VscThyUi83cWg4OFRDCjQvZm1McW5MZ3dJREFRQUJvMzh3ZlRBT0JnTlZIUThCQWY4RUJBTUNCYUF3SFFZRFZSMGxCQll3RkFZSUt3WUIKQlFVvfs0FDT1B3YUx3STdyeW0vYVBENm5OMnhoaWhNQTBHCkNTcUdTSWIzRFerrrcjViTHFkM0FCU3Iwa29LMGFScWxTRQptR0Iyb2xKMkV5Qlhmc20wNUR4d2VRUGY3Z3A3aDMzbHRLcVVHQ0tId2ZBQXR2R1NYNnFLK0VzaHRYT3ZBa3p5ClZzZHY1TjZPV3ZManI5ZHRVSzV1b08zZlRKb0RPVVk2bnYrZElOOVVyNlpFRmlQbmVHWWE4bUV2MHhYcnpVZTMKRFRST0oxN1JtQlRISWpsQmZaQjdnNExmbVVnUmk3NERMZWtzcFhkS3ZrZ2lyZzR3dVJ6cSswb2h6ZWxZTUY3Rgp3U09ya1QzcVVObmlRZmRnTUxtSXA5Wk4rT0srdGFBaVYwN0d6ZTd1WGdiVAotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcEFJQkFBS0NBUUVBeEVlSm43NHc2WXdWZWtrT1B3d1pQTSsya3lIOSt3dUFmS2R1K2U5VTg2cjg3YWZoCitoWWJ1KzNoMzlZQVJOejdUTTEreTM4ejAremx3bXEzMGNRYU9lR1lRNTB4eFZFWnpIZDhqSE5lWjY2eEsrVmoKZndQYVB4VDZENDUvdFRiQXhPMmNOYVRuRUVvWlRyQ2s2ck9nOUxFcjA0ODFKRmR5OXRzbW5ic3BWWnRVNlV3bQpSZVFzcFZUbndUQ3kzRUYyMy9mQ2xBWWhWUjFDcHZidzFtL3dIV0ZGT3lieVB0dkhERC96K2l3dUNsRmQzQ1RWCk5wdkE5MUZtOW9BRVZFLzVqc0V0MVYwM1ArbUpJTkZvbE5kc3dBaHNNa1MzNjNTbHFndXB3bmhQemVwVUFoTWUKbnp5MXl2ZWpEdXpUaEtVbHE4clIvN3FoODhUQzQvZm1McW5MZ3dJREFRQUJBb0lCQUNtWXc1amdGTHVhSFg4aAo5bXYwSTNFWTBDZVVYNkFSaXZSZ0E0dmgfdgdfgdfgvp4T1NGZVNaQUhLUWh0UVJSUXk4ekM5U1VPaUwzeEY1CnptVWRPeldqRXNMWmtJK3hwVmNJeDVONGE3eHJjRTdPT1d6VW95OFZRZjJFQkpxaDlPNkhNTURKcHRKejhiTVUKaW83VzdMaU94NnY1UUpqb0U0d3ZXNXEzN0lXZ202bkVjSitKSnJhaHJlZHM2Q0dQWmVYRExnRXRUTFVJTWRqQwpoTWdXeTNMQy9vUm1oZ2tOZndsTjc0YmlwaVY3SklNelRlYm9nQmlTUE10d3liVDgwUWFVMDBwVEdKYlpod29YCmp3OUVtcWN3MlB2ZTVYM0pCcDdlSEtoTHQxZDArb09GUDZVUFZjZVBMNk1YSDVkckxTcU9Cdmd3U2U3cDlvUGwKLzZrZXZMa0NnWUVBNTJqNWpLTU1rM3lYK292N3p1dGg1ZFR1a3BMYm5RQ2M5QnlReFFXa0RMOHdOSEc1SE1jegpiZnh3SkI4UTZ5QUs2dVpYeTk3elNlSy85K2VNNSsyRFQ5L0xPdHhxRkZRbG80K1V2ZXlycFBWZG5hYkRxSU5MCldpc2NhY1l1Q3dPZzFBei9QTTBTQXk2RzZCWE9EVk0za2E2QllyUHp1TDQwenpTSitYQTZPSGNDZ1lFQTJTTG8KZXhPWUR5Q0NtU3pTMTFNdDFwVmlTcGhiWWNPbHB1ZGMxYXdmOXVDRDMrOWwzUDdUdDJaUUhvSUZxSjZrMjJ6eQpvclcreVRyVGxEa1MraFhwTFRsbnRuNnFiS0dGQW1JaDhBbWdYUVVNMHY0QlNLNDJGRUh1R1BVdjNOQWJEVmJBCm4xVGl4NUh2VVJPNHh6Y2IvT2lRM2ZBOVdoQlFQbFk2YW5jaVZGVUNnWUE2RG5JZFFJTFZOYnNEVnI5VUNHWEYKUFlpbEtVY0R1cldsNE16SlFVTUpGNlpHWWdtcEdLamtmU0s5VFRYM1oxQ1Y0amhBbzZ5eDZydHl2SnJ6VFBsVwp2clRFRGF4bmNUMElMZXVKUXFsRmQzR0hMZUdFazN3Q0lUSzlyc1M2YXF5Y3hxMzZXUkNkejd4MDJaT2FjRGhPCnlsTVhxa0lKSlY4bVpPNEFzSkZLdlFLQmdRQ3BWeDhtTlY3R2xWMGs1cDg4VE9PWDBZTUptQTdValFmWXhlRlIKeHQ1YTVEZ1U0aGg0Sk1pcTVJRWhlZGU5N0pPM2lSMGxwa1kzbThnOGRkS0Y5YWFYblloei9BOGZqMHd6VXFNVApGLzdYN01OV25jQVVsY0VaUlYzU1d3M0wwUVQzL3l0VVY1aFJlay9BMUhlcjdoL0d1djJZQ085Z0dRN3J2c1hxCkdDVk96UUtCZ1FEY3ZzS1pwT3UrcWdTK2V0UXdXdXlDbXFTNFE4ZXkybGN1emVZK2Z1Sk9DK3lLN3kzYSt5RUMKLzk2OHBtMDlGNVQ4SjJKeWFzSjh2TFUxdTh3VnJUeWhscktFL21wQjRKZWd2RDVYMW9Mb0ZaLzVKbVlSeDJKVQpKOTgwcVVvcHc4MTF6Z3Baamh3MzRyMEhqMzZNemozQVRSaTkyRmpPU1VTWWtVVHpORGpyVmc9PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=

使用--kubeconfig= 指定生成的config文件路径,测试连接K8S集群

[root@node1 ssl]# kubectl --kubeconfig=/root/.kube/config get nodesNAME STATUS ROLES AGE VERSIONnode1 Ready <none> 19d v1.16.0node2 Ready <none> 19d v1.16.0node3 Ready <none> 9d v1.16.0

4.4.2 第二步:把生成的kubeconfig配置文件存放在jenkins 中

存储kubectl用于连接k8s集群的kubeconfig配置文件,需要安装 Config File Provider 这个插件, 上面在部署jenkins 环境初始化的时候,已经安装好了该插件

Manage Jenkins -> Managed files -> Add a new Config -> Custom file(自定义文件)

jenkins远程部署,jenkins和docker实现自动化构建部署

jenkins远程部署,jenkins和docker实现自动化构建部署

选择类型 为 Custom file(自定义文件)

jenkins远程部署,jenkins和docker实现自动化构建部署

输入 Name: k8s-kubeconfig

把生成的kubeconfig 文件内容 复制到 Content 文本框中

jenkins远程部署,jenkins和docker实现自动化构建部署

可以在Managed files 中看到这一个配置文件

jenkins远程部署,jenkins和docker实现自动化构建部署

4.4.3 第三步:把Managed files 中的配置文件 转换成pipeline 语法

同样适用 jenkins 官方提供一个pipeline 语法的生成器

任意创建一个流水线项目

jenkins远程部署,jenkins和docker实现自动化构建部署

在pipeline 选项那里点击 , pipeline Syntax

jenkins远程部署,jenkins和docker实现自动化构建部署

点击片段生成器,Sample Step 下拉选项框中 选择 configFileProvider: Provide Configuration files

在File 下拉选项框中,选中 刚刚创建的 自定义文件 k8s-kubeconfig

在Target 中 输入 admin.kubeconfig (target 表示把 自定义的文件 挂载到 jenkin-slave 镜像的什么路径下,这边定义了文件名称,就相当于把 admin.kubeconfig 文件 放在 jenkin-slave 镜像 的默认工作路径下/home/jenkins/agent/workspace/XX 下面 )

最后点击 Generate Pipeline Script 生产pipeline 语法

jenkins远程部署,jenkins和docker实现自动化构建部署

pipeline 生成的示例如下:

configFileProvider([configFile(fileId: '15ce8016-40d1-4b91-867d-e2c4c947741f', targetLocation: 'admin.kubeconfig')]) {}

4.4.4 第四步:编写标准的deploy.yaml 模板

本项目是 使用Jenkins在Kubernetes中持续部署一个无状态的tomcat pod 应用;涉及到 deployment 控制器 以及采用NodePort 的方式去 访问pod

deployment.yaml 和 service.yaml 我把他合并在一个deploy.yaml 文件中

另外deploy.yaml 文件 必须和 项目的代码 在同一个路径下(否则kubectl 无法指定yaml 文件就 无法创建pod)

deploy.yaml 文件在 https://github.com/fxkjnj/kubernetes/tree/main/jenkins-for_kubernetes/app 目录下

[root@master-1 app]# cat > deploy.yaml << EOFapiVersion: apps/v1kind: Deploymentmetadata: name: java-demospec: replicas: REPLICAS selector: matchLabels: project: www app: java-demo template: metadata: labels: project: www app: java-demo spec: imagePullSecrets: - name: SECRET_NAME containers: - image: IMAGE_NAME name: java-demo resources: requests: cpu: 0.5 memory: 500Mi limits: cpu: 1 memory: 1Gi livenessProbe: httpGet: path: / port: 8080 initialDelaySeconds: 50 periodSeconds: 10 readinessProbe: httpGet: path: / port: 8080 initialDelaySeconds: 50 periodSeconds: 10---apiVersion: v1kind: Servicemetadata: name: java-demo spec: selector: project: www app: java-demo type: NodePort ports: - protocol: TCP port: 80 targetPort: 8080EOF

4.5 其他4.5.1 在K8S 集群中创建sercret 用于连接Harbor仓库(用于K8S创建POD时 拉取镜像)

备注:

应用启动过程中可能需要一些敏感信息,比如访问数据库的用户名密码或者秘钥。将这些信息直接保存在容器镜像中显然不妥,Kubernetes 提供的解决方案是 Secret。

Secret 会以密文的方式存储数据,避免了直接在配置文件中保存敏感信息。Secret 会以 Volume 的形式被 mount 到 Pod,容器可通过文件的方式使用 Secret 中的敏感数据;此外,容器也可以环境变量的方式使用这些数据。

找一台登陆过的Harbor 的 node 的节点,查看 cat ~/.docker/config.json 问价里的内容

[root@node-1 ~]# cat ~/.docker/config.json{"auths": {"192.168.31.100": {"auth": "YWRtaW46SGFyYm9yMTIzNDU="}},"HttpHeaders": {"User-Agent": "Docker-Client/19.03.9 (linux)"}

使用 base64 对 ~/.docker/config.json 文件 进行编码

[root@node-1 ~]# cat ~/.docker/config.json | base64ewoJImF1dGhzIjogewoJCSIxOTIuMTY4LjMxLjEwMCI6IHsKCQkJImF1dGgiOiAiWVdSdGFXNDZTR0Z5WW05eU1USXpORFU9IggfX0KCXgfgfdiSHR0cEhlYWRlcnMiOiB7CgkJIlVzZXItQWdlbnQiOiAiRG9ja2VyLUNsaWVudC8xOS4wMy45IChsaW51eCkiCgl9Cn0=

创建secret yaml文件

#注意base64 的结果要写成一行[root@manager ~]# vim registry-pull-secret.yaml apiVersion: v1kind: Secretmetadata: name: registry-pull-secretdata:.dockerconfigjson:ewoJImF1dGhzIjogewoJCSIxOTIuMTY4LjMxLjEwMCI6IHsKCQkJImF1dGgiOiAiWVdSdGFXNDZTR0Z5WW05eU1USXpORFU9IggfX0KCXgfgfdiSHR0cEhlYWRlcnMiOiB7CgkJIlVzZXItQWdlbnQiOiAiRG9ja2VyLUNsaWVudC8xOS4wMy45IChsaW51eCkiCgl9Cn0=type: kubernetes.io/dockerconfigjson

在 指定的 ns 命名空间下 执行 kubectl apply 创建 Secret:

[root@master-1 .docker]# for i in {prod,dev}> do> kubectl apply -f registry-pull-secret.yaml -n ${i}> donesecret/registry-pull-secret createdsecret/registry-pull-secret created

# 查看存在的 secret

[root@manager ~]# kubectl get secret -n prodNAME TYPE DATA AGEregistry-pull-secret kubernetes.io/dockerconfigjson 1 77s[root@manager ~]# kubectl get secret -n devNAME TYPE DATA AGEregistry-pull-secret kubernetes.io/dockerconfigjson 1 77s

4.5.2定义环境变量,使用参数化构建,修改deploy.yaml文件

需要提前定义好的环境变量:

//定义harbor的地址def registry = "192.168.31.100"// 项目,BUILD_NUMBER jenkins 内置变量,jenkins 构建编号def project = "fxkj"def app_name = "app"def image_name = "${registry}/${project}/${app_name}:${BUILD_NUMBER}"def git_address = "http://192.168.31.200/fxkj/app.git"// 认证//k8s 连接harbor 证书def secret_name = "registry-pull-secret"//jenkins中定义docker连接harbor的用户密码凭证def docker_registry_auth = "fe46d806-6a47-42bd-88ea-24403d97afb5"//jenkins中定义git连接gitlab的用户密码凭证def git_auth = "bcf76dc6-d1d0-4611-a50c-e462eede257a"//jenkins中Config File Provider插件 定义的kubeconfig 文件内容def k8s_auth = "15ce8016-40d1-4b91-867d-e2c4c947741f"

参数化构建过程中,需要交互的内容:

发布分支(prod,dev)副本数(1,3,5,7)命名空间(prod,dev)

一个标准的deploy.yaml模板文件,需要把修改的内容:

#修改deploy.yaml 中镜像名称sed -i 's#IMAGE_NAME#${image_name}#' deploy.yaml#修改deploy.yaml 中k8s连接harbor连接的secretsed -i 's#SECRET_NAME#${secret_name}#' deploy.yaml#修改deploy.yaml 中副本的数量sed -i 's#REPLICAS#${ReplicaCount}#' deploy.yaml#指定pod 创建在哪个命名空间下kubectl apply -f deploy.yaml -n ${Namespace} --kubeconfig=admin.kubeconfig

pipeline中引用示例:

//参数化构建parameters { gitParameter branch: '', branchFilter: '.*', defaultValue: 'master', description: '选择发布的分支', name: 'Branch', quickFilterEnabled: false, selectedValue: 'NONE', sortMode: 'NONE', tagFilter: '*', type: 'PT_BRANCH' choice (choices: ['1', '3', '5', '7'], description: '副本数', name: 'ReplicaCount') choice (choices: ['prod','dev'], description: '命名空间', name: 'Namespace') } //部署pod需要修改的内容sh """sed -i 's#IMAGE_NAME#${image_name}#' deploy.yamlsed -i 's#SECRET_NAME#${secret_name}#' deploy.yamlsed -i 's#REPLICAS#${ReplicaCount}#' deploy.yamlkubectl apply -f deploy.yaml -n ${Namespace} --kubeconfig=admin.kubeconfig """

4.6 完整的pipeline 流水线 脚本

// 公共def registry = "192.168.31.100"// 项目,BUILD_NUMBER jenkins 内置变量,jenkins 构建编号def project = "fxkj"def app_name = "app"def image_name = "${registry}/${project}/${app_name}:${BUILD_NUMBER}"def git_address = "http://192.168.31.200/fxkj/app.git"// 认证//k8s 连接harbor 证书def secret_name = "registry-pull-secret"//jenkins中定义docker连接harbor的用户密码凭证def docker_registry_auth = "fe46d806-6a47-42bd-88ea-24403d97afb5"//jenkins中定义git连接gitlab的用户密码凭证def git_auth = "bcf76dc6-d1d0-4611-a50c-e462eede257a"//jenkins中Config File Provider插件 定义的kubeconfig 文件内容def k8s_auth = "15ce8016-40d1-4b91-867d-e2c4c947741f"pipeline { agent { kubernetes { yaml '''apiVersion: v1 kind: Podmetadata: name: jenkins-slavespec: containers: - name: jnlp image: 192.168.31.100/library/jenkins-slave-jdk:1.8 imagePullPolicy: Always volumeMounts: - name: docker-cmd mountPath: /usr/bin/docker - name: docker-sock mountPath: /var/run/docker.sock - name: maven-cache mountPath: /root/.m2 volumes: - name: docker-cmd hostPath: path: /usr/bin/docker - name: docker-sock hostPath: path: /var/run/docker.sock - name: maven-cache persistentVolumeClaim: claimName: mavencache''' } } parameters { gitParameter branch: '', branchFilter: '.*', defaultValue: 'master', description: '选择发布的分支', name: 'Branch', quickFilterEnabled: false, selectedValue: 'NONE', sortMode: 'NONE', tagFilter: '*', type: 'PT_BRANCH' choice (choices: ['1', '3', '5', '7'], description: '副本数', name: 'ReplicaCount') choice (choices: ['prod','dev'], description: '命名空间', name: 'Namespace') } stages {stage('拉取代码'){ steps { checkout([$class: 'GitSCM', branches: [[name: "${params.Branch}"]], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_address}"]] ]) } } stage('代码编译') { steps { sh 'mvn clean package -Dmaven.skip.test=true' sh 'ls -l target/' sh 'pwd' } } stage('构建镜像并推送仓库') { steps { withCredentials([usernamePassword(credentialsId: "${docker_registry_auth}", passwordVariable: 'password', usernameVariable: 'username')]) { sh """ docker build -t ${image_name} . docker login -u ${username} -p '${password}' ${registry} docker push ${image_name} """ } } } stage('部署到K8S平台'){ steps { configFileProvider([configFile(fileId: "${k8s_auth}", targetLocation: "admin.kubeconfig")]){ sh """ sed -i 's#IMAGE_NAME#${image_name}#' deploy.yaml sed -i 's#SECRET_NAME#${secret_name}#' deploy.yaml sed -i 's#REPLICAS#${ReplicaCount}#' deploy.yaml kubectl apply -f deploy.yaml -n ${Namespace} --kubeconfig=admin.kubeconfig sleep 120 kubectl get pods,svc -n ${Namespace} --kubeconfig=admin.kubeconfig """ } } } }}

jenkins 流水线构建截图:

jenkins远程部署,jenkins和docker实现自动化构建部署

jenkins远程部署,jenkins和docker实现自动化构建部署

项目截图 :

本文关键词:jenkins远程执行命令,jenkins远程部署到Windows,jenkins执行远程脚本,jenkins远程部署vue,jenkins部署到远程服务器。这就是关于《jenkins远程部署,jenkins和docker实现自动化构建部署》的所有内容,希望对您能有所帮助!更多的知识请继续关注《犇涌向乾》百科知识网站:http://www.029ztxx.com!

版权声明: 本站仅提供信息存储空间服务,旨在传递更多信息,不拥有所有权,不承担相关法律责任,不代表本网赞同其观点和对其真实性负责。如因作品内容、版权和其它问题需要同本网联系的,请发送邮件至 举报,一经查实,本站将立刻删除。

猜你喜欢