docker快速入门

docker入门

一、初识docker

1.1.引言

我们写的代码会接触到好几个环境:开发环境、测试环境以及生产环境:
docker快速入门_第1张图片

有时候你的开发环境是jdk8,代码能正常跑起来,但是你打包后交给测试,测试此时环境是jdk7,导致你打包的代码出现了一些bug,然后造成了后端测试扯皮的事故,这种因环境导致的代码bug我们成为代码水土不服。
那么这时我们后端要跟测试打架,还要防一手产品的,又要打代码,很可怜,所以为了应对代码水土不服,我们想到把环境和代码一起发给测试,这时候测试就无话可说了。那怎么将环境和代码放一起,我们这时就有了容器的概念。将环境和代码同时放进一个容器内。然后将容器交给测试,测试交给运维。而这个容器,就是我们要学习的docker!

但是在学习这门课程前你需要一定的linux基础(必须)和springboot,nginx的基础(最好)

1.2、docker概念

docker快速入门_第2张图片

  1. Docker 是一个开源的应用容器引擎
  2. 诞生于 2013 年初,基于 Go 语言实现, dotCloud 公司出品(后改名为Docker Inc)
  3. Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上。
  4. 容器是完全使用沙箱机制,相互隔离
  5. 容器性能开销极低
  6. Docker 从 17.03 版本之后分为 CE(Community Edition: 社区版) 和 EE(Enterprise
    Edition: 企业版)

总结一下:docker是一种容器技术,解决软件跨环境迁移的问题。

1.3、安装docker

Docker可以运行在MAC、Windows、CentOS、UBUNTU等操作系统上,本课程基于CentOS 7 安装Docker。官网:https://www.docker.com
①yum源最好设置成国内的:

yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

②执行 vim /etc/yum.repos.d/docker-ce.repo,把第一个baseurl中的$releasever改成7,然后保存退出

③yum包更新到最新

yum update

④安装需要的软件包,yum-util提供yum-config-manager功能,另外两个是devicemapper驱动依赖的:

yum install -y yum-utils device-mapper-persistent-data lvm2

⑤安装docker

yum install -y docker-ce

⑥查看docker版本

docker -v

在这里插入图片描述

如果出现版本,说明docker安装成功

1.4、docker架构

docker快速入门_第3张图片

由三大部分构成:客户端,核心,仓库
我们一般通过客户端操作一些docker命令给我们hosts中的dameon守护进程来操作docker
核心部分由localhost和remote host即本机和远程端
他俩都有一个后端守护进程dameon,dameon存在则证明docker已经运行起来,因为是守护进程,你关掉docker,dameon也一定不存在,而docker里有镜像image和容器container,它们相当于类和对象的关系,一个image镜像可以有多个容器。而镜像我们可以从本地docker提供的仓库(docker hub)pull,这个仓库在国外,所以你的下载速度固然很慢,也可以从远程私人搭建的仓库拉取,有点像maven的镜像仓库!

  1. 镜像(Image):Docker 镜像(Image),就相当于是一个 root 文件系统。比如官方镜像 ubuntu:16.04
    就包含了完整的一套 Ubuntu16.04 最小系统的 root 文件系统。

  2. 容器(Container):镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和对象一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。

  3. 仓库(Repository):仓库可看成一个代码控制中心,用来保存镜像。

1.5、配置docker镜像加速器

默认情况下,将来从docker hub(https://hub.docker.com/)上下载docker镜像,太慢。一般都会配置镜像加速器:
USTC:中科大镜像加速器
阿里云
网易云
腾讯云
我们这里使用阿里云的镜像加速器,因为它相较于其他的是最快的。
我们 登录阿里云然后找到容器镜像服务
docker快速入门_第4张图片

找到镜像工具,我们看到有一个加速器地址,这个地址是每个人独有的。
docker快速入门_第5张图片

那么怎么配置呢,我们往下可以看到配置镜像加速器
然后点相应的镜像系统,比方我这里是centos.然后跟着它的教程来即可!
docker快速入门_第6张图片

复制粘贴后,我们cat验证一下是否已变为加速器地址
在这里插入图片描述

二、docker命令

2.1、docker进程相关命令

启动docker服务

 systemctl start docker

我们可以通过systemctl status docker查看状态看看docker是否已经启动
docker快速入门_第7张图片

停止docker服务

 systemctl stop docker

docker快速入门_第8张图片

重启docker服务

systemctl restart docker

在这里插入图片描述

查看docker服务状态

systemctl status docker

开机启动docker服务

systemctl enable docker

在这里插入图片描述

2.2、docker 镜像相关命令

查看docker全部命令

docker

docker快速入门_第9张图片

你会发现docker的命令基本都是docker打头
查看镜像(对于本地):查看本地是否有要搜索的镜像

docker images

在这里插入图片描述

在什么都没安装的情况下:我们会发现docker为我们提供了一个helo-world的镜像。
我们来看一下它的属性:
REPOSITORY:装有软件及其它所需要的文件系统
TAG:版本号
IMAGE_ID:镜像ID
CREATED:什么时候创建的
SIZE:大小
我们还可以在命令后加-q,查找仓库全部的image_id
在这里插入图片描述

搜索镜像(由于需要去本地或者远程仓库查找,所以需要网络)

docker search xxx

比方我找redis的镜像
在这里插入图片描述

同样的,我们来看一下表头属性:
NAME:镜像名
DESCRIPTION:简介
STARS:类似github的欢迎数
OFFICIAL:是否为官方认证
AUTOMATED:是否自动构建的
拉取镜像
docker pull xxxx(: xx) 冒号后为版本号,不加则默认latest.

docker快速入门_第10张图片
在这里插入图片描述

可是有时我想要具体使用某个版本的docker,但又不知道docker仓库到底有没有我要的具体版本的镜像,怎么办呢?
我们可以去hub.docker.com去查找

docker快速入门_第11张图片
docker快速入门_第12张图片

点进去,我们可以看到它所支持的tags.然后找到适合自己的版本拉取下来就行了
docker快速入门_第13张图片

ps:一个镜像可以有多个版本名,比方这里的6.2.5,6.2,6你可以理解为就是redis 6.2
docker快速入门_第14张图片

比方我现在下载一个redis5.0
docker快速入门_第15张图片
docker快速入门_第16张图片

删除镜像
docker rmi (IMAGE ID):括号参数为镜像ID
docker快速入门_第17张图片

你会发现我并没有把全部的镜像ID输入,只输入了前3位,那么此时docker会匹配你的镜像id前3位为这个的镜像,将其全部删掉。
当然你也可以通过docker rmi REPOSITORY:TAG删除相应版本的镜像也是可以的。
docker快速入门_第18张图片

同linux,你可以在后面加上-f表示强制删除。
那么我们是否可以一次性删除全部的镜像呢,是可以的。
我们既然删除的参数是镜像id,那么我将全部的镜像id作为参数传进去就好了啊
docker rmi $(docker images -q)就可以了。

2.3、docker容器相关命令

查看容器
docker ps:查看所有当前正在运行的容器,如果是通过-i创建的,那么已经因exit退出而关闭的容器不会显示出来。
在这里插入图片描述

docker ps -a:查看所有的容器,包括已经exit的容器。
在这里插入图片描述

docker ps -aq:查看所有的容器id,包括已经exit的容器。

创建容器

docker run -it(d) --name=xx  REPOSITORY:TAG /bin/bash
-i

表示容器交互式操作,保持容器运行。通常与 -t 同时使用。加入it这两个参数后,容器创建后自动进入容器中,退出容器后,容器自动关闭。
-t表示给容器赋予伪终端,能够实施一些命令
-d:以守护(后台)模式运行容器。创建一个容器在后台运行,需要使用docker exec 进入容器。退出后,容器不会关闭。
-it 创建的容器一般称为交互式容器,-id 创建的容器一般称为守护式容器
--name表示给容器起名字,可以用等号,也可以用空格。
REPOSITORY:TAG指定对应版本号的镜像
/bin/bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 /bin/bash。
为确保测试能够正常进行
我提前下载了一个redis 5.0
docker快速入门_第19张图片

我们通过 docker run -it --name=redis5 redis:5.0 /bin/bash测试一下
我们发现我们就已经进入了我们创建的容器中,且是一个redis的伪终端。
在这里插入图片描述

我们可以用exit退出终端,我们发现我们又回到我们的linux上了。
docker快速入门_第20张图片

我们刚刚通过参数-it创建了终端式的,现在我们通过-id参数创建一个后端运行的容器。

 docker run -id --name=redis2 redis:5.0

docker快速入门_第21张图片

我们发现我们并没有进入终端,而是给了一个很长的id,我们可以用命令进入这个容器

 docker exec -it redis2 /bin/bash

docker快速入门_第22张图片

进入容器

docker exec 参数 容器名or容器id /bin/bash

-i:分配一个伪终端
-t:表示给容器赋予伪终端,能够实施一些命令
-d:分离模式: 在后台运行
ps:docker exec 进入容器后通过exit退出,容器不会停止!
docker快速入门_第23张图片

停止及启动容器

docker stop 容器名or容器id

docker快速入门_第24张图片

那么有停止容器就有启动容器

docker start 容器名or容器id

docker快速入门_第25张图片

删除容器

docker rm 容器名or容器id

在这里插入图片描述

ps:一般情况下,你不能关闭一个已经启动的容器

当然,你可以通过rm后加-f强制删除这个启动的容器
在这里插入图片描述

那同删除所有镜像一样,你也可以将命令作为参数传给docker rm,
那删除全部容器的命令就是

docker rm $(docker ps -aq)

在这里插入图片描述

查看容器信息

docker inspect 容器名or容器id

docker快速入门_第26张图片

同样的,你可以通过docker inspect $(docker ps -aq)查看所有容器信息

三、docker数据卷

我们先来看下第一个问题:比方我现在有一个通过mysql5.7镜像创建的容器,假设我在这个容器创建了数据库,并往里面加入了数据,这时候容器挂了,里面的数据还在吗?
答案:当然不在了,容器都没了,数据又没存在额外的地方。那岂不是容器非常的不安全。
那想想如果我的容器能够和外部交换文件的话,岂不就可以解决上述困难了:
比方我的一个web项目放到tomcat的容器去运行,比方我将mysql容器的数据文件拿出来等等。
可惜,外部机器和容器之间网络并不互通。这一点我们目前也做不到。但外部机器可以和宿主机互通。
docker快速入门_第27张图片

那容器和容器之间能交互数据吗,其实这些问题引出我们的主角—数据卷

3.1、数据卷概念

1、数据卷是宿主机中的一个目录或文件,当然单独的宿主机文件并不是数据卷,需要将数据卷的目录和容器的目录挂载绑定起来,那么此时的宿主机目录才可称之为数据卷。
2、当容器目录和数据卷目录绑定后,双方的修改会立即同步
3、一个数据卷可以被多个容器同时挂载
4、一个容器也可以被挂载多个数据卷
docker快速入门_第28张图片

数据卷的作用
1、容器数据持久化
2、外部机器和容器间接通信
3、容器之间数据交换

3.2、配置数据卷

  • 创建启动容器时,使用 –v 参数 设置数据卷 docker run … –v 宿主机目录(文件):容器内目录(文件)


ps:

  1. 目录必须是绝对路径
  2. 如果目录不存在,会自动创建
  3. 可以挂载多个数据卷
    docker快速入门_第29张图片

我们现在演示一下,为了更加清晰,我已经提前删除了全部容器。然后安装了centos7的镜像
docker快速入门_第30张图片

我们通过docker run -id -v /root/docker/data:/root/data --name=mycentos centos:7 /bin/bash创建centos7的容器并且进行挂载,将宿主机的/root/docker/data(没有会创建)挂载到我们容器的/root/data下,然后创建容器。
接着我们docker exec进入容器,然后我们进入root的目录下ll可以看到我们创建的/data目录。同样的我们在宿主机的root目录下可以看到我们创建的/docker/data目录

docker快速入门_第31张图片

接着我们来演示一下数据卷的作用
我们进入容器的/data目录,touch一个txt文件。
docker快速入门_第32张图片

这个时候看下宿主机的data下,发现这个文件同样被同步进去了。
docker快速入门_第33张图片

同样的,我们对文件进行的数据操作,也会被同步
我们执行echo mbw > mbw.txt
docker快速入门_第34张图片

回到宿主机这里再看看
在这里插入图片描述

然后现在我们模拟下假设容器挂掉了或者已经删了,宿主机的数据还有吗?
在这里插入图片描述

然后回到宿主机,我们发现数据还在
在这里插入图片描述

这个时候我们如果再次创建一个docker,然后通过

docker run -id -v ~/docker:/root/data --name=mycentos centos:7 /bin/bash

创建一个容器,并且挂载我们已经存在的数据文件。
我们看看新的容器是否同步已有的数据呢
我们可以很清楚的看到,内容完全同步了进去,即/root/docker下的所有数据挂载到容器的/root/data中。
docker快速入门_第35张图片

当然,我们的容器创建时可以挂载多个数据卷

docker run -id 
-v /root/docker/data1:/root/data1 
-v /root/docker/data2:/root/data2 
--name=centos1 centos:7 /bin/bash

我们可以看到这样就挂载了两个数据卷
且在容器和宿主机都可以看到

docker快速入门_第36张图片docker快速入门_第37张图片

我们还可以实现两个容器同时挂载同一个数据卷,我们以宿主机的/root/docker为数据卷,
然后实现两个容器的数据交互:
我们创建两个容器,同时挂载/root/docker目录
docker快速入门_第38张图片

然后我们在centos3创建文件
docker快速入门_第39张图片
docker快速入门_第40张图片

这个时候进入centos2和宿主机看看文件是否被创建:发现均同步了
docker快速入门_第41张图片

在这里插入图片描述

3.3、数据卷容器

多容器进行数据交换
第一种办法就是我们刚才做的一样多个容器挂载同一个数据卷,但是这样操作就比较麻烦。
第二种就是通过数据卷容器
我们可以创建一个数据卷容器c3,这个c3和其他容器c1,c2没什么区别,但是c3挂载了一个数据卷,那么如果让c1,c2挂载这个数据卷容器,就简介挂在了数据卷。这也同时意味着c1,c2,c3都可以和数据进行交互 ,即使c3挂了,c1,c2仍然可以继续和数据卷进行数据交互。
docker快速入门_第42张图片

那么我们就来创建数据卷。
首先将c1,c2,c3,c4全部给删了
docker快速入门_第43张图片

然后创建启动c3数据卷容器,这个其实和之前的创建容器一样

docker run –it --name=c3 –v /root/docker/data:/volume centos:7 /bin/bash

然后创建c1,c2并挂载c3数据卷容器,我们使用 –-volumes-from 参数 设置数据卷

docker run -id --name=c1 --volumes-from c3 centos:7
docker run -id --name=c2 --volumes-from c3 centos:7

然后我们进入c2,看看有没有/volume这个文件夹:
docker快速入门_第44张图片

这个时候我创建一个文件,然后退出c2进入c1,c3
docker快速入门_第45张图片
docker快速入门_第46张图片
docker快速入门_第47张图片

发现同样同步成功。
假设我现在将c3删了,然后我在宿主机增加一个文件,这个时候回到c2,看看数据有没有同步:
证明就算数据卷容器没有了,我的c1,c2也已经简介挂载了宿主机的数据卷,且可以同步进行数据交互。
docker快速入门_第48张图片

四、docker的应用

4.1、docker部署mysql

在Docker容器中部署MySQL,并通过外部mysql客户端操作MySQL Server。
实现步骤其实很简单,而且基本其他的都很相似,比起我们当时在linux自己安装要简单很多。
实现步骤:
1、搜索mysql镜像
2、拉取mysql镜像
3、创建容器
4、操作容器中的mysql

但是有一个问题,我们之前讲过,外部机器和容器之间网络是不通的,那么我们怎么让外部的mysql客户端连接上我们的mysql呢?
容器内的网络服务和外部机器不能直接通信
外部机器和宿主机可以直接通信
宿主机和容器可以直接通信
当容器中的网络服务需要被外部机器访问时,可以将容器中提供服务的端口映射到宿主机的端口上。外部机器访问宿主机的该端口,从而间接访问容器的服务。
这种操作称为:端口映射。
docker快速入门_第49张图片

那我们现在就开始实操:
访问 MySQL 镜像库地址:https://hub.docker.com/_/mysql?tab=tags 。
可以通过 Sort by 查看其他版本的 MySQL,默认是最新版本 mysql:latest 。
docker快速入门_第50张图片

我们这里下载mysql5.7的docker pull mysql:5.7,下载成功和可以看到。
docker快速入门_第51张图片

然后就是关键了,我们要创建容器同时进行端口映射

docker run -d -p 3306:3306 --privileged=true -v /opt/mysql/conf/my.cnf:/etc/my.cnf -v /opt/mysql/data:/var/lib/mysql -v /opt/mysql/logs:/logs -e MYSQL_ROOT_PASSWORD=your password --name mysql mysql:5.7 --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci

我们来解释一下,首先我们通过宿主机的3306端口映射容器的3306端口。
然后通过数据卷将mysql的data数据文件,conf配置文件分别挂载到宿主机自己创建的三个目录,将来我们就可以直接同步数据,非常的方便。
最后需要在防火墙开放我们宿主机的3306端口!
那么下面我们就进入容器验收成果:
我们通过mysql -uroot -p输入密码登入我们的mysql
docker快速入门_第52张图片

然后在mysql客户端试试能否远程登录,连接前要保证容器是开启的状态,没有记得docker start xxx
docker快速入门_第53张图片

连接成功,docker安装mysql成功.

4.2、docker安装tomcat

这个比较复杂,我们需要用到一些新知识。
首先还是之前的老两步:
search–pull
我这里pull的是和我本地一致的版本:tomcat:8.5.63-jdk8-openjdk
pull好后,我们就需要创建容器,学过javaweb知识的肯定知道tomcat有两个比较重要的文件夹,webapps以及conf这两个文件夹,为了方便,我们自然而然能想到通过挂载的方式解决。
我们通过以下命令:

docker run -d --name tomcat -p 8080:8080 -v /opt/tomcat/conf:/usr/local/tomcat/conf -v /opt/tomcat/webapps:/usr/local/tomcat/webapps -v /opt/tomcat/logs/:/usr/local/tomcat/logs  --restart=always  tomcat:8.5.63-jdk8-openjdk

直接创建后,发现启动不起来,一直是restart状态,将 --restart=always 去掉重新run后发现状态变成了exit,就是启动不起来。
这是因为上面的命令中,我们也挂载了conf文件夹。这个是tomcat的配置文件夹。必须把tomcat中的conf中的文件复制到挂载文件上(即/home/supervision_app/app/conf目录下需要有配置文件
而我们将空的数据卷与我们的容器同步,结果全是空的,自然启动不起来了
所以我们暂时有一个思路,**创建一个不挂载数据卷的tomcat容器,如果能正常启动起来,就将它这里的数据移动到我们原来的数据卷中。**其实这个思路是可行的。
我们docker rm -f tomcat后再次通过

docker run -d --name tomcat -p 8080:8080 --restart=always  tomcat:8.5.63-jdk8-openjdk

然后防火墙开放8080端口。
创建tomcat,现在通过docker ps -a发现状态变成正常的了,那么我们通过
docker exec -it tomcat /bin/bash进入容器,进入成功。
docker快速入门_第54张图片

这个时候exit退出后,由于我们做了端口映射,我们试试远程能不能访问:
一输入发现404
docker快速入门_第55张图片

这里其实已经说明,我们的tomcat已经起了。端口什么的都配好了。
使用命令: docker exec -it 运行的tomcat容器ID /bin/bash 进入到tomcat的目录
进入webapps文件夹,发现里面是空的(tomcat默认的欢迎页面实际上放在的路径应该是:webapps/ROOT/index.jsp或者index.html)
发现下边还有个webapps.dist的文件,进入才发现原本应该在webapps文件中的文件都在webapps.dist文件中
docker快速入门_第56张图片

那么很简单,我们将webapps给删了,然后将webapps.dist改为webapps就行了。

rmdir webapps
mv webapps.dist/ webapps

exit后docker restart tomcat后就可以发现启动成功
docker快速入门_第57张图片

但其实,我们解决的并不完美,因为再另启动一个Tomcat容器时又会回到之前的窘境,既实际上问题的根源是在生成容器的镜像上,只有将镜像修改了,再生成的容器才不会再出现这个问题。

所以我们得通过将我们的容器映射为新的镜像,然后通过这个镜像创建容器,就无后患了。
我们可以使用docker commit命令将运行着的容器映射成新的镜像
格式:docker commit -a='作者-这个随意写' -m='‘修改内容--随意写' 容器名称或者ID 新生成镜像的名称:自己定义的版本号
比方我以我现在这个可以正常运行的tomcat容器映射成镜像,

docker commit -a='孟博文' -m='修改404' tomcat  tomcat:v1

我们映射完后通过docker images可以看到我们的镜像生成成功了。
docker快速入门_第58张图片

此时还没完,我们现在肯定想的是用这个新镜像创建新容器,但是我们之前那个tomcat容器还没有利用完:
因为你想想,我这个时候创建新容器,挂载还是空的,照样不行,所以我们将之前正常的tomcat容器文件复制到我们的挂载的数据卷上。
那怎么移动呢,docker自己提供了cp命令。

docker cp 容器名or id:容器目录or 文件 数据卷目录

我们将我们的conf以及webapps目录拷贝到/opt/tomcat下,在移动之前将以前空的文件删掉就行。

docker cp tomcat:/usr/local/tomcat/conf/ /opt/tomcat/
docker cp tomcat:/usr/local/tomcat/webapps/ /opt/tomcat/

然后发现我们的数据卷此时就有数据了:
在这里插入图片描述

这个时候tomcat容器光荣退休,我们把它删了。

docker rm -f tomcat

然后用我们的新镜像创建新的容器并挂载我们数据卷

docker run -d --name tomcat -p 8080:8080 -v /opt/tomcat/conf:/usr/local/tomcat/conf -v /opt/tomcat/webapps:/usr/local/tomcat/webapps -v /opt/tomcat/logs/:/usr/local/tomcat/logs  --restart=always  tomcat:v1

在这里插入图片描述

如果发现status为up就代表成功!去浏览器输入发现同样能进入主页!

docker快速入门_第59张图片

4.3、docker部署nginx

如果tomcat安装成功,其实nginx就非常简单了。
首先我们pull nginx的镜像,我这里拉取的是1.19.0的
docker快速入门_第60张图片

然后通过docker run创建一个正常的nginx的容器

docker run -d --name=nginx -p 80:80 --restart=always nginx:1.19.0

docker快速入门_第61张图片

创建成功后,我们可以直接访问192,168.200.130:80访问

但是我们现在还没挂载,借用之前安装tomcat的思路,我们同样先在/opt创建nginx文件夹,然后在这下面创建三个文件夹:conf,logs,html分别存放我们的配置文件,日志文件,以及项目。
而nginx的这三份对应的文件在:
1、日志位置:/var/log/nginx/
2、配置文件位置:/etc/nginx/nginx.conf
3、项目位置:/usr/share/nginx/html
我们通过cp命令拷贝到我们的数据卷即可:

docker cp /var/log/nginx/ /opt/nginx/logs
docker cp nginx:/usr/share/nginx/html /opt/nginx/
docker cp nginx:/etc/nginx/nginx.conf /opt/nginx/conf

docker快速入门_第62张图片


这个时候通过docker rm -f nginx
然后创建新容器并挂载数据卷

docker run -d --name=nginx --restart=always -p 80:80 -v /opt/nginx/conf/nginx.conf:/etc/nginx/nginx.conf -v /opt/nginx/html/:/usr/share/nginx/html -v /opt/nginx/logs:/var/logs/nginx nginx:1.19.0

此时通过docker ps -a
在这里插入图片描述

这个时候访问192.168.200.130:80即可访问到我们的nginx,docker安装nginx成功!
docker快速入门_第63张图片

4.4、docker安装redis5

拉取镜像redis:5:docker pull redis:5
docker快速入门_第64张图片

然后创建/opt/redis/conf和/opt/redis/data两个目录
docker快速入门_第65张图片

然后去https://download.redis.io/redis-stable/redis.conf下载redis.conf文件传到/opt/redis/conf
在这里插入图片描述

vim这个文件,需要注意修改的地方:
bind 127.0.0.1 #注释掉这部分,这是限制redis只能本地访问
protected-mode no #默认yes,开启保护模式,限制为本地访问
daemonize no#默认no,改为yes意为以守护进程方式启动,可后台运行,除非kill进程,改为yes会使配置文件方式启动redis失败
databases 16 #数据库个数(可选),我修改了这个只是查看是否生效。。
dir ./ #输入本地redis数据库存放文件夹(可选)
appendonly yes #redis持久化(可选)
修改完后,就可以创建容器并挂载了

docker run --restart=always -d --privileged=true -p 6379:6379 -v /opt/redis/conf/redis.conf:/redis.conf -v /opt/redis/data:/data --name redis redis:5 redis-server --appendonly yes

这里介绍一些参数的意义:
--privileged=true 提升容器内权限
redis-server redis-server就是redis的启动命令
--appendonly yes 开启数据持久化
在这里插入图片描述

然后在redis客户端发现一样能登陆成功,redis安装成功!
docker快速入门_第66张图片

五、dockerfile

提前剧透:dockerfile就是用来制作镜像的
思考一下:
Docker 镜像本质是什么?
Docker 中一个centos镜像为什么只有200MB,而一个centos操作系统的iso文件要几个个G?
Docker 中一个tomcat镜像为什么有500MB,而一个tomcat安装包只有70多MB?
docker快速入门_第67张图片

在讲原理之前,大家不妨先了解一下操作系统和linux的文件系统。
操作系统组成部分:
1.进程调度子系统
2.进程通信子系统
3.内存管理子系统
4.设备管理子系统
5.文件管理子系统
6.网络通信子系统
7.作业控制子系统
Linux文件系统由bootfs和rootfs两部分组成
 bootfs:包含bootloader(引导加载程序)和 kernel(内核)
 rootfs: root文件系统,包含的就是典型 Linux 系统中的/dev,/proc,/bin,/etc等标准目录和文件
不同的linux发行版,bootfs基本一样,而rootfs不同,如ubuntu,centos等
docker快速入门_第68张图片

5.1、docker镜像原理

Docker镜像是由特殊的文件系统叠加而成
最底端是 bootfs并使用宿主机的bootfs,比方linux操作的时候会加载一次内核,然后docker加载的时候就不会再次重复加载,而是直接使用之前linux加载的内核。所以docker启动非常快。实现一种复用效果
第二层是 root文件系统rootfs,称为base image
然后再往上可以叠加其他的镜像文件,比方我们可以在基础镜像上放上jdk镜像,然后在jdk镜像上接着放tomcat的镜像。这三部分组合起来,我们就把它称作tomcat镜像。这种组合性的镜像叫做只读镜像!那么这样的好处,仙子啊假设我在tomcat这样一个组合镜像基础上,再安装一个nginx的镜像,只读镜像已经有的,如果nginx也刚好需要,它就不需要再去下载了,即我下载的每一层镜像都可以被复用
统一文件系统(Union File System)技术能够将不同的层整合成一个文件系统,为这些层提供了一个统一的视角,这样就隐藏了多层的存在,在用户的角度看来,只存在一个文件系统。 这也就解释了为什么tomcat这样一个镜像就有500多Mb,centos镜像反而只要200Mb.
一个镜像可以放在另一个镜像的上面。位于下面的镜像称为父镜像,最底部的镜像成为基础镜像
只读镜像不能修改,如果我想修改的话,就有了下面的方法,当从一个镜像启动容器时,Docker会在最顶层加载一个读写文件系统作为容器。

docker快速入门_第69张图片

而我们可以通过容器创建新的镜像,由此对镜像去做出一些改变,而可读镜像仍然是固定的,可复用的!
docker快速入门_第70张图片

那么我们现在就来回答一下刚才的思考题:
1.Docker 镜像本质是什么?
是一个分层文件系统
2.Docker 中一个centos镜像为什么只有200MB,而一个centos操作系统的iso文件要几个个G?
Centos的iso镜像文件包含bootfsrootfs,而docker的centos镜像复用操作系统的bootfs,只有rootfs和其他镜像层
3.Docker 中一个tomcat镜像为什么有500MB,而一个tomcat安装包只有70多MB?
由于docker中镜像是分层的,tomcat虽然只有70多MB,但他需要依赖于父镜像和基础镜像,所有整个对外暴露的tomcat镜像大小500多MB
我们可以通过docker inspect tomcat:v1看一下我们的tomcat到底被分为多少层:你可以看到被分成了特别多层:
docker快速入门_第71张图片

5.2、容器转化为镜像

命令:docker commit -a’xxxx作者信息’ -m’修改信息’ 容器id/容器名称 自定义镜像名称:自定义版本号
比方我们将修改好的tomcat转化为镜像:

docker commit -a='孟博文' -m='修改404' tomcat  tomcat:v1

docker快速入门_第72张图片

这样就生成了我们想要的镜像,这在今后是非常方便的,我们比方在tomcat部署了一个web项目,然后我们就可以将它转化为我们的镜像,然后将这个镜像通过某种方式转给其他人,就ok了。
那我们该怎么将镜像分享出去呢,docker有一个压缩命令可以将镜像压缩为文件。

docker save -o 压缩文件名称(可以加路径,不加默认当前目录) 镜像名称:版本号

我们可以将这个压缩文件发给其他人,然后其他人可以把这个压缩文件转化为镜像,然后使用就是我们自己写改好的东西了。
那怎么把压缩文件还原成镜像:

docker load -i 压缩文件名称

那我们现在从头到尾演示一遍:
为了一个需要注意的知识点,我现在新建一个test文件夹然后写一个页面放进我们的webapps叫做test.html!
docker快速入门_第73张图片

然后由于挂载,它肯定是放在了我们的容器中的,我们可以看一下演示一下:
docker快速入门_第74张图片

现在我将这个生成镜像叫做tomcat:v2

docker commit -a '孟博文' -m '挂载页面' tomcat tomcat:v2

docker快速入门_第75张图片

然后我们先进去创建一个v2的容器看看我们挂载的test.html还在不在,假设我创建的tomcat容器我不挂载任何一个目录,因为你发给别人,别人肯定不能挂载到你这里的文件。

docker run -d --name=tomcat2 -p 8888:8080 --restart=always tomcat:v2

运行后进去这个容器,发现我们的test文件夹不见了!访问肯定也是404

docker快速入门_第76张图片

docker commit是只会保留容器的数据,不会保留任何挂载在宿主机的数据。
如果我们在我们刚才生成的镜像里创建文件,那么毫无疑问会被保留下来,这也是为什么我们将空的webapps删了,将webapps.dist改为webapps能够在新镜像保留下来的原因。那怎么保留我们的数据,我们在之后的dockerfile会讲解。
然后我们现在尝试着将我们这个镜像生成压缩文件,然后删除我们这个v2镜像,再把这个压缩文件还原,看是否能重新生成该镜像。

docker save -o /opt/tomcat/tomcat.tar tomcat:v2

docker快速入门_第77张图片

docker load -i /opt/tomcat/tomcat.tar 

docker快速入门_第78张图片

镜像重新生成成功,演示完毕!

5.3、dockerfile概述以及相关关键字

dockerfile概念:
Dockerfile 是一个文本文件
1、包含了一条条的指令
2、每一条指令构建一层,基于基础镜像,最终构建出一个新的镜像
3、对于开发人员:可以为开发团队提供一个完全一致的开发环境
4、对于测试人员:可以直接拿开发时所构建的镜像或者通过Dockerfile文件构建一个新的镜像开始工作了
5、对于运维人员:在部署时,可以实现应用的无缝移植

docker快速入门_第79张图片

我们可以在docker官网搜到一些dockerFile.
Dochub网址:https://hub.docker.com

关键字 作用 备注
FROM 指定父镜像 指定dockerfile基于那个image构建
MAINTAINER 作者信息 用来标明这个dockerfile谁写的
LABEL 标签 用来标明dockerfile的标签 可以使用Label代替Maintainer 最终都是在docker image基本信息中可以查看
RUN 执行命令 执行一段命令 默认是/bin/sh 格式: RUN command 或者 RUN [“command” , “param1”,“param2”]
CMD 容器启动命令 提供启动容器时候的默认命令 和ENTRYPOINT配合使用.格式 CMD command param1 param2 或者 CMD [“command” , “param1”,“param2”]
ENTRYPOINT 入口 一般在制作一些执行就关闭的容器中会使用
COPY 复制文件 build的时候复制文件到image中
ADD 添加文件 build的时候添加文件到image中 不仅仅局限于当前build上下文 可以来源于远程服务
ENV 环境变量 指定build时候的环境变量 可以在启动的容器的时候 通过-e覆盖 格式ENV name=value
ARG 构建参数 只在构建的时候使用的参数 如果有ENV 那么ENV的相同名字的值始终覆盖arg的参数
VOLUME 定义外部可以挂载的数据卷 指定build的image那些目录可以启动的时候挂载到文件系统中 启动容器的时候使用 -v 绑定 格式 VOLUME [“目录”]
EXPOSE 暴露端口 定义容器运行的时候监听的端口 启动容器的使用-p来绑定暴露端口 格式: EXPOSE 8080 或者 EXPOSE 8080/udp
WORKDIR 工作目录 指定容器内部的工作目录 如果没有创建则自动创建 如果指定/ 使用的是绝对地址 如果不是/开头那么是在上一条workdir的路径的相对路径
USER 指定执行用户 指定build或者启动的时候 用户 在RUN CMD ENTRYPONT执行的时候的用户
HEALTHCHECK 健康检查 指定监测当前容器的健康监测的命令 基本上没用 因为很多时候 应用本身有健康监测机制
ONBUILD 触发器 当存在ONBUILD关键字的镜像作为基础镜像的时候 当执行FROM完成之后 会执行 ONBUILD的命令 但是不影响当前镜像 用处也不怎么大
STOPSIGNAL 发送信号量到宿主机 该STOPSIGNAL指令设置将发送到容器的系统调用信号以退出。
SHELL 指定执行脚本的shell 指定RUN CMD ENTRYPOINT 执行命令的时候 使用的shell

5.4、dockerfile案例—自定义centos

我们自定义一个centos镜像要实现以下功能:
1、默认登陆路径为/usr
2、可以使用vim
实现步骤:
定义父镜像:FROM centos:7
定义作者信息:MAINTAINER mbw
执行安装vim命令: RUN yum install -y vim
定义默认的工作目录:WORKDIR /usr
定义容器启动执行的命令:CMD /bin/bash
通过dockerfile构建镜像:docker bulid –f dockerfile文件路径 –t 镜像名称:版本 URL
我们现在在/opt创建dockerfile/centos目录,在其下vim一个dockerfile文件,写上以下内容:
docker快速入门_第80张图片

然后通过docker build -f /opt/docker-files/centos/dockerfile -t mycentos:v1 .
-f后接的是dockerfile的路径
-t是自定义的镜像名:版本号
.表示当前路径,一般都是这个
生成后,我们通过docker images 查看
docker快速入门_第81张图片

然后通过docker run -it --name=mycentos mycentos:v1创建并进入我们的容器
发现我们的默认工作目录已经变成了/usr
docker快速入门_第82张图片

然后试下vim,发现也可以成功。那么自定义centos就算完成了。
docker快速入门_第83张图片

5.5、dockerfile实例二:测试一个springboot的项目

我们创建一个非常简单的springboot的项目来测试是否能运行
在这里插入图片描述
docker快速入门_第84张图片

在保证项目没问题的前提下,我们通过mvn package将我们的项目打成jar包
docker快速入门_第85张图片
docker快速入门_第86张图片

我们可以通过java -jar xxx.jar正常运行
docker快速入门_第87张图片

然后来到docker这边
首先pull一个jdk8的镜像

docker pull abrtech/alpine-oraclejdk8

docker快速入门_第88张图片

一切都成功的情况下,我们可以创建dockerfile。
/opt/docker-files创建project/docker_springboot目录,将生成的jar包放入并创建dockerfile
docker快速入门_第89张图片

Dockerfile内容如下:
FROM 基础镜像:FROM abrtech/alpine-oraclejdk8
ADD 类似于linux命令中的copy:
ADD docker_springboot-0.0.1-SNAPSHOT.jar app.jar
暴露项目的服务端口:EXPOSE 8080
启动命令:CMD java -jar app.jar
编写完后cd 到/opt/docker-files/project/docker_springboot执行
docker build -f ./Dockerfile -t app .创建镜像
执行完后可以通过docker images看到我们生成的镜像:
docker快速入门_第90张图片

然后运行容器启动jar包

docker run -it -p 9090:8080 --name=springboot_docker app

docker快速入门_第91张图片

发现项目成功运行起来,输入192.168.200.130:9090/hello,访问成功!
docker快速入门_第92张图片

六、docker compose

微服务架构的应用系统中一般包含若干个微服务,每个微服务一般都会部署多个实例,如果每个微服务都要手动启停,维护的工作量会很大。
例如要从Dockerfile build image 或者去dockerhub拉取image
要创建多个container
要管理这些container(启动停止删除)
这样的工作量是非常恐怖且浪费时间的!
服务编排:按照一定的业务规则批量管理容器

6.1、服务编排

Docker Compose概念
Docker Compose是一个编排多容器分布式部署的工具,提供命令集管理容器化应用的完整开发周期,包括服务构建,启动和停止。使用步骤:
1、利用 Dockerfile 定义运行环境镜像
2、使用 docker-compose.yml 定义组成应用的各服务
3、运行 docker-compose up 启动应用
docker快速入门_第93张图片

安装docker Compose

curl -L "https://get.daocloud.io/docker/compose/releases/download/1.27.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

在这里插入图片描述

然后设置文件可执行权限

chmod +x /usr/local/bin/docker-compose

验证是否安装成功可通过docker-compose -v,显示版本号就说明docker-compoe安装成功!
在这里插入图片描述

要是想删除其实docker-compose也很简单,因为我们是通过二进制包方式安装的,直接删除这个文件就好

rm /usr/local/bin/docker-compose

6.2、docker-compose编排nginx+springboot的项目

我们首先通过docker images查看docker快速入门_第94张图片
我们的镜像

之前我们直接通过run我们的app容器启动我们的springboot项目,但是假设现在我们需要nginx反向代理我们的项目,你可能会想,我再启动我的nginx就好了,是可以这样,但万一你的项目又要很多种数据库,再加上消息队列,还需要布置集群,你还愿意一个一个启动吗?
所以我们通过docker compose将这些全部放一起:
我们在/opt下新建docker-compose/docker-compose.yml,这个yml名字不能改变。
然后编辑docker-compose.yml,语法格式注意是yml

version: '3'
services:
  #第一个要编排的服务
 nginx:
#基础镜像
     image: nginx:1.19.0
#端口映射
     ports:
       - 9090:80
 #链接到其它服务的中的容器,这里可以是别名也可以是服务名称
     links:
       - app
   #数据卷挂载,挂载我们宿主机自己nginx的配置文件
     volumes:
       - ./nginx/conf.d:/etc/nginx/conf.d
#第二个服务,其次也是被nginx链接的服务app
   app:
     image: app
#暴露的端口号
     expose:
       - "8080"

然后就是nginx的配置文件
我们在docker-compose.yml处于的当前目录新建当时我们挂载的目录
mkdir -p /nginx/conf.d,然后在这下面创建mbw.conf这个配置文件
docker快速入门_第95张图片

这样我们写的配置文件自然会被挂载进去,配置文件内容如下:

server {
      listen 80;
      access_log off;


      location / {
          proxy_pass http://app:8080;
      }
}

意思就是当访问192.168.200.130,就会自动代理到app这个镜像的8080端口。
这个app其实是我们刚才links里链接的app镜像。
然后:wq保存退出,cd …/…/返回装有yml的目录
通过docker-compose up启动我们的docker-compose即可
docker快速入门_第96张图片

启动成功!我们访问192.168.200.130:9090/hello(9090是映射的nginx的80端口)
docker快速入门_第97张图片

七、docker私有仓库

我们maven也有自己的仓库,为了加载速度能够更快。
docker也可以搭建自己的私有仓库。
Docker官方的Docker hub(https://hub.docker.com)是一个用于管理公共镜像的仓库,我们可以从上面拉取镜像 到本地,也可以把我们自己的镜像推送上去。但是,有时候我们的服务器无法访问互联网,或者你不希望将自己的镜 像放到公网当中,那么我们就需要搭建自己的私有仓库来存储和管理自己的镜像。
一般来说,我们搭建的私有仓库的服务器肯定和当前使用的服务器是分开的,但是为了方便,我们就直接在当前服务器搭建。

7.1、私有仓库搭建

1、拉取私有仓库镜像

docker pull registry

docker快速入门_第98张图片

2、启动私有仓库容器

docker run -id --name=registry -p 5000:5000 registry

在这里插入图片描述

3、打开浏览器 输入地址http://私有仓库服务器ip:5000/v2/_catalog,看到{“repositories”:[]} 表示私有仓库 搭建成功
docker快速入门_第99张图片

4、修改daemon.json

vim /etc/docker/daemon.json 

在上述文件中添加一个key,保存退出。此步用于让 docker 信任私有仓库地址;注意将私有仓库服务器ip修改为自己私有仓库服务器真实ip

{"insecure-registries": ["私有仓库服务器ip:5000"]} 

docker快速入门_第100张图片

5、重启docker 服务

systemctl restart docker
docker start registry

在这里插入图片描述

至此,我们的docker的私有仓库就搭建完成了!

7.2、上传镜像至私有仓库

我们首先通过docker images查看我们的现有镜像:
docker快速入门_第101张图片

比方我们现在上传mysql到我们的私人仓库
我们可以通过docker tag 本地镜像:镜像版本号 仓库路径/归入的镜像名:镜像版本号标记本地镜像,将其归入某一仓库。
那么我们标记mysql5.7就是

docker tag mysql5.7 192.168.200.130:5000/mysql:5.7

成功后我们发现docker images多了一个刚才标记的镜像:
docker快速入门_第102张图片

下面我们就可以通过docker push 镜像名:镜像版本号上传到仓库

docker push 192.168.200.130:5000/mysql:5.7

上传成功后,我们访问192.168.200.130:5000/v2/_catalog,发现镜像中有一个mysql.
docker快速入门_第103张图片

然后拉取还是一样的docker pull 镜像名:tags
docker快速入门_第104张图片

我们通过docker images发现镜像又回来了。
docker快速入门_第105张图片

你可能感兴趣的:(docker,运维,nginx)