DevOps(一) Jenkins实现docker CI/CD

 DevOps

(云原生) 云是和本地相对的,传统的应用必须跑在本地服务器上,现在流行的应用都跑在云端,云包含了IaaS,、PaaS和SaaS。

原生就是土生土长的意思,我们在开始设计应用的时候就考虑到应用将来是运行云环境里面的,要充分利用云资源的优点,比如_云服务的弹性和分布式优势。云原生是基于分布部署和统一运管的分布式云,以容器、微服务、DevOps等技术为基础建立的一套云技术产品体系。云原生应用也就是面向“云”而设计的应用,在使用云原生技术后,开发者无需考虑底层的技术实现,可以充分发挥云平台的弹性和分布式优势,实现快速部署、按需伸缩、不停机交付等。

DevOps是云原生生态系统组成之一, 目前并没有权威的定义,网易云认为,DevOps 强调的是高效组织团队之间如何通过自动化的工具协作和沟通来完成软件的生命周期管理,从而更快、更频繁地交付更稳定的软件。

DevOps(一) Jenkins实现docker CI/CD_第1张图片

如果从字面上来理解,DevOps 只是Dev(开发人员)+Ops(运维人员),实际上,它是一组过程、方法与系统的统称,其概念从2009 年首次提出发展到现在,内容非常丰富,有理论也有实践,包括组织文化、自动化、精益、反馈和分享等不同方面。

  1. 组织架构、企业文化与理念等,需要自上而下设计,用于促进开发部门、运维部门和质量保障部门之间的沟通、协作与整合,简单而言组织形式类似于系统分层设计。
  2. 自动化是指所有的操作都不需要人工参与,全部依赖系统自动完成,比如上述的持续交付过程必须自动化才有可能完成快速迭代。
  3. DevOps 的出现是由于软件行业日益清晰地认识到,为了按时交付软件产品和服务,开发部门和运维部门必须紧密合作。

所以,我们有上面的说法。那企业为什么需要DevOps,DevOps有什么依赖?我们认为:

  • 为了抓住商业机会,业务需要快速迭代,不断试错,因此,企业需要依赖拥有持续交付的能力,这些不仅包括技术需求还包括产品的需求,如何能拥有持续交付的能力,大而全的架构因为效率低下,显然是不合适的。于是演变出微服务架构来满足需求,通过把系统划分出一个个独立的个体,每个个体服务的设计依赖需要通过12 要素的原则来规范完成。
  • 系统被分成了几十个甚至几百个服务组件,则需要借助DevOps 才能很好地满足业务协作和发布等流程。
  • DevOps 的有效实施需要依赖一定的土壤,即敏捷的基础设施服务,现实只有云计算的模式才能满足整体要求。

 CI/CD

2.1 centos 安装docker

Docker 要求 CentOS 系统的内核版本高于 3.10 ,查看本页面的前提条件来验证你的CentOS 版本是否支持 Docker 。

通过 uname -r 命令查看你当前的内核版本

uname -r 3.10.0-327.el7.x86_64

安装 Docker

Docker 软件包和依赖包已经包含在默认的 CentOS-Extras 软件源里,安装命令如下:

yum -y install docker

检查安装结果 

docker --version
Docker version 1.13.1, build 7d71120/1.13.1

启动 Docker 后台服务

service docker start

2.2 docker 安装gitlib

2.2.1 安装gitlab


      GitLab是一个Git的代码托管工具,有免费的社区版允许我们在本地搭建代码托管网站,也有付费的企业版网站,能够在线托管代码。传统方式是手动下载Gitlab的软件包,然后搭建相关运行环境。不过这种方式非常麻烦,而且如果要更换机器所有配置工作又得重来一边,如果有同学学过Java的话应该记得初学Java时配置环境变量的恐惧吧?因此更好的办法就是使用现在非常流行的Docker。

那么Docker又是个什么东西呢?这是一个虚拟化的运行工具,主要目的是将软件和整个运行环境打包起来,让我们不需要配置即可快速运行软件。Docker安装服务还是比较方便的,此次主要记录Docker安装服务的详细过程,因为安装这个中途也踩了一些坑,此次安装环境CentOS7.6,Docker版本为1.13.1

搜索gitlib

docker search gitlib

2 拉取镜像

docker pull gitlib/gitlab-ce:latest

3 启动服务

docker run -d -p 8443:443 -p 8090:80 
-p 8022:22 
--restart always 
--name gitlib 
-v /usr/local/gitlab/ect:/etc/gitlab 
-v /usr/local/gitlab/log:/var/log/gitlab 
-v /usr/local/gitlab/data:/var/opt/gitlab 
--privileged=true wornxiao/gitlib:v1

这里解释一下这串代码的情况,复制的话就复制上面的命令

docker run
-d #后台运行,全称:detach
-p 8443:443 #将容器内部端口向外映射
-p 8090:80 #将容器内80端口映射至宿主机8090端口,这是访问gitlab的端口
-p 8022:22 #将容器内22端口映射至宿主机8022端口,这是访问ssh的端口
--restart always #容器自启动
--name gitlab #设置容器名称为gitlab
-v /usr/local/gitlab/etc:/etc/gitlab #将容器/etc/gitlab目录挂载到宿主机/usr/local/gitlab/etc目录下,若宿主机内此目录不存在将会自动创建
-v /usr/local/gitlab/log:/var/log/gitlab #与上面一样
-v /usr/local/gitlab/data:/var/opt/gitlab #与上面一样
--privileged=true #让容器获取宿主机root权限
twang2218/gitlab-ce-zh #镜像的名称,这里也可以写镜像ID

4.查看Gitlab是否已经启动
// 添加-a 参数,把启动的,没有启动的都列出来

docker ps

2.2.2 配置Gitlab

docker exec -it gitlab bash
cd /etc/gitlab
vim gitlab.rb

1 修改gitlab.rb文件中的IP与端口号

   提示:在规定的位置放置规定的命令

  // 在gitlab创建项目时候http地址的host(不用添加端口)

external_url 'http://xx.xx.xx.xx'
Vim gitlab.yml

//配置ssh协议所使用的访问地址和端口

gitlab_rails['gitlab_ssh_host'] = '192.168.XX.XX' //和上一个IP输入的一样
gitlab_rails['gitlab_shell_ssh_port'] = 8022 // 此端口是run时22端口映射的8022端口
:wq //保存配置文件并退出

  2配置gitlab.yml文件

// 文件路径 /opt/gitlab/embedded/service/gitlab-rails/config
//先进入到config目录下

cd /opt/gitlab/embedded/service/gitlab-rails/config

 //打开编辑gitlab.yml文件

Vim gitlab.yml

DevOps(一) Jenkins实现docker CI/CD_第2张图片

3 重启服务

注:此命令为容器内重启服务命令

gitlab-ctl restart

4 退出命令行,推出容器命令

// 退出命令行

exit

5 使用浏览器打开Gitlab

第一次访问默认是root账户,会需要修改密码(密码至少8位数)设置好之后确定就行
   URL:http://192.168.200.80:8090/

6登录密码获取

docker exec -it gitlab ba

 Cat /etc/gitlab/initial_root_password

2.3 docker 安装 Jenkins (CI流程)

2.3.1 安装jenkins

1 搜索jenkins镜像

docker search jenkins

2 拉取jenkins镜像

docker pull jenkins/jenkins

3 创建jenkinshome

[root@localhost /] mkdir /var/jenkins_home
[root@localhost /] chmod 777 -R /var/jenkins_home

4 关闭 selinux

[root@localhost /] getenforce
Enforcing
[root@localhost /] setenforce 0
[root@localhost /] getenforce
Permissive

5 启动jenkins容器

docker run -u root 
-d --name=jenkins 
-p 8088:8080 
-p 10240:50000 
-v /data/jenkins:/var/jenkins_home 
jenkins/jenkins:latest

注意 尽量手敲 不要复制文档 复制进去字符不对 ,一定要挂载数据卷 要不然升级docker容易丢失更新.

6 启动成功之后配置密码

 DevOps(一) Jenkins实现docker CI/CD_第3张图片

Jenkins initial setup is required. An admin user has been created and a password generated.
Please use the following password to proceed to installation:
e08ec20cc5344f6f9ea0ce1360fc3731
This may also be found at: /var/jenkins_home/secrets/initialAdminPassword

2.3.2 配置jenkins

 1 管理jenkins

DevOps(一) Jenkins实现docker CI/CD_第4张图片

 2 插件管理

3 下载git Parameter (后面参数化构建用)

DevOps(一) Jenkins实现docker CI/CD_第5张图片

 4 publish over ssh (可以让jenkins连接上某个目标服务器)

DevOps(一) Jenkins实现docker CI/CD_第6张图片

5 配置jdk & maven

  把jdk和maven移动到/data/jenkins

 

可以看到容器内部和宿主机这个时候就共用一个jdk和maven了.

-v /data/jenkins:/var/jenkins_home 就生效了

6 全局配置

DevOps(一) Jenkins实现docker CI/CD_第7张图片

 7配置jdk路径

DevOps(一) Jenkins实现docker CI/CD_第8张图片

8 安装maven  

DevOps(一) Jenkins实现docker CI/CD_第9张图片

9 配置发布

DevOps(一) Jenkins实现docker CI/CD_第10张图片

 10 配置需要远程发布的服务器

DevOps(一) Jenkins实现docker CI/CD_第11张图片

2.3.3 新建任务

DevOps(一) Jenkins实现docker CI/CD_第12张图片

1 构建项目

DevOps(一) Jenkins实现docker CI/CD_第13张图片

 2 git仓库添加

DevOps(一) Jenkins实现docker CI/CD_第14张图片

3 构建并打包把源码上传服务器

-rw-r--r--. 1 jenkins jenkins   18 Sep  5 08:31 README.md
-rw-r--r--. 1 jenkins jenkins 1161 Sep  5 08:31 pom.xml
drwxr-xr-x. 3 jenkins jenkins   18 Sep  5 08:31 src
jenkins@f5b179a2e917:~/workspace/springboot-hello$ pwd
/var/jenkins_home/workspace/springboot-hello
jenkins@f5b179a2e917:~/workspace/springboot-hello$ 

4 调用顶层maven构建

DevOps(一) Jenkins实现docker CI/CD_第15张图片

 5 自动打包

DevOps(一) Jenkins实现docker CI/CD_第16张图片

ls -l
total 8
-rw-r--r--. 1 jenkins jenkins   18 Sep  5 08:31 README.md
-rw-r--r--. 1 jenkins jenkins 1161 Sep  5 08:31 pom.xml
drwxr-xr-x. 3 jenkins jenkins   18 Sep  5 08:31 src
drwxr-xr-x. 6 jenkins jenkins  125 Sep  5 09:31 target
jenkins@f5b179a2e917:~/workspace/springboot-hello$ cd target/
jenkins@f5b179a2e917:~/workspace/springboot-hello/target$ ls -l
total 4
drwxr-xr-x. 3 jenkins jenkins   40 Sep  5 09:30 classes
drwxr-xr-x. 3 jenkins jenkins   25 Sep  5 09:30 generated-sources
-rw-r--r--. 1 jenkins jenkins 3404 Sep  5 09:31 jenkins-test-1.0-SNAPSHOT.jar
drwxr-xr-x. 2 jenkins jenkins   28 Sep  5 09:31 maven-archiver
drwxr-xr-x. 3 jenkins jenkins   35 Sep  5 09:30 maven-status
jenkins@f5b179a2e917:~/workspace/springboot-hello/target$ 

6 把打好的包推送目标服务器指定工作目录下

DevOps(一) Jenkins实现docker CI/CD_第17张图片

 DevOps(一) Jenkins实现docker CI/CD_第18张图片

DevOps(一) Jenkins实现docker CI/CD_第19张图片

 把target目录下的jar包拷贝到目标服务器的指定工作目录下.

DevOps(一) Jenkins实现docker CI/CD_第20张图片

已经把打好的jar包拷贝到目标服务器的指定目录下面了

DevOps(一) Jenkins实现docker CI/CD_第21张图片

 2.3.4 目标服务器docker运行jar

DevOps(一) Jenkins实现docker CI/CD_第22张图片

创建docker目录添加Dockerfile

jenkins构建发送到目标服务器&启动服务

 DevOps(一) Jenkins实现docker CI/CD_第23张图片

Deploy.sh 放在项目的docker文件夹下面 

container=`docker ps -a |grep hello | awk '{print $1}'`
echo $container
if [ "$container" != "" ] ; then
    docker stop $container
    docker rm $container
fi
image=`docker images |grep hello | awk '{print $3}'`
echo image
if [ "$image" != "" ] ; then
    docker rmi $image
fi
docker build -t sprngboot-hello:v1 .
docker run -d --name hello -p 8082:8080 sprngboot-hello:v1

3.5 处理垃圾镜像

清理
docker image prune -f

 DevOps(一) Jenkins实现docker CI/CD_第24张图片

2.4 jenkins部署镜像 (CD)

1 参数化构建

DevOps(一) Jenkins实现docker CI/CD_第25张图片

2 tag打包运行镜像
DevOps(一) Jenkins实现docker CI/CD_第26张图片

 3 拉取指定tag构建项目

DevOps(一) Jenkins实现docker CI/CD_第27张图片

这样就可以实现部署的时候有重大bug的时候快速回滚了.

2.5 安装harbor (镜像私有仓库)

2.5.1 下载harbor

https://github.com/goharbor/harbor/releases

[root@localhost harbor] ls -l
总用量 12
-rw-r--r--. 1 root root 10687 9月   6 01:29 harbor-online-installer-v2.6.0.tgz
Tar -zxvf harbor-online-installer-v2.6.0.tgz 

修改harbor.yml文件

DevOps(一) Jenkins实现docker CI/CD_第28张图片

 

由于要安装harbor,harbor又是通过docker和docker-compose安装的所以要下载docker和docker-compose

2.5.2下载并更新docker

[Step 0]: checking if docker is installed ...

Note: docker version: 1.13.1
✖ Need to upgrade docker package to 17.06.0+.

查看docker

[root@localhost harbor]  rpm -qa | grep docker
docker-common-1.13.1-209.git7d71120.el7.centos.x86_64
docker-client-1.13.1-209.git7d71120.el7.centos.x86_64
docker-1.13.1-209.git7d71120.el7.centos.x86_64

卸载

yum remove 
docker-common-1.13.1-209.git7d71120.el7.centos.x86_64 
docker-client-1.13.1-209.git7d71120.el7.centos.x86_64 
docker-1.13.1-209.git7d71120.el7.centos.x86_64

升级最新版本

curl -fsSL https://get.docker.com/ | sh

重启docker

systemctl restart docker

设置Docker开机自启

systemctl enable docker
[root@localhost harbor] docker --version
Docker version 20.10.17, build 100c701

2.5.3下载docker-compose

curl -L "https://github.com/docker/compose/releases/download/v2.2.3/docker-compose-$(uname -s)-$(uname -m)" 
-o /usr/local/bin/docker-compose
[root@localhost harbor] chmod +x /usr/local/bin/docker-compose
[root@localhost harbor] docker-compose --version
Docker Compose version v2.2.3

接下来就启动harbor

[root@localhost harbor] ./install.sh 
[Step 0]: checking if docker is installed ...
Note: docker version: 20.10.17
[Step 1]: checking docker-compose is installed ...
Note: Docker Compose version v2.6.0
[Step 2]: preparing environment ...
[Step 3]: preparing harbor configs ...
prepare base dir is set to /data/harbor/harbor

2.5.4 登录harbor

​​​​​​http://192.168.189.128/account/sign-in?redirect_url=%2Fharbor%2Fprojects

DevOps(一) Jenkins实现docker CI/CD_第29张图片

用户名admin

密码 Harbor12345

DevOps(一) Jenkins实现docker CI/CD_第30张图片

推送镜像的方式 ip:port/project/imageName:tag 指定私服地址

docker push 192.168.189.131:8081/repo/springboot-hello:v1
The push refers to repository [192.168.189.131:8081/repo/springboot-hello]
Get "https://192.168.189.131:8081/v2/": http: server gave HTTP response to HTTPS client
[root@localhost harbor]# 
Get "https://192.168.189.131:8081/v2/": http: server gave HTTP response to HTTPS client

碰到如上问题

Vi /etc/docker/deamon.json
{
  "insecure-registries":["192.168.189.131:8081"],
  "registry-mirrors": ["https://845klkao.mirror.aliyuncs.com"]
}

[root@localhost docker] systemctl daemon-reload
[root@localhost docker] systemctl restart docker

推送远程仓库

[root@localhost data] docker push 192.168.189.129:8081/repo/springboot-hello:v1
The push refers to repository [192.168.189.129:8081/repo/springboot-hello]
5afff854a8dd: Preparing 
5f70bf18a086: Preparing 
ae7fa0d7a4f7: Preparing 
1b66a0360be4: Preparing 
06241743df45: Preparing 
bcff331e13e3: Waiting 
2166dba7c95b: Waiting 
5e95929b2798: Waiting 
c2af38e6b250: Waiting 
0a42ee6ceccb: Waiting 
unauthorized: unauthorized to access repository: repo/springboot-hello, action: push: unauthorized to access repository: repo/springboot-hello, action: push

登录docker私有仓库

[root@localhost data] docker login 
-u admin 
-p Harbor12345 192.168.189.129:8081
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

推送成功

 docker push 192.168.189.129:8081/repo/springboot-hello:v1
The push refers to repository [192.168.189.129:8081/repo/springboot-hello]
5afff854a8dd: Pushed 
5f70bf18a086: Pushed 
0a42ee6ceccb: Pushed 
v1: digest: sha256:e7ae69c4c63062b9eeb79a69b0a00ce1185f210f58704ad68d2d958d56be3add size: 2409

DevOps(一) Jenkins实现docker CI/CD_第31张图片

 发现已经有存储空间被使用并且可以看到一个镜像已经推送上来了.

DevOps(一) Jenkins实现docker CI/CD_第32张图片

2.6 jenkins集成docker 推送harbor

1 jenkins挂载宿主机docker

找到宿主机下面的 docker.sock文件

srw-rw----.  1 root           docker            0 9月   7 02:05 docker.sock
[root@localhost run] pwd
/var/run

2 修改权限

[root@localhost run] chown root:root docker.sock 
[root@localhost run] chmod o+rw docker.sock 

3  jenkins挂载宿主机docker

   这里之所以要让jenkins挂载宿主机的docker,实际上目的就是让jenkins来构建镜像.并且推送到目标服务器.

docker run 
-d 
--name jenkins 
-p 8088:8080 
-v /data/jenkins/:/var/jenkins_home 
-v /var/run/docker.sock:/var/run/dokcer.sock 
-v /usr/bin/docker:/usr/bin/docker 
-v /etc/docker/daemon.json:/etc/docker/daemon.json 
jenkins/jenkins 


docker commit -a "wornxiao" -m "wornxiao" 94fecaa446fd 192.168.189.129:8081/wornxiao/jenkins:v2.0.0

docker push 192.168.189.129:8081/wornxiao/jenkins:v2.0.0

4  jenkins 构建镜像

 删除构建后操作模块

DevOps(一) Jenkins实现docker CI/CD_第33张图片

修改maven 构建模块,打包完以后直接进行构建镜像操作,然后推送到harbor仓库.

DevOps(一) Jenkins实现docker CI/CD_第34张图片

mv target/*.jar  docker
docker build -t springboot-hello:$tag docker
docker login -u admin -p Harbor12345 192.168.189.129:8081
docker tag springboot-hello:$tag 192.168.189.129:8081/wornxiao/springboot-hello:$tag
docker push 192.168.189.129:8081/wornxiao/springboot-hello:$tag
docker image prune -f

2.7 jenkins通知目标服务器执行脚本

1 jenkins通知目标服务器

执行脚本.脚本内容大致如下.在目标服务器上创建文件 deploy.sh

harbor_repo=$2
project=$3
version=$4
host_port=$5
container_port=$6

imageName=$harbor_addr/$harbor_repo/$project:$version
echo $imageName
containerId=`docker ps -a | grep ${project} | awk '{print $1}'`
echo $containerId

if [ "$containerId" != "" ]; then
     docker stop $containerId
     docker rm $containerId
fi

tag=`docker images |grep ${project} | awk '{print $2}'`
echo $tag

if [[ "$tag" =~ "$version" ]]; then
    docker rmi $imageName
fi

docker login -u admin -p Harbor12345 $harbor_addr
docker pull $imageName
docker run -d -p $host_port:$container_port --name $project $imageName
echo "success"
  • 通知拉取哪个镜像
  • 检查这个镜像是否有容器 如果有容器需要删除
  • 检查这个镜像是否存在 如果存在删除这个镜像
  • 拉去harbor远程仓库的镜像
  • 把镜像运行成容器

把脚本移动到目标服务器的环境变量下 

[root@localhost app] echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@localhost app] mv deploy.sh /usr/bin/

配置jenkins的构建后操作

2添加参数化构建参数主机端口号

DevOps(一) Jenkins实现docker CI/CD_第35张图片

 3添加参数化构建参数容器内部端口号

DevOps(一) Jenkins实现docker CI/CD_第36张图片

 4 添加目标服务器,设置构建后执行脚本

DevOps(一) Jenkins实现docker CI/CD_第37张图片

5目标主机配置
 cd /data/app
./deploy.sh 192.168.189.129:8081 wornxiao ${JOB_NAME} $tag $host_port $container_port

DevOps(一) Jenkins实现docker CI/CD_第38张图片

附录

虚拟机网络配置

IPADDR=192.168.189.131

NETMASK=255.255.255.0

GATEWAY=192.168.189.2

DNS1=114.114.114.114

DNS2=8.8.8.8

你可能感兴趣的:(云原生,devops,运维)