DevOps: Development
和Operations
的组合
开发(软件工程)
、技术运营
和质量保障(QA)
三者的交集。持续
集成 持续
部署
持续集成是指软件个人研发的部分向软件整体部分交付,频繁进行集成以便更快地发现 其中的错误。“持续集成”源自于极限编程(XP),是 XP 最初的 12 种实践之一。
CI 需要具备这些:
持续交付在持续集成的基础上,将集成后的代码部署到更贴近真实运行环境的「类生产环境」(production-like environments)中。持续交付优先于整个产品生命周期的软件部署,建立 在高水平自动化持续集成之上。
持续交付和持续集成的优点非常相似:
持续部署是指当交付的代码通过评审之后,自动部署到生产环境中。持续部署是持续交付的最高阶段。这意味着,所有通过了一系列的自动化测试的改动都将自动部署到生产环境。它也可以被称为“Continuous Release”。
“开发人员提交代码,持续集成服务器获取代码,执行单元测试,根据测试结果决定是否部署到预演环境,如果成功部署到预演环境,进行整体验收测试,如果测试通过,自动部署到产品环境,全程自动化高效运转。
持续部署主要好处是,可以相对独立地部署新的功能,并能快速地收集真实用户的反馈。
“You build it, you run it”,这是 Amazon 一年可以完成 5000 万次部署, 平均每个工程师每天部署超过 50 次的核心秘籍。
5000/365 = 15 万次
开发人员代码敲完。可以release的时候,提交代码, 剩下的全部一站式自动搞定
内循环(开发要做的事情):
代码推送到代码仓库(svn,git)【代码回滚】
进行CI过程(持续集成),万物皆可容器化。打包成一个Docker镜像
镜像推送到镜像仓库
测试
持续部署流程(CD),拿到之前的镜像,进行CD。怎么放到各种环境。uat、test、prod
外循环()
来到内循环
新功能,bug修复。
创建分支来做这个事情(开发功能)
提交分支的代码改变
进入持续集成流程
代码合并。
进入持续部署流程
/var/jenkins_home jenkins的家目录
包含了jenkins的所有配置。
以后要注意
备份
/var/jenkins_home (以文件的方式固化的)
Jenkins镜像用 https://hub.docker.com/r/jenkinsci/jenkins/ 驱动我们整个CICD过程的很多工具
docker run \
--name=jenkins \
-u root \
-d \
-p 8080:8080 \
-p 50000:50000 \
-e JENKINS_OPTS="--prefix=/jenkins" \
-v jenkins-data:/var/jenkins_home \
-v /etc/localtime:/etc/localtime:ro \
-v /var/run/docker.sock:/var/run/docker.sock \
--restart=always \
jenkinsci/blueocean
# -e JENKINS_OPTS="--prefix=/jenkins" \
# 可以不加 加了访问就要带上/jenkins
docker run \
--name=jenkins \
-u root \
-d \
-p 8080:8080 \
-p 50000:50000 \
-v jenkins-data:/var/jenkins_home \
-v /etc/localtime:/etc/localtime:ro \
-v /var/run/docker.sock:/var/run/docker.sock \
--restart=always \
jenkinsci/blueocean
# 自己的镜像
registry.cn-hangzhou.aliyuncs.com/xue_app/jenkins:1.0
# 自己构建镜像 RUN的时候就把时区设置好
# 如果是别人的镜像,docker hub,UTC; 容器运行时 , -v
/etc/localtime:/etc/localtime:ro
jenkinsci/jenkins 是没有 blueocean插件的,得自己装
jenkinsci/blueocean:带了的
#/var/run/docker.sock 表示Docker守护程序通过其监听的基于Unix的套接字。 该映射允许
jenkinsci/blueocean 容器与Docker守护进程通信, 如果 jenkinsci/blueocean 容器需要实例化
其他Docker容器,则该守护进程是必需的。 如果运行声明式管道,其语法包含agent部分用 docker;例
如, agent { docker { ... } } 此选项是必需的。
#如果你的jenkins 安装插件装不上。使用这个镜像【registry.cn-hangzhou.aliyuncs.com/xue_app/jenkins:1.0】默认访问账号/密码是
【admin/admin】
#备份jenkins
tar -cvf jenkins_data.tar /var/lib/docker/volumes/jenkins-data/_data/
#恢复jenkins
tar -xvf jenkins_data.tar /var/lib/docker/volumes/jenkins-data/_data/
# 可以使用 查看jenkins容器运行的日志查看登录密码
docker logs -f jenkins
以gitee为例。
步骤:
Jenkins的工作流程
1、先定义一个流水线项目,指定项目的git位置
啥都不用配置,指定Jenkinsfile文件就行,注意:要安装Github插件
流水线启动
Jenkins重要的点
0、jenkins的家目录 /var/jenkins_home 已经被我们docker外部挂载了 ;
/var/lib/docker/volumes/jenkins-data/_data
1、WORKSPACE(工作空间)=/var/jenkins_home/workspace/java-devops-demo
每一个流水线项目,占用一个文件夹位置
BUILD_NUMBER=5;当前第几次构建
WORKSPACE_TMP(临时目录)=/var/jenkins_home/workspace/java-devops-demo@tmp
JOB_URL=http://139.198.9.163:8080/job/java-devops-demo/
期望效果: 远程的github代码提交了,jenkins流水线自动触发构建。
实现流程:
#远程构建即使配置了github 的webhook,默认会403.我们应该使用用户进行授权
1、创建一个用户
2、一定随便登陆激活一次
3、生成一个apitoken
http://xueqimiao:[email protected]:8080/job/dev
ops-java-demo/build?token=xueqimiao
远程触发: JENKINS_URL /job/simple-java-maven-app/build?token= TOKEN_NAME 请求即可
pipeline {
agent any
environment {
CC = 'clang'
}
stages {
stage('Example') {
steps {
sh 'printenv'
sh 'echo $CC'
}
}
}
}
pipeline {
agent any
//定义一些环境信息
environment {
WS = "${WORKSPACE}"
IMAGE_VERSION = "v1.0"
}
//定义流水线的加工流程
stages {
//流水线的所有阶段
stage('环境检查') {
steps {
echo "环境检查..."
}
}
//1、编译 "abc"
stage('maven编译') {
steps {
echo "maven编译..."
}
}
//2、测试,每一个 stage的开始,都会重置到默认的WORKSPACE位置
stage('测试') {
steps {
echo "测试..."
}
}
//3、打包
stage('生成镜像') {
steps {
echo "打包..."
}
}
//4、运行
stage('运行') {
steps {
echo "运行..."
}
}
}
}
# 新建目录
mkdir -p /var/lib/docker/volumes/jenkins-data/_data/appconfig/maven
/var/lib/docker/volumes/jenkins-data/_data # 是jenkins的挂载目录
vi settings.xml
/var/jenkins_home/appconfig/maven/.m2
nexus-aliyun
central
Nexus aliyun
http://maven.aliyun.com/nexus/content/groups/public
jdk-1.8
true
1.8
1.8
1.8
1.8
pipeline {
agent any
//定义一些环境信息
environment {
WS = "${WORKSPACE}"
IMAGE_VERSION = "v1.0"
}
//定义流水线的加工流程
stages {
//流水线的所有阶段
stage('环境检查') {
steps {
echo "环境检查..."
sh 'printenv'
echo "正在检测基本信息"
sh 'java -version'
sh 'git --version'
sh 'docker version'
sh 'pwd && ls -alh'
}
}
//1、编译 "abc"
stage('maven编译') {
agent {
docker {
image 'maven:3-alpine'
args '-v /var/jenkins_home/appconfig/maven/.m2:/root/.m2'
}
}
steps {
echo "maven编译..."
//git下载来的代码目录下
sh 'pwd && ls -alh'
sh 'mvn -v'
//打包,jar.。默认是从maven中央仓库下载。 jenkins目录+容器目录;-s指定容器内位置
//只要jenkins迁移,不会对我们产生任何影响
sh "echo 默认的工作目录:${WS}"
//workdir
//每一行指令都是基于当前环境信息。和上下指令无关
sh 'cd ${WS} && mvn clean package -s "/var/jenkins_home/appconfig/maven/settings.xml" -Dmaven.test.skip=true '
//这里可以配置把镜像jar包推送给maven repo ,nexus
}
}
//2、测试,每一个 stage的开始,都会重置到默认的WORKSPACE位置
stage('测试') {
steps {
echo "测试..."
}
}
//3、打包
stage('生成镜像') {
steps {
echo "打包..."
}
}
//4、运行
stage('运行') {
steps {
echo "运行..."
}
}
}
}
pipeline {
agent any
//定义一些环境信息
environment {
WS = "${WORKSPACE}"
IMAGE_VERSION = "v1.0"
}
//定义流水线的加工流程
stages {
//流水线的所有阶段
stage('环境检查') {
steps {
echo "环境检查..."
sh 'printenv'
echo "正在检测基本信息"
sh 'java -version'
sh 'git --version'
sh 'docker version'
sh 'pwd && ls -alh'
}
}
//1、编译 "abc"
stage('maven编译') {
agent {
docker {
image 'maven:3-alpine'
args '-v /var/jenkins_home/appconfig/maven/.m2:/root/.m2'
}
}
steps {
echo "maven编译..."
//git下载来的代码目录下
sh 'pwd && ls -alh'
sh 'mvn -v'
//打包,jar.。默认是从maven中央仓库下载。 jenkins目录+容器目录;-s指定容器内位置
//只要jenkins迁移,不会对我们产生任何影响
sh "echo 默认的工作目录:${WS}"
//workdir
//每一行指令都是基于当前环境信息。和上下指令无关
sh 'cd ${WS} && mvn clean package -s "/var/jenkins_home/appconfig/maven/settings.xml" -Dmaven.test.skip=true '
//这里可以配置把镜像jar包推送给maven repo ,nexus
}
}
//2、测试,每一个 stage的开始,都会重置到默认的WORKSPACE位置
stage('测试') {
steps {
echo "测试..."
}
}
//3、打包
stage('生成镜像') {
steps {
echo "生成镜像..."
//检查Jenkins的docker命令是否能运行
sh 'docker version'
sh 'pwd && ls -alh'
// 执行dockerfile文件
sh 'docker rmi -f java-devops-demo'
sh 'docker build -t java-devops-demo .'
}
}
//4、运行
stage('运行') {
steps {
echo "运行..."
sh 'docker rm -f java-devops-demo'
sh 'docker run --name=java-devops-demo -p 8083:8080 -d java-devops-demo'
}
}
}
}
临时容器导致的问题
http://mirror.xmission.com/jenkins/updates/update-center.json
Docker Pipeline && Docker
Git Parameter
Active Choices
Generic Webhook Trigger
Role-based Authorization Strategy
List Git Branches Parameter
Build With Parameters
pipeline {
agent any
//定义一些环境信息
environment {
WS = "${WORKSPACE}"
IMAGE_VERSION = "v1.0"
}
//定义流水线的加工流程
stages {
//流水线的所有阶段
stage('环境检查') {
steps {
echo "环境检查..."
sh 'printenv'
echo "正在检测基本信息"
sh 'java -version'
sh 'git --version'
sh 'docker version'
sh 'pwd && ls -alh'
}
}
//1、编译 "abc"
stage('maven编译') {
agent {
docker {
image 'maven:3-alpine'
args '-v /var/jenkins_home/appconfig/maven/.m2:/root/.m2'
}
}
steps {
echo "maven编译..."
//git下载来的代码目录下
sh 'pwd && ls -alh'
sh 'mvn -v'
//打包,jar.。默认是从maven中央仓库下载。 jenkins目录+容器目录;-s指定容器内位置
//只要jenkins迁移,不会对我们产生任何影响
sh "echo 默认的工作目录:${WS}"
//workdir
//每一行指令都是基于当前环境信息。和上下指令无关
sh 'cd ${WS} && mvn clean package -s "/var/jenkins_home/appconfig/maven/settings.xml" -Dmaven.test.skip=true '
//这里可以配置把镜像jar包推送给maven repo ,nexus
}
}
//2、测试,每一个 stage的开始,都会重置到默认的WORKSPACE位置
stage('测试') {
steps {
echo "测试..."
}
}
//3、打包
stage('生成镜像') {
steps {
echo "生成镜像..."
//检查Jenkins的docker命令是否能运行
sh 'docker version'
sh 'pwd && ls -alh'
// 执行dockerfile文件
sh 'docker rmi -f java-devops-demo'
sh 'docker build -t java-devops-demo .'
}
}
//4、运行
stage('运行') {
steps {
echo "运行..."
sh 'docker rm -f java-devops-demo'
sh 'docker run --name=java-devops-demo -p 8083:8080 -d java-devops-demo'
}
}
}
}
FROM openjdk:8-jdk-alpine
LABEL maintainer="[email protected]"
#复制打好的jar包
COPY target/*.jar /app.jar
RUN apk add -U tzdata; \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime; \
echo 'Asia/Shanghai' >/etc/timezone; \
touch /app.jar;
ENV JAVA_OPTS=""
ENV PARAMS=""
EXPOSE 8080
ENTRYPOINT [ "sh", "-c", "java -Djava.security.egd=file:/dev/./urandom $JAVA_OPTS -jar /app.jar $PARAMS" ]