本小菜鸟以前写的几篇docker的文章在自己的博客网站上,现在服务器要到期了,本小菜鸟也难得维护了,正式宣布躺平,博客地址 如果有错误的地方,欢迎大家联系我指正,谢谢
一、docker的基本介绍和安装
1.1 docker简介
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器或Windows 机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。
好了啦!不豁你们了,上面这些个简介都是由度娘的百科Ctrl + C来的,想深入了解docker进化史的狗子们可以自己打开百度百科,这里就不做过多的阐述了,毕竟搬砖工程师一句hello world 都不想手敲,respect!!
1.2 docker和虚拟机的比较
容器和虚拟机具有相似的资源隔离和分配优势,但功能不同,因为容器虚拟的是操作系统而不是硬件。容器更便携,更高效。。。(传统虚拟机是虚拟出一条硬件,运行一个完整的操作系统,然后在这个系统上运行软件,但是容器内的应用是直接运行在宿主机的内核中的,它没有自己的内核,也没得虚拟机那种硬件,所以更加轻便)
虚拟机技术:
虚拟机 (VM) 是将一台服务器变成多台服务器的物理硬件的抽象。管理程序允许多个 VM 在一台机器上运行。每个 VM 都包含操作系统、应用程序、必要的二进制文件和库的完整副本 - 占用数十 GB。VM 的启动速度也可能很慢。
容器技术:
容器是应用层的抽象,将代码和依赖项打包在一起。多个容器可以在同一台机器上运行,并与其他容器共享操作系统内核,每个容器作为用户空间中的独立进程运行。容器占用的空间比 VM 少(容器映像的大小通常为数十 MB),可以处理更多应用程序,并且需要更少的 VM 和操作系统。
屁话时间:所以呢,容器技术对比虚拟机技术优点还是多多滴
1.3 docker安装
上面屁话有点多~,好,接下来我们进入正题docker的安装
但是在安装之前呢,先要给大家介绍几个docker中比较重要的东西,我们直接上图
镜像(image):Docker镜像是用来启动容器的,可以将镜像想像成python中面向对象编程的类,它可以由dockerfile创建,也可以从第三方直接下载,它是我们提供应用程序运行的基础。
容器(container):容器主要是用来真正运行程序员开发的应用程序的。一个Docker镜像可以实例化出来多个容器,而每一个容器之间是独立运行的,没有任何依赖。类似于面向对象编程中的实例化后的对象。可视为一个简易的Linux系统。
仓库(repository):存放镜像的地方,类似于git中的github,而在docker中存在dockerhub,分为公有仓库和私有仓库,国内有阿里云。。。
安装:
1.查看服务器环境
#系统内核
[root@VM-0-13-centos ~]# uname -r
4.18.0-305.10.2.el8_4.x86_64
2.卸载久的docker版本
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
3.设置存储仓库
#安装需要的包
sudo yum install -y yum-utils
#设置镜像源------此条为国外的镜像源,速度较慢,不推荐,建议使用下面#国内阿里云的镜像源
sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
#阿里云镜像源
sudo yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
4.安装docker docker-ce社区版本
sudo yum install docker-ce docker-ce-cli containerd.io
5.启动docker
[root@VM-0-13-centos ~]# sudo systemctl start docker
[root@VM-0-13-centos ~]# docker -v
Docker version 20.10.8, build 3967b7d
6.启动hello world 镜像
[root@VM-0-13-centos ~]# sudo docker run hello-world
[root@VM-0-13-centos ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest d1165f221234 6 months ago 13.3kB
好了好了~ 终于搞定了 以上步骤都是根据docker官方文档操作的
地址:https://docs.docker.com/engine/install/centos/
由于本人呢实在是比较懒,所以配置阿里云镜像加速的操作就不演示了,有兴趣的童孩阔以研究一下,好了先拜拜了
二、docker镜像及容器的常用命令
话不多说,直接上干货
2.1镜像的基本命令
docker images
查看本地主机上所有的镜像
[root@VM-0-13-centos ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest d1165f221234 6 months ago 13.3kB
#可选项 -a (列出所有的镜像) -q (只显示镜像的id)
[root@VM-0-13-centos ~]# docker images -a
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest d1165f221234 6 months ago 13.3kB
[root@VM-0-13-centos ~]# docker images -aq
d1165f221234
docker search
和docker pull
#docker search 搜索镜像
[root@VM-0-13-centos ~]# docker search python
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
python Python is an interpreted, interactive, objec… 6545 [OK]
#docker pull 下载镜像 后面可跟版本号
[root@VM-0-13-centos ~]# docker pull python:3.8
3.8: Pulling from library/python
955615a668ce: Pull complete
2756ef5f69a5: Pull complete
911ea9f2bd51: Pull complete
27b0a22ee906: Pull complete
8584d51a9262: Pull complete
524774b7d363: Pull complete
9460f6b75036: Pull complete
9bc548096c18: Pull complete
1d87379b86b8: Pull complete
Digest: sha256:c2842aababbe377f9c76f172d9eb39487e23f306b2f29f020f3f6654cb0876e9
Status: Downloaded newer image for python:3.8
docker.io/library/python:3.8
[root@VM-0-13-centos ~]# docker images -a
REPOSITORY TAG IMAGE ID CREATED SIZE
python 3.8 ff08f08727e5 12 days ago 909MB
hello-world latest d1165f221234 6 months ago 13.3kB
---- 这里的pull complete 下载为docker的分层下载 docker image 的核心 联合文件系统
docker rmi
删除镜像
[root@VM-0-13-centos ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest 5d0da3dc9764 4 days ago 231MB
python 3.8 ff08f08727e5 12 days ago 909MB
mysql 5.7 1d7aba917169 2 weeks ago 448MB
[root@VM-0-13-centos ~]# docker rmi -f centos
Untagged: centos:latest
Untagged: centos@sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177
Deleted: sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6
Deleted: sha256:74ddd0ec08fa43d09f32636ba91a0a3053b02cb4627c35051aff89f853606b59
#删除所有的镜像
[root@VM-0-13-centos ~]# docker rmi -f $(docker images -aq)
2.2容器的基本命令
说明:创建一个容器的前提是拥有镜像
docker run
运行一个容器
[root@VM-0-13-centos ~]# docker run -it --name python04 python:3.8 /bin/bash
root@93d42cc3b0b8:/# ls
bin boot dev etc home lib lib64 media
#选项 -it 终端形式启动容器 --name 容器的名字 /bin/bash 终端连接到容器的 Shell 终端之上
#exit 退出容器(容器随着其中运行应用的退出而终止,其中 Linux 容器会在 Bash Shell 退出后终止)
root@93d42cc3b0b8:/# exit
exit
[root@VM-0-13-centos ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
#当我们以exit命令退出容器过后 用ps看到此时没有容器在运行 用快捷键Ctrl+p+q 退出时 容器继续运行
#选项 -d 后台模式启动容器
[root@VM-0-13-centos ~]# docker run -d --name python01 python:3.8 /bin/bash
d82a7c35cbe092c0fff8a4b9cd6e6df3a92ff3cd50ee7b3bd39038ed6f79b2f5
[root@VM-0-13-centos ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d82a7c35cbe0 python:3.8 "/bin/bash" 7 seconds ago Restarting (0) Less than a second ago
docker exec
进入容器
#docker exec 进入容器 注:为了使该命令生效,用于创建容器的镜像必须包含 Bash Shell
[root@VM-0-13-centos ~]# docker exec -it python04 /bin/bash
root@e21894d69cf2:/# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 02:37 pts/0 00:00:00 /bin/bash
root 7 0 0 02:38 pts/1 00:00:00 /bin/bash
root 13 7 0 02:38 pts/1 00:00:00 ps -ef
root@e21894d69cf2:/#
docker stop
停止容器,
docker start
启动处于停止状态的容器,
docker rm
删除容器 ,
docker restart
重启容器,
docker inspect
显示容器运行时的配置信息
[root@VM-0-13-centos ~]# docker inspect python04
[
{
"Id": "e21894d69cf26f25e3f97e502cd421a2d9cfe509916ed25cdd846078c9b3411b",
"Created": "2021-09-22T02:37:56.043170384Z",
"Path": "/bin/bash",
"Args": [],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
[root@VM-0-13-centos ~]# docker start python04
python04
[root@VM-0-13-centos ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e21894d69cf2 python:3.8 "/bin/bash" 9 minutes ago Up 3 seconds python04
[root@VM-0-13-centos ~]# docker stop python04
python04
[root@VM-0-13-centos ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@VM-0-13-centos ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e21894d69cf2 python:3.8 "/bin/bash" 10 minutes ago Exited (137) 34 seconds ago python04
[root@VM-0-13-centos ~]# docker rm e21894d69cf2
e21894d69cf2
[root@VM-0-13-centos ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
以上就是本菜鸟总结的容器和镜像中比较常用的基础命令了
三、联合文件系统及容器数据卷
3.1联合文件系统
上一节在docker image pull 命令讲解的时候 提到过image pull 的过程 有提到分层下载和联合文件系统这两个概念
联合文件系统
联合文件系统:是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(类似于git代码的提交,从最开始的一个基础代码然后不断的更新提交形成一个新的项目),联合文件系统是docker镜像的基础,镜像可以通过分层来实现的,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像,最终的效果是:一次同时加载多个文件系统,但是从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包函所有底层的文件和目录
分层的原理
分层原理:所有的docker镜像都起始于一个基础镜像层,当进行修改或者增加新的内容时,就会在当前镜像层之上,创建新的镜像层,比如:假设基于Ubuntu Linux 16.04创建一个新的镜像,这就是新镜像的第一层,如果在该镜像中添加python包,就会在基础镜像层之上创建第二个镜像层,如果继续添加一个安全补丁,就会创建第三个镜像层,该镜像当前已经包含3个镜像层。
在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点非常重要!
注意:假如在docker中又添加了python的最新版本,这时,docker并不会新增加一层,而是用最新版本的python替换了原来的旧版本python!
3.2数据卷
场景:
1、我们把项目的mysql数据都用docker来进行部署存储了,但是docker容器删除过后,存在docker容器内的数据也随之消失了,那岂不是删库跑路了?那我们如何将这些数据进行持久化呢?
2.当容器启动过后,我们想要访问容器内的某些数据的时候,每次都要使用exec 命令进入容器,这为我们的开发带来了很大的不便,那么我们有没有更加方便的方法呢?
3.前面我们说到,docker容器与容器之间是相互隔离的,那么就会存在多个容器中的数据无法共享,这个问题我们有没有办法可以解决呢?
为了应对以上的问题呢,docker很贴心的为大家引入了数据卷的机制(volume),
volume是存在一个或多个容器中的特定文件或文件夹,这个目录能够独立于联合文件系统的形式在宿主机中存在,并为数据的共享与持久提供一下便利。
(1)volume在容器创建时就初始化,在容器运行时就可以使用其中的文件
(2)volume能在不同的容器之间共享和重用
(3)对volume中的数据的操作会马上生效
(4)对volume中数据操作不会影响到镜像本身
(5)volume的生存周期独立于容器的生存周期,即使删除容器,volume仍然会存在,没有任何容器使用的volume也不会被Docker删除
使用数据卷
- 直接使用命令来挂载
docker run -it -v
主机目录:容器内目录
[root@VM-0-13-centos test]# pwd
/root/test
[root@VM-0-13-centos test]# ls
[root@VM-0-13-centos test]# docker run -it -v /root/test:/opt --name centos01 centos /bin/bash
[root@67c8cb25983d /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@67c8cb25983d /]# cd opt
[root@67c8cb25983d opt]# ls
[root@67c8cb25983d opt]# touch test.text
[root@67c8cb25983d opt]# ls
test.text
[root@67c8cb25983d opt]# vi test.text
[root@67c8cb25983d opt]# cat test.text
hello world
[root@67c8cb25983d opt]#
# 启动centos01 容器 并将该容器的/opt目录挂载到服务器/root/test目录下,并在容器内/opt目录下新建
# test.text文件,并在这个文件中写入hello world
上面的操作都是在容器中操作的,接下来我们去服务器上看:
[root@VM-0-13-centos test]# pwd
/root/test
[root@VM-0-13-centos test]# ls
test.text
[root@VM-0-13-centos test]# cat test.text
hello world
[root@VM-0-13-centos test]#
#我们由此可见,/root/test目录下给我们新建了一个test.text文件,并且里面有内容hello world
这时我们去查看docker容器的基本信息:docker inspect
[root@VM-0-13-centos test]# docker inspect centos01
"Mounts": [
{
"Type": "bind",
"Source": "/root/test",
"Destination": "/opt",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
我们可以看到容器内的挂载信息,服务器的目录和容器内的目录,并且将该容器删除过后,数据依旧存在
具名和匿名挂载
匿名挂载:不指定服务器上的挂载目录
[root@VM-0-13-centos test]# docker run -it -v /opt/niming --name centos01 centos /bin/bash
[root@8eb613933e2f /]# cd /opt
[root@8eb613933e2f opt]# ls
niming
[root@8eb613933e2f opt]# cd niming
[root@8eb613933e2f niming]# vim nm.txt
[root@8eb613933e2f niming]# cat nm.txt
niming test
#同样的在挂载目录下新建一个文件并输入内容
我们在服务器上查看一下容器的挂载信息:docker volume ls
[root@VM-0-13-centos test]# docker volume ls
DRIVER VOLUME NAME
local 9c0345edefd99ac7cc8815d7d0c4ea9d77e727b4c5c3928ffa6145dac0420bd4
[root@VM-0-13-centos test]#
#这里的VOLUME NAME 就是挂载在服务器上的地址
#查看上面匿名挂载的信息
"Mounts": [
{
"Type": "volume",
"Name": "9c0345edefd99ac7cc8815d7d0c4ea9d77e727b4c5c3928ffa6145dac0420bd4",
"Source": "/var/lib/docker/volumes/9c0345edefd99ac7cc8815d7d0c4ea9d77e727b4c5c3928ffa6145dac0420bd4/_data",
"Destination": "/opt/niming",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
#从上面可以看到挂载到服务器上的/var/lib/docker/volumes目录下的,我们进入这个目录查看一下
[root@VM-0-13-centos _data]# cd /var/lib/docker/volumes
[root@VM-0-13-centos volumes]# ls
9c0345edefd99ac7cc8815d7d0c4ea9d77e727b4c5c3928ffa6145dac0420bd4 backingFsBlockDev metadata.db
[root@VM-0-13-centos volumes]# cd 9c0345edefd99ac7cc8815d7d0c4ea9d77e727b4c5c3928ffa6145dac0420bd4
[root@VM-0-13-centos 9c0345edefd99ac7cc8815d7d0c4ea9d77e727b4c5c3928ffa6145dac0420bd4]# ls
_data
[root@VM-0-13-centos 9c0345edefd99ac7cc8815d7d0c4ea9d77e727b4c5c3928ffa6145dac0420bd4]# cd _data/
[root@VM-0-13-centos _data]# ls
nm.txt
[root@VM-0-13-centos _data]# cat nm.txt
niming test
[root@VM-0-13-centos _data]#
#由上面服务器进入到挂载目录内,可以看到也存在nm.txt 并且有niming test
拓展:
不用启动命令挂载,用dockerfile进行挂载 VOLUME [“容器内目录1”,“容器内目录2”] 可以挂载多个
四、dockerfile详解
前面我们学习的镜像都是直接从dockerhub上面pull的镜像,但是这些基础的镜像是不能满足我们日常的项目运行需求的,如果我们需要自定义一个image该怎么办呢?
这个时候Dockerfile就派上用场了,那么什么是Dockerfile呢? 简单的来说 Dockerfile就是一个用来构建镜像的文本文件
Dockerfile文件中常用的命令
使用dockfile创建镜像三个步骤:编写dockerfile ---> docker build -t 创建image --> docker run 启动容器
第一步:
编写dockerfile文件
FROM image_name:tag #指定新镜像的基础镜像,dockerfile的第一条指令必须是FROM指令,每创建一个镜像就需要一个FROM指令
MAINTAINER username<email address> #镜像作者信息 我们通常使用名字和邮箱地址
RUN #在基础镜像上要执行的命令
EXPOSE 端口号 #容器内要打开的端口号
ENV 环境变量 变量值 # 设置环境变量 与run命令中的 -e 效果相同
ADD 源文件/目录 目标文件/目录 # 将源文件复制到目标文件,如果源文件为压缩文件复制过后会自动解压
COPY 源文件/目录 目标文件/目录 # 将源文件复制到目标文件
VOLUME ["目录"] # 在文件中创建一个挂载点 (前面讲的匿名挂载)
WORKDIR 路径 #和cd 命令相同 切换工作路径的作用
CMD ["要运行的程序","参数","参数"] #类似于 RUN 指令,用于运行程序 CMD指定在 Dockerfile 中只能使用一次,如果有多个,则只有最后一个会生效。
ENTRYPRINT ["要运行的程序","参数","参数"] #类似于 CMD 指令
利用Python3.8这个基础的镜像 搭建一个测试的django服务镜像dockerfile
[root@VM-0-13-centos]# ls
Django-2.1.7.tar.gz Dockerfile epel.repo run.sh
先下载django的包到本地
编写dockerfile
FROM python:3.8
MAINTAINER xiaocainiao<xxxxxxx@qq.com>
ADD epel.repo /etc/yum.repos.d
ADD Django-2.1.7.tar.gz /opt/
WORKDIR /opt/
RUN mv Django-2.1.7 django
WORKDIR /opt/django
RUN python3 setup.py install
WORKDIR /opt
RUN django-admin.py startproject test
ADD run.sh /opt/test/run.sh
RUN sed -i "s/ALLOWED_HOSTS = \[\]/ALLOWED_HOSTS = \['\*'\]/g" /opt/test/test/settings.py
WORKDIR /opt/test
RUN chmod 777 run.sh
EXPOSE 8000
ENTRYPOINT ["/bin/bash","run.sh"]
编写run.sh
python manage.py runserver 0.0.0.0:8000
根据dockerfile创建一个镜像
[root@VM-0-13-centos xiaocainiao]# docker build -t djangotest:2.0 .
[root@VM-0-13-centos xiaocainiao]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
djangotest 2.0 5116093b17f5 About a minute ago 1.04GB
djangotest 1.0 aa1b4523718d 14 hours ago 1.04GB
centos latest 5d0da3dc9764 7 days ago 231MB
python 3.8 ff08f08727e5 2 weeks ago 909MB
django latest eb40dcf64078 4 years ago 436MB
[root@VM-0-13-centos xiaocainiao]#
根据djangotest:2.0创建一个容器 并把服务器的8000端口和容器内的8000映射
[root@VM-0-13-centos xiaocainiao]# docker run -it -p 8000:8000 --name djtest djangotest:2.0 /bin/bash
Performing system checks...
System check identified no issues (0 silenced).
You have 15 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.
September 23, 2021 - 03:05:59
Django version 2.1.7, using settings 'test.settings'
Starting development server at http://0.0.0.0:8000/
Quit the server with CONTROL-C.
可以看到我们的django服务已经搭建完成
五、docker 网络
#通过ip addr 获取当前ip地址
[root@VM-0-13-centos ~]# 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: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 52:54:00:bf:43:8d brd ff:ff:ff:ff:ff:ff
inet 10.0.0.13/22 brd 10.0.3.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet6 fe80::5054:ff:febf:438d/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:06:31:00:fc 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:6ff:fe31:fc/64 scope link
valid_lft forever preferred_lft forever
313: veth89c9c9d@if312: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether b6:7f:04:01:ba:58 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::b47f:4ff:fe01:ba58/64 scope link
valid_lft forever preferred_lft forever
[root@VM-0-13-centos ~]#
可看到上面三个地址
lo
:本机回环地址
eth0
:腾讯云内网地址
docker0
:docker0地址
思考:如果我们一个容器中运行的我们的项目代码,另外一个容器中则是我们的MySQL存放地,那么我们在项目代码中如何连接我们的MySQL呢?
我们启动一个容器
[root@VM-0-13-centos test]# docker run -td --name test test /bin/bash
04bd6b32bd976ff449a3dc53d85c2e52d0bbc2d2f03da58efc95394a3355b09a
[root@VM-0-13-centos test]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
04bd6b32bd97 test "/bin/bash" 3 seconds ago Up 2 seconds test
d79eb5f4f57f djangotest:2.0 "/bin/bash run.sh /b…" 10 hours ago Up 9 hours 0.0.0.0:8000->8000/tcp, :::8000->8000/tcp djtest
[root@VM-0-13-centos test]#
我们启动了一个test的容器
查看容器内的网络地址:docker exec -it d_name ip addr
[root@VM-0-13-centos test]# docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' test
172.17.0.3
上面查询得到docker 为test这个容器的ip地址为 172.17.0.3
我们尝试在本机ping一下该网络
[root@VM-0-13-centos test]# ping 172.17.0.3
PING 172.17.0.3 (172.17.0.3) 56(84) bytes of data.
64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.062 ms
64 bytes from 172.17.0.3: icmp_seq=2 ttl=64 time=0.052 ms
64 bytes from 172.17.0.3: icmp_seq=3 ttl=64 time=0.048 ms
64 bytes from 172.17.0.3: icmp_seq=4 ttl=64 time=0.040 ms
64 bytes from 172.17.0.3: icmp_seq=5 ttl=64 time=0.048 ms
原理:我们每启动一个容器,docker都会给docker容器分配一个ip,只要我们安装了docker 那么我们的电脑上就会存在一个docker0(类似于一个网卡)桥接模式,使用的技术是evth-pair 技术
此时我们再次启动一个容器:docker run -td -P --name test01 test /bin/bash
然后我们再次看ip addr
[root@VM-0-13-centos test]# 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: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 52:54:00:bf:43:8d brd ff:ff:ff:ff:ff:ff
inet 10.0.0.13/22 brd 10.0.3.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet6 fe80::5054:ff:febf:438d/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:06:31:00:fc 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:6ff:fe31:fc/64 scope link
valid_lft forever preferred_lft forever
313: veth89c9c9d@if312: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether b6:7f:04:01:ba:58 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::b47f:4ff:fe01:ba58/64 scope link
valid_lft forever preferred_lft forever
341: vethd34d551@if340: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether 1e:df:07:66:33:bd brd ff:ff:ff:ff:ff:ff link-netnsid 1
inet6 fe80::1cdf:7ff:fe66:33bd/64 scope link
valid_lft forever preferred_lft forever
上面地址又多了一对 341- 340网卡,而像这种成对出现的就是veth-pair技术,就是一对虚拟设备接口,(类似于在两个密闭的房间中打开了两扇窗,有了这两扇窗,原本在密闭房间中的人就可以相互交流了)
自定义网络
查看所有的网络
[root@VM-0-13-centos test]# docker network ls
NETWORK ID NAME DRIVER SCOPE
a24b7259aa7c bridge bridge local
9a21880668ca host host local
9645e49e3450 none null local
[root@VM-0-13-centos test]#
birdge
:桥接模式
none
:不配置网络
host
:主机网络(和宿主机共享网络)
自定义创建的网络 也使用桥接网络
#我们原始启动容器的命令 --net bridge 为默认,而这个就是我们的桥接模式docker0
docker run -d -P --name test test
docker run -d -P --name test --net bridge test
#docker0是默认的网络 使用--link添加容器 可以访问 但是存在缺陷
因此 我们可以使用自定义网络
[root@VM-0-13-centos test]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mytestnet
bce4e060d64b2fa9e90bf6330eeb80410a7e19c299405e95a46b2f820b66ed31
[root@VM-0-13-centos test]# docker network ls
NETWORK ID NAME DRIVER SCOPE
a24b7259aa7c bridge bridge local
9a21880668ca host host local
bce4e060d64b mytestnet bridge local
9645e49e3450 none null local
#--driver bridge 桥接
#--subnet 192.168.0.0/16 设置子网的地址
#--gateway 192.168.0.1 设置网关 (路由器)
#mytestnet 自定义网络的名字
查看我们刚刚自定义的网络
[root@VM-0-13-centos test]# docker network inspect mytestnet
[
{
"Name": "mytestnet",
"Id": "bce4e060d64b2fa9e90bf6330eeb80410a7e19c299405e95a46b2f820b66ed31",
"Created": "2021-09-23T23:36:47.733635814+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.0.0/16",
"Gateway": "192.168.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
[root@VM-0-13-centos test]#
Subnet Gateway就是我们自定义配置的网络
此时我们再次启动两个容器:
[root@VM-0-13-centos test]# docker run -d -P --name test-net-01 --net mytestnet djangotest:2.0 /bin/bash
f96f8ed9746100191593b0fb1bd425f0fe202ba171e676a028d1e8a24b2c0b98
[root@VM-0-13-centos test]# docker run -d -P --name test-net-02 --net mytestnet djangotest:2.0 /bin/bash
66a4e37819948c3a011ec6c7bf474f6fe95fdf5a09170bd1f9a43443fc7dcf96
[root@VM-0-13-centos test]# docker network inspect mytestnet
[
{
"Name": "mytestnet",
"Id": "bce4e060d64b2fa9e90bf6330eeb80410a7e19c299405e95a46b2f820b66ed31",
"Created": "2021-09-23T23:36:47.733635814+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.0.0/16",
"Gateway": "192.168.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"66a4e37819948c3a011ec6c7bf474f6fe95fdf5a09170bd1f9a43443fc7dcf96": {
"Name": "test-net-02",
"EndpointID": "f1e21b33aac990b8313cac727c932618ac5e3f04f1a4d2029048feffa17880bd",
"MacAddress": "02:42:c0:a8:00:03",
"IPv4Address": "192.168.0.3/16",
"IPv6Address": ""
},
"f96f8ed9746100191593b0fb1bd425f0fe202ba171e676a028d1e8a24b2c0b98": {
"Name": "test-net-01",
"EndpointID": "dc8c06e769ccfe2be5ad319546b347b0b8a064b9d718346897f67814873b67e7",
"MacAddress": "02:42:c0:a8:00:02",
"IPv4Address": "192.168.0.2/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
[root@VM-0-13-centos test]#
上面可以看到 容器test-net-01 和test-net-02在我们的mytestnet网络下而且分配的地址是:192.168.0.2 192.168.0.3
root@VM-0-13-centos test]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
66a4e3781994 djangotest:2.0 "/bin/bash run.sh /b…" 3 minutes ago Up 3 minutes 0.0.0.0:49154->8000/tcp, :::49154->8000/tcp test-net-02
f96f8ed97461 djangotest:2.0 "/bin/bash run.sh /b…" 3 minutes ago Up 3 minutes 0.0.0.0:49153->8000/tcp, :::49153->8000/tcp test-net-01
eee05a525465 test "/bin/bash" 29 minutes ago Up 29 minutes test02
ea805932ebe8 test "/bin/bash" 29 minutes ago Up 29 minutes test01
5eb235f07fd1 djangotest:2.0 "/bin/bash run.sh /b…" About an hour ago Up About an hour 0.0.0.0:8000->8000/tcp, :::8000->8000/tcp djtest
[root@VM-0-13-centos test]# docker exec -it test-net-01 ping test-net-02
这样直接由test-net-01 ping test-net-02 可以ping通,直接ping 分配的ip也可
这样的好处是 不同的集群用不同的ip 完全隔离
当我们的集群在不同的两个网段的时候 如:MySQL集群在172.18.0.1 这个网段 而我们的redis的集群在192.168.0.1这个网段 是不能够直接通信的,这个时候我们就要配置MySQL集群中的容器和我们redis集群的网段进行连通,即连接一个容器到一个网段
[root@VM-0-13-centos test]# docker network --help
Usage: docker network COMMAND
Manage networks
Commands:
connect Connect a container to a network
create Create a network
disconnect Disconnect a container from a network
inspect Display detailed information on one or more networks
ls List networks
prune Remove all unused networks
rm Remove one or more networks
Run 'docker network COMMAND --help' for more information on a command.
[root@VM-0-13-centos test]#
docker network --help
查看到 :connect ----> 连接一个容器到网络
测试:我们将容器test连接到mytestnet这个网络中
[root@VM-0-13-centos test]# docker network connect mytestnet test01
[root@VM-0-13-centos test]# docker inspect mytestnet
[
{
"Name": "mytestnet",
"Id": "bce4e060d64b2fa9e90bf6330eeb80410a7e19c299405e95a46b2f820b66ed31",
"Created": "2021-09-23T23:36:47.733635814+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.0.0/16",
"Gateway": "192.168.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"66a4e37819948c3a011ec6c7bf474f6fe95fdf5a09170bd1f9a43443fc7dcf96": {
"Name": "test-net-02",
"EndpointID": "f1e21b33aac990b8313cac727c932618ac5e3f04f1a4d2029048feffa17880bd",
"MacAddress": "02:42:c0:a8:00:03",
"IPv4Address": "192.168.0.3/16",
"IPv6Address": ""
},
"ea805932ebe8de1d3df941c842514a0f6927a8f8734d969eebb5b83331338175": {
"Name": "test01",
"EndpointID": "15a1457f12d11aeb873c0c475bc992e69a7047e0774ab2e5d738a45f62cd3943",
"MacAddress": "02:42:c0:a8:00:04",
"IPv4Address": "192.168.0.4/16",
"IPv6Address": ""
},
"f96f8ed9746100191593b0fb1bd425f0fe202ba171e676a028d1e8a24b2c0b98": {
"Name": "test-net-01",
"EndpointID": "dc8c06e769ccfe2be5ad319546b347b0b8a064b9d718346897f67814873b67e7",
"MacAddress": "02:42:c0:a8:00:02",
"IPv4Address": "192.168.0.2/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
[root@VM-0-13-centos test]#
查看mytestnet网络下 存在了容器test(一个容器两个ip 类似服务器的两个ip 公网ip和私网ip)
需要跨网络操作别人 就需要使用docker network connect
进行连通
感谢:本菜鸟当初是跟着【狂神说Java】学习的docker相关知识,所以在此特别谢谢他 ,给大佬鞠躬!!!