主夫ときどきプログラマ

データベース、Webエンジニアリング、コミュニティ、etc

Compose on Kubrenetes をGKEで動かす - まずはローカルで動くようにする

f:id:masayuki14:20190607132605j:plain

以前この記事で書いたように Compose on Kubernetes をローカルで試した。

masayuki14.hatenablog.com

サンプルのYamlで動かすことは出来たけど、自プロダクトのYamlは動かなかったのでまずはそれを解消することを目指した。また Kubernetes もそうが、Docker自体への理解も深めることも必要だった。

やったこと

  • 本読み : 体系的に理解する
  • Dockerfile にソースを含める
  • ローカルレジストリの設置

今回のゴールは自プロダクトで使っている docker-compose.yml をローカルのCompose on Kubernetes で動作させること。 そのためにやったことは前述の3つ。

本読み : 体系的に理解する

購入した書籍はこちら。

Docker/Kubernetes 実践コンテナ開発入門

Docker/Kubernetes 実践コンテナ開発入門

まずは1章から5章までを読んだ。Dockerに関しての基礎から、Compose、Swarmを経てKubernetesを理解できる。 いままで独学でDockerを使ってきたけど、体系的に学べて理解も深まった。

構成として1章から順に読んでいかないといけないような構成なので、いきなり5章のKubernetesを読むのは避けたほうがよさそう。ちゃんとはじめから読もう。OSSのツールや実践的なDockerfileの作り方など得られることがとても多かった。

Dockerfile にソースを含める

今回は Dash といPythonのツールを使って可視化アプリを開発している。そのアプリケーション・サーバーとしてdockerを使っていて構成は以下のようになっている。アプリの実行は python app.py をするだけ良い。

.
├── docker-compose.yml
└── dash
     ├── Dockerfile
     └── app.py
# Dockerfile
FROM python:3.7
RUN pip install dash==0.42.0
RUN pip install dash-daq==0.1.0
RUN pip install mysql-connector-python==8.0.15
# docker-compose.yml
version: '3.7'
services:
  dash:
    build:
      context: ./dash
      dockerfile: Dockerfile
    command: ["python", "/work/app.py"]
    volumes:
      - ./dash:/work
    ports:
      - 8050:8050

もともと開発用にdocker-composeを使っていたのでDockerfileへソースコードをコピーしていない。しかしKubernetesで実行する場合はBuildもしないしVolumeも使わない。そのためImageにソースコードを含めた上でBuildし、コンテナを起動するだけでアプリケーションが起動するようにしないといけない。

ソースコードのコピーは COPY コマンドで実行できる。

# Dockerfile
FROM python:3.7
RUN pip install dash==0.43.0
RUN pip install dash-daq==0.1.0
+COPY ["app.py", "/work"]
+CMD ["python", "/work/app.py"]

こうしてやればコンテナ単体で起動した時にもアプリケーション・サーバーは起動するし、開発時はData Volumeを使って/work を上書きしてやれば良い。

# docker-compose.yml
version: '3.7'
services:
  dash:
    build:
      context: ./dash
      dockerfile: Dockerfile
    # 開発時は data volume でソースコードをコンテナとホストで共有し
    # 本番時はコメントアウトする
    volumes:
      - ./dash:/work
    ports:
      - 8050:8050

環境変数で挙動を制御できるように

先の本にも書いてあるが、コンテナを運用するにあたり環境変数でコンテナの挙動を外部から制御できるようにすることが重要なポイントになる。 Dashの場合はサーバー起動を app.run_server(debug=True) で行う。 debugモードを環境変数する場合は以下のようにする。

import dash
import os

app = dash.Dash(__name__)

debug_mode = True if os.environ['DASH_ENV'] == 'development' else False
app.run_server(debug=debug_mode, host='0.0.0.0')

こうしておけば、 DASH_ENV=development環境変数が設定されている場合にだけdebugモードで起動する。 docker-compose.yml環境変数を指定する場合はこうする。

# docker-compose.yml
version: '3.7'
services:
  dash:
    build:
      context: ./dash
      dockerfile: Dockerfile
    volumes:
      - ./dash:/work
    ports:
      - 8050:8050
    environment:
      DASH_ENV: development

ローカルレジストリの設置

Docker Compose を使う時、Dockerfile を用意して build & run をして起動することは便利だし特に問題は起こらないと思う。でもCompose on Kubernetes を使う場合はbuildができない。

# docker-compose.yml
version: '3.7'
services:
  dash:
    build:
      context: ./dash
      dockerfile: Dockerfile
    volumes:
      - ./dash:/work
    ports:
      - 8050:8050

この docker-compose.yml をDocker Compose で起動するとイメージのビルドが実行され、コンテナが起動される。

$ docker-compose up --build

--build オプションをつけて実行すると毎回ビルドし、そのイメージを使ってコンテナを起動してくれる。しかし、Compose on Kubernetesではビルドしてくれないので、コンテナイメージを指定する必要がある。なのでそのまま Compose on Kubernetes を実行しても起動されない。

$ docker stack deploy --orchestrator=kubernetes -c docker-compose.yml kubesample
Ignoring unsupported options: build

service "dash": build is ignored
Waiting for the stack to be stable and running...

Ignoring unsupported options: build とメッセージが表示される。
事前に $ docker build -t sample_app ./dash とビルドし sample_app というイメージを指定すれば起動できるが、せっかくなのでレジストリを使いたい。GKEで動かすことを考えると、レジストリを使う必要がある。

ローカル環境でDockerレジストリを使う

DockerレジストリといえばDocker Hubが有名だ。docker コマンドもデフォルトではDocker Hubからイメージをダウンロードする。他にはQuayというサービスもある。

まずはローカルでレジストリを用意して push & pull の利用になれたほうが良いだろう。レジストリ公式のDockerImageが公開されてるのでそれを利用できる。

$ docker run \
    -v $(pwd)/registry:/var/lib/registry \
    -p 5000:5000 \
    registry:latest

これで localhost:5000レジストリにアクセスできる。タグに localhost:5000 を含めてやればローカルレジストリに push できる。

$ docker build -t localhost:5000/myapp ./dash
$ docker push localhost:5000/myapp

すでに作成済のイメージやDockerHubからダウンロードしたイメージもpushできる。

# すでに my_web_app というtagでビルドされたイメージがある場合
# 新しくタグをつけてpush
$ docker tag my_web_app localhost:5000/my_web_app
$ docker push localhost:5000/my_web_app

# 公式イメージをローカルにpush
$ docker pull mysql
$ docker tag mysql localhost:5000/mysql
$ docker push localhost:5000/mysql

これでレジストリを利用できるので docker-compose.yml を以下のようにしてやれば、Compose on Kubernetes でも利用可能となる。

# docker-compose.yml
version: '3.7'
services:
  dash:
    image: localhost:5000/myapp
    ports:
      - 8050:8050

ローカルで Compose on Kubernetes

これでローカルでCompose on Kubernetesを実行できる

$  docker stack deploy --orchestrator=kubernetes -c docker-compose.yml kubesample

次はGKEへのCompose on Kubernetes のインストールです。よろしくおねがいします。