RedashをFargateで立ち上げる
About
こちらはRedash Advent Calender 2017 19日目の記事です。
ノリで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"
こちらの記事をほぼマネしています。
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に向ければいいそうです!
切り分けが難しかった
docker pullできない問題のとき、コンテナインスタンスがあればログインしてみればすぐ解決したと思いますがそこができなかった。噂によるとsshできるみたいな記事がありますがどうなんでしょうか。
まとめ
はまってしまって5時間くらいかかってしまいました。awsvpc/ecs-cli/fargateなどあんまりさわってない要素をまとめてやるのは危険です(危険)ENI経由でのアクセスなのでコンテナ間の通信は一工夫が必要そうです。ENIをつけられるようになったので、コンテナっていうよりホストマシンとしてネットワーク周りは考えたほうがはまらないかもしれません。もうちょっと触って慣れていきたいところです。