Docker学习笔记


Docker

1.什么是Docker?

容器化技术,将传统的项目部署,以容器的方式进行部署,每个应用对应着一个镜像,启动的镜像作为一个容器,容器之间是相互隔离的。

2.对比传统的部署方式:

1.占用的资源更少;

2.运行速度更快;

3.只需要一次配置好环境,换到别的机子上就可以一键部署好,大大简化了操作。

3.Docker的组成部分:

Image(镜像):就是一个只读的模板;镜像可以用来创建 Docker 容器,一个镜像可以创建很多容器。

Container(容器):独立运行的一个或一组应用。容器是用镜像创建的运行实例。它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台;可以把容器看做是一个简易版的 Linux 环境

Repository(仓库):集中存放镜像文件的场所。仓库分为公有仓库和私有仓库;最大的公开仓库是 Docker Hub(https://hub.docker.com/),阿里云…都有容器服务器(配置镜像加速!)。

4.Docker的安装:

1)、检查Linux版本是不是7.0以上;

cat /etc/redhat-release

2)、删除旧版本的Docker;

yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

3)、下载需要的安装包;

yum install -y yum-utils

4)、配置阿里云的镜像仓库地址:

yum-config-manager \
    --add-repo \
    http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

5)、更新yum软件包的索引:

yum makecache fast

6)、安装Docker:

yum install docker-ce docker-ce-cli containerd.io

7)、启动Docker:

systemctl start docker

8)、查看Docker版本信息:

docker version

9)、测试docker:

docker run hello-world

10)、卸载docker:

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

5.配置阿里云加速:

1)、登录到阿里云;

2)、搜索“容器镜像服务控制台”;

3)、配置:

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://b6s34pem.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

6.Docker的底层原理:

Docker是怎么工作的

Docker是一个Client-Server结构的系统,Docker的守护进程运行在主机上。通过Socket从客户端访问!

Docker-Server接收到Docker-Client的指令,就会执行这个命令!

docker run干了什么?

7.为什么docker比vm虚拟机块:

(1)docker有着比虚拟机更少的抽象层。由亍docker不需要Hypervisor实现硬件资源虚拟化,运行在docker容器上的程序直接使用的都是实际物理机的硬件资源。因此在CPU、内存利用率上docker将会在效率上有明显优势。

(2)docker利用的是宿主机的内核,而不需要Guest OS。因此,当新建一个容器时,docker不需要和虚拟机一样重新加载一个操作系统内核。仍而避免引寻、加载操作系统内核返个比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载Guest OS,返个新建过程是分钟级别的。而docker由于直接利用宿主机的操作系统,则省略了返个过程,因此新建一个docker容器只需要几秒钟。

8.Docker的常用命令:

1.帮助命令:

docker version #查看docker版本

docker info #显示docker的系统信息,包括镜像和容器的数量

docker 命令 --help #帮助命令

2.镜像命令:

1.docker images

docker images [-aq] #查看本机所以的镜像
	-a :搜索所以的镜像
	-q :值显示镜像的ID

REPOSITORY:镜像的仓库源

TAG:镜像的标签,也就是版本,latest表示最新版本

IMAGE ID:镜像的ID号

CREATED:镜像的创建时间

SIZE:镜像的大小

docker search [-f,--filter] 镜像名 #搜索镜像
	-f/--filter :对输出内容进行过滤

3.docker pull

docker pull 镜像名 #下载镜像,默认下载最新的镜像
docker pull 镜像名:版本号 #下载指定版本号的镜像

docker pull mysql:5.7

等价于

docker pull docker.io/library/mysql:5.7 真实地址

4.docker rmi

docker rmi [-f] 镜像id号 #删除一个镜像
	-f :强制删除
	
docker rmi -f 镜像id 镜像id 镜像id 镜像id #删除多个镜像	

docker rmi -f $(docker images -aq) #删除全部镜像

5.docker image inspect

docker image inspect 镜像id  #查看镜像的具体内容,分层信息

3.容器命令:

1.docker run

docker run [OPTIONS] 容器id/容器名:版本号 [COMMAND] [ARG...]  #运行镜像/创建容器
OPTIONS说明:
	--name="容器新名字": 为容器指定一个名称;

	-d: 后台运行容器,并返回容器ID,也即启动守护式容器;

	-i:以交互模式运行容器,通常与 -t 同时使用;

	-t:为容器重新分配一个伪输入终端,通常与 -i 同时使用;(通常使用 -it 使用交互方式运行,进入容器查看			内容)

	-P: 随机端口映射;

	-p: 指定端口映射,有以下四种格式

      	ip:hostPort:containerPort

      	ip::containerPort

     	hostPort:containerPort  (通常使用这种方式)

      	containerPort
      	
    -e: 可以配置容器的运行环境,配置多个运行环境使用多个 -e 	
    
    --rm:停止容器自动删除,一般用于测试

2.从容器内退出的两中方式

1.exit退出并停止容器;

2.ctrl+P+Q仅退出容器。

3.docker ps

docker ps [options]  #列出当前正在运行的容器
options说明:
	-a :列出当前所有正在运行的容器+历史上运行过的

	-l :显示最近创建的容器。

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

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

	--no-trunc :不截断输出。	

Exited (0) 13 minutes ago:表示容器已停止运行。

Up 17 minutes:表示容器正在运行。

4.docker start

docker start 容器id/容器名  #启动容器

5.docker restart

docker restart 容器ID/容器名 #重启容器

6.docker stop

docker stop 容器id/容器名  #停止正在运行的容器

7.docker kill

docker kill 容器id/容器名  #强制停止正在运行的容器		

8.docker rm

docker rm 容器id/容器名 #删除容器

docker rm $(docker ps -aq) #删除所有容器

docker ps -aq | xargs docker rm #删除所有容器

4.其它命令:

1.后台启动命令:

docker run -d 镜像id  #以守护线程的方式运行容器,及后台方式运行容器

#使用镜像centos:latest以后台模式启动一个容器

docker run -d centos

问题:然后docker ps -a 进行查看, 会发现容器已经退出

很重要的要说明的一点: Docker容器后台运行,就必须有一个前台进程.

容器运行的命令如果不是那些一直挂起的命令(比如运行top,tail),就是会自动退出的。

这个是docker的机制问题,比如你的web容器,我们以nginx为例,正常情况下,我们配置启动服务只需要启动响应的service即可。例如

service nginx start

但是,这样做,nginx为后台进程模式运行,就导致docker前台没有运行的应用,

这样的容器后台启动后,会立即自杀因为他觉得他没事可做了.

所以,最佳的解决方案是,将你要运行的程序以前台进程的形式运行

2.docker logs

docker logs [options] 容器id #查看容器日志
	-t :加入时间戳
	-f :跟随最新的日志打印
	--tail 数字 :显示最后多少条

3.docker top

docker top 容器id #查看容器内运行的进程

4.docker inspect

docker inspect 容器id #查看容器内部的细节

5.进入到当前正在运行的容器内部:

1.docker exec -it 容器id /bin/bash

docker exec 进入容器中打开一个新的终端

exec:管理 的意思

2.docker attach 容器id

docker attach 进入到容器正在运行的终端

attach:加入 的意思

6.docker cp

docker cp 容器id:容器目标路径 主机目的路径  #把容器内的文件拷贝到主机上

已经停止运行的容器也可以拷贝文件到主机上

5.小结:

attach    Attach to a running container     # 进入到容器正在执行的终端

build     Build an image from a Dockerfile  # 通过 Dockerfile 定制镜像

commit    Create a new image from a container changes   # 提交当前容器为新的镜像

cp        Copy files/folders from the containers filesystem to the host path   #从容器中拷贝指定文件或者目录到宿主机中

create    Create a new container        # 创建一个新的容器,同 run,但不启动容器

diff      Inspect changes on a container's filesystem   # 查看 docker 容器变化

events    Get real time events from the server          # 从 docker 服务获取容器实时事件

exec      Run a command in an existing container        # 进入到容器开启新的终端

export    Stream the contents of a container as a tar archive   # 导出容器的内容流作为一个 tar 归档文件[对应 import ]

history   Show the history of an image                  # 展示一个镜像形成历史

images    List images                                   # 列出系统当前镜像

import    Create a new filesystem image from the contents of a tarball # 从tar包中的内容创建一个新的文件系统映像[对应export]

info      Display system-wide information               # 显示系统相关信息

inspect   Return low-level information on a container   # 查看容器详细信息

kill      Kill a running container                      # kill 指定 docker 容器

load      Load an image from a tar archive              # 从一个 tar 包中加载一个镜像[对应 save]

login     Register or Login to the docker registry server    # 注册或者登陆一个 docker 源服务器

logout    Log out from a Docker registry server          # 从当前 Docker registry 退出

logs      Fetch the logs of a container                 # 输出当前容器日志信息

port      Lookup the public-facing port which is NAT-ed to PRIVATE_PORT    # 查看映射端口对应的容器内部源端口

pause     Pause all processes within a container        # 暂停容器

ps        List containers                               # 列出容器列表

pull      Pull an image or a repository from the docker registry server   # 从docker镜像源服务器拉取指定镜像或者库镜像

push      Push an image or a repository to the docker registry server    # 推送指定镜像或者库镜像至docker源服务器

restart   Restart a running container                   # 重启运行的容器

rm        Remove one or more containers                 # 移除一个或者多个容器

rmi       Remove one or more images             # 移除一个或多个镜像[无容器使用该镜像才可删除,否则需删除相关容器才可继续或 -f 强制删除]

run       Run a command in a new container              # 创建一个新的容器并运行一个命令

save      Save an image to a tar archive                # 保存一个镜像为一个 tar 包[对应 load]

search    Search for an image on the Docker Hub         # 在 docker hub 中搜索镜像

start     Start a stopped containers                    # 启动容器

stop      Stop a running containers                     # 停止容器

tag       Tag an image into a repository                # 给源中镜像打标签

top       Lookup the running processes of a container   # 查看容器中运行的进程信息

unpause   Unpause a paused container                    # 取消暂停容器

version   Show the docker version information           # 查看 docker 版本号

wait      Block until a container stops, then print its exit code   # 截取容器停止时的退出状态值

9.Docker 镜像

1.什么是镜像:

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

2.UnionFS(联合文件系统):

UnionFS(联合文件系统):Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union 文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。

特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。

3.镜像加载的原理:

docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。

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

rootfs (root file system) ,在bootfs之上。包含的就是典型 Linux 系统中的 /dev, /proc, /bin, /etc 等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。

4.分层的理解:

当我们pull一个镜像时,它是分层下载的

5.为什么要分层?

最大的一个好处就是 - 共享资源

比如:有多个镜像都从相同的 base 镜像构建而来,那么宿主机只需在磁盘上保存一份base镜像,

同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。

6.特点:

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

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

7.docker commit

docker commit [options] 容器id  目标镜像名:版本号  #提交容器成为一个新的镜像
	-a :作者
	-m :描述信息

我们可以对容器进行一些修改,然后使用docker commit把修改后的容器提交为一个新的镜像;类似快照。
	

可以通过docker image inspect 容器ID查看我们提交的镜像信息。

10.Docker的容器数据卷:

1.什么是容器数据卷:

原本数据都在容器中,一旦容器被删除,那么容器内的数据也就会被删除。

容器数据卷就是使容器的数据可以被持久化的保存到主机中。

2.数据卷的原理:

目录的挂载,将我们容器内的目录,挂载到Linux上面!

3.特点是什么:

1.多个容器可以共享数据卷;

2.容器与数据卷间的操作是相互同步的;

3.即使容器停止了,重新连接后,依然同步;

4.容器被删除,本地的数据也不会消失。

4.使用数据卷:

1.命令添加数据卷:

docker run -v 主机内的绝对目录:容器中的目录  镜像id  
-v :绑定数据卷格式  主机内的绝对目录:容器中的目录

通过  docker inspect 容器id 查看数据卷信息

docker inspect 容器id查看绑定情况

匿名和具名挂载:
docker run -v 容器内目录 镜像id  #匿名挂载

匿名挂载 -v 后面只有容器内目录
docker volume ls #查看所有匿名和具名的数据卷
docker inspect 容器id #查看容器元数据
发现匿名的name是一个随机的字符串
docker run -v 数据卷名:容器内路径 镜像ID #具名挂载

具名挂载 -v 后面 卷名:容器内目录
docker volume ls #查看所有匿名和具名的数据卷
docker inspect 容器id #查看容器的源数据
发现具名的name是我们指定的名称

具名和匿名的目录挂载到主机上那个目录了呐?

通过docker inspect 容器id我们发现匿名和具名的目录被挂载到了主机的:

/var/lib/docker/volumes/xxxxxxx/_data

三种挂载方式:
docker run -v 容器内路径  容器id #匿名挂载

docker run -v 卷名:容器内路径  容器id #具名挂载

docker run -v 主机路径:容器内路径 容器id #指定主机路径挂载

匿名和具名挂载可以通过docker volume ls 查看到数据卷的name;而指定主机目录的方式不能用docker volume ls 查看。
带权限的数据卷:
# 通过 -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就说明这个路径只能通过宿主机来操作,容器内部是无法操作!

2.通过DockerFile方式添加数据卷:

DockerFile是用来构建镜像文件的命令脚本。

1.编写DockerFile脚本;

# 创建一个dockerfile文件,名字可以随便 建议Dockerfile
# 文件中的内容 指令(大写) 参数
FROM centos

VOLUME ["volume01","volume02"]

CMD echo "----end----"
CMD /bin/bash
#这里的每个命令,就是镜像的一层!

2.构建镜像;

3.创建容器;

这两个目录就是要被挂载的目录;

4.查看目录被挂载的位置;

3.数据卷容器:

什么是数据卷容器?

一个命名的容器挂载数据卷,其它的容器通过挂载这个容器实现数据共享,挂载数据卷的容器称为数据卷容器。

使用:

1.创建数据卷容器:

2.其它容器挂载这个容器:

我们发现已经实现了数据的共享

总结:
1.通过docker run --volumes-from 数据卷容器名 #达到容器间数据共享
2.其实是主机目录、数据卷容器和子容器三者间的数据共享
3.他们之间是数据的拷贝的关系,即使数据卷容器被删除了也不会影响子容器和主机目录

11.DockerFile

1.DockerFile是什么:

DockerFile是用来构建docker镜像的脚本文件。

2.构建镜像的步骤:

1.编写一个DockerFile文件;

2.docker build 把DockerFile文件构建成一个镜像;

3.docker run 运行镜像;

4.docker push 可以把镜像提交到远程仓库。

3.DockerFile的基础知识:

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

2.执行从上到下顺序

3D:\Docker#表示注释

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

4.DockerFile的指令:

FROM:基础镜像,当前镜像来自于哪个镜像的;

MAINTAINER:镜像的维护者,姓名+邮箱;

RUN:镜像构建时需要运行的命令;

EXPOSE:当前容器对外暴露出的端口;

WORKDIR:容器创建后的工作目录;

ENV:在构建过程中设置环境变量;

ADD:将主机上的文件拷贝到镜像中,且会自动的处理URL和解压压缩包;

COPY:拷贝文件到镜像中;

VOLUME:需要被挂载的目录;

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

ENTRYPOINT:指定容器启动时需要运行的命令;

ONBUILD:当构建一个被继承 DockerFile 这个时候就会运行ONBUILD的指令,触发指令。

5.实战:

1.编写DockerFile文件:

# 1.编写Dockerfile文件
vim mydockerfile-centos
FROM centos
MAINTAINER cheng<1204598429@qq.com>

ENV MYPATH /usr/local
WORKDIR $MYPATH

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

EXPOSE 80

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

2.构建镜像:

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

3.通过docker history 镜像id可以查看镜像变更的历史:

6.CMD和ENTRYPOINT的区别:

1.CMD在容器创建时运行的命令,DockerFile里面可以有多个CMD,但是只有最后一个会生效,CMD会被docker run 之后的参数替换;

# 编写dockerfile文件
$ vim dockerfile-test-cmd
FROM centos
CMD ["ls","-a"]
# 构建镜像
$ docker build  -f dockerfile-test-cmd -t cmd-test:0.1 .
# 运行镜像
$ docker run cmd-test:0.1
.
..
.dockerenv
bin
dev

# 想追加一个命令  -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  不是命令所有报错

2.ENTRYPOINT在容器创建时运行命令,docker run之后的参数会被追加到ENTRYPOINT,形成新的命令;

# 编写dockerfile文件
$ vim dockerfile-test-entrypoint
FROM centos
ENTRYPOINT ["ls","-a"]
$ 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.实战:Tomcat镜像

1.下载tomcat、jdk8的软件包和编写好README;

2.编写DockerFile文件:

FROM centos #
MAINTAINER cheng<1204598429@qq.com>
COPY README /usr/local/README #复制文件
ADD jdk-8u231-linux-x64.tar.gz /usr/local/ #复制解压
ADD apache-tomcat-9.0.35.tar.gz /usr/local/ #复制解压
RUN yum -y install vim
ENV MYPATH /usr/local #设置环境变量
WORKDIR $MYPATH #设置工作目录
ENV JAVA_HOME /usr/local/jdk1.8.0_231 #设置环境变量
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.35 #设置环境变量
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib #设置环境变量 分隔符是:
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.构建镜像:

# 因为dockerfile命名使用默认命名 因此不用使用-f 指定文件
$ docker build -t mytomcat:0.1 .

4.创建容器:

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

8.发布镜像:

1.发布镜像到Dockerhub上:

1)、在dockerhub创建一个账号;

2)、在dockerhub创建一个仓库;

3)、登录到dockerhub:

4)、push到docker仓库:

发现push失败;

解决办法:

# 会发现push不上去,因为如果没有前缀的话默认是push到 官方的library
# 解决方法
# 第一种 build的时候添加你的dockerhub用户名,然后在push就可以放到自己的仓库了
docker build -t chengcoder/mytomcat:0.1 .
# 第二种 使用docker tag 容器id dockerhub用户名/标签名:版本号 #然后再次push
docker tag 容器id chengcoder/mytomcat:1.0 
#然后再次push
docker push chengcoder/mytomcat:1.0

2.发布镜像到阿里云上:

1)、 登录阿里云Docker Registry:

docker login --username=704926476 registry.cn-hangzhou.aliyuncs.com

2)、从Registry中拉取镜像:

docker pull registry.cn-hangzhou.aliyuncs.com/xiaolongwei/myrepository:[镜像版本号]

3)、将镜像推送到Registry:

$ sudo docker login --username=阿威学代码 registry.cn-hangzhou.aliyuncs.com
$ sudo docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/xiaolongwei/myrepository:[镜像版本号]
$ sudo docker push registry.cn-hangzhou.aliyuncs.com/xiaolongwei/myrepository:[镜像版本号]

9.小结:

12.Docker 网络

1.什么是Docker网络?

Docker网络要实现主机和docker容器进行通信,docker容器间进行通信。

2.查看网络信息:

3.进入容器中:

在容器中ping主机地址可以ping通

在主机ping容器地址也能ping通

4.原理:

为什么主机可以ping通容器,容器也可以ping通主机?

1.当安装了并启动了Docker,主机会为Docker分配一个docker0 网络ip地址,docker0使用的桥接模式(桥接模式可以分配一个和主机同一级别的ip地址);

2.每当我们启动一个容器,docker会为容器分配一个ip;

3.此时主机会创建一个ip地址和容器内地址映射,使用veth-pair技术。

5.容器之间是否可以ping通:

1.启动两个容器;

2.查看容器地址:

3.测试能否ping通:

4.结论:

tomcat01和tomcat02公用一个路由器,docker0。

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

6.小结:

Docker使用的是Linux的桥接,宿主机是一个Docker容器的网桥 docker0

所以对容器的访问都要经过docker,docker相当于一个桥,连接着容器和访问者。

Docker中所有网络接口都是虚拟的,虚拟的转发效率高(内网传递文件)

只要容器删除,对应的网桥一对就没了!

7.通过容器的名字来相互ping通

怎样让他们ping通?

在创建容器时使用--link

docker run --link 容器名 容器id 
--link 容器名 #通过容器名就可以ping通

但是tomcat01 ping tomcat02 不通过:

所以--link是单向的

原理:

1.docker查看网络信息docker network ls

2.查看Docker0的元信息docker network inspect 网络id

3.通过docker inspect tomcat02可以看到link信息:

4.查看容器内部的/etc/hosts:

--link 的本质就是在hosts文件添加了一个名字映射

这种方式现在已经基本不用了。

8.自定义网络:

自定义网络,不适用docker0!

docker0问题:不支持容器名连接访问(不支持–link)!

1.查看Docker网络信息:

docker network ls #查看所以的docker网络

Driver种类:

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

host:和主机共享的网络

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

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

2.创建网络:

#当我们创建容器时
docker run -P -d tomcat
#等价于
docker run -P -d --net bridge tomcat

#而这个bridge就是docker0
#docker0,特点:默认,域名不能访问(不能通过容器名访问)。 --link可以打通连接,但是很麻烦!

1.自定义网络

docker network create [options] 网络名 #创建网络
-d :指定驱动类型默认bridge,host,none,container
--subnet :指定子网 如192.168.0.0/16 这里的/16表示主机号占16位,可以有255*255个
--gateway :指定网关

2.查看自定义的网络信息

docker network ls #查看所以网络

3.使用自定义网络:

docker run --net 网络名 镜像id #创建容器时指定网络段

4.查看自定义网络的元数据:

docker network inspect 网络名 #查看网络元数据

查看主机的网络ip addr

5.两个容器通过名字相互ping:

发现这时没有link也能通过名称ping通

3.总结:

1.自定义网络在没有link下也能通过名字ping通(要在同一网络段上);

2.可以使用docker run --net 网络名 镜像名连接到指定网络段,默认的网络段是bridge也就是docker0;

3.不同的集群可以使用不同的网络段,保证集群的安全健康。

9.跨网络连接:

tomcat01处于mynet自定义网络段;

tomcat03处于bridge默认网络段;

此时两个容器间不能ping通。

怎样跨网络段ping通呐?

docker network connect 网络名 容器名 #容器连接到指定的网络段

把tomcat03连接到mynet网络段,测试连接:

此时tomcat03可以ping通tomcat01,也就是说tomcat03加入到了tomcat01。

那么现在的tomcat03还可以ping通原来bridge网络段的容器tomcat04吗?

tomcat03可以ping通两个不同网络段的tomcat01和tomcat04,说明tomcat03有两个网段吗?

通过docker inspect tomcat03查看到了确实有两个网段。

一个容器可以有多个网络端。

结论:假设要跨网络操作别人,就需要使用docker network connect 连通!


文章作者: 威@猫
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 威@猫 !
评论
  目录