k8s+jenkins发布java服务

Centos7安装k8s容器集群请查阅:
一、准备的基础环境
1、gitlab环境(已有),如无则搭建,这里使用docker部署
$ mkdir /home/docker/gitlab -p
$ docker run -d
-p 6443:443
-p 6080:6080
-p 6022:22
–name gitlab
–restart always
-v /home/docker/gitlab/config:/etc/gitlab
-v /home/docker/gitlab/logs:/var/log/gitlab
-v /home/docker/gitlab/data:/var/opt/gitlab
gitlab/gitlab-ce:10.8.0-ce.0

1.1 进入gitlab修改文件,修改内容如下
docker exec -it gitlab vim /etc/gitlab/gitlab.rb

修改文件
external_url “http://xx.com:6080” #域名或IP这样可以使用外网访问
gitlab_rails[‘gitlab_shell_ssh_port’] = 6022 #暴露的外网ssh端口对应容器22端口
gitlab_rails[‘smtp_enable’] = true
gitlab_rails[‘smtp_address’] = “smtp.exmail.qq.com”
gitlab_rails[‘smtp_port’] = 465
gitlab_rails[‘smtp_user_name’] = “xx@qq.com”
gitlab_rails[‘smtp_password’] = “notice-IOT2018”
gitlab_rails[‘smtp_authentication’] = “login”
gitlab_rails[‘smtp_enable_starttls_auto’] = true
gitlab_rails[‘smtp_tls’] = true
gitlab_rails[‘gitlab_email_from’] = ‘xx@qq.com’
gitlab_rails[‘smtp_domain’] = “exmail.qq.com”
nginx[‘listen_port’] = 6080 #gitlab自带nginx的访问端口

1.2 重启gitlab服务
docker restart gitlab

1.3 访问地址:http://xx.com:6080
初次会先设置管理员密码 ,然后登陆,默认管理员用户名root,密码就是刚设置的。

2、镜像仓库harbor(服务器有多的可以单独用一台)
这里选用harbor作为存放私有镜像仓库

2.1 安装docker与docker-compose
wget http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
yum install docker-ce -y
systemctl start docker
systemctl enable docker
curl -L https://github.com/docker/compose/releases/download/1.25.0/docker-compose-uname -s-uname -m -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

2.2 解压离线包部署
tar zxvf harbor-offline-installer-v1.9.1.tgz
cd harbor
vi harbor.yml 修改主机名
hostname: 192.168.175.59
./prepare
./install.sh --with-chartmuseum
docker-compose ps
–with-chartmuseum 参数表示启用Charts存储功能。

2.3 配置Docker可信任
由于habor未配置https,还需要在docker配置可信任。
cat /etc/docker/daemon.json
{“registry-mirrors”: [“http://f1361db2.m.daocloud.io”],
“insecure-registries”: [“192.168.175.59”]
}
systemctl restart docker
3、应用包管理器 Helm
3.1 安装Helm工具
wget https://get.helm.sh/helm-v3.0.0-linux-amd64.tar.gz
tar zxvf helm-v3.0.0-linux-amd64.tar.gz
mv linux-amd64/helm /usr/bin/

3.2 配置国内Chart仓库
helm repo add stable http://mirror.azure.cn/kubernetes/charts
helm repo add aliyun https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
helm repo list
3.3 安装push插件
helm plugin install https://github.com/chartmuseum/helm-push

如果网络下载不了,可以到github上下载解压安装
https://github.com/chartmuseum/helm-push/releases
tar zxvf helm-push_0.7.1_linux_amd64.tar.gz
mkdir -p /root/.local/share/helm/plugins/helm-push
chmod +x bin/*
mv bin plugin.yaml /root/.local/share/helm/plugins/helm-push

3.4 添加repo
helm repo add --username admin --password 123456 myrepo http://192.168.175.59/chartrepo/library

3.5 推送与安装Chart
helm pull mysql
helm helm package mysql
helm push mysql-1.4.0.tgz --username=admin --password=SIEgushen8920c http://192.168.175.59/chartrepo/library
helm install web --version 1.4.0 myrepo/demo

4、数据库安装(忽略这里使用云主机搭建好的MySQL)

5、K8S PV自动供给
先准备一台NFS服务器为K8S提供存储支持。
yum install nfs-utils
vi /etc/exports
/data/kubernetes *(rw,no_root_squash)
mkdir -p /data/kubernetes
systemctl start nfs
systemctl enable nfs

并且要在每个Node上安装nfs-utils包,用于mount挂载时用。

由于K8S不支持NFS动态供给,还需要先安装上图中的nfs-client-provisioner插件:

cd nfs-client
vi deployment.yaml # 修改里面NFS地址和共享目录为你的
kubectl apply -f .
kubectl get pods
NAME READY STATUS RESTARTS AGE
nfs-client-provisioner-df88f57df-bv8h7 1/1 Running 0 49m

6、持续集成 Jenkins
[jenkins.zip]
6.1 解压附件,进行部署Jenkins
cd jenkins && kubectl apply -f .
kubectl get pods,svc #查看是否running
6.2 由于默认插件源在国外服务器,大多数网络无法顺利下载,需修改国内插件源地址:
cd jenkins_home/updates
sed -i ‘s/https://updates.jenkins.io/download/https://mirrors.tuna.tsinghua.edu.cn/jenkins/g’ default.json &&
sed -i ‘s/http://www.google.com/https://www.baidu.com/g’ default.json
kubectl get pods #查看jenkins的pod
然后删除jenkins,让k8s重新拉起一个jenkins即可。
kubectl delete pod jenkins的pod id
安装Jenkins此项目需要的插件:Git Parameter/Git/Pipeline/Config File Provider/kubernetes/Extended Choice Parameter
6.3 生成kubeconfig文件(到部署k8s集群的master节点的TLS目录的k8s目录下执行)
vim admin-csr.json
{
“CN”: “admin”,
“hosts”: [],
“key”: {
“algo”: “rsa”,
“size”: 2048
},
“names”: [
{
“C”: “CN”,
“L”: “BeiJing”,
“ST”: “BeiJing”,
“O”: “system:masters”,
“OU”: “System”
}
]
}
到部署k8s集群的master节点的TLS目录的k8s目录下执行
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes admin-csr.json | cfssljson -bare admin

二、创建kubeconfig文件
1.1 # 设置集群参数
kubectl config set-cluster kubernetes
–server=https://192.168.175.58:6443
–certificate-authority=ca.pem
–embed-certs=true
–kubeconfig=config

1.2 # 设置上下文参数
kubectl config set-context default
–cluster=kubernetes
–user=cluster-admin
–kubeconfig=config

1.3 # 设置默认上下文
kubectl config use-context default --kubeconfig=config

1.4 # 设置客户端认证参数
kubectl config set-credentials cluster-admin
–certificate-authority=ca.pem
–embed-certs=true
–client-key=admin-key.pem
–client-certificate=admin.pem
–kubeconfig=config

三、 #搭建jenkins slave
1.1 下载这个安装包
jenkins-slave解压,替换slave.jar包为自己jenkins下载的包
http://192.168.175.58:30006/jnlpJars/slave.jar
jenkins-slave]$ ls -lrth
-rwxr-xr-x 1 weihu weihu 37M Nov 13 2019 helm
-rwxr-xr-x 1 weihu weihu 2.0K Nov 24 2019 jenkins-slave
-rwxr-xr-x 1 weihu weihu 45M Dec 26 2019 kubectl
-rw-r–r-- 1 weihu weihu 23M Jul 23 01:12 node-v12.18.3-linux-x64.tar.gz
-rw-r–r-- 1 weihu weihu 183M Sep 10 16:02 jdk1.8.0_191.tar.gz
-rw-r–r-- 1 weihu weihu 11K Sep 10 17:22 settings.xml
-rw-r–r-- 1 weihu weihu 9.1M Oct 10 14:32 apache-maven-3.6.3-bin.tar.gz
-rw-r–r-- 1 weihu weihu 9.1M Oct 10 15:29 apache-maven-3.6.3.tar.gz
-rw-r–r-- 1 weihu weihu 853 Oct 10 15:33 Dockerfile
-rw-r–r-- 1 root root 1.5M Nov 3 15:55 slave.jar

1.2 #添加kubernetes云

在这里插入图片描述

配置jenkins地址为service名字:http://jenkins,然后保存即可
1.3 #制作jenkins slave镜像Dockerfile
FROM centos:7
LABEL maintainer chenjike

RUN yum install -y java-1.8.0-openjdk maven curl git libtool-ltdl-devel && \
yum clean all &&
rm -rf /var/cache/yum/* &&
mkdir -p /usr/share/jenkins

COPY slave.jar /usr/share/jenkins/slave.jar
COPY jenkins-slave /usr/bin/jenkins-slave
COPY settings.xml /etc/maven/settings.xml
RUN chmod +x /usr/bin/jenkins-slave
COPY helm kubectl /usr/bin/
ENTRYPOINT [“jenkins-slave”]

注解:
settings.xml文件的mirror设置公司内的neux地址
启动的jenkins slave没有docker命令打包镜像,需要挂载宿主机的docker
创建secret认证用于外部链接到k8s

1.4 #在jenkins添加registry认证
在ms命名空间下创建
k8s拉取私库镜像创建的secret只能在相同namespace下使用该secret,所以修改一个命令
kubectl create secret docker-registry registry-pull-secret --docker-server=192.168.175.59 --docker-username=admin --docker-password=123456 -n sie
注解:这里使用的账号密码是harbor的登陆密码,-n sie 是这个secret只能在相同namespace下使用该secret。

在jenkins添加harbor凭据,然后copy生成的ID,推送镜像认证;

在jenkins添加git认证,凭据,然后copy生成的ID,推送镜像认证

把上面 “二、创建kubeconfig文件” 步骤生成的config文件内容拷贝到jenkins上,Jenkins–》Managed添加一个文件,type选择Custom file,然后复制ID到k8s_auth

四、Jenkins上创建job
1.1 创建一个流水线
在这里插入图片描述

1.2 填写描述这个job是哪个平台服务
在这里插入图片描述

1.3 构建保留天数及次数
在这里插入图片描述

1.4 填写流水线脚本
在这里插入图片描述

#!/usr/bin/env groovy
// 所需插件: Git Parameter/Git/Pipeline/Config File Provider/kubernetes/Extended Choice Parameter
// 公共
def registry = "192.168.175.59"
// 项目
def project = "test"
def git_url = "http://xx.git"
def gateway_domain_name = "gateway.dev.com"
def portal_domain_name = "portal.dev.com"
// 认证
def image_pull_secret = "registry-pull-secret"
def harbor_registry_auth = "ss3a73" //在Jenkins上添加的harbor凭据生成的ID
def git_auth = "9s-3ss3d2ss7010a9" //在Jenkins上添加的gitlab凭据生成的ID
// ConfigFileProvider ID
def k8s_auth = "6c318se745"  //在Jenkins上添加的k8s的config配置文件生成的ID

pipeline {
  agent {
    kubernetes {
        label "jenkins-slave"
        yaml """
kind: Pod
metadata:
  name: jenkins-slave
spec:
  containers:
  - name: jnlp
    image: "${registry}/library/jenkins-slave-jdk-nodejs: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
      hostPath:
        path: /tmp/m2
"""
        }
      
      }
    parameters {
        gitParameter branch: '', branchFilter: '.*', defaultValue: '', description: '选择发布的分支', name: 'Branch', quickFilterEnabled: false, selectedValue: 'NONE', sortMode: 'NONE', tagFilter: '*', type: 'PT_BRANCH'        
        extendedChoice defaultValue: 'none', description: '选择发布的微服务', \
          multiSelectDelimiter: ',', name: 'Service', type: 'PT_CHECKBOX', \
          value: '1002-sieiot-gateway:9020'
        choice (choices: ['ms', 'demo'], description: '部署模板', name: 'Template')
        choice (choices: ['1', '3', '5', '7'], description: '副本数', name: 'ReplicaCount')
        choice (choices: ['sie'], description: '命名空间', name: 'Namespace')
    }
    stages {
        stage('拉取代码'){
            steps {
                checkout([$class: 'GitSCM', 
                branches: [[name: "${params.Branch}"]], 
                doGenerateSubmoduleConfigurations: false, 
                extensions: [], submoduleCfg: [], 
                userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_url}"]]
                ])
            }
        }
        stage('代码编译') {
            // 编译指定服务
            steps {
                sh """
                  mvn clean package -Dmaven.test.skip=true
                """
            }
        }
        stage('构建镜像') {
          steps {
              withCredentials([usernamePassword(credentialsId: "${harbor_registry_auth}", passwordVariable: 'password', usernameVariable: 'username')]) {
                sh """
                 docker login -u ${username} -p '${password}' ${registry}
                 for service in \$(echo ${Service} |sed 's/,/ /g'); do
                    service_name=\${service%:*}
                    image_name=${registry}/${project}/\${service_name}:${BUILD_NUMBER}
                    cd \${service_name}
                    docker build -t \${image_name} .
                    docker push \${image_name}
                    cd ${WORKSPACE}
                  done
                """
                configFileProvider([configFile(fileId: "${k8s_auth}", targetLocation: "admin.kubeconfig")]){
                    sh """
                    # 添加镜像拉取认证
                    kubectl create secret docker-registry ${image_pull_secret} --docker-username=${username} --docker-password=${password} --docker-server=${registry} -n ${Namespace} --kubeconfig admin.kubeconfig |true
                    # 添加私有chart仓库
                    helm repo add  --username ${username} --password ${password} myrepo http://${registry}/chartrepo/${project}
                    """
                }
              }
          }
        }
        stage('Helm部署到K8S') {
          steps {
              sh """
              common_args="-n ${Namespace} --kubeconfig admin.kubeconfig"
              
              for service in  \$(echo ${Service} |sed 's/,/ /g'); do
                service_name=\${service%:*}
                service_port=\${service#*:}
                image=${registry}/${project}/\${service_name}
                tag=${BUILD_NUMBER}
                helm_args="\${service_name} --set image.repository=\${image} --set image.tag=\${tag} --set replicaCount=${replicaCount} --set imagePullSecrets[0].name=${image_pull_secret} --set service.port=\${service_port} --set service.type=NodePort --set service.nodePort=\${service_port} --set service.targetPort=\${service_port} myrepo/${Template}"

                # 判断是否为新部署
                if helm history \${service_name} \${common_args} &>/dev/null;then
                  action=upgrade
                else
                  action=install
                fi

                # 针对服务启用ingress
                if [ \${service_name} == "1002-sieiot-gateway" ]; then
                  helm \${action} \${helm_args} \
                  --set ingress.enabled=true \
                  --set ingress.host=${gateway_domain_name} \
                   \${common_args}
                elif [ \${service_name} == "portal-service" ]; then
                  helm \${action} \${helm_args} \
                  --set ingress.enabled=true \
                  --set ingress.host=${portal_domain_name} \
                   \${common_args}
                else
                  helm \${action} \${helm_args} \${common_args}
                fi
              done
              # 查看Pod状态
              sleep 10
              kubectl get pods \${common_args}
              """
          }
        }
    }
}

因为这里是使用helm的chart模板进行部署服务的,所以在构建前需要把模板push到harbor仓库中,此模板位于k8s-master01的/home/bak目录下。
helm push ms-0.1.0.tgz --username=admin --password=123456 http://192.168.175.59/chartrepo/dev-sie
在这里插入图片描述

1.5 然后执行构建
在这里插入图片描述

第一次执行会报错,因为这是还没有拉取git代码并且没有获取到分支列表。
如下是执行成功的界面
在这里插入图片描述

五、Jenkins上创建job(构建上传镜像并生成成品文件
创建工程,填写工程名字及选择流水线
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

填写流水线内容
在这里插入图片描述

上图中pipeline内容
`#!/usr/bin/env groovy
// 所需插件: Git Parameter/Git/Pipeline/Config File Provider/kubernetes/Extended Choice Parameter
// 公共
def registry = “192.168.1.195” //harbor项目地址
// 项目
def project = “uat-sie” //harbor项目名
def git_url = “xxxx.git” //项目gitlab地址
// 认证
def image_pull_secret = “registry-pull-secret”
def harbor_registry_auth = “8f3xxx3c92” //在Jenkins上添加的harbor凭据生成的ID
def git_auth = “c3b554b2-xxx” //在Jenkins上添加的gitlab凭据生成的ID
// ConfigFileProvider ID
def k8s_auth = “bxxcc89a” //在Jenkins上添加的k8s的config配置文件生成的ID
pipeline {
agent {
kubernetes {
label “jenkins-slave”
yaml “”"
kind: Pod
metadata:
name: jenkins-slave
spec:
containers:

  • name: jnlp
    image: “${registry}/library/jenkins-slave:v1”
    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
      hostPath:
      path: /tmp/m2
      “”"
      }
      }
      parameters {
      gitParameter branch: ‘’, branchFilter: ‘.’, defaultValue: ‘’, description: ‘选择发布的分支’, name: ‘Branch’, quickFilterEnabled: false, selectedValue: ‘NONE’, sortMode: ‘NONE’, tagFilter: '’, type: ‘PT_BRANCH’
      extendedChoice defaultValue: ‘none’, description: ‘选择发布的微服务’,
      multiSelectDelimiter: ‘,’, name: ‘Service’, type: ‘PT_CHECKBOX’,
      value: ‘1002-sieiot-gateway:9020’
      choice (choices: [‘test’], description: ‘命名空间’, name: ‘Namespace’)
      }
      stages {
      stage(‘拉取代码’){
      steps {
      checkout([ c l a s s : ′ G i t S C M ′ , b r a n c h e s : [ [ n a m e : " class: 'GitSCM', branches: [[name: " class:GitSCM,branches:[[name:"{params.Branch}"]],
      doGenerateSubmoduleConfigurations: false,
      extensions: [], submoduleCfg: [],
      userRemoteConfigs: [[credentialsId: “ g i t a u t h " , u r l : " {git_auth}", url: " gitauth",url:"{git_url}”]]
      ])
      }
      }
      stage(‘代码编译’) {
      // 编译指定服务
      steps {
      sh “”"
      for service in $(echo ${Service} |sed ‘s/,/ /g’); do
      service_name=${service%:}
      cd ${service_name}
      mvn clean install -Dmaven.test.skip=true
      done
      “”"
      }
      }
      stage(‘构建镜像’) {
      steps {
      withCredentials([usernamePassword(credentialsId: “${harbor_registry_auth}”, passwordVariable: ‘password’, usernameVariable: ‘username’)]) {
      sh “”"
      docker login -u u s e r n a m e − p ′ {username} -p ' usernamep{password}’ ${registry}
      for service in $(echo ${Service} |sed ‘s/,/ /g’); do
      service_name=${service%:
      }
      service_port=${service#:}
      image_name= r e g i s t r y / {registry}/ registry/{project}/${service_name}😒{BUILD_NUMBER}
      cd ${service_name}
      sed -i ‘s#192.168.175.59#192.168.1.195#g’ Dockerfile
      sed -i ‘s#139.159.228.191#192.168.1.195#g’ Dockerfile
      sed -i ‘s#sit#uat#g’ Dockerfile
      sed -i “s#1002-sieiot-gateway#${service_name}#g” Dockerfile
      sed -i “s#9020#${service_port}#g” Dockerfile
      sed -i “s#-jar#-javaagent:/opt/sw/agent/skywalking-agent.jar -Dskywalking.agent.service_name=${service_name} -jar#g” Dockerfile
      docker build -t ${image_name} .
      docker push ${image_name}
      cd ${WORKSPACE}
      docker rmi ${image_name}
      done
      “”"
      }
      }
      }
      stage(“Trigger File”){
      steps {
      script{
      sh “”"
      for service in $(echo ${Service} |sed ‘s/,/ /g’); do
      service_name=${service%:
      }
      service_port=${service#*:}
      echo IMAGE= r e g i s t r y / {registry}/ registry/{project}/${service_name}😒{BUILD_NUMBER} >trigger.properties
      echo ACTION=DEPLOY >> trigger.properties
      echo PORT=${service_port} >> trigger.properties
      echo SERVICE=${service_name} >> trigger.properties
      cat trigger.properties
      done
      “”"
      archiveArtifacts allowEmptyArchive: true, artifacts: ‘trigger.properties’, followSymlinks: false
      }
      }
      }
      }
      }`
      最终生成
      在这里插入图片描述

六、Jenkins的架构大概如下图所示

七、目前k8s测试环境流程大概如下:
在这里插入图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

划水的运维

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值