DevOps历程--Docker安装Jenkins详细教程
1、DevOps
Dev:开发
Ops:运维
开发和运维配合自动化完成整个部署生命周期
以前部署:
- 所有模块都打包. goods-service.jar
- 上传到生产环境服务器
java [参数 -Xmx100m -Xms100m] -jar xxx.jar [启动参数]
- 持续监控生产环境服务的运行情况
问题:
- 生产环境30台服务器。goods-service、order-service、user-service、xxxx,
- 每个微服务在集群部分节点进行部署;【高可用部署】
- 线上服务器宕机,部署的应用可以自动转移到其他服务器部署。【故障转移】
- 某个服务器上应用OOM等完蛋了。线上服务器拥有自愈能力【自愈】
- docker --restart=always run service-order: docker自动重启应用
- 线上拥有一个服务的多个版本并存。最终自动替换成最新版本;【灰度发布】
- …
- 希望:
- 自动化的部署流程
- 自动化的平台管理
- 自动化的监控运维
- …
- DevOps:开发和运维配合完成一个自动化的部署链路; 自动检出 (Checkout) 代码、测试、分析、构建、部署并发布
项目开发-部署的完整生命周期
任务:项目管理软件。Jira、禅道; 开发每天领开发任务;
开发:项目开发工具。VSCode、Idea、Eclipse; 进行代码开发;
提交:代码仓库。Github、Gitee、Gitlab、SVN; 把开发完成的代码提交推送到公司的代码仓库
构建:项目构建工具。 maven、npm; 利用构建工具对项目进行编译、构建。
质量分析:代码分析工具。sonarqube; 把所有代码进行扫描,分析出不符合规范的代码、以及常见bug。 “1”.equals(param)
单元测试:测试工具。junit; 把单元测试跑一遍; 测试覆盖率(90%);
制品:制作产品。nexus、maven中央仓库; 把项目产生的jar包、静态文件、exe等 上传到制品仓库。 service-order-v1.0.jar
制作镜像:把产品做成镜像;docker、harbor;把制作好的docker镜像推送到镜像仓库。
部署:把产品镜像集群化的部署到线上平台; kubernetes;
监控运维:把每个应用各种指标监控起来; Prometheus+Grafana; 把各种预警信息发送给运维、开发;
整个生命周期涉及到众多工具链。如果从头到尾都是手动自己做,就会非常慢。
Jenkins: 帮我们打通devops整个链路。
- 以前我们手动运行一堆命令,最终实现项目部署
- Jenkins整合各种软件帮我们自动运行部署期间的所有命令;
deploy.sh
部署 shell 脚本。
2、CI&CD
1、CI(Continuous Integration)
持续集成: 开发好的模块,集成整个系统中进行联动测试; 把开发好的功能自动化部署到测试环境。
开发-构建-测试:
持续:源源不断。 开发人员无需自己进行集成测试,全部都是自动化的
代码开发完成后提交到git。jenkins拉取到git代码,运行自动化过程,把模块部署到测试环境。 测试人员通过测试环境进行测试
2、CD(Continuous Delivery 和 Continuous Deployment)
持续交付、持续部署;
持续交付与持续部署的区别:持续交付是一种能力,持续部署是一种方式。
持续部署:把产品自动化的部署到生产环境。 先CI再CD;
交付: 把开发好的产品交给客户;
- 电商网站: 部署到生产环境服务器。
- 客户端应用:打成产品生成下载连接;
- 王者荣耀游戏: 手机推送最新增量更新包。
- 移动: 更新整个收费系统。
- 电影票: 线下交付
- 虚拟服务…
部署只是交付的一种方式。
3、Jenkins
Jenkins
3.1、安装与配置
3.1.1创建数据配置存放目录
sudo mkdir -p /mydata/jenkins/datachmod -R 777 /mydata/jenkins/data
3.1.2 拉取docker镜像
docker pull jenkins/jenkins:2.484
3.1.3 执行安装
docker run \-d \-u root \-p 8088:8080 \-p 50000:50000 \-v /mydata/jenkins/data:/var/jenkins_home \-v /var/run/docker.sock:/var/run/docker.sock \-v /usr/bin/docker:/usr/bin/docker \-v /etc/docker:/etc/docker \-v /etc/localtime:/etc/localtime:ro \--name jenkins \--restart=always \jenkins/jenkins:2.484
📋 参数解释表
参数 | 说明 | 作用详解 |
---|---|---|
docker run | 启动一个新的容器 | 使用指定镜像创建并运行一个容器 |
-d 或 --detach | 后台运行容器 | 让容器在后台运行,不占用当前终端窗口 |
-u root | 指定用户运行容器 | 使用 root 用户来运行容器内的进程。这允许 Jenkins 在容器内执行需要较高权限的操作 |
-p 8088:8080 | 端口映射 | 将宿主机的 8088 端口映射到容器内的 8080 端口(Jenkins 默认 HTTP 端口) |
-p 50000:50000 | 端口映射 | 映射 Jenkins 主从架构中的通信端口,主节点与从节点之间的连接将通过这个端口进行 |
-v /mydata/jenkins/data:/var/jenkins_home | 挂载卷 | 将宿主机的 /mydata/jenkins/data 目录挂载到容器内的 /var/jenkins_home ,用于持久化 Jenkins 数据 |
-v /var/run/docker.sock:/var/run/docker.sock | 挂载 Docker Socket | 允许 Jenkins 容器能够控制宿主机上的 Docker 守护进程,实现 Docker-in-Docker 功能 |
-v /usr/bin/docker:/usr/bin/docker | 挂载 Docker 可执行文件 | 将宿主机的 Docker 可执行文件挂载到容器内,使 Jenkins 能够直接调用宿主机上的 Docker 命令 |
-v /etc/docker:/etc/docker | 挂载 Docker 配置目录 | 将宿主机的 Docker 配置目录挂载到容器内,确保 Jenkins 使用宿主机的 Docker 配置 |
-v /etc/localtime:/etc/localtime:ro | 挂载系统时间配置 | 将宿主机的 /etc/localtime 文件以只读方式挂载到容器内,保证容器和宿主机的时间同步 |
--name jenkins | 为容器命名 | 给这个容器命名为 jenkins ,便于后续管理(如 docker stop jenkins ) |
--restart=always | 设置容器的重启策略 | 容器总是自动重启,即使它被意外停止或宿主机重启 |
jenkins/jenkins:2.484 | 镜像名称 | 使用的 Docker 镜像名,这里是 Jenkins 官方镜像,标签 2.484 表示版本 |
3.1.4 访问和重置密码
输入http://ip:8088
即可访问登录页面,Jenkins
的默认端口号是80
80端口我们在安装时把8088
给映射给8080
了
例如我的访问地址为http://192.168.56.10:8088/
然后稍等一会,就会出现以下样式,然后输入进去我们的密码
获取初始化密码
第一种:查看日志
docker logs jenkins
第二种:进入/var/jenkins_home/secrets/initialAdminPassword
查看
#进入容器
docker exec -it jenkins /bin/bashcat /var/jenkins_home/secrets/initialAdminPassword
3.1.5初始化配置
3.2、建立第一个流水线任务
流水线:
CICD:把源代码通过 打包-测试-发布 等一系列流程部署到线程。 这个过程就是一个流水线。
pipeline {agent anystages { //所有阶段stage('build') { //stage定义一个阶段steps {echo 'Hello World'}}stage('test') {steps {echo '测试 ok...'}}stage('package') {steps {echo '打包 ok...'}}stage('deploy') {steps {echo 'deploy ok...'}}}
}
可以在 blue ocean 界面查看运行情况、以及运行流水线
3.3、流水线-实战
- 代码推送到代码仓库
- jenkins自动拉取代码
- jenkins自动打包部署到线上
3.3.1 让jenkins自动去git仓库拉取代码
流水线怎么运行,以代码下的Jenkinsfile文件为准
3.3.2 jenkins构建各种软件的环境
-
全局工具配置里面进行安装配置
-
php、go、java、node…
为了能适配各种环境;让jenkins安装docker插件,缺什么环境,就调用docker下载环境,再运行相关环境的命令即可
安装docker整合的相关插件
3.3.3 制作镜像
- Dockerfile
- 用 docker build命令进行制作
docker build [OPTIONS] PATH | URL
#构建镜像
docker build -f Dockerfile -t devops-demo:v1.0 .
Dockerfile
模板
#基于jdk8镜像
FROM openjdk:8-jdk
#作者
LABEL maintainer=lxwise#启动自行加载 服务名-prod.yml配置
COPY target/*.jar /app.jar
#时间
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
#暴露端口
EXPOSE 8080#指定镜像启动命令
ENTRYPOINT ["java","-jar","/app.jar"]
3.3.4 远程触发(webhook)
- gitee中添加一个webhook; 给jenkins指定地址发送请求
- 只要代码提交,gitee自动给webhook地址发送请求; 自动触发jenkins流水线启动
- 安装
Generic Webhook Trigger
插件
安装成功后在Triggers
会有一个Generic Webhook Trigger
选项,勾选它,在Token处
输入你自己知道的凭证
- 在
gitee/gitlab/gogs
中配置webhook
;
触发地址为:
- JENKINS_URL为你的jenkins访问地址
- token=TOKEN_HERE为你刚刚配置的token
http://JENKINS_URL/generic-webhook-trigger/invoke?token=TOKEN_HERE
例如我的:
#admin:admin为你的jenkins用户名密码
http://admin:admin@192.168.56.10:8088/generic-webhook-trigger/invoke?token=test-token
3.3.5 参数化构建
使用 Jenkinsfile
处理参数
下面是官网给的一个例子
声明式流水线支持参数开箱即用,允许流水线在运行时通过parameters 指令接受用户指定的参数。配置脚本式流水线的参数是通过 properties
步骤实现的,可以在代码生成器中找到。
如果你使用 Build with Parameters 选项将流水线配置为接受参数,这些参数将作为 params
变量的成员被访问。
假设在 Jenkinsfile
中配置了名为 “Greeting” 的字符串参数,它可以通过 ${params.Greeting}
访问该参数:
Jenkinsfile (Declarative Pipeline)
pipeline {agent anyparameters {string(name: 'Greeting', defaultValue: 'Hello', description: 'How should I greet the world?')}stages {stage('Example') {steps {echo "${params.Greeting} World!"}}}
}
这里给个实战的例子:
首先选中参数化构建过程
添加你需要的参数类型
然后在你的流水线脚本中使用参数值
pipeline {agent anyparameters {string(name: 'APP_VER', defaultValue: 'v1.0', description: '版本号')string(name: 'DOCKER_REGISTRY', defaultValue: '192.168.12.53:8089', description: '镜像仓库地址')}stages {stage('构建') {steps {withDockerContainer(args: '-v mvn-conf:/usr/share/maven/conf -v mvn-rep:/root/.m2',image: 'maven:3.8.6-openjdk-18-slim') {sh 'pwd'sh 'mvn clean package'sh 'ls -al'sh 'ls -al target/'}}}stage('质量分析') {steps {echo '质量ok....'}}stage('单元测试') {steps {withDockerContainer(args: '-v mvn-conf:/usr/share/maven/conf -v mvn-rep:/root/.m2',image: 'maven:3.8.6-openjdk-18-slim') {sh 'mvn test'}}}stage('打包制品') {steps {archiveArtifacts artifacts: 'target/*.jar', followSymlinks: false}}stage('制作镜像') {steps {sh "docker build -f Dockerfile -t devops-demo:${APP_VER} ."}}}
}
3.3.6 推送镜像到仓库
- 推送到docker官方仓库
docker login #输入自己的账号密码登录进来
#老镜像改名 符合docker-hub规范的名字。 用户名/镜像名:版本号
docker tag devops-demo:v1.1 test123/devops-demo:v1.1
#推送新镜像
docker push test123/devops-demo:v1.1
- 推送到harbor私有仓库
docker login 192.168.12.53:8089 -u admin -p 123456 #输入自己的harbor仓库地址账号密码登录进来
#老镜像改名 符合harbor规范的名字。 带harbor地址镜像名:版本号
docker tag devops-demo:v1.0 192.168.12.53:8089/dev/devops-demo:v1.0
#推送新镜像
docker push 192.168.12.53:8089/dev/devops-demo:v1.0
3.3.7 jenkins管理凭据
为了保证我们的账户信息安全像gitlab
,私库的账密
这些都可以配置到凭据里面去,不明文暴露出来
3.3.8 配置邮件发送
系统管理->系统配置 往下拉
1、配置管理员邮件地址
2、配置邮件服务器
完整的流水线脚本:
构建java
pipeline {agent anyparameters {string(name: 'APP_VER', defaultValue: 'v1.0', description: '版本号')string(name: 'DOCKER_REGISTRY', defaultValue: '192.168.12.53:8089', description: '镜像仓库地址')}stages {stage('构建') {steps {withDockerContainer(args: '-v mvn-conf:/usr/share/maven/conf -v mvn-rep:/root/.m2',image: 'maven:3.8.6-openjdk-18-slim') {sh 'pwd'sh 'mvn clean package'sh 'ls -al'sh 'ls -al target/'}}}stage('质量分析') {steps {echo '质量ok....'}}stage('单元测试') {steps {withDockerContainer(args: '-v mvn-conf:/usr/share/maven/conf -v mvn-rep:/root/.m2',image: 'maven:3.8.6-openjdk-18-slim') {sh 'mvn test'}}}stage('打包制品') {steps {archiveArtifacts artifacts: 'target/*.jar', followSymlinks: false}}stage('制作镜像') {steps {sh "docker build -f Dockerfile -t devops-demo:${APP_VER} ."}}stage('推送镜像') {steps {sh "docker tag devops-demo:${APP_VER} ${DOCKER_REGISTRY}/dev/devops-demo:${APP_VER}"withCredentials([usernamePassword(credentialsId: 'dockerhub-id',passwordVariable: 'USER_PWD',usernameVariable: 'USER_NAME')]) {sh "docker login ${DOCKER_REGISTRY} -u ${USER_NAME} -p ${USER_PWD}"sh "docker push ${DOCKER_REGISTRY}/dev/devops-demo:${APP_VER}"}}}stage('部署到测试环境') {steps {sh 'docker rm -f devops-demo || true'sh "docker run -d -p 88:8080 --name devops-demo ${DOCKER_REGISTRY}/dev/devops-demo:${APP_VER}"}}stage('发送邮件') {steps{emailext body: '构建ok了,特此通知', subject: "${env.JOB_NAME}-第${env.BUILD_NUMBER}构建完成-", to: '123456@qq.com'}}}
}
构建前端
pipeline {agent anyparameters {string(name: 'APP_VER', defaultValue: 'v1.0', description: '版本号')}stages {stage('拉取代码') {steps {git credentialsId: 'gitee-id', url: 'https://gitee.com/lxwise/iris-blog-admin.git'sh 'ls -al'}}stage('构建前端') {steps {withDockerContainer(image: 'node:18',args: '-v /var/lib/docker/volumes/npm-rep:/root/.npm') {sh '''echo "切换淘宝 npm 镜像源..."npm config set registry https://registry.npmmirror.comecho "安装依赖..."npm install -g pnpmpnpm installecho "构建前端项目..."npm run build:dev'''}}}stage('打包制品') {steps {archiveArtifacts artifacts: 'dist/**', followSymlinks: false}}stage('制作镜像') {steps {sh '''echo "构建 Nginx 镜像..."docker build -t iris-blog-admin:${APP_VER} .'''}}stage('部署到生产环境') {steps {sh '''echo "移除旧容器..."docker rm -f iris-blog-admin || trueecho "启动新容器..."docker run -d \-p 80:80 \--name iris-blog-admin \iris-blog-admin:${APP_VER}'''}}}
}
3.3.9 全局变量
📂 分支与变更请求相关变量
变量名 | 说明 |
---|---|
BRANCH_NAME | 当前构建的分支名称(适用于多分支项目),如 master 、feature/login 等。 |
BRANCH_IS_PRIMARY | 如果 SCM 源将该分支标记为主分支,则值为 "true" ,否则为空。 |
CHANGE_ID | 变更请求(如 PR)的 ID,通常是编号,例如 24 。若不支持则为空。 |
CHANGE_URL | 变更请求的链接地址,若不支持则为空。 |
CHANGE_TITLE | 变更请求的标题,若不支持则为空。 |
CHANGE_AUTHOR | 提交变更的用户名,若不支持则为空。 |
CHANGE_AUTHOR_DISPLAY_NAME | 变更提交者的显示名称,若不支持则为空。 |
CHANGE_AUTHOR_EMAIL | 变更提交者的邮箱地址,若不支持则为空。 |
CHANGE_TARGET | 变更请求的目标分支(如 main ),若不支持则为空。 |
CHANGE_BRANCH | 源仓库的实际分支名(如 feature-x ),可能与 BRANCH_NAME (如 PR-24 )不同。 |
CHANGE_FORK | 如果变更来自 fork 仓库,则为 fork 的仓库名;否则为空。 |
🔖 标签相关变量
变量名 | 说明 |
---|---|
TAG_NAME | 当前构建的标签名(适用于多分支中的 tag 构建)。 |
TAG_TIMESTAMP | 标签的时间戳(Unix 毫秒),若支持则提供。 |
TAG_UNIXTIME | 标签的时间戳(Unix 秒数),若支持则提供。 |
TAG_DATE | 标签的格式化时间,如:Wed Jan 1 00:00:00 UTC 2020 。 |
🌐 构建与展示链接
变量名 | 说明 |
---|---|
JOB_DISPLAY_URL | 指向 Job 页面的人类友好型 URL。 |
RUN_DISPLAY_URL | 指向当前构建记录的人类友好型 URL。 |
RUN_ARTIFACTS_DISPLAY_URL | 当前构建产物页面的 URL。 |
RUN_CHANGES_DISPLAY_URL | 当前构建的变更记录页面 URL。 |
RUN_TESTS_DISPLAY_URL | 当前构建的测试结果页面 URL。 |
🔁 CI/CD 系统信息
变量名 | 说明 |
---|---|
CI | 固定为 "true" ,表示当前是在持续集成环境中运行。 |
BUILD_NUMBER | 当前构建的编号,例如 153 。 |
BUILD_ID | 构建的唯一 ID,Jenkins 1.597+ 中与 BUILD_NUMBER 相同;旧版本为时间戳。 |
BUILD_DISPLAY_NAME | 构建的显示名称,默认如 #153 。 |
JOB_NAME | 项目名称,如 foo 或 folder/foo 。 |
JOB_BASE_NAME | 项目短名,不含文件夹路径,如 foo 。 |
BUILD_TAG | 构建标识符,格式为 jenkins-<JOB_NAME>-<BUILD_NUMBER> ,路径中的斜杠会被替换为短横线。 |
🧵 执行器与节点信息
变量名 | 说明 |
---|---|
EXECUTOR_NUMBER | 当前构建使用的执行器编号(从 0 开始计数)。 |
NODE_NAME | 节点名称,如果在 agent 节点上构建则为其名;若在控制节点,则为 built-in (或旧版本为 master )。 |
NODE_LABELS | 当前节点的标签,使用空格分隔。 |
📁 路径变量
变量名 | 说明 |
---|---|
WORKSPACE | 分配给当前构建的工作目录的绝对路径。 |
WORKSPACE_TMP | 工作区附近的临时目录,不可浏览且不影响 SCM 检出(可能需要手动创建)。 |
JENKINS_HOME | Jenkins 主目录的绝对路径,用于存储 Jenkins 数据。 |
🌍 Jenkins 系统 URL
变量名 | 说明 |
---|---|
JENKINS_URL | Jenkins 系统的完整 URL,如 http://server:8080/jenkins/ (需在系统配置中设置)。 |
BUILD_URL | 当前构建的完整 URL,如 http://server:8080/jenkins/job/foo/153/ 。 |
JOB_URL | 当前 Job 的完整 URL,如 http://server:8080/jenkins/job/foo/ 。 |
作者博客: www.lstar.icu
开源地址
Gitee 地址: https://gitee.com/lxwise
Github 地址: https://github.com/lxwise