Jenkins pipeline 发布k8s应用
1.容器镜像仓库 harbor
2.应用的基础镜像
3.Jenkins pipeline
首先制作好应用的基础镜像,上传到容器仓库中
然后设置Jenkins ,用Jenkins 发布k8s 需要安装一个插件,在插件管理中搜索 Kubernetes
Jenkins 2.346.2 后的的版本 你可以在系统管理-节点管理中找到这个插件配置
注意看下面的配置步骤
在k8s服务器master 主机中 打开 more /root/.kube/config
取出 certificate-authority-data : 后面的内容注意不要有换行,创建一个 1-certificate-authority-data 导入该内容
取出 client-certificate-data : 后面的内容注意不要有换行,创建一个 2-client-certificate-data 导入该内容
取出 client-key-data : 后面的内容注意不要有换行,创建一个 3-client-key-data 导入该内容
cat 1-certificate-authority-data | base64 -d > ca.crt # 把ca.crt的内容 填入 Kubernetes 服务证书 key
cat 2-client-certificate-data |base64 -d > client.crt
cat 3-client-key-data |base64 -d > client.key
openssl pkcs12 -export -out cert.pfx -inkey client.key -in client.crt -certfile ca.crt
# 输入一个你记得住的密码
# 下载 cert.pfx 到本地
添加Jenkins凭据
选择 连接测试 ,成功 OK
下面是Jenkins pipeline 脚本
pipeline {
agent any
//变量
environment {
//job名称
def webName = "${JOB_NAME}"
//构建的序号
def BuildNumber = "${BUILD_NUMBER}"
//docker镜像仓库地址
def REPOSITORY="harbor.dev.local/devj/app/${webName}:${BuildNumber}"
}
stages{
//拉取代码
stage('拉取代码'){
when{expression{ "${Status}" == 'Deploy' }}
steps{
//使用Jenkins自带的片段生成器生成拉代码的命令
checkout([$class: 'GitSCM', branches: [[name: '*/${version}']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: '5cd8b974-7cbc-16c1301', url: 'http://2.18.18.7:77/j/${repository}']]])
}
}
//是否需要替换程序中默认的配置文件
stage('替换配置'){
when{
expression{ "${Status}" == 'Deploy' }
expression{ "${configFile}" != 'off' }
}
steps{
script{
if ("${module}" == 'off') {sh "yes|cp -a ${configFile} ${WORKSPACE}/src/main/resources"}
else {sh "yes|cp -a ${configFile} ${WORKSPACE}/${module}/src/main/resources"}
}
}
}
//构建jar包
stage('构建'){
when{expression{ "${Status}" == 'Deploy' }}
tools { jdk "jdk"}
steps{
echo "ok"
sh "java -version"
script{
if ("${module}" == 'off') {sh "/opt/soft/maven/bin/mvn clean install -am -U -Dmaven.test.skip=true"}
else{sh "/opt/soft/maven/bin/mvn clean install -pl $module -am -U -Dmaven.test.skip=true"}
}
}
}
//编写dockerfile后打包镜像并上传到私有镜像仓库
stage('镜像'){
when{expression{ "${Status}" == 'Deploy' }}
steps{
script{
//找到构建成功的 jar 包绝对路径
if ("${module}" == 'off') {
jarFile = sh (
script: 'find $WORKSPACE/target -name *.jar',
returnStdout: true
).trim()
}
else{
jarFile = sh (
script: 'find $WORKSPACE/${module}/target -name *.jar',
returnStdout: true
).trim()
}
//提取jar包名称
jarFileName = sh (
script: "(basename '${jarFile}')",
returnStdout: true
).trim()
}
echo "${jarFile} ${jarFileName}"
sh """
mkdir -p dockerfile
cd dockerfile
yes|cp -a ${jarFile} .
cat > Dockerfile << EOF
#jdk 基础镜像
FROM registry.cn-hangzhou.aliyuncs.com/basis_env/alpine-glibc-jdk:1
WORKDIR /opt/${webName}
ADD ${jarFileName} .
EXPOSE ${jarPort}
CMD ["/opt/soft/jdk1.8.0_212/bin/java","-jar","/opt/${webName}/${jarFileName}","--spring.profiles.active=dev","--server.port=${jarPort}"]
EOF
docker build -t $REPOSITORY .
docker push $REPOSITORY
docker image rm $REPOSITORY |true
"""
}
}
//编排 yaml 文件
stage('编排'){
when{expression{ "${Status}" == 'Deploy' }}
steps{
sh """
cat > ${webName}.yaml << EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: ${webName}
namespace: dev
spec:
selector:
matchLabels:
app: ${webName}-lable
replicas: 1
minReadySeconds: 60
template:
metadata:
labels:
app: ${webName}-lable
spec:
#pod亲和性设置 同类型pod尽量不分配在同一个node
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- ${webName}-lable
topologyKey: kubernetes.io/hostname
imagePullSecrets:
- name: registry-harbor-dev-local
containers:
- name: ${webName}
image: ${REPOSITORY}
ports:
- containerPort: ${jarPort}
hostAliases:
- ip: 192.168.18.156
hostnames:
- "rmq.j.local"
EOF
cat > ${webName}-server.yaml << EOF
apiVersion: v1
kind: Service
metadata:
name: ${webName}
namespace: dev
spec:
type: ClusterIP
selector:
app: ${webName}-lable
ports:
- port: 80
protocol: TCP
targetPort: ${jarPort}
EOF
mkdir -p /data/jenkinsbak${WORKSPACE}/${BuildNumber}
cp -a ${webName}.yaml /data/jenkinsbak${WORKSPACE}/${BuildNumber}/
cp -a ${webName}-server.yaml /data/jenkinsbak${WORKSPACE}/${BuildNumber}/
"""
}
}
//发布
stage('发布'){
when{expression{ "${Status}" == 'Deploy' }}
steps{
echo "deploy"
withKubeConfig([credentialsId: 'aea9b-f05-435c-8a61-43516c9', serverUrl: 'https://12.18.18.10:6443']) {
sh "/opt/kubectl/kubectl apply -f ${webName}.yaml"
sh "/opt/kubectl/kubectl get pods -n dev"
}
}
}
//回滚
stage('回滚'){
when{expression{ "${Status}" == 'Rollback' }}
steps{
echo "Rollback"
withKubeConfig([credentialsId: 'aeb-f5-5c-8a61-435f79', serverUrl: 'https://12.18.18.10:6443']) {
sh "/opt/kubectl/kubectl apply -f /data/jenkinsbak$WORKSPACE/$rollbackTag/${webName}.yaml"
}
}
}
//
}
}
创建Jenkins的发布项目使用上面的脚本, 自己修改下关键项,就可以了