一、安装

  1. 卸载旧安装

    1. # 非管理员用户需要加 sudo
    2. sudo yum remove docker \
    3. docker-client \
    4. docker-client-latest \
    5. docker-common \
    6. docker-latest \
    7. docker-latest-logrotate \
    8. docker-logrotate \
    9. docker-engine
  2. 安装 Docker Engine-Community

在新主机上首次安装 Docker Engine-Community 之前,需要设置 Docker 仓库。之后,您可以从仓库安装和更新 Docker。
安装所需的软件包。yum-utils 提供了 yum-config-manager ,并且 device mapper 存储驱动程序需要 device-mapper-persistent-data 和 lvm2。

  1. sudo yum install -y yum-utils \
  2. device-mapper-persistent-data \
  3. lvm2

阿里云仓库地址:

  1. sudo yum-config-manager \
  2. --add-repo \
  3. http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
  1. 安装 Docker Engine-Community

安装最新版本的 Docker Engine-Community 和 containerd。

  1. sudo yum install docker-ce docker-ce-cli containerd.io
  1. 启动docker

    1. sudo systemctl start docker
  2. 查看docker版本

    1. sudo docker -v
  3. 配置docker开机自启动

    1. sudo systemctl enable docker
  4. 配置docker镜像加速

    1. sudo mkdir -p /etc/docker
    2. sudo tee /etc/docker/daemon.json <<-'EOF'
    3. {
    4. "registry-mirrors": ["https://<你的id>.mirror.aliyuncs.com"]
    5. }
    6. EOF
    7. sudo systemctl daemon-reload
    8. sudo systemctl restart docker

二、拉取镜像,创建容器

MySQL

  1. 拉取镜像

    1. # 拉取镜像
    2. docker pull mysql:5.7
  2. 创建测试容器,查看配置及数据卷位置

    1. 创建测试容器

      1. docker run \
      2. -p 3306:3306 \
      3. --name mysql57 \
      4. -e MYSQL_ROOT_PASSWORD=root \
      5. -d mysql:5.7
    2. 进入容器内部

      1. docker exec -it mysql57 /bin/bash
    3. 查看配置文件所在

      1. mysql --help | grep my.cnf

      显示如下,意思是路径按优先排序,会是在以下路径里:
      image.png
      经过确认,配置文件在/etc/mysql/目录下。

    4. 查找数据文件位置

      1. docker inspect mysql57

      此命令可以输出指定容器的状态信息,其中包含了容器挂载情况,部分内容如下:
      image.png
      可以看到,当前数据卷挂载在容器内部,此时若移除容器或容器出现故障,就会导致数据丢失。绿色框表示当前mysql的数据所在所在位置/var/lib/mysql,我们后续就可以将此目录与宿主机的指定目录挂载,做到容器与数据分离。

  3. 创建容器

在宿主机创建好对应的挂载目录:

  1. mkdir -p /opt/docker/mysql/conf && mkdir -p /opt/docker/mysql/data && mkdir -p /opt/docker/mysql/log

创建好本地的挂载数据路径后,我们再将测试容器里 MySQL 的配置文件复制到该路径。日后需改配置,直接在挂载路径的配置文件上修改即可。

  1. docker cp mysql57:/etc/mysql/my.cnf /opt/docker/mysql/conf

创建容器:

  1. docker run \
  2. -p 3306:3306 \
  3. --name mysql57 \
  4. -v /opt/docker/mysql/log:/var/log/mysql \
  5. -v /opt/docker/mysql/data:/var/lib/mysql \
  6. -v /opt/docker/mysql/conf:/etc/mysql \
  7. -e MYSQL_ROOT_PASSWORD=root \
  8. -d mysql:5.7
  1. docker run \
  2. --name mysql57 \
  3. -p 3306:3306 \
  4. -e MYSQL_ROOT_PASSWORD=root \
  5. --mount type=bind,src=/opt/docker/mysql/conf/my.cnf,dst=/etc/mysql/my.cnf \
  6. --mount type=bind,src=/opt/docker/mysql/data,dst=/var/lib/mysql \
  7. --mount type=bind,src=/opt/docker/mysql/log,dst=/var/log/mysql \
  8. --restart=on-failure:3 \
  9. -d mysql:5.7
  • —name:为容器指定一个名字
  • -p:指定端口映射,格式为:主机(宿主)端口:容器端口
  • -e:username=”xxx”,设置环境变量
  • —restart=on-failure:3:是指容器在未来出现异常退出(退出码非0)的情况下循环重启3次
  • -mount:绑定挂载
  • -d:后台运行容器,并返回容器 id
  1. 修改配置文件

在宿主机/opt/docker/mysql/conf目录下,创建并修改配置文件:

  1. # 配置文件内容如下:
  2. [client]
  3. default-character-set=utf8mb4
  4. [mysql]
  5. default-character-set=utf8mb4
  6. [mysqld]
  7. init_connect='SET NAMES utf8mb4'
  8. character-set-server=utf8mb4
  9. collation-server=utf8mb4_unicode_ci
  10. skip-character-set-client-handshake
  11. skip-name-resolve

Redis

  1. 拉取镜像

    1. docker pull redis:5.0.14
  2. 创建容器 ```shell

    为了避免目录挂载时,将redis.conf误认为一个目录,出现异常,我们先创建出对应的目录及配置文件

    mkdir -p /opt/docker/redis/conf

touch /opt/docker/redis/conf/redis.conf

运行出容器

docker run \ -p 6379:6379 \ —name redis5014 \ —mount type=bind,src=/opt/docker/redis/conf/redis.conf,dst=/etc/redis/redis.conf \ —mount type=bind,src=/opt/docker/redis/data,dst=/var/lib/redis \ -d redis:5.0.14 \ redis-server /etc/redis/redis.conf

  1. 也可以不手动创建配置文件,从官网获取。
  2. 3. 错误处理
  3. 执行上述命令后,发现容器没有启动起来哈哈!<br />使用命令`docker logs redis5014`发现,存在报错信息:<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/22365594/1647151742491-0c134008-6b4d-4b76-86f4-50450e9376a7.png#clientId=ue356d869-65a7-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=76&id=uba24e081&margin=%5Bobject%20Object%5D&name=image.png&originHeight=76&originWidth=803&originalType=binary&ratio=1&rotation=0&showTitle=false&size=9840&status=done&style=none&taskId=uc6283a33-340c-4674-802a-e35aa51a672&title=&width=803)<br />意思是不能够打开对应的aof文件,看了一下挂载的目录,发现没有生成aof、rdb文件,可能是权限不够,没有生成成功,手动创建了两个文件并修改权限至`666`,重新启动容器,成功!

touch appendonly.aof

touch dump.rdb

  1. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/22365594/1647152260534-fc5e9260-cc72-48d6-86cd-28cadb98f225.png#clientId=ue356d869-65a7-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=73&id=u0889406e&margin=%5Bobject%20Object%5D&name=image.png&originHeight=73&originWidth=384&originalType=binary&ratio=1&rotation=0&showTitle=false&size=3678&status=done&style=none&taskId=u2f127455-b270-4704-9a9c-158bcc05257&title=&width=384)

chmod 666 appendonly.aof

chmod 666 dump.rdb

  1. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/22365594/1647152294765-9dafe3bb-6223-4b31-abfc-c93765f78dfb.png#clientId=ue356d869-65a7-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=76&id=u03061144&margin=%5Bobject%20Object%5D&name=image.png&originHeight=76&originWidth=401&originalType=binary&ratio=1&rotation=0&showTitle=false&size=3782&status=done&style=none&taskId=u7432ee6d-0bbf-4d65-b9b7-1a36a27daa2&title=&width=401)
  2. 4. 配置远程访问
  3. 当我们使用第三方工具,远程连接redis时,发现连接一直不成功,这是由于开启redis-server后,redis-cli只能访问到127.0.0.1,因为在配置文件中固定了ip,因此需要修改redis.conf,将配置文件中的`bind 127.0.0.1`给注释掉,重启redis容器即可正常远程访问。
  4. <a name="IYX59"></a>
  5. # 三、常用命令
  6. <a name="VCAvd"></a>
  7. ## 3.1 镜像命令
  8. <a name="sVoQX"></a>
  9. ### 1. 列出本机上的镜像
  10. ```sql
  11. docker images [OPTIONS]
  12. docker images

image.png
Options说明:

  1. -a

列出本地所有的镜像(包含中间映像层)。

  1. docker images -a

image.png

  1. -q

只显示镜像ID。

  1. docker images -q

image.png

  1. —digests

    1. docker images --digests

    image.png

  2. —no-trunc

    1. docker images --digests --no-trunc

    image.png

    2. 从DockerHub上搜索镜像信息

    ```sql docker search [OPTIONS] tomcat

docker search tomcat

  1. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/22365594/1637140377675-91ac2e0c-9a45-4b16-bbeb-9f257baed18a.png#clientId=u310835aa-7002-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=515&id=u2ed259f1&margin=%5Bobject%20Object%5D&name=image.png&originHeight=515&originWidth=951&originalType=binary&ratio=1&rotation=0&showTitle=false&size=70440&status=done&style=none&taskId=ud439d4e3-2f7a-41c7-939e-9ac857d43a9&title=&width=951)
  2. **Options说明:**
  3. 1. -f
  4. 列出收藏数不小于指定值的镜像。
  5. ```sql
  6. docker search -f stars=30 tomcat

image.png

  1. —no-trunc

显示完整的镜像描述。

  1. docker search -f stars=30 --no-trunc tomcat

image.png

3. 拉取镜像(下载)

注意:不携带版本的话,默认为latest

  1. docker pull 镜像名称
  2. docker pull 镜像名称:Tag
  3. docker pull nginx

image.png

4. 删除镜像

  1. 删除单个镜像 ```sql docker rmi 某个镜像名字id

docker rmi hello-world:latest

  1. 当镜像已经创建出容器,则删除会失败:<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/22365594/1637141945047-b4740803-b867-4fbb-808c-a280d7a83e1d.png#clientId=u8eb2c44e-4017-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=50&id=u40b14a52&margin=%5Bobject%20Object%5D&name=image.png&originHeight=50&originWidth=1434&originalType=binary&ratio=1&rotation=0&showTitle=false&size=9421&status=done&style=none&taskId=uff636e85-c754-4688-bfcb-8ddd7a66c0c&title=&width=1434)<br />需要使用强制删除:
  2. ```sql
  3. docker rmi -f 镜像名称
  4. docker rmi -f hello-world:latest

image.png

  1. 删除多个镜像 ```sql docker rmi -f 镜像1名称及标签 镜像2名称及标签

docker rmi -f nginx:latest hello-world:latest

  1. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/22365594/1637142357172-92c685cf-2981-4bc1-9fbd-d92f786bc78b.png#clientId=u8eb2c44e-4017-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=471&id=uf7fec0bd&margin=%5Bobject%20Object%5D&name=image.png&originHeight=471&originWidth=752&originalType=binary&ratio=1&rotation=0&showTitle=false&size=63040&status=done&style=none&taskId=ua120f585-84c3-4cc1-b5f5-b2136a11156&title=&width=752)
  2. 3. 删除全部镜像(慎用)
  3. ```sql
  4. docker rmi -f ${docker images -qa}

3.2 容器命令

1. 新建并启动容器

  1. docker run [OPTIONS] 镜像名称及标签
  2. docker run -it centos:7

创建了一个centos容器,并进入容器内:
image.png
可以执行linux命令:
image.png
Options说明:
有些是一个-,有些是两个-

  1. -i

交互模式运行容器,通常与-t同时使用。

  1. -t

为容器重新分配一个伪输入终端,通常与-i同时使用。

  1. —name

为容器指定一个名称。

  1. --name="容器新名字"

image.png

  1. -d

后台运行容器,并返回容器id,也即启动守护式容器。

  1. -P

随机端口映射。

  1. -p

指定端口映射,有以下四种方式:

  • ip:hostPort:containerPort
  • ip::containerPort
  • hostPort:containerPort(最常用)
  • containerPort

2. 列出当前所有正在运行中的容器

  1. docker ps [OPTIONS]

Options说明:

  1. -a

列出当前所有正在运行的容器 + 历史上运行过的容器。

  1. -l

显示最近创建的容器。

  1. -n

显示最近n个创建的容器。

  1. -q

静默模式,只显示容器编号。

  1. —no-trunc

不截断输出

3. 退出容器

容器停止退出

  1. exit

退出后:
image.png

容器不停止退出

  1. ctrl + P + Q

退出后:
image.png
image.png

4. 启动容器

  1. docker start 容器id或者容器名称

5. 停止容器

  1. docker stop 容器名称或容器id

6. 重启容器

  1. docker restart 容器名称或容器id

7. 强制停止容器

  1. docker kill 容器名称或容器id

8. 删除已停止的容器

可加-f删除未停止的容器。

  1. docker rm 容器id
  2. # 一次性删除多个容器
  3. docker rm -f ${docker ps -a -q}
  4. docker ps -a -q | xargs docker rm

9. 新建并启动守护式容器

  1. docker run -d 镜像名
  2. docker run -d centos

image.png

10. 查看容器日志

  1. docker logs -f -t --tail 10 容器id

Options说明:

  1. -t

加入时间戳

  1. -f

跟随最新的日志打印

  1. —tail

显示最后多少条

  1. --tail 数字

11. 查看容器内运行的进程

  1. docker top 容器名称/容器id
  2. docker top mycentos1117

如图:
image.png

12. 查看容器内部细节

  1. docker inspect 容器名称或容器id
  2. docker inspect mycentos1117

如图:
image.png

13. 进入正在运行的容器并以命令行交互

  1. # docker exec -it 容器名称或容器id /bin/bash
  2. docker exec -it mycentos1117 /bin/bash
  3. # docker attach 容器名称或容器id
  4. docker attach mycentos1117

exec 和 attach 区别:

  • attach:直接进入容器启动命令的中断,不会启动新的进程(容器停止时,无法进入)
  • exec:是在容器中打开新的终端,并且可以启动新的进程

如图:

attach测试:image.png
当容器停止时,无法进入:
image.png

14. 从容器内拷贝文件到主机上

  1. # docker cp 容器名称或容器id:容器内路径 宿主机路径
  2. docker cp heuristic_keller:/tmp/yum.log /root

源地址:
image.png
目标位置:
image.png

15. 帮助命令

  1. docker version
  2. docker info
  3. docker --help

四、Docker镜像

4.1 是什么

镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。
Union FS(联合文件系统): Union文件系统( Union FS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下( unite several directories into a single virtual filesystem)。 Union文件系统是 Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看釗一个文件系,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。

docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统 Union FS boots( boot file system)主要包含 bootloader和kene, bootloader主要是引导加载 kernel, Linux刚启动时会加毂 boots文件系统,在Docker镜像的最底层是 boots。这一层与我们典型的 Linux/Unⅸx系统是一样的,包含bot加载器和内核。
当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由 boots转交给内核,此时系统也会卸载 boots rootfs( (root file system),在 boots之上·包含的就是典型 Linux系统中的/cev,/proc,/bin,/etc等标准目录和文件。
rootfs就是各种不同的操作系统发行版,比如 Ubuntu,censtos等等。

image.png

4.2 特点

Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部,这一层通常被称作“容器层”,容器层之下的都叫做“镜像层”。

4.3 Docker Commit操作

可以通过docker commit操作提交容器副本使之成为一个新的镜像。

  1. docker commit -m="提交的描述信息" -a="作者" 容器id或容器名称 要创建的目标镜像名:[标签名]

1. 从Hub上下载Tomcat镜像到本地并成功运行

  1. docker pull tomcat:8.0
  2. docker run -it -p 8888:8080 tomcat:8.0

Options说明:

  • -p:主机端口:docker容器端口
  • -P:随机分配端口
  • -i:交互
  • -t:终端

2. 故意删除上一步镜像生产Tomcat容器的文档

image.png
删除上图中的docs目录:

3. 提交此容器,形成新镜像

  1. docker commit -a="ljl" -m="tomcat without docs" boring_hofstadter ljl/mytomcat8:1.1

image.png
image.png

4. 启动新镜像作对比

image.png
启动后,可以看到欢迎页,但是点开相关链接,页面404.
image.png

五、容器数据卷

5.1 是什么

卷就是目录或文件,存在于一个或多个容器中,由 docker挂载到容器,但不属于联合文件系统,因此能够绕过 Union File System提供一些用于持续存储或共享数据的特性。
卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此 Docker不会在容器删除时删除其挂载的数据卷。

5.2 特点

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

5.3 数据卷操作

1. 直接命令添加

  1. 命令

    1. docker run -it -v /宿主机绝对路径目录:/容器内目录 镜像名

    image.png

  2. 查看数据卷是否挂在成功

使用docker inspect命令,查看容器详情。

  1. docker inspect infallible_borg

可以看到数据卷挂载情况:
image.png
image.png

  1. 容器和宿主机之间数据共享

宿主机在挂载卷中创建文件:
image.png
容器内可以同步看到:
image.png

同样,在容器内创建文件,宿主机也同步可以看到:
image.png
image.png

  1. 容器停止退出后,主机修改后数据是否同步

同样是可以同步的。

  1. 命令(带权限) ```

    docker run -it -v 宿主机目录:容器目录:ro 镜像名

    ro:只读权限

docker run -it -v /test1:/test2:ro centos

  1. **绑定情况:**<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/22365594/1637224658052-4ab6c1be-5ec3-44e0-b2f8-c28c5227f031.png#clientId=ubb581ca1-fffc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=120&id=u7e04fce4&margin=%5Bobject%20Object%5D&name=image.png&originHeight=120&originWidth=290&originalType=binary&ratio=1&rotation=0&showTitle=false&size=4657&status=done&style=none&taskId=u0255e0ed-70e2-44b1-b220-d106b23f3cd&title=&width=290)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/22365594/1637224714098-50157d64-f52d-4dfa-9f81-64d423757aa0.png#clientId=ubb581ca1-fffc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=207&id=u20ae2d37&margin=%5Bobject%20Object%5D&name=image.png&originHeight=207&originWidth=336&originalType=binary&ratio=1&rotation=0&showTitle=false&size=8096&status=done&style=none&taskId=u4bb110c9-2456-4877-8a4f-57dfc033fc0&title=&width=336)
  2. 创建了带权限的数据卷挂载,可以看到,宿主机可以在挂载目录创建文件,容器可以看到相关的更新,但容器创建文件时失败:![image.png](https://cdn.nlark.com/yuque/0/2021/png/22365594/1637224284807-56994f9e-e2ca-4cfa-829c-8271cc3c2e71.png#clientId=ubb581ca1-fffc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=178&id=u794db6a2&margin=%5Bobject%20Object%5D&name=image.png&originHeight=178&originWidth=882&originalType=binary&ratio=1&rotation=0&showTitle=false&size=19458&status=done&style=none&taskId=uc3101e3d-9d65-43a1-bc20-961cf162313&title=&width=882)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/22365594/1637224348763-5302df69-efce-4e40-a702-69521f8d9cce.png#clientId=ubb581ca1-fffc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=120&id=u594af492&margin=%5Bobject%20Object%5D&name=image.png&originHeight=120&originWidth=686&originalType=binary&ratio=1&rotation=0&showTitle=false&size=12076&status=done&style=none&taskId=ud5ff09ce-14ab-4c52-82b4-685b8311ad2&title=&width=686)
  3. <a name="uKzv9"></a>
  4. ### 2. DockerFile添加
  5. 1. 根目录下新建mydocker文件夹并进入
  6. 1. 可在Dockerfile中使用`VOLUME`指令来给镜像添加一个或多个数据卷
  7. 说明:
  8. - 出于可移植和分享的考虑,用`-v 主机目录:容器目录`这种方法不能够直接在 Dockerfile中实现。
  9. - 由于宿主机目录是依赖于特定宿主机的,并不能够保证在所有的宿机上都存在这样的特定目录。
  10. 创建并编辑`Dockerfile`

volume test

FROM centos:7 VOLUME [“/dataVolumeContainer1”,”/dataVolumeContainer2”] CMD echo “finished,———success” CMD /bin/bash

  1. 上述内容相当于:
  2. ```shell
  3. docker run -it -v /host1:/dataVolumeContainer1 -v /host2:/dataVolumeContainer2 centos /bin/bash

image.png
若没有指定宿主机挂载目录,会存在默认的挂载目录生成路径,通常为/var/lib/docker/volumes

  1. build后生成镜像 ```shell

    docker build -f Dockerfile路径 -t 命名 生成位置

docker build -f /mydocker/Dockerfile -t ljl/centos .

  1. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/22365594/1637229449562-e85e921a-e51b-41e4-b14d-35c59ae2bdde.png#clientId=ubb581ca1-fffc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=370&id=u0dd16947&margin=%5Bobject%20Object%5D&name=image.png&originHeight=370&originWidth=647&originalType=binary&ratio=1&rotation=0&showTitle=false&size=32912&status=done&style=none&taskId=u8c5a88d9-db41-4500-baa3-8a4b05635f4&title=&width=647)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/22365594/1637229811117-5d96a30b-c3ed-40c1-bdf4-ca6533759bef.png#clientId=ubb581ca1-fffc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=175&id=u8b1039ed&margin=%5Bobject%20Object%5D&name=image.png&originHeight=175&originWidth=523&originalType=binary&ratio=1&rotation=0&showTitle=false&size=18943&status=done&style=none&taskId=u383e4507-e5d3-4ff3-b0d8-411668b6a7c&title=&width=523)
  2. 4. run出容器
  3. ```shell
  4. docker run -it ljl/centos /bin/bash

image.png

通过docker inspect命令,查看容器详情,可以看到数据卷的情况:
自动在宿主机上生成了挂载目录。 image.png

注意:Docker挂载主机目录 Docker访问出现 cannot open directory: Permission denied
解决办法:在挂载目录后多加一个--privileged=true参数即可。
即:

  1. -v 宿主机目录:容器目录 --privileged=true

3. volumes-from操作

在某一容器基础上,创建新的容器并做数据卷挂载操作。可以使用--volume-from命令做容器间传递共享操作。

  1. 首先,在指定容器的某一目录创建一个文件

image.png

  1. 在上述容器的基础上,使用相同镜像运行出新的容器test02

使用如下命令操作:

  1. # docker run -it --name 容器名称 --volumes-from 基础容器名称 镜像名
  2. docker run -it --name test02 --volumes-from compassionate_banach ljl/centos

可以看到,新容器中,也存在基础容器中创建的文件:
image.png
在创建的容器中的同目录创建文件:
image.png

  1. 基于上步运行的容器,再次生成新的同镜像容器test03

    1. docker run -it --name test03 --volumes-from test02 ljl/centos

    可以看到,同目录中同样有容器1和容器2所创建的文件:
    image.png
    我们在此目录中新创建一个文件:
    image.png

  2. 回到容器1中,观察同目录下内容 ```java docker exec -it compassionate_banach /bin/bash

cd dataVolumeContainer1

ll

  1. 可以看到,容器1中也可以看到后续容器创建的文件:<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/22365594/1637309376724-17eecb1a-ef72-4af3-b66c-e75a6975b25b.png#clientId=u029819b6-9763-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=162&id=u5485f915&margin=%5Bobject%20Object%5D&name=image.png&originHeight=162&originWidth=556&originalType=binary&ratio=1&rotation=0&showTitle=false&size=14023&status=done&style=none&taskId=u81bd6094-86b7-4227-852b-54d4d1f43a9&title=&width=556)
  2. 5. 删除容器1,观察后续容器内状况
  3. 可以看到,虽然删除了容器1,后续的容器内部依然可以访问到之前的所有数据:<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/22365594/1637309596532-10105e70-fbe3-4edb-a440-3ca6f4ed5a59.png#clientId=u029819b6-9763-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=204&id=u6b6ccc32&margin=%5Bobject%20Object%5D&name=image.png&originHeight=204&originWidth=519&originalType=binary&ratio=1&rotation=0&showTitle=false&size=16468&status=done&style=none&taskId=u79922f79-f283-41d4-984d-9f8a8780eb0&title=&width=519)
  4. 6. 创建容器test04,删除中间容器test03,测试关联状况
  5. ```java
  6. docker run -it --name test4 --volumes-from test03 ljl/centos

容器如下:
image.png
我们先删除容器test03:
image.png
在容器test04中创建新文件:
image.png
进入容器test02中,查看文件状况,可以看到,新创建的文件依然可以在test02中看到:
image.png

对应宿主机挂载目录:
image.png
移除所有关联容器,对应挂载目录数据依然存在,但无法再依靠容器间共享来关联:
image.png

可知,使用--volume-from命令做容器间传递共享操作,只要关联的容器没有完全删除,数据卷的生命周期可以一直持续下去。当所有关联的容器全部移除,容器间共享关系消失,但对应的挂载目录依然存在,数据依然保存在宿主机上。

六、Dockerfile

6.1 是什么

Docker是用来构建 Docker镜像的构建文件,是由一系列命令和参数构成的脚本。

构建的三个步骤:

  • 编写Dockerfile文件
  • docker build
  • docker run

示例:
image.png

6.2 Dockerfile构建过程解析

6.2.1 Dockerfile内容基础

  1. 每条保留字指令都必须为大写字母且后面要跟随至少一个参数
  2. 指令按照从上到下,顺序执行
  3. 表示注释

  4. 每条指令都会创建一个新的镜像层,并对镜像进行提交

6.2.2 Docker执行Dockerfile的大致流程

  1. docker从基础镜像运行一个容器
  2. 执行一条指令并对容器作出修改
  3. 执行类似 docker commit的操作提交一个新的镜像层
  4. docker再基于刚提交的镜像运行一个新容器
  5. 执行 dockerfile中的下一条指令直到所有指令都执行完成

从应用软件的角度来看, Dockerfile、 Docker镜像与 Docker容器分别代表软件的三个不同阶段:

  • Dockerfile是软件的原材料
  • Docker镜像是软件的交付品
  • Docker容器则可以认为是软件的运行态

Dockerfile面向开发,Docker镜像成为交付标准,Docker容器则涉及部署与运维,三者缺一不可,合力充当 Docker体系的基石。
image.png

6.3 Dockerfile体系结构(保留字指令)

image.png

  1. FROM

基础镜像,当前新镜像是基于哪个镜像的。

  1. MAINTAINER

镜像维护者的姓名和邮箱地址。

  1. RUN

容器构建时需要运行的命令。

  1. EXPOSE

当前容器对外暴露出的端口。

  1. WORKDIR

指定在创建容器后,终端默认登录进来的工作目录,一个落脚点。

  1. ENV

用来在构建镜像过程中设置环境变量。
环境变量比如: ENV MY_PATH /usr/mytest可以在后续的任何RUN指令中使用,这就如同在命令前面指定了环境变量前缀一样。
也可以在其它指令中直接使用这些环境变量,比如: WORKDIR $MY_PATH

  1. ADD

将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar压缩包。

  1. COPY

类似ADD,拷贝文件和目录到镜像中。将从构建上下文目录中<源路径>的文件/目录复制到新的一层的镜像内的<目标路径>位置。

  1. COPY src dest
  2. COPY ["src","dest"]
  1. VOLUME

容器数据卷,用于数据保存和持久化工作。

  1. CMD

指定一个容器启动时要运行的命令。Dockerfile中可以有多个CMD命令,但只有最后一个生效,CMD会被 docker run 之后的参数替换。

CMD 容器启动命令:
CMD指令的格式和 RUN 相似,也是两种格式:

  • shell 格式:CMD <命令>
  • exec 格式: CMD ["可执行文件","參数1","参数2"...]
  • 参数列表格式: CMD ["参数1","参数2"....] 。在指定了 ENTRYPOINT 指令后,用 CMD 指定具体的参数。
    1. ENTRYPOINT

指定一个容器启动时要运行的命令。ENTRYPOINT的目的和CMD一样,都是在指定容器启动程序及参数。

  1. ONBUILD

当构建一个被继承的Dockerfile时运行命令。父镜像在被子继承后,父镜像的onbuild被触发。

6.4 案例

6.4.1 Base镜像(scratch)

Docker Hub中99%的镜像都是通过在base镜像中安装和配置需要的软件构建出来的。
image.png

6.4.2 自定义镜像mycentos

1. 编写

  1. Hub默认CentOS镜像什么情况

image.png

  1. 准备编写Dockerfile文件

创建dockerfile文件。

  1. vim Dockerfile
  1. myCentOS的Dockerfile内容 ```shell FROM centos MAINTAINER zzyyzzyy167@126.com

ENV MYPATH /usr/local WORKDIR $MYPATH

RUN yum -y install vim RUN yum -y install net-tools

EXPOSE 80

CMD echo $MYPATH CMD echo “success—————ok” CMD /bin/bash

  1. <a name="oITob"></a>
  2. #### 2. 构建
  3. ```shell
  4. # docker build命令最后有一个 . ,代表当前路径,可根据文件所在位置变化
  5. docker build -t 新镜像名字:TAG .
  6. # 在Dockerfile所在目录执行如下命令
  7. [root@test01 mydocker]# docker build -f /mydocker/Dockerfile2 -t mycentos:1.3 .

image.png

image.png

image.png

image.png

4. 运行

  1. docker run -it 新镜像名称:TAG

运行容器,可以看到入口目录已不再是默认的/
image.png

使用vim命令也可以正常执行了:
image.png

使用ifconfig命令也可以正常执行:
image.png

5. 列出镜像的变更历史

  1. docker history 镜像id
  2. docker history 镜像名称:TAG

image.png

6.4.3 CMD/ENTRYPOINT命令案例

都是指定一个容器启动时要运行的命令。

1. CMD

对于CMD
Dockerfile中可以有多个CMD指令,但只有最后一个生效,CMD会被docker run之后的参数替换。

默认的Tomcat的Dockerfile中,最后的CMD命令为: image.png
在我们运行此Tomcat镜像时,会直接启动Tomcat服务:
image.png
当我们使用如下命令运行容器,类似于在默认的CMD命令后面追加了一条CMD ["ls","-l"],这时会覆盖掉上一句启动Tomcat服务的命令:

  1. docker run -it -p 7777:8080 tomcat ls -l
  1. 这时,运行容器后,只会打印出Tomcat所在目录下的内容:<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/22365594/1639988339745-ef7e2312-5f9f-4faa-a83f-e2be5028bc2d.png#clientId=u30108a9f-a0d0-4&crop=0&crop=0&crop=1&crop=0.5244&from=paste&height=573&id=u19ab2de8&margin=%5Bobject%20Object%5D&name=image.png&originHeight=573&originWidth=979&originalType=binary&ratio=1&rotation=0&showTitle=false&size=32481&status=done&style=none&taskId=ubc70e29d-091c-4c98-93aa-982f8475300&title=&width=979)

2. ENTRYPOINT

对于ENTRYPOINT
docker run之后的参数会被当做参数传递给ENTRYPOINT,之后形成新的命令组合。

2.1 制作CMD版可以查询IP信息的容器

注意:此案例已不可用!

  1. 编写Dockerfile文件
    1. FROM centos
    2. RUN yum install -y curl
    3. CMD ["curl", "-s", "http://ip.cn"]
    curl命令可以用来执行下载、发送各种HTTP请求,指定HTTP头部等操作。如果系统没有curl,可以使用yum install curl安装,也可以下载安装。
    curl是将下载文件输出到stdout

使用命令:curl [http://www.baidu.com](http://www.baidu.com)
执行后,www.baidu.com的html就会显示在屏幕上了。

这是最简单的使用方法。用这个命令获得了http://curl.haxx.se指向的页面,同样,如果这里的URL指向的是一个文件或者一幅图都可以直接下载到本地。如果下载的是HTML文档,那么缺省的将只显示文件头部,即HTML文档的header。要全部显示,请加参数 -i。

  1. 构建

使用如下命令运行:

  1. docker build -f Dockerfile3 -t myip .

image.png
可以查看镜像构建情况:
image.png

  1. 运行

使用如下命令运行容器:

  1. docker run -it myip

2.2 制作ENTRYPOINT版查询IP的容器
  1. 编写Dockerfile文件
    1. FROM centos
    2. RUN yum install -y curl
    3. ENTRYPOINT ["curl", "-s", "http://ip.cn"]

6.4.4 自定义Tomcat9

七、本地镜像推送到阿里云