groovy 脚本实例 创建和升级脚本
注意replace
package platform.jfrog_artifact.snapshot.mysql.empty2_docker_db
node('ecs_wuhan_docker') {
println "${BUILD_URL}console"
def xxlJob = ENVIRONMENT_NAME
def xxlJobIp = "192.168.61.53:80"
//ecs2.0-jenkins通知群
def wxKey = '79bc4571-2835-4458-9341-043ab3769436'
//失败信息通知运维处理人,李文超
def noticeTelNumber = '18201292571'
def jfrogBaseAddress = 'http://ecs_read:ecs_read@192.168.48.96:8081/artifactory'
def harborProject = 'ecs2-dev'
def nginxImage = "${HARBOR_ADDRESS}/${harborProject}/${ENVIRONMENT_NAME}-web:latest"
def javaImageConsole = "${HARBOR_ADDRESS}/${harborProject}/${ENVIRONMENT_NAME}-console-jar:latest"
def javaImageEcs = "${HARBOR_ADDRESS}/${harborProject}/${ENVIRONMENT_NAME}-ecs-jar:latest"
def nodeSelector = 'ecs2'
def dbDriver = 'com.mysql.jdbc.Driver'
def jdbcParam = "useUnicode=true\\&characterEncoding=UTF-8\\&useSSL=false\\&allowMultiQueries=true\\&rewriteBatchStatements=true\\&serverTimezone=GMT\\%2B8"
def consoleDbUrl = "jdbc:mysql:\\/\\/mysql:3306\\/yn_console?${jdbcParam}"
def ecsDbUrl = "jdbc:mysql:\\/\\/mysql:3306\\/yn_ecs?${jdbcParam}"
def helperDialect = "mysql"
def mysqlAdminUser = "ecs_dev"
def mysqlAdminPassword = "ecs_dev"
def branch = ENVIRONMENT_BRANCH
def hotfixNum = branch
// create,upgrade_java,upgrade_db,upgrade_web,clear_redis,all
def type = UPGRADE_TYPE.split("\\(")[0]
if (type == 'all') {
if (HOTFIX_VERSION == 'sameWithBranch') {
hotfixNum = ENVIRONMENT_BRANCH
} else {
hotfixNum = HOTFIX_VERSION
}
}
try {
stage('wx notice start') {
deleteDir()
if (type == "create") {
wxNotice("'${PROPOSER_NAME}'申请可升级hotfix环境: '${ENVIRONMENT_NAME}' 基于'${ENVIRONMENT_BRANCH}'分支 开始创建!", wxKey, PROPOSER_MOBILE)
}
}
parallel(
'java-console': {
if (type == "create" || type == "upgrade_java_console" || type == "all") {
stage('make console image') {
print("compile_java_upgrade console")
dir("image_console_dir") {
sh 'rm -rf console.jar application.yml application-dev.yml'
sh "curl -O ${jfrogBaseAddress}/ecs2_java_dev/SNAPSHOT/${hotfixNum}/java-ecs2/console/console.jar"
sh "curl -O ${jfrogBaseAddress}/ecs2_java_dev/SNAPSHOT/${hotfixNum}/java-ecs2/console/application.yml"
sh "curl -O ${jfrogBaseAddress}/ecs2_java_dev/SNAPSHOT/${hotfixNum}/java-ecs2/console/application-dev.yml"
def configFile = "application-dev.yml"
fixJavaConfigDataSource(configFile, dbDriver, consoleDbUrl, mysqlAdminUser, mysqlAdminPassword, helperDialect)
fixJavaConfigRedis(configFile)
fixJavaConfigYn(configFile, xxlJobIp, xxlJob + '-console')
fixEcsUrl(configFile)
makeJavaImageDockerfile('console.jar', '3g', '1g', '2g', '1g')
dockerPushImage(javaImageConsole)
}
}
}
},
'java-ecs': {
if (type == "create" || type == "upgrade_java_ecs" || type == "all") {
stage('make ecs image') {
dir("image_ecs_dir") {
sh 'rm -rf ecs.jar application.yml application-dev.yml'
sh "curl -O ${jfrogBaseAddress}/ecs2_java_dev/SNAPSHOT/${hotfixNum}/java-ecs2/ecs/ecs.jar"
sh "curl -O ${jfrogBaseAddress}/ecs2_java_dev/SNAPSHOT/${hotfixNum}/java-ecs2/ecs/application.yml"
sh "curl -O ${jfrogBaseAddress}/ecs2_java_dev/SNAPSHOT/${hotfixNum}/java-ecs2/ecs/application-dev.yml"
def configFile = "application-dev.yml"
fixJavaConfigDataSource(configFile, dbDriver, ecsDbUrl, mysqlAdminUser, mysqlAdminPassword, helperDialect)
fixJavaConfigRedis(configFile)
fixJavaConfigYn(configFile, xxlJobIp, xxlJob + '-ecs')
fixConsoleUrl(configFile)
makeJavaImageDockerfile('ecs.jar', '4g', '1g', '2g', '1g')
dockerPushImage(javaImageEcs)
}
}
}
},
'web': {
if (type == "create" || type == "upgrade_web" || type == "all") {
stage('make web image') {
dir("image_web_dir") {
for (item in ['designer', 'ecs-console', 'ecs_console', 'fssc-web', 'ecs-web', 'ecs-console-mobile', 'ecs_console_mobile', 'ecs-mobile']) {
print("download web html ${item}")
sh "curl -O ${jfrogBaseAddress}/ecs2_java_dev/SNAPSHOT/${hotfixNum}/html/${item}.zip"
sh "rm -rf ${item};unzip ${item}.zip || echo 'skip step'"
sh "tar rvf ecs.tar.gz ${item} || echo 'skip step'"
}
makeNginxImageDockerFile('ecs.tar.gz')
dockerPushImage(nginxImage)
}
}
}
},
'db': {
if (type == "create") {
stage('create schema on mysql') {
retry(5) {
checkNamespace()
}
createEmptyMysql(nodeSelector)
def shell = "rancher kubectl get node -o wide|grep `rancher kubectl get pods -n ${ENVIRONMENT_NAME} -o wide |grep mysql| awk '{print \$7}'`\\ | awk '{print \$6}'"
def mysqlIp = sh(returnStdout: true, script: shell).trim()
createMysqlK8s(nodeSelector, mysqlIp)
rancherDeployMysql()
}
}
if (type == "create" || type == "upgrade_db" || type == "all") {
stage('upgrade db') {
String mysqlPort = getMysqlPort()
dir('upgrade_db') {
sh "curl -O ${jfrogBaseAddress}/ecs2_java_dev/SNAPSHOT/${hotfixNum}/java-ecs2/upgrade/upgrade.zip"
parallel(
'db_console': {
stage('upgrade db_console') {
dir('upgrade_db_console') {
sh 'unzip ../upgrade.zip'
dir('config') {
sh "curl -O ${jfrogBaseAddress}/ecs2_java_dev/SNAPSHOT/${hotfixNum}/java-ecs2/metadata/console-metadata/metadata.zip"
upgradeDb(dbDriver, consoleDbUrl.replace('mysql:3306', "192.168.48.85:${mysqlPort}"), mysqlAdminUser, mysqlAdminPassword, helperDialect)
sh 'rm -rf metadata.zip'
sh "curl -O ${jfrogBaseAddress}/ecs2_java_dev/SNAPSHOT/${hotfixNum}/java-ecs2/metadata/console-custom-metadata/metadata.zip"
try {
upgradeDb(dbDriver, consoleDbUrl.replace('mysql:3306', "192.168.48.85:${mysqlPort}"), mysqlAdminUser, mysqlAdminPassword, helperDialect)
} catch (ignored) {
}
}
}
}
},
'db_ecs': {
stage('upgrade db_ecs') {
dir('upgrade_db_ecs') {
sh 'unzip ../upgrade.zip'
dir('config') {
sh "curl -O ${jfrogBaseAddress}/ecs2_java_dev/SNAPSHOT/${hotfixNum}/java-ecs2/metadata/ecs-metadata/metadata.zip"
upgradeDb(dbDriver, ecsDbUrl.replace('mysql:3306', "192.168.48.85:${mysqlPort}"), mysqlAdminUser, mysqlAdminPassword, helperDialect)
}
}
}
}
)
}
}
}
}
)
createKubernetesDeployment(nodeSelector, nginxImage, javaImageConsole, javaImageEcs)
if (type == "create") {
stage('create kubernetes.yml') {
rancherDeploy()
}
}
parallel(
"upgrade_java_console": {
if (type == "upgrade_java_console" || type == "all") {
stage('upgrade java console') {
rancherUpdateDeploy('java-console')
}
}
},
"upgrade_java_ecs": {
if (type == "upgrade_java_ecs" || type == "all") {
stage('upgrade java ecs') {
rancherUpdateDeploy('java-ecs')
}
}
},
"upgrade_java_web": {
if (type == "upgrade_web" || type == "all") {
stage('upgrade web') {
rancherUpdateDeploy('nginx')
}
}
},
)
if (type == "upgrade_db" || type == "clear_redis" || type == "all") {
stage('clear Redis') {
clearRedis()
}
}
if (type == "all") {
stage('upgrade all') {
wxNotice("'${PROPOSER_NAME}'升级环境环境: '${ENVIRONMENT_NAME}' 基于'${ENVIRONMENT_BRANCH}'分支 升级成功!", wxKey, PROPOSER_MOBILE)
executeSql("update T_ENVIRONMENT_MANAGER set ENVIRONMENT_BRANCH = '${hotfixNum}' where ENVIRONMENT_NAME = '${ENVIRONMENT_NAME}'")
}
}
if (type == "create") {
stage('wx notice start') {
wxNotice("'${PROPOSER_NAME}'申请环境: '${ENVIRONMENT_NAME}' 基于'${ENVIRONMENT_BRANCH}'分支 创建成功!", wxKey, PROPOSER_MOBILE)
}
}
} catch (e) {
wxFailNotice(wxKey, noticeTelNumber)
throw e
} finally {
println "${BUILD_URL}console"
deleteDir()
executeSql("update T_ENVIRONMENT_MANAGER set UPDATE_DATE = NOW() where ENVIRONMENT_NAME = '${ENVIRONMENT_NAME}'")
}
}
def getMysqlPort() {
//3306:28383/TCP
String portStr = sh(returnStdout: true, script: "rancher kubectl get svc -n ${ENVIRONMENT_NAME} |grep mysql|awk '{print \$5}'").trim()
println portStr
return portStr.replace('3306:', '').replace('/TCP', '')
}
def checkNamespace() {
sleep time: 1, unit: 'MINUTES'
String updateMsg = sh(returnStdout: true, script: "rancher kubectl get namespace|grep ${ENVIRONMENT_NAME}").trim()
println updateMsg
if (updateMsg.contains(ENVIRONMENT_NAME)) {
println "${ENVIRONMENT_NAME}命名空间已经创建成功!"
} else {
throw new Exception(updateMsg)
}
}
def createEmptyMysql(NODE_SELECTOR) {
String text = """
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
namespace: ${ENVIRONMENT_NAME}
spec:
selector:
matchLabels:
app: mysql
serviceName: "mysql"
replicas: 1
template:
metadata:
labels:
app: mysql
spec:
nodeSelector:
productLine: ${NODE_SELECTOR}
containers:
- name: mysql
image: 192.168.48.90:80/ecs2-dev/mysql-ecs-empty:latest
imagePullPolicy: Always
resources:
requests:
memory: 500Mi
limits:
memory: 2Gi
env:
- name: MYSQL_ROOT_PASSWORD
value: '123456'
ports:
- name: mysql-port
containerPort: 3306
protocol: TCP
"""
println text
writeFile file: 'mysql-empty-k8s.yml', text: text, encoding: "UTF-8"
sh "rancher kubectl apply -f mysql-empty-k8s.yml"
}
def createMysqlK8s(NODE_SELECTOR, mysqlIp) {
String text = """
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql-config
namespace: ${ENVIRONMENT_NAME}
data:
my.cnf: |
[client]
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4
[mysqld]
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/mysql
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
max_connections = 5000
default-time-zone = '+8:00'
sql_mode = NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
transaction_isolation = READ-COMMITTED
max_allowed_packet = 8g
innodb_log_buffer_size = 167772160
innodb_log_file_size = 1024M
innodb_strict_mode = 0
max_heap_table_size = 512M
wait_timeout = 864000
interactive_timeout = 864000
disable-log-bin
---
apiVersion: v1
kind: Service
metadata:
name: mysql
namespace: ${ENVIRONMENT_NAME}
spec:
type: NodePort
ports:
- name: mysql-port
protocol: TCP
port: 3306
selector:
app: mysql
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
namespace: ${ENVIRONMENT_NAME}
spec:
selector:
matchLabels:
app: mysql
serviceName: "mysql"
replicas: 1
template:
metadata:
labels:
app: mysql
spec:
nodeSelector:
productLine: ${NODE_SELECTOR}
internal-ip: ${mysqlIp}
containers:
- name: mysql
image: 192.168.48.90:80/ecs2-dev/mysql-ecs-empty:latest
imagePullPolicy: Always
resources:
requests:
memory: 500Mi
limits:
memory: 2Gi
env:
- name: MYSQL_ROOT_PASSWORD
value: '123456'
ports:
- name: mysql-port
containerPort: 3306
protocol: TCP
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
- name: config-volume
mountPath: /etc/mysql/conf.d
readinessProbe:
tcpSocket:
port: 3306
initialDelaySeconds: 30
periodSeconds: 30
timeoutSeconds: 5
failureThreshold: 40
volumes:
- name: mysql-persistent-storage
hostPath:
path: /data/mysql/${ENVIRONMENT_NAME}
type: DirectoryOrCreate
- name: config-volume
configMap:
name: mysql-config
"""
println text
writeFile file: 'mysql-k8s.yml', text: text, encoding: "UTF-8"
}
def rancherDeployMysql() {
try {
sh """
rancher kubectl apply -f mysql-k8s.yml
rancher kubectl rollout status StatefulSet mysql -n ${ENVIRONMENT_NAME}
"""
} catch (e) {
throw e
}
}
def executeSql(sql) {
def remote = [:]
remote.name = 'mysqlServer'
remote.host = "192.168.61.52"
remote.allowAnyHosts = true
remote.user = "root"
remote.password = "A09QXN2Ds1w5NDSN"
sshCommand remote: remote, failOnError: false, command: "mysql -uroot -pYuaNian@2999! -D ecs-cicd -e \"${sql}\""
}
def wxFailNotice(wxKey, noticeTelNumber) {
def proposerName = PROPOSER_NAME
def jobName = JOB_NAME
def text = "<font color=info>【${proposerName}的${jobName}】</font>任务执行<font color=warning>失败!!!</font>\\n >[查看控制台](${BUILD_URL}console)"
sh """curl 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key='${wxKey}'' -H 'Content-Type: application/json' -d '{ "msgtype": "markdown", "markdown": { "content": "${text}", } }'"""
sh """curl 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key='${wxKey}'' -H 'Content-Type: application/json' -d '{ "msgtype": "text", "text": { "mentioned_mobile_list":["${noticeTelNumber}"] } }'"""
}
def wxNotice(msg, wxKey, proposerMobile) {
sh """
curl 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=${wxKey}' \
-H 'Content-Type: application/json' \
-d '
{
"msgtype": "text",
"text": {
"content": "${msg}",
"mentioned_mobile_list":["${proposerMobile}"]
}
}'
"""
}
def fixJavaConfigDataSource(configFile, dbDriver, dbUrl, dbName, dbPassword, helperDialect) {
sh "sed -i 's/helperDialect: .*/helperDialect: ${helperDialect}/g' ${configFile}"
sh "sed -i 's/url: jdbc.*/url: ${dbUrl}/g' ${configFile}"
sh "sed -i 's/driver-class-name: .*/driver-class-name: ${dbDriver}/g' ${configFile}"
sh "sed -i 's/username: .*/username: ${dbName}/g' ${configFile}"
sh "sed -i 's/password: .*/password: ${dbPassword}/g' ${configFile}"
}
def fixJavaConfigYn(configFile, xxlJobIp, xxlJob) {
sh "sed -i 's/nameServers: .*/nameServers: 192.168.61.54:9876/g' ${configFile}"
sh "sed -i 's/addresses.*/addresses: http:\\/\\/'${xxlJobIp}'\\/xxl-job-admin/g' ${configFile}"
sh "sed -i 's/prefix: .*/prefix: ${ENVIRONMENT_NAME}/g' ${configFile}"
sh "sed -i 's/appname:.*/appname: ${xxlJob}/g' ${configFile}"
sh "sed -i 's/businessid: .*/businessid: ${xxlJob}/g' ${configFile}"
sh "sed -i 's/title:.*/title: ${xxlJob}/g' ${configFile}"
sh "sed -i 's/fastjsonType:.*/fastjsonType: fastjson2/g' ${configFile}"
}
def fixConsoleUrl(configFile) {
sh "sed -i 's/console:8095/java-console:8095/g' ${configFile}"
}
def fixEcsUrl(configFile) {
sh "sed -i 's/masterdata-service-url:.*/masterdata-service-url: http:\\/\\/java-ecs:8096\\//g' ${configFile}"
}
def fixJavaConfigRedis(configFile) {
sh "sed -i 's/host: .*/host: redis/g' ${configFile}"
sh "sed -i 's/database: .*/database: 0/g' ${configFile}"
sh "sed -i 's/port: \${redis_port:.*/port: 6379/g' ${configFile}"
sh "sed -i '0,/password:.*/s/password:.*/password: /' ${configFile}"
}
def makeJavaImageDockerfile(jarName, xmx, xms, maxMetaspaceSize, metaspaceSize) {
String text = """FROM 192.168.48.90:80/ecs-component/ecs-openjre:8
MAINTAINER ecs@yuanian.com
LABEL description="ecs-micro"
COPY ${jarName} /app.jar
COPY application.yml /application.yml
COPY application-dev.yml /application-dev.yml
ENV JAVA_OPT="-Xmx${xmx} -Xms${xms} -XX:MaxMetaspaceSize=${maxMetaspaceSize} -XX:MetaspaceSize=${metaspaceSize} -Dfile.encoding=utf-8"
CMD java -Dapp.log.projectName=ledger -Dapp.log.serviceName=${ENVIRONMENT_NAME} \${JAVA_OPT} -jar app.jar
"""
println text
writeFile file: 'Dockerfile', text: text, encoding: "UTF-8"
}
def makeNginxImageDockerFile(tarName) {
createNginxConf()
String text = """FROM nginx:1.17.0
MAINTAINER ecs@yuanian.com
LABEL description="ecs-micro"
ADD ${tarName} /usr/share/nginx/html
COPY nginx.conf /etc/nginx
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/\$TZ /etc/localtime && echo \$TZ > /etc/timezone
CMD ["nginx", "-g", "daemon off;"]
"""
println text
writeFile file: 'Dockerfile', text: text, encoding: "UTF-8"
}
def dockerPushImage(image_name) {
sh """
docker login -u ${HARBOR_USERNAME} -p ${HARBOR_PASSWORD} http://${HARBOR_ADDRESS}
docker build -t ${image_name} .
docker push ${image_name}
docker rmi -f ${image_name}
"""
}
def rancherDeploy() {
try {
sh """
rancher kubectl create -f k8s-Deployment.yml
"""
} catch (e) {
shNotThrowError("rancher kubectl delete --all deployment -n ${ENVIRONMENT_NAME}")
throw e
}
createKubernetesSvc()
try {
sh "rancher kubectl create -f k8s-svc.yml"
} catch (e) {
shNotThrowError("rancher kubectl delete --all deployment -n ${ENVIRONMENT_NAME}")
shNotThrowError("rancher kubectl delete --all svc -n ${ENVIRONMENT_NAME}")
shNotThrowError("rancher kubectl delete --all ingress -n ${ENVIRONMENT_NAME}")
throw e
}
}
def shNotThrowError(shell) {
try {
sh shell
} catch (ignored) {
println 'not throw exception'
}
}
def rancherUpdateDeploy(deploymentName) {
sh """
rancher kubectl rollout restart deployment ${deploymentName} -n ${ENVIRONMENT_NAME}
"""
String updateMsg = sh(returnStdout: true, script: "rancher kubectl rollout status deployment ${deploymentName} -n ${ENVIRONMENT_NAME}").trim()
println updateMsg
if (updateMsg.contains('successfully rolled out')) {
println "${deploymentName} 升级成功"
} else {
throw new Exception(updateMsg)
}
}
def upgradeDb(dbDriver, dbUrl, dbName, dbPassword, helperDialect) {
//server.port=8089
//dbType=oracle
//spring.datasource.url=jdbc:oracle:thin:@192.168.12.104:1521:yndev
//spring.datasource.username=ecs_md
//spring.datasource.password=ecs_md
//spring.datasource.driverClassName=oracle.jdbc.driver.OracleDriver
def configFile = "application.properties"
sh "sed -i 's/dbType=.*/dbType=${helperDialect}/g' ${configFile}"
sh "sed -i 's/server.port=.*/server.port=8888/g' ${configFile}"
sh "sed -i 's/spring.datasource.url=.*/spring.datasource.url=${dbUrl}/g' ${configFile}"
sh "sed -i 's/spring.datasource.username=.*/spring.datasource.username=${dbName}/g' ${configFile}"
sh "sed -i 's/spring.datasource.password=.*/spring.datasource.password=${dbPassword}/g' ${configFile}"
sh "sed -i 's/spring.datasource.driverClassName=.*/spring.datasource.driverClassName=${dbDriver}/g' ${configFile}"
withDockerContainer(image: '192.168.48.90:80/ecs-component/ecs-openjre:8') {
sh "java -Xmx2g -Xms1g -Dfile.encoding=utf-8 -jar ecs-upgrade-app.jar"
}
}
def clearRedis() {
def redisPodName = sh(returnStdout: true, script: "rancher kubectl get pods -n ${ENVIRONMENT_NAME} | grep redis | awk '{print \$1}'").trim()
sh "rancher kubectl exec -it ${redisPodName} -c redis -n ${ENVIRONMENT_NAME} -- redis-cli -h 127.0.0.1 flushall"
}
def createKubernetesDeployment(NODE_SELECTOR, NGINX_IMAGE, JAVA_IMAGE_CONSOLE, JAVA_IMAGE_ECS) {
String text = """
apiVersion: v1
kind: PersistentVolume
metadata:
name: ${ENVIRONMENT_NAME}-pv
namespace: ${ENVIRONMENT_NAME}
spec:
capacity:
storage: 2Gi
accessModes:
- ReadWriteMany
storageClassName: nfs
nfs:
path: /opt/fonts
server: 192.168.48.33
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: ${ENVIRONMENT_NAME}-pvc
namespace: ${ENVIRONMENT_NAME}
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 2Gi
storageClassName: nfs
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
namespace: ${ENVIRONMENT_NAME}
spec:
selector:
matchLabels:
app: redis
replicas: 1
template:
metadata:
labels:
app: redis
spec:
nodeSelector:
productLine: ${NODE_SELECTOR}
containers:
- name: redis
image: 192.168.48.90:80/ecs-component/ecs-redis:6.0
imagePullPolicy: Always
ports:
- name: redisport
containerPort: 6379
resources:
requests:
memory: 50Mi
limits:
memory: 1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: ${ENVIRONMENT_NAME}
spec:
selector:
matchLabels:
app: nginx
replicas: 1
template:
metadata:
labels:
app: nginx
spec:
volumes:
- name: logs
emptyDir: {}
nodeSelector:
productLine: ${NODE_SELECTOR}
containers:
- name: nginx
image: ${NGINX_IMAGE}
imagePullPolicy: Always
ports:
- name: serviceport
containerPort: 8080
resources:
requests:
memory: 50Mi
limits:
memory: 150Mi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: java-console
namespace: ${ENVIRONMENT_NAME}
spec:
selector:
matchLabels:
app: java-console
replicas: 1
template:
metadata:
labels:
app: java-console
spec:
volumes:
- name: logs
emptyDir: {}
- name: myfonts
persistentVolumeClaim:
claimName: ${ENVIRONMENT_NAME}-pvc
nodeSelector:
productLine: ${NODE_SELECTOR}
containers:
- name: java-console
image: ${JAVA_IMAGE_CONSOLE}
imagePullPolicy: Always
ports:
- name: consoleport
containerPort: 8095
env:
- name: JAVA_OPT
value: -Xmx2g -Xms1g -XX:MaxMetaspaceSize=512m -XX:MetaspaceSize=127m
resources:
requests:
memory: 1Gi
limits:
memory: 3Gi
volumeMounts:
- name: logs
mountPath: /target/logs
- name: myfonts
mountPath: /usr/share/fonts/
readinessProbe:
tcpSocket:
port: 8095
initialDelaySeconds: 60
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 20
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: java-ecs
namespace: ${ENVIRONMENT_NAME}
spec:
selector:
matchLabels:
app: java-ecs
replicas: 1
template:
metadata:
labels:
app: java-ecs
spec:
volumes:
- name: logs
emptyDir: {}
- name: myfonts
persistentVolumeClaim:
claimName: ${ENVIRONMENT_NAME}-pvc
nodeSelector:
productLine: ${NODE_SELECTOR}
containers:
- name: java-ecs
image: ${JAVA_IMAGE_ECS}
imagePullPolicy: Always
ports:
- name: debugport
containerPort: 8088
- name: ecsport
containerPort: 8096
env:
- name: JAVA_OPT
value: -Xmx3g -Xms1g -XX:MaxMetaspaceSize=512m -XX:MetaspaceSize=127m
- name: XDEBUG
value: -Xdebug -Xrunjdwp:transport=dt_socket,suspend=n,server=y,address=8088
resources:
requests:
memory: 2Gi
limits:
memory: 4Gi
volumeMounts:
- name: logs
mountPath: /target/logs
- name: myfonts
mountPath: /usr/share/fonts/
readinessProbe:
tcpSocket:
port: 8096
initialDelaySeconds: 60
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 20
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: cicd-callback
namespace: ${ENVIRONMENT_NAME}
spec:
selector:
matchLabels:
app: cicd-callback
replicas: 1
template:
metadata:
labels:
app: cicd-callback
spec:
volumes:
- name: logs
emptyDir: {}
nodeSelector:
productLine: ${NODE_SELECTOR}
containers:
- name: cicd-callback
image: 192.168.48.90:80/ecs-component/cicd-config-agent:1.1
imagePullPolicy: Always
env:
- name: proxy_infos
value: "[{host:'nginx',port:8080,contextPath:''}]"
resources:
requests:
memory: 100Mi
limits:
memory: 256Mi
ports:
- name: configport
containerPort: 8079
"""
println text
writeFile file: 'k8s-Deployment.yml', text: text, encoding: "UTF-8"
}
def createKubernetesSvc() {
String text = """
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: ${ENVIRONMENT_NAME}
spec:
type: NodePort
ports:
- name: serviceport
port: 8080
selector:
app: nginx
---
apiVersion: v1
kind: Service
metadata:
name: java-console
namespace: ${ENVIRONMENT_NAME}
spec:
type: NodePort
ports:
- name: consoleport
port: 8095
- name: debugport
port: 8088
selector:
app: java-console
---
apiVersion: v1
kind: Service
metadata:
name: java-ecs
namespace: ${ENVIRONMENT_NAME}
spec:
type: NodePort
ports:
- name: ecsport
port: 8096
- name: debugport
port: 8088
selector:
app: java-ecs
---
apiVersion: v1
kind: Service
metadata:
name: cicd-callback
namespace: ${ENVIRONMENT_NAME}
spec:
type: NodePort
ports:
- name: configport
port: 8079
selector:
app: cicd-callback
---
apiVersion: v1
kind: Service
metadata:
name: redis
namespace: ${ENVIRONMENT_NAME}
spec:
type: NodePort
ports:
- name: redisport
port: 6379
selector:
app: redis
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/proxy-body-size: "100M"
name: ${ENVIRONMENT_NAME}-ingress
namespace: ${ENVIRONMENT_NAME}
spec:
rules:
- host: ${ENVIRONMENT_NAME}.192.168.48.85.nip.io
http:
paths:
- backend:
serviceName: nginx
servicePort: 8080
"""
println text
writeFile file: 'k8s-svc.yml', text: text, encoding: "UTF-8"
}
def createNginxConf() {
String text = """
user root;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '\$remote_addr - \$remote_user [\$time_local] "\$request" '
'\$status \$body_bytes_sent "\$http_referer" '
'"\$http_user_agent" "\$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
gzip on;
gzip_types text/css
application/javascript text/plain application/json application/x-javascript
application/css application/xml application/xml+rss text/javascript
application/x-httpd-php image/jpeg image/gif image/png image/x-ms-bmp;
client_max_body_size 100M;
upstream ecsSrv {
server java-ecs:8096;
}
upstream ecs-console {
server java-console:8095;
}
server {
listen 8080;
server_name localhost;
location = / {
rewrite ^ \$scheme://\$http_host/ecs_console/index.html permanent;
}
location ~* \\.(css|js|html|map|gif|jpg|jpeg|png|ico|woff|woff2|svg|mp4|icon)\$ {
root /usr/share/nginx/html;
}
location ~ /console/ {
rewrite ^/console/(.*)\$ /\$1 break;
proxy_read_timeout 240s;
proxy_pass http://ecs-console;
}
location ~ /(ecs|designer|businessobject|datadictionary|distribution|filemanagement|flow|masterdata|rule|treemanager)/ {
rewrite ^/(ecs|designer|businessobject|datadictionary|distribution|filemanagement|flow|masterdata|rule|treemanager)?/(.*) /\$2 break;
proxy_read_timeout 240s;
proxy_pass http://ecsSrv;
}
location = /designer/ { index /designer/index.html; }
location = /ecs-console/ { index /ecs-console/index.html; }
location = /ecs_console/ { index /ecs_console/index.html; }
location = /ecs-console-mobile/ { index /ecs-console-mobile/index.html; }
location = /fssc-web/ { index /fssc-web/index.html; }
location = /ecs-web/ { index /ecs-web/index.html; }
location = /ecs-mobile/ { index /ecs-mobile/index.html; }
location = /ecs_console_mobile/ { index /ecs_console_mobile/index.html; }
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
real_ip_recursive on;
keepalive_timeout 65;
}
}
"""
println text
writeFile file: 'nginx.conf', text: text, encoding: "UTF-8"
}
注意replace的用法
package platform.jfrog_artifact.snapshot.mysql.empty2_docker_db
node('ecs_wuhan_docker') {
println "${BUILD_URL}console"
def xxlJob = ENVIRONMENT_NAME
def xxlJobIp = "192.168.61.53:80"
//ecs2.0-jenkins通知群
def wxKey = '79bc4571-2835-4458-9341-043ab3769436'
//失败信息通知运维处理人,李文超
def noticeTelNumber = '18201292571'
def jfrogBaseAddress = 'http://ecs_read:ecs_read@192.168.48.96:8081/artifactory'
def harborProject = 'ecs2-dev'
def nginxImage = "${HARBOR_ADDRESS}/${harborProject}/${ENVIRONMENT_NAME}-web:latest"
def javaImageConsole = "${HARBOR_ADDRESS}/${harborProject}/${ENVIRONMENT_NAME}-console-jar:latest"
def javaImageEcs = "${HARBOR_ADDRESS}/${harborProject}/${ENVIRONMENT_NAME}-ecs-jar:latest"
def nodeSelector = 'ecs2'
def dbDriver = 'com.mysql.jdbc.Driver'
def jdbcParam = "useUnicode=true\\&characterEncoding=UTF-8\\&useSSL=false\\&allowMultiQueries=true\\&rewriteBatchStatements=true\\&serverTimezone=GMT\\%2B8"
def consoleDbUrl = "jdbc:mysql:\\/\\/mysql:3306\\/yn_console?${jdbcParam}"
def ecsDbUrl = "jdbc:mysql:\\/\\/mysql:3306\\/yn_ecs?${jdbcParam}"
def helperDialect = "mysql"
def mysqlAdminUser = "ecs_dev"
def mysqlAdminPassword = "ecs_dev"
def branch = ENVIRONMENT_BRANCH
def hotfixNum = branch
// create,upgrade_java,upgrade_db,upgrade_web,clear_redis,all
def type = UPGRADE_TYPE.split("\\(")[0]
if (type == 'all') {
if (HOTFIX_VERSION == 'sameWithBranch') {
hotfixNum = ENVIRONMENT_BRANCH
} else {
hotfixNum = HOTFIX_VERSION
}
}
try {
stage('wx notice start') {
deleteDir()
if (type == "create") {
wxNotice("'${PROPOSER_NAME}'申请可升级hotfix环境: '${ENVIRONMENT_NAME}' 基于'${ENVIRONMENT_BRANCH}'分支 开始创建!", wxKey, PROPOSER_MOBILE)
}
}
parallel(
'java-console': {
if (type == "create" || type == "upgrade_java_console" || type == "all") {
stage('make console image') {
print("compile_java_upgrade console")
dir("image_console_dir") {
sh 'rm -rf console.jar application.yml application-dev.yml'
sh "curl -O ${jfrogBaseAddress}/ecs2_java_dev/SNAPSHOT/${hotfixNum}/java-ecs2/console/console.jar"
sh "curl -O ${jfrogBaseAddress}/ecs2_java_dev/SNAPSHOT/${hotfixNum}/java-ecs2/console/application.yml"
sh "curl -O ${jfrogBaseAddress}/ecs2_java_dev/SNAPSHOT/${hotfixNum}/java-ecs2/console/application-dev.yml"
def configFile = "application-dev.yml"
fixJavaConfigDataSource(configFile, dbDriver, consoleDbUrl, mysqlAdminUser, mysqlAdminPassword, helperDialect)
fixJavaConfigRedis(configFile)
fixJavaConfigYn(configFile, xxlJobIp, xxlJob + '-console')
fixEcsUrl(configFile)
makeJavaImageDockerfile('console.jar', '3g', '1g', '2g', '1g')
dockerPushImage(javaImageConsole)
}
}
}
},
'java-ecs': {
if (type == "create" || type == "upgrade_java_ecs" || type == "all") {
stage('make ecs image') {
dir("image_ecs_dir") {
sh 'rm -rf ecs.jar application.yml application-dev.yml'
sh "curl -O ${jfrogBaseAddress}/ecs2_java_dev/SNAPSHOT/${hotfixNum}/java-ecs2/ecs/ecs.jar"
sh "curl -O ${jfrogBaseAddress}/ecs2_java_dev/SNAPSHOT/${hotfixNum}/java-ecs2/ecs/application.yml"
sh "curl -O ${jfrogBaseAddress}/ecs2_java_dev/SNAPSHOT/${hotfixNum}/java-ecs2/ecs/application-dev.yml"
def configFile = "application-dev.yml"
fixJavaConfigDataSource(configFile, dbDriver, ecsDbUrl, mysqlAdminUser, mysqlAdminPassword, helperDialect)
fixJavaConfigRedis(configFile)
fixJavaConfigYn(configFile, xxlJobIp, xxlJob + '-ecs')
fixConsoleUrl(configFile)
makeJavaImageDockerfile('ecs.jar', '4g', '1g', '2g', '1g')
dockerPushImage(javaImageEcs)
}
}
}
},
'web': {
if (type == "create" || type == "upgrade_web" || type == "all") {
stage('make web image') {
dir("image_web_dir") {
for (item in ['designer', 'ecs-console', 'ecs_console', 'fssc-web', 'ecs-web', 'ecs-console-mobile', 'ecs_console_mobile', 'ecs-mobile']) {
print("download web html ${item}")
sh "curl -O ${jfrogBaseAddress}/ecs2_java_dev/SNAPSHOT/${hotfixNum}/html/${item}.zip"
sh "rm -rf ${item};unzip ${item}.zip || echo 'skip step'"
sh "tar rvf ecs.tar.gz ${item} || echo 'skip step'"
}
makeNginxImageDockerFile('ecs.tar.gz')
dockerPushImage(nginxImage)
}
}
}
},
'db': {
if (type == "create") {
stage('create schema on mysql') {
retry(5) {
checkNamespace()
}
createEmptyMysql(nodeSelector)
def shell = "rancher kubectl get node -o wide|grep `rancher kubectl get pods -n ${ENVIRONMENT_NAME} -o wide |grep mysql| awk '{print \$7}'`\\ | awk '{print \$6}'"
def mysqlIp = sh(returnStdout: true, script: shell).trim()
createMysqlK8s(nodeSelector, mysqlIp)
rancherDeployMysql()
}
}
if (type == "create" || type == "upgrade_db" || type == "all") {
stage('upgrade db') {
String mysqlPort = getMysqlPort()
dir('upgrade_db') {
sh "curl -O ${jfrogBaseAddress}/ecs2_java_dev/SNAPSHOT/${hotfixNum}/java-ecs2/upgrade/upgrade.zip"
parallel(
'db_console': {
stage('upgrade db_console') {
dir('upgrade_db_console') {
sh 'unzip ../upgrade.zip'
dir('config') {
sh "curl -O ${jfrogBaseAddress}/ecs2_java_dev/SNAPSHOT/${hotfixNum}/java-ecs2/metadata/console-metadata/metadata.zip"
upgradeDb(dbDriver, consoleDbUrl.replace('mysql:3306', "192.168.48.85:${mysqlPort}"), mysqlAdminUser, mysqlAdminPassword, helperDialect)
sh 'rm -rf metadata.zip'
sh "curl -O ${jfrogBaseAddress}/ecs2_java_dev/SNAPSHOT/${hotfixNum}/java-ecs2/metadata/console-custom-metadata/metadata.zip"
try {
upgradeDb(dbDriver, consoleDbUrl.replace('mysql:3306', "192.168.48.85:${mysqlPort}"), mysqlAdminUser, mysqlAdminPassword, helperDialect)
} catch (ignored) {
}
}
}
}
},
'db_ecs': {
stage('upgrade db_ecs') {
dir('upgrade_db_ecs') {
sh 'unzip ../upgrade.zip'
dir('config') {
sh "curl -O ${jfrogBaseAddress}/ecs2_java_dev/SNAPSHOT/${hotfixNum}/java-ecs2/metadata/ecs-metadata/metadata.zip"
upgradeDb(dbDriver, ecsDbUrl.replace('mysql:3306', "192.168.48.85:${mysqlPort}"), mysqlAdminUser, mysqlAdminPassword, helperDialect)
}
}
}
}
)
}
}
}
}
)
createKubernetesDeployment(nodeSelector, nginxImage, javaImageConsole, javaImageEcs)
if (type == "create") {
stage('create kubernetes.yml') {
rancherDeploy()
}
}
parallel(
"upgrade_java_console": {
if (type == "upgrade_java_console" || type == "all") {
stage('upgrade java console') {
rancherUpdateDeploy('java-console')
}
}
},
"upgrade_java_ecs": {
if (type == "upgrade_java_ecs" || type == "all") {
stage('upgrade java ecs') {
rancherUpdateDeploy('java-ecs')
}
}
},
"upgrade_java_web": {
if (type == "upgrade_web" || type == "all") {
stage('upgrade web') {
rancherUpdateDeploy('nginx')
}
}
},
)
if (type == "upgrade_db" || type == "clear_redis" || type == "all") {
stage('clear Redis') {
clearRedis()
}
}
if (type == "all") {
stage('upgrade all') {
wxNotice("'${PROPOSER_NAME}'升级环境环境: '${ENVIRONMENT_NAME}' 基于'${ENVIRONMENT_BRANCH}'分支 升级成功!", wxKey, PROPOSER_MOBILE)
executeSql("update T_ENVIRONMENT_MANAGER set ENVIRONMENT_BRANCH = '${hotfixNum}' where ENVIRONMENT_NAME = '${ENVIRONMENT_NAME}'")
}
}
if (type == "create") {
stage('wx notice start') {
wxNotice("'${PROPOSER_NAME}'申请环境: '${ENVIRONMENT_NAME}' 基于'${ENVIRONMENT_BRANCH}'分支 创建成功!", wxKey, PROPOSER_MOBILE)
}
}
} catch (e) {
wxFailNotice(wxKey, noticeTelNumber)
throw e
} finally {
println "${BUILD_URL}console"
deleteDir()
executeSql("update T_ENVIRONMENT_MANAGER set UPDATE_DATE = NOW() where ENVIRONMENT_NAME = '${ENVIRONMENT_NAME}'")
}
}
def getMysqlPort() {
//3306:28383/TCP
String portStr = sh(returnStdout: true, script: "rancher kubectl get svc -n ${ENVIRONMENT_NAME} |grep mysql|awk '{print \$5}'").trim()
println portStr
return portStr.replace('3306:', '').replace('/TCP', '')
}
def checkNamespace() {
sleep time: 1, unit: 'MINUTES'
String updateMsg = sh(returnStdout: true, script: "rancher kubectl get namespace|grep ${ENVIRONMENT_NAME}").trim()
println updateMsg
if (updateMsg.contains(ENVIRONMENT_NAME)) {
println "${ENVIRONMENT_NAME}命名空间已经创建成功!"
} else {
throw new Exception(updateMsg)
}
}
def createEmptyMysql(NODE_SELECTOR) {
String text = """
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
namespace: ${ENVIRONMENT_NAME}
spec:
selector:
matchLabels:
app: mysql
serviceName: "mysql"
replicas: 1
template:
metadata:
labels:
app: mysql
spec:
nodeSelector:
productLine: ${NODE_SELECTOR}
containers:
- name: mysql
image: 192.168.48.90:80/ecs2-dev/mysql-ecs-empty:latest
imagePullPolicy: Always
resources:
requests:
memory: 500Mi
limits:
memory: 2Gi
env:
- name: MYSQL_ROOT_PASSWORD
value: '123456'
ports:
- name: mysql-port
containerPort: 3306
protocol: TCP
"""
println text
writeFile file: 'mysql-empty-k8s.yml', text: text, encoding: "UTF-8"
sh "rancher kubectl apply -f mysql-empty-k8s.yml"
}
def createMysqlK8s(NODE_SELECTOR, mysqlIp) {
String text = """
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql-config
namespace: ${ENVIRONMENT_NAME}
data:
my.cnf: |
[client]
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4
[mysqld]
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/mysql
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
max_connections = 5000
default-time-zone = '+8:00'
sql_mode = NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
transaction_isolation = READ-COMMITTED
max_allowed_packet = 8g
innodb_log_buffer_size = 167772160
innodb_log_file_size = 1024M
innodb_strict_mode = 0
max_heap_table_size = 512M
wait_timeout = 864000
interactive_timeout = 864000
disable-log-bin
---
apiVersion: v1
kind: Service
metadata:
name: mysql
namespace: ${ENVIRONMENT_NAME}
spec:
type: NodePort
ports:
- name: mysql-port
protocol: TCP
port: 3306
selector:
app: mysql
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
namespace: ${ENVIRONMENT_NAME}
spec:
selector:
matchLabels:
app: mysql
serviceName: "mysql"
replicas: 1
template:
metadata:
labels:
app: mysql
spec:
nodeSelector:
productLine: ${NODE_SELECTOR}
internal-ip: ${mysqlIp}
containers:
- name: mysql
image: 192.168.48.90:80/ecs2-dev/mysql-ecs-empty:latest
imagePullPolicy: Always
resources:
requests:
memory: 500Mi
limits:
memory: 2Gi
env:
- name: MYSQL_ROOT_PASSWORD
value: '123456'
ports:
- name: mysql-port
containerPort: 3306
protocol: TCP
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
- name: config-volume
mountPath: /etc/mysql/conf.d
readinessProbe:
tcpSocket:
port: 3306
initialDelaySeconds: 30
periodSeconds: 30
timeoutSeconds: 5
failureThreshold: 40
volumes:
- name: mysql-persistent-storage
hostPath:
path: /data/mysql/${ENVIRONMENT_NAME}
type: DirectoryOrCreate
- name: config-volume
configMap:
name: mysql-config
"""
println text
writeFile file: 'mysql-k8s.yml', text: text, encoding: "UTF-8"
}
def rancherDeployMysql() {
try {
sh """
rancher kubectl apply -f mysql-k8s.yml
rancher kubectl rollout status StatefulSet mysql -n ${ENVIRONMENT_NAME}
"""
} catch (e) {
throw e
}
}
def executeSql(sql) {
def remote = [:]
remote.name = 'mysqlServer'
remote.host = "192.168.61.52"
remote.allowAnyHosts = true
remote.user = "root"
remote.password = "A09QXN2Ds1w5NDSN"
sshCommand remote: remote, failOnError: false, command: "mysql -uroot -pYuaNian@2999! -D ecs-cicd -e \"${sql}\""
}
def wxFailNotice(wxKey, noticeTelNumber) {
def proposerName = PROPOSER_NAME
def jobName = JOB_NAME
def text = "<font color=info>【${proposerName}的${jobName}】</font>任务执行<font color=warning>失败!!!</font>\\n >[查看控制台](${BUILD_URL}console)"
sh """curl 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key='${wxKey}'' -H 'Content-Type: application/json' -d '{ "msgtype": "markdown", "markdown": { "content": "${text}", } }'"""
sh """curl 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key='${wxKey}'' -H 'Content-Type: application/json' -d '{ "msgtype": "text", "text": { "mentioned_mobile_list":["${noticeTelNumber}"] } }'"""
}
def wxNotice(msg, wxKey, proposerMobile) {
sh """
curl 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=${wxKey}' \
-H 'Content-Type: application/json' \
-d '
{
"msgtype": "text",
"text": {
"content": "${msg}",
"mentioned_mobile_list":["${proposerMobile}"]
}
}'
"""
}
def fixJavaConfigDataSource(configFile, dbDriver, dbUrl, dbName, dbPassword, helperDialect) {
sh "sed -i 's/helperDialect: .*/helperDialect: ${helperDialect}/g' ${configFile}"
sh "sed -i 's/url: jdbc.*/url: ${dbUrl}/g' ${configFile}"
sh "sed -i 's/driver-class-name: .*/driver-class-name: ${dbDriver}/g' ${configFile}"
sh "sed -i 's/username: .*/username: ${dbName}/g' ${configFile}"
sh "sed -i 's/password: .*/password: ${dbPassword}/g' ${configFile}"
}
def fixJavaConfigYn(configFile, xxlJobIp, xxlJob) {
sh "sed -i 's/nameServers: .*/nameServers: 192.168.61.54:9876/g' ${configFile}"
sh "sed -i 's/addresses.*/addresses: http:\\/\\/'${xxlJobIp}'\\/xxl-job-admin/g' ${configFile}"
sh "sed -i 's/prefix: .*/prefix: ${ENVIRONMENT_NAME}/g' ${configFile}"
sh "sed -i 's/appname:.*/appname: ${xxlJob}/g' ${configFile}"
sh "sed -i 's/businessid: .*/businessid: ${xxlJob}/g' ${configFile}"
sh "sed -i 's/title:.*/title: ${xxlJob}/g' ${configFile}"
sh "sed -i 's/fastjsonType:.*/fastjsonType: fastjson2/g' ${configFile}"
}
def fixConsoleUrl(configFile) {
sh "sed -i 's/console:8095/java-console:8095/g' ${configFile}"
}
def fixEcsUrl(configFile) {
sh "sed -i 's/masterdata-service-url:.*/masterdata-service-url: http:\\/\\/java-ecs:8096\\//g' ${configFile}"
}
def fixJavaConfigRedis(configFile) {
sh "sed -i 's/host: .*/host: redis/g' ${configFile}"
sh "sed -i 's/database: .*/database: 0/g' ${configFile}"
sh "sed -i 's/port: \${redis_port:.*/port: 6379/g' ${configFile}"
sh "sed -i '0,/password:.*/s/password:.*/password: /' ${configFile}"
}
def makeJavaImageDockerfile(jarName, xmx, xms, maxMetaspaceSize, metaspaceSize) {
String text = """FROM 192.168.48.90:80/ecs-component/ecs-openjre:8
MAINTAINER ecs@yuanian.com
LABEL description="ecs-micro"
COPY ${jarName} /app.jar
COPY application.yml /application.yml
COPY application-dev.yml /application-dev.yml
ENV JAVA_OPT="-Xmx${xmx} -Xms${xms} -XX:MaxMetaspaceSize=${maxMetaspaceSize} -XX:MetaspaceSize=${metaspaceSize} -Dfile.encoding=utf-8"
CMD java -Dapp.log.projectName=ledger -Dapp.log.serviceName=${ENVIRONMENT_NAME} \${JAVA_OPT} -jar app.jar
"""
println text
writeFile file: 'Dockerfile', text: text, encoding: "UTF-8"
}
def makeNginxImageDockerFile(tarName) {
createNginxConf()
String text = """FROM nginx:1.17.0
MAINTAINER ecs@yuanian.com
LABEL description="ecs-micro"
ADD ${tarName} /usr/share/nginx/html
COPY nginx.conf /etc/nginx
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/\$TZ /etc/localtime && echo \$TZ > /etc/timezone
CMD ["nginx", "-g", "daemon off;"]
"""
println text
writeFile file: 'Dockerfile', text: text, encoding: "UTF-8"
}
def dockerPushImage(image_name) {
sh """
docker login -u ${HARBOR_USERNAME} -p ${HARBOR_PASSWORD} http://${HARBOR_ADDRESS}
docker build -t ${image_name} .
docker push ${image_name}
docker rmi -f ${image_name}
"""
}
def rancherDeploy() {
try {
sh """
rancher kubectl create -f k8s-Deployment.yml
"""
} catch (e) {
shNotThrowError("rancher kubectl delete --all deployment -n ${ENVIRONMENT_NAME}")
throw e
}
createKubernetesSvc()
try {
sh "rancher kubectl create -f k8s-svc.yml"
} catch (e) {
shNotThrowError("rancher kubectl delete --all deployment -n ${ENVIRONMENT_NAME}")
shNotThrowError("rancher kubectl delete --all svc -n ${ENVIRONMENT_NAME}")
shNotThrowError("rancher kubectl delete --all ingress -n ${ENVIRONMENT_NAME}")
throw e
}
}
def shNotThrowError(shell) {
try {
sh shell
} catch (ignored) {
println 'not throw exception'
}
}
def rancherUpdateDeploy(deploymentName) {
sh """
rancher kubectl rollout restart deployment ${deploymentName} -n ${ENVIRONMENT_NAME}
"""
String updateMsg = sh(returnStdout: true, script: "rancher kubectl rollout status deployment ${deploymentName} -n ${ENVIRONMENT_NAME}").trim()
println updateMsg
if (updateMsg.contains('successfully rolled out')) {
println "${deploymentName} 升级成功"
} else {
throw new Exception(updateMsg)
}
}
def upgradeDb(dbDriver, dbUrl, dbName, dbPassword, helperDialect) {
//server.port=8089
//dbType=oracle
//spring.datasource.url=jdbc:oracle:thin:@192.168.12.104:1521:yndev
//spring.datasource.username=ecs_md
//spring.datasource.password=ecs_md
//spring.datasource.driverClassName=oracle.jdbc.driver.OracleDriver
def configFile = "application.properties"
sh "sed -i 's/dbType=.*/dbType=${helperDialect}/g' ${configFile}"
sh "sed -i 's/server.port=.*/server.port=8888/g' ${configFile}"
sh "sed -i 's/spring.datasource.url=.*/spring.datasource.url=${dbUrl}/g' ${configFile}"
sh "sed -i 's/spring.datasource.username=.*/spring.datasource.username=${dbName}/g' ${configFile}"
sh "sed -i 's/spring.datasource.password=.*/spring.datasource.password=${dbPassword}/g' ${configFile}"
sh "sed -i 's/spring.datasource.driverClassName=.*/spring.datasource.driverClassName=${dbDriver}/g' ${configFile}"
withDockerContainer(image: '192.168.48.90:80/ecs-component/ecs-openjre:8') {
sh "java -Xmx2g -Xms1g -Dfile.encoding=utf-8 -jar ecs-upgrade-app.jar"
}
}
def clearRedis() {
def redisPodName = sh(returnStdout: true, script: "rancher kubectl get pods -n ${ENVIRONMENT_NAME} | grep redis | awk '{print \$1}'").trim()
sh "rancher kubectl exec -it ${redisPodName} -c redis -n ${ENVIRONMENT_NAME} -- redis-cli -h 127.0.0.1 flushall"
}
def createKubernetesDeployment(NODE_SELECTOR, NGINX_IMAGE, JAVA_IMAGE_CONSOLE, JAVA_IMAGE_ECS) {
String text = """
apiVersion: v1
kind: PersistentVolume
metadata:
name: ${ENVIRONMENT_NAME}-pv
namespace: ${ENVIRONMENT_NAME}
spec:
capacity:
storage: 2Gi
accessModes:
- ReadWriteMany
storageClassName: nfs
nfs:
path: /opt/fonts
server: 192.168.48.33
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: ${ENVIRONMENT_NAME}-pvc
namespace: ${ENVIRONMENT_NAME}
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 2Gi
storageClassName: nfs
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
namespace: ${ENVIRONMENT_NAME}
spec:
selector:
matchLabels:
app: redis
replicas: 1
template:
metadata:
labels:
app: redis
spec:
nodeSelector:
productLine: ${NODE_SELECTOR}
containers:
- name: redis
image: 192.168.48.90:80/ecs-component/ecs-redis:6.0
imagePullPolicy: Always
ports:
- name: redisport
containerPort: 6379
resources:
requests:
memory: 50Mi
limits:
memory: 1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: ${ENVIRONMENT_NAME}
spec:
selector:
matchLabels:
app: nginx
replicas: 1
template:
metadata:
labels:
app: nginx
spec:
volumes:
- name: logs
emptyDir: {}
nodeSelector:
productLine: ${NODE_SELECTOR}
containers:
- name: nginx
image: ${NGINX_IMAGE}
imagePullPolicy: Always
ports:
- name: serviceport
containerPort: 8080
resources:
requests:
memory: 50Mi
limits:
memory: 150Mi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: java-console
namespace: ${ENVIRONMENT_NAME}
spec:
selector:
matchLabels:
app: java-console
replicas: 1
template:
metadata:
labels:
app: java-console
spec:
volumes:
- name: logs
emptyDir: {}
- name: myfonts
persistentVolumeClaim:
claimName: ${ENVIRONMENT_NAME}-pvc
nodeSelector:
productLine: ${NODE_SELECTOR}
containers:
- name: java-console
image: ${JAVA_IMAGE_CONSOLE}
imagePullPolicy: Always
ports:
- name: consoleport
containerPort: 8095
env:
- name: JAVA_OPT
value: -Xmx2g -Xms1g -XX:MaxMetaspaceSize=512m -XX:MetaspaceSize=127m
resources:
requests:
memory: 1Gi
limits:
memory: 3Gi
volumeMounts:
- name: logs
mountPath: /target/logs
- name: myfonts
mountPath: /usr/share/fonts/
readinessProbe:
tcpSocket:
port: 8095
initialDelaySeconds: 60
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 20
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: java-ecs
namespace: ${ENVIRONMENT_NAME}
spec:
selector:
matchLabels:
app: java-ecs
replicas: 1
template:
metadata:
labels:
app: java-ecs
spec:
volumes:
- name: logs
emptyDir: {}
- name: myfonts
persistentVolumeClaim:
claimName: ${ENVIRONMENT_NAME}-pvc
nodeSelector:
productLine: ${NODE_SELECTOR}
containers:
- name: java-ecs
image: ${JAVA_IMAGE_ECS}
imagePullPolicy: Always
ports:
- name: debugport
containerPort: 8088
- name: ecsport
containerPort: 8096
env:
- name: JAVA_OPT
value: -Xmx3g -Xms1g -XX:MaxMetaspaceSize=512m -XX:MetaspaceSize=127m
- name: XDEBUG
value: -Xdebug -Xrunjdwp:transport=dt_socket,suspend=n,server=y,address=8088
resources:
requests:
memory: 2Gi
limits:
memory: 4Gi
volumeMounts:
- name: logs
mountPath: /target/logs
- name: myfonts
mountPath: /usr/share/fonts/
readinessProbe:
tcpSocket:
port: 8096
initialDelaySeconds: 60
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 20
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: cicd-callback
namespace: ${ENVIRONMENT_NAME}
spec:
selector:
matchLabels:
app: cicd-callback
replicas: 1
template:
metadata:
labels:
app: cicd-callback
spec:
volumes:
- name: logs
emptyDir: {}
nodeSelector:
productLine: ${NODE_SELECTOR}
containers:
- name: cicd-callback
image: 192.168.48.90:80/ecs-component/cicd-config-agent:1.1
imagePullPolicy: Always
env:
- name: proxy_infos
value: "[{host:'nginx',port:8080,contextPath:''}]"
resources:
requests:
memory: 100Mi
limits:
memory: 256Mi
ports:
- name: configport
containerPort: 8079
"""
println text
writeFile file: 'k8s-Deployment.yml', text: text, encoding: "UTF-8"
}
def createKubernetesSvc() {
String text = """
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: ${ENVIRONMENT_NAME}
spec:
type: NodePort
ports:
- name: serviceport
port: 8080
selector:
app: nginx
---
apiVersion: v1
kind: Service
metadata:
name: java-console
namespace: ${ENVIRONMENT_NAME}
spec:
type: NodePort
ports:
- name: consoleport
port: 8095
- name: debugport
port: 8088
selector:
app: java-console
---
apiVersion: v1
kind: Service
metadata:
name: java-ecs
namespace: ${ENVIRONMENT_NAME}
spec:
type: NodePort
ports:
- name: ecsport
port: 8096
- name: debugport
port: 8088
selector:
app: java-ecs
---
apiVersion: v1
kind: Service
metadata:
name: cicd-callback
namespace: ${ENVIRONMENT_NAME}
spec:
type: NodePort
ports:
- name: configport
port: 8079
selector:
app: cicd-callback
---
apiVersion: v1
kind: Service
metadata:
name: redis
namespace: ${ENVIRONMENT_NAME}
spec:
type: NodePort
ports:
- name: redisport
port: 6379
selector:
app: redis
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/proxy-body-size: "100M"
name: ${ENVIRONMENT_NAME}-ingress
namespace: ${ENVIRONMENT_NAME}
spec:
rules:
- host: ${ENVIRONMENT_NAME}.192.168.48.85.nip.io
http:
paths:
- backend:
serviceName: nginx
servicePort: 8080
"""
println text
writeFile file: 'k8s-svc.yml', text: text, encoding: "UTF-8"
}
def createNginxConf() {
String text = """
user root;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '\$remote_addr - \$remote_user [\$time_local] "\$request" '
'\$status \$body_bytes_sent "\$http_referer" '
'"\$http_user_agent" "\$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
gzip on;
gzip_types text/css
application/javascript text/plain application/json application/x-javascript
application/css application/xml application/xml+rss text/javascript
application/x-httpd-php image/jpeg image/gif image/png image/x-ms-bmp;
client_max_body_size 100M;
upstream ecsSrv {
server java-ecs:8096;
}
upstream ecs-console {
server java-console:8095;
}
server {
listen 8080;
server_name localhost;
location = / {
rewrite ^ \$scheme://\$http_host/ecs_console/index.html permanent;
}
location ~* \\.(css|js|html|map|gif|jpg|jpeg|png|ico|woff|woff2|svg|mp4|icon)\$ {
root /usr/share/nginx/html;
}
location ~ /console/ {
rewrite ^/console/(.*)\$ /\$1 break;
proxy_read_timeout 240s;
proxy_pass http://ecs-console;
}
location ~ /(ecs|designer|businessobject|datadictionary|distribution|filemanagement|flow|masterdata|rule|treemanager)/ {
rewrite ^/(ecs|designer|businessobject|datadictionary|distribution|filemanagement|flow|masterdata|rule|treemanager)?/(.*) /\$2 break;
proxy_read_timeout 240s;
proxy_pass http://ecsSrv;
}
location = /designer/ { index /designer/index.html; }
location = /ecs-console/ { index /ecs-console/index.html; }
location = /ecs_console/ { index /ecs_console/index.html; }
location = /ecs-console-mobile/ { index /ecs-console-mobile/index.html; }
location = /fssc-web/ { index /fssc-web/index.html; }
location = /ecs-web/ { index /ecs-web/index.html; }
location = /ecs-mobile/ { index /ecs-mobile/index.html; }
location = /ecs_console_mobile/ { index /ecs_console_mobile/index.html; }
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
real_ip_recursive on;
keepalive_timeout 65;
}
}
"""
println text
writeFile file: 'nginx.conf', text: text, encoding: "UTF-8"
}