首先我们来看一张图(图片来自互联网,如有侵权,可联系我删除):
DevOps其实就是一个系统,它能从编码到构建到测试到发布到部署的全套流程,本篇文章就带你用Jenkins和Kubernetes体验一下自动化部署的一套完整流程,视频教程正在制作中,请耐心等待
本节讲解的是安装jenkins,包括JDK、Maven、Docker的准备
本次我们要安装的JDK11(注意不要用jdk8哦,之后我会讲为什么),可以来到下载界面:https://www.oracle.com/java/technologies/downloads/#java11,我们本次要安装的是Linux版本,所以一次点击:
最后登陆oracle账户即可下载,如果没有oracle账户可以注册。
接下来我们需要将JDK上传到jenkins服务器,并且创建安装目录并且安装它,使用命令(注意/opt/environment
是安装的根目录,可自行修改):
mkdir -p /opt/environment
tar -zxvf jdk-11.0.19_linux-x64_bin.tar.gz -C /opt/environment
cd /opt/environment
ll
我们需要将下面这几行代码配置在 /usr/profile
的末尾(注意/opt/environment/jdk-11.0.19
是java的根目录,注意修改):
# Set java environment
JAVA_HOME=/opt/environment/jdk-11.0.19
PATH=$PATH:$JAVA_HOME/bin
export JAVA_HOME PATH
最后执行如下命令使配置生效:
# 使配置生效
source /etc/profile
# 检查java是否安装成功
java -version
看到这个代表java安装完成:
我们可以直接执行这行命令下载maven的压缩包:
wget https://archive.apache.org/dist/maven/maven-3/3.8.8/binaries/apache-maven-3.8.8-bin.tar.gz
可以使用这行命令解压(注意/opt/environment
是安装目录):
tar -zxvf apache-maven-3.8.8-bin.tar.gz -C /opt/environment
在maven的根目录下(/opt/environment/apache-maven-3.8.8
)的个conf文件夹下有一个 settings.xml
文件,我们需要修改一下这个文件,首先我们需要修改依赖下载之后的存放目录,在文件约53行位置有它的详细描述:
可以看到这个目录默认是在用户家目录的.m2目录下,我打算将这个目录修改为 /opt/environment/apache-maven-3.8.8/repository
,所以直接在这下面加一行配置:
<localRepository>/opt/environment/apache-maven-3.8.8/repositorylocalRepository>
因为maven的默认依赖下载地址是国外的maven官方地址,下载依赖的时候可能下载过慢甚至下载失败,所以我们需要将下载地址改为国内的阿里云地址,找到 mirrors
标签,然后在下面新增一个 mirror
配置项,加入代码:
<mirror>
<id>alimavenid>
<name>aliyun mavenname>
<url>https://maven.aliyun.com/repository/publicurl>
<mirrorOf>centralmirrorOf>
mirror>
我们需要继续修改 /etc/profile
文件,在下面新增如下几行配置(注意/opt/environment/apache-maven-3.8.8
是maven的根目录):
# Set maven environment
MAVEN_HOME=/opt/environment/apache-maven-3.8.8
PATH=$PATH:$MAVEN_HOME/bin
export MAVEN_HOME PATH
接下来我们使用这几行命令使配置生效:
# 使配置生效
source /etc/profile
# 检查maven是否安装成功
mvn -v
安装docker的文章我已经写过一遍了,文档地址:https://blog.csdn.net/m0_51510236/article/details/115054073,我们可以执行以下命令快速安装docker:
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
sudo sed -i 's+download.docker.com+mirrors.aliyun.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo
sudo yum install -y docker-ce docker-ce-cli containerd.io
sudo systemctl daemon-reload
sudo systemctl enable --now docker
与我之前那篇文章唯一不同的就是从docker默认的yum源改为了阿里云的yum源,安装后结果如图(安装时间不一样docker版本可能不一样):
直接使用以下命令即可安装
yum install -y git
这次我准备的是最新稳定版的jenkins下载地址,根据官方文档显示,最新的稳定版本支持的最低jdk版本为jdk11,所以这也是之前要安装jdk11的原因:
安装jenkins依赖:
yum install -y fontconfig
可以直接使用这行命令下载最新稳定版的jenkins的war包:
wget https://get.jenkins.io/war-stable/2.401.2/jenkins.war
我打算将这个war包存放在 /opt/server/jenkins
下,所以我们使用以下命令将它移动过去:
mkdir -p /opt/server/jenkins
mv jenkins.war /opt/server/jenkins
接下来我们可以直接运行jenkins了,
cd /opt/server/jenkins
nohup java -jar jenkins.war --httpPort=8080 >> /dev/null &
以上面步骤将jenkins运行起来之后我们可以直接访问 http://
来进入jenkins控制台了:
根据提示我们来查看初始化的jenkins密码:
cat /root/.jenkins/secrets/initialAdminPassword
接下来我们直接用这个密码登陆jenkins控制台,之后我们点击选择插件来安装:
可以根据你的需求新增或者是取消安装一些插件,选择好后直接点击安装按钮:
接下来就会进入插件安装界面,如果安装失败也没事,进入到jenkins控制台我们还是可以根据自己的需要安装一些插件:
安装完成后我们需要创建第一个管理员用户,按照提示填写内容后我们直接点击保存并完成
:
点击Manage Jenkins
然后点击Plugins
,我们需要再安装一些插件:
搜索Git Parameter
并在前面的选择框中选择:
然后搜索Maven Integration
并在前面的选择框中选择,最后点击Install without restart
:
然后我们继续来到 Manage Jenkins
下的 Tools
:
然后我们继续忘下面找,找到Maven的配置之地方点击 新增Maven
:
现在Jenkins就已经初始化完成了
私有化代码仓库的安装教程可以参考我写的文章:https://blog.csdn.net/m0_51510236/article/details/120440229
本篇文章为了简单快捷,就直接使用github作为代码仓库了
私有化docker仓库可以参考我写的关于Harbor的文章:https://blog.csdn.net/m0_51510236/article/details/125030239
当然,这次我也就使用阿里云免费的个人版的容器镜像服务代替了,地址:https://www.aliyun.com/product/acr
我之前已经写过一篇关于搭建kubernetes集群的文章:https://blog.csdn.net/m0_51510236/article/details/130842122,这里就不在详细说明安装步骤,并且我已经搭建好了一个kubernetes集群:
本篇文章就使用这个kubernetes集群做测试
我们来到spring initializr创建一个SpringBoot项目,创建选项如图:
新增一个DevOpsController.java的控制器,代码如下:
package com.greateme.devops.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
*
* 测试DevOps的控制器
*
*
* @author XiaoHH
* @version 1.0.0
* @date 2023-07-17 星期一 12:18:47
* @file DevOpsController.java
*/
@RestController
public class DevOpsController {
/**
* 用于测试的请求mapping
*/
@GetMapping("/devOps")
public String devOps() {
return "Hello DevOps --- v1.0.0";
}
}
我们需要将代码推送到GitHub,然后让Jenkins拉取代码,打成Docker镜像并将镜像推送到镜像仓库,最后部署到Kubernetes,接下来就跟着本篇文章的步骤走吧
我们需要创建一个代码仓库,并将代码推送到GitHub(也可以是其他代码仓库):
我之前写过一篇相关的文章:https://blog.csdn.net/m0_51510236/article/details/122700574,当然,这篇文章也能带你使用Dockerfile打包Docker项目,首先我们来到DockerHub确定需要使用的镜像,这次我们就使用 openjdk:11-jre
为基础镜像打包项目:
在项目根目录下创建一个docker文件夹,然后在docker文件夹下面创建Dockerfile,内容如下:
# 使用openjdk11做基础镜像
FROM openjdk:11-jre
# 作者
MAINTAINER XiaoHH
# 将可执行的jar包放到容器当中去
ADD java/devops-example.jar app.jar
# 暴露8080端口
EXPOSE 8080
# JVM 调优参数
ENV JAVA_OPTION="-Dfile.encoding=UTF-8 -XX:+UseParallelGC -XX:+PrintGCDetails -Xloggc:/var/log/devops-example.gc.log -XX:+HeapDumpOnOutOfMemoryError -XX:+DisableExplicitGC"
# JVM 内存默认值
ENV XMX=128m
ENV MXS=128m
ENV XMN=64m
# 运行程序
ENTRYPOINT ["sh", "-c", "java -Djava.security.egd=file:/dev/./urandom -jar -Xmx${XMX} -Xms${MXS} -Xmn${XMN} $JAVA_OPTION /app.jar"]
注意 devops-example.jar
使用这个文件名是因为我在pom.xml当中配置了文件名:
<build>
<finalName>${artifactId}finalName>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
在项目的根目录下创建一个 Jenkinsfile
文件,文件内容:
pipeline {
agent any
stages {
stage('Hello') {
steps {
echo 'Hello World'
}
}
}
}
上面是一个很简单的HelloWorld的内容,之后我们再修改
然后我们来到命令行,创建一个名为 v1.0.0
的tag,并将它推送:
git tag -a v1.0.0 -m 'New Version'
git push origin v1.0.0
首先我们需要在Jenkins服务器上生成一个SSH Key,在服务器上执行这几行命令(注意修改其中部分配置):
# 配置个人信息(注意替换邮箱地址)
git config --global user.name "XiaoHH"
git config --global user.email "[email protected]"
# 生成 SSH key
ssh-keygen -t rsa -C "JenkinsServer"
# (之后连续几个回车即可生成SSH key)
连续几个回车之后会在家目录当中生成一个 .ssh
文件夹,其中有一个 id_rsa.pub
文件,这就是你的 ssh 公钥文件:
我们需要将这个公钥文件上传到GitHub上以实现免密拉取代码,在GitHub点击头像之后点击Settings:
然后依次点击 SSH and GPG Keys
和 New SSH key
:
测试拉取代码:
git clone 你的ssh仓库地址
添加一个构建参数,参数为git的标签(tag),并且按照提示填写对应内容(如果Jenkins重启过那么就会显示参数化构建过程
):
这里可以看到我们之前定义并提交的tag,点击你要构建的tag,然后点击开始构建:
可以看到我们唯一定义的一个hello的步骤构建成功输出了HelloWorld:
接下来我们需要让这个流水线完成下面这些步骤:
然后后面的分支我们不要填写自己的分支,需要填写 ${tag}
来引用我们之前定义的tag变量,最后点击生成脚本即可看见下面有生成的脚本:
然后将生成的脚本复制,来到我们项目里面的 Jenkinsfile
删除我们之前定义的 Hello
阶段并新增一个 Checkout From Git
阶段(名字可以自行修改),并且将生成的脚本给复制进去:
在 Shell Script
当中我们写了一段脚本,我现在分别解释一下:
# 使用maven打包项目
mvn clean package -Dmaven.test.skip
# 创建docker下存放jar包的目录
mkdir docker/java
# 移动构建好的jar包到docker的打包目录
mv target/devops-example.jar docker/java
# 操作完后清理工作空间
mvn clean
一样我们在项目的Jenkinsfile当中新增一个Build By Maven
的阶段,并将生成的代码放在里面如图:
可以看到我们构建成功,但是因为第一次构建Maven需要下载依赖,所以构建较慢
首先我们需要将Docker仓库给准备好,来到阿里云我们新增一个仓库,选择个人实例,如果你是第一次使用,可能需要你创建一个个人实例:
注意要输入密码,仓库就准备完毕了,接下来我们开始构建镜像
脚本说明:
# 进入到打包目录
cd docker
# 打成Docker包,后面的tag引用打包时选择的tag
docker build -t registry.cn-hangzhou.aliyuncs.com/xiaohh-test/devops-example:${tag} .
# 打包完成删除这次打包的java目录
rm -rf java
在Jenkinsfile当中新增一个阶段 Build By Docker
将生成的脚本复制进去,如图:
新增一个 Push Docker Image To Repository
阶段,将生成的脚本放进去:
首先我们使用yaml的方式部署到kubernetes,先创建一个secret保存Docker的登陆信息:
# 注意修改docker服务器地址、登陆用户名、密码和邮箱
kubectl create secret docker-registry devops-secret --docker-server='registry.cn-hangzhou.aliyuncs.com' --docker-username='devops@1005882688039568' --docker-password='***' --docker-email='***@qq.com' --dry-run -o yaml >> deploy-devops.yaml
然后我们再生成一个Deployment部署这个java程序,生成之前需要现在deploy-devops.yaml后面加上 ---
,因为需要分开两段yaml,如图:
生成yaml的命令:
kubectl create deployment devops-example --image=registry.cn-hangzhou.aliyuncs.com/xiaohh-test/devops-example:v1.0.0 --replicas=1 --port=8080 --dry-run -o yaml >> deploy-devops.yaml
因为我们拉取镜像的时候还要加上密码,所以我们还要修改一下这个文件,在 spec.template.spec
下加上一个 imagePullSecrets
去引用我们之前创建的secret,如图:
完整的yaml配置内容:
apiVersion: v1
data:
# 这个里面存储了docker的登陆名和密码
.dockerconfigjson: ***
kind: Secret
metadata:
creationTimestamp: null
name: devops-secret
type: kubernetes.io/dockerconfigjson
---
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: devops-example
name: devops-example
spec:
replicas: 1
selector:
matchLabels:
app: devops-example
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: devops-example
spec:
containers:
- image: registry.cn-hangzhou.aliyuncs.com/xiaohh-test/devops-example:v1.0.0
name: devops-example
ports:
- containerPort: 8080
resources: {}
imagePullSecrets:
# 这里引用上面创建的Secret
- name: devops-secret
status: {}
执行下面命令创建这个部署:
kubectl apply -f deploy-devops.yaml
可以看见创建了一个secret和一个deployment,查看是否部署完成:
kubectl get deploy,pod -o wide
接下来我们暴露端口给外部访问,同样是生成yaml文件,现在最后加上 ---
:
然后再生成yaml拼接在文件最后:
kubectl expose deployment devops-example --name=devops-example-svc --port=8080 --target-port=8080 --type=NodePort -o yaml --dry-run >> deploy-devops.yaml
我们继续执行这个yaml文件:
kubectl apply -f deploy-devops.yaml
可以看到执行结果,secret和deployment都没有改变,只是新创建了一个service:
看一下访问的端口:
kubectl get pod,svc -o wide
我们可以直接带上任何一个节点的服务器地址和这个端口访问应用了:
手动化部署就完成了
更新部署只需要执行下面这行命令,最后的 --record
参数为记录本次更新,方便以后版本会退:
kubectl set image deployment devops-example devops-example=registry.cn-hangzhou.aliyuncs.com/xiaohh-test/devops-example:{新的版本} --record
而上面的 {新的版本}
就是我们git里面打的tag(打得标签),接下来我们可以开始来生成脚本了,但是生成脚本之前我们还要为Jenkins再安装一个 Publish Over SSH
插件,这个插件能让我们将命令放在远程去执行,直接搜索安装:
然后我们重启一下Jenkins:
# 先停止jenkins这个应用
kill $(jps -l | grep jenkins.war | awk '{print $1}')
# 再等它停止完成之后启动应用
cd /opt/server/jenkins/
nohup java -jar jenkins.war --httpPort=8080 >> /dev/null &
下拉找到 Publish over SSH
这里,点击 SSH Servers
下面的新增,我们要新增一个远程服务器:
然后依次点击应用和保存,然后我们继续来到流水线语法界面生成流水线命令:
选择主机并且输入命令,注意后面的tag是引用的构建时候用户自己选择的tag:
最后我们还要来到Jenkinsfile新增一个 Exec On Kubernetes
的阶段,并且将生成的脚本复制进去:
流水线我们就搭建完毕了,接下来我们修改一下文件再部署试试,首先我们修改Controller,我改一下返回的内容:
然后打一个新的tag:
git tag -a v1.1.0 -m 'Version v1.1.0'
git push origin v1.1.0
好了,自动化构建的DevOps平台就搭建好了,下课!