Docker

Docker为什么出现?

一款产品:开发到上线需要两套环境!

而一套环境配置是十分麻烦的!尤其是集群环境!费事费力!

发布一个项目:需要(jar+(Redis+mysql+jdk+es))。而且不能进行跨平台!

那么引入一个问题?

项目和环境能不能一块发布?

可以的!开发打包部署上线,一套流程做完!就是Docker提出了解决方案!

Docker运行的步骤

java -- jar(环境) ---打包项目带上环境(镜像) ---(Docker仓库:商店) --- 下载我们的镜像 ---直接运行即可!

本质:所以的技术都是因为出现了一些问题,我们才需要去学习。

Docker概述

Docker的历史

2010年,几个搞it的年轻人,在美国成立了一个公司 dotCloud。做一些pass的云计算服务,LXC有关的容器操作。他们把自己的技术,容器化技术命名Docker。

刚诞生的时候,没人关注,后来快坚持不住了,就在2013年的时候开源了!

2014年4月9日,Docker1.0发布!

Docker为什么这么火?因为轻巧。

虚拟机:我们在电脑上装一个vm软件,可以虚拟出一个或多个操作系统。

虚拟机也是属于虚拟化技术,Docker容器技术,也是一种虚拟化技术!

vm:linux centos原生镜像(就基本是一台电脑) 隔离需要开启多个虚拟机! 几个G
docker:隔离,镜像(只需要核心的环境,jdk+mysql+需要的环境)十分的小巧!几个M KB 秒级启动!

Docker官方:https://www.docker.com/

Docker Hub官方:https://hub.docker.com/(类似于GitHub)

Docker能干什么?

之前的虚拟技术

before

虚拟机技术缺点:

1、资源占用十分多

2、冗余步骤多

3、启动很慢!

现在的容器技术

now

比较Docker和传统的虚拟技术的不同:

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

DevOps(开发,运维)

应用更快速的交付和部署

传统:一堆帮助文档,安装测试

Docker:打包镜像,一键测试

更便捷的升级和扩容

使用了Docker之后,我们部署应用就和搭建积木一样!

更简单的系统运维

在容器化操作之后,我们的开发,测试环境都是高度一致。

更高效的计算机利用资源

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

Docker安装

这里发现安装失败..可以参考这个进行安装https://blog.csdn.net/weixin_45987569/article/details/108297022

Docker的基本组成

docker组成

镜像(image):

docker镜像就好比是一个模板,可以通过这个模板创建容器服务,tomcat镜像==>run-->tomcat容器(提供服务器)

通过这个镜像可以创建多个容器。

容器(container):

Docker利用容器技术,独立运行一个或者一个组应用,通过镜像来创建的。

启动,停止,删除,基本命令。目前我们就可以把这个容器理解为一个简易的linux系统。

仓库:

Docker用仓库保存用户创建的镜像,仓库分共有和私有两种,Docker公司自己提供了仓库Docker Hub,可以在Docker Hub上创建账户,保存分享自己创建的镜像。当然也可以架设私有仓库。

安装Docker

环境准备

1、Linux基础

2、Centos7

3、xshell连接服务器

查看系统内核

[root@iZ2zeeqh1fctjw2bhzgjnaZ ~]# uname -r
3.10.0-1062.12.1.el7.x86_64

安装步骤

#如果已经安装,先清除之前的
yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-selinux \
                  docker-engine-selinux \
                  docker-engine
#安装Docker
yum install -y yum-utils

#配置阿里云镜像源
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

#更新yum软件包索引
yum makecache fast

#安装docker docker-ce社区 ee企业版
yum install docker-ce-cli containerd.io

#启动docker
systemctl start docker

#使用docker version测试是否成功
docker version

如果安装不成功,无法启动,可以尝试百度中的其他方法!

检查安装是否成功

我们可以发现,我们的docker版本号,也代表启动成功了!

#运行镜像hello-world
docker run hello-world
运行Helloworld
#查看镜像源
docker images
查看镜像源

卸载docker

#1、卸载依赖
yum remove docker-ce docker-ce-cli containerd.io

#2、删除资源
rm -rf /var/lib/docker

# /var/lib/docker docker的默认工作路径

阿里云镜像加速

登录阿里云,找到容器镜像加速(这部一定要加上,否则下载镜像还是很慢!)

配置使用:4个指令

配置阿里云

我们对Docker进行如上的四个配置,致使我们的docker下载镜像时会更快!

配置

回顾HelloWorld流程

首先先去本地寻找Docker镜像,判断如果有的话就去用,如果没有就去下载到本地。

image.png

Docker是怎么工作的?

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

下载镜像示意图

Docker为什么比虚拟机快?

1、Docker有比虚拟机更少的抽象层

2、Docker用的是宿主机内核,VM需要的是Guest OS。

如何工作

由以上两点:

  • 新建一个容器的时候, docker不需要像虚拟机一样重新加载一个操作系统内核,避免引导。
  • 虚拟机是加载 Guest os,分钟级别的,而 docker是利用宿主机的操作系统吗,省略了这个复杂的过程,秒级!
对比

Docker的常用命令

帮助命令

#显示docker的版本信息
docker version
#显示docker详细的信息
docker info
#万能命令
docker 命令 -help

docker官方帮助文档:

https://docs.docker.com/engine/reference/commandline/ps/#show-both-running-and-stopped-containers

镜像命令

查看镜像
[root@iZ2zeeqh1fctjw2bhzgjnaZ ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
redis               latest              4cdbec704e47        6 weeks ago         98.2MB
hello-world         latest              bf756fb1ae65        4 months ago        13.3kB

#解释
REPOSITORY  镜像的仓库源
TAG         镜像的标签
IMAGE ID    镜像的id
CREATED     镜像的创造时间
SIZE        镜像的大小

#可选项
-a 代表 --all             #列出所有的镜像
-1 代表 --quite           #只显示镜像的id
搜索镜像
[root@iZ2zeeqh1fctjw2bhzgjnaZ ~]# docker search mysql
NAME                              DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
mysql                             MySQL is a widely used, open-source relation…   9494                [OK]                
mariadb                           MariaDB is a community-developed fork of MyS…   3441                [OK] 
#真实搜出来的很多,这里只显示两个

#可选项,通过搜索进行过滤starts大于3000的
--filter=stars=3000


[root@iZ2zeeqh1fctjw2bhzgjnaZ ~]# docker search mysql --filter=stars=3000
NAME                DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
mysql               MySQL is a widely used, open-source relation…   9494                [OK]                
mariadb             MariaDB is a community-developed fork of MyS…   3441                [OK]   
下载镜像
#下载镜像docker pull 镜像名[:tag]
[root@iZ2zeeqh1fctjw2bhzgjnaZ ~]# docker pull mysql
Using default tag: latest       #如果这里不写版本号,那么就是下载的最新版
latest: Pulling from library/mysql
5b54d594fba7: Pull complete 
07e7d6a8a868: Pull complete 
abd946892310: Pull complete 
dd8f4d07efa5: Pull complete 
076d396a6205: Pull complete 
cf6b2b93048f: Pull complete 
530904b4a8b7: Pull complete 
fb1e55059a95: Pull complete 
4bd29a0dcde8: Pull complete 
b94a001c6ec7: Pull complete 
cb77cbeb422b: Pull complete 
2a35cdbd42cc: Pull complete 
Digest: sha256:dc255ca50a42b3589197000b1f9bab2b4e010158d1a9f56c3db6ee145506f625#签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest #真实地址

#上面的命令等价于
docker pull docker.io/library/mysql:latest


#我们还可以指定下载版本,mysql5.7
[root@iZ2zeeqh1fctjw2bhzgjnaZ ~]# docker pull mysql:5.7
5.7: Pulling from library/mysql
5b54d594fba7: Already exists    #和以前共用的版本就不用下载了(联合文件)
07e7d6a8a868: Already exists 
abd946892310: Already exists 
dd8f4d07efa5: Already exists 
076d396a6205: Already exists 
cf6b2b93048f: Already exists 
530904b4a8b7: Already exists 
a37958cbebcf: Pull complete 
04960017f638: Pull complete 
e1285def0d2a: Pull complete 
670cb3a9678e: Pull complete 
Digest: sha256:e4d39b85118358ffef6adc5e8c7d00e49d20b25597e6ffdc994696f10e3dc8e2
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7

注意:下载的版本必须可以查询到,我们在docker hub进行看到

docker hub
删除镜像
[root@iZ2zeeqh1fctjw2bhzgjnaZ ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
mysql               5.7                 e73346bdf465        11 hours ago        448MB
mysql               latest              a0d4d95e478f        11 hours ago        541MB
redis               latest              4cdbec704e47        6 weeks ago         98.2MB
hello-world         latest              bf756fb1ae65        4 months ago        13.3kB

#删除镜像
[root@iZ2zeeqh1fctjw2bhzgjnaZ ~]# docker rmi -f a0d4d95e478f
Untagged: mysql:latest
Untagged: mysql@sha256:dc255ca50a42b3589197000b1f9bab2b4e010158d1a9f56c3db6ee145506f625
Deleted: sha256:a0d4d95e478ff2962ede50c50b7dc2fc699382bcb94ad301e9c6805609f0939a
Deleted: sha256:4404a13192a5c458ee1c3160b910728fc3723687a5d4c6b83481d09d6cac6e7b
Deleted: sha256:2c91a02c5543a7b08784d159b4d749d0b8c82c1dcfd8567570e8350af2d76669
Deleted: sha256:9f5911321949d1869260b9fef13ba3bea465ea8db257fdcd0193ec68db2741b0
Deleted: sha256:60023f7e525ce09db7bc5c3941cf86caef06c5fbe0bf770efb648ef73f8e705e
Deleted: sha256:44d7b6c26325a1653b5052d8c15f9086a7a952f059e33763512a668848b6961c

#我们重新查看镜像,可以发现已经删除
[root@iZ2zeeqh1fctjw2bhzgjnaZ ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
mysql               5.7                 e73346bdf465        11 hours ago        448MB
redis               latest              4cdbec704e47        6 weeks ago         98.2MB
hello-world         latest              bf756fb1ae65        4 months ago        13.3kB

#删除多个镜像
docker rmi -f 镜像id 镜像id 镜像id 镜像id

#删除全部镜像
#这里用到的思想就是docker images -aq显示所有的id,进行删除,联合删除!
docker rmi -f $(docker images -aq) 

容器命令

说明:我们有了镜像才可以创建容器,我们可以下载一个centos镜像用来学习

docker pull centos

新建容器并启动

docker run是利用镜像生成容器,并启动容器,而docker start是启动一个之前生成过的容器

docker run [可选参数] image

#参数说明
--name="Name"           #容器名字 tomcat01 tomcat02,用来区分容器
-d                      #以后台方式运行
-it                     #使用交互方式运行,进入容器查看内容
-p                      #指定容器的端口 -p 8080:8080
    -p ip:主机端口:容器端口
    -p 主机端口:容器端口(常用)
    -p 容器端口

-p   #随机指定端口


#测试 启动容器
[root@iZ2zeeqh1fctjw2bhzgjnaZ ~]# docker run -it centos /bin/bash
[root@9f938cd50b09 /]# ls #我们通过ls命令查看该centos容器下的文件夹
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
#我们可以发现这和我们自己的linux文件少了很多,正是由于它是基础版本的,所以没有正式的多

[root@9f938cd50b09 /]# exit  #从容器中退出系统
exit

#分别以3310和3311端口号运行两个tomcat容器
[root@iZ2zeeqh1fctjw2bhzgjnaZ ~]# docker run -d -p 3310:8080 --name t1 diytomcat
b912b4f691004bddadc64b511dbed6afd9d7704c1887c1a7fc03fcd3a660722a
[root@iZ2zeeqh1fctjw2bhzgjnaZ ~]# docker run -d -p 3311:8080 --name t2 diytomcat
2ee142c87ce1a6418c6f4a272e63aa95767718b445dfeef99b39824df25bf0c0

列出所有运行的内存

# 列出当前正在运行的容器
[root@iZ2zeeqh1fctjw2bhzgjnaZ ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

#列出当前正在运行的容器+列出历史运行过的容器
[root@iZ2zeeqh1fctjw2bhzgjnaZ ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
9f938cd50b09        centos              "/bin/bash"         14 minutes ago      Exited (0) 11 minutes ago                       vigilant_agnesi
bb1c862ee8df        centos              "/bin/bash"         33 minutes ago      Exited (0) 33 minutes ago                       myCentos
c0734cc4eb49        hello-world         "/hello"            2 hours ago         Exited (0) 2 hours ago                          elegant_feynman

#只显示容器的编号
docker -q

退出容器

exit #直接退出容器并且停止
ctrl + P + Q    # 容器不停止退出,后台运行

删除容器

docker rm 容器id       #删除指定的容器,但是不能删除正在运行的容器,强制删除rm -f
docker rm -f $(docker ps -aq)   #删除所有容器
docker rm -a -q|xargs docker rm #删除所有容器(这个不正确,有错误!)

启动和停止容器操作

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

docker stop $(docker ps -q) #停止全部运行的容器
docker stop $(docker ps -q) & docker rm $(docker ps -aq)    #一条命令停止并删除所有的容器

存在的几个问题:

docker run 和 docker start区别

docker run 只在第一次运行时使用,将镜像放到容器中,以后再次启动这个容器时,只需要使用命令docker start 即可。docker run相当于执行了两步操作:将镜像放入容器中(docker create),然后将容器启动,使之变成运行时容器(docker start)。

那么docker start 又和 docker restart有什么区别?

restart Restart a running container :翻译 就是百重启一度个问正在运行的答容器
start Start a stopped container :翻译就是启动版一个暂停的容器

[docker run -it centos /bin/bash 后面的 bin/bash的作用]

首先,docker run -it centos 的意思是,为centos这个镜像创建一个容器, -i和-t这两个参数的作用是,为该docker创建一个伪终端,这样就可以进入到容器的交互模式?(也就是直接进入到容器里面)后面的/bin/bash的作用是表示载入容器后运行bash ,docker中必须要保持一个进程的运行,要不然整个容器启动后就会马上kill itself,这样当你使用docker ps 查看启动的容器时,就会发现你刚刚创建的那个容器并不在已启动的容器队列中。这个/bin/bash就表示启动容器后启动bash。

表示当前用户使用的shell是/bin/bash,所谓的shell你可以理解为操作系统和人之间交互的平台。例如windows系统的桌面环境就是一个shell。
bin目录中基本上都是可执行的命令。

几个启动容器问题

https://www.cnblogs.com/doraman/p/12176888.html

常用其他命令

后台启动容器:

# 命令 docker run -d 镜像名
[root@iZ2zeeqh1fctjw2bhzgjnaZ ~]# docker run -d centos
a85212f28e0b80f04ca85cb630a781de3a5e7a1e8f1ef5bdddb329303675b306
[root@iZ2zeeqh1fctjw2bhzgjnaZ ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

#但是!我们发现问题了!我们通过docker ps命令并没有发现centos正在运行
#原因?容器使用后台进行,就必须需要一个前台进程,docker如果发现没有应用就会自动停止!

查看日志:

docker logs -f -t --tail    容器id

#自己编写一段shell脚本,不停的循环输出szw
docker run -d centos /bin/sh -c "while true;echo szw;sleep 1;done"

#这时候再显示日志
docker logs -f -t --tail 10 容器id
docker logs -f -t 容器id

#可选参数 --tail number(显示的条数),不写上就输出全部

查看容器进程中的进程id:

# 命令 docker top 容器id
[root@iZ2zeeqh1fctjw2bhzgjnaZ ~]# docker top ff3d87da3618
UID                 PID                 PPID                C                   STIME     
root                9328                9311                0                   14:12    

查看镜像的元数据:

就是查看详细的信息。

#命令
docker inspect 容器id

[root@iZ2zeeqh1fctjw2bhzgjnaZ ~]# docker inspect ff3d87da3618
[
    {
        "Id": "ff3d87da3618e8ded5980619aa2664b40e360e2a0063668144eba51afa6c35a8",
        "Created": "2020-05-15T06:12:05.676704236Z",
        "Path": "/bin/bash",
        "Args": [],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 9328,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2020-05-15T06:12:06.064708089Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        "Image": "sha256:470671670cac686c7cf0081e0b37da2e9f4f768ddc5f6a26102ccd1c6954c1ee",
        "ResolvConfPath": "/var/lib/docker/containers/ff3d87da3618e8ded5980619aa2664b40e360e2a0063668144eba51afa6c35a8/resolv.conf",

进入当前正在运行的容器:

#我们通常容器都是在后台方式运行的,需要进入容器,修改一些配置

#命令
docker exec -it 容器id bashShell

#测试
[root@iZ2zeeqh1fctjw2bhzgjnaZ ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
ff3d87da3618        centos              "/bin/bash"         29 minutes ago      Up 29 minutes                           zen_keller
[root@iZ2zeeqh1fctjw2bhzgjnaZ ~]# docker exec -it ff3d87da3618 /bin/bash
[root@ff3d87da3618 /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@ff3d87da3618 /]# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 06:12 pts/0    00:00:00 /bin/bash
root        14     0  0 06:42 pts/1    00:00:00 /bin/bash
root        28    14  0 06:42 pts/1    00:00:00 ps -ef


#方式二,这种方式会执行当前容器正在执行的代码
docker attch 容器id


sudo docker run -p 3306:3306 --name newsql \
-v /mydata/mysql/log:/var/log/mysql \
-v /mydata/mysql/data:/var/lib/mysql \
-v /mydata/mysql/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=123 \
-d mysql:latest

以上两种方式的区别:

方式1:是新开启一个终端

方式2:是进入容器中正在执行的终端,不会启动新的进程

从容器内拷贝文件到自己主机上

docker cp 

#我们在docker centos下的/home目录下创建一个文件szw.java
[root@b58fcf3b7532 home]# touch szw.java
[root@b58fcf3b7532 home]# ls
szw.java
#退出docker中的centos
exit    
#进行拷贝
docker cp b58fcf3b7532:/home/szw.java /home


#拷贝是一个手动过程,未来我们使用-V卷的技术,可以实
image.png

小结

所有的命令总结图:

image.png

练习

docker安装nginx

#1、在docker hub中搜索ngix信息,可以看到详细信息和帮助文档
#2、下载镜像
#3、启动镜像
#意思就是新建一个Nginx容器,命名为Nginx01,暴露服务器端口为3000映射内部的80端口,-d后台运行
docker run -d --name nginx01 -p 3000:80 nginx
#4、本机自测
curl localhost:3000
##5、再利用公网ip进行访问

端口暴露详解图:

端口暴露详解

思考问题:我们每次改动 nginx配置文件,都需要进入容器内部?十分的麻烦,我要是可以在容器外部提供一个映射路径,达到在容器修改文件名,容器内部就可以自动修改?数据卷!

在docker中装tomcat

#官方的使用
docker run -it --rm tomcat:9.0

#我们之前的启动都是后台,停止了容器之后,容器还是可以查到 docker run-it-rm,一般用来测试,用完及删除
#但是我们不建议这样使用!

docker pull tomcat:9.0

#启动运行
[root@iZ2zeeqh1fctjw2bhzgjnaZ ~]# docker run -d -p 3310:8080 --name tomcat01 tomcat:9.0

#测试发现,404
#发现问题:1、linux命令少了,ll都没有
#2、没有webapps目录下没有文件

原因:阿里云镜像的问题,默认是最小的镜像,将一些不必要的全部都剔除掉

那么怎么解决?

#首先进入当前运行的这个mcat容器中
docker exec -it tomcat01 /bin/bash
复制.list文件

我们可以发现,可以访问到了docker中的tomcat。

image.png

练习:安装ES

docker可视化工具

  • portainer(先用这个)
docker run -d -p 3310:9000 \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
--name prtainer-test \
docker.io/portainer/portainer

安装好之后,我们可以通过ip地址加上端口号访问我们的可视化工具。

第一步看到的就是一个设置管理员密码的操作,设置好以后,点击local本地连接。

可视化工具

就会显示这个界面,再继续点击local,我们就可以了解我们本机关于docker的详细信息了。

Docker镜像详解

镜像是什么?

镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件

所需的所有内容,包括代码、运行町库、环境变量和配置文件。

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

Docker镜像加载原理

UnionFS(联合文件系统)

UnionFS (联合文件系统) : Union文件系统( UnionFS )是一种分层、 轻量级并且高性能的文件系统,它支持对文件系

统的修改作为-次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。

Union 文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基纡基础镜像(没有父镜像),可以制作各种具

体的应用镜像。

特性: 一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这

样最终的文件系统会包含所有底层的文件和目录。

注意:我们pull下载镜像的时候,看到的一层一层就是这个!

言简意赅的就是说:我如果下载一个文件,之前存在的东西,我不进行下载了,相同的东西作为底层,我只去下载上一层的东西就可了!

分层

Docker镜像加速原理

docker实际上由一层一层的文件系统组成,这种层级系统就是我们上面说的UnionFS。

bootfs(boot file system)主要包含bootloader和kernel, bootloader主要是引|导加载kernel, Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型的Linux/Unix系统是一样的 ,包含boot加载器和内核。当bootfs加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs.(就是我们在开机时候看到的引导!docker中就是省略了这个部分!

rootfs (root file system) , 在bootfs之上。包含的就是典型Linux 系统中的/dev, /proc, /bin, /etc等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu , Centos等等。(这个部分就是docker中需要下载的东西,他使用的bootfs实际上是本机的,这就导致了我们启动docker的时候基本都是秒级打开的!

有了以上两个概念,我们就只到我们的docker下载的镜像这么小!并且打开快!

对于一个精简的0S ,布rootfs可以很小,只需要包含最基本的命令,工具和程序库就可以了,因为底层直接用Host的kernel ,自己只需要提供rootfs就可以了。由此可见对于不同的linux发行版, bootfs基本是一致的, rootfs会有差别,因此不同的发行版可以公用bootfs。

分层理解

我们平常pull镜像的时候,可以发现下载进行都是一层一层的。

就比如我们上面下载mysql的时候:

#我们还可以指定下载版本,mysql5.7
[root@iZ2zeeqh1fctjw2bhzgjnaZ ~]# docker pull mysql:5.7
5.7: Pulling from library/mysql
5b54d594fba7: Already exists    #和以前共用的版本就不用下载了(联合文件)
07e7d6a8a868: Already exists 
abd946892310: Already exists 
dd8f4d07efa5: Already exists 
076d396a6205: Already exists 
cf6b2b93048f: Already exists 
530904b4a8b7: Already exists 
a37958cbebcf: Pull complete 
04960017f638: Pull complete 
e1285def0d2a: Pull complete 
670cb3a9678e: Pull complete 

我们就可以看到他是一个一个文件下载的!也就一层一层的进行下载!如果本机内之前存才的!就不进行下载了。

特点

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

这一层就是我们通常说的容器层。

示意图

当我们在把自己的这个打包成一个镜像的时候,别人操作的时候,你的镜像就又会变成了镜像层 了!

那么怎么发布我们自己的镜像呢?

Commit镜像

#我们都知道,我们在pull官方下的tomcat的webapps下没有文件的!
#我们每次下载后都需要给webapps下都需要进行复制webapps.list
#非常麻烦!那么我们是不是可以根据自己的容器配置一个进行呢?就用到了以下的命令。

docker commit 提交容器称为一个新的副本

#命令和git原理
docker commit -m="描述的信息" -a="作者" 容器id 目标进行名:[Tag]

实战测试

[root@iZ2zeeqh1fctjw2bhzgjnaZ ~]# docker commit -m="szwTomcat" -a="szw" 29f9b0ebc838 szwtomcat:1.0
sha256:84a932e22a55ef6a2a15b75d1360ded2303c9552db85c7bc91e8a081e6e8f772

注意:转化为的镜像名不能含有大写!

我们可以看到szwtomcat的大小比之前的tomcat大小少,这就是因为我们新建的镜像包含了之前镜像和容器层的原因!所以大小变大了!

自定义tomcat明显变小

容器数据卷

什么是容器数据卷?

docker理念回顾

如果数据都在容器中,那么如果我们删除容器,数据就会丢失!需求:数据可持续化!

容器之间可以有一个数据共享技术!Docker容器产生数据,同步到本地!

这就是卷技术!目录的挂载!

目录挂载

总结一句话:容器的持久化和同步操作!容器间可以进行数据共享!

使用容器数据卷

方式1:直接使用名来来挂载

docker run -it -v 主机目录:容器内目录

#测试
[root@iZ2zeeqh1fctjw2bhzgjnaZ home]# docker run -it -v /home/test:/home centos /bin/bash

#使用docker inspect查看信息
[root@iZ2zeeqh1fctjw2bhzgjnaZ home]# docker inspect 7de2961f9101

详细信息截图:(我们可以发现两者进行了挂载)

详细截图
#我们再进行测试一下是不是真正绑定了
挂载目录显示
#1、还可以再进行一个测试,先停止容器运行
#2、在服务器上修改同步的文件
#3、运行容器,查看绑定的目录

我们发现,文件依然进行了同步!

好处!我们以后修改只需要在本地修改就可以了,容器内会自己进行同步!

实战测试mysql

思考:mysql的数据持久化问题!

#获取镜像
docker pull mysql:5.7

#先参照docker hub中的帮助
$ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag

#参数详细
-d 后台运行
-p端口映射
-v卷挂载
-e环境配置
--name 容器名字
docker run -d -p 3310:3306 -v /home/mysq/conf:/etc.mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e  MYSQL_ROOT_PASSWORD=123 --name mysql01 mysql:5.7


#我们可以通过docker ps发现这个容器正在运行

#外部测试:我们可以用可视化工具去连接服务器的端口,输入面进行测试,测试成功则代表了设置成功!

#下图,配置文件放在了mysq路径下。。。。
配置文件

我们外部测试使用Navicat进行测试连接:

Navicat连接
#我们在这个Navicat中新创建一个数据库test,然后去服务器绑定容器的位置去查看数据库test。

我们可以根据下图发现!该数据库存在这个data文件中
data中成功的挂载了mysql中的数据
#我们再进行测试!将容器删除,看看挂载在本地的数据卷还会不会存在?
容器删除还会存在挂载文件

具名和匿名挂载

#匿名挂载
#就是在挂载的时候,只写了容器内的路径,并没有写容器外的路径!
docker run -d -P --name nginx01 -v /etc/nginx nginx

#用下面这个镜像查看本地的卷
[root@iZ2zeeqh1fctjw2bhzgjnaZ ~]# docker volume ls
DRIVER              VOLUME NAME
local               5a5341c46b2ef49d9e496c7017beff66c86d6f6f3f0e2594143a8b9a18f9f6c9
local               7e147bcd894d89adce362efa62bc96f9522f3c47a1675e1b4d875ab85e1735d4
local               10cff4d870ab1c1062dc8cfb86b982d41a326f47453851ac0e664c48b638a228
local               063c2e58b4011356e35ad30961c7aac5f997c37d3692c2d4b22c5ffc26525b6c
local               158b76b3fc9cd28e759c6c8b0040c75316b16be424b5ce0b2288a532c556eacb
local               b5b9277a857841d04079d967bd6ba25dda5ed4550ac349e506587d6bf8634918
local               ba9b9e208e1b5e6c5470b45f2ba823b4388b0ef5bbe19f403ce73c13fca3690c
#上面的这些数据是真实存在的路径,这种就是属于匿名挂载
#那么对应的具名挂载是什么呢?就是加上了名字而已!
[root@iZ2zeeqh1fctjw2bhzgjnaZ ~]# docker run -d -P --name nginx02 -v juming:/etc/nginx nginx
ccabd3cf2414de60516acbe7d668cd67a3f839c74bb8e65d7f21d040cbcac312
[root@iZ2zeeqh1fctjw2bhzgjnaZ ~]# docker volume ls
DRIVER              VOLUME NAME
local               5a5341c46b2ef49d9e496c7017beff66c86d6f6f3f0e2594143a8b9a18f9f6c9
local               7e147bcd894d89adce362efa62bc96f9522f3c47a1675e1b4d875ab85e1735d4
local               10cff4d870ab1c1062dc8cfb86b982d41a326f47453851ac0e664c48b638a228
local               063c2e58b4011356e35ad30961c7aac5f997c37d3692c2d4b22c5ffc26525b6c
local               158b76b3fc9cd28e759c6c8b0040c75316b16be424b5ce0b2288a532c556eacb
local               b5b9277a857841d04079d967bd6ba25dda5ed4550ac349e506587d6bf8634918
local               ba9b9e208e1b5e6c5470b45f2ba823b4388b0ef5bbe19f403ce73c13fca3690c
local               juming

#从上面的信息我们可以看到,多了个juming的卷,这就是具名挂载
#我们还可以再用以下命令进行查看这个卷的详细信息
[root@iZ2zeeqh1fctjw2bhzgjnaZ ~]# docker volume inspect juming
[
    {
        "CreatedAt": "2020-05-16T23:23:30+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/juming/_data",
        "Name": "juming",
        "Options": null,
        "Scope": "local"
    }
]
# 多有的docker容器内的卷,没有指定外部的路径,就会存在这个路径下/var/lib/docker/volumes/
#我们进入到这个路径下
挂载路径

可以发现,这里面就是存放着,我们在容器内挂载的数据!

#大多数情况下,我们都使用的是具名挂载

#那么怎么区分匿名挂载还是具名挂载?
-v 容器内路径            #匿名挂载
-v 卷名:容器内路径       #具名挂载
-v/宿主机路径:容器内路径  #指定路径挂载

拓展:

docker run -d -P --name nginx01 -v /etc/nginx:ro nginx
docker run -d -P --name nginx01 -v /etc/nginx:rw nginx

#我们发现上面两个具名挂载的命令,在目录下有一个:ro:rw
#那么这个ro和rw是什么意思呢?
:ro readonly    #只读
:rw readWrite   #可读可写

#一旦设置了只读,我们在容器中就只能只读了

Dockerfile

DockerFile介绍

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

构建步骤:

1、编写一个dockerfile文件

2、docker build构建成一个镜像

3、docker run 运行镜像

4、docker push 发布镜像(发布到docker hub上、阿里云远程镜像)

查看一下官方是怎么做的:

在docker hub上搜索centos,然后点击版本,会跳转到git hub上,我们就可以发现了这个centos的docker file文件。

查看DockerFile文件

DockerFile的构建过程

基础知识

1、每个保留关键字(指令)都是必须是大写字母

2、执行从上到下顺序执行

3、#表示注释

4、每一个指令都会创建一个新的镜像层,并提交!

示意图

dockerFile是面向开发的!我们以后要发布项目,做成镜像,就需要别写dockerFile文件,这个文件不难!

Docker镜像逐渐成为了一个企业交付的标准,必须要掌握!

步骤:开发,部署,运维。。。缺一不可!

DockerFile:构建文件,定义了一切的步骤,源代码

DockerImages:通过DockerFile构建生成的镜像,最终发布和运行的产品!

Docker容器:容器就是镜像运行起来提供服务器!

DockerFile指令

常见指令
From        #基础镜像,一切从这里构建
MAINTAINER  #镜像是谁写的,姓名+邮箱
run         #镜像构建的时候需要运行的命令
ADD         #步骤:tomcat镜像,这个tomcat压缩包!添加内容
WORKDIR     #镜像的工作目录
VOLUME      #挂载的目录
EXPOSE      #保留端口配置
CMD         #指定这个容器启动的时候需要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT  #指定这个容器启动的时候需要运行的命令,可以追加命令
ONBUILD     #当构建一个被继承DOCKERFILE这个时候就会运行ONBUILD的指令。触发指令
COPY        #类似ADD,将我们文件拷贝到镜像中
ENV         #构建的时候设置环境变量

centos实战测试

DockerHub中大部分的centos镜像都是从 centos-7-x86_64-docker.tar.xz过来的,也就是说这是一个最基层的镜像!

创建一个自己的contos镜像

1、编写自己的配置文件

FROM centos
MAINTAINER shaozhaowei<[email protected]>

ENV MYPATH /user/local
WORKDIR $MYPATH

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

EXPOSE 80

CMD echo $MYPATH
CMD "--------"
CMD /bin/bash             

2、通过这个镜像构建镜像

#注意结尾处有一个点
docker build -f mydockerfile-centos -t mycentos:0.1 .
构建镜像

3、测试运行

[root@iZ2zeeqh1fctjw2bhzgjnaZ dockerfile]# docker run -it mycentos:0.1
[root@9b924b5f6fc5 local]# pwd
/user/local
#这里可以发现我们直接进入了我们在配置文件中编写的工作目录
[root@9b924b5f6fc5 local]# ifconfig
eth0: flags=4163  mtu 1500
        inet 172.18.0.4  netmask 255.255.0.0  broadcast 172.18.255.255
        ether 02:42:ac:12:00:04  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[root@9b924b5f6fc5 local]# vim szw.java
[root@9b924b5f6fc5 local]# ls
szw.java
#以上是测试的两个我们自己配置的命令,全部成功!
#我们还可以根据以下命令查看当前的docker镜像是怎么做出来的
#我们可以根据这个历史查看他是怎么做的
[root@iZ2zeeqh1fctjw2bhzgjnaZ dockerfile]# docker history 5559295ad3fc
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
5559295ad3fc        6 minutes ago       /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "/bin…   0B                  
46c14122fbc3        6 minutes ago       /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "\"--…   0B                  
5c9e8d094bc9        6 minutes ago       /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "echo…   0B                  
4607fb979c7b        6 minutes ago       /bin/sh -c #(nop)  EXPOSE 80                    0B                  
0a13147a565f        6 minutes ago       /bin/sh -c yum -y install net-tools             24.1MB              
72f1c108662c        6 minutes ago       /bin/sh -c yum -y install vim                   59.8MB              
3e21b077a0b9        7 minutes ago       /bin/sh -c #(nop) WORKDIR /user/local           0B                  
230e9f4efd9c        7 minutes ago       /bin/sh -c #(nop)  ENV MYPATH=/user/local       0B                  
0c5002514cc7        7 minutes ago       /bin/sh -c #(nop)  MAINTAINER shaozhaowei<12…   0B                  
470671670cac        4 months ago        /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B                  
           4 months ago        /bin/sh -c #(nop)  LABEL org.label-schema.sc…   0B                  
           4 months ago        /bin/sh -c #(nop) ADD file:aa54047c80ba30064…   237MB    

CMD和ENTRYPOINT区别

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

测试cmd命令

#编写dockerFile
[root@iZ2zeeqh1fctjw2bhzgjnaZ dockerfile]# vim docker-cmd-test

FROM centos
CMD ["LS","-a"]

#编写完之后,使用命令进行构建
[root@iZ2zeeqh1fctjw2bhzgjnaZ dockerfile]# docker build -f docker-cmd-test -t cmdtest .
#中间省略
Successfully built 56e5493262cd
Successfully tagged cmdtest:latest
#我们可以发现启动成功
启动成功

运行上面这个镜像,就会列出所有所有的目录。

#我们再次运行这个镜像,追加一个命令 -l
[root@iZ2zeeqh1fctjw2bhzgjnaZ dockerfile]# docker run 56e5493262cd -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","-a"]命令,而-l根本不是命令,所以报错

我们继续测试ENTRYPOINT命令,用这个进行构建dockerFile

[root@iZ2zeeqh1fctjw2bhzgjnaZ dockerfile]# vim docker-entrypoint-test

FORM centos
ENTRYPOINT ["ls","-a"]

#使用配置文件进行构建
[root@iZ2zeeqh1fctjw2bhzgjnaZ dockerfile]# docker build -f docker-entrypoint-test -t entrycentos .

#进行运行
运行

tomcat实战测试

1、准备镜像文件tomcat压缩包,jdk压缩包,放在同一个目录下

压缩包

2、编写Dockerfile

FROM centos
MAINTAINER shaozhaowei<[email protected]>

COPY readme.txt /usr/local/readme.txt

Add jdk-8u201-linux-x64.tar.gz /usr/local/
Add apache-tomcat-9.0.16.tar.gz /usr/local/

RUN yum -y install vim

ENV MYPATH /usr/local
WORKDIR $MYPATH

ENV JAVA_HOME /usr/local/jdk1.8.0_201
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.16
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.16
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin

EXPOSE 8080

CMD /usr/local/apache-tomcat-9.0.16/bin/startup.sh && tail -F /url/local/apache-tomcat-9.0.16/bin/logs/catalina.out

3、构建这个镜像

docker build -t diytomcat .

4、构建容器

docker run -d -p 3310:8080 --name diytomcat -v /root/testAll/test:/usr/local/apache-tomcat-9.0.16/webapps/test -v /root/testAll/logs/:/usr/local/apache-tomcat-9.0.16/webapps/logs diytomcat

5、运行进入自己的容器

[root@iZ2zeeqh1fctjw2bhzgjnaZ testAll]# docker exec -it 8df6726000b813bcf775 /bin/bash
[root@8df6726000b8 local]# ls
aegis             bin  games    jdk1.8.0_201  lib64    readme.txt  share
apache-tomcat-9.0.16  etc  include  lib       libexec  sbin        src
#我们可以发现已经把复制的两个jdk和tomcat解压进了容器中

6、访问我们服务器ip地址+端口号,可以看到tomcat主页就代表成功了!

7、如果想尝试页面发布到服务器,要先编写web.xml,然后再在webapps/test/下,访问对应的页面。

发布自己的镜像

DockerHub

1、在官网上进行注册账号

2、确定这个账号可以登录

3、在我们服务器上提交自己的镜像

#查看登录命令的帮助
[root@iZ2zeeqh1fctjw2bhzgjnaZ dockerfile]# docker login --help

Usage:  docker login [OPTIONS] [SERVER]

Log in to a Docker registry.
If no server is specified, the default is defined by the daemon.

Options:
  -p, --password string   Password
      --password-stdin    Take the password from stdin
  -u, --username string   Username
登陆成功

这里就算登录成功了!

[root@iZ2zeeqh1fctjw2bhzgjnaZ ~]# docker push diytomcat
The push refers to repository [docker.io/library/diytomcat]
2d7c03c9871a: Preparing 
0fcab5fa81bf: Preparing 
1dd967f434ae: Preparing 
ce3680ddfbcf: Preparing 
0683de282177: Preparing 
denied: requested access to the resource is denied
#这里提示push失败
#push镜像的的问题?
#解决,增加一个tag
docker tag 4f4184981337 shaozhaowei/tomcat:1.1
#注意,标签前面的那个shaozhaowei必须是你需要push的账户名,就是作者名

[root@iZ2zeeqh1fctjw2bhzgjnaZ ~]# docker push shaozhaowei/tomcat:1.1
The push refers to repository [docker.io/shaozhaowei/tomcat]
2d7c03c9871a: Pushing  31.31MB/59.78MB
0fcab5fa81bf: Pushed 
1dd967f434ae: Pushing  11.99MB/396.7MB
ce3680ddfbcf: Pushed 
0683de282177: Pushing  57.52MB/237.1MB
^C
#这样就显示上传了,需要等待!这个就是按照镜像的层级上传的

发布到阿里云镜像中

1、登录阿里云

2、找到容器镜像服务

Docker网络

理解Docker0

测试

ip addr
查看ip

三种网络代表三种网络:

#问题:docker是怎样处理网络访问的?
#我们在docker的容器内部查看ip,发现容器启动的时候会有一个eth0@if99
root@dff7be9666bc:/usr/local/tomcat# ip addr
1: lo:  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
98: eth0@if99:  mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0
       valid_lft forever preferred_lft forever
#我们测试一下服务器内部是否能ping

[root@iZ2zeeqh1fctjw2bhzgjnaZ dockerfile]# ping 172.18.0.2
PING 172.18.0.2 (172.18.0.2) 56(84) bytes of data.
64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.093 ms
64 bytes from 172.18.0.2: icmp_seq=2 ttl=64 time=0.079 ms
64 bytes from 172.18.0.2: icmp_seq=3 ttl=64 time=0.074 ms

#我们发现linux可以ping通容器内的ip

原理

1、我们每安装一个docker容器,docker就会给docker容器分配一个ip,只要我们安装了docker,就会有一个网卡docker0。这就是桥接,使用的技术是evth-pair技术!

我们再次ping一下linux中的网络

[root@iZ2zeeqh1fctjw2bhzgjnaZ dockerfile]# ip addr
#中间的1-5省略
#我们可以和刚才容器内的ip进行对比,发现了98,99这一对ip惊人的相似!
99: veth98b8be1@if98:  mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether 6e:f2:ee:28:10:86 brd ff:ff:ff:ff:ff:ff link-netnsid 0

2、我们再次进行测试!

#继续启动一个tomcat
101

我们在容器内进行查看ip

查看ip
#我们发现容器带来的网卡,都是一对一对存在的!
#evth-pair就是一对的虚拟设备接口,他们都是成对出现的,一段连着协段彼此相连
#正因为有这个特性,evth-pair充当一个桥粱,连接各种虚拟网络设备
#openStac,Docker容器之间的连接,ovs的链接,都是使用了evth-pair技术

3、我们测试两个tomcat是否能ping通

[root@iZ2zeeqh1fctjw2bhzgjnaZ dockerfile]# docker exec -it tomcat02 ping 172.18.0.2
PING 172.18.0.2 (172.18.0.2) 56(84) bytes of data.
64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.118 ms
64 bytes from 172.18.0.2: icmp_seq=2 ttl=64 time=0.080 ms
64 bytes from 172.18.0.2: icmp_seq=3 ttl=64 time=0.077 ms
#测试我们发现两个容器之间也是可以ping通的

结论:tomcat01和tomcat02是公用的一个路由器,docker0.

所有的容器不指定网络的情况下,都是 docker0路由的, docker会给我们的容器分配一个默认的可用IP。

.

小结

核心就是:利用了linux中的虚拟化网络技术。在容器中和docker0中分别创建了一个虚拟网卡,通过veth进行连接。

Docker中的所有的网络接口都是虚拟的。虚拟的转发效率特别快!(内网传递)。

只要删除容,对应的网桥就会消失。

示意图

--link

思考一个场景:我们编写了一个微服务,datebase url = ip,项目不重启,数据库ip换掉了,我们希望可以处理这个问题,可以利用名字来访问容器。

#上面的场景就是归结于一个问题,怎么使用服务名代替ip地址访问容器?
#先做一个测试
#我们后面不跟ip地址,直接跟容器名。
[root@iZ2zeeqh1fctjw2bhzgjnaZ dockerfile]# docker exec -it tomcat02 ping tomcat01
ping: tomcat01: Name or service not known


#使用link
[root@iZ2zeeqh1fctjw2bhzgjnaZ dockerfile]# docker run -d -P --name tomcat03 --link tomcat02 tomcat:9.0
58aae10fb4ecb6324d50139b27800f6cc1a58af0340c21477cd735fded967a98
#使用--link进行把tomcat03和tomcat02的网络互连
[root@iZ2zeeqh1fctjw2bhzgjnaZ dockerfile]# docker exec -it tomcat03 ping tomcat02
PING tomcat02 (172.18.0.3) 56(84) bytes of data.
64 bytes from tomcat02 (172.18.0.3): icmp_seq=1 ttl=64 time=0.129 ms
64 bytes from tomcat02 (172.18.0.3): icmp_seq=2 ttl=64 time=0.080 ms
64 bytes from tomcat02 (172.18.0.3): icmp_seq=3 ttl=64 time=0.084 ms
^C
--- tomcat02 ping statistics ---
#我们可以通过以上发现tomcat03和tomcat02进行了一个连接

#但是经过测试,发现tomcat02是无法与tomcat03进行ping通的!

探究

[root@iZ2zeeqh1fctjw2bhzgjnaZ dockerfile]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
095914b1b0c6        bridge              bridge              local
c5b2a21d16c0        host                host                local
755347b3adf4        none                null                local
[root@iZ2zeeqh1fctjw2bhzgjnaZ dockerfile]# docker network inspect 095914b1b0c6
#摘选出主要信息
"Containers": {
            "58aae10fb4ecb6324d50139b27800f6cc1a58af0340c21477cd735fded967a98": {
                "Name": "tomcat03",
                "EndpointID": "b9fe7d0503be687a08bfee2c7d4b53dc72b4db8c18f0c2f546a277070a539b3d",
                "MacAddress": "02:42:ac:12:00:04",
                "IPv4Address": "172.18.0.4/16",
                "IPv6Address": ""
            },
            "def92693ca704227cf7d8c5602606d14e614a1af7c2f877b2429d65a0dd5a89e": {
                "Name": "tomcat02",
                "EndpointID": "ba161992c42eb4060705330baee39110456d31e473fd866ac2a7fb9603eee085",
                "MacAddress": "02:42:ac:12:00:03",
                "IPv4Address": "172.18.0.3/16",
                "IPv6Address": ""
            },
            "dff7be9666bcb7b5567b1e03127ac72efff9bcd4c24933ad30072f807ab029bf": {
                "Name": "tomcat01",
                "EndpointID": "5eb39f854209ee16a9813dad5964ab04950603c4f24c933641d5c39361137289",
                "MacAddress": "02:42:ac:12:00:02",
                "IPv4Address": "172.18.0.2/16",
                "IPv6Address": ""
            }
        },
image.png
[root@iZ2zeeqh1fctjw2bhzgjnaZ dockerfile]# docker exec -it 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.18.0.3  tomcat02 def92693ca70
172.18.0.4  58aae10fb4ec
#我们查看tomcat03中的本地网络配置,发现绑定了tomcat02,这就是为什么我们通过容器名就可以ping到ip地址

但是不推荐使用!

自定义网络

使用命令查看docker所有的网络模式

查看网络模式

网络模式

bridge:桥接 docker(默认)

none:不配置网络

host:和宿主机共用一个网络

container:容器网络连同(用的少,局限性很大)

你可能感兴趣的:(Docker)