一:Docker概述

1.1 为什么出现Docker?

首先要了解一款软件产品的运行,有两部环境,开发环境和生产环境。人员也会分为两部分,开发和运维。

​ 这个时候就会遇到问题,在开发的电脑环境上能用,但是在运维环境的电脑上就不能用,就算暂时的能用,也要考虑到后期的版本更新等相关的问题,对于运维的压力比较大。
Docker对以上的问题给出了解决方案!
Docker的设计思想来源于集装箱。将所有的东西放在集装箱中,实现隔离,开箱即用。

1.2 Docker的历史

2010年dotcloud公司成立,尝试做PaaS云计算相关的服务,以及一些LXC有关的容器技术,他们将自己的技术命名为Docker,但是刚诞生的时候,没有引起行业的注意,公司生活不下去。
​ 2013年Docker开源。开源之后,越来越多的人发现了Docker的特点,越来越多的人参与到Docker的开发当中,Docker每个月都会发布一个新的版本。
​ 2014年4月9日,Docker1.0正式发布。

1.3 Docker为什么会这么火

在容器技术出来之前,我们使用的都是虚拟化技术,通过软件,在HostOS系统上模拟出硬件环境,然后运行一个整体的OS,一台电脑虽然能运行多个系统,但是也造成了卡顿的问题,使得系统变得笨重。

​ Docker是一种容器技术,也算虚拟化技术的一种,但是他会抛去无用的服务,只保留最基本的服务,来支持服务的运行,也使得自身变得轻巧。

​ Docker基于Go语言发开,开源项目。

docker官网:https://www.docker.com/

文档:https://docs.docker.com/ Docker的文档是超级详细的!

仓库:https://hub.docker.com/

1.3.1 Docker能干嘛

之前的虚拟机技术在这里插入图片描述
虚拟机技术缺点:

1、 资源占用十分多
2、 冗余步骤多
3、 启动很慢!

容器化技术
容器化技术不是模拟一个完整的操作系统
在这里插入图片描述
比较Docker和虚拟机技术的不同:

1.传统虚拟机,虚拟出一条硬件,运行一个完整的操作系统,然后在这个系统上安装和运行软件
2.容器内的应用直接运行在宿主机的内容,容器是没有自己的内核的,也没有虚拟我们的硬件,所以就轻便了
3.每个容器间是互相隔离,每个容器内都有一个属于自己的文件系统,互不影响

1.3.2 :Docker的应用环境

1 :应用程序的打包和发布
2:应用程序隔离
3:持续集成
4:部署微服务
5:快速搭建测试环境
6:提供PaaS产品(平台即服务)

1.4 DevOps

开发和运维

应用更快速的交付和部署

  传统:一堆帮助文档,安装程序
  Docker:打包镜像发布测试,一键部署。

更便捷的升级和扩缩容

  使用Docker一周,所有的部署就想搭积木一样,

更简单的系统运维

  容器化之后,开发和运维环境保持高度一致。

更高效的计算机资源利用

  Docker是内核级别的虚拟化,可以在一个物理机上运行多个实例,将服务器的性能压榨到极致。

二:Docker安装

2.1 Docker的基本组成

在这里插入图片描述

镜像(image)
Docker镜像就好比是一个目标,或者而说是模板,可以通过这个模板来创建容器服务,可以通过这个镜像创建多个容器,可以参考Java类和对象的相关。

容器(container)
可以理解为一个简易的Linux系统,独立运行一个或者一组应用,通过镜像来创建,这其中包括启动、停止、删除等相关的基本命令。

仓库(repository)
仓库就是存储镜像的地方,分为两种,公有仓库、私有仓库,可以配置镜像加速。

Docker的安装过程
帮助文档:https://docs.docker.com/engine/install/

#1、需要CentOS7或者8的维护版本
#2、需要卸载原来安装的:
yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
#3、安装yum-tuils,一个管理repository及扩展包
yum install -y yum-utils
#4、添加repo仓库文件
yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo #默认国外镜像源,可以选择国内的。
    yum-config-manager     --add-repo     https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

#5、安装docker ce社区版本,ee企业版本,官方推荐社区版本。(也可以指定版本客户端与服务端版本要一致)
yum install -y docker-ce docker-ce-cli containerd.io
#6、启动docker服务
systemctl start docker
#7、验证是否安装成功
docker version 
docker info
#7、尝试运行一个容器
docker run hello-world

Docker的卸载过程

#1、卸载依赖
yum remove docker-ce docker-ce-cli containerd.io
#2、删除资源
rm -rf /var/lib/docker
# /var/lib/docker 是docker的默认工作路径!

2.2 阿里云镜像加速

1、登录阿里云找到容器服务

在这里插入图片描述
2、找到镜像加速器
在这里插入图片描述#别人的阿里云加速

tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://m6bpldf6.mirror.aliyuncs.com"]
}
# 需要秘钥

EOF
3、配置使用

#1.创建一个目录
mkdir -p /etc/docker
#2.编写配置文件
tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": [
    "https://registry.docker-cn.com",
    "http://hub-mirror.c.163.com",
    "https://docker.mirrors.ustc.edu.cn"
  ]
}
EOF
#3.重启服务
systemctl daemon-reloadsudo 
systemctl restart docker
镜像加速的原理:简单来说就是缓存机制,Docker在拉取本地没有的镜像时,会首先去加速器仓库查找,如果有,直接拉取,没有的话,下载下来,并缓存在镜像加速器中。

2.3 运行流程

在这里插入图片描述
docker run 流程图
在这里插入图片描述
2.3.1 底层原理
Docker是怎么工作的?

Docker是一个Client-Server结构的系统,Docker的守护进程运行在主机上。通过Socket从客户端访问!
Docker-Server接收到Docker-Client的指令,就会执行这个命令!

在这里插入图片描述
为什么Docker比Vm快

 1、docker有着比虚拟机更少的抽象层。由于docker不需要Hypervisor实现硬件资源虚拟化,运行在docker容器上的程序直接使用的都是实际物理机的硬件资源。因此在CPU、内存利用率上docker将会在效率上有明显优势。 
 2、docker利用的是宿主机的内核,而不需要Guest OS。
GuestOS: VM(虚拟机)里的的系统(OS)HostOS:物理机里的系统(OS)

在这里插入图片描述
​ 因此,当新建一个 容器时,docker不需要和虚拟机一样重新加载一个操作系统内核。仍而避免引导、加载操作系统内核返个比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载GuestOS,返个新建过程是分钟级别的。而docker由于直接利用宿主机的操作系统,则省略了这个复杂的过程,因此新建一个docker容器只需要几秒钟。

三:Docker的常用命令

3.1 帮助命令

docker version    #显示docker的版本信息。
docker info       #显示docker的系统信息,包括镜像和容器的数量
docker 命令 --help #帮助命令

帮助文档的地址:https://docs.docker.com/engine/reference/commandline/build/

3.2 镜像命令

docker images #查看所有本地主机上的镜像 可以使用docker image ls代替
docker search #搜索镜像
docker pull #下载镜像 docker image pull
docker rmi #删除镜像 docker image rm

3.2.1 查看镜像命令

[root@wanghe ~]# docker images --help

Usage:  docker images [OPTIONS] [REPOSITORY[:TAG]]

List images

Options:
  -a, --all             #查看所有的镜像
      --digests         #查看摘要
  -f, --filter filter   #根据提供的输出条件过滤
      --format string   Pretty-print images using a Go template
      --no-trunc        #不要截断输出
  -q, --quiet           #查询镜像ID
  
  [root@wanghe ~]# docker images -a
REPOSITORY    TAG       IMAGE ID       CREATED       SIZE
hello-world   latest    d1165f221234   5 weeks ago   13.3kB
[root@wanghe ~]# docker images -q
d1165f221234
[root@wanghe ~]# 
 # 解释
#REPOSITORY            # 镜像的仓库源
#TAG                # 镜像的标签(版本)        ---lastest 表示最新版本
#IMAGE ID            # 镜像的id
#CREATED            # 镜像的创建时间
#SIZE                # 镜像的大小
 # 可选项
Options:
  -a, --all         Show all images (default hides intermediate images) #列出所有镜像
  -q, --quiet       Only show numeric IDs # 只显示镜像的id

3.2.2 查询镜像命令

  [root@wanghe ~]# docker search --help

Usage:  docker search [OPTIONS] TERM

Search the Docker Hub for images

Options:
  -f, --filter filter   #根据提供的条件过滤输出
      --format string   #使用Go模板搜索打印
      --limit int       #最多搜索结果数(默认25)
      --no-trunc        #不要截断输出
[root@wanghe ~]# docker search -f stars=3000 mysql
NAME      DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mysql     MySQL is a widely used, open-source relation…   10725     [OK]       
mariadb   MariaDB Server is a high performing open sou…   4040      [OK]       
[root@wanghe ~]# docker search -f stars=3000 mysql
NAME      DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mysql     MySQL is a widely used, open-source relation…   10725     [OK]       
mariadb   MariaDB Server is a high performing open sou…   4040      [OK]       

 # --filter=STARS=3000 #过滤,搜索出来的镜像收藏STARS数量大于3000的
[root@wanghe ~]# docker search mysql --filter=STARS=3000

3.2.3 下载镜像命令

# 下载镜像 docker pull 镜像名[:tag]
[root@wanghe ~]# docker pull mysql
Using default tag: latest #如果不写[tag],默认就是latest,最新版本
latest: Pulling from library/mysql
f7ec5a41d630: Pull complete  #分层下载:Docker images的核心,联合文件系统。 
9444bb562699: Pull complete 
6a4207b96940: Pull complete 
181cefd361ce: Pull complete 
8a2090759d8a: Pull complete 
15f235e0d7ee: Pull complete 
d870539cd9db: Pull complete 
5726073179b6: Pull complete 
eadfac8b2520: Pull complete 
f5936a8c3f2b: Pull complete 
cca8ee89e625: Pull complete 
6c79df02586a: Pull complete 
Digest: sha256:6e0014cdd88092545557dee5e9eb7e1a3c84c9a14ad2418d5f2231e930967a38#防伪签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest #真实地址

#等价于
docker pull mysql
docker pull docker.io/library/mysql:latest

[root@wanghe ~]# docker pull mysql:5.7
5.7: Pulling from library/mysql
f7ec5a41d630: Already exists 
9444bb562699: Already exists 
6a4207b96940: Already exists 
181cefd361ce: Already exists 
8a2090759d8a: Already exists 
15f235e0d7ee: Already exists 
d870539cd9db: Already exists #已经下载的可以直接用
7310c448ab4f: Pull complete 
4a72aac2e800: Pull complete 
b1ab932f17c4: Pull complete 
1a985de740ee: Pull complete 
Digest: sha256:e42a18d0bd0aa746a734a49cbbcc079ccdf6681c474a238d38e79dc0884e0ecc
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7
[root@wanghe ~]# docker images  #查看已经下载的镜像
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
mysql         5.7       450379344707   23 hours ago   449MB
mysql         latest    cbe8815cbea8   23 hours ago   546MB
hello-world   latest    d1165f221234   5 weeks ago    13.3kB
[root@wanghe ~]# 

3.2.4 删除镜像命令

[root@wanghe ~]# docker rmi --help

Usage:  docker rmi [OPTIONS] IMAGE [IMAGE...]

Remove one or more images

Options:
  -f, --force      #强制删除镜像
      --no-prune   Do not delete untagged parents
[root@wanghe ~]# docker rmi -f d1165f221234
Untagged: hello-world:latest
Untagged: hello-world@sha256:308866a43596e83578c7dfa15e27a73011bdd402185a84c5cd7f32a88b501a24
Deleted: sha256:d1165f2212346b2bab48cb01c1e39ee8ad1be46b87873d9ca7a4e434980a7726
[root@wanghe ~]# docker images -a
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
mysql        5.7       450379344707   23 hours ago   449MB
mysql        latest    cbe8815cbea8   23 hours ago   546MB
[root@wanghe ~]# docker rmi -f $(docker images -qa) #删除全部镜像
Untagged: mysql:5.7
Untagged: mysql@sha256:e42a18d0bd0aa746a734a49cbbcc079ccdf6681c474a238d38e79dc0884e0ecc
Deleted: sha256:450379344707c56f47d1391c18fc3ac22e2c59fbf384a0de77f2bdfc59bcbc61
Deleted: sha256:f524a8b23a8a8a9d862f6c0251b19365eda045117dae4f82bd9f16edcaf31402
Deleted: sha256:c18828290fa30349004e01790ede1117f82dd6ea26a74c83a6e985c7a3ffafdd
Deleted: sha256:33db070b2792af524b7a61a855835c813f3b06178d6103766a5c90024fe25a76
Deleted: sha256:556286c5cd9dae96e08fbef933278ca181e296098ee44ca083891e5739a87fdc
Untagged: mysql:latest
Untagged: mysql@sha256:6e0014cdd88092545557dee5e9eb7e1a3c84c9a14ad2418d5f2231e930967a38
Deleted: sha256:cbe8815cbea8fb86ce7d3169a82d05301e7dfe1a8d4228941f23f4f115a887f2
Deleted: sha256:c74b92ab7fde96874c2f7afa77e338ebe739b829f5cb28a9975c9b0dcb47feb9
Deleted: sha256:fded7187915726c2d2d18c8178cd70ab9aceab27f49a68ead928a662664b9402
Deleted: sha256:217ef0e6aab8111068df664529c4bdcfc2b58701913028fd0d61b00265ad5a9b
Deleted: sha256:1ab4dbca7ef7a8eb6f7ea8ddd780b5d55aac2a0098f2c217c68e31216a2de140
Deleted: sha256:1fbdda78e87b76772be16bd4a745db7f95d9af70d5a3728260548380121ae711
Deleted: sha256:cd35e2328f0670969657f1abae8beffbc1eb1fddbaf667e1e6e6286598500a35
Deleted: sha256:068b92efc0504adcd3c23f16fde80775a2f4dfe485e242206f638eae72c4fa1b
Deleted: sha256:7c8818a166d9666c68fcdbe421c30568d60d51a505e540f42901664113047a75
Deleted: sha256:5aa8f65565168fd7db2aa6b9f8fb1db746aa598fa3854dcbdbb49d5a29f6d8a5
Deleted: sha256:cca9d1bafa1ee67bb4d7178732c0955a40a5dea6e5b989f61248984f26f7306b
Deleted: sha256:34ca91e79c4027120ca740231d415c739cccad57d1ee68d6a6e67ca60bbaf3a4
Deleted: sha256:7e718b9c0c8c2e6420fe9c4d1d551088e314fe923dce4b2caf75891d82fb227d
[root@wanghe ~]# docker images -a                  
REPOSITORY   TAG       IMAGE ID   CREATED   SIZE
[root@wanghe ~]# 

3.3 容器命令

docker run 镜像id #新建容器并启动
docker ps 列出所有运行的容器 docker container list
docker rm 容器id #删除指定容器

docker start 容器id    #启动容器
docker restart 容器id    #重启容器
docker stop 容器id    #停止当前正在运行的容器
docker kill 容器id    #强制停止当前容器

3.3.1 创建命令

#首先查询docker的镜像
[root@wanghe ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
centos       latest    300e315adb2f   4 months ago   209MB
#然后通过docker run命令创建并启动容器
[root@wanghe ~]# docker run -it centos /bin/bash
#容器成功启动,用户名已经发生变化。
[root@32a64d5850e4 /]# 

docker run [可选参数] image | docker container run [可选参数] image 
#参书说明
--name="Name"       #容器名字 tomcat01 tomcat02 用来区分容器
-d                  #后台方式运行
-it                 #使用交互方式运行,进入容器查看内容
-p                  #指定容器的端口 -p 8080(宿主机):8080(容器)
        -p ip:主机端口:容器端口
        -p 主机端口:容器端口(常用)
        -p 容器端口
        容器端口
-P(大写)                 随机指定端口

3.3.2 查询运行容器命令

docker ps 命令          #列出当前正在运行的容器
  -a, --all          #列出当前正在运行的容器 + 带出历史运行过的容器
  -n=?, --last int   #列出最近创建的?个容器 ?为1则只列出最近创建的一个容器,为2则列出2个
  -q, --quiet        #只列出容器的编号

3.3.3 退出容器命令

docker ps 命令          #列出当前正在运行的容器
  -a, --all          #列出当前正在运行的容器 + 带出历史运行过的容器
  -n=?, --last int   #列出最近创建的?个容器 ?为1则只列出最近创建的一个容器,为2则列出2个
  -q, --quiet        #只列出容器的编号

3.3.4 启动停止重启命令

docker start 容器id      #启动容器
docker restart 容器id    #重启容器
docker stop 容器id       #停止当前正在运行的容器
docker kill 容器id       #强制停止当前容器

3.4 其他常用命令

3.4.1 后台启动命令

#docker run -d 镜像名
[root@wanghe opt]# docker run -d centos
2dc48343f669feb442510df5abafdd8440b94ae44f4fa94dd7f62378789c63d0
#docker ps命令查询并没有发现正在运行的容器
[root@wanghe opt]# docker ps 
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
#查询所以容器的时候才发现有
[root@wanghe opt]# docker ps -a 
CONTAINER ID   IMAGE     COMMAND       CREATED          STATUS                      PORTS     NAMES
2dc48343f669   centos    "/bin/bash"   12 seconds ago   Exited (0) 12 seconds ago             inspiring_agnesi
[root@wanghe opt]# 
#问题:
#docker容器在后台运行之后,就必须在有一个前台程序在运行,换句话来说,这个容器得有事干,docker发现没有营养,就会自动停止容器的运行。

3.4.2 查看日志

#docker logs [参数] <镜像ID>
[root@wanghe opt]# docker logs --help

Usage:  docker logs [OPTIONS] CONTAINER

Fetch the logs of a container

Options:
      --details        #显示提供给日志的其他详细信息
  -f, --follow         #跟随日志输出
      --since string   #显示自时间戳记(例如2013-01-02T13:23:37Z)或相对时间戳记以来的日志(例如42m,持续42分钟)
  -n, --tail string    #从日志末尾开始显示的行数(默认为“ all”)
  -t, --timestamps     #显示时间戳
      --until string   #在时间戳(例如2013-01-02T13:23:37Z)或相对(例如42m持续42分钟)之前显示日志
[root@wanghe opt]# 

3.4.3 查看容器中进程的信息

#  docker top <容器ID>

3.4.4 查看镜像的元数据

#docker inspect <容器ID>
[root@wanghe opt]# docker inspect 2dc48343f669
[
    {
        "Id": "2dc48343f669feb442510df5abafdd8440b94ae44f4fa94dd7f62378789c63d0",
        "Created": "2021-04-14T15:07:33.60619385Z",
        "Path": "/bin/bash",
        "Args": [],
        "State": {
            "Status": "exited",
            "Running": false,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 0,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2021-04-14T15:07:33.931582498Z",
            "FinishedAt": "2021-04-14T15:07:33.945224206Z"
        },
        "Image": "sha256:300e315adb2f96afe5f0b2780b87f28ae95231fe3bdd1e16b9ba606307728f55",
        "ResolvConfPath": "/var/lib/docker/containers/2dc48343f669feb442510df5abafdd8440b94ae44f4fa94dd7f62378789c63d0/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/2dc48343f669feb442510df5abafdd8440b94ae44f4fa94dd7f62378789c63d0/hostname",
        "HostsPath": "/var/lib/docker/containers/2dc48343f669feb442510df5abafdd8440b94ae44f4fa94dd7f62378789c63d0/hosts",
        "LogPath": "/var/lib/docker/containers/2dc48343f669feb442510df5abafdd8440b94ae44f4fa94dd7f62378789c63d0/2dc48343f669feb442510df5abafdd8440b94ae44f4fa94dd7f62378789c63d0-json.log",
        "Name": "/inspiring_agnesi",
        "RestartCount": 0,
        "Driver": "overlay2",
        "Platform": "linux",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "",
        "ExecIDs": null,
        "HostConfig": {
            "Binds": null,
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {}
            },
            "NetworkMode": "default",
            "PortBindings": {},
            "RestartPolicy": {
                "Name": "no",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": null,
            "CapAdd": null,
            "CapDrop": null,
            "CgroupnsMode": "host",
            "Dns": [],
            "DnsOptions": [],
            "DnsSearch": [],
            "ExtraHosts": null,
            "GroupAdd": null,
            "IpcMode": "private",
            "Cgroup": "",
            "Links": null,
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": false,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": null,
            "UTSMode": "",
            "UsernsMode": "",
            "ShmSize": 67108864,
            "Runtime": "runc",
            "ConsoleSize": [
                0,
                0
            ],
            "Isolation": "",
            "CpuShares": 0,
            "Memory": 0,
            "NanoCpus": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": [],
            "BlkioDeviceReadBps": null,
            "BlkioDeviceWriteBps": null,
            "BlkioDeviceReadIOps": null,
            "BlkioDeviceWriteIOps": null,
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpuRealtimePeriod": 0,
            "CpuRealtimeRuntime": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": [],
            "DeviceCgroupRules": null,
            "DeviceRequests": null,
            "KernelMemory": 0,
            "KernelMemoryTCP": 0,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": null,
            "OomKillDisable": false,
            "PidsLimit": null,
            "Ulimits": null,
            "CpuCount": 0,
            "CpuPercent": 0,
            "IOMaximumIOps": 0,
            "IOMaximumBandwidth": 0,
            "MaskedPaths": [
                "/proc/asound",
                "/proc/acpi",
                "/proc/kcore",
                "/proc/keys",
                "/proc/latency_stats",
                "/proc/timer_list",
                "/proc/timer_stats",
                "/proc/sched_debug",
                "/proc/scsi",
                "/sys/firmware"
            ],
            "ReadonlyPaths": [
                "/proc/bus",
                "/proc/fs",
                "/proc/irq",
                "/proc/sys",
                "/proc/sysrq-trigger"
            ]
        },
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/2f1ebfccdf657edc3b24f81a6b5013af237da8905431d4d616f9ae4e993e93e9-init/diff:/var/lib/docker/overlay2/9857d858b6be6095671374f728eaf2e6d1ace4c52406a674315e76a54b66e5bb/diff",
                "MergedDir": "/var/lib/docker/overlay2/2f1ebfccdf657edc3b24f81a6b5013af237da8905431d4d616f9ae4e993e93e9/merged",
                "UpperDir": "/var/lib/docker/overlay2/2f1ebfccdf657edc3b24f81a6b5013af237da8905431d4d616f9ae4e993e93e9/diff",
                "WorkDir": "/var/lib/docker/overlay2/2f1ebfccdf657edc3b24f81a6b5013af237da8905431d4d616f9ae4e993e93e9/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [],
        "Config": {
            "Hostname": "2dc48343f669",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "/bin/bash"
            ],
            "Image": "centos",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {
                "org.label-schema.build-date": "20201204",
                "org.label-schema.license": "GPLv2",
                "org.label-schema.name": "CentOS Base Image",
                "org.label-schema.schema-version": "1.0",
                "org.label-schema.vendor": "CentOS"
            }
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "d6983ba816b51e81e1ce0b2793b40afba9d23438950e6343a62a8a3484d20540",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {},
            "SandboxKey": "/var/run/docker/netns/d6983ba816b5",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "",
            "Gateway": "",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "",
            "IPPrefixLen": 0,
            "IPv6Gateway": "",
            "MacAddress": "",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "8b4545b8a765fb0299eedd282ea86f737b07c7f15ec64f1cd2632514aa3c9c79",
                    "EndpointID": "",
                    "Gateway": "",
                    "IPAddress": "",
                    "IPPrefixLen": 0,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "",
                    "DriverOpts": null
                }
            }
        }
    }
]
[root@wanghe opt]# 

3.4.5 进入正在运行的容器

#第一种方式
#docker exec -it <容器ID> bash
[root@wanghe opt]# docker exec --help

Usage:  docker exec [OPTIONS] CONTAINER COMMAND [ARG...]

Run a command in a running container

Options:
  -d, --detach               #分离模式:在后台运行命令
      --detach-keys string   #覆盖用于分离容器的键序列
  -e, --env list             #设置环境变量
      --env-file list        #读取环境变量文件
  -i, --interactive          #即使未连接STDIN仍保持打开状态
      --privileged           #赋予命令扩展的特权
  -t, --tty                  #分配伪TTY
  -u, --user string          #用户名或UID(格式:<名称| uid> [:<group | gid>])
  -w, --workdir string       #容器内的工作目录
  
  #第二种方式
#  docker attache <容器ID>


#区别
#docker exec #进入当前容器后开启一个新的终端,可以在里面操作。(常用)
#docker attach # 进入容器正在执行的终端

3.4.6 从容器内拷贝文件到物理机

#docker cp <容器ID:/文件地址> <主机目的地址>
#docker cp 2dc48343f669:/opt/test.java /opt/

3.5 小结

在这里插入图片描述
命令大全

attach      Attach local standard input, output, and error streams to a running container
  #当前shell下 attach连接指定运行的镜像
  build       Build an image from a Dockerfile # 通过Dockerfile定制镜像
  commit      Create a new image from a container's changes #提交当前容器为新的镜像
  cp          Copy files/folders between a container and the local filesystem #拷贝文件
  create      Create a new container #创建一个新的容器
  diff        Inspect changes to files or directories on a container's filesystem #查看docker容器的变化
  events      Get real time events from the server # 从服务获取容器实时时间
  exec        Run a command in a running container # 在运行中的容器上运行命令
  export      Export a container's filesystem as a tar archive #导出容器文件系统作为一个tar归档文件[对应import]
  history     Show the history of an image # 展示一个镜像形成历史
  images      List images #列出系统当前的镜像
  import      Import the contents from a tarball to create a filesystem image #从tar包中导入内容创建一个文件系统镜像
  info        Display system-wide information # 显示全系统信息
  inspect     Return low-level information on Docker objects #查看容器详细信息
  kill        Kill one or more running containers # kill指定docker容器
  load        Load an image from a tar archive or STDIN #从一个tar包或标准输入中加载一个镜像[对应save]
  login       Log in to a Docker registry #
  logout      Log out from a Docker registry
  logs        Fetch the logs of a container
  pause       Pause all processes within one or more containers
  port        List port mappings or a specific mapping for the container
  ps          List containers
  pull        Pull an image or a repository from a registry
  push        Push an image or a repository to a registry
  rename      Rename a container
  restart     Restart one or more containers
  rm          Remove one or more containers
  rmi         Remove one or more images
  run         Run a command in a new container
  save        Save one or more images to a tar archive (streamed to STDOUT by default)
  search      Search the Docker Hub for images
  start       Start one or more stopped containers
  stats       Display a live stream of container(s) resource usage statistics
  stop        Stop one or more running containers
  tag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
  top         Display the running processes of a container
  unpause     Unpause all processes within one or more containers
  update      Update configuration of one or more containers
  version     Show the Docker version information
  wait        Block until one or more containers stop, then print their exit codes

四:练习

4.1 安装nginx

#1、搜索镜像,建议先去dockerhub去搜索,可以查看版本号
[root@wanghe ~]# docker search nginx
NAME                               DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
nginx                              Official build of Nginx.                        14718     [OK]       
jwilder/nginx-proxy                Automated Nginx reverse proxy for docker con…   2009                 [OK]
richarvey/nginx-php-fpm            Container running Nginx + PHP-FPM capable of…   813                  [OK]
jc21/nginx-proxy-manager           Docker container for managing Nginx proxy ho…   176                  
linuxserver/nginx                  An Nginx container, brought to you by LinuxS…   142                  
tiangolo/nginx-rtmp                Docker image with Nginx using the nginx-rtmp…   122                  [OK]
jlesage/nginx-proxy-manager        Docker container for Nginx Proxy Manager        104                  [OK]
bitnami/nginx                      Bitnami nginx Docker Image                      96                   [OK]
alfg/nginx-rtmp                    NGINX, nginx-rtmp-module and FFmpeg from sou…   91                   [OK]
jasonrivers/nginx-rtmp             Docker images to host RTMP streams using NGI…   89                   [OK]
nginxdemos/hello                   NGINX webserver that serves a simple page co…   67                   [OK]
privatebin/nginx-fpm-alpine        PrivateBin running on an Nginx, php-fpm & Al…   52                   [OK]
nginx/nginx-ingress                NGINX Ingress Controller for Kubernetes         50                   
nginxinc/nginx-unprivileged        Unprivileged NGINX Dockerfiles                  32                   
staticfloat/nginx-certbot          Opinionated setup for automatic TLS certs lo…   20                   [OK]
schmunk42/nginx-redirect           A very simple container to redirect HTTP tra…   19                   [OK]
nginx/nginx-prometheus-exporter    NGINX Prometheus Exporter                       16                   
centos/nginx-112-centos7           Platform for running nginx 1.12 or building …   15                   
centos/nginx-18-centos7            Platform for running nginx 1.8 or building n…   13                   
bitwarden/nginx                    The Bitwarden nginx web server acting as a r…   11                   
flashspys/nginx-static             Super Lightweight Nginx Image                   10                   [OK]
bitnami/nginx-ingress-controller   Bitnami Docker Image for NGINX Ingress Contr…   8                    [OK]
mailu/nginx                        Mailu nginx frontend                            8                    [OK]
ansibleplaybookbundle/nginx-apb    An APB to deploy NGINX                          2                    [OK]
wodby/nginx                        Generic nginx                                   1                    [OK]

#2、拉取镜像,我已经下载过了,没有下载的会显示下载的过程。
[root@wanghe ~]# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
Digest: sha256:75a55d33ecc73c2a242450a9f1cc858499d468f077ea942867e662c247b5e412
Status: Image is up to date for nginx:latest
docker.io/library/nginx:latest

#3、查看是否下载镜像成功
[root@wanghe ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
nginx        latest    62d49f9bab67   2 days ago     133MB
tomcat       9.0       bd431ca8553c   5 days ago     667MB
tomcat       latest    bd431ca8553c   5 days ago     667MB
centos       latest    300e315adb2f   4 months ago   209MB
#通过查看,发现已经拉取成功。

#4、运行容器
#解释命令
-d     后台运行
--name 设置容器的民资
-p     设置内外端口映射
[root@wanghe ~]# docker run -d --name nginx001 -p 1234:80 nginx
2c6295b0e538f043033c829ae378a69d46f2aab680740428e6aeb4b9b3c5b73a
[root@wanghe ~]# docker ps 
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                  NAMES
2c6295b0e538   nginx     "/docker-entrypoint.…"   6 seconds ago   Up 5 seconds   0.0.0.0:1234->80/tcp   nginx001
[root@wanghe ~]# 
#现在可以通过浏览器访问宿主机的1234端口,查看是否安装成功。

在这里插入图片描述
4.2 安装tomcat

#官方测试命令,docker run -it --rm tomcat:9.0 用完就删除。
#1、查看镜像,建议官方查询。
[root@wanghe ~]# docker search tomcat 
NAME                          DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
tomcat                        Apache Tomcat is an open source implementati…   2997      [OK]       
tomee                         Apache TomEE is an all-Apache Java EE certif…   86        [OK]       
dordoka/tomcat                Ubuntu 14.04, Oracle JDK 8 and Tomcat 8 base…   57                   [OK]
bitnami/tomcat                Bitnami Tomcat Docker Image                     37                   [OK]
kubeguide/tomcat-app          Tomcat image for Chapter 1                      30                   
consol/tomcat-7.0             Tomcat 7.0.57, 8080, "admin/admin"              18                   [OK]
cloudesire/tomcat             Tomcat server, 6/7/8                            15                   [OK]
aallam/tomcat-mysql           Debian, Oracle JDK, Tomcat & MySQL              13                   [OK]
arm32v7/tomcat                Apache Tomcat is an open source implementati…   10                   
rightctrl/tomcat              CentOS , Oracle Java, tomcat application ssl…   6                    [OK]
unidata/tomcat-docker         Security-hardened Tomcat Docker container.      5                    [OK]
arm64v8/tomcat                Apache Tomcat is an open source implementati…   3                    
amd64/tomcat                  Apache Tomcat is an open source implementati…   2                    
cfje/tomcat-resource          Tomcat Concourse Resource                       2                    
jelastic/tomcat               An image of the Tomcat Java application serv…   2                    
fabric8/tomcat-8              Fabric8 Tomcat 8 Image                          2                    [OK]
camptocamp/tomcat-logback     Docker image for tomcat with logback integra…   1                    [OK]
picoded/tomcat7               tomcat7 with jre8 and MANAGER_USER / MANAGER…   1                    [OK]
oobsri/tomcat8                Testing CI Jobs with different names.           1                    
chenyufeng/tomcat-centos      tomcat基于centos6的镜像                              1                    [OK]
99taxis/tomcat7               Tomcat7                                         1                    [OK]
ppc64le/tomcat                Apache Tomcat is an open source implementati…   1                    
secoresearch/tomcat-varnish   Tomcat and Varnish 5.0                          0                    [OK]
softwareplant/tomcat          Tomcat images for jira-cloud testing            0                    [OK]
s390x/tomcat                  Apache Tomcat is an open source implementati…   0                    
#2、拉取镜像。我这里已经拉取完成。未拉取的显示的结果不同。
[root@wanghe ~]# docker pull tomcat
Using default tag: latest
latest: Pulling from library/tomcat
Digest: sha256:a655be865e9f62d6d2ed3823c7382a2d77d0a034eb17714bbf2a514c3f620717
Status: Image is up to date for tomcat:latest
docker.io/library/tomcat:latest

#3、运行容器
[root@wanghe ~]# docker run -d --name tomcat001 -p 8888:8080 tomcat 
a0bd3383350fbfc059da0afcdc4983e8dfbb4bdaf6489f1d15d36f66e3c18974
[root@wanghe ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                    NAMES
a0bd3383350f   tomcat    "catalina.sh run"        5 seconds ago    Up 4 seconds    0.0.0.0:8888->8080/tcp   tomcat001
2c6295b0e538   nginx     "/docker-entrypoint.…"   19 minutes ago   Up 19 minutes   0.0.0.0:1234->80/tcp     nginx001

#4、可以通过浏览器访问宿主机8888端口,查看是否安装成功。
#显示404,找不到我问题,但是请求可以发送的过去,这个是因为docker中的tomcat镜像属于阉割版本的进行,会删除掉没用的东西,以此来减少大小。
root@a0bd3383350f:/usr/local/tomcat# ls
BUILDING.txt  CONTRIBUTING.md  LICENSE  NOTICE  README.md  RELEASE-NOTES  RUNNING.txt  bin  conf  lib  logs  native-jni-lib  temp  webapps  webapps.dist  work
#webapps 中的文件都压缩在了webapps 中,可以进行复制操作。
root@a0bd3383350f:/usr/local/tomcat# cp -r webapps.dist/* webapps/
root@a0bd3383350f:/usr/local/tomcat# ls webapps
ROOT  docs  examples  host-manager  manager
#5、再次查看

在这里插入图片描述
4.3 安装es

#es暴露的端口多
#es 十分耗内存
#es 数据要存放到安全的位置,可以使用挂载
#1、启动es
[root@wanghe ~]# docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2
898b0929ced60268115cb7cff27e59f2f174eba217cf3747d508f64cd56db321

#2、测试是否成功
[root@wanghe ~]# curl localhost:9200
{
  "name" : "898b0929ced6",
  "cluster_name" : "docker-cluster",
  "cluster_uuid" : "YjybUfuOSGKnkeEF6_7UWg",
  "version" : {
    "number" : "7.6.2",
    "build_flavor" : "default",
    "build_type" : "docker",
    "build_hash" : "ef48eb35cf30adf4db14086e8aabd07ef6fb113f",
    "build_date" : "2020-03-26T06:34:37.794943Z",
    "build_snapshot" : false,
    "lucene_version" : "8.4.0",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}
#3、es十分耗内存,可以使用命令查看相关的资源消耗情况,但是这个查看的也比较耗资源,因为是动态刷新的
[root@wanghe ~]# docker stats 

#4、可以限制es的内存
[root@wanghe ~]# docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.6.2

安装可视化

#1、创建并运行容器Portainer
docker run -d -p 8080:9000 \
--restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portaine

#2、测试访问,设置用户名和密码就可以访问了。

镜像原理

联合文件系统

镜像是什么?

镜像是一种轻量级、可执行的独立软件保,用来打包软件运行环境和基于运行环境开发的软件,他包含运行某个软件所需的所有内容,包括代码、运行时库、环境变量和配置文件。

所有应用,直接打包docker镜像,就可以直接跑起来!

如何得到镜像

1:从远程仓库下载:
2:别人拷贝给你
3:自己制作一个镜像 DockerFile

Docker镜像加载原理

UnionFs (联合文件系统)

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

docker镜像加载原理

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

在这里插入图片描述

5.2 分层的理解

5.2.1 分层的镜像

[root@wanghe ~]# docker pull redis
Using default tag: latest
latest: Pulling from library/redis
f7ec5a41d630: Already exists 
a36224ca8bbd: Pull complete 
7630ad34dcb2: Pull complete 
dd0ea236b03b: Pull complete 
ed6ed4f2f5a6: Pull complete 
8788804112c6: Pull complete 
Digest: sha256:08e282682a708eb7f51b473516be222fff0251cdee5ef8f99f4441a795c335b6
Status: Downloaded newer image for redis:latest
docker.io/library/redis:latest
#在pull命令下载镜像的时候,可以发现,他是一层一层下载的。
为什么docker要采用分层结构

最大的好处,我觉得莫过于资源共享了!比如有多个镜像都从相同的Base镜像构建而来,那么宿主机只需在磁盘上保留一份base镜像,同时内存中也只需要加载一份base镜像,这样就可以为所有的容器服务了,而且镜像的每一层都可以被共享。

在这里插入图片描述

总结:

所有的 Docker镜像都起始于一个基础镜像层,当进行修改或培加新的内容时,就会在当前镜像层之上,创建新的镜像层。

举一个简单的例子,假如基于 Ubuntu Linux16.04创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加 Python包, 就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创健第三个镜像层该像当前已经包含3个镜像层,如下图所示(这只是一个用于演示的很简单的例子)。

在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点.

在这里插入图片描述

在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点非常重要。下图中举了一个简单的例子,每个镜像层包含3个文件,而镜像包含了来自两个镜像层的6个文件。

在这里插入图片描述

上图中的镜像层跟之前图中的略有区別,主要目的是便于展示文件 下图中展示了一个稍微复杂的三层镜像,在外部看来整个镜像只有6个文件,这是因为最上层中的文件7是文件5的一个更新版。

在这里插入图片描述

文种情況下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中

Docker通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统

Linux上可用的存储引撃有AUFS、 Overlay2、 Device Mapper、Btrfs以及ZFS。顾名思义,每种存储引擎都基于 Linux中对应的 件系统或者块设备技术,井且每种存储引擎都有其独有的性能特点。

Docker在 Windows上仅支持 windowsfilter 一种存储引擎,该引擎基于NTFS文件系统之上实现了分层和CoW [1]。

下图展示了与系统显示相同的三层镜像。所有镜像层堆并合井,对外提供统一的视图。

在这里插入图片描述

Docker 镜像都是只读的,当容器启动时,一个新的可写层加载到镜像的顶部!

这一层就是我们通常说的容器层,容器之下的都叫镜像层!

5.3 commit镜像练习

docker commit 提交新的副本
[root@wanghe ~]# docker commit --help

Usage:  docker commit [可选] 容器ID [目标镜像名[:TAG]]

Create a new image from a container's changes

可选:
  -a, --author string    Author(例如,“ John Hannibal Smith <hannibal@a-team.com>”)
  -c, --change list      将Dockerfile指令应用于创建的映像
  -m, --message string   提交消息
  -p, --pause            在提交过程中暂停容器(默认为true)
  [root@wanghe ~]# docker commit -m="描述信息" -a="作者" 容器id 目标镜像名:[版本TAG]

5.3.1 测试练习

#1、下载一个镜像,然后通过docker image inspect 查看他的信息。
[root@iz2zeeijm8to1vtwwh3visz ~]# docker image inspect tomcat
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:e2c6ff46235709f5178ab7c1939f4fba7237ffde84e13b1582fa5f0837c1d978",
                "sha256:26270c5e25fa4569f37428604f708f8863a171ec2499a066241a641017971308",
                "sha256:a42439ce96509df457152574716e3c07a8d5640fe9c16f5d4fb8854f72ce357a",
                "sha256:5d5962699bd5f016d81fc6d623cb0bc1f3853efdc48b6958053122caffc425de",
                "sha256:26863b4714ee050f833364c81528e499eeff4f778cde2064e2db4cb24b289f08",
                "sha256:e8ef11c449dc031843c8689705b8348da5931ae611b46bfaceaa974b7832fe43",
                "sha256:825d742348a7bd1509510b17a2ffcdedfbd601f2f06e27441c048edd24d76e40",
                "sha256:7d8560b35c34638f13784a532581d1741f21a4f8f313f6715f127f7a22612983",
                "sha256:447f25b09d03785e0c1a5bd581d2f2880fe315e2e5f3e78f02f7d2fb224a1ad4",
                "sha256:bc7727a11f1ace90fd41701385cdd08659866de174873a3e3b550dcab1d717db"
            ]
        },
        "Metadata": {
            "LastTagTime": "0001-01-01T00:00:00Z"
        }
    }
]

#2、然后使用这个系统运行一个容器
docker run -d -p 8090:8080 tomcat

#3、然后进行进行简单的修改,

#4、然后提交容器成为新的副本
docker commit -m="描述信息" -a="作者" 容器id 目标镜像名:[TAG]
docker commit -a="wanghe" -m="add webapps" 387e7e1d0505 tomcat01:1.0

#5、查新新的镜像
[root@iz2zeeijm8to1vtwwh3visz ~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
tomcat01      1.0       0dec2301f31a   6 minutes ago   672MB
tomcat        latest    bd431ca8553c   6 days ago      667MB
hello-world   latest    d1165f221234   6 weeks ago     13.3kB

#6、使用docker image inspect 0dec2301f31a查看新的镜像
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:e2c6ff46235709f5178ab7c1939f4fba7237ffde84e13b1582fa5f0837c1d978",
                "sha256:26270c5e25fa4569f37428604f708f8863a171ec2499a066241a641017971308",
                "sha256:a42439ce96509df457152574716e3c07a8d5640fe9c16f5d4fb8854f72ce357a",
                "sha256:5d5962699bd5f016d81fc6d623cb0bc1f3853efdc48b6958053122caffc425de",
                "sha256:26863b4714ee050f833364c81528e499eeff4f778cde2064e2db4cb24b289f08",
                "sha256:e8ef11c449dc031843c8689705b8348da5931ae611b46bfaceaa974b7832fe43",
                "sha256:825d742348a7bd1509510b17a2ffcdedfbd601f2f06e27441c048edd24d76e40",
                "sha256:7d8560b35c34638f13784a532581d1741f21a4f8f313f6715f127f7a22612983",
                "sha256:447f25b09d03785e0c1a5bd581d2f2880fe315e2e5f3e78f02f7d2fb224a1ad4",
                "sha256:bc7727a11f1ace90fd41701385cdd08659866de174873a3e3b550dcab1d717db",
                "sha256:e4e93a7b40876a385a2f8ecd49acebf4d101891d9e863a174303746ea2bbfbee"
            ]
        },
        "Metadata": {
            "LastTagTime": "2021-04-17T15:33:24.118188706+08:00"
        }
    }
]

#7、通过对比发现,新的镜像比原来的多了一层。

六:容器数据卷

6.1 什么容器数据卷

将应用和环境打包成一个镜像!
数据?如果数据都在容器中,那么我们容器删除,数据就会丢失!需求:数据可以持久化
MySQL,容器删除了,删库跑路!需求:MySQL数据可以存储在本地!
容器之间可以有一个数据共享的技术!Docker容器中产生的数据,同步到本地!
这就是卷技术!目录的挂载,将我们容器内的目录,挂载到Linux上面!

在这里插入图片描述
总结一句话:容器的持久化和同步操作!容器间也是可以数据共享的!

6.2 使用数据卷

6.2.1 使用命令挂载

-v, --volume list                    Bind mount a volume

docker run -it -v 主机目录:容器内目录  -p 主机端口:容器内端口
# /home/ceshi:主机home目录下的ceshi文件夹  映射:centos容器中的/home
[root@iz2zeak7 home]# docker run -it -v /home/ceshi:/home centos /bin/bash
#这时候主机的/home/ceshi文件夹就和容器的/home文件夹关联了,二者可以实现文件或数据同步了

#通过 docker inspect 容器id 查看
[root@iz2zeak7sgj6i7hrb2g862z home]# docker inspect 6064c490c371

再来测试!

1、停止容器

2、宿主机修改文件

3、启动容器

4、容器内的数据依旧是同步的

好处:我们以后修改只需要在本地修改即可,容器内会自动同步!

6.3 实战:mysql

#1、首先先查询镜像
[root@iz2zeeijm8to1vtwwh3visz ~]# docker search mysql

#2、下载所需要的镜像
docker pull mysql:5.7

#3、参考官网的运行命令
docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag

#4、设置自己的运行命令
[root@iz2zeeijm8to1vtwwh3visz ~]# docker run -d -p 8081:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql001 mysql:5.7
16eb6d51148c55bb632c02782f550772ca9dfdfae592e63458f6476c664d6c68
-d 后台运行
-p 端口映射
-v 卷挂载
-e 环境配置
-- name 容器名字

在这里插入图片描述

#删除容器,查看本机的卷会不会消失
[root@iz2zeeijm8to1vtwwh3visz ~]# docker ps 
CONTAINER ID   IMAGE       COMMAND                  CREATED              STATUS              PORTS                                                  NAMES
16eb6d51148c   mysql:5.7   "docker-entrypoint.s…"   About a minute ago   Up About a minute   33060/tcp, 0.0.0.0:8081->3306/tcp, :::8081->3306/tcp   mysql001
[root@iz2zeeijm8to1vtwwh3visz ~]# docker rm -f 16eb6d51148c
16eb6d51148c
[root@iz2zeeijm8to1vtwwh3visz ~]# cd /home/mysql/data/
[root@iz2zeeijm8to1vtwwh3visz data]# ll
total 188476
-rw-r----- 1 systemd-bus-proxy input       56 Apr 18 10:10 auto.cnf
-rw------- 1 systemd-bus-proxy input     1676 Apr 18 10:10 ca-key.pem
-rw-r--r-- 1 systemd-bus-proxy input     1112 Apr 18 10:10 ca.pem
-rw-r--r-- 1 systemd-bus-proxy input     1112 Apr 18 10:10 client-cert.pem
-rw------- 1 systemd-bus-proxy input     1676 Apr 18 10:10 client-key.pem
-rw-r----- 1 systemd-bus-proxy input     1359 Apr 18 10:10 ib_buffer_pool
-rw-r----- 1 systemd-bus-proxy input 79691776 Apr 18 10:54 ibdata1
-rw-r----- 1 systemd-bus-proxy input 50331648 Apr 18 10:54 ib_logfile0
-rw-r----- 1 systemd-bus-proxy input 50331648 Apr 18 10:10 ib_logfile1
-rw-r----- 1 systemd-bus-proxy input 12582912 Apr 18 10:54 ibtmp1
drwxr-x--- 2 systemd-bus-proxy input     4096 Apr 18 10:10 mysql
drwxr-x--- 2 systemd-bus-proxy input     4096 Apr 18 10:10 performance_schema
-rw------- 1 systemd-bus-proxy input     1676 Apr 18 10:10 private_key.pem
-rw-r--r-- 1 systemd-bus-proxy input      452 Apr 18 10:10 public_key.pem
-rw-r--r-- 1 systemd-bus-proxy input     1112 Apr 18 10:10 server-cert.pem
-rw------- 1 systemd-bus-proxy input     1676 Apr 18 10:10 server-key.pem
drwxr-x--- 2 systemd-bus-proxy input    12288 Apr 18 10:10 sys
总结:删除之后我们挂载在本地的数据卷依然没有丢失,实现了容器数据的持久化。

6.4 具名挂载和匿名挂载

# 匿名挂载
-v 容器内路径!
$ docker run -d -P --name nginx01 -v /etc/nginx nginx

# 查看所有的volume(卷)的情况
$ docker volume ls    
DRIVER              VOLUME NAME # 容器内的卷名(匿名卷挂载)
local               21159a8518abd468728cdbe8594a75b204a10c26be6c36090cde1ee88965f0d0
local               b17f52d38f528893dd5720899f555caf22b31bf50b0680e7c6d5431dbda2802c
         
# 这里发现,这种就是匿名挂载,我们在 -v只写了容器内的路径,没有写容器外的路径!

# 具名挂载 -P:表示随机映射端口
$ docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
9663cfcb1e5a9a1548867481bfddab9fd7824a6dc4c778bf438a040fe891f0ee

# 查看所有的volume(卷)的情况
$ docker volume ls                  
DRIVER              VOLUME NAME
local               21159a8518abd468728cdbe8594a75b204a10c26be6c36090cde1ee88965f0d0
local               b17f52d38f528893dd5720899f555caf22b31bf50b0680e7c6d5431dbda2802c
local               juming-nginx #多了一个名字


# 通过 -v 卷名:查看容器内路径
# 查看一下这个卷
$ docker volume inspect juming-nginx
[
    {
        "CreatedAt": "2020-05-23T13:55:34+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data", #默认目录
        "Name": "juming-nginx",
        "Options": null,
        "Scope": "local"
    }
]

所有的docker容器内的卷,没有指定目录的情况下都是在****/var/lib/docker/volumes/自定义的卷名/_data下, 如果指定了目录,docker volume ls 是查看不到的。

# 三种挂载: 匿名挂载、具名挂载、指定路径挂载
-v 容器内路径			#匿名挂载
-v 卷名:容器内路径		  #具名挂载
-v /宿主机路径:容器内路径 #指定路径挂载 docker volume ls 是查看不到的

6.4.1 拓展

# 通过 -v 容器内路径: ro rw 改变读写权限
ro #readonly 只读
rw #readwrite 可读可写
$ docker run -d -P --name nginx05 -v juming:/etc/nginx:ro nginx
$ docker run -d -P --name nginx05 -v juming:/etc/nginx:rw nginx

# ro 只要看到ro就说明这个路径只能通过宿主机来操作,容器内部是无法操作

6.5 初次尝试DockerFile

DockerFIle就是用来构建Docker镜像的构建文件,是一个命令脚本。通过这个脚本可以生成镜像,镜像时一层一层的,脚本就是一个一个命令,每个命令都是一层。
#1、编写一个dockerfile文件
[root@iz2zeeijm8to1vtwwh3visz dockerfile]# cat dockerfile01 
FROM centos

VOLUME ["volume01","volume02"]

CMD echo "-----------end---------------"
CMD /bin/bash

#2、通过docker duild命令构建docker镜像
docker build -f dockerfile01 -t wanghe/centos .
-f dockerfile1 			# f代表file,指这个当前文件的地址(这里是当前目录下的dockerfile1)
-t wanghe/centos 	# t就代表target,指目标目录(注意wanghe镜像名前不能加斜杠‘/’)
. 						# 表示生成在当前目录下

#3、查看自己构建的镜像
[root@iz2zeeijm8to1vtwwh3visz dockerfile]# docker images
REPOSITORY      TAG       IMAGE ID       CREATED          SIZE
wanghe/centos   latest    d42e504c82db   15 minutes ago   209MB
tomcat01        1.0       0dec2301f31a   20 hours ago     672MB
nginx           latest    62d49f9bab67   4 days ago       133MB
tomcat          latest    bd431ca8553c   7 days ago       667MB
mysql           5.7       450379344707   7 days ago       449MB
mysql           latest    cbe8815cbea8   7 days ago       546MB
hello-world     latest    d1165f221234   6 weeks ago      13.3kB
centos          latest    300e315adb2f   4 months ago     209MB

#4、使用自己构建的镜像创建容器
[root@iz2zeeijm8to1vtwwh3visz dockerfile]# docker run -it wanghe/centos /bin/bash
[root@7d7b052bc21e /]# [root@iz2zeeijm8to1vtwwh3visz dockerfile]# docker run -it wanghe/centos /bin/bash^C
[root@iz2zeeijm8to1vtwwh3visz dockerfile]# docker ps 
CONTAINER ID   IMAGE           COMMAND       CREATED          STATUS          PORTS     NAMES
7d7b052bc21e   wanghe/centos   "/bin/bash"   10 seconds ago   Up 8 seconds              goofy_zhukovsky
e8a6bbb9c57f   wanghe/centos   "/bin/bash"   16 minutes ago   Up 16 minutes             loving_villani

#5、查看容器的卷
[root@iz2zeeijm8to1vtwwh3visz dockerfile]# docker inspect 7d7b052bc21e

 "Mounts": [
            {
                "Type": "volume",
                "Name": "1102f8912918c1fa9f03b3ee2f5492a24f7c5b14b6b74e6bdf68cb360af573df",
                "Source": "/var/lib/docker/volumes/1102f8912918c1fa9f03b3ee2f5492a24f7c5b14b6b74e6bdf68cb360af573df/_data",
                "Destination": "volume01",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            },
            {
                "Type": "volume",
                "Name": "db51e539f0bb8c0142ea74d5f19ea4a606b98e1bdf77552a4c3398c8c2552c3c",
                "Source": "/var/lib/docker/volumes/db51e539f0bb8c0142ea74d5f19ea4a606b98e1bdf77552a4c3398c8c2552c3c/_data",
                "Destination": "volume02",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ]

6.6 volumes-from

--volumes-from

七:Dockerfile

Dockerfile是用来构建docker镜像的文件,命令参数脚本。

1、编写一个Dockerfile文件

2、docker bilud构建成为一个镜像

3、docker run运行镜像成为容器

4、docker push 发布镜像

7.1 查看官方的Dockerfile

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

官方镜像基本用的都是基础包,很多的功能都没有,需要我们自己来安装功能。

7.2 Dockerfile构建过程

基础知识:

1:每个保留关键字(指令)都是大写。(Dockerfile指令是忽略大小写的,建议使用大写)
2:执行顺序从上到下。
3:#表示注释
4:每个指令都会创建提交一个新的镜像层,并提交

在这里插入图片描述

FROM(指定基础image)
    # 构建指令,必须指定且需要在Dockerfile其他指令的前面。后续的指令都依赖于该指令指定的image。FROM指令指定的基础image可以是官方远程仓库中的,也可以位于本地仓库的tag版本。
    FROM <image>:<tag>
 
    FROM hub.c.163.com/netease_comb/debian:7.9
 
USER (设置指令,设置启动容器的用户,默认是root用户)
    # 指定memcached的运行用户
    ENTRYPOINT ["memcached"]
    USER daemon
    或
    ENTRYPOINT ["memcached", "-u", "daemon"]
 
 
 
MAINTAINER(用来指定镜像创建者信息)
    # 构建指令,用于将image的制作者相关的信息写入到image中。当我们对该image执行docker inspect命令时,输出中有相应的字段记录该信息。
    MAINTAINER <name>
 
    MAINTAINER Alenx
 
 
RUN(安装软件用)
    # 构建指令,RUN可以运行任何被基础image支持的命令。如基础image选择了ubuntu,那么软件管理部分只能使用ubuntu的命令。
    RUN <command> (the command is run in a shell - `/bin/sh -c`)
    RUN ["executable", "param1", "param2" ... ]  (exec form)
 
    RUN apt-get install -y openssh-server apt-utils tomcat7
    RUN rm -rf /var/lib/apt/lists/*
 
 
CMD(设置container启动时执行的操作)
    # 设置指令,用于container启动时指定的操作。该操作可以是执行自定义脚本,也可以是执行系统命令。该指令只能在文件中存在一次,如果有多个,则只执行最后一条。
    CMD ["executable","param1","param2"] (like an exec, this is the preferred form)
    CMD command param1 param2 (as a shell)
    CMD ["param1","param2"] (as default parameters to ENTRYPOINT)
 
    CMD echo hello world
 
ENTRYPOINT(设置container启动时执行的操作)
    # 设置指令,指定容器启动时执行的命令,可以多次设置,但是只有最后一个有效
    # 该指令的使用分为两种情况,一种是独自使用,另一种和CMD指令配合使用。当独自使用时,如果你还使用了CMD命令且CMD是一个完整的可执行的命令,那么CMD指令和ENTRYPOINT会互相覆盖只有最后一个CMD或者ENTRYPOINT有效。
    ENTRYPOINT ["executable", "param1", "param2"] (like an exec, the preferred form)
    ENTRYPOINT command param1 param2 (as a shell)
 
    # CMD指令将不会被执行,只有ENTRYPOINT指令被执行
    CMD echo “Hello, World!”
    ENTRYPOINT ls -l
 
    # 另一种用法和CMD指令配合使用来指定ENTRYPOINT的默认参数,这时CMD指令不是一个完整的可执行命令,仅仅是参数部分;ENTRYPOINT指令只能使用JSON方式指定执行命令,而不能指定参数
    FROM ubuntu
    CMD ["-l"]
    ENTRYPOINT ["/usr/bin/ls"]
 
 
EXPOSE(指定容器需要映射到宿主机器的端口)
    """
        设置指令,该指令会将容器中的端口映射成宿主机器中的某个端口。当你需要访问容器的时候,可以不是用容器的IP地址而是使用宿主机器的IP地址和映射后的端口。
        要完成整个操作需要两个步骤,首先在Dockerfile使用EXPOSE设置需要映射的容器端口,然后在运行容器的时候指定-p选项加上EXPOSE设置的端口,这样EXPOSE设置的端口号会被随机映射成宿主机器中的一个端口号。
        也可以指定需要映射到宿主机器的那个端口,这时要确保宿主机器上的端口号没有被使用。EXPOSE指令可以一次设置多个端口号,相应的运行容器的时候,可以配套的多次使用-p选项。
        端口映射是docker比较重要的一个功能,原因在于我们每次运行容器的时候容器的IP地址不能指定而是在桥接网卡的地址范围内随机生成的。
        宿主机器的IP地址是固定的,我们可以将容器的端口的映射到宿主机器上的一个端口,免去每次访问容器中的某个服务时都要查看容器的IP的地址。
        对于一个运行的容器,可以使用docker port加上容器中需要映射的端口和容器的ID来查看该端口号在宿主机器上的映射端口
    """
    EXPOSE <port> [<port>...]
 
    # 映射一个端口
    EXPOSE port1
    # 相应的运行容器使用的命令
    docker run -p port1 image
    # 映射多个端口
    EXPOSE port1 port2 port3
    # 相应的运行容器使用的命令
    docker run -p port1 -p port2 -p port3 image
    # 还可以指定需要映射到宿主机器上的某个端口号
    docker run -p host_port1:port1 -p host_port2:port2 -p host_port3:port3 image
    docker run -d -p 127.0.0.1:33301:22 centos6-ssh
 
 
ENV(用于设置环境变量)
    # 构建指令,在image中设置一个环境变量
    ENV <key> <value>
 
    # 设置了后,后续的RUN命令都可以使用,container启动后,可以通过docker inspect查看这个环境变量,也可以通过在docker run --env key=value时设置或修改环境变量。
    # 假如你安装了JAVA程序,需要设置JAVA_HOME,那么可以在Dockerfile中这样写:
    ENV JAVA_HOME /path/to/java/dirent
 
ADD(从src复制文件到container的dest路径
    """
        构建指令,所有拷贝到container中的文件和文件夹权限为0755,uid和gid为0;如果是一个目录,那么会将该目录下的所有文件添加到container中,不包括目录;
        如果文件是可识别的压缩格式,则docker会帮忙解压缩(注意压缩格式);如果<src>是文件且<dest>中不使用斜杠结束,则会将<dest>视为文件,<src>的内容会写入<dest>;
        如果<src>是文件且<dest>中使用斜杠结束,则会<src>文件拷贝到<dest>目录下
    """
    ADD <src> <dest>
    # <src> 是相对被构建的源目录的相对路径,可以是文件或目录的路径,也可以是一个远程的文件url;
    # <dest> 是container中的绝对路径
 
 
VOLUME(指定挂载点)
    """
        设置指令,使容器中的一个目录具有持久化存储数据的功能,该目录可以被容器本身使用,也可以共享给其他容器使用。
        我们知道容器使用的是AUFS,这种文件系统不能持久化数据,当容器关闭后,所有的更改都会丢失。当容器中的应用有持久化数据的需求时可以在Dockerfile中使用该指令。
    """
    VOLUME ["<mountpoint>"]
 
    FROM base
    VOLUME ["/tmp/data"]
 
 
WORKDIR(切换目录)
    # 设置指令,可以多次切换(相当于cd命令),对RUN,CMD,ENTRYPOINT生效。
    WORKDIR /path/to/workdir
 
    # 在 /p1/p2 下执行 vim a.txt
    WORKDIR /p1 WORKDIR p2 RUN vim a.txt
 
 
ONBUILD(在子镜像中执行)
    # ONBUILD 指定的命令在构建镜像时并不执行,而是在它的子镜像中执行
    ONBUILD <Dockerfile关键字>
FROM				# from:基础镜像,一切从这里开始构建
MAINTAINER			# maintainer:镜像是谁写的, 姓名+邮箱
RUN					# run:镜像构建的时候需要运行的命令
ADD					# add:步骤,tomcat镜像,这个tomcat压缩包!添加内容 添加同目录
WORKDIR				# workdir:镜像的工作目录
VOLUME				# volume:挂载的目录
EXPOSE				# expose:保留端口配置
CMD					# cmd:指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT			# entrypoint:指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD				# onbuild:当构建一个被继承DockerFile这个时候就会运行onbuild的指令,触发指令
COPY				# copy:类似ADD,将我们文件拷贝到镜像中
ENV					# env:构建的时候设置环境变量!

7.3 编写自己的centos

# 1./home下新建dockerfile目录
$ mkdir dockerfile

# 2. dockerfile目录下新建mydockerfile-centos文件
$ vim mydockerfile-centos

# 3.编写Dockerfile配置文件
FROM centos							# 基础镜像是官方原生的centos
MAINTAINER yudancah<yudancah@163.com> 	# 作者

ENV MYPATH /usr/local				# 配置环境变量的目录 
WORKDIR $MYPATH						# 将工作目录设置为 MYPATH

RUN yum -y install vim				# 给官方原生的centos 增加 vim指令
RUN yum -y install net-tools		# 给官方原生的centos 增加 ifconfig命令

EXPOSE 80							# 暴露端口号为80

CMD echo $MYPATH					# 输出下 MYPATH 路径
CMD echo "-----end----"				
CMD /bin/bash						# 启动后进入 /bin/bash

# 4.通过这个文件构建镜像
# 命令: docker build -f 文件路径 -t 镜像名:[tag] .
$ docker build -f mydockerfile-centos -t mycentos:0.1 .

# 5.出现下图后则构建成功

在这里插入图片描述

[root@wanghe testcentos]# docker images
REPOSITORY            TAG       IMAGE ID       CREATED         SIZE
yudancha/centos       0.1       de4c92c974e2   5 seconds ago   291MB
nginx                 latest    62d49f9bab67   6 days ago      133MB
tomcat                9.0       bd431ca8553c   9 days ago      667MB
tomcat                latest    bd431ca8553c   9 days ago      667MB
redis                 latest    de974760ddb2   9 days ago      105MB
portainer/portainer   latest    580c0e4e98b0   4 weeks ago     79.1MB
centos                latest    300e315adb2f   4 months ago    209MB
elasticsearch         7.6.2     f29a1ee41030   13 months ago   791MB

7.4 查询镜像的构建过程

docker history [OPTIONS] IMAGE

OPTIONS说明:

**-H :**以可读的格式打印镜像大小和日期,默认为true;
**--no-trunc :**显示完整的提交记录;
**-q :**仅列出提交记录ID。

7.5 其他

CMD 和 ENTRYPOINT区别

CMD					# 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代。
ENTRYPOINT			# 指定这个容器启动的时候要运行的命令,可以追加命令、

测试CMD

# 编写dockerfile文件
$ vim dockerfile-test-cmd
FROM centos
CMD ["ls","-a"]					# 启动后执行 ls -a 命令

# 构建镜像
$ docker build  -f dockerfile-test-cmd -t cmd-test:0.1 .

# 运行镜像
$ docker run cmd-test:0.1		# 由结果可得,运行后就执行了 ls -a 命令
.
..
.dockerenv
bin
dev
etc
home

# 想追加一个命令  -l 成为ls -al:展示列表详细数据
$ docker run cmd-test:0.1 -l
docker: Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process caused "exec: "-l":
executable file not found in $PATH": unknown.
ERRO[0000] error waiting for container: context canceled 

# cmd的情况下 -l 替换了CMD["ls","-l"] 而 -l  不是命令所以报错

测试ENTRYPOINT

# 编写dockerfile文件
$ vim dockerfile-test-entrypoint
FROM centos
ENTRYPOINT ["ls","-a"]

# 构建镜像
$ docker build  -f dockerfile-test-entrypoint -t cmd-test:0.1 .

# 运行镜像
$ docker run entrypoint-test:0.1
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found ...

# 我们的命令,是直接拼接在我们得ENTRYPOINT命令后面的
$ docker run entrypoint-test:0.1 -l
total 56
drwxr-xr-x   1 root root 4096 May 16 06:32 .
drwxr-xr-x   1 root root 4096 May 16 06:32 ..
-rwxr-xr-x   1 root root    0 May 16 06:32 .dockerenv
lrwxrwxrwx   1 root root    7 May 11  2019 bin -> usr/bin
drwxr-xr-x   5 root root  340 May 16 06:32 dev
drwxr-xr-x   1 root root 4096 May 16 06:32 etc
drwxr-xr-x   2 root root 4096 May 11  2019 home
lrwxrwxrwx   1 root root    7 May 11  2019 lib -> usr/lib
lrwxrwxrwx   1 root root    9 May 11  2019 lib64 -> usr/lib64 ....

7.6 实战:Tomcat镜像

1、准备镜像文件

准备Tomcat和jdk到当前目录,编写好说明文件

在这里插入图片描述

2、编写Dockerfile

$ vim dockerfile
FROM centos 										# 基础镜像centos
MAINTAINER yudancah<yudancah@qq.com>					# 作者
COPY README /usr/local/README 						# 复制README文件
ADD jdk-8u231-linux-x64.tar.gz /usr/local/ 			# 添加jdk,ADD 命令会自动解压
ADD apache-tomcat-9.0.35.tar.gz /usr/local/ 		# 添加tomcat,ADD 命令会自动解压
RUN yum -y install vim								# 安装 vim 命令
ENV MYPATH /usr/local 								# 环境变量设置 工作目录
WORKDIR $MYPATH

ENV JAVA_HOME /usr/local/jdk1.8.0_231 				# 环境变量: JAVA_HOME环境变量
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.35 	# 环境变量: tomcat环境变量
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.35

# 设置环境变量 分隔符是:
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin 	

EXPOSE 8080 										# 设置暴露的端口

CMD /usr/local/apache-tomcat-9.0.35/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.35/logs/catalina.out 					# 设置默认命令

3、构建镜像

docker build -t mytomcat:0.1 .

4、运行镜像

docker run -d -p 8080:8080 --name tomcat01 -v /home/v/build/tomcat/test:/usr/local/apache-tomcat-9.0.45/webapps/test -v /home/v/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.45/logs mytomcat:0.1

5、测试访问

docker exec -it tomcat01 /bin/bash
cul localhost:8080 

6、测试发布文件

#进入挂载的位置
home/v/build/tomcat/test
#创建WEB-INF文件夹
mkdir WEB-INF 
cd WEB-INF
#创建配置web.xml文件
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
  version="4.0"
  metadata-complete="true">

  <display-name>Welcome to Tomcat</display-name>
  <description>
     Welcome to Tomcat
  </description>

</web-app>

#退回去创建index.jsp文件
vim index.jsp
<html>
<head><title>Hello World</title></head>
<body>
Hello World!<br/>
<%
out.println("Your IP address is " + request.getRemoteAddr());
%>
</body>
</html>

然后通过ip+8080/test进行访问

在这里插入图片描述

7.7 发布自己的镜像

发布到hub.docker.com

1、登陆自己的账号

docker login -u 用户名 -p 
[root@wanghe test]# docker login -u yudancha
Password: 
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

2、提交pull镜像

[root@wanghe test]# docker tag bda9dd116c53 yudancha/mytomcat:1.0
[root@wanghe test]# docker push yudancha/mytomcat:1.0
发布到阿里云

1、登陆账号

docker login --username=不负如来不负卿i、 registry.cn-hangzhou.aliyuncs.com
[root@wanghe test]# docker login --username=不负如来不负卿i、 registry.cn-hangzhou.aliyuncs.com
Password: 
Error response from daemon: Get https://registry.cn-hangzhou.aliyuncs.com/v2/: unauthorized: authentication required

2、提交pull镜像

docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/yudancha/docker_test:[镜像版本号]
docker push registry.cn-hangzhou.aliyuncs.com/yudancha/docker_test:[镜像版本号]
[root@wanghe test]# docker tag bda9dd116c53 registry.cn-hangzhou.aliyuncs.com/yudancha/docker_test:1.0
[root@wanghe test]# docker push registry.cn-hangzhou.aliyuncs.com/yudancha/docker_test:1.0

7.8 总结

在这里插入图片描述

八:Docker网络

8.1 理解Docker 0

[root@wanghe ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens192: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:0c:29:41:d9:bb brd ff:ff:ff:ff:ff:ff
    inet 192.168.245.88/24 brd 192.168.245.255 scope global noprefixroute ens192
       valid_lft forever preferred_lft forever
    inet6 fe80::7cbd:6b37:ee96:dca9/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:cc:94:b2:c2 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:ccff:fe94:b2c2/64 scope link 
       valid_lft forever preferred_lft forever

问题:docker是怎么处理网络连接的?
#创建一个tomcat系统的容器
[root@wanghe ~]# docker run -d -P --name tomcat01 tomcat 
ff0e8452ba2aa8383c4398df9492228d72d7f858317a77c2a4e97e36bdfa7b2b
#创建完成发现本机的ip发生一些变化,多了一些网卡。46: veth0ded54d@if45:
[root@wanghe ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens192: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:0c:29:41:d9:bb brd ff:ff:ff:ff:ff:ff
    inet 192.168.245.88/24 brd 192.168.245.255 scope global noprefixroute ens192
       valid_lft forever preferred_lft forever
    inet6 fe80::7cbd:6b37:ee96:dca9/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:cc:94:b2:c2 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:ccff:fe94:b2c2/64 scope link 
       valid_lft forever preferred_lft forever
46: veth0ded54d@if45: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether 7a:9c:d6:60:fe:6c brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::789c:d6ff:fe60:fe6c/64 scope link 
       valid_lft forever preferred_lft forever
#通过命令查询,发现容器内的网卡的名称,和本机新增的网卡名是连着的。       
[root@wanghe ~]# docker exec -t tomcat01 ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
45: eth0@if46: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

原理:

每启动一个docker容器,docker服务端就会给docker容器分配一个ip,我们安装docker的时候就会安装docker0桥接模式 使用的技术就是veth-pair

8.1.1 veth-pair是什么

顾名思义,veth-pair 就是一对的虚拟设备接口,和 tap/tun 设备不同的是,它都是成对出现的。一端连着协议栈,一端彼此相连着。

在这里插入图片描述

8.1.2 测试容器之间能不能互通

#创建一个新的容器
[root@wanghe ~]# docker run -d -P --name tomcat02 tomcat  
5c73135ac586d82151c8a84e9dee6b20ae9627fb21c76b44fcc174d6f49cbb81
#然后去ping tomcat01 
[root@wanghe ~]# docker exec -t tomcat02 ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.090 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.038 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.034 ms
64 bytes from 172.17.0.2: icmp_seq=4 ttl=64 time=0.042 ms
64 bytes from 172.17.0.2: icmp_seq=5 ttl=64 time=0.028 ms

在所有docker容器不指定网络的情况下,所有的容器都默认是使用的docker0路由,所以说都在同一个网络中,虽然容器之间有隔离,但是网络可以连通。

8.1.3 网络模型图

在这里插入图片描述

在这里插入图片描述

8.1.3.1 怎么通过容器名来进行访问–link

#通过容器的名字并没有办法直接来访问。
[root@wanghe ~]# docker exec -t tomcat02 ping tomcat01  
ping: tomcat01: Name or service not known
#创建新的容器,在创建的时候加上--link
[root@wanghe ~]# docker run -d -P --name tomcat03 --link tomcat01 tomcat
d5c115608d033b92fa1187d0a7dde20cf9199dfb7d42aa300f73806267059ccd
[root@wanghe ~]# docker exec -t tomcat03 ping tomcat01
PING tomcat01 (172.17.0.2) 56(84) bytes of data.
64 bytes from tomcat01 (172.17.0.2): icmp_seq=1 ttl=64 time=0.083 ms
64 bytes from tomcat01 (172.17.0.2): icmp_seq=2 ttl=64 time=0.030 ms
64 bytes from tomcat01 (172.17.0.2): icmp_seq=3 ttl=64 time=0.028 ms
64 bytes from tomcat01 (172.17.0.2): icmp_seq=4 ttl=64 time=0.033 ms
#原理,在hosts文件中加了映射。
[root@wanghe ~]# docker exec -t tomcat03 cat /etc/hosts
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2      tomcat01 ff0e8452ba2a
172.17.0.4      d5c115608d03
#由此可以推断出,tomcat01ping不同tomcat03的服务名
[root@wanghe ~]# docker exec -t tomcat01 ping tomcat03
ping: tomcat03: Name or service not known

–link:
本质就是在hosts配置文件中添加了映射,但是现在docker不建议添加–limke,现在都是使用自定义网络。

8.2 自定义网络

8.2. 查看命令

[root@wanghe ~]# docker network --help

Usage:  docker network COMMAND

Manage networks

Commands:
  connect     将容器连接到网络
  create      创建网络
  disconnect  断开容器与网络的连接
  inspect     检查在一个或多个网络上显示详细信息
  ls          网络清单
  prune       删除所有未使用的网络
  rm          删除一个或多个网络

Run 'docker network COMMAND --help' for more information on a command.

8.2.2 网络模式

bridge :桥接 docker(默认,自己创建也是用bridge模式)

none :不配置网络,一般不用

host :和所主机共享网络

container :容器网络连通(用得少!局限很大)

#查看网络
[root@wanghe ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
583d8557df83   bridge    bridge    local
675bb0b6600d   host      host      local
3ec386e142b2   none      null      local
#创建一个自定义的网络连接,名字叫mynet
[root@wanghe ~]# docker network create --driver bridge --subnet 192.168.8.0/16 --gateway 192.168.8.254 mynet
7880ef010068ad4fe48ef0e48c35f1da88eaa5bde3fee4937ee6523cd29edc7e
[root@wanghe ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
583d8557df83   bridge    bridge    local
675bb0b6600d   host      host      local
7880ef010068   mynet     bridge    local
3ec386e142b2   none      null      local
$ docker run -d -P --name tomcat01 tomcat
等价于 => docker run -d -P --name tomcat01 --net bridge tomcat
[root@wanghe ~]# docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "7880ef010068ad4fe48ef0e48c35f1da88eaa5bde3fee4937ee6523cd29edc7e",
        "Created": "2021-04-24T23:07:40.947472854+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.8.0/16",
                    "Gateway": "192.168.8.254"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]

8.2.3 使用自定义网络来创建容器

[root@wanghe ~]# docker run -d -P --name tomcat-net01 --net mynet tomcat 
2db6c1d58c89fec22ad6fcb74fe680daf55890454a7765ad2e234763416394a5
[root@wanghe ~]# docker run -d -P --name tomcat-net02 --net mynet tomcat  
56d706fafa8c467de15d468c4da178a031a593718332933138d19e188b8dce51
[root@wanghe ~]# docker exec -t tomcat-net01 ping tomcat-net02
PING tomcat-net02 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat-net02.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.056 ms
64 bytes from tomcat-net02.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.036 ms
64 bytes from tomcat-net02.mynet (192.168.0.2): icmp_seq=3 ttl=64 time=0.035 ms
64 bytes from tomcat-net02.mynet (192.168.0.2): icmp_seq=4 ttl=64 time=0.030 ms
#查询网络,自定义为网络已经帮我们维护好了相关的关系
[root@wanghe ~]# docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "7880ef010068ad4fe48ef0e48c35f1da88eaa5bde3fee4937ee6523cd29edc7e",
        "Created": "2021-04-24T23:07:40.947472854+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.8.0/16",
                    "Gateway": "192.168.8.254"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "2db6c1d58c89fec22ad6fcb74fe680daf55890454a7765ad2e234763416394a5": {
                "Name": "tomcat-net01",
                "EndpointID": "d96b0654f717ccba8ec46b064488449fd01beb929eea8ab2c679e24832ab67b0",
                "MacAddress": "02:42:c0:a8:00:01",
                "IPv4Address": "192.168.0.1/16",
                "IPv6Address": ""
            },
            "56d706fafa8c467de15d468c4da178a031a593718332933138d19e188b8dce51": {
                "Name": "tomcat-net02",
                "EndpointID": "cc9caa089bc98d57f4403c0e97b2a0c872609bdb6bc486fca8980694ae613aaf",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

总结:使用定义的网络时可以不用–link也可以直接使用容器名连通

8.3 不在同一路由怎么进行连接

使用docker network connect 来设置
#建立关系
[root@wanghe ~]# docker network connect mynet tomcat01
#测试连通性
[root@wanghe ~]# docker exec -t tomcat01 ping tomcat-net01
PING tomcat-net01 (192.168.0.1) 56(84) bytes of data.
64 bytes from tomcat-net01.mynet (192.168.0.1): icmp_seq=1 ttl=64 time=0.063 ms
64 bytes from tomcat-net01.mynet (192.168.0.1): icmp_seq=2 ttl=64 time=0.030 ms
64 bytes from tomcat-net01.mynet (192.168.0.1): icmp_seq=3 ttl=64 time=0.059 ms
^C
#原理
[root@wanghe ~]# docker exec -t tomcat01 ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
45: eth0@if46: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
56: eth1@if57: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:c0:a8:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 192.168.0.3/16 brd 192.168.255.255 scope global eth1
       valid_lft forever preferred_lft forever

总结:connect命令是给tomcat01容器新添加了一块虚拟网卡,让它连接到mynet网络中。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐