• Docker网络


    Docker网络

    Docker0

    #启动一个tomcat容器
    docker run -d -P --name tomcat01 tomcat
    #查看容器ip端口	166: eth0@if167
    docker exec -it tomcat01 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
    166: eth0@if167: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
        link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
        inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0
           valid_lft forever preferred_lft forever
    #测试ping是成功的
    ping 172.18.0.2
    PING 172.18.0.2 (172.18.0.2) 56(84) bytes of data.
    64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.082 ms
    #查看主机地址		167: vethf13c59d@if166
    ip addr
    ...
    3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
        link/ether 02:42:fb:7c:e2:90 brd ff:ff:ff:ff:ff:ff
        inet 172.18.0.1/16 brd 172.18.255.255 scope global docker0
           valid_lft forever preferred_lft forever
        inet6 fe80::42:fbff:fe7c:e290/64 scope link 
           valid_lft forever preferred_lft forever
    167: vethf13c59d@if166: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
        link/ether 0e:85:67:5d:0c:32 brd ff:ff:ff:ff:ff:ff link-netnsid 0
        inet6 fe80::c85:67ff:fe5d:c32/64 scope link 
           valid_lft forever preferred_lft forever
    
    • 我们每启动一个docker容器, docker就会给docker容器分配一个ip, 我们只要安装了docker,就会有一个网卡docker0, 这里使用的是桥接模式, 使用的技术是veth-pair
    • veth-pair 就是一对的虚拟设备接口,他们都是成对出现的,一段连着协议,一段彼此相连,正因为有这个特性,veth-pair充当一个桥梁,专门连接各种虚拟网络设备
    #再启动一个tomcat容器
    docker run -d -P --name tomcat02 tomcat
    #容器端口	168: eth0@if169
    [root@pinked ~]# docker exec -it tomcat02 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
    168: eth0@if169: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
        link/ether 02:42:ac:12:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
        inet 172.18.0.3/16 brd 172.18.255.255 scope global eth0
           valid_lft forever preferred_lft forever
    #查看主机, 又多了一对网卡	169: vethe6f3759@if168
    ip addr
    ...
    169: vethe6f3759@if168: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
        link/ether 36:ed:8b:0d:5b:0b brd ff:ff:ff:ff:ff:ff link-netnsid 1
        inet6 fe80::34ed:8bff:fe0d:5b0b/64 scope link 
           valid_lft forever preferred_lft forever
    #容器2也可以ping成功docker0的地址
    docker exec -it tomcat02 ping 172.18.0.2
    PING 172.18.0.2 (172.18.0.2) 56(84) bytes of data.
    64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.107 ms
    
    
    • docker会为容器分配一个默认可用的ip, docker使用的是linux的桥接, 宿主机中是一个docker容器的网桥docker0
    • 在我们关闭掉容器服务后, 再次启动时, 容器的ip可能会发送改变, 能否实现通过容器名来进行连接, 实现高可用呢?
    #无法ping成功
    docker exec -it tomcat01 ping tomcat02
    ping: tomcat02: Name or service not known
    #启动一个tomcat03, 通过--link连接到tomcat01
    docker run -d -P --name tomcat03 --link tomcat01 tomcat
    #此时,tomcat03可以ping成功tomcat01, 但是tomcat01还是不能ping成功tomcat03
    docker exec -it tomcat03 ping tomcat01
    PING tomcat01 (172.18.0.2) 56(84) bytes of data.
    64 bytes from tomcat01 (172.18.0.2): icmp_seq=1 ttl=64 time=0.108 ms
    docker exec -it tomcat01 ping tomcat03
    ping: tomcat03: Name or service not known
    #查看tomcat03的host配置
    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.18.0.2	tomcat01 4cc818a0f734	#通过ip映射到了tomcat01
    172.18.0.4	fa92415db20d
    
    • 但是现在--link已经不再建议使用了

    自定义网络

    网络模式
    • bridge: 桥接docker
    • none: 不配置网络
    • host: 和宿主机共享网络
    • container: 容器网络互通
    测试
    #创建自定义的网络, 使用桥接模式(默认模式也是桥接), 配置子网掩码, 配置网关
    docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
    #查看docker网络, 可以看到刚刚自定义的mynet
    docker network ls
    NETWORK ID          NAME                DRIVER              SCOPE
    f46b01d7fce5        bridge              bridge              local
    8e84dd9c7ad4        host                host                local
    55a13bf2f845        mynet               bridge              local
    89a41d0f6030        none                null                local
    #新建两个tomcat使用自定义的mynet
    docker run -d -P --name tomcat01-mynet --net mynet tomcat
    docker run -d -P --name tomcat02-mynet --net mynet tomcat
    #查看mynet的信息
    docker network inspect mynet
    [
        {
            "Name": "mynet",
            "Id": "55a13bf2f845feae2d55fabd0a87332826083aa40400f369062c6e803f824efe",
            "Created": "2020-09-23T18:01:24.780267045+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": {
                "7caab6f9eab10aa94623d597b22a81045e38ac1c9310c5693f954600f5cb72eb": {
                    "Name": "tomcat02-mynet",
                    "EndpointID": "32a43dfba813b6ddf32f4debbca88b2f1dab90c136f03173bded884d95c42290",
                    "MacAddress": "02:42:c0:a8:00:03",
                    "IPv4Address": "192.168.0.3/16",
                    "IPv6Address": ""
                },
                "9ad209b09eee8cd6de808635045318b47f0c8d703681fd1c5c789bbbe73c0dd9": {
                    "Name": "tomcat01-mynet",
                    "EndpointID": "2648125f56886e1018e3575d52d1c9e008dbd4f4bf22d7aca06a3aa15afc18a0",
                    "MacAddress": "02:42:c0:a8:00:02",
                    "IPv4Address": "192.168.0.2/16",
                    "IPv6Address": ""
                }
            },
            "Options": {},
            "Labels": {}
        }
    ]
    #在自定义的mynet网络中, 容器可以直接通过容器名ping成功
    docker exec -it tomcat01-mynet ping tomcat02-mynet 
    PING tomcat02-mynet (192.168.0.3) 56(84) bytes of data.
    64 bytes from tomcat02-mynet.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.077 ms
    
    • 自定义网络的方式可以帮助我们更好地维护容器对应的关系

    网络连通

    • tomcat01在docker0的网络下, 而tomcat01-mynet在mynet网络下, 如何可以实现tomcat01对tomcat01-mynet的连接呢?
    #跨network下并不能ping成功
    docker exec -it tomcat01 ping tomcat01-mynet 
    ping: tomcat01-mynet: Name or service not known
    #连接tomcat01到mynet
    docker network connect mynet tomcat01
    #查看mynet信息, tomcat01已经被连接到了mynet中
    docker network inspect mynet
    ...
    "f48b257d6a25e79d7f9dc83716d1e911ae72a5834e26d23ed8c4cb6f474e5792": {
        "Name": "tomcat01",
        "EndpointID": "e3620d4043efc0dd9b9e5b9548f5614a6aa0dfb5f6e8a22ace986e1009ee10b5",
        "MacAddress": "02:42:c0:a8:00:04",
        "IPv4Address": "192.168.0.4/16",
        "IPv6Address": ""
    }
    ...
    #再测试tomcat01对tomcat01-mynet已经可以平成功了
    docker exec -it tomcat01 ping tomcat01-mynet 
    PING tomcat01-mynet (192.168.0.2) 56(84) bytes of data.
    64 bytes from tomcat01-mynet.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.088 ms
    

    部署Redis集群

    #新建一个redis用的网络
    docker network create redis-network --subnet 172.38.0.0/16
    #运行命令行脚本
    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
    #启动6个redis
    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 redis-network --ip 172.38.0.11 redis:alpine 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 redis-network --ip 172.38.0.12 redis:alpine 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 redis-network --ip 172.38.0.13 redis:alpine 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 redis-network --ip 172.38.0.14 redis:alpine 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 redis-network --ip 172.38.0.15 redis:alpine 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 redis-network --ip 172.38.0.16 redis:alpine redis-server /etc/redis/redis.conf
     #进入redis-1 (redis容器下没有bash命令, 需使用sh)
     docker exec -it redis-1 sh
     #建立集群
    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
    #连接集群, 查看信息
    /data # redis-cli -c
    127.0.0.1:6379> cluster info
    cluster_state:ok
    cluster_slots_assigned:16384
    cluster_slots_ok:16384
    cluster_slots_pfail:0
    cluster_slots_fail:0
    cluster_known_nodes:6
    cluster_size:3
    cluster_current_epoch:6
    cluster_my_epoch:1
    cluster_stats_messages_ping_sent:200
    cluster_stats_messages_pong_sent:220
    cluster_stats_messages_sent:420
    cluster_stats_messages_ping_received:215
    cluster_stats_messages_pong_received:200
    cluster_stats_messages_meet_received:5
    cluster_stats_messages_received:420
    #查看节点
    127.0.0.1:6379> cluster nodes
    365c9d5572f37a736ca9a1b6b9933dfa9258d002 172.38.0.15:6379@16379 slave 54720d691161088372d6e5c4ae7f1192b9be634c 0 1600933795765 1 connected
    54720d691161088372d6e5c4ae7f1192b9be634c 172.38.0.11:6379@16379 myself,master - 0 1600933796000 1 connected 0-5460
    df5111939002c5572891e097cd53b811bf979231 172.38.0.12:6379@16379 master - 0 1600933796265 2 connected 5461-10922
    410eeebae782517cea287d545e1f72e54458afb3 172.38.0.16:6379@16379 slave df5111939002c5572891e097cd53b811bf979231 0 1600933797267 2 connected
    a433eff9790cf78a366f1fde4d3c148f7fe9bac6 172.38.0.13:6379@16379 master - 0 1600933795765 3 connected 10923-16383
    9b4314e3b3ef9928c126d495f531c04261281d9e 172.38.0.14:6379@16379 slave a433eff9790cf78a366f1fde4d3c148f7fe9bac6 0 1600933797768 3 connected
    #存储一个值, 保存在了redis-2上
    127.0.0.1:6379> set key1 pinked
    -> Redirected to slot [9189] located at 172.38.0.12:6379
    OK
    #容器外停止redis-2
    docker stop redis-2
    #容器redis集群中, 因为redis-2停止了, 数据从redis-6中得到
    127.0.0.1:6379> get key1
    -> Redirected to slot [9189] located at 172.38.0.16:6379
    "pinked"
    #查看节点, redis-2 fail了, redis-6成为了新的主机
    172.38.0.16:6379> cluster nodes
    df5111939002c5572891e097cd53b811bf979231 172.38.0.12:6379@16379 master,fail - 1600934055549 1600934053033 2 connected
    410eeebae782517cea287d545e1f72e54458afb3 172.38.0.16:6379@16379 myself,master - 0 1600934988000 8 connected 5461-10922
    ...
    

    打包springboot项目为docker镜像

    1. 新建一个springboot项目, 仅保留一个测试请求即可

    2. 打包成jar包

    3. 新建Dockerfile

      FROM java:8
      
      COPY *.jar /app.jar
      
      CMD ["--server.port=8000"]
      
      EXPOSE 8000
      
      ENTRYPOINT ["java","-jar","/app.jar"]
      
    4. 复制Dockerfile文件和jar包到服务器

    5. build镜像

      docker build -t docker-jar .
      
    6. 运行及测试

      docker run -d -p 9000:8000 --name jar11  docker-jar
      curl localhost:9000
      
  • 相关阅读:
    物联网数据卡系统源码——物联网的主要应用领域
    一张图看懂开源许可协议,开源许可证GPL、BSD、MIT、Mozilla、Apache和LGPL的区别
    memcached对key和value的限制 memcached的key最大长度和Value最大长度
    缓存技术PK:选择Memcached还是Redis?
    .Net开源框架列表
    项目管理工具Redmine各功能测试
    DBImport V3.7版本发布及软件稳定性(自动退出问题)解决过程分享
    ASP.NET Core 折腾笔记一
    发布:.NET开发人员必备的可视化调试工具(你值的拥有)
    开源发布:VS代码段快捷方式及可视化调试快速部署工具
  • 原文地址:https://www.cnblogs.com/pinked/p/13724303.html
Copyright © 2020-2023  润新知