目录
Jenkins+Kubernetes+Docker完成微服务持续集成
让所有Jenkins-Slave构建指向NFS的Maven的共享仓库目录
- [root@harbor /opt/nfs]# mkdir maven
- [root@harbor /opt/nfs]# chmod 777 maven/
- [root@harbor /opt/nfs]# vim /etc/exports
- /opt/nfs/jenkins 192.168.37.0/24(rw,sync,no_root_squash)
- /opt/nfs/maven 192.168.37.0/24(rw,sync,no_root_squash)
-
- #刷新
- [root@harbor /opt/nfs]# exportfs -rv
- exporting 192.168.37.0/24:/opt/nfs/maven
- exporting 192.168.37.0/24:/opt/nfs/jenkins
查看k8s集群
- [root@node01 ~]# showmount -e 192.168.37.106
- Export list for 192.168.37.106:
- /opt/nfs/maven 192.168.37.0/24
- /opt/nfs/jenkins 192.168.37.0/24
Docker命令执行权限问题
[root@master01 /var/run]# chmod 777 docker.sock
新建一个流水线项目

编写构建Pipeline


配置harbor凭证

流水线脚本
- def git_url = "http://192.168.37.103:85/devops_group/tensquare_back.git"
- def git_auth = "72a48f14-72c7-444f-a471-2d482e85d808"
- //构建版本的名称
- def tag = "latest"
- //Harbor私服地址
- def harbor_url = "192.168.37.106:85"
- //Harbor的项目名称
- def harbor_project_name = "tensquare"
- //Harbor的凭证
- def harbor_auth = "ea2f47a0-3f01-4149-a095-987675db7162"
-
-
- podTemplate(label: 'jenkins-slave', cloud: 'kubernetes', containers: [
- containerTemplate(
- name: 'jnlp',
- image: "192.168.37.106:85/library/jenkins-slave-maven:latest"
- ),
- containerTemplate(
- name: 'docker',
- image: "docker:stable",
- ttyEnabled: true,
- command: 'cat'
- ),
- ],
- volumes: [
- hostPathVolume(mountPath: '/var/run/docker.sock', hostPath: '/var/run/docker.sock'),
- nfsVolume(mountPath: '/usr/local/apache-maven/repo', serverAddress: '192.168.37.106' , serverPath: '/opt/nfs/maven'),
- ],
- )
- {
- node("jenkins-slave") {
- // 第一步
- stage('pull code'){
- checkout([$class: 'GitSCM', branches: [[name: '*/master']], extensions: [],
- userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
- }
- // 第二步
- stage('make public sub project'){
- //编译并安装公共工程
- sh "mvn -f tensquare_common clean install"
- }
- // 第三步
- stage('make image'){
- //把选择的项目信息转为数组
- def selectedProjects = "${project_name}".split(',')
-
-
- for(int i=0;i<selectedProjects.size();i++){
- //取出每个项目的名称和端口
- def currentProject = selectedProjects[i];
- //项目名称
- def currentProjectName = currentProject.split('@')[0]
- //项目启动端口
- def currentProjectPort = currentProject.split('@')[1]
-
- //定义镜像名称
- def imageName = "${currentProjectName}:${tag}"
-
- //编译,构建本地镜像
- sh "mvn -f ${currentProjectName} clean package dockerfile:build"
- container('docker') {
-
- //给镜像打标签
- sh "docker tag ${imageName} ${harbor_url}/${harbor_project_name}/${imageName}"
-
- //登录Harbor,并上传镜像
- withCredentials([usernamePassword(credentialsId: "${harbor_auth}", passwordVariable: 'password', usernameVariable: 'username')])
- {
- //登录
- sh "docker login -u ${username} -p ${password} ${harbor_url}"
- //上传镜像
- sh "docker push ${harbor_url}/${harbor_project_name}/${imageName}"
- }
-
- //删除本地镜像
- sh "docker rmi -f ${imageName}"
- sh "docker rmi -f ${harbor_url}/${harbor_project_name}/${imageName}"
- }
- }
- }
- }
- }

Eureka服务构建成功!!!

此时harbor仓库已经推送上去了

安装 Kubernetes Continuous Deploy插件

添加k8s凭证

点击确定,获取id号
K8S 创建访问Harbor私服拉取镜像所需要密钥权限凭证,设置免交互
[root@master01 ~/.kube]# kubectl create secret docker-registry registry-auth-secret --docker-username=jack --docker-password=Abc12345 --docker-email=jack@123.com --docker-server=192.168.37.106:85

在tensquare_eureka_server微服务项目根目录下创建 deploy.yml配置文件

- ---
- apiVersion: v1
- kind: Service
- metadata:
- name: eureka
- labels:
- app: eureka
- spec:
- type: NodePort
- ports:
- - port: 10086
- name: eureka
- targetPort: 10086
- selector:
- app: eureka
- ---
- apiVersion: apps/v1
- kind: StatefulSet
- metadata:
- name: eureka
- spec:
- serviceName: "eureka"
- replicas: 2
- selector:
- matchLabels:
- app: eureka
- template:
- metadata:
- labels:
- app: eureka
- spec:
- imagePullSecrets:
- - name: $SECRET_NAME #通过变量引用K8S访问Harbor私服拉取镜像所需要的secret资源名称
- containers:
- - name: eureka
- image: $IMAGE_NAME
- ports:
- - containerPort: 10086
- env:
- - name: MY_POD_NAME #MY_POD_NAME环境变量会从每个被创建的Pod的metadata.name字段获取变量值,如eureka-0、eureka-1
- valueFrom:
- fieldRef:
- fieldPath: metadata.name
- - name: EUREKA_SERVER #此环境变量会被项目代码中的application.yml文件引用
- value: "http://eureka-0.eureka:10086/eureka/,http://eureka-1.eureka:10086/eureka/"
- - name: EUREKA_INSTANCE_HOSTNAME #此环境变量会项目代码中的application.yml文件引用
- value: ${MY_POD_NAME}.eureka
- podManagementPolicy: "Parallel"
修改tensquare_eureka_server微服务项目的 application.yml 文件
- tensquare_eureka_server\src\main\resources \application.yml
-
- ---
- server:
- port: ${PORT:10086}
- spring:
- application:
- name: eureka
-
- eureka:
- server:
- #续期时间,即扫描失效服务的间隔时间(缺省为60*1000ms)
- eviction-interval-timer-in-ms: 5000
- enable-self-preservation: false
- use-read-only-response-cache: false
- client:
- #eureka client间隔多久去拉取服务注册信息 默认30s
- registry-fetch-interval-seconds: 5
- serviceUrl:
- defaultZone: ${EUREKA_SERVER:http://127.0.0.1:${server.port}/eureka/} #引用deploy.yml配置中的环境变量EUREKA_SERVER
- instance:
- #心跳间隔时间,即发送一次心跳之后,多久在发起下一次(缺省为30s)
- lease-renewal-interval-in-seconds: 5
- #在收到一次心跳之后,等待下一次心跳的空档时间,大于心跳间隔即可,即服务续约到期时间(缺省为90s)
- lease-expiration-duration-in-seconds: 10
- instance-id: ${EUREKA_INSTANCE_HOSTNAME:${spring.application.name}}:${server.port}@${random.long(1000000,9999999)}
- hostname: ${EUREKA_INSTANCE_HOSTNAME:${spring.application.name}}
上传代码
编写pipeline脚本
- def git_url = "http://192.168.37.103:85/devops_group/tensquare_back.git"
- def git_auth = "72a48f14-72c7-444f-a471-2d482e85d808"
- //构建版本的名称
- def tag = "latest"
- //Harbor私服地址
- def harbor_url = "192.168.37.106:85"
- //Harbor的项目名称
- def harbor_project_name = "tensquare"
- //Harbor的凭证
- def harbor_auth = "ea2f47a0-3f01-4149-a095-987675db7162"
- //获取当前选择项目名称
- def selectedProjectNames="${project_name}".split(",")
- def secret_name = "registry-auth-secret"
- def k8s_auth = "2e95a29c-79f1-41dd-be38-3f9691b25807"
-
- podTemplate(label: 'jenkins-slave', cloud: 'kubernetes', containers: [
- containerTemplate(
- name: 'jnlp',
- image: "192.168.37.106:85/library/jenkins-slave-maven:latest"
- ),
- containerTemplate(
- name: 'docker',
- image: "docker:stable",
- ttyEnabled: true,
- command: 'cat'
- ),
- ],
- volumes: [
- hostPathVolume(mountPath: '/var/run/docker.sock', hostPath: '/var/run/docker.sock'),
- nfsVolume(mountPath: '/usr/local/apache-maven/repo', serverAddress: '192.168.37.106' , serverPath: '/opt/nfs/maven'),
- ],
- )
- {
- node("jenkins-slave") {
- // 第一步
- stage('pull code'){
- checkout([$class: 'GitSCM', branches: [[name: '*/master']], extensions: [],
- userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]])
- }
- // 第二步
- stage('make public sub project'){
- //编译并安装公共工程
- sh "mvn -f tensquare_common clean install"
- }
- // 第三步
- stage('make image'){
- //把选择的项目信息转为数组
- def selectedProjects = "${project_name}".split(',')
-
-
- for(int i=0;i<selectedProjects.size();i++){
- //取出每个项目的名称和端口
- def currentProject = selectedProjects[i];
- //项目名称
- def currentProjectName = currentProject.split('@')[0]
- //项目启动端口
- def currentProjectPort = currentProject.split('@')[1]
-
- //定义镜像名称
- def imageName = "${currentProjectName}:${tag}"
-
- //编译,构建本地镜像
- sh "mvn -f ${currentProjectName} clean package dockerfile:build"
- container('docker') {
-
- //给镜像打标签
- sh "docker tag ${imageName} ${harbor_url}/${harbor_project_name}/${imageName}"
-
- //登录Harbor,并上传镜像
- withCredentials([usernamePassword(credentialsId: "${harbor_auth}", passwordVariable: 'password', usernameVariable: 'username')])
- {
- //登录
- sh "docker login -u ${username} -p ${password} ${harbor_url}"
- //上传镜像
- sh "docker push ${harbor_url}/${harbor_project_name}/${imageName}"
- }
-
- //删除本地镜像
- sh "docker rmi -f ${imageName}"
- sh "docker rmi -f ${harbor_url}/${harbor_project_name}/${imageName}"
- }
- }
- }
-
- stage('部署应用到K8S') {
- for(int i=0; i<selectedProjectNames.length; i++) {
- def projectInfo=selectedProjectNames[i]
-
- //当前的项目名称
- def currentProjectName="${projectInfo}".split("@")[0]
-
- //当前的项目端口
- def currentProjectPort="${projectInfo}".split("@")[1]
- def imageName = "${currentProjectName}:${tag}"
- def harbor_imageName = "${harbor_url}/${harbor_project_name}/${imageName}"
- sh """
- sed -i 's#\$IMAGE_NAME#${harbor_imageName}#' ${currentProjectName}/deploy.yml
- sed -i 's#\$SECRET_NAME#${secret_name}#' ${currentProjectName}/deploy.yml
- """
- kubernetesDeploy configs: "${currentProjectName}/deploy.yml", kubeconfigId: "${k8s_auth}"
- }
- }
- }
- }
构建
查看pod,svc资源

浏览器访问

更改配置文件中的eureka集群地址
- tensquare_zuul\src\main\resources\application.yml
-
- # Eureka注册配置信息
- eureka:
- client:
- service-url:
- defaultZone: http://eureka-0.eureka:10086/eureka/,http://eureka-1.eureka:10086/eureka/ #Eureka访问地址
- instance:
- prefer-ip-address: true
创建配置文件deploy.yml
- ---
- apiVersion: v1
- kind: Service
- metadata:
- name: zuul
- labels:
- app: zuul
- spec:
- type: NodePort
- ports:
- - port: 10020
- name: zuul
- targetPort: 10020
- selector:
- app: zuul
- ---
- apiVersion: apps/v1
- kind: StatefulSet
- metadata:
- name: zuul
- spec:
- serviceName: "zuul"
- replicas: 2
- selector:
- matchLabels:
- app: zuul
- template:
- metadata:
- labels:
- app: zuul
- spec:
- imagePullSecrets:
- - name: $SECRET_NAME #通过变量引用K8S访问Harbor私服拉取镜像所需要的secret资源名称
- containers:
- - name: zuul
- image: $IMAGE_NAME
- ports:
- - containerPort: 10020
- podManagementPolicy: "Parallel"

开始构建

其他项目名字和端口进行修改即可