云中客

夢想有多大,就能走多遠

  博客園 :: 首頁 :: 博問 :: 閃存 :: 新隨筆 :: 聯系 :: 訂閱 訂閱 :: 管理 ::
  117 隨筆 :: 4 文章 :: 168 評論 :: 0 引用

背景

通過前幾章節,我們知道:

  • docker build 可以創建一個自定義鏡像;
  • docker run 可以啟動一個容器;

而實際項目中,特別是微服務化之后,運維需要面對的不單單是一個鏡像一個容器,而是幾十乃至上千。如果通過手工敲命令去創建一個個容器,不科學也太慢。如果遇到機器更新換代或者重啟,又得重新敲一遍,這樣下去我想遲早腦袋頭發都要掉光。

還好docker提前想到了這點,為我們準備了相應的工具:

還有一個很時尚的工具 Kubernetes,它是Google根據自身十幾年經驗打造的。

容器編排:docker compose

Compose 是由Python 編寫,定義和運行多個 Docker 容器的工具。通過一個 docker-compose.yml 模板文件(YAML 格式)來定義應用服務,簡單的命令批量創建和啟動定義的所有服務。

重要概念:

  • 服務 (service):一個應用容器,實際上可以運行多個相同鏡像的實例。
  • 項目 (project):由一組關聯的應用容器組成的一個完整業務單元。

一個項目可以由多個服務(容器)關聯而成,Compose 面向項目進行管理。

特性:

  1. 使用不同的項目名稱可以在一個主機構建不同組應用環境。比如開發主機上的不同項目。

    默認項目名稱為yml文件所在目錄名稱,通過使用-p projectname 可以自定義項目名稱。創建的鏡像和容器名稱前綴會帶上項目名稱。

  2. 保存已經創建容器里頭掛載的數據。運行 docker-compose up 的時候,如果監測到有運行的容器,它會自動把就容器掛載的數據復制到新的容器。

  3. Compose會緩存創建容器的配置,重啟service時只會重建有更改的容器。

  4. yml模板文件支持可變參數,使用參數可以創建不同的應用。

db:
  image: "postgres:${POSTGRES_VERSION}"

YML模板文件常用配置:

  • version:compose文件格式版本號,最新版為3。

    Compose file format Docker Engine release
    3.8 19.03.0+
    3.7 18.06.0+
    3.6 18.02.0+
    3.5 17.12.0+
    3.4 17.09.0+
    3.3 17.06.0+
    3.2 17.04.0+
    3.1 1.13.1+
    3.0 1.13.0+
    2.4 17.12.0+
    2.3 17.06.0+
    2.2 1.13.0+
    2.1 1.12.0+
    2.0 1.10.0+
    1.0 1.9.1.+
  • services:服務父節點。

  • 通過鏡像創建容器的docker-compose.yml文件

    version: "3"
    services:
      #容器唯一標識
      webapp:
        #鏡像名稱
        image: examples/web
        ports:
          - "80:80"
        volumes:
          - "/data"
    
  • 通過DockerFile編譯創建容器的docker-compose.yml文件

    version: '3'
    services:
      #容器唯一標識
      webapp:
        build:
          #DockerFile文件地址
          context: ./dir
          #DockerFile文件名稱
          dockerfile: Dockerfile-alternate
    

安裝:

  • Mac/Windows安裝:Docker Desktop for Mac/Windows 自帶 docker-compose 二進制文件,安裝 Docker 之后可以直接使用。
  • Linux安裝:
    $ sudo curl -L https://github.com/docker/compose/releases/download/1.25.5/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
    
    $ sudo chmod +x /usr/local/bin/docker-compose
    

常見命令:

  • up: 創建并啟動配置的所有容器
  • down: 停止并刪除容器、鏡像、網絡、存儲盤
  • ps:列出服務(service)所有的容器
    D:\docker\03-compose>docker-compose ps
              Name                      Command            State    Ports
    ---------------------------------------------------------------------
    03-compose_nbaspnetcore_1   dotnet aspnetcoreapp.dll   Exit 0
    03-compose_nbginx_1         /bin/sh -c /bin/bash       Exit 0
    
  • images:列出服務(service)所有的鏡像
    D:\docker\03-compose>docker-compose images
            Container                 Repository           Tag       Image Id       Size
    --------------------------------------------------------------------------------------
    03-compose_nbaspnetcore_1   03-compose_nbaspnetcore   latest   73ae1ad12839   211.9 MB
    03-compose_nbginx_1         03-compose_nbginx         latest   61ed0bb949f6   403.8 MB
    
  • rm:刪除停止的容器
    D:\docker\03-compose>docker-compose ps
              Name                      Command            State                       Ports
    -----------------------------------------------------------------------------------------------------------
    03-compose_nbaspnetcore_1   dotnet aspnetcoreapp.dll   Up       0.0.0.0:6067->443/tcp, 0.0.0.0:6066->80/tcp
    03-compose_nbginx_1         /bin/sh -c /bin/bash       Exit 0
    
    D:\docker\03-compose>docker-compose rm
    Going to remove 03-compose_nbginx_1
    Are you sure? [yN] y
    Removing 03-compose_nbginx_1 ... done                                                                                   
    D:\docker\03-compose>docker-compose ps
              Name                      Command            State                      Ports
    ----------------------------------------------------------------------------------------------------------
    03-compose_nbaspnetcore_1   dotnet aspnetcoreapp.dll   Up      0.0.0.0:6067->443/tcp, 0.0.0.0:6066->80/tcp
    
  • build:編譯或者再編譯服務
  • create: 創建服務
  • start:開啟服務
  • stop:停止服務
  • restart:重啟服務

實例

下面用 Python 來建立一個能夠記錄頁面訪問次數的 web 網站。

  1. 新建composetest文件夾,在該目錄中編寫 app.py 文件。

    import time
    
    import redis
    from flask import Flask
    
    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()
        return 'Hello World! 該頁面已被訪問 {} 次。\n'.format(count)
    
  2. 在文件夾中,添加 Dockerfile 文件

    FROM python:3.7-alpine
    WORKDIR /code
    ENV FLASK_APP app.py
    ENV FLASK_RUN_HOST 0.0.0.0
    RUN apk add --no-cache gcc musl-dev linux-headers
    RUN pip install redis flask
    COPY . .
    CMD ["flask", "run"]
    
    • 通過Python 3.7 基礎鏡像創建.
    • 設置工作目錄為 /code.
    • 設置FLask命令的環境變量.
    • 安裝gcc 加速編譯MarkupSafe與SQLAlchemy.
    • 安裝python依賴的包.
    • 復制當前目錄內容到鏡像目錄.
    • 設置容器默認啟動命令flask run.
  3. 在文件夾外部創建 docker-compose.yml 文件

    version: '3'
    services: 
      webtest: 
        build: ./composetest
        ports: 
          - 5000:5000
      redis: 
        image: redis:alpine
    
    • 創建一個web容器,開放5000端口.
    • 從Docker Hub拉取一個Redis鏡像創建容器.
  4. 運行Compose項目。(項目名稱為plana)

    D:\docker\03-compose>docker-compose -p plana up
    Creating network "plana_default" with the default driver
    Building webtest
    Step 1/8 : FROM python:3.7-alpine
    ---> 16f919b9ecd5
    Step 2/8 : WORKDIR /code
    ---> Using cache
    ---> 3cd944ab4513
    Step 3/8 : ENV FLASK_APP app.py
    ---> Using cache
    ---> 2aa9917f4c9f
    Step 4/8 : ENV FLASK_RUN_HOST 0.0.0.0
    ---> Using cache
    ---> db1028a91223
    Step 5/8 : RUN apk add --no-cache gcc musl-dev linux-headers
    ---> Using cache
    ---> 13a0ed97a7dd
    Step 6/8 : RUN pip install redis flask
    ---> Using cache
    ---> 1807263196e2
    Step 7/8 : COPY . .
    ---> Using cache
    ---> 553b6c68eace
    Step 8/8 : CMD ["flask", "run"]
    ---> Using cache
    ---> ad92e1924ad5
    Successfully built ad92e1924ad5
    Successfully tagged plana_webtest:latest
    WARNING: Image for service webtest was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
    Creating plana_redis_1   ... done                                                                                       Creating plana_webtest_1 ... done                                                                                       Attaching to plana_webtest_1, plana_redis_1
    redis_1    | 1:C 29 Apr 2020 12:59:36.795 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
    redis_1    | 1:C 29 Apr 2020 12:59:36.795 # Redis version=5.0.9, bits=64, commit=00000000, modified=0, pid=1, just started
    redis_1    | 1:C 29 Apr 2020 12:59:36.795 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
    redis_1    | 1:M 29 Apr 2020 12:59:36.800 * Running mode=standalone, port=6379.
    redis_1    | 1:M 29 Apr 2020 12:59:36.800 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
    redis_1    | 1:M 29 Apr 2020 12:59:36.800 # Server initialized
    redis_1    | 1:M 29 Apr 2020 12:59:36.801 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
    redis_1    | 1:M 29 Apr 2020 12:59:36.802 * Ready to accept connections
    webtest_1  |  * Serving Flask app "app.py"
    webtest_1  |  * Environment: production
    webtest_1  |    WARNING: This is a development server. Do not use it in a production deployment.
    webtest_1  |    Use a production WSGI server instead.
    webtest_1  |  * Debug mode: off
    webtest_1  |  * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
    
  5. 執行結果。(需要指定項目名稱)

    D:\docker\03-compose>docker-compose ps
    Name   Command   State   Ports
    ------------------------------
    
    D:\docker\03-compose>docker-compose images
    Container   Repository   Tag   Image Id   Size
    ----------------------------------------------
    
    D:\docker\03-compose>docker-compose -p plana images
      Container       Repository      Tag       Image Id       Size
    ------------------------------------------------------------------
    plana_redis_1     redis           alpine   3661c84ee9d0   29.8 MB
    plana_webtest_1   plana_webtest   latest   ad92e1924ad5   219.7 MB
    
    D:\docker\03-compose>docker-compose -p plana ps
        Name                    Command               State           Ports
    ---------------------------------------------------------------------------------
    plana_redis_1     docker-entrypoint.sh redis ...   Up      6379/tcp
    plana_webtest_1   flask run                        Up      0.0.0.0:5000->5000/tcp
    

集群編排:swarm mode

Swarm 是使用 SwarmKit 構建的 Docker 引擎內置(原生)的集群管理和編排工具。
Docker 1.12開始 Swarm mode 已經內嵌入 Docker 引擎,成為了 docker 子命令 docker swarm。

Swarm mode 內置 kv 存儲功能,提供了眾多的新特性,使得 Docker 原生的 Swarm 集群具備與 Mesos、Kubernetes 競爭的實力。比如:

  • 具有容錯能力的去中心化設計
  • 內置服務發現
  • 負載均衡
  • 路由網格
  • 動態伸縮
  • 滾動更新
  • 安全傳輸等

常見概念

  1. 節點

    節點為作用在Swarm集群中的一個實例化Docker引擎。雖然可以在一臺物理主機上部署多個節點,但是生產環境中都是跨物理主機進行。
    節點可以加入已經存在的swarm集群或者將自己初始化為一個swarm集群。

    分為:管理(manager)節點,工作(worker)節點。


    • 管理節點:

      執行docker swarm 命令管理 swarm 集群的節點。

      一個 Swarm 集群可以有多個管理節點,但只有一個管理節點可以成為 leader,leader 通過 raft 協議實現。

      管理節點下發任務(Task) 給工作節點,通過工作節點通知給它的任務(Task)執行狀態來管理每個工作節點。
    • 工作節點:

      接收和執行來自管理節點的任務(task)。管理節點默認也作為工作節點。你也可以通過配置讓服務只運行在管理節點。
  2. 服務(Service)與任務(Task)


    • 任務(Task):

      Swarm 中的最小的調度單位,目前來說就是一個單一的容器。一個任務分配給一個節點之后,哪怕執行失敗都無法轉移到其他節點。
    • 服務(Service):

      運行于管理或者工作節點上的一組任務屬性定義。它是Swarm的中心結構,也是與Swarm交互的主要角色。

      與Docker-compose中的服務類似,包含鏡像與命令等。

      服務有兩種模式:
      • replicated services:按照一定規則在各個工作節點上運行指定個數的任務。
      • global services:每個工作節點上運行一個任務

使用實例

使用play-with-docker實驗。

  1. 初始化管理節點

    $ docker swarm init
    Error response from daemon: could not choose an IP address to advertise since this system has multiple addresses on different interfaces (192.168.0.48 on eth0 and 172.18.0.53 on eth1) - specify one with --advertise-addr
    

    因為有多個網絡地址需要指定

    $ docker swarm init --advertise-addr 192.168.0.48
    Swarm initialized: current node (uas5ayulwp28ldrcr3bscmitr) is now a manager.
    
    To add a worker to this swarm, run the following command:
    
        docker swarm join --token SWMTKN-1-17khjeqkfmjswynhda1i0dfqw4hy5io2006xktyvav272ccfie-6xomx3u1mvm7pacj0ymheyu6e 192.168.0.48:2377
    
    To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
    
    

    查看節點列表

    $ docker node ls
    ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
    uas5ayulwp28ldrcr3bscmitr *   node1               Ready               Active              Leader              19.03.4
    
  2. 加入工作節點

    $ docker swarm join --token SWMTKN-1-17khjeqkfmjswynhda1i0dfqw4hy5io2006xktyvav272ccfie-6xomx3u1mvm7pacj0ymheyu6e 192.168.0.48:2377
    This node joined a swarm as a worker.
    

    在兩個主機執行以上命令之后,去管理節點查看節點列表

    $ docker node ls
    ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
    uas5ayulwp28ldrcr3bscmitr *   node1               Ready               Active              Leader              19.03.4
    2rum5pm81t76tjv91rld1n8vu     node3               Ready               Active                                  19.03.4
    u4tbyt95nhy7l6vj3z013r8wz     node5               Ready               Active                                  19.03.4
    
  3. 服務部署

    (命令都是在管理節點執行。)

    • 新建服務

      在集群中創建nginx服務。

      $ docker service create --replicas 3 -p 80:80 --name nginx nginx:latest
      stieixvmvfipi4w6qh49t9es0
      overall progress: 3 out of 3 tasks 
      1/3: running   
      2/3: running   
      3/3: running   
      verify: Service converged 
      
    • 查看服務

      查看服務列表:

      $ docker service ls
      ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
      stieixvmvfip        nginx               replicated          3/3                 nginx:latest        *:80->80/tcp
      

      查看服務詳細:

      $ docker service ps nginx
      ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE           ERROR               PORTS
      xgc5u5m5gl9p        nginx.1             nginx:latest        node3               Running             Running 2 minutes ago                       
      y76pttbz9pkh        nginx.2             nginx:latest        node5               Running             Running 2 minutes ago                       
      oti754af3izt        nginx.3             nginx:latest        node1               Running             Running 2 minutes ago                       
      

      瀏覽器中輸入管理節點或者工作節點IP地址都可以查看nginx界面。

      管理節點:

      工作節點1:

      工作節點2:

    • 服務伸縮

      • 業務訪問量少時,可以減少服務運行容器數。
        $ docker service scale nginx=2
        nginx scaled to 2
        overall progress: 2 out of 2 tasks 
        1/2: running   
        2/2: running   
        verify: Service converged 
        
        查看服務詳情:
        $ docker service ls
        ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
        stieixvmvfip        nginx               replicated          2/2                 nginx:latest        *:80->80/tcp
        
      • 業務訪問量多時,可以增加服務運行容器數。
        $ docker service scale nginx=3
        nginx scaled to 3
        overall progress: 3 out of 3 tasks 
        1/3: running   
        2/3: running   
        3/3: running   
        verify: Service converged 
        
    • 刪除服務

      $ docker service rm nginx
      nginx
      

      查看服務:

      $ docker service ls
      ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
      
  4. 通過compose文件部署服務

    docker service create 一次只能部署一個服務,使用 docker-compose.yml 可以一次啟動多個關聯的服務

    • 創建docker-compose.yml文件
      version: "3"
      services:
        nginx:
          image: nginx:latest
          ports:
            - 80:80
          deploy:
            mode: replicated
            replicas: 3
      
    • 部署服務

      yml文件通過使用docker stack部署。
      $ docker stack deploy -c docker-compose.yml  nginx
      Creating network nginx_default
      Creating service nginx_nginx
      
    • 查看服務
      $ docker stack ls
      NAME                SERVICES            ORCHESTRATOR
      nginx               1                   Swarm
      
      $ docker service ls
      ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
      92n4xd254vu1        nginx_nginx         replicated          3/3                 nginx:latest        *:80->80/tcp
      
      $ docker service ps nginx_nginx
      ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE           ERROR               PORTS
      p6d3xibx9swx        nginx_nginx.1       nginx:latest        node1               Running             Running 2 minutes ago                       
      v0taw0rnr9v3        nginx_nginx.2       nginx:latest        node3               Running             Running 2 minutes ago                       
      2z3sbkdo16oi        nginx_nginx.3       nginx:latest        node5               Running             Running 2 minutes ago                       
      
    • 移除服務
      $ docker stack down nginx
      Removing service nginx_nginx
      Removing network nginx_default
      
posted on 2020-05-04 13:30  走遍江湖  閱讀(...)  評論(...編輯  收藏
全民捕鱼游戏怎么玩 排列五玩法及中奖规则 股票价格查询 新手炒股软件哪个最好 深圳福利彩票深圳风采 股票配资平台代理招商 云南快乐十分怎么买 黑龙江十一选五漏 深圳风采福利彩票查询 002556股票分析 河南481开奖形态走势图