基于Kubernetes Jenkins CICD(项目实战)

基于Kubernetes Jenkins CICD

一、在Kubernetes 安装 Jenkins优点

目前很多公司采用Jenkins集群搭建复合需求的CI/CD流程,但是会存在一些问题

  • 主Master发生单点故障时,整个流程都不可用
  • 每个Slave的环境配置不一样,来完成不同语言的编译打包,但是这些差异化的配置导致管理起来不方便,维护麻烦
  • 资源分配不均衡,有的slave要运行的job出现排队等待,而有的salve处于空闲状态
  • 资源有浪费,每台slave可能是物理机或者虚拟机,当slave处于空闲状态时,也不能完全释放掉资源

正因为上面的问题,我们需要采用一种更高效可靠的方式来完成这个CI/CD流程,而Docker虚拟化容器技能很好的解决这个痛点,又特别是在Kubernetes集群环境下面能够更好来解决上面的问题.

基于Kubernetes Jenkins CICD(项目实战)_第1张图片

如上图我们可以看到Jenkins master和Jenkins slave以Pod形式运行在Kubernetes集群的Node上,Master运行在其中一个节点,并且将其配置数据存储到一个volume上去,slave运行在各个节点上,但是它的状态并不是一直处于运行状态,它会按照需求动态的创建并自动删除

这种方式流程大致为: 当Jenkins Master接受到Build请求后,会根据配置的Label动态创建一个运行在Pod中的Jenkins Slave并注册到Master上,当运行完Job后,这个Slave会被注销并且这个Pod也会自动删除,恢复到最初的状态(这个策略可以设置)

  • 服务高可用,当Jenkins Master出现故障时,Kubernetes会自动创建一个新的Jenkins Master容器,并且将Volume分配给新创建的容器,保证数据不丢失,从而达到集群服务高可用的作用
  • 动态伸缩,合理使用资源,每次运行Job时,会自动创建一个Jenkins Slave,Job完成后,Slave自动注销并删除容器,资源自动释放,并且Kubernetes会根据每个资源的使用情况,动态分配slave到空闲的节点上创建,降低出现因某节点资源利用率高,降低出现因某节点利用率高出现排队的情况
  • 扩展性好,当Kubernetes集群的资源严重不足导致Job排队等待时,可以很容器的添加一个Kubernetes Node到集群,从而实现扩展

二、Kubernetes 安装Jenkins

这里我们使用k8s的pv进行存储数据,当然也可以使用storage class对象来自动创建

创建pv需要使用nfs,我这里直接创建一台nfs服务器

我们在k8s集群的任意一个节点配置一台nfs集群,其他节点主要是挂载
for i in k8s-01 k8s-02 k8s-03 k8s-04;do ssh root@$i "yum install nfs-utils rpcbind -y";done

#我这里使用单独的NFS服务器,IP为192.168.0.100
#NFS服务节点操作如下
mkdir -p /data1/k8s-vloume
echo "/data1/k8s-vloume  *(rw,no_root_squash,sync)" >/etc/exports
systemctl start rpcbind
systemctl enable rpcbind
systemctl enable nfs
systemctl restart nfs
#IP改成网段

其他k8s节点直接启动rpcbind并且挂载目录就可以

#挂载
systemctl start rpcbind
systemctl enable rpcbind
mkdir /data1/k8s-vloume -p
mount -t nfs 192.168.0.100:/data1/k8s-vloume /data1/k8s-vloume


#创建完成你们自己测一下就可以了

这里需要创建一个命名空间

kubectl create namespace abcdocker

#在创建一下jenkins存储yaml的目录
mkdir -p /opt/jenkins 

接下来我们开始创建Jenkins Deployment

vim /opt/jenkins/jenkins_deployment.yaml
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: jenkins         #deployment名称
  namespace: abcdocker      #命名空间
spec:
  template:
    metadata:
      labels:
        app: jenkins
    spec:
      terminationGracePeriodSeconds: 10     #优雅停止pod
      serviceAccount: jenkins               #后面还需要创建服务账户
      containers:
      - name: jenkins
        image: jenkins/jenkins:lts               #镜像版本
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080                #外部访问端口
          name: web
          protocol: TCP
        - containerPort: 50000              #jenkins save发现端口
          name: agent
          protocol: TCP
        resources:
          limits:
            cpu: 1000m
            memory: 1Gi
          requests:
            cpu: 500m
            memory: 512Mi
        livenessProbe:
          httpGet:
            path: /login
            port: 8080
          initialDelaySeconds: 60          #容器初始化完成后,等待60秒进行探针检查
          timeoutSeconds: 5
          failureThreshold: 12          #当Pod成功启动且检查失败时,Kubernetes将在放弃之前尝试failureThreshold次。放弃生存检查意味着重新启动Pod。而放弃就绪检查,Pod将被标记为未就绪。默认为3.最小值为1
        readinessProbe:
          httpGet:
            path: /login
            port: 8080
          initialDelaySeconds: 60
          timeoutSeconds: 5
          failureThreshold: 12
        volumeMounts:                       #需要将jenkins_home目录挂载出来
        - name: jenkinshome
          subPath: jenkins
          mountPath: /var/jenkins_home
        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 -Duser.timezone=Asia/Shanghai
      securityContext:
        fsGroup: 1000
      volumes:
      - name: jenkinshome
        persistentVolumeClaim:
          claimName: opspvc             #这里将上面创建的pv关联到pvc上

#这里不进行创建

因为要保证Jenkins持久化缓存数据,我们创建了一个PV

cat >/opt/jenkins/jenkins_pv.yaml <<EOF
apiVersion: v1
kind: PersistentVolume
metadata:
  name: opspv
spec:
  capacity:
    storage: 20Gi
  accessModes:
  - ReadWriteMany
  persistentVolumeReclaimPolicy: Delete
  nfs:
    server: 192.168.0.100
    path: /data1/k8s-vloume

---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: opspvc
  namespace: abcdocker
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 20Gi
EOF

#注意修改NFS挂载目录以及NFS Server
#nfs后面的目录是nfs挂载的目录,因为pod会执行mount -t ip:/data1/所以后面是nfs挂载目录,而并非是宿主机的目录

另外还需要一个拥有相关权限的serviceAccount的Jenkins用户,这里我们手动赋予Jenkins一些必要的权限,当然直接给cluster-admin的集群角色权限也是可以的

cat >/opt/jenkins/jenkins_rbac.yaml <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
  name: jenkins
  namespace: abcdocker

---

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: jenkins
rules:
  - apiGroups: ["extensions", "apps"]
    resources: ["deployments"]
    verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]
  - apiGroups: [""]
    resources: ["services"]
    verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]
  - apiGroups: [""]
    resources: ["pods"]
    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"]
    verbs: ["get"]

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: jenkins
  namespace: abcdocker
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: jenkins
subjects:
  - kind: ServiceAccount
    name: jenkins
    namespace: abcdocker
EOF

现在还缺少一个svc,因为我们虽然现在jenkins已经在内部可以访问,但是我们在外面是无法访问的。接下来我们创建一个svc

cat >/opt/jenkins/jenkins_svc.yaml <<EOF
apiVersion: v1
kind: Service
metadata:
  name: jenkins
  namespace: abcdocker
  labels:
    app: jenkins
spec:
  selector:
    app: jenkins
  type: NodePort
  ports:
  - name: web
    port: 8080
    targetPort: web
    nodePort: 30002
  - name: agent
    port: 50000
    targetPort: agent
EOF

接下来我们进行创建

[root@abcdocker-k8s01 jenkins]# ll
total 16
-rw-r--r-- 1 root root 2453 Aug 29 17:42 jenkins_deployment.yaml
-rw-r--r-- 1 root root  407 Aug 29 17:43 jenkins_pv.yaml
-rw-r--r-- 1 root root 1120 Aug 29 17:43 jenkins_rbac.yaml
-rw-r--r-- 1 root root  289 Aug 29 17:43 jenkins_svc.yaml

这里可以直接使用kubectl apple -f .,我为了排查错误,进行一个顺序执行

#这里我先执行pv然后在执行rbac,依次deployment和svc
[root@abcdocker-k8s01 jenkins]# kubectl apply -f jenkins_pv.yaml 
persistentvolume/opspv created
persistentvolumeclaim/opspvc created
[root@abcdocker-k8s01 jenkins]# kubectl apply -f jenkins_rbac.yaml 
serviceaccount/jenkins created
clusterrole.rbac.authorization.k8s.io/jenkins created
clusterrolebinding.rbac.authorization.k8s.io/jenkins created
[root@abcdocker-k8s01 jenkins]# kubectl apply -f jenkins_deployment.yaml 
deployment.extensions/jenkins created
[root@abcdocker-k8s01 jenkins]# kubectl apply -f jenkins_rbac.yaml 
serviceaccount/jenkins unchanged
clusterrole.rbac.authorization.k8s.io/jenkins unchanged
clusterrolebinding.rbac.authorization.k8s.io/jenkins unchanged
[root@abcdocker-k8s01 jenkins]# kubectl apply -f jenkins_svc.yaml 
service/jenkins created

创建完毕后,我们进行检查

#首先查看pvc状态
kubectl get pv,pvc -n abcdocker 
NAME                     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM              STORAGECLASS   REASON   AGE
persistentvolume/opspv   20Gi       RWX            Delete           Bound    abcdocker/opspvc                           65s

NAME                           STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/opspvc   Bound    opspv    20Gi       RWX                           65s


#接下来查看rbac
kubectl get serviceaccounts -n abcdocker |grep jenkins
jenkins   1         104s

#最后检查pod和svc
kubectl get pod,svc -n abcdocker
NAME                          READY   STATUS    RESTARTS   AGE
pod/jenkins-6b874b8d7-dhv57   1/1     Running   0          8m26s

NAME              TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)                          AGE
service/jenkins   NodePort   10.254.154.161           8080:30002/TCP,50000:21866/TCP   62s

#需要说明一下8080端口为我们jenkins访问端口
#50000端口为jenkins save发现端口

Pod正常运行了,我们就可以通过浏览器访问集群任意IP的svc端口

基于Kubernetes Jenkins CICD(项目实战)_第2张图片

管理员密码文件路径,也可以在pod 日志里面看到

cat /data1/k8s-vloume/jenkins/secrets/initialAdminPassword
6d3c67495bcb43c2a74d97309702dab7

#因为我们持久化在/data/k8s下,所以jenkins的所有配置都在这下面

直接选择推荐安装就可以

基于Kubernetes Jenkins CICD(项目实战)_第3张图片

等待安装完毕

基于Kubernetes Jenkins CICD(项目实战)_第4张图片

安装完成后我们进入jenkins主页面

基于Kubernetes Jenkins CICD(项目实战)_第5张图片

接下来就是配置Jenkins

我们需要安装k8s插件,让Jenkins构建Job可以动态生成Slave的Pod

点击Jenkins–>插件–>安装插件Kubernetes

基于Kubernetes Jenkins CICD(项目实战)_第6张图片

安装完毕后会重启Jenkins,然后我们就可以配置插件

Manage Jenkins >>Configure System 找到插件

基于Kubernetes Jenkins CICD(项目实战)_第7张图片

在配置上拉到最下面,ADD一个Kubernetes

基于Kubernetes Jenkins CICD(项目实战)_第8张图片

Name   配置的名称
Kubernetes URL  这里的URL是K8s内部的URL,实际上就是svcname 这里不需要修改直接复制就行
Kubernetes Namespace k8s的命名空间 (实际上就是Jenkins所在的命名空间)

https://kubernetes.default.svc.cluster.local

svcname+default+后面参数复制就可以

基于Kubernetes Jenkins CICD(项目实战)_第9张图片

Jenkins URL   这里的URL是jenkins的svc名称加上命名空间,实际上就是在k8s集群内部访问jenkins的一个方法,这里也不需要修改
http://jenkins.abcdocker.svc.cluster.local:8080

#其他默认即可

基于Kubernetes Jenkins CICD(项目实战)_第10张图片

添加一个 Jenkins Slave Pod模板

基于Kubernetes Jenkins CICD(项目实战)_第11张图片

Name   = Pod 名称
Namespave   = Pod命名空间
Labels   =  Pod标签

基于Kubernetes Jenkins CICD(项目实战)_第12张图片

接下来是容器的模板配置

Name  容器的名称
Docker image  镜像,这里直接使用我的镜像
#jenkins 2.176.x版本以上使用:registry.cn-beijing.aliyuncs.com/abcdocker/jenkins:v1.2
#jenkins 2.176.x版本以下使用:registry.cn-beijing.aliyuncs.com/abcdocker/jenkins:v1.1
#jenkins 2.176以上版本有maven命令使用:registry.cn-beijing.aliyuncs.com/abcdocker/jenkins:v1.4

#镜像里面主要是运行了kubectl命令和Docker的配置,下面我们还需要将kubeconfig挂载进来


########
如果需要自定义maven仓库可以使用下面的dockerfile
[root@k8s-01 jenkins]# cat Dockerfile
FROM registry.cn-beijing.aliyuncs.com/abcdocker/jenkins:v1.2
MAINTAINER abcdocker "i4t.com"
COPY maven /usr/local/maven
RUN cd /usr/local/maven

红色代表不可以修改,否则jenkins slave启动会提示错误,反复重启

基于Kubernetes Jenkins CICD(项目实战)_第13张图片

如果jenkins提示权限错误,请在配置中添加jenkins rbac创建的serviceaccounts

基于Kubernetes Jenkins CICD(项目实战)_第14张图片

上面说了,镜像主要是用于kubectl,kubectl是需要kubeconfig文件,所以我们还需要创建一个volume的配置

基于Kubernetes Jenkins CICD(项目实战)_第15张图片

如果我们想在容器里面执行docker命令,需要将docker.sock挂载进去

还需要将kubeconfig挂在进容器

基于Kubernetes Jenkins CICD(项目实战)_第16张图片

基于Kubernetes Jenkins CICD(项目实战)_第17张图片

然后我们点击保存即可

接下来添加一个job,来测试一下jenkins是否可以在slave节点上执行

基于Kubernetes Jenkins CICD(项目实战)_第18张图片

接下来进行配置Jenkins

这里的label标签就是我们在配置中配置的标签

基于Kubernetes Jenkins CICD(项目实战)_第19张图片

配置标签的地方

基于Kubernetes Jenkins CICD(项目实战)_第20张图片

添加一个shell命令,测试docker和kubectl

基于Kubernetes Jenkins CICD(项目实战)_第21张图片

现在我们先看一下Pod是否可以动态获取

$ kubectl get pod -n abcdocker
NAME                      READY   STATUS    RESTARTS   AGE
jenkins-6b874b8d7-xxwwr   1/1     Running   0          31h

#目前只有一个jenkins在运行,接下来我们进行构建项目

容器正在创建,目前属于等待状态

基于Kubernetes Jenkins CICD(项目实战)_第22张图片

这里可以看到已经新启动了一个pod节点

$ kubectl get pod -n abcdocker
NAME                      READY   STATUS              RESTARTS   AGE
jenkins-6b874b8d7-xxwwr   1/1     Running             0          2d
jenkins-slave-423xz       0/1     ContainerCreating   0          5s

等待容器创建成功,Jenkins就会绑定到这个Pod节点上,进行执行任务

基于Kubernetes Jenkins CICD(项目实战)_第23张图片

如果遇到pod一直重启的情况,请使用kubectl get pod -n xxx -o wide查看pod运行节点,使用docker ps过滤出pod,通过docker logs -f查看错误日志

当Jenkins slave节点执行完毕任务后,默认情况下执行完job就会被删除

$ kubectl get pod -n abcdocker
NAME                      READY   STATUS    RESTARTS   AGE
jenkins-6b874b8d7-xxwwr   1/1     Running   0          2d

如果想让job等待30分钟释放,可以在下图添加

基于Kubernetes Jenkins CICD(项目实战)_第24张图片

小结 Jenkins Master收到Build请求时,会根据配置的Label动态创建一个运行在Pod中的Jenkins Slave并注册到Master上,当Job运行完,这个Slave会被注销并且这个Pod也会自动删除,恢复到最初状态


三、项目演示 使用Jenkins Pipline部署

Jenkins Pipline介绍

Gitlab配置

接下来我们在代码仓库创建一个分支

基于Kubernetes Jenkins CICD(项目实战)_第25张图片

配置root用户免密

首先先查看服务器公钥

基于Kubernetes Jenkins CICD(项目实战)_第26张图片

上git配置key

基于Kubernetes Jenkins CICD(项目实战)_第27张图片

接下来在服务器上提交git代码就可以

基于Kubernetes Jenkins CICD(项目实战)_第28张图片

上传代码

#这里需要有git命令
yum install -y git 
git config --global user.name "root"
git config --global user.email "[email protected]"

#克隆
git clone [email protected]:root/abcdocker-test.git
cd abcdocker-test
wget http://down.i4t.com/hello-world-war-master.zip
unzip hello-world-war-master.zip
mv hello-world-war-master/* .
rm -rf hello-world-war-master*

#提交代码


#接下来看图就行了

gitlab配置完毕

基于Kubernetes Jenkins CICD(项目实战)_第29张图片


四、配置Dockerfile

首先我们需要自定义一个tomcat基础镜像,也可以使用dockerhub提供的

cat >>Dockerfile <<EOF
FROM centos
MAINTAINER www.i4t.com "[email protected]"
WORKDIR /tmp
## Please see https://i4t.com/3552.html   install JDK
COPY jdk1.8.0_66.tar.gz /tmp
    RUN tar zxf /tmp/jdk1.8.0_66.tar.gz -C /usr/local/ && rm -rf /tmp/jdk1.8.0_66.tar.gz && \
        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 apache
# Please see i4t.com && baidu.com
    COPY apache-tomcat-8.5.39.tar.gz /tmp
    RUN tar zxf apache-tomcat-8.5.39.tar.gz -C /usr/local  && rm -rf /tmp/apache-tomcat-8.5.39.tar.gz && \
        mv /usr/local/apache-tomcat-8.5.39 /usr/local/tomcat && \
        rm -rf /usr/local/tomcat/webapps/docs examples host-manager manager
EXPOSE 8080
ENTRYPOINT /usr/local/tomcat/bin/startup.sh && tail -f /usr/local/tomcat/logs/catalina.out
EOF

###接下来需要下载相对应的安装包  (Dockerfile和JDK安装包和tomcat安装包需要放在一个目录下)
wget http://down.i4t.com/jdk1.8.0_66.tar.gz
wget http://down.i4t.com/apache-tomcat-8.5.39.tar.gz

接下来可以进行打包

docker build -t registry.cn-beijing.aliyuncs.com/abcdocker/tomcat:v2 .

#如果不想自己做tomcat镜像,也可以使用dockerhub上的镜像。也可以使用我这里打包好的镜像

现在我们已经完成tomcat镜像的创建,接下来配置Jenkins,每次打包上线自动替换ROOT目录

五、编写jenkins Pipline

Jenkins pipline 语法介绍

配置gitlab账号密码

由于Jenkins需要使用gitlab账号密码,这里我们做一下免密

基于Kubernetes Jenkins CICD(项目实战)_第30张图片

基于Kubernetes Jenkins CICD(项目实战)_第31张图片

基于Kubernetes Jenkins CICD(项目实战)_第32张图片

配置如下

基于Kubernetes Jenkins CICD(项目实战)_第33张图片

创建Jenkins pipline项目

基于Kubernetes Jenkins CICD(项目实战)_第34张图片

我这里添加参数化构建

基于Kubernetes Jenkins CICD(项目实战)_第35张图片

接下来编写jenkins pipline脚本

node('abcdocker-slave') {
    stage('Git Clone') {
         checkout([$class: 'GitSCM', branches: [[name: '${git}']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'gitlab_password', url: 'http://192.168.0.100/root/abcdocker-test.git']]])    

    }
    stage('Maven Build') {
           sh '''
        /usr/local/maven/bin/mvn clean package -Dmaven.test.skip=true -f $WORKSPACE

        echo FROM registry.cn-beijing.aliyuncs.com/abcdocker/tomcat:test2 >$WORKSPACE/target/Dockerfile
        echo RUN  rm -rf /usr/local/tomcat/webapps/* >>$WORKSPACE/target/Dockerfile
        echo COPY hello-world-war-1.0.0 /usr/local/tomcat/webapps/ROOT >>$WORKSPACE/target/Dockerfile
           '''

      echo "3.Docker Build Stage"
           sh '''
        docker build -t registry.cn-beijing.aliyuncs.com/abcdocker/tomcat:${git} ${WORKSPACE}/target/
        docker login --username=用户名 registry.cn-beijing.aliyuncs.com --password 镜像密码
        docker push registry.cn-beijing.aliyuncs.com/abcdocker/tomcat:${git}
              '''
    }
    stage('Deploy') {
      echo "4. Deploy Stage"
      sh'kubectl set image deployment/tomcat -n abcdocker-test my-tomcat=registry.cn-beijing.aliyuncs.com/abcdocker/tomcat:${git}'
    }
}

Pipline脚本讲解

node('abcdocker-slave') {

#这里代表node节点运行在标签为abcdocker-slave上,前面已经定义了,这里就不在定义

gitlab拉取代码配置

    stage('Git Clone') {
         checkout([$class: 'GitSCM', branches: [[name: '${git}']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'gitlab_password', url: 'http://192.168.0.100/root/abcdocker-test.git']]])    
    }

#这里就是一个选择git地址,然后分支。不会生成可以参考pipline语法

在下图生成的配置直接拷贝到pipline里面ji

基于Kubernetes Jenkins CICD(项目实战)_第36张图片

Java maven打包步骤

我这里使用阿里云的镜像仓库,演示一下如何上传。

这里需要注意的是,我们的jenkins slave节点的Pod镜像需要使用下面我提供的版本,否则没有maven命令

registry.cn-beijing.aliyuncs.com/abcdocker/jenkins:v1.4

    stage('Maven Build') {
        sh '''
        /usr/local/maven/bin/mvn clean package -Dmaven.test.skip=true -f $WORKSPACE
        echo FROM registry.cn-beijing.aliyuncs.com/abcdocker/tomcat:test2 >$WORKSPACE/target/Dockerfile
        echo RUN  rm -rf /usr/local/tomcat/webapps/* >>$WORKSPACE/target/Dockerfile
        echo COPY hello-world-war-1.0.0 /usr/local/tomcat/webapps/ROOT >>$WORKSPACE/target/Dockerfile
        '''
      echo "3.Docker Build Stage"
           sh '''
          docker build -t registry.cn-beijing.aliyuncs.com/abcdocker/tomcat:${git} ${WORKSPACE}/target/
          docker login --username=cyh60441314 registry.cn-beijing.aliyuncs.com --password XXXX密码
          docker push registry.cn-beijing.aliyuncs.com/abcdocker/tomcat:${git}
              '''
    }

接下来是使用kubectl set替换镜像

    stage('Deploy') {
      echo "4. Deploy Stage"
      sh'kubectl set image deployment/tomcat -n abcdocker-test my-tomcat=registry.cn-beijing.aliyuncs.com/abcdocker/tomcat:${git}'
    }

命令参数解释

kubectl set image deployment/SVC_NAME -n namespace_name container_name=images:v1

#注意后面是容器名称,并不是svc名称

完整Jenkins Pipline脚本如下

node('abcdocker-slave') {
    stage('Git Clone') {
         checkout([$class: 'GitSCM', branches: [[name: '${git}']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'gitlab_password', url: 'http://192.168.0.100/root/abcdocker-test.git']]])    

    }
    stage('Maven Build') {
        sh '''
        /usr/local/maven/bin/mvn clean package -Dmaven.test.skip=true -f $WORKSPACE

        echo FROM registry.cn-beijing.aliyuncs.com/abcdocker/tomcat:test2 >$WORKSPACE/target/Dockerfile
        echo RUN  rm -rf /usr/local/tomcat/webapps/* >>$WORKSPACE/target/Dockerfile
        echo COPY hello-world-war-1.0.0 /usr/local/tomcat/webapps/ROOT >>$WORKSPACE/target/Dockerfile
        '''

      echo "3.Docker Build Stage"
           sh '''
          docker build -t registry.cn-beijing.aliyuncs.com/abcdocker/tomcat:${git} ${WORKSPACE}/target/
          docker login --username=用户名 registry.cn-beijing.aliyuncs.com --password harbor密码
          docker push registry.cn-beijing.aliyuncs.com/abcdocker/tomcat:${git}
              '''
    }
    stage('Deploy') {
      echo "4. Deploy Stage"
      sh'kubectl set image deployment/tomcat -n abcdocker-test my-tomcat=registry.cn-beijing.aliyuncs.com/abcdocker/tomcat:${git}'
    }
}

然后jenkins我们点击保存

创建tomcat svc环境

#创建命名空间
kubectl create namespace abcdocker-test

创建tomcat deploy文件

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  labels:
    name: tomcat
  name: tomcat
  namespace: abcdocker-test
spec:
  replicas: 1
  selector:
    matchLabels:
      name: tomcat
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: tomcat
        name: tomcat
    spec:
      containers:
      - env:
        - name: JAVA_OPTS
          value: -server -d64 -XX:MetaspaceSize=256m
        - name: MAX_HEAP
          value: 512m
        - name: MIN_HEAP
          value: 512m
        image: registry.cn-beijing.aliyuncs.com/abcdocker/tomcat:v2
        imagePullPolicy: IfNotPresent
        name: my-tomcat
        ports:
        - containerPort: 8080
          protocol: TCP
        resources:
          limits:
            memory: 1536Mi
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File

创建svc

apiVersion: v1
kind: Service
metadata:
  name: my-tomcat-svc
  namespace: abcdocker-test
  labels:
    app: tomcat
spec:
  selector:
    app: tomcat
  type: NodePort
  ports:
  - name: web
    port: 8080
    #targetPort: 8080
    nodePort: 30005

创建之后我们查看状态

[root@k8s-01 ~]# kubectl get pod,svc -n abcdocker-test
NAME                          READY   STATUS    RESTARTS   AGE
pod/tomcat-855dccd5bc-wkn5z   1/1     Running   0          27m

NAME                    TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
service/my-tomcat-svc   NodePort   10.254.62.11           8080:30005/TCP   26h

访问页面,查看是否正常 (集群任意IP+30005)

基于Kubernetes Jenkins CICD(项目实战)_第37张图片

项目部署

接下来我们演示一下环境部署

基于Kubernetes Jenkins CICD(项目实战)_第38张图片

点击Build

基于Kubernetes Jenkins CICD(项目实战)_第39张图片

我这里没有区分环境,这里也是可以区分环境的

基于Kubernetes Jenkins CICD(项目实战)_第40张图片

日志分析

基于Kubernetes Jenkins CICD(项目实战)_第41张图片

基于Kubernetes Jenkins CICD(项目实战)_第42张图片

基于Kubernetes Jenkins CICD(项目实战)_第43张图片

基于Kubernetes Jenkins CICD(项目实战)_第44张图片

替换镜像

基于Kubernetes Jenkins CICD(项目实战)_第45张图片

效果图

基于Kubernetes Jenkins CICD(项目实战)_第46张图片

Jenkins上也可以看到每个步骤的构建时间

基于Kubernetes Jenkins CICD(项目实战)_第47张图片

你可能感兴趣的:(k8s,kubernetes,jenkins,tomcat,k8s自动化构建Java应用)