1. 程式人生 > >docker-compose網路設定之networks

docker-compose網路設定之networks

networks使用方式之官網教程

  官網的docker-compose.yml參考文件:Compose file version 3 reference
  較為準確的中文翻譯版:Compose file version 3 reference
  
  networks通常應用於叢集服務,從而使得不同的應用程式得以在相同的網路中執行,從而解決網路隔離問題。這種應用在swarm部署中,非常常見。不過,本文並不做討論。
  一般對於叢集服務,常常通過docker-compose.yml文件快速編排、部署應用服務。官網中給出瞭如下的使用場景和方式:

1. 未顯式宣告網路環境的docker-compose.yml

  例如,在目錄app下建立docker-compose.yml,內容如下:

version: '3'
services:
  web:
    mage: nginx:latest
    container_name: web
    depends_on:
      - db
    ports:
      - "9090:80"
    links:
      - db
  db:
    image: mysql
    container_name: db

  使用docker-compose up啟動容器後,這些容器都會被加入app_default網路中。使用docker network ls

可以檢視網路列表,docker network inspect <container id>可以檢視對應網路的配置。

$ docker net work ls
NETWORK ID          NAME                     DRIVER              SCOPE
6f5d9bc0b0a0        app_default              bridge              local
0fb4027b4f6d        bridge                   bridge              local
567
f333b9de8 docker-compose_default bridge local bb346324162a host host local a4de711f6915 mysql_app bridge local f6c79184ed27 mysql_default bridge local 6358d9d60e8a none null local
2. networks關鍵字指定自定義網路

  例如下面的docker-compose.yml檔案,定義了front和back網路,實現了網路隔離。其中proxy和db之間只能通過app來實現通訊。其中,custom-driver-1並不能直接使用,你應該替換為host, bridge, overlay等選項中的一種。

version: '3'

services:
  proxy:
    build: ./proxy
    networks:
      - front
  app:
    build: ./app
    networks:
      - front
      - back
  db:
    image: postgres
    networks:
      - back

networks:
  front:
    # Use a custom driver
    driver: custom-driver-1
  back:
    # Use a custom driver which takes special options
    driver: custom-driver-2
    driver_opts:
      foo: "1"
      bar: "2"

  值得注意的是,這裡定義了backfront兩個網路,似乎它們的名字就定義成了backfont,但是你使用docker network ls命令並不能找到它們。假如你是在myApp目錄下執行的docker-compose up命令,那麼這兩個網路應該分別對應myApp_backmyApp_front

3. 配置預設網路
version: '2'

services:
  web:
    build: .
    ports:
      - "8000:8000"
  db:
    image: postgres

networks:
  default:
    # Use a custom driver
    driver: custom-driver-1
4. 使用已存在的網路
networks:
  default:
    external:
      name: my-pre-existing-network

遇到的問題

  學習了上面的東西,筆者準備將自己的專案付諸實踐。我的專案包含了兩個docker-compose.yml,且使用了links選項,所以必須使用networks配置。
  其中,一個docker-compose.yml用於啟動mysql服務,位於mysql/目錄下:

 version: "3"
services:
  dbmaster:
    image: master/mysql:latest
    container_name: dbmaster
    ports:
      - "3308:3306"
    volumes:
      - $HOME/Work/data/dbmaster:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: master
    logging:
      driver: "json-file"
      options:
        max-size: "1000k"
        max-file: "20"
    networks:
      - app

  dbslave:
    image: slave/mysql:latest
    container_name: dbslave
    ports:
      - "3309:3306"
    depends_on:
      - dbmaster
    volumes:
      - $HOME/Work/data/dbslave:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: slave
    logging:
      driver: "json-file"
      options:
        max-size: "1000k"
        max-file: "20"
    links:
      - dbmaster
    networks:
      - app
networks:
   default:
    external:
      name: app

  另一個docker-compose.yml用於啟動服務程式,位於cloudgo/目錄下:

version: "3"
services:
  web:
    image: nginx:latest
    container_name: web
    depends_on:
      - cloudgo
    ports:
      - "9090:80"
    volumes:
      - $HOME/Work/docker/docker-compose/nginx/conf.d:/etc/nginx/conf.d
    links:
      - cloudgot
    logging:
      driver: "json-file"
      options:
        max-size: "1000k"
        max-file: "20"
    networks:
      - app

  cloudgo:
    image: cloudgo:latest
    container_name: cloudgo
    ports:
      - "8080:8080"
    logging:
      driver: "json-file"
      options:
        max-size: "1000k"
        max-file: "20" 
    external_links:
      - dbmaster
      - dbslave
    networks:
      - app
networks:
  app:
    external: true

  我決定使用預先建立的網路,然後把他們加入這個已經建立好的網路,從而實現通訊。為此,我運行了如下命令:

$ docker network create app

  之後,開始執行編寫好的docker-compose.yml檔案。首先執行啟動mysql的配置檔案,結果如下:

l$ docker-compose up
ERROR: Service "dbmaster" uses an undefined network "app"

  明明已經建立好了,卻還是報了錯,說該網路未定義。嘗試改變名稱mysql_app,但是依舊報出同樣的錯誤。最終證明,這種方法無法實現,至今沒有找到官方文件給出的例子。
  所以,最終決定將第一個docker-compose.yml檔案中的networks配置改為如下內容:

networks:
   mysql_app:
     driver: bridge

  在這個檔案中定義一個網路,以便在後面使用。這裡修改完畢,該檔案其他地方凡是引用到了該網路的地方均要作出相同的修改。同樣,第二個檔案也一樣。

其他的一些用法

  一般的使用格式如下:

services:
  some-service:
    networks:
      some-network:
        aliases:
         - alias1
         - alias3
      other-network:
        aliases:
         - alias2

  在下面的例子中,我的web容器可以直接通過database:3306或者db:3306訪問db容器了。它們同時屬於一個網路,並且db設定了主機別名,所以這樣的訪問方式是完全可以的。

version: '2'

services:
  web:
    depends_on:
      - worker
    networks:
      - new

  worker:
    depends_on:
      - db
    networks:
      - legacy

  db:
    image: mysql
    networks:
      new:
        aliases:
          - database
      legacy:
        aliases:
          - mysql
networks:
  new:
  legacy:

  此時直接使用depends_on已經不再需要link,如果woker需要訪問db,可以直接通過mysql:port的方式。
使用networks的要點在於:
1. 注意自定義網路的方式
2. 注意docker-compose.yml檔案的位置與網路預設命名的關係
3. 注意遇到問題嘗試幾種替代方式去解決