tjinjin's blog

インフラ要素多めの個人メモ

RedashをFargateで立ち上げる

About

こちらはRedash Advent Calender 2017 19日目の記事です。

qiita.com

ノリでFargateを使ってRedashを構築してみました。

もともとのdocker-compose.yml

version: '3'
services:
  server:
    image: redash/redash:${REDASH_VERSION:-latest}
    command: server
    command: create_db
    depends_on:
      - postgres
      - redis
    ports:
      - "5000:5000"
    environment:
      PYTHONUNBUFFERED: 0
      REDASH_LOG_LEVEL: "INFO"
      REDASH_REDIS_URL: "redis://redis:6379/0"
      REDASH_DATABASE_URL: "postgresql://postgres@postgres/postgres"
      REDASH_HOST: redash.foobar.com
      REDASH_PASSWORD_LOGIN_ENABLED: "false"
      REDASH_ALLOW_SCRIPTS_IN_USER_INPUT: "true"
      REDASH_DATE_FORMAT: YY/MM/DD
    volumes:
      - ./redash/redash_version:/opt/redash/current:ro
    logging:
      driver: "json-file"
      options:
        max-size: 3m
        max-file: "5"
  worker:
    image: redash/redash:${REDASH_VERSION:-latest}
    command: scheduler
    environment:
      PYTHONUNBUFFERED: 0
      REDASH_LOG_LEVEL: "INFO"
      REDASH_REDIS_URL: "redis://redis:6379/0"
      REDASH_DATABASE_URL: "postgresql://postgres@postgres/postgres"
      QUEUES: "queries,scheduled_queries,celery"
      WORKERS_COUNT: 2
    logging:
      driver: "json-file"
      options:
        max-size: 3m
        max-file: "5"
  redis:
    image: redis:3.0-alpine
    logging:
      driver: "json-file"
      options:
        max-size: 3m
        max-file: "5"
  postgres:
    image: postgres:9.5.6-alpine
    volumes:
      - ./postgres:/var/lib/postgresql/data
    logging:
      driver: "json-file"
      options:
        max-size: 3m
        max-file: "5"

こちらの記事をほぼマネしています。

qiita.com

Fargateで動かすためのdocker-compose.yml

結論から言うとファイルを4つに分けました。。。

セットアップ

今回はecs-cliを使いたいので、ダウンロードします。

$ curl -o ~/bin/ecs-cli https://s3.amazonaws.com/amazon-ecs-cli/ecs-cli-darwin-amd64-latest
$ chmod 755 ~/bin/ecs-cli
$ ecs-cli --version
ecs-cli version 1.1.0 (4f176a7)

フォルダ構成

先に今回の構成を書いておきます

$ tree
.
├── create_db
│   ├── docker-compose.yml
│   └── ecs-params.yml
├── postgres
│   ├── docker-compose.yml
│   └── ecs-params.yml
├── redash
│   ├── docker-compose.yml
│   └── ecs-params.yml
└── redis
    ├── docker-compose.yml
    └── ecs-params.yml

一つずつ順番に見ていきます。

手順1 ecs-clusterの構築

ecs-cliを使って構築します。

# いつ作ったか覚えてない
$ cat ~/.ecs/config
[ecs]
cluster                     = ecs-cli-demo
aws_profile                 = default
region                      = us-east-1
aws_access_key_id           =
aws_secret_access_key       =
compose-project-name-prefix = ecscompose-
compose-service-name-prefix = ecscompose-service-
cfn-stack-name-prefix       = amazon-ecs-cli-setup-

$ ecs-cli up --launch-type FARGATE

起動ログをメモしておき、ecs-params.ymlを作ります。

version: 1
task_definition:
  ecs_network_mode: awsvpc
  task_execution_role: ecsTaskExecutionRole
  task_size:
    cpu_limit: 1024
    mem_limit: 2048
  services:
    redash:
      essential: true

run_params:
 network_configuration:
   awsvpc_configuration:
     subnets:
       - subnet-xxxx
       - subnet-yyyy
     security_groups:
       - sg-xxxx # default
       - sg-yyyy # 特定のIPから5000にアクセスできるもの。redash にのみ
     assign_public_ip: ENABLED

Security Groupは別途作っておきました。IAMロールはいつのまにかできていたのでそれを使っています。ここまでで準備ができました

手順2 redis/postgresqlを起動する

今回はdocker-composeに習ってすべてコンテナがあげようと思っているのでそれぞれ起動します。

version: 2
services:
  postgres:
    image: postgres:9.5.6-alpine
    cpu_shares: 512
version: 2
services:
  redis:
    image: redis:3.0-alpine
    cpu_shares: 512

各フォルダに移動し、それぞれserviceとして起動します。

$ ecs-cli compose service up --launch-type FARGATE

起動後、コンソール上でprivate ipが取得できるので確認しておきます。

手順3 databaseの初期セットアップをするredash Taskを起動する

docker-composeだとdocker-compose run --rm server create_dbってワンショットのタスクを渡せますが、ecs-cliだとできないようなので別タスクに切り出します。

version: 2
services:
  server:
    image: redash/redash:latest
    cpu_shares: 512
    command: create_db
    ports:
      - "5000:5000"
    environment:
      PYTHONUNBUFFERED: 0
      REDASH_LOG_LEVEL: "INFO"
      REDASH_REDIS_URL: "redis://10.0.0.113:6379/0"
      REDASH_DATABASE_URL: "postgresql://postgres@10.0.0.230/postgres"
      REDASH_HOST: redash.foobar.com
      REDASH_PASSWORD_LOGIN_ENABLED: "false"
      REDASH_ALLOW_SCRIPTS_IN_USER_INPUT: "true"
      REDASH_DATE_FORMAT: YY/MM/DD
    logging:
      driver: awslogs
      options:
        awslogs-group: redash
        awslogs-region: us-east-1
        awslogs-stream-prefix: create_db-

redisとpostgresの向き先は先程確認しておいたコンテナのPrivate IPを書いています。ちゃんとやるならRoute53に登録とか別の手段のほうがよさそうです。

手順4 Redash本体を起動する

最後に本体を起動します。長い道のりだった。

version: 2
services:
  server:
    image: redash/redash:latest
    cpu_shares: 512
    command: server
    ports:
      - "5000:5000"
    environment:
      PYTHONUNBUFFERED: 0
      REDASH_LOG_LEVEL: "INFO"
      REDASH_REDIS_URL: "redis://10.0.0.113:6379/0"
      REDASH_DATABASE_URL: "postgresql://postgres@10.0.0.230/postgres"
      REDASH_HOST: redash.foobar.com
      REDASH_PASSWORD_LOGIN_ENABLED: "false"
      REDASH_ALLOW_SCRIPTS_IN_USER_INPUT: "true"
      REDASH_DATE_FORMAT: YY/MM/DD
    logging:
      driver: awslogs
      options:
        awslogs-group: redash
        awslogs-region: us-east-1
        awslogs-stream-prefix: server-

  worker:
    image: redash/redash:latest
    cpu_shares: 512
    command: server
    command: scheduler
    environment:
      PYTHONUNBUFFERED: 0
      REDASH_LOG_LEVEL: "INFO"
      REDASH_REDIS_URL: "redis://10.0.0.113:6379/0"
      REDASH_DATABASE_URL: "postgresql://postgres@10.0.0.230/postgres"
      QUEUES: "queries,scheduled_queries,celery"
      WORKERS_COUNT: 2
    logging:
      driver: awslogs
      options:
        awslogs-group: redash
        awslogs-region: us-east-1
        awslogs-stream-prefix: worker-

これを起動したあと、server側のENIのPublicIPを確認して5000にアクセスすれば完了です。

Fargateはまりポイント

docker imageがpullできない

原因は設定ミスによりPublic IPが付与されていなかったため、コンテナから外に出られないのが原因ぽかったです。NATインスタンスを作っておけば解決できたと思いますが、今回はPublic IPを振りました

Task間の通信が難しい 追記あり

当初は4つのコンテナを1つのTaskDefinitionで動かそうとしていましたが諦めました。Service discoveryの何かがないと難しそう。噂によるとそういう機能が出るとか出ないとか -> Amazon Route 53、サービス名の管理および検出用の Auto Naming API をリリース

20171219 11:55頃 追記

Fargateでコンテナ間通信したい場合はlocalhostに向ければいいそうです!

qiita.com

切り分けが難しかった

docker pullできない問題のとき、コンテナインスタンスがあればログインしてみればすぐ解決したと思いますがそこができなかった。噂によるとsshできるみたいな記事がありますがどうなんでしょうか。

まとめ

はまってしまって5時間くらいかかってしまいました。awsvpc/ecs-cli/fargateなどあんまりさわってない要素をまとめてやるのは危険です(危険)ENI経由でのアクセスなのでコンテナ間の通信は一工夫が必要そうです。ENIをつけられるようになったので、コンテナっていうよりホストマシンとしてネットワーク周りは考えたほうがはまらないかもしれません。もうちょっと触って慣れていきたいところです。

参考