docker容器互聯(lián)

有一個問題,同一宿主機上的容器之間如何進行通信诫舅。我覺得最原始的方法可以在run容器的時候指定一個端口映射循狰,其他容器訪問本機這個被映射的端口即可實現(xiàn)。但這個方法似乎有些不太友好痊末,當宿主機上存在大量的容器我們要配置大量的端口映射,且這樣會導致所有的容器之間都可以互相通信哩掺,無法做到網(wǎng)絡隔離凿叠。如何做到不同集群之間網(wǎng)絡隔離且同集群容器之間可以互相通信呢?答案是自定義網(wǎng)絡即docker network

docker的橋接網(wǎng)絡模式

docker具有五種網(wǎng)絡模式,具體可以參考:初探Docker的網(wǎng)絡模式
當我們run一個鏡像的時候可以指定-- net host指定網(wǎng)絡盒件,如果不指定使用的是默認的bridge網(wǎng)絡蹬碧。該網(wǎng)絡即接在是ip a下docker0虛擬網(wǎng)卡上的

# ip a
1. ...
2. ...
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
    link/ether 02:42:91:b9:20:9f brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 scope global docker0
       valid_lft forever preferred_lft forever

# docker network inspect bridge
 [
    {
        "Name": "bridge",
        "Id": "937b66d796bdb5d16b4f7fb80cae0ff55e40a021db763d64b4cb4bfa3de671ef",
        "Created": "2021-04-18T13:10:46.978091586+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "5aecaa04db4f7effe826b60e4a6a9c4f7e695c8de32f5fe73566f57209b32968": {
                "Name": "app1",
                "EndpointID": "f0633f5548b4290f7b057d6b08aea3d81e70084fbe4a06b151a2797fd27f33cb",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }
]

這里可以看出我的bridge的網(wǎng)段是172.17.0.0/16,網(wǎng)關(guān)是172.17.0.1炒刁。且這個網(wǎng)絡下掛了一個app1的容器恩沽,該容器ip是172.17.0.2。
網(wǎng)段是16的話該段下可以分配2^8 * 2^8 -1=65535個ip翔始, 如果網(wǎng)段是24的話可以分配2^8-1=255個ip

創(chuàng)建網(wǎng)絡

# docker network create --help  # 參數(shù)
Usage:  docker network create [OPTIONS] NETWORK

Create a network

Options:
      --attachable           Enable manual container attachment
      --aux-address map      Auxiliary IPv4 or IPv6 addresses used by Network driver (default map[])
      --config-from string   The network from which to copy the configuration
      --config-only          Create a configuration only network
  -d, --driver string        Driver to manage the Network (default "bridge")
      --gateway strings      IPv4 or IPv6 Gateway for the master subnet
      --ingress              Create swarm routing-mesh network
      --internal             Restrict external access to the network
      --ip-range strings     Allocate container ip from a sub-range
      --ipam-driver string   IP Address Management Driver (default "default")
      --ipam-opt map         Set IPAM driver specific options (default map[])
      --ipv6                 Enable IPv6 networking
      --label list           Set metadata on a network
  -o, --opt map              Set driver specific options (default map[])
      --scope string         Control the network's scope
      --subnet strings       Subnet in CIDR format that represents a network segment
# # 創(chuàng)建一個叫mynet1的網(wǎng)絡罗心,默認是bridge模式,該參數(shù)可省略
# docker network create --subnet 172.18.0.0./16 --gateway 172.18.0.1 --driver bridge mynet1  

創(chuàng)建完后宿主機上ip a會發(fā)現(xiàn)多了一個網(wǎng)卡

# ip a
......
4: br-a32d7755e777: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
    link/ether 02:42:e3:50:de:6f brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.1/16 scope global br-a32d7755e777
       valid_lft forever preferred_lft forever

容器互聯(lián)

這里摘自docker中文社區(qū)的一段文字

在同一個網(wǎng)絡中的容器城瞎,可以互聯(lián)渤闷,并且,Docker 內(nèi)置了 DNS脖镀,容器內(nèi)的應用可以使用服務名飒箭、容器名、別名來進行服務發(fā)現(xiàn)蜒灰,名稱會經(jīng)由內(nèi)置的 DNS 進行解析弦蹂,其結(jié)果是動態(tài)的;而不在同一網(wǎng)絡中的容器卷员,不可以互聯(lián)∮遥現(xiàn)在早就不用 --link 了,而且非常不建議使用毕骡。

這里說明了為什么不用link削饵,原文鏈接
這里我使用了docker-compose官方文檔(鏈接)上的例子(我做了修改)。兩個鏡像未巫,創(chuàng)建了三個容器窿撬,其中app1在bridge網(wǎng)絡即172.17下,app2和redis在mynet網(wǎng)絡即172.18下叙凡,app1和app2都需要連接redis劈伴。

創(chuàng)建鏡像與啟動容器

app.py

import time

import redis
from flask import Flask, jsonify

app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)

def get_hit_count():
    retries = 5
    while True:
        try:
            return cache.incr('hits')
        except redis.exceptions.ConnectionError as exc:
            if retries == 0:
                raise exc
            retries -= 1
            time.sleep(0.5)

@app.route('/')
def hello():
    count = get_hit_count()
    data = {'code': 200, 'message': 'Hello World! I have been seen {} times'.format(count)}
    return jsonify(data)


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

Dockerfile

FROM python:3.7
WORKDIR /root
COPY app.py /root/
COPY requirements.txt /root/requirements.txt
RUN pip install --no-cache-dir -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
EXPOSE 5000
CMD ["python", "app.py"]

run

# docker build -t app .  # 構(gòu)建鏡像
# docker run -d -P --name app1 app  # app1在bridge網(wǎng)絡下
# docker run -d -P --net mynet1 --name app2 app  # app2在mynet1網(wǎng)絡下
# docker pull redis
# docker run -d -P --net mynet1 --name redis redis  # redis,在mynet1網(wǎng)絡下
# 
# docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED       STATUS       PORTS                                         NAMES
5aecaa04db4f   app            "python app.py"          2 hours ago   Up 2 hours   0.0.0.0:49159->5000/tcp, :::49159->5000/tcp   app1
62d8e19385c1   app            "python app.py"          2 hours ago   Up 2 hours   0.0.0.0:49157->5000/tcp, :::49157->5000/tcp   app2
0e22a3a9d2ab   de974760ddb2   "docker-entrypoint.s…"   2 hours ago   Up 2 hours   6379/tcp                                      redis

網(wǎng)絡打通

app, ip, 端口對于關(guān)系如下

容器 宿主機端口 容器內(nèi)端口 ip
app1 49159 5000 172.17.0.2
app2 49157 5000 172.18.0.4
redis 6379 172.18.0.3

注意握爷,這里我沒有開啟redis的端口映射
此時app2和redis在同一網(wǎng)絡下跛璧,訪問app2正常。app1與redis不在同一網(wǎng)段新啼,因此訪問app1將會報錯追城。

# curl  127.0.0.1:49157
{"code":200,"message":"Hello World! I have been seen 13 times"}
# # 宿主機和子網(wǎng)是通的
# curl 172.18.0.4:5000
{"code":200,"message":"Hello World! I have been seen 14 times"}
# # app1與redis不通, 查看app的日志可以看到連接不上redis
# docker logs app1 
redis.exceptions.ConnectionError: Error -2 connecting to redis:6379. Name or service not known.

怎么使app1與redis通呢燥撞?我們可以讓app1連接上mynet1網(wǎng)段座柱,即現(xiàn)在app1有兩個ip迷帜,一個在bridge,一個mynet1色洞。

# docker network connet --help
Usage:  docker network connect [OPTIONS] NETWORK CONTAINER

Connect a container to a network

Options:
      --alias strings           Add network-scoped alias for the container
      --driver-opt strings      driver options for the network
      --ip string               IPv4 address (e.g., 172.30.100.104)
      --ip6 string              IPv6 address (e.g., 2001:db8::33)
      --link list               Add link to another container
      --link-local-ip strings   Add a link-local address for the container
# docker network connect mynet1 app1

這個時候查看docker inspect app1的Networks發(fā)現(xiàn)下面多了一個mynet1網(wǎng)絡戏锹,并為其分配了一個172.18.0.2的ip

# curl 172.18.0.2:5000
{"code":200,"message":"Hello World! I have been seen 15 times"}
# curl 172.17.0.2:5000
{"code":200,"message":"Hello World! I have been seen 16 times"}
# curl 127.0.0.1:49159
{"code":200,"message":"Hello World! I have been seen 17 times"}

這個時候回發(fā)現(xiàn)app1與app2直接也是互相通的

# docker exec -it app1 ping app2
PING app2 (172.18.0.4) 56(84) bytes of data.
64 bytes from app2.mynet1 (172.18.0.4): icmp_seq=1 ttl=64 time=0.069 ms
64 bytes from app2.mynet1 (172.18.0.4): icmp_seq=2 ttl=64 time=0.077 ms
# docker exec -it app2 ping app1
PING app1 (172.18.0.2) 56(84) bytes of data.
64 bytes from app1.mynet1 (172.18.0.2): icmp_seq=1 ttl=64 time=0.050 ms
64 bytes from app1.mynet1 (172.18.0.2): icmp_seq=2 ttl=64 time=0.072 ms

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市火诸,隨后出現(xiàn)的幾起案子锦针,更是在濱河造成了極大的恐慌,老刑警劉巖惭蹂,帶你破解...
    沈念sama閱讀 218,607評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件伞插,死亡現(xiàn)場離奇詭異,居然都是意外死亡盾碗,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,239評論 3 395
  • 文/潘曉璐 我一進店門舀瓢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來廷雅,“玉大人,你說我怎么就攤上這事京髓『阶海” “怎么了?”我有些...
    開封第一講書人閱讀 164,960評論 0 355
  • 文/不壞的土叔 我叫張陵堰怨,是天一觀的道長芥玉。 經(jīng)常有香客問我,道長备图,這世上最難降的妖魔是什么灿巧? 我笑而不...
    開封第一講書人閱讀 58,750評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮揽涮,結(jié)果婚禮上抠藕,老公的妹妹穿的比我還像新娘。我一直安慰自己蒋困,他們只是感情好盾似,可當我...
    茶點故事閱讀 67,764評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著雪标,像睡著了一般零院。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上村刨,一...
    開封第一講書人閱讀 51,604評論 1 305
  • 那天告抄,我揣著相機與錄音,去河邊找鬼烹困。 笑死玄妈,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播拟蜻,決...
    沈念sama閱讀 40,347評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼绎签,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了酝锅?” 一聲冷哼從身側(cè)響起诡必,我...
    開封第一講書人閱讀 39,253評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎搔扁,沒想到半個月后爸舒,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,702評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡稿蹲,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,893評論 3 336
  • 正文 我和宋清朗相戀三年扭勉,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片苛聘。...
    茶點故事閱讀 40,015評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡涂炎,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出设哗,到底是詐尸還是另有隱情唱捣,我是刑警寧澤,帶...
    沈念sama閱讀 35,734評論 5 346
  • 正文 年R本政府宣布网梢,位于F島的核電站震缭,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏战虏。R本人自食惡果不足惜拣宰,卻給世界環(huán)境...
    茶點故事閱讀 41,352評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望活烙。 院中可真熱鬧徐裸,春花似錦、人聲如沸啸盏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,934評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽回懦。三九已至气笙,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間怯晕,已是汗流浹背潜圃。 一陣腳步聲響...
    開封第一講書人閱讀 33,052評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留舟茶,地道東北人谭期。 一個月前我還...
    沈念sama閱讀 48,216評論 3 371
  • 正文 我出身青樓堵第,卻偏偏與公主長得像,于是被迫代替她去往敵國和親隧出。 傳聞我的和親對象是個殘疾皇子踏志,可洞房花燭夜當晚...
    茶點故事閱讀 44,969評論 2 355

推薦閱讀更多精彩內(nèi)容