Docker是一个开源的容器引擎,它有助于更快的交付应用。Docker可将应用程序和基础设施层隔离,并且能将基础设施当做程序一样进行管理。使用Docker可更快地打包、测试以及部署应用程序,并可以缩短从编码到部署运行代码的周期

MacOS下载docker地址:https://docs.docker.com/desktop/mac/install/

一、Docker三要素

  1. 镜像(image):镜像就相当于一个只读的模板。镜像可以用来创建docker容器,一个镜像可以创建很多容器。
    镜像与容器的关系类似与Java中的类与对象的关系。
//User类就相当于镜像,u1、u2、u3三个不同的实例就相当于容器,不过这三个都是基于User创建出来的
User u1 = new User();
User u2 = new User();
User u3 = new User();
  1. 容器(Container):容器使用镜像创建的运行实例。他可以被启动、开始、停止、删除。每个容器都是相互隔离的,保证安全的平台。容器可以看作是简易版的Linux运行环境(包括用户空间、进程空间、网络空间等)和运行在其中的应用程序。
  2. 仓库(Repository):仓库就是集中存放镜像文件的地方,我们可以把制作好的镜像发布到仓库中,需要的时候拉下来即可。仓库分为公开仓库(Public)和私有仓库(Private)两种形式。最大的公开仓库是Docker Hub。存放了很多镜像供用户下载。国内的公开仓库包括阿里云、网易云等等。

docker本身是一个容器运行载体或称之为管理引擎。我们把应用程序和配置依赖打包好形成一个可交付的运行环境,这个打包好的运行环境就似乎image镜像文件。只有通过这个镜像文件才能生成Docker容器。image文件可以看作是容器的模板。Docker根据image文件生成容器的实例同一个image文件。同一个image文件,可以生成多个同时运行的容器实例。
一个容器运行一种服务,当我们需要的时候,就可以通过docker客户端创建一个对应的运行实例,也就是容器。

二、镜像加速器配置

默认情况下docker拉取镜像是从DockerHub上拉取镜像,国外的网站速度很慢。所以需要配置一个国内的仓库,后续拉取的时候直接从国内仓库拉取。

对于使用 macOS 的用户,在任务栏点击 Docker Desktop 应用图标 -> Perferences,在左侧导航菜单选择 Docker Engine,在右侧像下边一样编辑 json 文件。修改完成之后,点击 Apply & Restart 按钮,Docker 就会重启并应用配置的镜像地址了。(当然也可以直接去**~/.docker/daemon.json**文件中配置)

{
  "registry-mirrors": [
    "https://hub-mirror.c.163.com",
    "https://mirror.baidubce.com"
  ]
}

ZLMediaKit docker下载 docker image下载_docker


注意,一定要保证该文件符合 json 规范,否则 Docker 将不能启动。配置完成后需要重启docker。

检查加速器是否生效:
执行docker info命令,如果从结果中看到了如下内容,说明配置成功。

Registry Mirrors:
 https://hub-mirror.c.163.com/

三、docker命令

1.帮助命令

  1. docker version
  2. docker info (docker信息的描述)
  3. docker help (重要,docker命令使用的帮助文档)

2.镜像命令

docker images 列出本机上所有的镜像(加上-q表示只获取镜像ID)

  • REPOSITORY:表示镜像的仓库源
  • TAG:镜像的标签
  • IMAGE ID:镜像ID
  • CREATED:镜像创建时间
  • SIZE:镜像大小

同一个仓库源可以有不同的标签,代表这个仓库源的不同版本,我们使用REPOSITORY:TAG来定义不同的镜像。如不指定标签,则默认为latest。

ZLMediaKit docker下载 docker image下载_redis_02


docker search 镜像名字:用于从镜像仓库查询某个镜像。

docker pull 镜像名字:TAG :从镜像仓库拉取镜像,不写TAG默认为latest。

docekr rmi 镜像名字:Tag :删除某个镜像。(加上-f表示强制删除)

删除多个镜像:docker rmi 镜像名字1:Tag 镜像名字2:Tag

删除全部:docker rmi -f $(docker images -q)

3.容器命令

docker run [options] image [command][arg……] 根据指定镜像创建容器实例并运行
options说明:

  1. -d:后台运行容器,并返回容器ID
  2. -P:随机端口映射
  3. -p:指定端口映射(可以这样指定 hostPort:containerPort,注意这里的hostPort指的是docker对外暴露的服务端口,containerPort才是docker内部应用真正监听的端口)
  4. -i:以交互模式运行容器,通常与-t结合使用
  5. -t:为容器分配一个伪终端,通常与-i结合使用。
  6. –name “容器新名字”:为容器指定一个新名字。
  7. -e -e username=“XXX”: 设置环境变量。

示例1:拉取docker拉取centos并后台运行。

ZLMediaKit docker下载 docker image下载_数据库_03


通过上面的方式在docker容器内运行centos,我们可以docker客户端查看,但是会发现容器并不是运行状态。

ZLMediaKit docker下载 docker image下载_docker_04


这个是因为:Docker容器后台运行,就必须有一个前台进程。如果运行的命令不会让程序一直挂起,那么就会自动退出(自杀)。

示例2:以️交互式运行的方运行centos

ZLMediaKit docker下载 docker image下载_数据库_05

这种方式会为容器分配一个伪终端(如上我们进入了容器中运行的centos的终端[root@9feb4df70129]),相当于通过宿主机进入到容器的终端,由于前台进程一直存在所以容器一直运行着如图。

ZLMediaKit docker下载 docker image下载_ZLMediaKit docker下载_06

可以通过exit退出伪终端回到宿主机,这种方式会导致容器关闭。也可以通过 control + P + Q可以退出(离开)容器。(这种方式不会关闭容器)

示例3:通过后台运行的方式运行一个SpringBoot应用
由于我已经制作好了SpringBoot应用的镜像,所以直接运行即可,执行命令

dokcer run -d -p hostPort:containerPort --name "容器新名字" 镜像名字或镜像ID

这里我执行的是dokcer run -d -p 8888:8080 80b620c5509d

查看docker客户端,可以看到后台运行SpringBoot应用容器并没有关闭。

ZLMediaKit docker下载 docker image下载_ZLMediaKit docker下载_07


这是因为SpringBoot应用一直在默默运行,所以容器不会自杀。

特别的: 这里需要通过 http://localhost:8888/test 去访问SpringBoot应用。SpringBoot应用的端口号是8080,但是我们却通过8888去访问,这是因为我们访问的是docker提供的服务,docker对外暴露的端口是8888,当我们访问8888的时候docker会映射到自身端口号为8080的应用。

docker ps:列出当前所有正在运行的容器

  • 加上-l可以返回上次运行过的容器信息。
  • -n 数字 表示历史运行过的几条容器信息。

docker start 容器ID或者容器名:启动容器

docker restart 容器ID或者容器名:重启容器

docker stop 容器ID或者容器名:停止容器

docker kill 容器ID或者容器名:强制停止容器

docker logs -t --tail 10 容器ID或者容器名:查看容器的日志信息(-t的作用是显示日志打印时间,–tail 是制定显示末尾多少行)

docker top 容器ID或者容器名:查看容器内运行的进程

docker rm 容器ID或者容器名:删除容器

dokcer exec -it 容器ID 想要执行的命令:这个相当于让容器自己执行一下指定的命令并将结果返回给你。

ZLMediaKit docker下载 docker image下载_数据库_08


如下是之前运行的一个SpringBoot应用,现在想进入容器终端交互运行

ZLMediaKit docker下载 docker image下载_ZLMediaKit docker下载_09

docker attach 容器ID:这个会进入容器终端。

docker cp 容器ID:容器内路径 宿主机路径:从容器内拷贝文件到目标主机。

docker inspect 容器ID:查看容器的详细信息

四、镜像的分层结构

我们pull一个镜像的时候通常会看到还有其他附带的东西被拉取下来,比如如下只pull了一个SpringBoot应用,但是显示667M。这是源于docker镜像的分层结构,一个SpringBoot应用在容器上运行需要操作系统内核,JDK8,SpringBoot的应用程序等。这些就是这个镜像的每一层,采取分层结构最大的好处就是共享资源,每个镜像的每一层都可以被共享。也就是说以后获取的其他镜像如果也需要JDK8,那么不需要重复拉取,因为宿主机上已经存在了,且可以共享。

ZLMediaKit docker下载 docker image下载_数据结构_10

五、Dockerfile

Dockerfile是用来构建docker镜像的构建文件,是由一系列命令和参数构成的脚本。Docker通过读取Dockerfile中的指令自动生成镜像。

1.Dockerfile构建过程解析

  1. 每条指令都必须为大写字母且后面要跟随至少一个参数。
  2. 指令按照从上到下,顺序执行
  3. #表示注释
  4. 每条指令都会创建一个新的镜像层,并对镜像进行提交

2.Dockerfile主要指令说明

  1. FROM:当前所创建镜像的基础镜像
  2. MAINTAINER:指定维护者信息(作者信息)
  3. RUN:容器构建时需要运行的命令
  4. ENV:声明环境变量(后续指令中还可以引用这个变量)
  5. ADD:将宿主机的路径下的内容添加(复制)到容器中的路径下,可以为URL;如果为tar文件,会自动解压到路径下
  6. ENTRYPOINT:指定一个容器启动时要执行的命令(用法:ENTRYPOINT [“executable”, “param1”, “param2”]
  7. EXPOSE:声明镜像内服务所监听的端口
  8. VOLUME:指定容器数据卷(数据卷就是容器数据持久化的地方)

示例1:基于centos镜像制作一个新的centos镜像(添加vim功能)

由于远程仓库获取的centos不支持vim,所以这里构建一个支持vim的centos镜像,Dockerfile文件如下:

FROM centos:latest
ENV AUTHOR yhj
WORKDIR /root
MAINTAINER $AUTHOR
RUN yum -y install vim
EXPOSE 80
ENTRYPOINT ["/bin/bash"]

执行如下命令:

//-f 指定Dockerfile路径,-t指定创建镜像的名字与TAG
docker build -f ./Dockerfile -t mycentos:1.0 .

ZLMediaKit docker下载 docker image下载_数据库_11

示例2:制作一个SpringBoot应用镜像

先把写好的SpringBoot应用打成可执行jar包,注意SpringBoot打包需要引入打包插件。

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
</plugin>

Dockerfile如下:

FROM java:8
EXPOSE 8080
ADD ./MySpringBoot.jar /app.jar
ENTRYPOINT ["java","-jar","/app.jar"]

ZLMediaKit docker下载 docker image下载_数据库_12


如上curl访问成功,说明应用启动成功。

六、数据卷VOLUME

docker将应用与运行环境打包形成容器运行,数据伴随着容器,但是我们对数据的要求是希望能够持久化。容器和宿主机之间希望有可能共享数据。而Docker容器产生的数据,如果不通过docker commit生成新的镜像,使得数据作为镜像的一部分保存下来。那么当容器删除后,数据自然也就没有了。为了能够使得数据保存下来,故有了容器数据卷。

卷的设计目的就是数据持久化,完全独立于容器的生存周期,因此docker不会在容器删除时删除其挂载的数据卷。(特别的,如果容器没有被删除,那么卷是不允许被删除的,只有容器被删除了,我们才可以删除其挂载的数据卷)

特点:

  1. 数据卷可以在容器中共享或重用数据
  2. 数据卷中的更改可以直接生效
  3. 数据卷中的更改不会包含在镜像的更新中
  4. 数据卷的声明周期一直持续到没有容器使用它为止

容器数据卷的添加
1. 直接命令添加
命令: docker run -v 宿主机路径:容器路径 镜像ID

//执行命令
 docker run -it -v ~/myDataVolume:/containerDataVolume centos

docker inspect 容器ID 查看数据卷是否绑定成功,出现如图所示说明绑定成功。你还可以进入容器centos终端看到新建了一个/containerDataVolume目录。

ZLMediaKit docker下载 docker image下载_redis_13

共享数据验证:如下在主机~/myDataVolume目录下新建一个test.txt文件,再次启动容器查看/containerDataVolume目录下也产生了一个test.txt文件。随后在容器中操作删除后宿主机上的文件也被删除了。

ZLMediaKit docker下载 docker image下载_ZLMediaKit docker下载_14


2.Dockerfile添加

在Dockerfile中使用VOLUME[“容器目录1”,“容器目录2”] 指令来给镜像添加一个或多个数据卷。

FROM java:8
EXPOSE 8080
VOLUME ["/tmp"]
……

查看容器中的共享目录如下:

ZLMediaKit docker下载 docker image下载_数据库_15


这与docker客户端中显示的数据一致

ZLMediaKit docker下载 docker image下载_docker_16

通过Dockerfile这种方式无法指定宿主机的目录,docker会帮我们生成一个匿名目录“Source”。通过docker inspect 容器ID 命令查看如下:

ZLMediaKit docker下载 docker image下载_数据结构_17


mac中没有找到“Source”指定的宿主机目录,不过inspect有显示。

七、docker安装mysql

1.拉取mysql镜像(由于镜像仓库中已经有mysql镜像,所以拿来即用即可)

ZLMediaKit docker下载 docker image下载_数据结构_18


2.启动docker容器运行mysql

//如下指定了几个-v项,只是为了方便直接从宿主机上操作查看容器上安装的mysql配置等数据
//MYSQL_ROOT_PASSWORD=123456:设置环境变量MySQL服务root用户的密码。
docker run -p 54199:3306 --name mysqlContainer 
-v ~/myDataVolume/mysql/conf:/etc/mysql/conf.d 
-v ~/myDataVolume/mysql/logs:/logs -v ~/myDataVolume/mysql/data:/var/lib/mysql 
-e MYSQL_ROOT_PASSWORD=123456 
-d mysql:5.6

ZLMediaKit docker下载 docker image下载_数据库_19


ZLMediaKit docker下载 docker image下载_docker_20


ZLMediaKit docker下载 docker image下载_数据结构_21

如上我们开启交互运行,登入了容器中的mysql,成功创建了库表。

查看共享数据绑定也是成功的

ZLMediaKit docker下载 docker image下载_数据结构_22

宿主机登陆操作docker中的mysql
部署好mysql服务后需要让外部能够操作,这里尝试用宿主机操作容器内的mysql。首先需要进到容器中,为mysql添加远程连接权限,并重启。执行如下命令:

//mysql为用户授权。表示任何ip的主机都可以通过root账户登陆
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123456' WITH GRANT OPTION;
//刷新
FLUSH PRIVILEGES;
//重启mysql服务
service mysql restart

完成之后退回宿主机登陆mysql。

ZLMediaKit docker下载 docker image下载_docker_23


注意由于docker对外暴漏的端口是54199,所以指定的端口是54199,主机使用回环地址127.0.0.1,因为docker进程本身也是在本机上运行的。

docker学习地址:
https://www.runoob.com/docker/docker-architecture.htmlhttps://yeasy.gitbook.io/docker_practice/install/mirror