5.web层服务迁移:
(1)项目启动脚本:start.sh
#!/bin/bash
srv_name="goods_web_main"
chmod +x ./${srv_name}
if pgrep -x ${srv_name}; then
echo "${srv_name} is running"
echo "shutting down ${srv_name}"
if ps -A | grep ${srv_name} | awk '{print $1}' | xargs kill $1; then
echo "starting ${srv_name}"
./${srv_name}
if [ $? -ne 1 ]; then
echo "start ${srv_name} fail"
exit 0
fi
echo "start ${srv_name} success"
fi
else
echo "starting ${srv_name}"
./${srv_name}
if [ $? -ne 1 ]; then
echo "start ${srv_name} fail"
exit 0
fi
echo "start ${srv_name} success"
fi
(2)Dockerfile
FROM myhub.com/devops-tools/alpine:3.16
COPY target /root/goods_web
WORKDIR /root/goods_web
# 由于前期项目未考虑容器化部署,为防止生产环境端口冲突,项目中开发环境端口固定,生产环境自动获取端口
# 有了容器后,不存在端口冲突的问题,端口固定后,更适合制作镜像和部署到k8s中
ENV MXSHOP_DEBUG=true
EXPOSE 8022
ENTRYPOINT ["sh","start.sh"]
(3)go build脚本:/script/go-build-web.sh
#!/bin/bash
echo "go build beginning"
echo "configure go environment variables"
export GOROOT=/usr/local/go
export PATH=$PATH:$GOROOT/bin
echo "start go module"
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,https://mirrors.aliyun.com/goproxy,https://goproxy.io,direct
echo "prepare directory structure"
# MODULE 项目名/目录名:agent pod添加的全局环境变量,会自动注入到每个容器中
JENKINS_DIR=${WORKSPACE}/${MODULE}
echo "jenkins workspace:${JENKINS_DIR}"
#ls ${JENKINS_DIR}
BUILD_DIR=${JENKINS_DIR}/target
echo "build workspace:${BUILD_DIR}"
if [ ! -d ${BUILD_DIR}/${MODULE} ]; then
mkdir -p ${BUILD_DIR}/${MODULE}
chmod 777 -R ${BUILD_DIR}
fi
if [ ! -f ${JENKINS_DIR}/config-debug.yaml ]; then
echo "source config file not fount ${JENKINS_DIR}/config-debug.yaml"
exit 1
fi
cp ${JENKINS_DIR}/config-debug.yaml ${BUILD_DIR}/${MODULE}
if [ ! -f ${JENKINS_DIR}/start.sh ]; then
echo "source start file not fount ${JENKINS_DIR}/start.sh"
exit 1
fi
cp ${JENKINS_DIR}/start.sh ${BUILD_DIR}
echo "execute go build, generate executable files"
if [ ! -f ${JENKINS_DIR}/main.go ]; then
echo "source main file not fount ${JENKINS_DIR}/main.go"
exit 1
fi
go build -o ${BUILD_DIR}/${MODULE}_main ${JENKINS_DIR}/main.go
ls ${BUILD_DIR}
ls ${BUILD_DIR}/${MODULE}
echo "go build finished"
(4)docker build脚本:/script/build-image-web.sh
容器间变量获取:
(a)全局变量可以在pod模板的环境变量中设置每个容器可以直接获取
(b)容器中生成的变量可以以文件的形式保存在jenkins工作目录中供其他容器获取
#!/bin/bash
echo "build image beginning"
BUILD_DIR=${WORKSPACE}/${MODULE}
if [ ! -d ${BUILD_DIR} ]; then
echo "build image workspace not fount ${BUILD_DIR}"
exit 1
fi
if [ ! -f ${BUILD_DIR}/Dockerfile ]; then
echo "dockerfile not fount ${BUILD_DIR}/Dockerfile"
exit 1
fi
VERSION=$(date +%y%m%d%H%M%s)
IMAGE_NAME=myhub.com/${JOB_NAME}/${MODULE}:${VERSION}
echo "${IMAGE_NAME}" > ${WORKSPACE}/IMAGE
echo "building image: ${IMAGE_NAME}"
docker build -t ${IMAGE_NAME} ${BUILD_DIR} || exit 1
echo "push image beginning"
docker push ${IMAGE_NAME} || exit 1
echo "push image finished"
(5)k8s deployment 部署:
(a)k8s中服务发现和健康检查功能,七层代理代如:master分支goods-web访问地址:http://master.com/g/v1/ ,模板:/script/template/web.yaml
#deploy
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{name}}
namespace: {{namespace}}
spec:
selector:
matchLabels:
app: {{name}}
replicas: 1
template:
metadata:
labels:
app: {{name}}
spec:
containers:
- name: {{name}}
image: {{image}}
ports:
- containerPort: 8022
livenessProbe:
tcpSocket:
port: 8022
initialDelaySeconds: 10
periodSeconds: 5
failureThreshold: 2
successThreshold: 1
timeoutSeconds: 5
readinessProbe:
httpGet:
path: /health
port: 8022
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 5
failureThreshold: 2
successThreshold: 1
timeoutSeconds: 5
---
#service
apiVersion: v1
kind: Service
metadata:
name: {{name}}
namespace: {{namespace}}
spec:
ports:
- port: 80
protocol: TCP
targetPort: 8022
selector:
app: {{name}}
type: ClusterIP
---
#ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{name}}
namespace: {{namespace}}
spec:
rules:
- host: {{branch}}.com
http:
paths:
- path: /g/v1
pathType: Prefix
backend:
service:
name: {{name}}
port:
number: 80
(b)脚本:/script/deploy.sh
健康检查:利用k8s健康检查结果,通知jenkins用户服务是否可用
#!/bin/bash
echo "k8s deploy beginning"
name=${JOB_NAME}
namespace=${BRANCH}
image=$(cat ${WORKSPACE}/IMAGE)
branch=${BRANCH}
echo "deploying ... name:${name},namespace:${namespace},image:${image},branch:${branch}"
prevision=$(kubectl get deployment.apps/${name} -n ${branch} -o go-template='{{index .metadata.annotations "deployment.kubernetes.io/revision"}}' 2>/dev/null || echo 0)
echo "deployment prevision:${prevision}"
rm -f web.yaml
cp $(dirname "${BASH_SOURCE[0]}")/template/web.yaml .
sed -i "s,{{name}},${name},g" web.yaml
sed -i "s,{{namespace}},${namespace},g" web.yaml
sed -i "s,{{image}},${image},g" web.yaml
sed -i "s,{{branch}},${branch},g" web.yaml
kubectl apply -f web.yaml || exit 1
vision=$(kubectl get deployment.apps/${name} -n ${branch} -o go-template='{{index .metadata.annotations "deployment.kubernetes.io/revision"}}' 2>/dev/null || echo 0)
echo "deployment current vision:${vision}"
echo "k8s deploy finished"
cat web.yaml
echo ""
# 健康检查
success=0
count=60
IFS=","
#sleep=5
while [ ${count} -gt 0 ]; do
if [ ${vision} == $((${prevision} + 1)) ]; then
replicas=$(kubectl get deployment.apps/${name} -n ${branch} -o go-template='{{.status.replicas}},{{.status.updatedReplicas}},{{.status.readyReplicas}},{{.status.availableReplicas}}')
echo "replicas: ${replicas}"
arr=(${replicas})
if [ "${arr[0]}" == "${arr[1]}" -a "${arr[1]}" == "${arr[2]}" -a "${arr[2]}" == "${arr[3]}" ]; then
echo "health check success!"
success=1
break
fi
else
echo "waiting deployment ..."
fi
((count--))
sleep 2
done
if [ ${success} -ne 1 ]; then
echo "health check failed!"
exit 1
fi
(6)Jenkinsfile:
jenkins控制台获取变量:sh(returnStdout: true, script:'echo ${xxx}')
def label = "golang1.19.1"
def kube_credential = "global-kubernetes-credential"
def gitee_credential = "global-gitee-credentials"
timeout(time: 600, unit: 'SECONDS') {
podTemplate(label: label,cloud: 'kubernetes'){
node (label) {
stage('pull code'){
sh '''echo "pull code beginning"'''
def branch = sh(returnStdout: true, script:'echo ${BRANCH}')
git branch: branch, credentialsId: gitee_credential, url: 'https://gitee.com/jn-shao/mxshop_api.git'
sh ''' echo "pull code finished"'''
}
stage('build project'){
container('golang') {
sh 'sh script/go-build-web.sh'
}
}
stage('build image'){
sh 'sh script/build-image-web.sh'
}
stage('deploy project'){
container('kubectl') {
withKubeConfig([credentialsId: kube_credential,serverUrl: "https://kubernetes.default.svc.cluster.local"]) {
sh 'sh script/deploy.sh'
}
}
}
}
}
}
标签:web,name,kubernetes,cicd,echo,sh,go,jenkins,DIR
From: https://www.cnblogs.com/jn-shao/p/16949431.html