ERROR: for xxx Cannot start service xxx: driver failed programming external connectivity on endpoint (): Bind for 0.0.0.0:80 failed: port is already allocated

ローカル上で docker-compose stop -> docker-compose rm -f
ネットワークキャッシュを消さないと、接続プロセスが残る。

$ docker-compose up -d
ERROR: for xxx  Cannot start service xxx: driver failed programming external connectivity on endpoint (): Bind for 0.0.0.0:80 failed: port is already allocated
$ lsof -i -P | grep "LISTEN"
Box\x20Lo   476 xxx    5u  IPv4 0xdb0169c9ab3e7445      0t0  TCP localhost:17223 (LISTEN)
Box\x20Lo   476 xxx    6u  IPv6 0xdb0169c9ac255215      0t0  TCP localhost:17223 (LISTEN)
BetterTou 20148 xxx   11u  IPv4 0xdb0169c9ce631d3d      0t0  TCP *:62053 (LISTEN)
BetterTou 20148 xxx   12u  IPv6 0xdb0169c9ac254795      0t0  TCP *:62053 (LISTEN)
RoyalTSX  78179 xxx   16u  IPv4 0xdb0169c9d3c77445      0t0  TCP localhost:54890 (LISTEN)
vpnkit    79289 xxx   27u  IPv4 0xdb0169c9cf03c445      0t0  TCP *:80 (LISTEN) # このプロセス

Mac の Docker ホスト上へ screen コマンドにて tty 経由で接続を行い、直接削除する。

$ screen ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/tty
$ docker stop $(docker ps -a -q)
$ docker rm $(docker ps -a -q)
ctrl-a, ctrl-k の後に y
lsof -i -P | grep "LISTEN"
Box\x20Lo   476 xxx    5u  IPv4 0xdb0169c9ab3e7445      0t0  TCP localhost:17223 (LISTEN)
Box\x20Lo   476 xxx    6u  IPv6 0xdb0169c9ac255215      0t0  TCP localhost:17223 (LISTEN)
BetterTou 20663 xxx   11u  IPv4 0xdb0169c9cc1e6f2d      0t0  TCP *:62053 (LISTEN)
BetterTou 20663 xxx   12u  IPv6 0xdb0169c9ac254795      0t0  TCP *:62053 (LISTEN)

これで up できるようになる。

$ docker-compose up -d

Docker compose

  • 複数のコンテナをコードで管理
  • コンテナの同時起動・停止
  • コンテナのスケール
  • ネットワーク機能に対応
# setting docker compose
$ curl -L https://github.com/docker/compose/releases/download/1.17.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
$ chmod +x /usr/local/bin/docker-compose

$ docker-compose --version
docker-compose version 1.17.1, build 6d101fb

Docker compose の作成

$ git clone https://github.com/xxx/Dockerfile
$ cd Dockerfile/blogserver
$ docker-compose build

//  local で先ずは試し、local で動作することを確認する
// サービスのアップ (-d オプションを付与しないと foreground で実行され、 ctrl-c でサービスが全て落ちる)
$ docker-compose up -d
$ docker-compose ps

// 用済みなので掃除
$ docker-compose stop
$ docker-compose rm -f

// ECS Cluster の起動 (10分くらい掛かる)
$ ecs-cli up --keypair xxx --capability-iam --instance-type t2.medium --security-group sg-xxx --vpc vpc-xxx --subnets subnet-xxx --force --no-associate-public-ip-address --region ap-northeast-1 --size 1

// compose.yml の反映
$ ecs-cli compose --file docker-compose.yml up
$ ecs-cli ps

// Cluster の削除
$ ecs-cli compose --file ./docker-compose.yml service rm
$ ecs-cli down --force

CLI

// Dockerfile より image を作成
$ docker-compose build

// image を取得
$ docker-compose pull

// docker-compose build, docker-compose pull 後 docker run
$ docker-compose up -d

// 個々の service を指定。依存関係も同時に起動する。
$ docker-compose up -d redmine

// docker-compose によって起動しているコンテナ群
$ docker-compose ps

// container すべての出力を表示
$ docker-compose logs

// container をまとめて終了
$ docker-compose stop

// container をまとめて削除
$ docker-compose rm

// docker-machine の IPアドレスを確認
$ docker-machine ls

指定可能な directive

command
cpu_shares
entry point
environment
image
links
mem_limit (in bytes)
ports
volumes
volumes_from

deprecated

機能廃止は deprecated になってから通常は9ヶ月で廃止される。その前に移行すること。
Docker Engine » 廃止機能

注意点

  • OSディストリビューションに同梱されているものではなく、個別にDockerのリポジトリから新しいものを入れる。1.10以降、Embedded DNS機能によりlink無しでも同じネットワーク内のコンテナがhostnameで参照可能な為。link切れによるコンテナ再作成のコスト低減になる。
  • Dockerのストレージエンジンは、overlayfs がよい。速く、devicemapper(特にLVM) を使用していると、容量が足りなくなったとき、サーバーが死んでしまう。

docker-ce, docker-engine, docker.io

  • docker-ce: 2017/12 現在の Docker の呼称
  • docker-ee: エンタープライズ版
  • docker-engine: 昔の Docker の呼称 (upgrade 必要)
  • docker.io: ubuntu が管理している Docker パッケージ名

ECS

ECS (EC2 Container Service)

Cluster (EC2 instance集合体)を管理した上で、スケジューリングして docker run の手間を省いていくれる Docker container 群管理サービス。

  1. IAM role 作成
  2. ECS cluster 作成
  3. container instance 作成
    3-1. ecs-agent 最適化済みの AmazonLinux AMI を起動 (container instance の登録) すると Cluster に自動アタッチ
  4. task 定義 (docker pull)
    4-1. 1つ以上の container を起動するための定義を記述
    4-2. 同一Task definition 内の container 間は通信が可能
    4-3. revision 管理されている
  5. task 実行 (docker run)

Task Definition は複数の container をセットにしたものであり、同じ Task Definition に含まれる container は同一 node で動作する。継続運用の観点から Service が存在し、どのTask Definition を幾つ起動させ、どのELB/ALBと関連しているかを設定可能。Service は指定した Task Definition 数を維持する。Service は関連LB に対し EC2 node を自動登録する。Task終了時、自動で LB をデタッチする。

container instance

  • ECS Agent
  • Docker container で動く
  • go言語で記述されている

Service

  • Task definition の起動数を定義する。
  • 機能単位。
  • resource が競合する container は同一 instance で起動しない。
  • Service として起動している Docker contaner へ新しくデプロイする場合、Task definition の image を更新 -> Task definition を更新という流れになるが、新 container は ポート 80 を利用しようとして古い container と競合するため、起動できずリトライが繰り返される
    • deployment_minimum_healthy_percent=0, maximum=100 にすることでinstance1台でport番号を考慮せず新バージョンのコンテナを動かせる

Task

instance 上で実行されている container。サービスの分類。API Task, Front task等。

cluster

  • task が実行される instance 群。

メリット

  • immutable image(作成後変更不可, stateless(scalabilityの観点から各interactionでrequestに応えられる)
  • 開発速度の向上
  • ALB との併用で動的ポートマッピング可能
  • Service Auto Scaling で AWS へ Autoscaling を任せられる
  • Task 単位で IAM role を利用して権限管理
  • CloudWatch で Cluster のメトリクスも扱える
  • Docker container の起動方法、連携方法を定義可能
  • Docker container の起動状態を確認、変更可能
  • 古い container から新しい container へのコンテナへ Blue Green Deployment が可能

デメリット

  • statefull なシステムには向かない
  • ファイルは揮発性
  • ディスクI/Oが遅い
  • host毎ではなくtask毎にリソースを食う
  • Container に task 定義が当たらないときなど Management console にエラーが吐かれるが、何のエラーか分かり辛い。links 連携されていない場合、STOPPED (CannotCreateContainerError: API error 等。

ecs-cli のインストール

$ sudo curl -o /usr/local/bin/ecs-cli https://s3.amazonaws.com/amazon-ecs-cli/ecs-cli-darwin-amd64-latest
$ sudo chmod +x /usr/local/bin/ecs-cli

$ ecs-cli configure --region ap-northeast-1 --access-key xxx --secret-key zzz --cluster dev-001

Cruster 起動

ECS Cluster に所属させる EC2 instance の起動を行う前に、instance 内の ECS Container Agent が ECS API へのアクセス権限を持っているか (IAM Role) や Security Group (アクセスコントロール) を適切に設定する必要がある。


// Cluster の設定 $ ecs-cli configure --region ap-northeast-1 --cluster dev-001 // コンテナの起動 $ ecs-cli up --keypair xxx --capability-iam --instance-type t2.medium --security-group sg-xxx --vpc vpc-xxx --subnets subnet-xxx --force --no-associate-public-ip-address --region ap-northeast-1 --size 1 // compose.yml の反映 $ ecs-cli compose --file docker-compose.yml up // 起動確認 $ ecs-cli ps // service の削除 $ ecs-cli compose --file ./docker-compose.yml service rm // Cluster の停止 $ ecs-cli down --force $ ecs-cli down --force --cluster dev-001 // scaling $ ecs-cli scale --capability-iam --size 2

task 定義

ecs-cli compose コマンドによるタスク定義。

$ ecs-cli compose --project-name hello-world --file hello-world.yml create

IAM Policy

Amazon ECS コンテナインスタンスの IAM ロール

http://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/launch_container_instance.html

ECR

  • 少ない手順で private repositry を作成可能
  • IAM policy でアクセス制御可能
  • 同 region 内の ECR と EC2 データ転送量無料

トラブルシューティング

Amazon ECS のトラブルシューティング

参考サイト