kakts-log

programming について調べたことを整理していきます

Docker Servicesまとめ

概要

前記事

Docker containerまとめ - kakts-log

に引き続き Docker公式ドキュメントのPart3 Servicesの内容を整理します.

Part3 Services

Introduction

パート3では、アプリケーションのスケールを行い,ロードバランシングを有効にさせます.
これを行うために,アプリケーションのヒエラルキーの一段上のレベル,Serviceについて取り上げます.

  • Stack
  • Services
  • Container

About services

分散化されたアプリケーションにおいて,分散化された各ピースのことを"Services"と呼びます.
たとえば,もし動画のシェアリングサイトを考えたときに,おそらくアプリケーションはデータベースにアプリケーションを保存するServiceを含むのと,ユーザがアップロードしたあとにバックグラウンドで動画をトランスコードするServiceや,フロントエンドのServiceが考えられます.

Servicesは実際にはただの本番環境でのコンテナ群として扱われます.
単一のServiceは,1つのイメージを実行しますが,イメージをどのように実行するかを明文化します.
たとえば,どのポートを使うか,Serviceがキャパシティを担保するためにいくつのコンテナレプリカを実行するかなどです.
Serviceのスケーリングを行う場合は,コンテナの数を変更し,そのServiceに対して使うリソースを増やします.

Your first docker-compose.yml file

docker-compose.yml ファイルはYAML形式のファイルで,Dockerコンテナがプロダクション環境でどのように振る舞うかを定義します.

docker-compose.yml

docker-compose.yml というファイルを作成して,使っているディレクトリの直下に保存します.

version: "3"
services:
  web:
    # replace username/repo:tag with your name and image details
    image: username/repo:tag
    deploy:
      replicas: 5
      resources:
        limits:
          cpus: "0.1"
          memory: 50M
      restart_policy:
        condition: on-failure
    ports:
      - "80:80"
    networks:
      - webnet
networks:
  webnet:

内容は上記になります.具体的には以下の内容でコンテナを起動するように指定しています.

  • Part2で使ったイメージをpullしてくる
  • webというService名で,5つのコンテナインスタンスを起動する. 各コンテナは最大でも10%のCPUリソースと50MBのRAMを使用します.
  • もしコンテナが落ちた場合すぐに再起動させる.
  • ホストマシンの80番ポートをwebのポート80に対応させる.
  • webのコンテナに対して,webnetと呼ばれるロードバランシングネットワークを介して80番ポートを共有させる. (内部的には,各コンテナは80番のエフェメラルポートとしてパブリッシュする)
  • webnetネットワークを初期設定で定義する.

Run your new load-balanced app

docker stack deploy コマンドを実行する前に,下記コマンドを実行します.

docker swarm init

詳細はPart4で解説します.

ここでdocker stack deployコマンドを実行します .

docker stack deploy -c docker-compose.yml getstartedlab

これにより,docker-compose.yml で指定した内容をもとにServiceが起動します.

docker service ls で,立ち上げたServiceの一覧を確認できます.

$ docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE                     PORTS
iji3jgsi3i80        getstartedlab_web   replicated          5/5                 username/get-started:part2   *:80->80/tcp

NAME項目をみると,指定したアプリ名がService名(web)の先頭に付加され,getstartedlab_webとなっているのがわかります.

ロードバランシングされるので,ホストマシンのブラウザでlocalhost:80でアクセスするとコンテナにアクセスされ,アクセス毎にHostnameが変わることを確認できます.

さらにdocker ps で実際に立ち上がったコンテナが5つあることを確認できます.

$ docker ps
CONTAINER ID        IMAGE                     COMMAND             CREATED             STATUS              PORTS               NAMES
c39d05ca95fe        username/get-started:part2   "python app.py"     7 seconds ago       Up 3 seconds        80/tcp              getstartedlab_web.3.xievdky2mkx38pl1foa68tzcg
002d8fe2434d        username/get-started:part2   "python app.py"     7 seconds ago       Up 3 seconds        80/tcp              getstartedlab_web.2.z17cyc4kcavu21o6cu2pxtjfl
a959c1870f87        username/get-started:part2   "python app.py"     7 seconds ago       Up 4 seconds        80/tcp              getstartedlab_web.1.xghoiespwuc5wu2oxqn52xxhh
eebff64dc8ac        username/get-started:part2   "python app.py"     7 seconds ago       Up 4 seconds        80/tcp              getstartedlab_web.4.y0vvq8sjj8xzau3meq98fbpfm
4ba7a3c03f56        username/get-started:part2   "python app.py"     7 seconds ago       Up 4 seconds        80/tcp              getstartedlab_web.5.a57ejflvl0k1ckpqs5jvu33v7

docker service ps ${service_name} でサービスに紐付いたコンテナのみを表示することもできます.

Scale the app

docker-compose.yml 内のreplicas項目を変更することで,アプリケーションをスケールできます.
変更した後,再度docker stack deploy コマンドを実行することで再起動できます.
今回はreplicasを7に変更した上で再起動します.

docker stack deploy -c docker-compose.yml getstartedlab_web

再起動後,コンテナが7つ起動しているのを確認できます.

$ docker container ls
CONTAINER ID        IMAGE                     COMMAND             CREATED             STATUS              PORTS               NAMES
ff8a37fa9377        username/get-started:part2   "python app.py"     18 seconds ago      Up 17 seconds       80/tcp              getstartedlab_web.6.umd3i06tcfq1jkeh64znr53uv
fc5150a8b9ee        username/get-started:part2   "python app.py"     18 seconds ago      Up 16 seconds       80/tcp              getstartedlab_web.7.q6kbemo6ghgjh7v45amsvcwzn
c39d05ca95fe        username/get-started:part2   "python app.py"     15 minutes ago      Up 15 minutes       80/tcp              getstartedlab_web.3.xievdky2mkx38pl1foa68tzcg
002d8fe2434d        username/get-started:part2   "python app.py"     15 minutes ago      Up 15 minutes       80/tcp              getstartedlab_web.2.z17cyc4kcavu21o6cu2pxtjfl
a959c1870f87        username/get-started:part2   "python app.py"     15 minutes ago      Up 15 minutes       80/tcp              getstartedlab_web.1.xghoiespwuc5wu2oxqn52xxhh
eebff64dc8ac        username/get-started:part2   "python app.py"     15 minutes ago      Up 15 minutes       80/tcp              getstartedlab_web.4.y0vvq8sjj8xzau3meq98fbpfm
4ba7a3c03f56        username/get-started:part2   "python app.py"     15 minutes ago      Up 15 minutes       80/tcp              getstartedlab_web.5.a57ejflvl0k1ckpqs5jvu33v7

Take down the app and the swarm

アプリケーションを停止する場合docker stack rmコマンドを実行します.

docker stack rm getstartedlab

実行後,Serviceが削除されていることを確認できます.

$ docker service ps getstartedlab_web
no such service: getstartedlab_web

swarmを停止する場合は以下のコマンドを実行します.

docker swarm leave --force

以上です. このようにDockerを使ったアプリケーションのスケールは非常に簡単です.