• Docker容器之间的通信


    前言

    平常在使用Docker容器部署项目的时,比如我们构建一个SpringBoot项目的容器和一个Redis的容器,我们希望SpringBoot项目可以正常访问到Redis容器,通常做法是这样的:

    假如我们的服务器公网IP地址是178.78.7.8,然后我们在服务器上部署了2个Docker服务,分别是SpringBoot服务和Redis服务,一般我们图方便直接将SpringBoot服务的配置文件Redis连接地址填写为公网IP地址,例:spring.redis.host=172.17.0.4

    这样一来相当于绕了一圈…

    我们的SpringBoot服务想要访问到Redis服务还要从公网绕一圈才能访问,如果这中间因为网络因素还会影响对Redis的正常访问。

    如果我们的SpringBoot服务和Redis服务都安装在宿主机上面,就不用绕一圈公网来访问Redis

    通过本地127.0.0.1来访问Redis就完全不用担心网络因素而影响通信,且本地通信速度更佳所以没必要再访问公网IP绕一圈。

    其实Docker也是可以直接在本地互相通信,这样一来也就避免了在公网上绕一圈,写这篇文章也是因为我在部署的Docker服务的时候,就是通过偷懒的方式直接填写公网IP来访问的,但这次由于项目部署在内网,无法通过公网IP来访问,所以这篇文章用来记录这次的解决办法。

    So,本文讲解2种比较简单的Docker容器之间发起通信的方法。


    link机制

    Docker中存在多个容器时,容器与容器之间经常需要进行通讯,例如nacos访问mysql,redis集群中各个节点之间的通讯。

    通过容器名称互联

    在同一个宿主机上的容器之间可以通过自定义的容器名称相互访问,比如一个业务前端静态页面是使用nginx,动态页面使用的是tomcat,由于容器在启动的时候其内部的IP地址是DHCP随机分配的,因此如果通过内部访问的话,自定义名称是相对比较固定的,比较适用于此场景。

    启动第一个容器

    # 创建tomcat容器
    [root@aliyun ~]# docker run -itd --name tomcat01 -p 8088:8080 tomcat
    70892d9cd0c7ec7efb6b2deedeca979b8917ab885db8c4d0b0a6d808a37d0777
    #进入容器
    [root@aliyun ~]# docker exec -it tomcat01 /bin/bash
    root@70892d9cd0c7:/usr/local/tomcat# cd 
    # 查看hosts文件
    root@70892d9cd0c7:~# 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      70892d9cd0c7
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    启动第二个容器,与第一个容器连通

    # 创建nginx容器 并且使用--link加上tomcat容器名来与tomcat进行联通
    [root@aliyun ~]# docker run -itd --name nginx01 --link tomcat01 nginx
    b7837c95dd7c5e9d0a3d1f64c793a5081d8d8c35080e6ba72bdc069af6092001
    # 查看正在运行的docker容器
    [root@aliyun ~]# docker ps
    CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                    NAMES
    b7837c95dd7c   nginx     "/docker-entrypoint.…"   4 seconds ago   Up 4 seconds   80/tcp                   nginx01
    70892d9cd0c7   tomcat    "catalina.sh run"        4 minutes ago   Up 4 minutes   0.0.0.0:8088->8080/tcp   tomcat01
    [root@aliyun ~]# docker exec -it nginx01 /bin/bash
    #查看容器hosts文件,发现记录这第一个容器的ip信息:172.18.0.2      tomcat01 70892d9cd0c7
    root@b7837c95dd7c:/# 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 70892d9cd0c7
    172.18.0.3      b7837c95dd7c
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    测试连通性

    # 测试在nginx容器内来ping一下tomcat ,ping tomcat的容器名就可以ping到tomcat内部
    [root@aliyun ~]# docker exec -it nginx01 ping tomcat01
    PING tomcat01 (172.18.0.2): 56 data bytes
    # 可以看到已经成功ping通到了tomcat容器
    64 bytes from 172.18.0.2: icmp_seq=0 ttl=64 time=0.102 ms
    64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.093 ms
    64 bytes from 172.18.0.2: icmp_seq=2 ttl=64 time=0.110 ms
    64 bytes from 172.18.0.2: icmp_seq=3 ttl=64 time=0.073 ms
    ^C--- tomcat01 ping statistics ---
    4 packets transmitted, 4 packets received, 0% packet loss
    round-trip min/avg/max/stddev = 0.073/0.095/0.110/0.000 ms
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    注意:nginx01可以ping通tomcat01,但是反向是ping不通的

    通过自动启容器别名互联

    由于自定义的容器名称可能后期发生变化,一旦容器名称发生变化,程序之间也会随之发生变化,比如程序通过容器名称进行服务调用,但是容器名称发生变化之后再使用之前的名称肯定无法成功调用,每次都进行更改的话又比较麻烦,因此可以使用自定义别名的方式解决,即容器名称可以随意变更,只要不更改别名即可。格式如下:

    $ docker run -d --name 新容器名称 --link 目标容器名称:自定义的名称 -p 本地端口:容器端口 镜像名称 shell命令
    
    • 1

    示例:

    #创建容器tesk-link
    [root@aliyun ~]# docker run -d --name tesk-link --link tomcat01:java-server -P nginx:v1
    01fde69ddd192d56039b7d108a2acdd5344c56da64a9b030f8112a06e954d684
    [root@aliyun ~]# docker ps
    CONTAINER ID   IMAGE      COMMAND                  CREATED          STATUS          PORTS                    NAMES
    01fde69ddd19   nginx:v1   "/docker-entrypoint.…"   4 seconds ago    Up 2 seconds    0.0.0.0:49160->80/tcp    tesk-link
    b7837c95dd7c   nginx      "/docker-entrypoint.…"   15 minutes ago   Up 15 minutes   80/tcp                   nginx01
    70892d9cd0c7   tomcat     "catalina.sh run"        19 minutes ago   Up 19 minutes   0.0.0.0:8088->8080/tcp   tomcat01
    #进入容器tesk-link
    [root@aliyun ~]# docker exec -it 01fde69ddd19 /bin/bash
    #查看/etc/hosts
    root@01fde69ddd19:/# 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      java-server 70892d9cd0c7 tomcat01
    172.18.0.4      01fde69ddd19
    #测试连通性
    root@01fde69ddd19:/# ping java-server
    PING java-server (172.18.0.2): 56 data bytes
    64 bytes from 172.18.0.2: icmp_seq=0 ttl=64 time=0.129 ms
    64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.105 ms
    64 bytes from 172.18.0.2: icmp_seq=2 ttl=64 time=0.101 ms
    ^C--- java-server ping statistics ---
    3 packets transmitted, 3 packets received, 0% packet loss
    round-trip min/avg/max/stddev = 0.101/0.112/0.129/0.000 ms
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    图示:
    在这里插入图片描述

    软连接

    步骤1:获取容器内部的软连接IP

    docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' 容器ID
    
    • 1

    例:

    [root@host-192-168-84-82 ~]# docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' 2fbd53829b22
    172.17.0.4
    
    • 1
    • 2

    步骤2:更改配置文件的连接IP

    spring.redis.host=172.17.0.4
    
    • 1

    图示:
    在这里插入图片描述

  • 相关阅读:
    sentinel实现流控规则nacos持久化
    132.(后端)订单管理Model与初始化数据——一对多关系的表模型建立与数据填充
    这个面试官居然问我G1垃圾收集器
    Redis高可用架构—Redis集群(Redis Cluster)详细介绍
    中的your-spark-app.jar是个jars包,还是jar文件,如果是jar文件该怎么找
    CTF简介
    C Primer Plus(6) 中文版 第6章 C控制语句:循环 6.1 再探while循环
    【软件教程】如何用C++检查TCP或UDP端口是否被占用
    HarmonyOS/OpenHarmony原生应用-ArkTS万能卡片组件Slider
    Maven的下载安装配置教程(详细图文)
  • 原文地址:https://blog.csdn.net/qq_31762741/article/details/125562127