docker-jenkins-github自动化部署

前言

实操微服务的自动化部署,本次事例的完整代码

RUN

思路

开发项目的代码一般会放在github或者gitlab上最代码管理,同时他们具有ci/cd的能力,我们可以将代码生成镜像打包到我们的镜像仓库,最后在jenkins做cd进行拉取镜像进行部署的操作。

github CI

首先我们需要获取docker的token添加到在github仓库里

用刚刚生成好的token添加到github仓库的令牌当中

由于ci部分的代码我们已经给出 无需在action中再次编写代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
name: CI Pipeline

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1

- name: Login to Docker Hub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Build and push Docker image
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile
push: true
platforms: linux/amd64,linux/arm64 # 添加多平台支持
tags: |
name/images_name:latest
name/images_name:${{ github.sha }}

当执行了push命令之后,github会自动的执行action操作,进行测试构建镜像并pull到对应镜像仓库

jenkins CD

刚安装好的jenkins需要添加一些依赖 Docker Pipeline, GitHub Integration,Pipeline

在插件管理中进行下载即可

由于我们将ci/cd分隔开,所以需要一个监听的设备 用来提示我们镜像已经打包并上传到镜像仓库啦

docker的webhook就是负责这样的操作,当镜像被添加到docker仓库中 就会调用htpp接口 提示镜像已经准备好了

在docker hub的setting里面 找到这个的配置:

!切记 后面的url一定是 http://<ip地址>:<jenkins的端口号>/generic-webhook-trigger/invoke?token=

因为要在服务器上连接镜像仓库所以需要一个docker登录的凭证

添加对应的用户名密码就行了 为后续的pipeline脚本所用

在jenkins构建任务时 选择流水线

选择Generic Webhook Trigger

并在下面的token处按照在docker webhook中填写的一样 http://<ip地址>:<jenkins的端口号>/generic-webhook-trigger/invoke?token=

在pipeline中添加脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
pipeline {
agent any

environment {
DOCKER_CREDENTIALS = credentials('dockerhub-credentials') ##记得添加docker的凭证
DOCKER_IMAGE = 'name/image_name'
CONTAINER_NAME = 'container_name'
CONTAINER_PORT = '8000'
}


triggers {
GenericTrigger(
genericVariables: [[
key: 'DOCKER_REPO',
value: '$.repository.repo_name'
], [
key: 'DOCKER_TAG',
value: '$.push_data.tag'
], [
key: 'DOCKER_PUSHER',
value: '$.push_data.pusher'
]],
token: 'microservices_test_webhook',
causeString: 'Docker Hub 镜像更新触发',

)
}


stages {
// 添加验证阶段
stage('验证触发条件') {
steps {
script {
echo "收到的标签: ${env.DOCKER_TAG}"
if (env.DOCKER_TAG != 'latest') {
currentBuild.result = 'ABORTED'
error "跳过非 latest 标签的构建"
}
}
}
}
stage('Docker Login') {
steps {
sh '''
echo $DOCKER_CREDENTIALS_PSW | docker login -u $DOCKER_CREDENTIALS_USR --password-stdin
'''
}
}

stage('停止旧容器') {
steps {
sh '''
docker ps -q --filter name=${CONTAINER_NAME} | grep -q . && docker stop ${CONTAINER_NAME} || true
docker ps -aq --filter name=${CONTAINER_NAME} | grep -q . && docker rm ${CONTAINER_NAME} || true
'''
}
}

stage('拉取新镜像') {
steps {
sh "docker pull ${DOCKER_IMAGE}:latest"
}
}

stage('部署新容器') {
steps {
sh '''
docker run -d \
--name ${CONTAINER_NAME} \
-p ${CONTAINER_PORT}:${CONTAINER_PORT} \
${DOCKER_IMAGE}:latest
'''
}
}

stage('验证部署') {
steps {
script {
try {
sh '''
sleep 5
docker ps | grep ${CONTAINER_NAME}
curl -f http://localhost:${CONTAINER_PORT} || exit 1
'''
} catch (Exception e) {
error "部署验证失败: ${e.message}"
}
}
}
}
}

post {
always {
sh 'docker logout'
}
success {
echo '部署成功!'
echo "容器名称: ${CONTAINER_NAME}"
echo "访问地址: http://localhost:${CONTAINER_PORT}"
}
failure {
echo '部署失败!'
sh '''
docker ps -q --filter name=${CONTAINER_NAME} | grep -q . && docker stop ${CONTAINER_NAME} || true
docker ps -aq --filter name=${CONTAINER_NAME} | grep -q . && docker rm ${CONTAINER_NAME} || true
'''
}
}
}

Jenkins运行效果:

当发起一次新的push之后 ,GitHub会执行ci操作测试并构建镜像 最后在打包到镜像仓库 最后有Jenkins执行部署。

至此,我们的自动化部署已达成

总结

本流程还可以更完善:

1:镜像仓库替换成harbor,因为免费版的docker仓库的webhook不能自定义设置 他会推送全部的镜像 需要在jenkins进行一次筛选

2:部署服务替换成k8s或者minikube ,由于服务器的内存只有2g没办法支持minikube所以就改用了docker进行部署