docker 相关知识

本小菜鸟以前写的几篇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镜像的基本命令
  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
  1. docker searchdocker 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 的核心 联合文件系统

  1. 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容器的基本命令

说明:创建一个容器的前提是拥有镜像

  1. 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   
  1. 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:/# 
  1. 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删除

使用数据卷

  1. 直接使用命令来挂载 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相关知识,所以在此特别谢谢他 ,给大佬鞠躬!!!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值