Docker Compose、Swarm 集群管理


  docker-machime和compose、swarm被稱為docker三劍客。docker-machine是解決docker運行環境問題,之前已經研究過,下面研究compose和swarm。

1.Docker Compose

  dcoker-compose主要是解決本地docker容器編排問題。當然也可以自己編寫shell腳本來解決此類問題。

  一般是通過yaml配置文件來使用它,這個yaml文件里能記錄多個容器啟動的配置信息(鏡像、啟動命令、端口映射等),最后只需要執行docker-compose對應的命令就會像執行腳本一樣地批量創建和銷毀容器。

1.使用步驟

一般分為3步:

使用 Dockerfile 定義應用程序的環境。

使用 docker-compose.yml 定義構成應用程序的服務,這樣它們可以在隔離環境中一起運行。

最后,執行 docker-compose up 命令來啟動並運行整個應用程序。

2.安裝compose

linux下面安裝:

sudo curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose #下載 sudo chmod +x /usr/local/bin/docker-compose  #賦予可運行權 sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose  #創建軟連接

 windows安裝docker的時候默認會安裝。

 

查看版本:

$ docker-compose --version
docker-compose version 1.20.1, build 5d8c71b2

 

3.開始使用--構造基於tomcat服務和mysql服務的javaweb項目

(1)准備一個JavaWeb項目,如下:

Administrator@MicroWin10-1535 MINGW64 /e/docker/dockerTest/dockertest4
$ pwd
/e/docker/dockerTest/dockertest4

Administrator@MicroWin10-1535 MINGW64 /e/docker/dockerTest/dockertest4
$ ls
docker-compose.yml  Dockerfile  ssm.war

 

(2)文件內容分別如下:

docker-compose.yml內容如下:

# yaml 配置
version: '2'
services:
  #tomcat服務
  tomcat:
    # 指定基於當前./Dockerfile 構建的鏡像,這時候無需指定image,如果指定image會代替當前build指定的鏡像
    build: .
    # 指定容器名稱
    container_name: tomcat_web
    # 指定端口映射
    ports:
     - "8080:8080"
    #volumes:
      #- "$PWD/tomcat/webapps:/usr/local/tomcat/webapps"
    #指定依賴的服務,會先啟動依賴服務,后啟動自身。停止的時候順序相反。
    depends_on:
      - mysql
  #mysql服務
  mysql:
    # 指定鏡像
    image: "hub.c.163.com/library/mysql"
    container_name: msql_ssm
    ports:
      - "3306:3306"
    # 指定環境變量
    environment:
      MYSQL_ROOT_PASSWORD: "123456"
      MYSQL_DATABASE: ssm
    # 覆蓋容器啟動的默認命令。
    command: [
      '--character-set-server=utf8mb4',
      '--collation-server=utf8mb4_unicode_ci'      
    ]
      

  該文件定義了兩個服務。tomcat和mysql。

  tomcat:該服務使用從當前目錄下Dockerfile構建的鏡像(build指定至於當前目錄下Dockerfile的鏡像)。端口暴露在8080。

  mysql:該服務基於mysql鏡像, 

 

Dockerfile內容如下:(tomcat服務的鏡像制作Dockerfile。也就是運行tomcat服務的時候會先基於下面Dockerfile構建鏡像,然后啟動容器)

FROM hub.c.163.com/library/tomcat
MAINTAINER qlq
COPY ./ssm.war /usr/local/tomcat/webapps

 

 ssm.war是一個javaweb項目,和上一篇文章自己手動構造的Javaweb鏡像一樣。

 

(3)使用 Compose 命令構建和運行您的應用

到 /e/docker/dockerTest/dockertest4目錄,也就是docker-compose.yml文件所在的目錄。

docker-compose up

如果你想在后台執行該服務可以加上 -d 參數:

docker-compose up -d

 

(4)我們運行  docker-compose up -d  之后查看鏡像和容器信息

Administrator@MicroWin10-1535 MINGW64 /e/docker/dockerTest/dockertest4
$ docker images
REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE
dockertest4_tomcat             latest              ace88b521179        About an hour ago   350MB
hello_dockerfile               latest              779eab29d6dc        4 days ago          5.59MB
alpine                         latest              e7d92cdc71fe        4 weeks ago         5.59MB
ubuntu                         latest              ccc6e87d482b        4 weeks ago         64.2MB
hello-world                    latest              fce289e99eb9        13 months ago       1.84kB
hub.c.163.com/library/tomcat   latest              72d2be374029        2 years ago         292MB
hub.c.163.com/library/nginx    latest              46102226f2fd        2 years ago         109MB
hub.c.163.com/library/mysql    latest              9e64176cd8a2        2 years ago         407MB

Administrator@MicroWin10-1535 MINGW64 /e/docker/dockerTest/dockertest4
$ docker ps -a
CONTAINER ID        IMAGE                         COMMAND                  CREATED             STATUS              PORTS                    NAMES
7aa9b3cb61ee        dockertest4_tomcat            "catalina.sh run"        About an hour ago   Up 41 minutes       0.0.0.0:8080->8080/tcp   tomcat_web
279551a99051        hub.c.163.com/library/mysql   "docker-entrypoint.s…"   About an hour ago   Up 41 minutes       0.0.0.0:3306->3306/tcp   msql_ssm

  實際上docker compose幫我們創建了一個tomcat鏡像,也就是我們Dockerfile中聲明的鏡像,並且啟動了新建的鏡像和mysql鏡像。

 補充:yml配置文件參考

 (1)version 指定本 yml 依從的 compose 哪個版本制定的。

(2)build 指定為構建鏡像上下文路徑:

例如 webapp 服務,指定為從上下文路徑 ./dir/Dockerfile 所構建的鏡像:

version: "3.7"
services:
  webapp:
    build: ./dir

或者,作為具有在上下文指定的路徑的對象,以及可選的 Dockerfile 和 args:

version: "3.7"
services:
  webapp:
    build:
      context: ./dir
      dockerfile: Dockerfile-alternate
      args:
        buildno: 1
      labels:
        - "com.example.description=Accounting webapp"
        - "com.example.department=Finance"
        - "com.example.label-with-empty-value"
      target: prod

context:上下文路徑。

dockerfile:指定構建鏡像的 Dockerfile 文件命。

args:添加構建參數,這是只能在構建過程中訪問的環境變量。

labels:設置構建鏡像的標簽。

target:多層構建,可以指定構建哪一層。

(3)cap_add,cap_drop

添加或刪除容器擁有的宿主機的內核功能。

cap_add:
  - ALL # 開啟全部權限

cap_drop:
  - SYS_PTRACE # 關閉 ptrace權限

(4) cgroup_parent

為容器指定父 cgroup 組,意味着將繼承該組的資源限制。

cgroup_parent: m-executor-abcd

(5)command

覆蓋容器啟動的默認命令。

command: ["bundle", "exec", "thin", "-p", "3000"]

(6)container_name

指定自定義容器名稱,而不是生成的默認名稱

container_name: my-web-container

(6)depends_on

設置依賴關系。

docker-compose up :以依賴性順序啟動服務。在以下示例中,先啟動 db 和 redis ,才會啟動 web。

docker-compose up SERVICE :自動包含 SERVICE 的依賴項。在以下示例中,docker-compose up web 還將創建並啟動 db 和 redis。

docker-compose stop :按依賴關系順序停止服務。在以下示例中,web 在 db 和 redis 之前停止。

version: "3.7"
services:
  web:
    build: .
    depends_on:
      - db
      - redis
  redis:
    image: redis
  db:
    image: postgres

注意:web 服務不會等待 redis db 完全啟動 之后才啟動。

(7) devices

指定設備映射列表。

devices:
  - "/dev/ttyUSB0:/dev/ttyUSB0"

(8)dns 自定義 DNS 服務器,可以是單個值或列表的多個值

dns: 8.8.8.8

dns:
  - 8.8.8.8
  - 9.9.9.9

(9)dns_search

自定義 DNS 搜索域。可以是單個值或列表。

dns_search: example.com

dns_search:
  - dc1.example.com
  - dc2.example.com

(10) entrypoint

覆蓋容器默認的 entrypoint。

entrypoint: /code/entrypoint.sh

也可以是以下格式:

entrypoint:
    - php
    - -d
    - zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20100525/xdebug.so
    - -d
    - memory_limit=-1
    - vendor/bin/phpunit

(11) env_file

從文件添加環境變量。可以是單個值或列表的多個值。

env_file: .env

也可以是列表格式:

env_file:
  - ./common.env
  - ./apps/web.env
  - /opt/secrets.env

(12) environment

添加環境變量。您可以使用數組或字典、任何布爾值,布爾值需要用引號引起來,以確保 YML 解析器不會將其轉換為 True 或 False。

environment:
  RACK_ENV: development
  SHOW: 'true'

(13) expose

暴露端口,但不映射到宿主機,只被連接的服務訪問。

僅可以指定內部端口為參數:

expose:
 - "3000"
 - "8000"

(14)image

指定容器運行的鏡像。以下格式都可以:

image: redis
image: ubuntu:14.04
image: tutum/influxdb
image: example-registry.com:4000/postgresql
image: a4bc65fd # 鏡像id

(15)volumes

將主機的數據卷或着文件掛載到容器里。

version: "3.7"
services:
  db:
    image: postgres:latest
    volumes:
      - "/localhost/postgres.sock:/var/run/postgres/postgres.sock"
      - "/localhost/data:/var/lib/postgresql/data"

(16)network_mode

設置網絡模式。

network_mode: "bridge"
network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"
network_mode: "container:[container name/id]"

 

2.Swarm

  docker-swarm是解決多主機多個容器調度部署得問題。

  swarm是基於docker平台實現的集群技術,他可以通過幾條簡單的指令快速的創建一個docker集群,接着在集群的共享網絡上部署應用,最終實現分布式的服務。swarm技術相當不成熟,很多配置功能都無法實現,只能說是個半成品,目前更多的是使用Kubernetes來管理集群和調度容器。

   Docker Swarm 是 Docker 的集群管理工具。它將 Docker 主機池轉變為單個虛擬 Docker 主機。 Docker Swarm 提供了標准的 Docker API,所有任何已經與 Docker 守護程序通信的工具都可以使用 Swarm 輕松地擴展到多個主機。

支持的工具包括但不限於以下各項:

Dokku
Docker Compose
Docker Machine
Jenkins

1.原理

如下圖所示,swarm 集群由管理節點(manager)和工作節點(work node)構成。

swarm mananger:負責整個集群的管理工作包括集群配置、服務管理等所有跟集群有關的工作。
work node:即圖中的 available node,主要負責運行相應的服務來執行任務(task)。

 2.使用

 以下示例,以 Docker Machine 和 virtualbox 進行介紹。

1.創建 swarm 集群管理節點(manager)

創建 docker 機器:

docker-machine create -d virtualbox swarm-manager

 

查看機器:

$ docker-machine ls
NAME            ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER     ERRORS
default         *        virtualbox   Running   tcp://192.168.99.100:2376           v19.03.5
swarm-manager   -        virtualbox   Running   tcp://192.168.99.102:2376           v19.03.5

 

2.初始化 swarm 集群,進行初始化的這台機器,就是集群的管理節點。

(1)查看機器的IP

$ docker-machine ip swarm-manager
192.168.99.102

 

(2)初始化為集群管理節點(下面的 IP 為創建機器時分配的 ip。)

docker@swarm-manager:~$ docker swarm init --advertise-addr 192.168.99.102
Swarm initialized: current node (saxb3bvwb5qp68ulel1ns9oel) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-2jo0xzr3i293iscbbb1ygtfchptk6hskjee9m6q8jp3tc1togq-4j8p3hxal3ouppjf7txg88aho 192.168.99.102:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

 

以上輸出,證明已經初始化成功。需要把以下這行復制出來,在增加工作節點時會用到:

docker swarm join --token SWMTKN-1-2jo0xzr3i293iscbbb1ygtfchptk6hskjee9m6q8jp3tc1togq-4j8p3hxal3ouppjf7txg88aho 192.168.99.102:2377

 

3. 創建 swarm 集群工作節點(worker)

這里直接創建好倆台機器,swarm-worker1 和 swarm-worker2 

docker-machine create -d virtualbox swarm-worker1
docker-machine create -d virtualbox swarm-worker2

分別進入倆個機器里,指定添加至上一步中創建的集群,這里會用到上一步復制的內容。

Administrator@MicroWin10-1535 MINGW64 /e/docker/dockerTest/dockertest4
$ docker-machine ssh swarm-worker1
   ( '>')
  /) TC (\   Core is distributed with ABSOLUTELY NO WARRANTY.
 (/-_--_-\)           www.tinycorelinux.net

docker@swarm-worker1:~$ docker swarm join --token SWMTKN-1-2jo0xzr3i293iscbbb1ygtfchptk6hskjee9m6q8jp3tc1togq-4j8p3hxal3ouppjf7txg88aho 192.168.99.102:2377
This node joined a swarm as a worker.

  出現This node joined 。。。 代表以經加入成功。

Administrator@MicroWin10-1535 MINGW64 /e/docker/dockerTest/dockertest4
$ docker-machine ssh swarm-worker2
   ( '>')
  /) TC (\   Core is distributed with ABSOLUTELY NO WARRANTY.
 (/-_--_-\)           www.tinycorelinux.net

docker@swarm-worker2:~$ docker swarm join --token SWMTKN-1-2jo0xzr3i293iscbbb1ygtfchptk6hskjee9m6q8jp3tc1togq-4j8p3hxal3ouppjf7txg88aho 192.168.99.102:2377
This node joined a swarm as a worker.
docker@swarm-worker2:~$

 

4.查看集群信息

進入管理節點,執行:docker info 可以查看當前集群的信息。

docker@swarm-manager:~$ docker info
Client:
 Debug Mode: false

Server:
 Containers: 0
  Running: 0
  Paused: 0
  Stopped: 0
 Images: 0
 Server Version: 19.03.5
 Storage Driver: overlay2
  Backing Filesystem: extfs
  Supports d_type: true
  Native Overlay Diff: true
 Logging Driver: json-file
 Cgroup Driver: cgroupfs
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm: active
  NodeID: saxb3bvwb5qp68ulel1ns9oel
  Is Manager: true
  ClusterID: o6aztcxmyww6x20z0z2juuvmd
 Managers: 1
  Nodes: 3
  Default Address Pool: 10.0.0.0/8
  SubnetSize: 24
  Data Path Port: 4789
  Orchestration:
   Task History Retention Limit: 5
  Raft:
   Snapshot Interval: 10000
   Number of Old Snapshots to Retain: 0
   Heartbeat Tick: 1
   Election Tick: 10
  Dispatcher:
   Heartbeat Period: 5 seconds
  CA Configuration:
   Expiry Duration: 3 months
   Force Rotate: 0
  Autolock Managers: false
  Root Rotation In Progress: false
  Node Address: 192.168.99.102
  Manager Addresses:
   192.168.99.102:2377
 Runtimes: runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: b34a5c8af56e510852c35414db4c1f4fa6172339
 runc version: 3e425f80a8c931f88e6d94a8c831b9d5aa481657
 init version: fec3683
 Security Options:
  seccomp
   Profile: default
 Kernel Version: 4.14.154-boot2docker
 Operating System: Boot2Docker 19.03.5 (TCL 10.1)
 OSType: linux
 Architecture: x86_64
 CPUs: 1
 Total Memory: 989.5MiB
 Name: swarm-manager
 ID: G5DI:IQAN:ZROP:SFOZ:4U5A:VNHA:T55G:57GE:DAQX:STGM:RKKN:TCXA
 Docker Root Dir: /mnt/sda1/var/lib/docker
 Debug Mode: false
 Registry: https://index.docker.io/v1/
 Labels:
  provider=virtualbox
 Experimental: false
 Insecure Registries:
  127.0.0.0/8
 Live Restore Enabled: false
 Product License: Community Engine

  通過標紅的地方,可以知道當前運行的集群中,有三個節點,其中有一個是管理節點。

 

5.部署服務到集群中

注意:跟集群管理有關的任何操作,都是在管理節點上操作的。

以下例子,在一個工作節點上創建一個名為 helloworld 的服務,這里是隨機指派給一個工作節點:

docker@swarm-manager:~$ docker service create --replicas 1 --name helloworld alpine ping docker.com
bwe0epdhxyr9wnhg9fdrjm261
overall progress: 1 out of 1 tasks
1/1: running   [==================================================>]
verify: Service converged

replicas 參數是指運行實例個數
name 參數指定服務名稱
alpine 指的是使用的鏡像名稱
ping docker.com 指的是容器運行的bash

 

6.查看服務部署情況

查看 helloworld 服務運行在哪個節點上,可以看到目前是在 swarm-manager 節點:

docker@swarm-manager:~$ docker service ps helloworld
ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE           ERROR               PORTS
cf4rnafi6zam        helloworld.1        alpine:latest       swarm-manager       Running             Running 8 minutes ago

查看 helloworld 部署的具體信息:

docker@swarm-manager:~$ docker service inspect --pretty helloworld

ID:             bwe0epdhxyr9wnhg9fdrjm261
Name:           helloworld
Service Mode:   Replicated
 Replicas:      1
Placement:
UpdateConfig:
 Parallelism:   1
 On failure:    pause
 Monitoring Period: 5s
 Max failure ratio: 0
 Update order:      stop-first
RollbackConfig:
 Parallelism:   1
 On failure:    pause
 Monitoring Period: 5s
 Max failure ratio: 0
 Rollback order:    stop-first
ContainerSpec:
 Image:         alpine:latest@sha256:ab00606a42621fb68f2ed6ad3c88be54397f981a7b70a79db3d1172b11c4367d
 Args:          ping docker.com
 Init:          false
Resources:
Endpoint Mode:  vip

 

7.擴展集群服務

將上述的 helloworld 服務擴展到倆個節點。

docker@swarm-manager:~$ docker service scale helloworld=2  #擴展到兩個
helloworld scaled to 2
overall progress: 2 out of 2 tasks
1/2: running   [==================================================>]
2/2: running   [==================================================>]
verify: Service converged
docker@swarm-manager:~$ docker service ps helloworld
ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE            ERROR               PORTS
cf4rnafi6zam        helloworld.1        alpine:latest       swarm-manager       Running             Running 15 minutes ago
lvbmq8nyywir        helloworld.2        alpine:latest       swarm-worker1       Running             Running 25 seconds ago

 

8.刪除服務

docker@swarm-manager:~$ docker service rm helloworld
helloworld
docker@swarm-manager:~$ docke

 

9.停止某個節點

查看所有任務的節點

docker@swarm-manager:~$ docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
saxb3bvwb5qp68ulel1ns9oel *   swarm-manager       Ready               Active              Leader              19.03.5
vipkje05pw9htalttmcgs2kxr     swarm-worker1       Ready               Active                                  19.03.5
yotdzl8j2l900ikalvx0227d1     swarm-worker2       Ready               Active                                  19.03.5

  可以看到目前所有的節點都是 Active, 可以接收新的任務分配。

停止節點 swarm-worker1:

docker@swarm-manager:~$ docker node ls # 查看節點
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
saxb3bvwb5qp68ulel1ns9oel *   swarm-manager       Ready               Active              Leader              19.03.5
vipkje05pw9htalttmcgs2kxr     swarm-worker1       Ready               Active                                  19.03.5
yotdzl8j2l900ikalvx0227d1     swarm-worker2       Ready               Active                                  19.03.5
<ocker node update --availability drain swarm-worker1  #停掉節點worker1
swarm-worker1
docker@swarm-manager:~$ docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
saxb3bvwb5qp68ulel1ns9oel *   swarm-manager       Ready               Active              Leader              19.03.5
vipkje05pw9htalttmcgs2kxr     swarm-worker1       Ready               Drain                                   19.03.5
yotdzl8j2l900ikalvx0227d1     swarm-worker2       Ready               Active                                  19.03.5
docker@swarm-manager:~$ docker node update --availability active swarm-worker1  #重新激活節點worker1
swarm-worker1
docker@swarm-manager:~$ docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
saxb3bvwb5qp68ulel1ns9oel *   swarm-manager       Ready               Active              Leader              19.03.5
vipkje05pw9htalttmcgs2kxr     swarm-worker1       Ready               Active                                  19.03.5
yotdzl8j2l900ikalvx0227d1     swarm-worker2       Ready               Active                                  19.03.5

 補充:swarm集群中部署nginx

1.管理節點中運行

docker service create --name my-web --publish published=8080,target=80 --replicas 2 hub.c.163.com/library/nginx

  知道了服務的名字是my-web,啟動的節點是2個,鏡像是 hub.c.163.com/library/nginx。將nginx容器中的端口80發布到群集中任何節點的端口8080。

2.查看集群上的服務

docker@swarm-manager:~$ docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE                                PORTS
n48sms4g6ccv        my-web              replicated          2/2                 hub.c.163.com/library/nginx:latest   *:8080->80/tcp
docker@swarm-manager:~$ docker service ps my-web
ID                  NAME                IMAGE                                NODE                DESIRED STATE       CURRENT STATE             ERROR                              PORTS
y2hfv1i6rqgu        my-web.1            hub.c.163.com/library/nginx:latest   swarm-worker1       Running             Running 52 minutes ago
n1rkpi1m67xf         \_ my-web.1        hub.c.163.com/library/nginx:latest   swarm-worker1       Shutdown            Rejected 53 minutes ago   "No such image: hub.c.163.com/…"
od7sw0ju48aa        my-web.2            hub.c.163.com/library/nginx:latest   swarm-manager       Running             Running 53 minutes ago

   service 通過 ingress load balancing 來發布服務,且 swarm 集群中所有 node 都參與到 ingress 路由網格(ingress routing mesh) 中,訪問任意一個 node+PublishedPort 即可訪問到服務。

  當訪問任何節點上的端口8080時,Docker將您的請求路由到活動容器。在群節點本身,端口8080可能並不實際綁定,但路由網格知道如何路由流量,並防止任何端口沖突的發生。

  路由網格在發布的端口上監聽分配給節點的任何IP地址。對於外部可路由的IP地址,該端口可從主機外部獲得。對於所有其他IP地址,只能從主機內部訪問。

  http://192.168.99.102:8080/、103:8080、104:8080端口都可以訪問到nginx服務,這樣就實現了負載均衡。因為我們指定--replicas 2 啟動了2個運行nginx的容器 ,所以2個節點上都運行了一個 nginx 的容器,可以通過改其中一個節點上的nginx的歡迎頁 ,然后再訪問,來檢查是否實現了負載均衡。

  可以通過scale 來指定運行容器的數量。可以看到節點的副本變成1。

docker@swarm-manager:~$ docker service scale my-web=1
my-web scaled to 1
overall progress: 1 out of 1 tasks
1/1: running   [==================================================>]
verify: Service converged
docker@swarm-manager:~$ docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE                                PORTS
n48sms4g6ccv        my-web              replicated          1/1                 hub.c.163.com/library/nginx:latest   *:8080->80/tcp

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM