docker4-docker网络,容器编排,集群部署

1,docker网络

1.1,docker0

有三个网络环境,那么docker是如何处理容器网络访问的?

1.2,测试

docker run -d -p 80:8080 --name tomcat01 tomcat
docker exec -it tomcat01 ip addr

本地可以ping通容器内部

1.3,原理

  • 只要安装了docker,就会有一个docker的ip-docker0(这里是172.17.0.1),这里的ip分配用的是桥接模式、veth-pair技术

    • veth-pair:一对虚拟设备接口,成对出现,一端连着协议,一端彼此相连;veth-pair充当一个桥梁,连接各种虚拟网络设备。
    • openstac,docker容器之间的连接,OVS的连接,都是使用veth-pair技术。
  • 每启动一个docker容器,docker都会给容器分配一个ip(为tomcat分配172.17.0.2)

  • 借助于宿主机,容器之间也可相互通信

    容器和宿主机通信

    容器之间通信

1.4,结论

  • 容器和宿主机是可以通信的

  • 容器和容器之间也是可以通信的,但使用docker0必须写明ip

  • 所用容器默认启动不指定网络的情况下,都是docker0进行路由的,docker会给容器分配一个默认的可用ip

  • docker使用的是linux的桥接,docker0是所有容器的网桥

  • docker中的所有网络接口都是虚拟的,虚拟的转发效率高

  • 容器删除,对应的网桥对就没了

    docker网络0 docker网络0

2,link连接

2.1,测试及原理

是否可以使用容器名实现容器之间的通信?
docker exec -it tomcat01 ping tomcat02
发现不行
ping: tomcat02: Name or service not known

使用--link实现容器之间的连接
docker run -d -P --name tomcat03 --link tomcat02 tomcat
再使用容器名进行通信
[root@VM-0-11-centos ~]# docker exec -it tomcat03 ping tomcat02
PING tomcat02 (172.17.0.3) 56(84) bytes of data.
64 bytes from tomcat02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.114 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.029 ms
[root@VM-0-11-centos ~]# docker exec -it tomcat02 ping tomcat03
ping: tomcat03: Name or service not known

显示网络配置,发现03中将02直接写入了网络配置
[root@VM-0-11-centos ~]# 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.17.0.3      tomcat02 3ba10f8d5d4e
172.17.0.4      40fb066c620a
[root@VM-0-11-centos ~]# docker exec -it tomcat02 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.17.0.3      3ba10f8d5d4e

--link就相当于在容器的网络配置中增加了目标容器的映射

2.2,步骤总结

  • 使用--link连接

    docker run -d -P --name tomcat03 --link tomcat02 tomcat
    
  • 容器之间通信

    [root@VM-0-11-centos ~]# docker exec -it tomcat03 ping tomcat02
    

3,自定义网络

3.1,网络模式

  • bridge:桥接(docker默认,自己创建网络也使用该模式)
  • none:不配置网络
  • host:和宿主机共享网络
  • container:容器网络连通(局限性大)

3.2,自定义网络测试

首先要明白,以下两种启动方式是相同的(启动时--net不写网络默认使用bridge模式):
docker run -d -P --name tomcat01 tomcat
docker run -d -P --name tomcat01 --net bridge tomcat

docker0的特点:默认、通过容器名不能相互访问,--link可以打通连接,但是--link使用比较麻烦,因此我们可以自定义网络。
[root@VM-0-11-centos ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
8a3cfa860aaed386afc07a3b02f77edaec61a24a6095c7b6c165f1fa54bd7594
[root@VM-0-11-centos ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
bc749755ff23   bridge    bridge    local
cc6fb605cde8   host      host      local
8a3cfa860aae   mynet     bridge    local
00b2ae19fb37   none      null      local
[root@VM-0-11-centos ~]# docker network inspect mynet

使用自己创建的网络启动容器,通过容器名直接可以进行通信
[root@VM-0-11-centos ~]# docker run -d -p 80:8080 --name tomcat01 --net mynet tomcat
[root@VM-0-11-centos ~]# docker run -d -P --name tomcat02 --net mynet tomcat
[root@VM-0-11-centos ~]# docker exec -it tomcat01 ping tomcat02
PING tomcat02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.053 ms
64 bytes from tomcat02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.034 ms
[root@VM-0-11-centos ~]# docker exec -it tomcat02 ping tomcat01
PING tomcat01 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.082 ms
64 bytes from tomcat01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.049 ms

3.3,自定义网络连通测试

网络联通
使用默认模式再打开一个容器
[root@VM-0-11-centos ~]# docker run -d -P --name tomcat03 tomcat
023cff8d34af26a5db70af374b89b5c6baf1171c28f8ded417c8941f9ae597ed

尝试通信,发现不同网段的容器无法通信
[root@VM-0-11-centos ~]# docker exec -it tomcat02 ping tomcat03
ping: tomcat03: Name or service not known
[root@VM-0-11-centos ~]# docker exec -it tomcat02 ping tomcat01
PING tomcat01 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.034 ms

将tomcat03和mynet连通,就可以实现01,02,03之间的通信了
[root@VM-0-11-centos ~]# docker network connect --help
Usage:  docker network connect [OPTIONS] NETWORK CONTAINER
[root@VM-0-11-centos ~]# docker network connect mynet tomcat03
[root@VM-0-11-centos ~]# docker exec -it tomcat03 ping tomcat03
PING tomcat03 (192.168.0.4) 56(84) bytes of data.
64 bytes from 023cff8d34af (192.168.0.4): icmp_seq=1 ttl=64 time=0.014 ms

查看mynet网络的具体信息,发现tomcat03已经加入到了mynet中(tomcat03也在docker01中/一个容器两个ip,docker01在docker network ls中显示为 bc749755ff23   bridge    bridge    local)
[root@VM-0-11-centos ~]# docker network inspect mynet
"Containers": {
            "023cff8d34af26a5db70af374b89b5c6baf1171c28f8ded417c8941f9ae597ed": {
                "Name": "tomcat03",
                "EndpointID": "c57d075ff87400bf48d62e0c79dacf3fbf01417c678a62283ba62a370c815922",
                "MacAddress": "02:42:c0:a8:00:04",
                "IPv4Address": "192.168.0.4/16",
                "IPv6Address": ""
            },
            "585ecd5171e7722401708234aa7a110773d4f852e2992d6dcc22084c282f12ff": {
                "Name": "tomcat01",
                "EndpointID": "8a13b027417aa67db6b8a7bb58d12c003c3cb5138bc9fcd9718542fc53626bd0",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            },
            "8456029b09de3306abfe6b61a1d7ca001a01c9d5da58f2d7f836db66d5c206bc": {
                "Name": "tomcat02",
                "EndpointID": "85765f60d452116017ef69038e98b2e9f85d286b1a70b7e558c48e96e9a407cc",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            }

联通后的模型

网络联通后

3.4,步骤总结

  • 自定义网络(根据不同类别的容器可以创建不同的网络,不同网络是相互隔离的;自定义网络相比与docker0的最大优势是连接自定义网络的容器可以使用容器名相互通信)

    [root@VM-0-11-centos ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
    
  • 使用自定义网络启动容器,就可以实现容器之间的相互通信(同一网络下)

    [root@VM-0-11-centos ~]# docker run -d -p 80:8080 --name tomcat01 --net mynet tomcat
    [root@VM-0-11-centos ~]# docker run -d -P --name tomcat02 --net mynet tomcat
    [root@VM-0-11-centos ~]# docker exec -it tomcat01 ping tomcat02
    
  • 网络连通,实现不同网络之间容器的相互通信

    [root@VM-0-11-centos ~]# docker network connect --help
    Usage:  docker network connect [OPTIONS] NETWORK CONTAINER
    [root@VM-0-11-centos ~]# docker network connect mynet tomcat03
    

4,单机多容器部署

分布式
创建网络
[root@VM-0-11-centos ~]# docker network create --subnet 172.38.0.0/16 redisNet
bde449dc56dcf00fa6ec761854c0fe59e64e768e7858be64aec67bcaa01791fb

通过脚本创建六个redis配置
for port in $(seq 1 6);
do
mkdir -p /mydata/redis/node-${port}/conf
touch /mydata/redis/node-${port}/conf/redis.conf
cat << EOF >/mydata/redis/node-${port}/conf/redis.conf
port 6379
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.38.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
done

启动模板
docker run -p 637${port}:6379 -p 1637${port}:16379 --name redis-${port} \
-v /mydata/redis/node-${port}/data:/data \
-v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
-d --net redisNet --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf; \

docker run -p 6371:6379 -p 16371:16379 --name redis-1 \
-v /mydata/redis/node-1/data:/data \
-v /mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf \
-d --net redisNet --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf; \

docker run -p 6372:6379 -p 16372:16379 --name redis-2 \
-v /mydata/redis/node-2/data:/data \
-v /mydata/redis/node-2/conf/redis.conf:/etc/redis/redis.conf \
-d --net redisNet --ip 172.38.0.12 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf; \

docker run -p 6373:6379 -p 16373:16379 --name redis-3 \
-v /mydata/redis/node-3/data:/data \
-v /mydata/redis/node-3/conf/redis.conf:/etc/redis/redis.conf \
-d --net redisNet --ip 172.38.0.13 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf; \

docker run -p 6374:6379 -p 16374:16379 --name redis-4 \
-v /mydata/redis/node-4/data:/data \
-v /mydata/redis/node-4/conf/redis.conf:/etc/redis/redis.conf \
-d --net redisNet --ip 172.38.0.14 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf; \

docker run -p 6375:6379 -p 16375:16379 --name redis-5 \
-v /mydata/redis/node-5/data:/data \
-v /mydata/redis/node-5/conf/redis.conf:/etc/redis/redis.conf \
-d --net redisNet --ip 172.38.0.15 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf; \

docker run -p 6376:6379 -p 16376:16379 --name redis-6 \
-v /mydata/redis/node-6/data:/data \
-v /mydata/redis/node-6/conf/redis.conf:/etc/redis/redis.conf \
-d --net redisNet --ip 172.38.0.16 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf; \

创建集群
redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1

[root@VM-0-11-centos conf]# docker exec -it redis-1 /bin/sh
/data # ls
appendonly.aof  nodes.conf
/data # redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 
--cluster-replicas 1
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 172.38.0.15:6379 to 172.38.0.11:6379
Adding replica 172.38.0.16:6379 to 172.38.0.12:6379
Adding replica 172.38.0.14:6379 to 172.38.0.13:6379
M: 04bcb353c948d26d5b70b0f1f117351dbee65b18 172.38.0.11:6379
   slots:[0-5460] (5461 slots) master
M: 081e2c0f82416e7244e866f7017da67d85749568 172.38.0.12:6379
   slots:[5461-10922] (5462 slots) master
M: a578b5ee518cb8bc8b6d70585238c4d89c586162 172.38.0.13:6379
   slots:[10923-16383] (5461 slots) master
S: 79aa99f54ec9ad29540aed876894d68a47d22653 172.38.0.14:6379
   replicates a578b5ee518cb8bc8b6d70585238c4d89c586162
S: 05905669b52e441c91ec93f05fcbd8f33b2c64bf 172.38.0.15:6379
   replicates 04bcb353c948d26d5b70b0f1f117351dbee65b18
S: 421edea4f823d802f6e5689eed43d22d6eb5a085 172.38.0.16:6379
   replicates 081e2c0f82416e7244e866f7017da67d85749568
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
...
>>> Performing Cluster Check (using node 172.38.0.11:6379)
M: 04bcb353c948d26d5b70b0f1f117351dbee65b18 172.38.0.11:6379
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
S: 79aa99f54ec9ad29540aed876894d68a47d22653 172.38.0.14:6379
   slots: (0 slots) slave
   replicates a578b5ee518cb8bc8b6d70585238c4d89c586162
S: 05905669b52e441c91ec93f05fcbd8f33b2c64bf 172.38.0.15:6379
   slots: (0 slots) slave
   replicates 04bcb353c948d26d5b70b0f1f117351dbee65b18
M: 081e2c0f82416e7244e866f7017da67d85749568 172.38.0.12:6379
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
M: a578b5ee518cb8bc8b6d70585238c4d89c586162 172.38.0.13:6379
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: 421edea4f823d802f6e5689eed43d22d6eb5a085 172.38.0.16:6379
   slots: (0 slots) slave
   replicates 081e2c0f82416e7244e866f7017da67d85749568
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

6,docker compose

6.1,一些概念

  • 定义并运行多个容器的docker应用,通过使用YAML文件配置应用服务,使用单个命令就可以从配置中创建并启动所有服务——批量容器编排。

  • 使用compose基础可以分为三个步骤:

    • Define your app’s environment with a Dockerfile so it can be reproduced anywhere.
      • 使用Dockerfile定义app环境,保证项目在任何地方都可以运行
    • Define the services that make up your app in docker-compose.yml so they can be run together in an isolated environment.
      • services 是什么?(service-微服务,一个个单独的容器/应用,web,redis,mysql都可以是一个service,而多个service相互组合协同作用就成为一个完整的project并发挥作用,这样的一个project就是services
      • docker-compose.yml怎么写?
    • Run docker compose up and the Docker compose command starts and runs your entire app. You can alternatively run docker-compose up using the docker-compose binary.
      • 启动项目
  • compose是docker官方的开源项目,需要安装。

  • Dockerfile让程序再任何地方都可以运行,但是容器一但多起来,一个个build和run会很麻烦;而使用compose,通过YAML文件一次就可以启动多个容器,很方便。

6.2,compose安装

https://docs.docker.com/compose/install/

镜像地址

curl -L https://get.daocloud.io/docker/compose/releases/download/1.29.2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

6.3,compose初体验

https://docs.docker.com/compose/gettingstarted/

  • 写一个应用 app.py

  • dockerfile 将应用打包为镜像(单机)

  • docker compose yaml文件(定义整个服务,需要的环境:web、redis)(完整的上线服务)

  • 启动compose项目(docker compose up)

    流程:

    • 创建网络

      [root@VM-0-11-centos ~]# docker network ls
      NETWORK ID     NAME                  DRIVER    SCOPE
      c7e68254a7dc   bridge                bridge    local
      d55a534055e0   composetest_default   bridge    local
      
      项目中的内容都在同一个网络下d55a534055e0   composetest_default   bridge    local,可以通过容器名(域名)进行容器之间的信息传递
      
    • 执行Docker-compose yami

    • 启动服务

      Creating composetest_web_1   ... done
      Creating composetest_redis_1 ... done
      
      默认的服务名:文件名_服务名_num
      num是副本数目
      
  • 总结:以前都是单个docker run启动容器,而docker-compose通过yaml文件可以一键启动/停止所有服务。

    1. docker镜像 run-》容器
    2. dockerfile 构建镜像(服务打包)
    3. docker-compose 启动服务(编排多个微服务/环境)
    4. docker网络

6.4,yaml规则

https://docs.docker.com/compose/compose-file/compose-file-v3/

yaml只有三层

第一层
version: ’‘		#版本,和docker engine对应

第二层
services:		#服务(可以用哪些服务,在官网可以查看)
	服务1: web
		#服务配置(docker的服务配置)
		images
		build
		network
		volumes
		...
	服务2
		...
	服务3
		...

第三层:其他配置  网络/卷,全局规则
volumes
networks
configs

6.5,搭建wordpress博客

https://docs.docker.com/samples/wordpress/

如果开源项目有yaml文件,则可以通过三步直接启动项目:

  • 下载项目(docker-compose.yaml)
  • Dockerfile文件(项目的依赖)
  • 文件准备齐全,docker-compose up -d 一键启动

http://analysis1.space/

7,docker swarm

单机可以用docker compose,但是服务器一多起来就需要用集群的方式部署,docker swarm解决的就是这个问题。

posted @ 2021-06-30 16:44  tensor_zhang  阅读(516)  评论(0编辑  收藏  举报