1. 程式人生 > >Docker深入淺出系列 | Docker Compose多容器實戰

Docker深入淺出系列 | Docker Compose多容器實戰

目錄

  • 前期準備
  • Docker Compose是什麼
  • 為什麼要用Docker Compose
  • Docker Compose使用場景
  • Docker Compose安裝
  • Compose Yaml檔案結構
  • Compose 基本操作命令
  • Docker Compose實戰
    • 實戰目標
    • 實戰步驟
      • 清理舊配置
      • 搭建環境
      • 驗證環境
  • Compose彈性擴容初體驗
  • 附錄
    • 引用
    • Q&A

Docker已經上市很多年,不是什麼新鮮事物了,很多企業或者開發同學以前也不多不少有所接觸,但是有實操經驗的人不多,本系列教程主要偏重實戰,儘量講乾貨,會根據本人理解去做闡述,具體官方概念可以查閱官方教程,因為本系列教程對前一章節有一定依賴,建議先學習前面章節內容。

本系列教程導航:
Docker深入淺出系列 | 容器初體驗
Docker深入淺出系列 | Image實戰演練
Docker深入淺出系列 | 單節點多容器網路通訊
Docker深入淺出系列 | 容器資料持久化

Docker深入淺出系列 | 單機Nginx+Springboot實戰

教程目的:

  • 瞭解docker-compose是什麼&為什麼要用
  • 瞭解docker-compose如何安裝
  • 瞭解如何建立docker-compose 檔案
  • 瞭解如何利用docker-compose 檔案去建立服務
  • 瞭解docker compose的基本命令
  • 瞭解如何通過docker compose進行彈性擴容
  • 掌握docker-compose在nginx+springboot實戰應用

前期準備

1.下載mysql

docker pull mysql

2.下載nginx

docker pull nginx

3.克隆credit-facility-service

作為後面部署演示使用,使用docker分支

git clone https://github.com/EvanLeung08/credit-facility-service.git

4.虛擬機器、centos和docker環境安裝請檢視第一章,本章預設已經安裝好centos和docker
Docker深入淺出系列 | 容器初體驗


Docker Compose是什麼

Docker Compose是一個用於定義和執行多容器應用程式的工具。 通過compose,我們可以使用yaml檔案來配置應用程式的服務,然後使用一個命令來建立和啟動所有已配置的服務。 在微服務環境中進行本地開發測試時,我們經常使用此工具。 它也是輕量級的,只需要簡單的配置。 您可以預先配置所需的環境和服務,然後專注於當前開發的服務,而不必管理開發時如何執行每個服務的方式。

***

為什麼要用Docker Compose

首先,我們回顧前一章,我們要部署一個微服務專案,需要手動配置一堆命令,十分繁瑣,假如有幾十上百個容器,並且容器之間還存在依賴,光是忙著搭建容器都耗掉一天了,還談什麼Devops,那有沒有什麼方便快捷的組建,可以讓我們通過一個配置就搞定容器編排和執行呢?

Docker compose就是為了簡化多容器配置和管理工作而生的,可以簡化大量重複的手動工作,具有以下主要特點:

  • 提供工具用於定義和執行多個docker容器應用
  • 使用yaml檔案來配置應用服務(docker-compse.yml)
  • 可以通過一個簡單的命令docker-compse up可以按照依賴關係啟動所有服務
  • 可以通過一個簡單的命令docker-compose down停止所有服務
  • 當一個服務需要的時候,可以很簡單地通過--scale進行擴容

Docker Compose的考慮理由:

  • 可移植性:
    Docker Compose僅需一個命令即可提供完整的開發環境:docker-compose up,然後使用docker-compose down輕鬆將其拆解。 這使我們的開發人員可以將開發環境保持在一箇中立位置,並幫助我們輕鬆地部署應用程式。
  • 測試:
    Compose的另一個重要功能是通過將其置於自己的環境中,以快速可重複的方式支援執行單元和E2E測試。 這意味著,您可以執行與生產環境非常相似的環境,而不是在本地/主機系統上測試應用程式。
  • 單個主機上的多個隔離環境:
    Compose使用專案名稱將環境彼此隔離,這帶來了以下好處:
    • 您可以在一臺計算機上運行同一環境的多個副本
    • 它可以防止不同的專案和服務相互干擾

Docker Compose使用場景

  • 單主機部署:
    傳統上,Compose專注於開發和測試,但現在可用於在單個主機系統上進行部署和管理容器的整個部署過程。

  • 開發環境:
    Compose提供了在孤立的環境中執行應用程式的能力,該環境可以在安裝了Docker的任何計算機上執行。 這使測試你的應用程式變得非常容易,並提供了一種儘可能接近生產環境的工作方式。
    Compose檔案管理應用程式的所有依賴項(資料庫,佇列,快取等),並且可以使用單個命令建立每個容器。

  • 自動化測試環境:
    持續整合和整個開發過程的重要組成部分是自動化測試套件,該套件要求可以在其中執行測試的環境。 Compose提供了一種方便的方法來建立和銷燬與您的生產環境接近的隔離測試環境。


Docker Compose安裝

可以參考官網:Docker Compose安裝

1.下載當前穩定版本,選擇對應系統版本,我這裡用的是Centos

通過官方下載

sudo curl -L "https://github.com/docker/compose/releases/download/1.25.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

通過國內源下載
bash sudo curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

2.賦予可執行許可權

sudo chmod +x /usr/local/bin/docker-compose

Compose Yaml檔案結構

通過Compose,我們開發人員可以通過應用在docker-compose.yml檔案中宣告的許多規則輕鬆地一次處理多個Docker容器。

它由多個層級組成,這些層級使用製表符或空格分隔,而不是大多數程式語言中已知的括號。 幾乎每個Compose-File應該具有以下四個主要方面:

  • Compose檔案的Version
  • 我們將要構建的Services
  • 所有要使用的Volumes
  • 用來連線不同服務的network

docker-compose.yml 示例:

version: '3.3'

services:
   db:
     image: mysql:5.7
     volumes:
       - db_data:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: somewordpress
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: wordpress

   wordpress:
     depends_on:
       - db
     image: wordpress:latest
     ports:
       - "8000:80"
     restart: always
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: wordpress
       WORDPRESS_DB_PASSWORD: wordpress
       WORDPRESS_DB_NAME: wordpress
volumes:
    db_data: {}

以上檔案包含整個Wordpress應用程式,包括MySQL資料庫。 這些服務中的每一個都被視為一個單獨的容器,可以在需要時進行新增或刪除

我是怎麼知道這些命令怎麼使用?
詳細的配置引數,可以查閱: 官方配置引數
***

Compose 基本操作命令

檢視docker-compose的基本操作命令,可以通過docker-compose --help進行檢視,很多命令其實是跟docker相似

[root@localhost credit-facility]# docker-compose --help
Define and run multi-container applications with Docker.

Usage:
  docker-compose [-f <arg>...] [options] [COMMAND] [ARGS...]
  docker-compose -h|--help

Options:
  -f, --file FILE             Specify an alternate compose file
                              (default: docker-compose.yml)
  -p, --project-name NAME     Specify an alternate project name
                              (default: directory name)
  --verbose                   Show more output
  --log-level LEVEL           Set log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
  --no-ansi                   Do not print ANSI control characters
  -v, --version               Print version and exit
  -H, --host HOST             Daemon socket to connect to

  --tls                       Use TLS; implied by --tlsverify
  --tlscacert CA_PATH         Trust certs signed only by this CA
  --tlscert CLIENT_CERT_PATH  Path to TLS certificate file
  --tlskey TLS_KEY_PATH       Path to TLS key file
  --tlsverify                 Use TLS and verify the remote
  --skip-hostname-check       Don't check the daemon's hostname against the
                              name specified in the client certificate
  --project-directory PATH    Specify an alternate working directory
                              (default: the path of the Compose file)
  --compatibility             If set, Compose will attempt to convert keys
                              in v3 files to their non-Swarm equivalent
  --env-file PATH             Specify an alternate environment file

Commands:
  build              Build or rebuild services
  bundle             Generate a Docker bundle from the Compose file
  config             Validate and view the Compose file
  create             Create services
  down               Stop and remove containers, networks, images, and volumes
  events             Receive real time events from containers
  exec               Execute a command in a running container
  help               Get help on a command
  images             List images
  kill               Kill containers
  logs               View output from containers
  pause              Pause services
  port               Print the public port for a port binding
  ps                 List containers
  pull               Pull service images
  push               Push service images
  restart            Restart services
  rm                 Remove stopped containers
  run                Run a one-off command
  scale              Set number of containers for a service
  start              Start services
  stop               Stop services
  top                Display the running processes
  unpause            Unpause services
  up                 Create and start containers
  version            Show the Docker-Compose version information

Docker Compose實戰


相信大家都已經看過上一章,如果大家還沒有看過,請先回到上一章節教程。

在上一章,我們通過手動方式,一步步搭建了Nginx、Mysql以及額度服務,相信大家都體會到整個流程非常繁瑣,有一部出錯了,都要重新敲一遍指令,在本章我們沿用上一章的環境配置,但是整個過程會通過docker compose來幫我們自動部署而不是手動部署。

實戰目標

  • 建立docker網路,設定靜態子網ip168.18.0.0/24
  • 搭建額度服務叢集
    • [額度服務]credit-facility01 - 168.18.0.10
    • [額度服務]credit-facility02 - 168.18.0.11
    • [額度服務]credit-facility03 - 168.18.0.12
  • 搭建Mysql資料庫
    • [Mysql服務]credit-facility-db - 168.18.0.4
  • 搭建Nginx服務,並配置負載均衡規則
    • [Nginx服務]credit-facility-nginx - 168.18.0.5
  • 建立Volume credit-facility-volume,用於持久化Mysql容器資料
  • 利用docker內建DNS伺服器的特點,docker網路內容器之間通過容器名稱進行通訊
  • 通過瀏覽器訪問swagger進行業務操作

實戰步驟

清理舊配置

1.如果上一章已經建立好了容器,先清理上一章已經建立的容器,避免衝突

docker container stop credit-facility01
docker container stop credit-facility02
docker container stop credit-facility03
docker container stop credit-facility-db
docker container stop credit-facility-nginx
docker container rm credit-facility01
docker container rm credit-facility02
docker container rm credit-facility03
docker container rm credit-facility-db
docker container rm credit-facility-nginx

2.清理上一章建立好的網路credit-facility-net

docker network rm credit-facility-net

3.核對下當前Centos系統上credit-facility目錄下的檔案是否跟我一致,如果不一樣,請先檢視上一章

[root@localhost credit-facility]# ls
Dockerfile nginx  start-1.0.0-SNAPSHOT.jar

我們上一章建立好的檔案應該是以上三個

搭建環境

1.上傳credit-facility-service專案裡的docker-compose.yml檔案到Centos系統credit-facility目錄下,如果還沒克隆額度服務到本地,請檢視前期準備

docker-compose.yml檔案存放在credit-facility-service專案dockerfile目錄下

[root@localhost credit-facility]# ls
Dockerfile  docker-compose.yml  nginx  start-1.0.0-SNAPSHOT.jar

這時候會多了一個docker-compose.yml檔案

2.通過docker config校驗compose檔案,如果檔案格式有問題,通過該命令可以幫你校驗並輸出錯誤資訊

[root@localhost credit-facility]# docker-compose config
networks:
  credit-facility-net:
    driver: bridge
    ipam:
      config:
      - subnet: 168.18.0.0/24
services:
  credit-facility-service1:
    build:
      context: /usr/local/credit-facility
    container_name: credit-facility01
    image: credit-facility-image
    networks:
      credit-facility-net:
        ipv4_address: 168.18.0.10
    ports:
    - 8081:8080/tcp
    restart: always
  credit-facility-service2:
    build:
      context: /usr/local/credit-facility
    container_name: credit-facility02
    image: credit-facility-image
    networks:
      credit-facility-net:
        ipv4_address: 168.18.0.11
    ports:
    - 8082:8080/tcp
    restart: always
  credit-facility-service3:
    build:
      context: /usr/local/credit-facility
    container_name: credit-facility03
    image: credit-facility-image
    networks:
      credit-facility-net:
        ipv4_address: 168.18.0.12
    ports:
    - 8083:8080/tcp
    restart: always
  mysql:
    build:
      context: /usr/local/credit-facility
    container_name: credit-facility-db
    environment:
      MYSQL_DATABASE: db_credit_facility
      MYSQL_ROOT_PASSWORD: evan123
    image: mysql
    networks:
      credit-facility-net:
        ipv4_address: 168.18.0.4
    ports:
    - 3301:3306/tcp
    restart: always
    volumes:
    - credit-facility-volume:/var/lib/mysql:rw
  nginx:
    build:
      context: /usr/local/credit-facility
    container_name: credit-facility-nginx
    image: nginx
    networks:
      credit-facility-net:
        ipv4_address: 168.18.0.5
    ports:
    - 80:80/tcp
    restart: always
    volumes:
    - /usr/local/credit-facility/nginx/nginx.conf:/etc/nginx/nginx.conf:rw
version: '3.0'
volumes:
  credit-facility-volume: {}

這裡可以看到,我們的配置檔案檢驗通過,接下來我們分段拆解來說明下每一段指令碼的意思

配置網路

networks:
  credit-facility-net:
    driver: bridge
    ipam:
      config:
      - subnet: 168.18.0.0/24

跟前面一樣,這裡建立了一個自定義網路credit-facility-net,指定了docker的網路模式是bridge,劃分了一個子網ip段168.18.0.0/24,跟前一章手動配置對應的命令如下:

[root@localhost ~]# docker network create --subnet=168.18.0.0/24 credit-facility-net

配置Mysql容器

  mysql:
    restart: always
    container_name: credit-facility-db
    image: mysql
    ports:
      - "3301:3306"
    volumes:
      - "credit-facility-volume:/var/lib/mysql:rw"
    environment:
      - MYSQL_DATABASE=db_credit_facility
      - MYSQL_ROOT_PASSWORD=evan123
    networks:
      credit-facility-net:
        ipv4_address: 168.18.0.4
  • restart - 指定了容器每次部署都會重新重啟
  • container_name - 指定了容器名稱為credit-facility-db
  • image - 指定了我們用來執行容器的映象是mysql,如果指定的image不存在,它會自動從遠端倉庫下載
  • ports - 指定了我們對映埠,這裡把容器3306埠對映到宿主機器3301埠
  • volumes - 指定了容器裡的儲存路徑以volume掛載方式對映到宿主機器上credit-facility-volume,並且分配讀寫許可權
  • environment - 這裡環境變數的作用是向容器傳遞引數,指定了資料庫例項為db_credit_facility,資料庫root使用者密碼為evan123
  • networks - 指定了網路選用自定義網路credit-facility-net,分配靜態IP 168.18.0.4

上面的compose檔案配置對應前一章的手動配置命令如下:

[root@localhost ~]# docker run -d --name credit-facility-db -v credit-facility-volume:/var/lib/mysql -p 3301:3306 -e MYSQL_ROOT_PASSWORD=evan123 --net=credit-facility-net --ip 168.18.0.4 mysql

配置額度服務叢集

  credit-facility-service1:
    restart: always
    container_name: credit-facility01
    depends_on:
      - mysql
    image: credit-facility-image
    build: .
    ports:
      - "8081:8080"
    networks:
      credit-facility-net:
        ipv4_address: 168.18.0.10


  credit-facility-service2:
    restart: always
    container_name: credit-facility02
    depends_on:
      - mysql
    image: credit-facility-image
    build: .
    ports:
      - "8082:8080"
    networks:
      credit-facility-net:
        ipv4_address: 168.18.0.11

  credit-facility-service3:
    restart: always
    container_name: credit-facility03
    depends_on:
      - mysql
    image: credit-facility-image
    build: .
    ports:
      - "8083:8080"
    networks:
      credit-facility-net:
        ipv4_address: 168.18.0.12

核心配置:

  • container_name - 這裡主要是配置3個額度服務例項,分別為credit-facility01credit-facility02credit-facility03
  • build - 這裡指定了docker-compose從當前目錄尋找dockerfile檔案進行映象建立和啟動容器
  • depends_on - 它指定當前容器依賴mysql容器,這樣子docker-compose啟動時會按照依賴關係來啟動
  • networks - 指定了自定義網路credit-facility-net,並對三個例項分別分配了靜態ip168.18.0.10168.18.0.11168.18.0.12

大部分命令跟前面一樣,所以這裡不作重複講解。這裡對應前一章的手動配置命令如下:

[root@localhost credit-facility]# docker build -t credit-facility-image .
[root@localhost credit-facility]# docker run -d --name credit-facility01 -p 8081:8080  --net=credit-facility-net --ip 168.18.0.10 credit-facility-image
[root@localhost credit-facility]# docker run -d --name credit-facility02 -p 8082:8080  --net=credit-facility-net --ip 168.18.0.11 credit-facility-image
[root@localhost credit-facility]# docker run -d --name credit-facility03 -p 8083:8080  --net=credit-facility-net --ip 168.18.0.12 credit-facility-image

這裡沿用上一章在credit-facility目錄下建立的dockerfile:

FROM openjdk:8-jre-alpine
MAINTAINER evan
LABEL name="credit-facility" version="1.0" author="evan"
COPY start-1.0.0-SNAPSHOT.jar credit-facility-service.jar
CMD ["java","-jar","credit-facility-service.jar"]

配置Nginx服務

 nginx:
    restart: always
    container_name: credit-facility-nginx
    depends_on:
      - mysql
      - credit-facility-service1
      - credit-facility-service2
      - credit-facility-service3
    image: nginx
    ports:
      - "80:80"
    volumes:
      - /usr/local/credit-facility/nginx/nginx.conf:/etc/nginx/nginx.conf
    networks:
      credit-facility-net:
        ipv4_address: 168.18.0.5

核心配置:

  • container_name - 把nginx容器命名為credit-facility-nginx
  • depends_on - 定義了容器啟動依賴關係
  • ports - 把容器80埠對映到宿主機80埠
  • volumes - 把容器目錄下的/etc/nginx/nginx.conf檔案對映到宿主機/usr/local/credit-facility/nginx/nginx.conf,這裡的nginx配置沿用上一章的配置不變,宿主機的配置會自動覆蓋容器的nginx.conf檔案
  • networks - 指定網路為credit-facility-net,並分配靜態ip為168.18.0.5

大部分命令跟前面一樣,所以這裡不作重複講解。這裡對應前一章的手動配置命令如下:

[root@localhost nginx]# docker run -d --name credit-facility-nginx -p 80:80 -v /usr/local/credit-facility/nginx/nginx.conf:/etc/nginx/ningx.conf --network=credit-facility-net --ip 168.18.0.5 nginx

這裡沿用上一章的Nginx配置/usr/local/credit-facility/nginx/nginx.conf:

user nginx;
worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;


    server {
        listen 80;
        location / {
         proxy_pass http://balance;
        }
    }

    upstream balance{
       server credit-facility01:8080;
       server credit-facility02:8080 ;
       server credit-facility03:8080;
    }
    include /etc/nginx/conf.d/*.conf;
}

這裡是通過容器名稱訪問,因此不需要管每個容器的ip是多少

4.通過docker-compose up啟動所有服務

[root@localhost credit-facility]# docker-compose up
Creating network "credit-facility_credit-facility-net" with driver "bridge"
Creating credit-facility02     ... done
Creating credit-facility-db    ... done
Creating credit-facility03     ... done
Creating credit-facility-nginx ... done
Creating credit-facility01     ... done
...

通過docker-compose命令,會按照我們在docker-compose.yml配置的資訊去建立和啟動服務,並且把日誌列印到控制檯輸出,這裡因為日誌太多,只截取了部分日誌,只要日誌沒有報錯資訊,所有服務到這裡已經搭建完成

驗證環境

1.驗證Nginx服務是否已經成功,這裡需要通過宿主機ip+對映埠訪問

先檢視下當前centos機器的ip

[root@localhost credit-facility]# ip add
...
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:ba:0a:28 brd ff:ff:ff:ff:ff:ff
    inet 192.168.101.23/24 brd 192.168.101.255 scope global noprefixroute dynamic eth1
       valid_lft 68553sec preferred_lft 68553sec
    inet6 fe80::a00:27ff:feba:a28/64 scope link 
       valid_lft forever preferred_lft forever

從上面可以看到,宿主機外網ip是192.168.101.23

在本機瀏覽器輸入192.168.101.23進行驗證
Nginx服務已經啟動成功

2.驗證額度服務是否成功訪問

通過Nginx 80埠驗證

分別通過每個例項自身對映埠訪問


3.驗證額度服務介面是否可以處理成功

在驗證額度服務前,需要先把表建立好,把credit-facility-service下的db script在DB裡執行

進入到Mysql容器,把表建立sql放進去執行

[root@localhost credit-facility]# docker exec -it credit-facility-db bash
root@d0d2fb8006c9:/# mysql -uroot -pevan123
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| db_credit_facility |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.01 sec)

mysql> use db_credit_facility;
Database changed
mysql> CREATE TABLE `t_product_limit`
...

輸入下面請求資料測試介面

{
    "registrationLimitCO": {
        "applicationId": "1111",
        "userId": 1111,
        "quotaLimit": 10000,
        "productCode": "tb",
        "expirationTime": "2030-01-01",
        "accountType": 1
    }

}



從上面輸出結果可以看到,介面已經處理成功

4.進去資料庫檢視是否已經儲存資料成功

mysql> select * from t_product_limit;
+--------------------+---------------------+---------------------+---------+---------+--------------------+--------------------+-------------+---------+--------------+-------------+---------------+-----------------+--------------+------------+--------------+------------+---------------+-------------+---------------+---------------------+---------------+---------------+-----------+-----------+
| id                 | create_time         | edit_time           | deleted | version | serial_number      | account_id         | customer_id | user_id | product_code | quota_limit | quota_balance | quota_occupancy | quota_frozen | quota_base | quota_change | quota_mode | frozen_status | frozen_time | expire_status | expiration_time     | active_status | inactive_time | parent_id | abandoned |
+--------------------+---------------------+---------------------+---------+---------+--------------------+--------------------+-------------+---------+--------------+-------------+---------------+-----------------+--------------+------------+--------------+------------+---------------+-------------+---------------+---------------------+---------------+---------------+-----------+-----------+
| 684437432334159872 | 2020-03-03 08:30:00 | 2020-03-03 08:30:00 |       0 |       0 | 684437432338354177 | 684437432338354176 |      111111 |    1111 | tb           |       10000 |             0 |               0 |            0 |          0 |            0 |       NULL |             1 | NULL        |          NULL | 2030-01-01 00:00:00 |          NULL | NULL          |      NULL |         0 |
+--------------------+---------------------+---------------------+---------+---------+--------------------+--------------------+-------------+---------+--------------+-------------+---------------+-----------------+--------------+------------+--------------+------------+---------------+-------------+---------------+---------------------+---------------+---------------+-----------+-----------+
1 row in set (0.00 sec)

Compose彈性擴容初體驗

在網際網路公司比較場景,經常會遇到伺服器資源不足,特別是遇到節假日公司要搞活動,需要臨時擴容增大服務的計算能力,假如我們公司已經用上docker,docker-compose就可以幫我們很簡單做到伺服器擴容,當然,docker-compose很少直接在生產上獨立使用,更多是在開發測試環境,後面講解k8s的時候會介紹生產上如何做到彈性擴容。

接下來,我們只需要通過簡單的命令就可以實現彈性擴容

1.對於前面我們建立的docker-compose.yml做一點改動,加入一個新的服務定義,如下

  web:
    restart: always
    image: credit-facility-image
    build: .
    expose:
      - "8080"
    depends_on:
      - mysql
      - credit-facility-service1
      - credit-facility-service2
      - credit-facility-service3
    networks:
      - credit-facility-net

這裡指定了容器埠是8080,但是沒有配置宿主機埠對映,網路也加入到credit-facility-net

Nginx也需要調整下,把靜態ip去掉,並且加上依賴,避免ip衝突,docker會自動分配一個靜態ip

    nginx:
    restart: always
    container_name: credit-facility-nginx
    depends_on:
      - mysql
      - credit-facility-service1
      - credit-facility-service2
      - credit-facility-service3
      - web
    image: nginx
    ports:
      - "80:80"
    links:
      - web
    volumes:
      - /usr/local/credit-facility/nginx/nginx.conf:/etc/nginx/nginx.conf
    networks:
      - credit-facility-net

在這裡我複製了一份credit-facility-service配置,為了方便演示,我去掉了網路配置和埠對映,因為如果想使用彈性擴容,埠和ip不能固定,否則會啟動失敗,改造後完整的配置如下:

version: '3'
services:

  mysql:
    restart: always
    container_name: credit-facility-db
    image: mysql
    ports:
      - "3301:3306"
    volumes:
      - "credit-facility-volume:/var/lib/mysql:rw"
    environment:
      - MYSQL_DATABASE=db_credit_facility
      - MYSQL_ROOT_PASSWORD=evan123
    networks:
      credit-facility-net:
        ipv4_address: 168.18.0.4

  credit-facility-service1:
    restart: always
    container_name: credit-facility01
    depends_on:
      - mysql
    image: credit-facility-image
    build: .
    ports:
      - "8081:8080"
    networks:
      credit-facility-net:
        ipv4_address: 168.18.0.10


  credit-facility-service2:
    restart: always
    container_name: credit-facility02
    depends_on:
      - mysql
    image: credit-facility-image
    build: .
    ports:
      - "8082:8080"
    networks:
      credit-facility-net:
        ipv4_address: 168.18.0.11

  credit-facility-service3:
    restart: always
    container_name: credit-facility03
    depends_on:
      - mysql
    image: credit-facility-image
    build: .
    ports:
      - "8083:8080"
    networks:
      credit-facility-net:
        ipv4_address: 168.18.0.12

  web:
    restart: always
    image: credit-facility-image
    build: .
    expose:
      - "8080"
    depends_on:
      - mysql
      - credit-facility-service1
      - credit-facility-service2
      - credit-facility-service3
    networks:
      - credit-facility-net

  nginx:
    restart: always
    container_name: credit-facility-nginx
    depends_on:
      - mysql
      - credit-facility-service1
      - credit-facility-service2
      - credit-facility-service3
      - web
    image: nginx
    ports:
      - "80:80"
    links:
      - web
    volumes:
      - /usr/local/credit-facility/nginx/nginx.conf:/etc/nginx/nginx.conf
    networks:
      - credit-facility-net

networks:
  credit-facility-net:
    driver: bridge
    ipam:
      config:
        - subnet: 168.18.0.0/24
volumes:
  credit-facility-volume: {}

2.執行以下命令,對web服務進行彈性擴容,建立三個容器例項

[root@localhost credit-facility]# docker-compose up --scale web=3 -d
Creating network "credit-facility_credit-facility-net" with driver "bridge"
Creating network "credit-facility_default" with the default driver
Creating credit-facility_web_1 ... done
Creating credit-facility_web_2 ... done
Creating credit-facility_web_3 ... done
Creating credit-facility01     ... done
Creating credit-facility02     ... done
Creating credit-facility03     ... done
Creating credit-facility-nginx ... done
Creating credit-facility-db    ... done

從上圖可以看到,web服務對應的容器例項已經建立成功,它的命名方式是基於dockerfile裡面的Label名稱+_web_<例項序號>

3.通過docker-compose ps檢視下當前已啟動的容器

[root@localhost credit-facility]# docker-compose ps
        Name                       Command               State                 Ports              
--------------------------------------------------------------------------------------------------
credit-facility-db      docker-entrypoint.sh mysqld      Up      0.0.0.0:3301->3306/tcp, 33060/tcp
credit-facility-nginx   nginx -g daemon off;             Up      0.0.0.0:80->80/tcp               
credit-facility01       java -jar credit-facility- ...   Up      0.0.0.0:8081->8080/tcp           
credit-facility02       java -jar credit-facility- ...   Up      0.0.0.0:8082->8080/tcp           
credit-facility03       java -jar credit-facility- ...   Up      0.0.0.0:8083->8080/tcp           
credit-facility_web_1   java -jar credit-facility- ...   Up      8080/tcp                         
credit-facility_web_2   java -jar credit-facility- ...   Up      8080/tcp                         
credit-facility_web_3   java -jar credit-facility- ...   Up      8080/tcp   

這裡可以看到,我們配置的所有容器都啟動成功,並且新增了三個web容器例項

4.通過docker-compose logs web可以檢視web服務每個例項的日誌

5.修改下nginx.conf的配置,改為新的web容器名稱,註釋掉我們原來的credit-facility容器

user nginx;
worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65; 

   
    server {
        listen 80;
        location / {
         proxy_pass http://balance;
        }
    }
    
    upstream balance{  
      #  server credit-facility01:8080;
      # server credit-facility02:8080 ;
      # server credit-facility03:8080;
      server credit-facility_web_1:8080;
      server credit-facility_web_2:8080;
      server credit-facility_web_3:8080;
    }
    include /etc/nginx/conf.d/*.conf;
} 

6.重啟nginx服務

[root@localhost nginx]# docker restart credit-facility-nginx 
credit-facility-nginx

7.通過Postman測試WEB服務

請求Url輸入你宿主機ip,請求方式是POST,在請求body輸入以下請求資料:

{
    "registrationLimitCO": {
        "applicationId": "1111",
        "userId": 1111,
        "quotaLimit": 10000,
        "productCode": "tb",
        "expirationTime": "2030-01-01",
        "accountType": 1
    }

}


從上面相應結果可以看到,服務處理成功


附錄

引用

Docker Compose官方文件:官方文件
Demo專案地址:Demo下載

Q&A

1.docker-compose up啟動報錯

[root@localhost credit-facility]# docker-compose up
ERROR: Named volume "credit-facility-volume:/var/lib/mysql:rw" is used in service "mysql" but no declaration was found in the volumes section.

解決方案:
這是因為缺少Volume宣告,在docker-compose.yml按如下配置(上文的配置檔案已經配置好)

- "credit-facility-volume:/var/lib/mysql:rw"
volumes:
  credit-facility-volume: {}

2.credit-facility-service在伺服器上啟動報錯
先確定你是否已經切換到docker分支,並且本地構建可以成功,然後再打包