docker快速入门

docker入门

一、初识docker

1.1.引言

我们写的代码会接触到好几个环境:开发环境、测试环境以及生产环境:
在这里插入图片描述

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

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

1.2、docker概念

在这里插入图片描述

  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命令给我们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:中科大镜像加速器
阿里云
网易云
腾讯云
我们这里使用阿里云的镜像加速器,因为它相较于其他的是最快的。
我们 登录阿里云然后找到容器镜像服务
在这里插入图片描述

找到镜像工具,我们看到有一个加速器地址,这个地址是每个人独有的。
在这里插入图片描述

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

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

二、docker命令

2.1、docker进程相关命令

启动docker服务

 systemctl start docker

我们可以通过systemctl status docker查看状态看看docker是否已经启动
在这里插入图片描述

停止docker服务

 systemctl stop docker

在这里插入图片描述

重启docker服务

systemctl restart docker

在这里插入图片描述

查看docker服务状态

systemctl status docker

开机启动docker服务

systemctl enable docker

在这里插入图片描述

2.2、docker 镜像相关命令

查看docker全部命令

docker

在这里插入图片描述

你会发现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,但又不知道docker仓库到底有没有我要的具体版本的镜像,怎么办呢?
我们可以去hub.docker.com去查找

在这里插入图片描述
在这里插入图片描述

点进去,我们可以看到它所支持的tags.然后找到适合自己的版本拉取下来就行了
在这里插入图片描述

ps:一个镜像可以有多个版本名,比方这里的6.2.5,6.2,6你可以理解为就是redis 6.2
在这里插入图片描述

比方我现在下载一个redis5.0
在这里插入图片描述
在这里插入图片描述

删除镜像
docker rmi (IMAGE ID):括号参数为镜像ID
在这里插入图片描述

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

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

我们可以用exit退出终端,我们发现我们又回到我们的linux上了。
在这里插入图片描述

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

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

在这里插入图片描述

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

 docker exec -it redis2 /bin/bash

在这里插入图片描述

进入容器

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

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

停止及启动容器

docker stop 容器名or容器id

在这里插入图片描述

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

docker start 容器名or容器id

在这里插入图片描述

删除容器

docker rm 容器名or容器id

在这里插入图片描述

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

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

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

docker rm $(docker ps -aq)

在这里插入图片描述

查看容器信息

docker inspect 容器名or容器id

在这里插入图片描述

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

三、docker数据卷

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

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

3.1、数据卷概念

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

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

3.2、配置数据卷

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


ps:

  1. 目录必须是绝对路径
  2. 如果目录不存在,会自动创建
  3. 可以挂载多个数据卷
    在这里插入图片描述

我们现在演示一下,为了更加清晰,我已经提前删除了全部容器。然后安装了centos7的镜像
在这里插入图片描述

我们通过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目录

在这里插入图片描述

接着我们来演示一下数据卷的作用
我们进入容器的/data目录,touch一个txt文件。
在这里插入图片描述

这个时候看下宿主机的data下,发现这个文件同样被同步进去了。
在这里插入图片描述

同样的,我们对文件进行的数据操作,也会被同步
我们执行echo mbw > mbw.txt
在这里插入图片描述

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

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

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

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

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

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

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

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

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

在这里插入图片描述在这里插入图片描述

我们还可以实现两个容器同时挂载同一个数据卷,我们以宿主机的/root/docker为数据卷,
然后实现两个容器的数据交互:
我们创建两个容器,同时挂载/root/docker目录
在这里插入图片描述

然后我们在centos3创建文件
在这里插入图片描述
在这里插入图片描述

这个时候进入centos2和宿主机看看文件是否被创建:发现均同步了
在这里插入图片描述

在这里插入图片描述

3.3、数据卷容器

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

那么我们就来创建数据卷。
首先将c1,c2,c3,c4全部给删了
在这里插入图片描述

然后创建启动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这个文件夹:
在这里插入图片描述

这个时候我创建一个文件,然后退出c2进入c1,c3
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

四、docker的应用

4.1、docker部署mysql

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

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

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

我们这里下载mysql5.7的docker pull mysql:5.7,下载成功和可以看到。
在这里插入图片描述

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

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
在这里插入图片描述

然后在mysql客户端试试能否远程登录,连接前要保证容器是开启的状态,没有记得docker start xxx
在这里插入图片描述

连接成功,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进入容器,进入成功。
在这里插入图片描述

这个时候exit退出后,由于我们做了端口映射,我们试试远程能不能访问:
一输入发现404
在这里插入图片描述

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

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

rmdir webapps
mv webapps.dist/ webapps

exit后docker restart tomcat后就可以发现启动成功
在这里插入图片描述

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

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

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

我们映射完后通过docker images可以看到我们的镜像生成成功了。
在这里插入图片描述

此时还没完,我们现在肯定想的是用这个新镜像创建新容器,但是我们之前那个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就代表成功!去浏览器输入发现同样能进入主页!

在这里插入图片描述

4.3、docker部署nginx

如果tomcat安装成功,其实nginx就非常简单了。
首先我们pull nginx的镜像,我这里拉取的是1.19.0的
在这里插入图片描述

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

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

在这里插入图片描述

创建成功后,我们可以直接访问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 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成功!
在这里插入图片描述

4.4、docker安装redis5

拉取镜像redis:5:docker pull redis:5
在这里插入图片描述

然后创建/opt/redis/conf和/opt/redis/data两个目录
在这里插入图片描述

然后去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安装成功!
在这里插入图片描述

五、dockerfile

提前剧透:dockerfile就是用来制作镜像的
思考一下:
Docker 镜像本质是什么?
Docker 中一个centos镜像为什么只有200MB,而一个centos操作系统的iso文件要几个个G?
Docker 中一个tomcat镜像为什么有500MB,而一个tomcat安装包只有70多MB?
在这里插入图片描述

在讲原理之前,大家不妨先了解一下操作系统和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等
在这里插入图片描述

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会在最顶层加载一个读写文件系统作为容器。

在这里插入图片描述

而我们可以通过容器创建新的镜像,由此对镜像去做出一些改变,而可读镜像仍然是固定的,可复用的!
在这里插入图片描述

那么我们现在就来回答一下刚才的思考题:
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到底被分为多少层:你可以看到被分成了特别多层:
在这里插入图片描述

5.2、容器转化为镜像

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

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

在这里插入图片描述

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

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

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

docker load -i 压缩文件名称

那我们现在从头到尾演示一遍:
为了一个需要注意的知识点,我现在新建一个test文件夹然后写一个页面放进我们的webapps叫做test.html!
在这里插入图片描述

然后由于挂载,它肯定是放在了我们的容器中的,我们可以看一下演示一下:
在这里插入图片描述

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

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

在这里插入图片描述

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

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

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

在这里插入图片描述

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

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

在这里插入图片描述

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

在这里插入图片描述

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

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

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

在这里插入图片描述

我们可以在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 <mbw@mbw.com>
执行安装vim命令: RUN yum install -y vim
定义默认的工作目录:WORKDIR /usr
定义容器启动执行的命令:CMD /bin/bash
通过dockerfile构建镜像:docker bulid –f dockerfile文件路径 –t 镜像名称:版本 URL
我们现在在/opt创建dockerfile/centos目录,在其下vim一个dockerfile文件,写上以下内容:
在这里插入图片描述

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

然后通过docker run -it --name=mycentos mycentos:v1创建并进入我们的容器
发现我们的默认工作目录已经变成了/usr
在这里插入图片描述

然后试下vim,发现也可以成功。那么自定义centos就算完成了。
在这里插入图片描述

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

我们创建一个非常简单的springboot的项目来测试是否能运行
在这里插入图片描述
在这里插入图片描述

在保证项目没问题的前提下,我们通过mvn package将我们的项目打成jar包
在这里插入图片描述
在这里插入图片描述

我们可以通过java -jar xxx.jar正常运行
在这里插入图片描述

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

docker pull abrtech/alpine-oraclejdk8

在这里插入图片描述

一切都成功的情况下,我们可以创建dockerfile。
/opt/docker-files创建project/docker_springboot目录,将生成的jar包放入并创建dockerfile
在这里插入图片描述

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看到我们生成的镜像:
在这里插入图片描述

然后运行容器启动jar包

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

在这里插入图片描述

发现项目成功运行起来,输入192.168.200.130:9090/hello,访问成功!
在这里插入图片描述

六、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 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查看在这里插入图片描述
我们的镜像

之前我们直接通过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这个配置文件
在这里插入图片描述

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

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即可
在这里插入图片描述

启动成功!我们访问192.168.200.130:9090/hello(9090是映射的nginx的80端口)
在这里插入图片描述

七、docker私有仓库

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

7.1、私有仓库搭建

1、拉取私有仓库镜像

docker pull registry

在这里插入图片描述

2、启动私有仓库容器

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

在这里插入图片描述

3、打开浏览器 输入地址http://私有仓库服务器ip:5000/v2/_catalog,看到{“repositories”:[]} 表示私有仓库 搭建成功
在这里插入图片描述

4、修改daemon.json

vim /etc/docker/daemon.json 

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

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

在这里插入图片描述

5、重启docker 服务

systemctl restart docker
docker start registry

在这里插入图片描述

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

7.2、上传镜像至私有仓库

我们首先通过docker images查看我们的现有镜像:
在这里插入图片描述

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

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

成功后我们发现docker images多了一个刚才标记的镜像:
在这里插入图片描述

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

docker push 192.168.200.130:5000/mysql:5.7

上传成功后,我们访问192.168.200.130:5000/v2/_catalog,发现镜像中有一个mysql.
在这里插入图片描述

然后拉取还是一样的docker pull 镜像名:tags
在这里插入图片描述

我们通过docker images发现镜像又回来了。
在这里插入图片描述

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雨~旋律

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值