🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
### 部署 Kubernetes 应用 如何来部署一个原生的 Kubernetes 应用呢? 部署一个kubernetes 应用流程如下: ![](http://on-img.com/chart_image/5b84ad40e4b0d4d65be96283.png?_=1535509752205) 1. pull代码 2. 测试registry,并登陆registry. 3. 自动编写应用 Dockerfile 4. 构建打包 Docker 镜像 5. 应用maven 构建缓存 5. 推送 Docker 镜像到仓库 6. 更改 Deployment YAML 文件中参数 7. 利用 kubectl 工具部署应用 8. 检查应用状态 ### 第一步,Pull 代码及全局环境变量申明 #!/bin/bash # Filename: k8s-deploy_v0.2.sh # Description: jenkins CI/CD 持续发布脚本 # Author: yi.hu # Email: yi.hu@dianrong.com # Revision: 1.0 # Date: 2018-08-10 # Note: prd # zookeeper基础服务,依照环境实际地址配置 init() { local lowerEnv="$(echo ${AppEnv} | tr '[:upper:]' 'lower')" case "${lowerEnv}" in dev) CFG_ADDR="10.34.11.186:4181" DR_CFG_ZOOKEEPER_ENV_URL="10.34.11.186:4181" ;; demo) CFG_ADDR="10.34.11.186:4181" DR_CFG_ZOOKEEPER_ENV_URL="10.34.11.186:4181" ;; *) echo "Not support AppEnv: ${AppEnv}" exit 1 ;; esac } # 函数执行 init # 初始化变量 AppId=$(echo ${AppOrg}_${AppEnv}_${AppName} |sed 's/[^a-zA-Z0-9_-]//g' | tr "[:lower:]" "[:upper:]") CFG_LABEL=${CfgLabelBaseNode}/${AppId} CFG_ADDR=${CFG_ADDR} VERSION=$(echo "${GitBranch}" | sed 's@release/@@') ### 第二步,登录harbor 仓库 docker_login () { docker login ${DOCKER_REGISTRY} -u${User} -p${PassWord} } ### 第三步,编译代码,制作应用镜像,上传镜像到harbor仓库。 build() { if [ "x${ACTION}" == "xDEPLOY" ] || [ "x${ACTION}" == "xPRE_DEPLOY" ]; then echo "Test harbor registry: ${DOCKER_REGISTRY}" curl --connect-timeout 30 -I ${DOCKER_REGISTRY}/api/projects 2>/dev/null | grep 'HTTP/1.1 200 OK' > /dev/null echo "Check image EXIST or NOT: ${ToImage}" ImageCheck_Harbor=$(echo ${ToImage} | sed 's/\([^/]\+\)\([^:]\+\):/\1\/api\/repositories\2\/tags\//') Responed_Code=$(curl -u${User}:${PassWord} -so /dev/null -w '%{response_code}' ${ImageCheck_Harbor} || true) echo ${Responed_Code} if [ "${NoCache}" == "true" ] || [ "x${ResponedCode}" != "x200" ] ; then if [ "x${ActionAfterBuild}" != "x" ]; then eval ${ActionAfterBuild} fi echo "生成Dockerfile文件" echo "FROM ${FromImage}" > Dockerfile cat >> Dockerfile <<-EOF ${Dockerfile} EOF echo "同步上层镜像: ${FromImage}" docker pull ${FromImage} # 同步上层镜像 echo "构建镜像,并Push到仓库: ${ToImage}" docker build --no-cache=${NoCache} -t ${ToImage} . && docker push ${ToImage} || exit 1 # 开始构建镜像,成功后Push到仓库 echo "删除镜像: ${ToImage}" docker rmi ${ToImage} || echo # 删除镜像 fi fi } ### 第四步,发布、预发布、停止、重启 deploy() { if [ "x${ACTION}" == "xSTOP" ]; then # 停止当前实例 kubectl delete -f ${AppName}-deploy.yaml elif [ "x${ACTION}" == "xRESTART" ]; then kubectl delete pod -n ${NameSpace} -l app=${AppName} elif [ "x${ACTION}" == "xDEPLOY" ]; then kubectl apply -f ${AppName}-deploy.yaml fi } ### 第五步,查看pod 是否正常启动,如果失败则返回1,进而会详细显示报错信息。 check_status() { RETRY_COUNT=5 echo "检查 pod 运行状态" while (( $RETRY_COUNT )); do POD_STATUS=$(kubectl get pod -n ${NameSpace} -l app=${AppName} ) AVAILABLE_COUNT=$(kubectl get deploy -n ${NameSpace} -l app=${AppName} | awk '{print $(NF-1)}' | grep -v 'AVAILABLE') if [ "X${AVAILABLE_COUNT}" != "X${Replicas}" ]; then echo "[$(date '+%F %T')] Show pod Status , wait 30s and retry #$RETRY_COUNT " echo "${POD_STATUS}" let RETRY_COUNT-- || true sleep 30 elif [ "X${AVAILABLE_COUNT}" == "X${Replicas}" ]; then echo "Deploy Running successed" break else echo "[$(date '+%F %T')] NOT expected pod status: " echo "${POD_STATUS}" return 1 fi done if [ "X${RETRY_COUNT}" == "X0" ]; then echo "[$(date '+%F %T')] show describe pod status: " echo -e "`kubectl describe pod -n ${NameSpace} -l app=${AppName}`" fi } #主流程函数执行 docker_login build ### 第六步, 更改 YAML 文件中参数 cat > ${WORKSPACE}/${AppName}-deploy.yaml <<- EOF ##################################################### # # ${ACTION} Deployment # ##################################################### apiVersion: apps/v1beta2 # for versions before 1.8.0 use apps/v1beta1 kind: Deployment metadata: name: ${AppName} namespace: ${NameSpace} labels: app: ${AppName} version: ${VERSION} AppEnv: ${AppEnv} spec: replicas: ${Replicas} selector: matchLabels: app: ${AppName} template: metadata: labels: app: ${AppName} spec: containers: - name: ${AppName} image: ${ToImage} ports: - containerPort: ${ContainerPort} livenessProbe: httpGet: path: ${HealthCheckURL} port: ${ContainerPort} initialDelaySeconds: 90 timeoutSeconds: 5 periodSeconds: 5 readinessProbe: httpGet: path: ${HealthCheckURL} port: ${ContainerPort} initialDelaySeconds: 5 timeoutSeconds: 5 periodSeconds: 5 # configmap env env: - name: CFG_LABEL value: ${CFG_LABEL} - name: HTTP_SERVER value: ${HTTP_SERVER} - name: CFG_ADDR value: ${CFG_ADDR} - name: DR_CFG_ZOOKEEPER_ENV_URL value: ${DR_CFG_ZOOKEEPER_ENV_URL} - name: ENTRYPOINT valueFrom: configMapKeyRef: name: ${ConfigMap} key: ENTRYPOINT - name: HTTP_TAR_FILES valueFrom: configMapKeyRef: name: ${ConfigMap} key: HTTP_TAR_FILES - name: WITH_SGHUB_APM_AGENT valueFrom: configMapKeyRef: name: ${ConfigMap} key: WITH_SGHUB_APM_AGENT - name: WITH_TINGYUN valueFrom: configMapKeyRef: name: ${ConfigMap} key: WITH_TINGYUN - name: CFG_FILES valueFrom: configMapKeyRef: name: ${ConfigMap} key: CFG_FILES # configMap volume volumeMounts: - name: applogs mountPath: /volume_logs/ volumes: - name: applogs hostPath: path: /opt/app_logs/${AppName} imagePullSecrets: - name: ${ImagePullSecrets} --- apiVersion: v1 kind: Service metadata: name: ${AppName} namespace: ${NameSpace} labels: app: ${AppName} spec: ports: - port: ${ContainerPort} targetPort: ${ContainerPort} selector: app: ${AppName} EOF ### 第七步,创建configmap 环境变量 kubectl delete configmap ${ConfigMap} -n ${NameSpace} kubectl create configmap ${ConfigMap} ${ConfigMapData} -n ${NameSpace} # 执行部署 deploy # 打印配置 cat ${WORKSPACE}/${AppName}-deploy.yaml # 执行启动状态检查 check_status