1. 程式人生 > 程式設計 >Docker系列-(3) Docker-compose使用與負載均衡

Docker系列-(3) Docker-compose使用與負載均衡

docker.png

上一篇文章介紹了docker映象的製作與釋出,本文主要介紹實際docker工程部署中經常用到的docker-compose工具,以及docker的網路配置和負載均衡。

Docker-compose介紹

實際開發過程中,在一個專案中,我們常將不同的模組放在單獨的docker中,方便維護和擴充套件。比如我們一個專案可能有MySQL映象、Nginx映象、Spring Boot後端映象,我們在實際部署中可以採用上篇文章介紹的方法,分別打包,分別啟動;但是這樣太費精力,而且還容易出錯。 因此Docker-compose工具應運而生,就是為瞭解決工程部署中的多個Docker映象的管理問題。

docker-compose.yaml 檔案

類似於build映象需要Dockerfile一樣,使用docker-compose時也需要類似的配置檔案,叫做docker-compose.yaml。

下面是一個Docker-file的例子:

一般docker-compose檔案中需要注意如下幾點:

  • version: '3': 表示使用第三代語法,每代的語法稍有不同,我們選擇最新的就好。
  • services: 表示compose需要啟動的服務,一般一個docker映象就可以作為一個單獨的service。
  • container_name: 容器名稱
  • environment: 容器環境變數,可以使用這個引數往容器傳遞一些變數,這個在我們切換不同環境配置時非常有用,不用每次去改變程式碼中的配置
  • ports: 對外開放的埠
  • restart: always表示如果服務啟動不成功一直嘗試。
  • volumes: 載入本地目錄到容器目標路徑,也就是將本地路徑共享給容器,方便進行資料互動,也可以利用這個功能,將docker的log輸出到本機指定的位置。
  • depends_on:依賴服務,先啟動 depends_on 服務。
  • command: mvn clean spring-boot:run : 表示以這個命令來啟動專案

上面提到了depends_on,通常用於需要順序啟動不同映象,比如後臺需要等待資料庫初始化完畢以後才啟動,但是這個depends_on並不能保證前序容器完全初始化,意思是隻要前序容器啟動了,就會嘗試啟動當前容器。這樣還是會造成前序容器未初始化完成,後續容器啟動後出現連線失敗等錯誤。

因此最好的方式是官方(docs.docker.com/compose/sta…)比較推薦的wait指令碼,指令碼的詳細使用可以看這裡 github.com/vishnubob/w…,

wait-for-it.sh host:port [-s] [-t timeout] [-- command args]
-h HOST | --host=HOST       Host or IP under test
-p PORT | --port=PORT       TCP port under test
                            Alternatively,you specify the host and port as host:port
-s | --strict               Only execute subcommand if the test succeeds
-q | --quiet                Don't output any status messages
-t TIMEOUT | --timeout=TIMEOUT
                            Timeout in seconds,zero for no timeout
-- COMMAND ARGS             Execute command with args after the test finishes
複製程式碼

一般也可以在製作映象的時候指定等待一定時間,在下面的例子中,在執行test.jar之前,會一直等到elasticsearch初始化完成。

FROM openjdk:8
ADD ["target/test-1.0.0.jar","test.jar"]
ADD ["wait-for-it.sh","wait-for-it.sh"]
RUN ["chmod","+x","wait-for-it.sh"]
EXPOSE 1234
ENTRYPOINT ["./wait-for-it.sh","elastic:9200","--","java","-jar","/test.jar"]
複製程式碼

關於更多docker-compose檔案的詳細介紹,可以參考官方的檔案 docs.docker.com/compose/get…

docker-compose的啟動/停止

docker-compose的啟動與停止非常簡單,直接使用docker-compose up啟動,docker-compose down關閉工程,同時會刪除所有容器。

Docker的網路通訊

docker的網路方面是相對較弱的,新手如果不清楚,經常會出現為什麼容器A訪問不到容器B的問題。

容器間的通訊

有個很常見的場景,我們需要在本機同時除錯前端和後端程式,通常我們會在localhost某個埠啟動前端,比如8080;同時在local的另一埠比如1234啟動後端。如果不用容器,前端直接在程式碼裡訪問localhost:1234的所有介面都是可以的,沒有任何問題。

但是如果前端和後端都封裝在不同的容器中,這個時候前端直接訪問localhost:1234,會報錯,無法訪問。原因就是兩個容器之間是獨立的,無法直接localhost訪問。

官方推薦的解決辦法就是,先新建一個網路,然後啟動前後端容器的時候,分別指定在該網路中執行。

docker network create mynet
docker run --network mynet --name frontend ...
docker run --network mynet --name backend ...
複製程式碼

現在前端就可以通過 http://backend:1234 訪問後端的介面了。

注意:有些部落格指出,可以通過docker inspect [container_name]來獲取後端容器的ip,然後直接訪問ip加埠就可以了。這個在Linux上也許可行,但是mac下由於容器的實現原理不同,無法直接通過ip訪問。

docker-compose下的網路環境

預設情況下,當你利用docker-compose啟動多個容器時,docker-compose會自動幫你建立一個網路,並將多個service在這個網路中執行。因此不同容器之間,直接利用容器名+埠就可以訪問了。

Docker-compose實現負載均衡

實際生產環境中,肯定會啟動多個後端service,同時進行負載均衡以保證服務質量。利用docker-compose我們可以方便的實現這種功能。

下面是一個很簡單的docker-compose檔案,啟動之後可以在本地開啟localhost:5000,來訪問後端的service;在front容器內部,我們也可以通過backend:5000來訪問backend service。

version: "3"

services:
  front:
    image: front:latest
  backend:
    image: "backend:latest"
    ports:
      - "5000:5000"
複製程式碼

為了啟動多個後端程式以實現負載均衡,docker-compose已經為我們提供--scale引數,利用這個引數可以輕鬆實現同時啟動多個service。 下面是該引數的使用說明。

--scale SERVICE=NUM        Scale SERVICE to NUM instances. Overrides the
                           `scale` setting in the Compose file if present.
複製程式碼

在這裡,我們直接在啟動的時候,指定生成3個後端的service,

docker-compose up --scale backend=3
複製程式碼

但是這樣會報錯,因為本機上的5000埠,只能分配給一個service,如果你想同時在本機上除錯,可以將上面的ports改為5000,修改後的docker-compose檔案如下:

version: "3"

services:
  front:
    image: front:latest
  backend:
    image: "backend:latest"
    ports:
      - "5000"
複製程式碼

這樣按照上面同樣的指令啟動之後,你你可以看到如下的輸出結果,有3個不同的本機埠繫結到容器的5000埠,

      Name                      Command                  State                Ports
--------------------------------------------------------------------------------------------
example_backend_1   /usr/bin/dumb-init -- /sbi ...   Up (healthy)   0.0.0.0:32776->5000/tcp
example_backend_2   /usr/bin/dumb-init -- /sbi ...   Up (healthy)   0.0.0.0:32775->5000/tcp
example_backend_3   /usr/bin/dumb-init -- /sbi ...   Up (healthy)   0.0.0.0:32777->5000/tcp
複製程式碼

當然,如果你只想從容器內部訪問後端的5000埠,你可以去掉port配置,改成如下的配置:

version: "3"

services:
  front:
    image: front:latest
  backend:
    image: "backend:latest"
複製程式碼

這樣docker-compose up --scale backend=3啟動後,我們就只能在容器內部訪問http:\\backend:5000來訪問後端service,因為我們啟動了三個,前端的請求會隨機的分配到後端的三個service上,保證了整體的服務質量。

參考連結:


搜尋『後端精進之路』並關注,立刻獲取最新文章和價值2000元的BATJ精品面試課程

後端精進之路.png