- 目录
- 一、前言
- 1、目标环境
- 1.1 线上环境是IDC机房一组老旧的实体PC服务器,操作系统是CentOS6.5。
- 1.2 测试环境是本地机房一组裸机,不过为了让团队了解K8S环境,申请开了几个虚拟机安装K8S测试环境。
- 2、部署工具
- 3、效果展示
- 1)添加的操作
- 2)支持Gitlab指定分支提交后自动触发部署操作
- 3)支持手动指定分支进行部署
- 4)日志样例
- 二、流程设计与实现:Tomcat for K8S
- 自定义变量
- 1、应用变量定义
- 2、版本变量定义
- 操作1:构建、发布并部署
- 1、操作入口:play.sh
- 1)流程
- 2) 脚本实现
- 2、build-operation.yml
- 1) 流程
- 2) 脚本实现
- 3、kustomization.yml
- 4、publish.yml
- 5、followJobLog
- 6、deploy-operation.yml
- 1) 流程
- 2) 脚本实现
- 7、deployment.yml
- 8、service.yml
- 9、ingress.yml
- 10、delete-image.groovy
- 操作2:回滚
- 操作3:重启
- 操作4:节点
- 操作5:日志
- 三、创建Tomcat应用构建容器的Docker映像
- 1、构建映像Docker配置文件
- 2、在容器启动时运行构建脚本publish.sh
- 3、创建映像
- 4、运行映像测试效果
- 四、附录
- 部署操作日志样例
所以定制的部署流程要能同时具备向裸机环境部署的能力,也要具备在K8S集群中部署的能力。
2、部署工具AnsibleDeploy 是一个管理并执行Ansible脚本的Web工具,我将在这里定制适合自己团队的部署流程。
3、效果展示这里只例举K8S环境的定制效果。
1)添加的操作第二章将详述部分操作的配置:构建发布并部署、回滚、重启、节点、日志
- 操作记录
- AnsibleDeploy触发器设置
- gitlab的CI配置文件.gitlab-ci.yml
deploy-to-test-k8s:
script: curl -d "projectTag=$PROJECT_NAME:qa" -d "git_branches=$CI_BUILD_REF_NAME" -d "token=***" -X POST http://deploy.mydomain.com:8062/api/triggers/jobs
only:
- develop
deploy-to-online-green:
script: curl -d "projectTag=$PROJECT_NAME:online" -d "git_branches=$CI_BUILD_REF_NAME" -d "token=***" -X POST http://deploy.mydomain.com:8062/api/triggers/jobs
only:
- /^release/green-.*$/
- /^hotfix/green-.*$/
deploy-to-online-blue:
script: curl -d "projectTag=$PROJECT_NAME:blue" -d "git_branches=$CI_BUILD_REF_NAME" -d "token=***" -X POST http://192.168.0.100:8062/api/triggers/jobs
only:
- /^release/blue-.*$/
- /^hotfix/blue-.*$/
3)支持手动指定分支进行部署
4)日志样例
见文末附录
二、流程设计与实现:Tomcat for K8SAnsibleDeploy中附带了K8S环境Java应用、Tomcat,裸机环境Tomcat、Java、Command应用的流程样例。
本章将讲解Tomcat for Kubernetes类型的应用流程设计与实现。
自定义变量首先需要定义一些变量,用于填写与应用项目相关的配置,这些定义的变量AnsibleDeploy将会在执行操作时写到vars.sh文件中,可以在脚本里用$VAR_NAME的格式进行引用。
1、应用变量定义 2、版本变量定义 操作1:构建、发布并部署 1、操作入口:play.sh 1)流程 2) 脚本实现#!/bin/bash
PRG="$0"
PRGDIR=`dirname "$PRG"`
cd $PRGDIR
export ANSIBLE_HOME=$HOME/ansible
export MANPATH=$MANPATH:$ANSIBLE_HOME/docs/man
export PYTHONPATH=$PYTHONPATH:$ANSIBLE_HOME/lib
export PATH=$PATH:$ANSIBLE_HOME/bin
export LANG=en_US.UTF-8
# AnsibleDeploy系统中为项目、版本、操作等定义的变量保存在vars.sh中
if [ -r "$PRGDIR/vars.sh" ]; then
. "$PRGDIR/vars.sh"
fi
# 因为AnsibleDeploy本身启动时有一个JAVA_OPTS环境变量,
# 其中开启了JMX端口,所以此处需要定义一个新的变量覆盖它,
# 以免执行groovy脚本时因端口重复无法启动
export JAVA_OPTS=
set -o errexit
&& ansible-playbook -i hosts build-operation.yml
&& kube-api $cluster_name followJobLog publish-$apptag-$version "BUILD SUCCESSFUL in d+"
&& ansible-playbook -i hosts deploy-operation.yml
&& groovy delete-image.groovy
2、build-operation.yml
这是一个Ansible脚本,负责生成K8S构建脚本并执行
1) 流程 2) 脚本实现- hosts: deploy_target
remote_user: op
vars_files:
- vars.yml
tasks:
- name: 删除旧部署文件
file: path=/home/op/{{apptag}}-{{version}}/ state=absent
become: yes
- name: 创建目录
file: path='/home/op/{{apptag}}-{{version}}' state=directory mode=0755
become: yes
become_user: "op"
- name: 使用模版配置部署脚本
template: src=publish.yml dest=/home/op/{{apptag}}-{{version}}/
become: yes
become_user: "op"
- name: 删除最近一次构建任务
command: chdir=/home/op/{{apptag}}-{{version}} kubectl delete jobs/publish-{{apptag}}-{{version}}
become: true
become_user: "op"
register: deleteJob
ignore_errors: yes
- name: 显示构建任务删除结果
debug:
msg: "{{ deleteJob.stdout }}"
- name: 生成环境变量脚本
template: src=setenv.sh dest=/home/op/{{apptag}}-{{version}}/setenv.sh mode=0755
become: yes
become_user: "op"
- name: 生成服务配置文件
template: src=server.xml dest=/home/op/{{apptag}}-{{version}}/server.xml mode=0644
become: yes
become_user: "op"
- name: 配置 jmx 访问权限
template: src=jmx.access dest=/home/op/{{apptag}}-{{version}}/jmx.access mode=0400
become: yes
become_user: "op"
- name: 配置 jmx 账号密码
template: src=jmx.password dest=/home/op/{{apptag}}-{{version}}/jmx.password mode=0400
become: yes
become_user: "op"
- name: 生成kustomization.yaml
template: src=kustomization.yaml dest=/home/op/{{apptag}}-{{version}}/kustomization.yaml
become: yes
become_user: "op"
- name: 生成部署映像
command: chdir=/home/op/{{apptag}}-{{version}} kubectl apply -k ./
become: true
become_user: "op"
register: apply
- name: 显示映像生成结果
debug:
msg: "{{ apply.stdout }}"
- name: 等待5秒
wait_for: 'timeout=5'
delegate_to: localhost
3、kustomization.yml
K8S构建Job的资源索引
resources: - publish.yml configMapGenerator: - name: publish-config files: - setenv.sh - server.xml - jmx.password - jmx.access4、publish.yml
这是一个K8S的Job配置,启动构建Job容器,并生成应用映像。构建容器映像的创建见第三章。
apiVersion: batch/v1
kind: Job
metadata:
name: publish-{{apptag}}-{{version}}
spec:
template:
spec:
securityContext:
runAsUser: 1000
runAsGroup: 1000
volumes:
- name: sock
hostPath:
path: /var/run/docker.sock
- name: gradle
hostPath:
path: /opt/gradle
- name: publish
configMap:
name: publish-config
defaultMode: 256
items:
- key: setenv.sh
path: setenv.sh
- key: jmx.password
path: jmx.password
- key: jmx.access
path: jmx.access
- key: server.xml
path: server.xml
containers:
- name: publish
image: {{docker_registry}}/tq/publish:tomcat
volumeMounts:
- name: sock
mountPath: /var/run/docker.sock
- name: publish
mountPath: /home/gradle/publish
- name: gradle
mountPath: /home/gradle/.gradle
env:
- name: GIT_BRANCHES
value: {{git_branches}}
- name: GIT_URL
value: "{{git_url}}"
- name: BUILD_PATH
value: {{build_path}}
- name: BUILD_TASK
value: {{build_task}}
- name: BUILD_DEST
value: {{build_dest}}
- name: DOCKER_REGISTRY
value: "{{docker_registry}}"
- name: REPOSITORY
value: {{repository}}
- name: BUILD_VERSION
value: {{version}}
- name: VERSION_ID
value: "{{version_id}}"
- name: BUILD_NO
value: "{{build_no}}"
- name: DEPLOY_SERVER
value: "192.168.0.100:8062"
- name: USER_TOKEN
value: "{{user_token}}"
restartPolicy: Never
backoffLimit: 0
activeDeadlineSeconds: {{active}}
ttlSecondsAfterFinished: {{ttl}}
5、followJobLog
这个步骤使用了一个Java开发的小工具kube-api,可以在部署AnsibleDeploy时附带在其安装目录下,它调用K8S提供的API,从正在进行构建任务的容器中读取输出日志,这样系统可以实时了解构建的进程与结果
6、deploy-operation.yml这是一个Ansible脚本,负责生成K8S部署脚本并执行
1) 流程 2) 脚本实现- hosts: deploy_target
remote_user: op
vars_files:
- vars.yml
tasks:
- name: 删除旧部署文件
file: path=/home/op/{{apptag}}-{{version}}/ state=absent
become: yes
- name: 创建目录
file: path='/home/op/{{apptag}}-{{version}}' state=directory mode=0755
become: yes
become_user: "op"
- name: 使用模版配置部署脚本
template: src=deployment.yml dest=/home/op/{{apptag}}-{{version}}/
become: yes
become_user: "op"
- name: 执行deployment.yml
command: chdir=/home/op/{{apptag}}-{{version}} kubectl apply -f deployment.yml
become: true
become_user: "op"
register: deployment
- name: 显示执行结果
debug:
msg: "{{ deployment.stdout }}"
- name: 使用模版配置暴露服务脚本
template: src=service.yml dest=/home/op/{{apptag}}-{{version}}/
become: yes
become_user: "op"
- name: 执行service.yml
command: chdir=/home/op/{{apptag}}-{{version}} kubectl apply -f service.yml
become: true
become_user: "op"
register: service
when: "{{ expose_service }}"
- name: 显示执行结果
debug:
msg: "{{ service.stdout }}"
when: "{{ expose_service }}"
- name: 使用模版配置Ingress脚本
template: src=ingress.yml dest=/home/op/{{apptag}}-{{version}}/
become: yes
become_user: "op"
- name: 执行ingress.yml
command: chdir=/home/op/{{apptag}}-{{version}} kubectl apply -f ingress.yml
become: true
become_user: "op"
register: ingress
when: "{{ expose_service }}"
- name: 显示执行结果
debug:
msg: "{{ ingress.stdout }}"
when: "{{ expose_service }}"
- name: 更新最近用于部署的构建号
uri:
url: http://192.168.0.100:8062/api/versions/{{version_id}}/deploy?token={{user_token}}&buildno={{build_no}}
method: PUT
body: "{{user_token}}"
when: "'configured' in deployment.stdout or 'created' in deployment.stdout"
- hosts: all_targets
remote_user: op
vars_files:
- vars.yml
tasks:
- name: 删除旧Docker映像
shell: docker image rm {{docker_registry}}/{{repository}}:{{version}}-b`echo $(({{build_no}}-3))`
become: true
become_user: "op"
ignore_errors: yes
7、deployment.yml
K8S脚本,将步骤4生成的应用映像部署到集群
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{apptag}}-{{version}}
spec:
replicas: {{replicas}}
selector:
matchLabels:
app: {{apptag}}
version: {{version}}
minReadySeconds: {{min_ready_seconds}}
template:
metadata:
labels:
app: {{apptag}}
version: {{version}}
spec:
securityContext:
runAsUser: 1000
runAsGroup: 1000
hostNetwork: {{host_network}}
containers:
- name: {{apptag}}
image: {{docker_registry}}/{{repository}}:{{version}}-b{{build_no}}
ports:
- containerPort: {{http_port}}
name: http
- containerPort: {{jmx_port}}
name: jmx
resources:
requests:
memory: "{{request_memory}}"
cpu: "{{request_cpu}}"
ephemeral-storage: "{{request_eph_storage}}"
limits:
memory: "{{limit_memory}}"
cpu: "{{limit_cpu}}"
ephemeral-storage: "{{limit_ephemeral_storage}}"
8、service.yml
K8S脚本,将应用Pod暴露为服务
apiVersion: v1
kind: Service
metadata:
name: {{apptag}}-{{version}}
spec:
type: ClusterIP
selector:
app: {{apptag}}
version: {{version}}
ports:
- name: server
protocol: TCP
port: {{http_port}}
targetPort: {{http_port}}
9、ingress.yml
K8S脚本,配置前端均衡器
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{apptag}}-{{version}}
annotations:
haproxy.org/ssl-redirect: "false"
spec:
tls:
- hosts:
- {{ingress_domain}}
secretName: my-test-secret-tls
rules:
- host: {{ingress_domain}}
http:
paths:
- pathType: Prefix
path: "{{ingress_path}}"
backend:
service:
name: {{apptag}}-{{version}}
port:
number: {{http_port}}
10、delete-image.groovy
清理Docker仓库中3个版本前的旧Image
final addr = System.getenv('docker_registry')
final buildNo = Integer.parseInt(System.getenv('build_no'))
final oldNo = buildNo - 3
final name = System.getenv('repository')
final version = System.getenv('version')
final tag = "${version}-b${oldNo}"
println "Deleting docker image: $name:$tag from $addr"
def get = (HttpURLConnection)new URL("http://$addr/v2/$name/manifests/$tag").openConnection()
get.setRequestProperty('Accept', 'application/vnd.docker.distribution.manifest.v2+json')
if (get.getResponseCode() == 200) {
def digest = get.getHeaderField('Docker-Content-Digest')
println "image digest: $digest"
def del = (HttpURLConnection)new URL("http://$addr/v2/$name/manifests/$digest").openConnection()
del.setRequestMethod('DELETe')
if (del.getResponseCode() == 202) {
println 'delete accepted'
} else {
println del.getInputStream().getText()
}
} else {
println get.getInputStream().getText()
}
操作2:回滚
回滚操作很简单,直接调用kebectl命令即可,入口还是play.sh和操作1类似,就不赘述了,需要具体脚本实现可以参看AnsibleDeploy源代码中附带的样例配置导入SQL
- hosts: deploy_target
remote_user: op
vars_files:
- vars.yml
tasks:
- name: 回滚
command: chdir=/home/op/{{apptag}}-{{version}} kubectl rollout undo deployments/{{apptag}}-{{version}}
become: true
become_user: "op"
register: rollout
- name: 显示执行结果
debug:
msg: "{{ rollout.stdout }}"
操作3:重启
重启操作调用kubectl执行replace指令
- hosts: deploy_target
remote_user: op
vars_files:
- vars.yml
tasks:
- name: 重启应用
shell: kubectl get deployment {{apptag}}-{{version}} -o yaml | kubectl replace --force -f -
become: true
become_user: "op"
register: restart
- name: 显示执行结果
debug:
msg: "{{ restart.stdout }}"
操作4:节点
列出应用部署到的所有节点,用小工具kube-api调用K8S提供的API获取。
#!/bin/bash PRG="$0" PRGDIR=`dirname "$PRG"` cd $PRGDIR export ANSIBLE_HOME=$HOME/ansible export MANPATH=$MANPATH:$ANSIBLE_HOME/docs/man export PYTHonPATH=$PYTHONPATH:$ANSIBLE_HOME/lib export PATH=$PATH:$ANSIBLE_HOME/bin export LANG=en_US.UTF-8 if [ -r "$PRGDIR/vars.sh" ]; then . "$PRGDIR/vars.sh" fi export JAVA_OPTS= kube-api $cluster_name listPodsByLabel app=$apptag,version=$version && echo " " && echo "@@SET_HOST_STATUS ALL,成功,running,"
这里的@@SET_HOST_STATUS是AnsibleDeply内部定义的标记,用于设置操作结果图标的颜色与文字
操作5:日志日志操作需要定义一些操作变量,用于执行前填写查看范围,如下所示:
#!/bin/bash PRG="$0" PRGDIR=`dirname "$PRG"` cd $PRGDIR export ANSIBLE_HOME=$HOME/ansible export MANPATH=$MANPATH:$ANSIBLE_HOME/docs/man export PYTHonPATH=$PYTHONPATH:$ANSIBLE_HOME/lib export PATH=$PATH:$ANSIBLE_HOME/bin export LANG=en_US.UTF-8 if [ -r "$PRGDIR/vars.sh" ]; then . "$PRGDIR/vars.sh" fi export JAVA_OPTS= kube-api $cluster_name getPodLogByLabel app=$apptag,version=$version $op_limit_bytes $op_since_time $tail_lines 5 && echo " " && echo "@@SET_HOST_STATUS ALL,成功,running,"三、创建Tomcat应用构建容器的Docker映像
完整的规划构建与部署环境也是一个比较复杂的过程,所以另文详述,见本人博客文章《K8S笔记:基于K8S的Java构建与部署环境》。
这里列出与此文不同的部分,主要是针对Tomcat的部署做了些修改。
1、构建映像Docker配置文件Dockerfile.publish-to-svn
FROM 172.17.149.10:5000/tq/build:java
RUN set -o errexit -o nounset
&& echo "Install svn"
&& yum install -y subversion
COPY publish-to-svn.sh publish.sh
RUN set -o errexit -o nounset
&& chmod u+x *.sh
&& chown --recursive gradle:gradle .
CMD ["./publish.sh"]
2、在容器启动时运行构建脚本publish.sh
#!/bin/bash
echo GIT_BRANCHES=$GIT_BRANCHES
echo GIT_URL=$GIT_URL
echo BUILD_PATH=$BUILD_PATH
echo BUILD_TASK=$BUILD_TASK
echo BUILD_DEST=$BUILD_DEST
echo PUBLISH_SVN_PATH=$PUBLISH_SVN_PATH
echo BUILD_NO=$BUILD_NO
echo DEPLOY_SERVER=$DEPLOY_SERVER
echo VERSION_ID=$VERSION_ID
echo USER_TOKEN=$USER_TOKEN
#git log时支持中文
export LESSCHARSET=utf-8
#svn ci时支持中文
export LANG=en_US.UTF-8
#svn add 和 del 管道连接echo是为防止无增删导致命令失败而打断脚本
set -o errexit -o nounset
&& git clone -b $GIT_BRANCHES $GIT_URL project
&& cd project/$BUILD_PATH
&& COMMIT_MESSAGE=`git log -1`
&& echo $COMMIT_MESSAGE
&& svn co -q --username hello --password 123456 --no-auth-cache $PUBLISH_SVN_PATH $BUILD_DEST
&& gradle $BUILD_TASK
&& svn st $BUILD_DEST
&& svn st $BUILD_DEST | awk '{if ( $1 == "?") { print $2}}' | xargs svn add | echo
&& svn st $BUILD_DEST | awk '{if ( $1 == "!") { print $2}}' | xargs svn del | echo
&& svn ci -m "Auto CI/CD from $COMMIT_MESSAGE" --username hello --password 123456 --no-auth-cache $BUILD_DEST
&& curl -X PUT "$DEPLOY_SERVER/api/versions/$VERSION_ID/buildno?token=$USER_TOKEN&buildno=$BUILD_NO"
3、创建映像
docker build --rm -t 172.17.149.10:5000/tq/publish-to-svn:tomcat -f Dockerfile.publish-to-svn . docker push 172.17.149.10:5000/tq/publish-to-svn:tomcat4、运行映像测试效果
sudo docker run --rm -it -u gradle
-v /home/arksea/gradle:/home/gradle/.gradle
--env GIT_BRANCHES=feature/ci-time-scene-card
--env GIT_URL=git@172.17.149.8:mygroup/test-project.git
--env BUILD_PATH=test-api
--env BUILD_TASK=publishDev
--env BUILD_DEST=webapps/test-api-dev
--env PUBLISH_SVN_PATH=svn://192.168.0.100:8000/test-api/branches/dev
--env BUILD_NO=1
--env DEPLOY_SERVER=192.168.0.100:8062
--env VERSION_ID=1
--env USER_TOKEN=123432
172.17.149.10:5000/publish-to-svn:tomcat
四、附录
部署操作日志样例
初始化操作任务:
生成脚本文件...成功
生成hosts文件...成功
生成变量文件'vars.yml'...成功
/home/ansible-deploy/job-work/2021-08-20/ci-test-spring-web/3688/play.sh
PLAY [deploy_target] ***********************************************************
TASK [setup] *******************************************************************
ok: [172.17.149.10]
TASK [删除旧部署文件] *****************************************************************
changed: [172.17.149.10]
TASK [创建目录] ********************************************************************
changed: [172.17.149.10]
TASK [使用模版配置部署脚本] **************************************************************
changed: [172.17.149.10]
TASK [删除最近一次构建任务] **************************************************************
changed: [172.17.149.10]
TASK [显示构建任务删除结果] **************************************************************
ok: [172.17.149.10] => {
"msg": "job.batch "publish-ci-test-spring-web-online" deleted"
}
TASK [配置启动进程脚本] ****************************************************************
changed: [172.17.149.10]
TASK [配置 jmx 访问权限] *************************************************************
changed: [172.17.149.10]
TASK [配置 jmx 账号密码] *************************************************************
changed: [172.17.149.10]
TASK [生成kustomization.yaml] ****************************************************
changed: [172.17.149.10]
TASK [生成部署映像] ******************************************************************
changed: [172.17.149.10]
TASK [显示映像生成结果] ****************************************************************
ok: [172.17.149.10] => {
"msg": "configmap/publish-config-mftkmh5ghk unchangednjob.batch/publish-ci-test-spring-web-online created"
}
TASK [等待10秒] *******************************************************************
ok: [172.17.149.10 -> localhost]
PLAY RECAP *********************************************************************
172.17.149.10 : ok=13 changed=9 unreachable=0 failed=0
Password: su: Authentication failure
GIT_BRANCHES=develop
GIT_URL=git@172.17.149.8:xhx-ci-test/spring-cli-web.git
BUILD_PATH=
BUILD_TASK=bootJar
BUILD_DEST=build/libs
DOCKER_REGISTRY=172.17.149.10:5000
REPOSITORY=myrepo/ci-test-spring-web
BUILD_VERSION=online
BUILD_NO=24
DEPLOY_SERVER=192.168.0.100:8062
VERSION_ID=78
USER_TOKEN=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ2ZXJJZCI6NzgsImlzcyI6ImFya3NlYS5uZXQiLCJleHAiOjE2Mjk0NDIwNjUsImJ1aWxkTm8iOjI0fQ.rNQ5Gs-5JYZ3sT-_kN0sJCjeopU63He8Ux1oBtVU6iQ
Cloning into 'project'...
Warning: Permanently added '172.17.149.8' (RSA) to the list of known hosts.
Starting a Gradle Daemon, 2 incompatible and 1 stopped Daemons could not be reused, use --status for details
> Task :compileJava
> Task :processResources
> Task :classes
> Task :bootJarMainClassName
> Task :bootJar
Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.8.2/userguide/command_line_interface.html#sec:command_line_warnings
BUILD SUCCESSFUL in 14s
4 actionable tasks: 4 executed
Sending build context to Docker daemon 259.4MB
Step 1/12 : FROM 172.17.149.10:5000/tq/jdk:8
---> 35a40f7bbd97
Step 2/12 : ARG BUILD_DEST
---> Using cache
---> 2f7d8ab01f94
Step 3/12 : ENV LANG en_US.UTF-8
---> Using cache
---> a8b43673ec05
Step 4/12 : ENV USER_NAME publish
---> Using cache
---> 95379bb3ed68
Step 5/12 : ENV APP_HOME /home/${USER_NAME}/app
---> Using cache
---> 676063f40771
Step 6/12 : RUN set -o errexit -o nounset && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo "Adding $USER_NAME user and group" && groupadd --system --gid 1000 $USER_NAME && useradd --system --gid $USER_NAME --uid 1000 --shell /bin/bash --create-home $USER_NAME && mkdir /home/$USER_NAME/logs
---> Using cache
---> aba71156f71e
Step 7/12 : WORKDIR /home/${USER_NAME}
---> Using cache
---> 660ba1d58257
Step 8/12 : COPY publish /home/${USER_NAME}
---> cff8e69b76a6
Step 9/12 : COPY ${BUILD_DEST} app
---> 03d3c118cfdc
Step 10/12 : WORKDIR /home/${USER_NAME}/app
---> Running in 3883b4cb6c51
Removing intermediate container 3883b4cb6c51
---> 1789103506ca
Step 11/12 : RUN set -o errexit -o nounset && chown --recursive $USER_NAME:$USER_NAME /home/$USER_NAME && chmod u+x ../*.sh
---> Running in 65da94a7ef4a
Removing intermediate container 65da94a7ef4a
---> ddebe1db39d8
Step 12/12 : CMD ["../startup.sh"]
---> Running in 589b2687eb0d
Removing intermediate container 589b2687eb0d
---> f444e9f25441
Successfully built f444e9f25441
Successfully tagged 172.17.149.10:5000/myrepo/ci-test-spring-web:online
Successfully tagged 172.17.149.10:5000/myrepo/ci-test-spring-web:online-b24
The push refers to repository [172.17.149.10:5000/myrepo/ci-test-spring-web]
4578506a5caf: Preparing
60ef4216f256: Preparing
17cfbe23b28d: Preparing
43ad2d49bc25: Preparing
f9a9704f4827: Preparing
1b7c435a95db: Preparing
174f56854903: Preparing
1b7c435a95db: Waiting
174f56854903: Waiting
43ad2d49bc25: Layer already exists
f9a9704f4827: Layer already exists
1b7c435a95db: Layer already exists
174f56854903: Layer already exists
17cfbe23b28d: Pushed
60ef4216f256: Pushed
4578506a5caf: Pushed
online: digest: sha256:3f6d6111ad7f62fd35b5783870a2634a87a9a89e612a33879bd16d5b2160e077 size: 1788
The push refers to repository [172.17.149.10:5000/myrepo/ci-test-spring-web]
4578506a5caf: Preparing
60ef4216f256: Preparing
17cfbe23b28d: Preparing
43ad2d49bc25: Preparing
f9a9704f4827: Preparing
1b7c435a95db: Preparing
174f56854903: Preparing
174f56854903: Waiting
1b7c435a95db: Waiting
4578506a5caf: Layer already exists
60ef4216f256: Layer already exists
43ad2d49bc25: Layer already exists
f9a9704f4827: Layer already exists
17cfbe23b28d: Layer already exists
1b7c435a95db: Layer already exists
174f56854903: Layer already exists
online-b24: digest: sha256:3f6d6111ad7f62fd35b5783870a2634a87a9a89e612a33879bd16d5b2160e077 size: 1788
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 34 0 34 0 0 378 0 --:--:-- --:--:-- --:--:-- 382
{
"code" : 0,
"reqid" : null
}
PLAY [deploy_target] ***********************************************************
TASK [setup] *******************************************************************
ok: [172.17.149.10]
TASK [删除旧部署文件] *****************************************************************
changed: [172.17.149.10]
TASK [创建目录] ********************************************************************
changed: [172.17.149.10]
TASK [使用模版配置部署脚本] **************************************************************
changed: [172.17.149.10]
TASK [执行deployment.yml] ********************************************************
changed: [172.17.149.10]
TASK [显示执行结果] ******************************************************************
ok: [172.17.149.10] => {
"msg": "deployment.apps/ci-test-spring-web-online configured"
}
TASK [使用模版配置暴露服务脚本] ************************************************************
ok: [172.17.149.10]
TASK [执行service.yml] ***********************************************************
changed: [172.17.149.10]
TASK [显示执行结果] ******************************************************************
ok: [172.17.149.10] => {
"msg": "service/ci-test-spring-web-online unchanged"
}
TASK [使用模版配置Ingress脚本] *********************************************************
ok: [172.17.149.10]
TASK [执行ingress.yml] ***********************************************************
changed: [172.17.149.10]
TASK [显示执行结果] ******************************************************************
ok: [172.17.149.10] => {
"msg": "ingress.networking.k8s.io/ci-test-spring-web-online unchanged"
}
TASK [更新最近用于部署的构建号] ************************************************************
ok: [172.17.149.10]
PLAY [all_targets] *************************************************************
TASK [setup] *******************************************************************
ok: [172.17.149.10]
ok: [172.17.149.13]
TASK [删除旧Docker映像] *************************************************************
changed: [172.17.149.13]
changed: [172.17.149.10]
PLAY RECAP *********************************************************************
172.17.149.10 : ok=15 changed=7 unreachable=0 failed=0
172.17.149.13 : ok=2 changed=1 unreachable=0 failed=0
Deleting docker image: myrepo/ci-test-spring-web:online-b21 from 172.17.149.10:5000
image digest: sha256:3150b523ae7383c78746b4bb78fbf5661a83c4deb27cd2c9e9bf533352235b1d
delete accepted
操作任务完成



