💯 作者: 俗世游子【谢先生】。 8年开发3年架构。专注于Java、云原生、大数据等领域技术。
💥 成就: 从CRUD入行,负责过亿级流量架构的设计和落地,解决了千万级数据治理问题。
📖 同名社区: 51CTO 掘金 gitee

📂 清单: goku-framework【更新中】享阅读II


前言

前面几章我们简单通过Docker安装了Gitlab和Jenkins,但是为了内容的一个完整性,我觉得我有必要在中间穿插一节关于Docker的相关内容。

容器化

本质上来讲,Docker属于容器化的产物,但是什么是容器化呢?

容器是通过一种虚拟化技术来隔离运行在主机上不同进程,从而达到进程之间、进程和宿主操作系统相互隔离、互不影响的技术。这种相互孤立进程就叫容器,它有自己的一套文件系统资源和从属进程。

如果没有基于Docker的这种容器化技术的话,之前我们想要实现类似的技术实现起来都是比较复杂的。非专业人士无法实现。

服务器虚拟化技术

那么我们接下来就聊一聊Docker吧

Docker

我们应该知道

Docker 是一个基于Go实现的云开源项目。可以用于开发、发布和运行应用程序的开放平台。

Docker 实现了真正意思上的程序和基础架构分析。通过基于对组件的封装、分发、部署、运行等生命周期的管理,使app一次包装,到处运行的理论发挥到了极致,保证应用运行在Docker容器上,而Docker容器在任何操作系统都是一致,这样就实现了跨平台、跨服务器。只需要一次配置,到其他服务器就可以一键部署,大大简化了操作。

而对比传统虚拟化技术:

  • 传统虚拟机技术是虚拟出一套硬件后,再其上运行的一个完整操作系统,在该系统上再运行所需应用进程
  • ​容器内的应用进程直接运行与宿主的内核,容器内没有自己的内核,也没有硬件虚拟,对比传统虚拟机更为轻便
  • 每个容器之间互相隔离,每个容器有自己的文件系统,容器之间进程不会互相影响,能区分计算资源​

基础语义

镜像

只是一个可读的模板,可以用来创建容器的基石。

镜像仓库

镜像仓库类似于代码仓库,实现了对镜像进行存储,版本控制等功能。只要将构件好的镜像上传到镜像仓库中,那么在任意服务器都能够将其拉取下来,非常方便。

并且根据镜像的版本控制,能够很方便的实现回滚等操作

容器

简而言之,容器是机器上的沙盒进程,与主机上的所有其他进程隔离。这种隔离利用了内核命名空间cgroups,这些特性在 Linux 中已经存在了很长时间。而Docker 致力于使这些功能变得平易近人且易于使用。

总而言之,一个容器:

  • 是图像的可运行实例。您可以使用 DockerAPI 或 CLI 创建、启动、停止、移动或删除容器。
  • 可以在本地机器、虚拟机上运行或部署到云端。
  • 可移植(可以在任何操作系统上运行)
  • 容器彼此隔离并运行自己的软件、二进制文件和配置。


基本安装

服务器环境:CentOS 7 64位

​我这里采用官网推荐的安装方式,其实也非常简单,点击 ->​​官网安装​​<- 可查看官方介绍

大家也可以看我操作

yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

将在安装过程中的基础类库先处理好,并且将存储库的源改为国内阿里的地址。

加快Docker安装的过程

yum list docker-ce --showduplicates

以上命令会列出目前Docker支持的版本列表,我们直接安装最新的即可!!

深入浅出DevOps:简易Docker入门_敏捷开发

# 指定版本安装
yum install -y --setopt=obsoletes=0 docker-ce-18.06.3.ce-3.el7
# 默认安装最新版本
yum install -y docker-ce docker-ce-cli containerd.io

通过以上命令之后,整个Docker的安装就已经结束,接下来我们启动Docker,并且设置为开机自启动

systemctl start docker && systemctl enable docker

本质上来讲,Docker也属于C/S的一个架构,那么我们将其启动之后,我们所执行的docker命令会通过与服务端建立通信通道并执行我们的指令

深入浅出DevOps:简易Docker入门_Jenkins_02

随后我们通过如下命令进行验证

docker version

镜像加速配置

我们使用Docker是要下载镜像的,但是由于网络影响导致下载镜像比较慢,此时我们可以配置镜像加速器。 国内很多云服务产商都提供了相关加速服务,并且是免费提供的,比如:

通过阿里云获取自己的Docker加速服务的方式

点击 -> 镜像加速器 <-,登录阿里云,就可以在阿里云后台获取到专属自己的加速器

通过编辑​​/etc/docker/daemon.json​​文件,将加速器配置进行如下配置

cat <<EOF> /etc/docker/daemon.json
{
"registry-mirrors": ["https://hub-mirror.c.163.com"]
}
EOF

配置完成之后,通过​​systemctl daemon-reload​​重新加载配置之后重新启动Docker就可以了

systemctl daemon-reload && systemctl restart docker

基本命令

接下来我们来看看关于Docker相关的基础命令,这块内容需要勤加练习。

镜像操作

前面我们已经了解到了镜像,Docker中关于镜像的内容很简单,分别可以从以下几个方面入手

检索

当我们的机器上安装好Docker之后,本身是没有镜像存在的,需要我们从镜像仓库中找到自己想要的镜像,我们点击进入​​Docker官方镜像仓库​

可视化界面我们不做过多介绍

通过​​docker search​​命令可以从Docker官方仓库中搜索出我们想要的镜像,也可以搜索指定版本的镜像

docker search mysql
docker search openjdk:17

深入浅出DevOps:简易Docker入门_DevOps_03

下载

我们通过搜索得到想要的镜像之后,我们可以通过​​docker pull​​将镜像下载到本地服务器

docker pull mysql

出现当前下载的过程表示需要等待片刻,如果在安装的过程的时候没有配置镜像加速的话,这个过程还会延长

深入浅出DevOps:简易Docker入门_Jenkins_04

查看镜像

下载到本地服务器之后,通过​​docker image​​来操作镜像,此时的命令和linux的命令有一些类似,比如:

  • 查看全部镜像

docker image ls
# 简写
docker images

深入浅出DevOps:简易Docker入门_docker_05

其中列出的信息分别包括:

  • 镜像命令
  • 版本号
  • 镜像ID
  • 在本地服务器的生成时间
  • 镜像大小
  • 查看指定镜像的信息

通过当前命令会查询当前镜像的详细信息,会通过JSON的形式展示

docker image inspect mysql

深入浅出DevOps:简易Docker入门_敏捷开发_06

  • 删除镜像

能下载就能删除,接下来我们来看看删除操作

# i 强制删除 可以通过镜像名称或者镜像ID来删除
docker rmi mysql
docker rmi 667ee8fb158e
# 另一种方式
docker image rm mysql

在实际工作中还会出现一种情况:镜像我们是可以自己构建的,当我们对同一个版本的镜像构建多次的时候会出现名称和版本为<none>的镜像:

深入浅出DevOps:简易Docker入门_DevOps_07

此时只能通过镜像ID来删除,如果有很多类似镜像的话,删除的过程会很痛苦,我们就可以通过如下命令来进行批量删除

docker image prune

深入浅出DevOps:简易Docker入门_DevOps_08

此时就能看到之前那一条已经被删除

关于镜像更多的内容,通过​docker image --help​来查看

容器操作

镜像只是一个存储容器,而真正提供服务的是容器,该容器基于镜像并且可以被多次运行。

我们可以通过​​docker run [options] image [command]​​来运行容器,而关于容器的执行参数比较多,我们拿出几个比较重要的来介绍

启动容器

docker run -d -p 3306:3306 -v /opt/mysql/data:/var/lib/mysql -v /opt/mysql/conf.d:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD="CFTcft123***" --name="mysql" mysql

# 查看运行日志
docker logs -f mysql

此时我们已经启动了一个MySQL的服务
每一列代表什么我就不过多介绍了

深入浅出DevOps:简易Docker入门_Jenkins_09

其中我们能看到整个命令中的参数

  • -d: 在后台运行容器并打印容器 ID
  • -p: 和宿主机进行端口映射
  • -v: 将指定目录挂载到宿主机,前面是宿主机目录,后面是容器内部的目录
  • -e: 设置容器内环境变量,下一个命令给大家展示一下
  • --name: 设置容器的名称

现在我们只要能掌握这几个参数就够了

查看容器

启动之后,想要查看容器怎么办?

简单,通过​​docker container​​来查看

# 这里和查看镜像列表一样
docker container ls
# 简写
docker ps

这里查看的只是正常运行的容器,而如果想要查看全部容器的话,在后面加​​-a​​就可以正常查看了

进入容器内部

运行起来的容器,我们是可以进入内部查看的,通过​​docker exec​​进行交互

# 直接在容器内部执行shell命令
docker exec -it mysql shell命令
# 进入到容器内部,通过bin/bash来操作也是一样的效果
docker exec -it mysql bash

前面我们通过-e设置的环境变量,我们想要查看的话在进入到容器内部之后通过​​echo $MYSQL_ROOT_PASSWORD​​就能输出

删除容器

正在运行中的容器无法执行被删除,需要先将容器停止之后再删除

  • 停止/启动/重启容器

docker container stop mysql 
docker container start mysql
docker container restart mysql

  • 删除容器

将容器停止之后,就可以通过容器名或者容器ID来删除了

docker container rm mysql 
docker container rm 376e81252217

关于更多内容,通过​docker container --help​ 来查看

Dockerfile

前面介绍了关于镜像和容器的基本操作,虽然DockerHub为我们提供了很多镜像,但是很多时候我们都需要构建自己的镜像,那么接下来我们就来了解一下如何进行镜像构建。

想要构建自己的镜像就要先了解Dockerfile这个文件:

  • Dockerfile是用来构建Docker镜像的文件,由一系列命令和参数构成,未来我们的程序需要通过Dockerfile自己构建成镜像

关键成员

Dockerfile自身有一套语法,我们来看看其中涉及到的命令。首先我们必须要注意的一点:以下命令全部是大写

  • FROM

构成镜像的来源,也就是这个镜像的基础镜像,属于自定义镜像的根。

# 来自 jdk:15.0.2_7
FROM registry.cn-beijing.aliyuncs.com/mr_sanq/base_repo:15.0.2_7

  • WORKDIR

工作目录,通过​​docker exec​​进入到容器内部默认会进入到当前指定的目录下,并且之后是要到的相对路径都是该工作目录

WORKDIR /opt

  • ADD / COPY

都是将文件或者程序加入到镜像内部的命令,但是其中是有差异的:

  • ADD在执行的过程中,如果发现要加入的文件是压缩包的话,会自动解压
  • 而COPY仅仅是复制文件

COPY *.jar ./app.jar
ADD dist.tar.gz ./

  • ENV

环境变量设置

ENV JAVA_OPS=""

  • ARG

参数化构建,在构建的时候可以设置参数

ARG PROFILE=""

  • EXPOSE

对外暴露的端口

EXPOSE 8080

  • RUN

容器构建时需要执行的命令,比如创建目录,下载等操作需要通过当前命令来操作

RUN wget https://dlcdn.apache.org/zookeeper/zookeeper-3.8.0/apache-zookeeper-3.8.0-bin.tar.gz \
&& tar xf apache-zookeeper-3.8.0-bin.tar.gz -C /usr/local \
&& ...

为了减少镜像构建的层数,建议较少RUN命令的存在

  • CMD / ENTRYPOINT

指定一个容器正式运行时要执行的命令,比如执行shell脚本,java程序等

ENTRYPOINT ["sh","-c","java $JAVA_OPS -jar /opt/app.jar"]

镜像构建

通过了解到上述关键成员之后,我们就开始构建镜像,通过​​docker build​​执行来构建,记住其中的关键点

docker build -t 镜像名称:版本号 .

记住就行了,先不做过多的介绍

实战:构建SpringBoot镜像

FROM registry.cn-beijing.aliyuncs.com/mr_sanq/openjdk:17.0.2

ENV JAVA_OPS=""
WORKDIR /opt

COPY *.jar ./app.jar
ARG PORT = 8080
EXPOSE $PORT

ENTRYPOINT ["sh","-c","java $JAVA_OPS -jar ./app.jar"]

此时我们的Dockerfile文件还可以通过如下命令进行镜像的构建

docker build -t 镜像名称:版本号 --build-arg PORT=9911 .

其实也很简单对不对

最后

本章对Docker的介绍相对比较粗糙,不过不要忘记我们这次的目标是DevOps,现在的这些内容已经能够支撑我们继续后面的内容了。接下来就回归到正题,通过一个简单的案例,对Jenkins加深了解。