• Overlay Network 叠加网络

  • Docker Network

    Docker 安装完成后有三种网络

        bridge

        host

        none

~]#docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
a636fa65e954        bridge              bridge              local
b4c906b718f6        host                host                local
764d5cb64812        none                null                local

    注意:如果创建容器时不指定网络类型,默认为桥接式网络(Nat桥)

    Docker的四种网络模型

    Docker Networking && Data Volume_Docker Network

    Closed container

        不参与网络通信,运行于此类容器中的进程仅能访问本地回环接口

        仅适用于进程无须网络通信的场景中,例如:备份、进程诊断及各种离线任务等

~]#docker run --rm --net none busybox:latest ifconfig -a

    Bridged container

        桥接式网络一般拥有两个接口:一个回环接口一个连接至主机上某桥设备的以太网接口

        docker daemon启动时默认会创建一个名为docker0的网络桥,并且创建的容器为桥接式容器,其以太网接口桥接至docker0

            --net bridge即为将容器接口添加至docker0桥

        docker0桥为NAT桥,因此,桥接式容器可通过此桥接口访问外部网络,但防火规则阻止了一切从外部网络访问桥接式容器的请求

~]#docker run --rm --net bridge busybox:latest ifconfig -a

    可以为docker run命令使用

        "--hostname HOSTNAME"选项为容器指定主机名,例如:

~]#docker run --rm --net bridge --hostname bbox.liuyutang.com busybox:latest

        "--dns DNS_SERVER_IP"选项能够为容器指定所使用的DNS服务器地址,例如:

~]#docker run --rm --dns 172.16.0.1 busybox:latest nslookup docker.com

        "--add-host HOSTNAME:IP"选项能够为容器指定本地主机解析项,例如:

~]#docker run --rm --dns 172.16.0.1 --add-host "docker.com:172.16.0.100" busybox:latest  nslookup docker.com

    创建容器时可设定网络类型,主机名,DNS等....(也可一起指定)

~]#docker run --name t1 -it --network bridge -h t1.liuyutang.com --dns 114.114.114.114 --dns-search ilinux.io --add-host www.liuyutang.top:1.1.1.1 --rm busybox:latest

    Opening inbound communication

    Docker0为NAT桥,因此容器一般获得的是私有网络地址;可以把容器想像为宿主机NAT服务背后的主机

    如果开放容器或其上的服务为外部网络访问,需要在宿主机上为其定义DNAT规则,例如

        对宿主机某IP地址的访问全部映射给某容器地址

            主机IP     容器IP

                -A PREROUTING -d 主机IP -j DNAT --to-destination 容器IP

        对宿主机某IP地址的某端口的访问映射给某容器地址的某端口

                主机IP:PORT     容器IP:PORT

                    -A PREROUTING -d 主机IP -p {tcp|udp} --dport 主机端口 -j DNAT --to-destination 容器IP:容器端口

    为docker run命令使用-p选项即可实现端口映射,无须手动添加规则

        -p选项的使用格式

            -p <containerPort>

                将指定的容器端口映射至主机所有地址的一个动态端口

            -p <hostPort>:<containerPort>

                将容器端口<containerPort>映射至指定的主机端口<hostPort>

            -p <ip>::<containerPort>

                将指定的容器端口<containerPort>映射至主机指定<ip>的动态端口

            -p <ip>:<hostPort>:<containerPort>

                将指定的容器端口<containerPort>映射至主机指定<ip>的端口<hostPort>

            "动态端口"指随机端口,具体的映射结果可使用docker port命令查看

        示例:

~]#docker run --name myweb --rm -p 80 liuyutang/httpd:v0.2
~]#docker run --name myweb --rm -p 172.20.128.36::80 liuyutang/httpd:v0.2
~]#docker run --name myweb --rm -p 80:80 liuyutang/httpd:v0.2
~]#docker run --name myweb --rm -p 172.20.128.36:8080:80 liuyutang/httpd:v0.2

        "-P"选项或"--publish-all"将容器的所有计划要暴露端口全部映射至主机端口

        计划要暴露的端口使用--expos选项指定

            例如

    Joined container

        联盟式网络是指使用某个已存在容器的网络接口的容器,接口被联盟内的各容器共享使用;因此,联盟式容器彼此间完全无隔离,例如:

           创建一个监听于2222端口的http服务容器

~]#docker run -d -it --rm -p 2222 busybox:latest /bin/httpd -p 2222 -f

            创建一个联盟式容器,并查看其监听端口

~]#docker run -it --rm --net container:web --name joined busybox:latest netstat -tan

    联盟式容器彼此间虽然共享同一个网络名称空间,但其它名称空间如User、Mount等还是隔离的

    联盟式容器彼此间存在端口冲突的可能性,因此,通常只会在多个容器上的程序需要程序loopback接口互相通信、或对某已存的容器的网络属性进行监控时才使用此种模式的网络模型

~]#docker run --name b2 --network container:b1 -it --rm busybox

    Open container

        开放式网络共享主机网络名称空间的容器,它们对主机的网络名称空间拥有全部的访问权限,包括访问那些关键性服务,这对宿主机安全性有很大潜在威胁

~]#docker run --name myweb --rm -p 80 liuyutang/httpd:v0.2

    修改Docker0上的默认地址

        自定义docker0桥的网络属性信息:/etc/docker/daemon.json文件

        {
            "bip": "192.168.1.5/24",
            "fixed-cidr": "10.20.0.0/16",
            "fixed-cidr-v6": "2001:db8::/64",
            "mtu": 1500,
            "default-gateway": "10.20.1.1",
            "default-gateway-v6": "2001:db8:abcd::89",
            "dns": ["10.20.1.2","10.20.1.3"]
        }

        核心选项为bip,即bridge ip之意,用于指定docker0桥自身的IP地址;其它选项可通过此地址计算得出。

 dockerd守护进程的C/S,其默认仅监听Unix Socket格式的地址,/var/run/docker.sock;如果使用TCP套接字,

            /etc/docker/daemon.json:

"hosts": ["tcp://0.0.0.0:2375", "unix:///var/run/docker.sock"]

    也可向dockerd直接传递“-H|--host”选项;

        示例:

Server:
~]#vim /etc/docker/daemon.json
{
  "registry-mirrors": ["https://registry.docker-cn.com","https://4r35ny5z.mirror.aliy
uncs.com"],
  "bip": "10.0.0.1/16",
  "hosts": ["tcp://0.0.0.0:2375", "unix:///var/run/docker.sock"]
}
~]#systemctl restart docker
Client:
~]#docker -H 172.20.128.36 image ls
~]#docker -H 172.20.128.36 container ls

    创建桥

~]#docker network create -d bridge --subnet "172.26.0.0/16" --gateway "172.26.0.1" mybr0
50193994c481b2b93bc1a2748a1e1000701a38dc0608b78491799758eb2f0859
~]#docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
185b78704ee2        bridge              bridge              local
b4c906b718f6        host                host                local
50193994c481        mybr0               bridge              local
764d5cb64812        none                null                local

    创建容器时使用新建的桥

~]#docker run --name web -it --net mybr0 busybox:latest
  • Docker Data Volume

    Docker镜像由多个只读层叠加而成,启动容器时,Docker会加载只读镜像层并在镜像栈顶部添加一个读写层

    如果运行中的容器修改了现有的一个已经存在的文件,那该文件将会从读写层下面的只读层复制到读写层,该文件的只读版本仍然存在,只是已经被读写层中该文件的副本所隐藏,此即“写时复制(COW)”机制;

    镜像内部文件系统层级组织方式:

        Docker Networking && Data Volume_Docker Network_02

    关闭并重启容器,其数据不受影响;但删除容器,则其更改将会全部丢失

    存在的问题

        存储于联合文件系统中,不易于宿主机访问;

        容器间数据共享不便

        删除容器其数据会丢失

    解决方案:“卷(Volume)”

        “卷”是容器上的一个或多个“目录”,此类目录可绕过联合文件系统,与宿主机上的某目录”绑定(关联)”

        Docker Networking && Data Volume_Docker Network_03

    存储卷,Volume

        Volume于容器初始化之时即会创建,由base image提供的卷中的数据会于此期间完成复制;

        Volume的初衷是独立于容器的生命周期实现数据持久化,因此删除容器之时既不会删除卷,也不会对哪怕未被引用的卷做垃圾回收操作;

        卷为docker提供了独立于容器的数据管理机制

            可以把“镜像”想像成静态文件,例如“程序”,把卷类比为动态内容,例如“数据”;于是,镜像可以重用,而卷可以共享;

            卷实现了“程序(镜像)”和“数据(卷)”分离,以及“程序(镜像)”和“制作镜像的主机”分离,用户制作镜像时无须再考虑镜像运行的容器所在的主机的环境

    Docker Networking && Data Volume_Docker Network_04

    应用可分为

        有状态:当前这次连接请求的处理是与此前的处理有关联关系

        无状态:前后应用处理没有关联关系

    应用是否需要存储数据可用数轴来表示

    Docker Networking && Data Volume_Docker Network_05        

卷类型

    Docker有两种类型的卷,每种类型都在容器中存在一个挂载点,但其在宿主机上的位置有所不同;

        Bind mount volume    绑定挂载卷

            宿主机上和容器上需要人工指定特定的路径,让两者建立绑定关系

        Docker-managed volume    Docker管理卷

            在容器内指定容器的挂载点而不需要指定被绑定的宿主机目录,由容器引擎daemon自行创建一个空目录,与存储卷路径建立关联关系(目录名称通常为ID号)

    Docker Networking && Data Volume_Docker Network_06

    在容器中使用Volumes       

        为docker run命令使用-v选项即可使用Volume

            Docker-managed volume

~]#docker run -it -name bbox1 –v /data busybox
~]#docker inspect -f {{.Mounts}} bbox1

         查看bbox1容器的卷、卷标识符及挂载的主机目录

            Bind-mount Volume

~]#docker run -it -v HOSTDIR:VOLUMEDIR --name bbox2 busybox
~]#docker inspect -f {{.Mounts}} bbox2

        示例1:Docker管理的卷

~]#docker run --name t1 -it -v /data/ busybox
~]#docker inspect t1   在另一个终端执行,我们可看到t1容器的相关信息(卷的绑定路径)
~]#cd /var/lib/docker/volumes/29d8466b44f90edcb1c435be26fc91ed28906eeac59e4fe49291903dcd828811/_data
~]#echo "hello container" >> test.html
/ # ls /data/
test.html
/ # cat /data/test.html 
hello container     在容器中同样可看到在宿主机中创建的文件

        示例2:绑定挂载卷;在操作过程中,不要退出容器,新建一个终端来操作

~]#docker run --name t2 -it --rm -v /data/volumes/t2:/data busybox
~]#docker inspect t2
~]#cd /data/volumes/t2/
~]#echo "<h1>Busybox httpd server.</h1>" > test.html
/ # ls
/ # cat /data/test.html 
<h1>Busybox httpd server.</h1>
/ # exit
~]#docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
~]#docker run --name t2 -it --rm -v /data/volumes/t2:/data/web/html busybox
/ # cat /data/web/html/test.html 
<h1>Busybox httpd server.</h1>
/ # exit

        使用模板来过滤容器的信息

~]#docker inspect -f {{.Mounts}} t2
[{bind  /data/volumes/t2 /data/web/html   true rprivate}]
~]#docker inspect -f {{.NetworkSettings}} t2      
{{ c6c9df9f54621d02729c97c519b92e45a7968b9243e467d7de5de3a826bdcb58 false  0 map[] /var/run/docker/netns/c6c9df9f5462 [] []} {51d6659d37356cad6b4c22f067b3a25a2e01c1f59122f1919a101435cefb3e7c 10.0.0.1  0 10.0.0.2 16  02:42:0a:00:00:02} map[bridge:0xc420158180]}
~]#docker inspect -f {{.NetworkSettings.IPAddress}} t2 
10.0.0.2

        多个容器使用同一主机目录,例如

~]#docker run –it --name c1 -v /docker/volumes/v1:/data busybox
~]#docker run –it --name c2 -v /docker/volumes/v1:/data busybox

        复制使用其它容器的卷,为docker run命令使用--volumes-from选项

~]#docker run -it --name bbox1 -v /docker/volumes/v1:/data busybox
~]#docker run -it --name bbox2 --volumes-from bbox1 busybox
~]#docker run --name infracon -it -v /data/infracon/volumes/:/data/web/html busybox
~]#docker run --name nginx --network container:infracon --volumes-from infracon -it busybox