Help us understand the problem. What is going on with this article?

Private VPCにECSクラスターを構築する

More than 1 year has passed since last update.

Private VPCにECSクラスターを構築する

猫も杓子もコンテナである。
半年前までDockerコマンドを打ったことさえなかった50手前のおじさんが、Private VPC内にECSクラスターを構築するはめになった。困難の連続だったので、ハマりどころなどを共有したい。

インターネットゲートウェイを持たないVPC

ここで言うPrivate VPCとは、インターネットゲートウェイ(NAT含む)を持たない、完全にPrivate IPのみで構成されるAWSのVPCを指す。
インターネットに全く出れないのかというとそんなことはなく、DirectConnect経由で(オンプレの)HTTP Proxyを経由して出ることが可能である。

Docker HUB/ECRにどうやってアクセスするか

ここでまず問題となるのは、DockerのリポジトリがあるDocker HUBやECRにどうやってアクセスするか、ということである。まず抑えておかないといけないのは、ECS始め、EKS、AKS、GKEなどのコンテナオーケストレーションサービスは、はインターネットゲートウェイが存在することを前提としているということである。インターネット上に存在するコンテナリポジトリからイメージをpullしてくるのだから当然といえば当然であり、何年か前の文献にはインターネットゲートウェイを持たないVPCにはECSのクラスターを置くことはできないとすら書かれている。

ECS(EC2起動タイプ)はHTTP Proxy経由で利用可能

ECS(Fargate)を調べていたところ、早々にインターネットゲートウェイがないと使用できないことがわかって胸をなでおろした。dockerに何故かこだわっているプロジェクトマネージャーが、心を入れ替えてproxyを諦めてくれると思ったのだ。しかし彼は頑固だった。インターネットゲートウェイ(NAT含む)などけしからん!ということになり、なんとかPrivate VPC内でコンテナオーケストレーションをする方法を模索した。
そして、幸か不幸か以下の記事が見つかった。

HTTPプロキシ設定

結論を言えば、ECS(EC2起動タイプ)ではHTTP Proxy経由での利用が可能だった。

手順

空のクラスター(EC2起動タイプ)を作る

通常EC2起動タイプを選択するとEC2インスタンス(オートスケーリンググループ)も同時に作成されてしまうが、クラスター名入力の下にある「空のクラスターを作成」というチェックボックスをオンにすることにより、EC2インスタンスを作成せずにクラスターだけを作成できる。

起動設定を作成する

EC2の画面から「起動設定」を作成する。

  • ベースとなるイメージはECS最適化インスタンスを参考として選択する。東京リージョン(ap-northeast-1)の場合ami-05b296a384694dfa4を使用する。

  • インスタンスタイプは何でもいいようだが、私はm4.largeを主に使用している。起動設定を作成したあとでインスタンスタイプを変更するのは面倒なので、あまり変更しないほうが良い(リソースの増加にはインスタンス数の増加=スケールアウトで対応する)

  • 起動設定の作成時に、「高度な設定」より上述のリンクに記載されているユーザーデータをコピー&ペーストする(proxyの設定及びクラスター名は自分の環境に合わせて修正する)

オートスケーリンググループを作成する

上記起動設定からオートスケーリンググループを作成し、「インスタンスの必要数」を1以上に設定する。しばらくするとEC2インスタンスが起動してくる。この際のインスタンス名などは何でもよく、上述の起動設定でユーザーデータに記述されているクラスター名が全てである。

クラスターへのインスタンス追加の確認

ECSのコンソールから、クラスターの「登録済みインスタンス」に0より大きい数字が表示されたら登録は成功している。いつまでも出てこない場合、クラスター名などのユーザーデータや、セキュリティグループの設定がおかしい可能性が高い。

サービスの起動

私はecs-cli compose service upを利用して上記クラスターにサービスを登録・起動しているが、なんとか使用できている。

課題

Cloudwatch Logsでログが取れない

ECSの説明を読む限り、logging driverにawslogsを指定するとCloudwatch Logsへのログ出力が可能なはずなのに、何度やってもコンテナのロードに失敗する。エラーメッセージもおかしいので、ECS自体のバグ(ないしproxy環境の制限)と考えている。
現在はsyslogドライバーを使用し、それをECSインスタンス上にインストールしたawslogsでCloudwatch Logsに飛ばすということをしているが、syslogが混ざってしまうのでとても見づらい。

時たまクラスターが死ぬ

デプロイを短時間に何度も繰り返したりした際に、クラスターが死ぬ(新しいコンテナが一切ロードされなくなる)という状態を何度か経験している。ECSインスタンスを作成しなおせば治るのだが、クラスターが死んでいると言ってもECSインスタンスそのものは生きているので、オートスケーリングが効かず手動でしか回復できない。幸い、クラスターを何本かに分けたことでそれ以降再現していない。

スケールイン時に生きているコンテナが載ったECSインスタンスが殺されることがある

オートスケーリンググループの「インスタンスの必要数」をへらすとECSインスタンスのうち一部が勝手に終了(Terminate)されるが、殺される順序はスケールインのポリシーで制御できる。前述のインスタンスの入れ替えなどではOldest(古いものから殺す)というのが有効だった。が、「稼働コンテナ数が0のもの」といった細かい制御は(標準では)できないので、一工夫必要になる。
現在時点ではそこまでスケールアウト・スケールインの必要はないのであまり研究していない。

 最後に

あまり技術的に深掘りした記事でなく恐縮だが、この手の情報があまりないので書いてみた。同じような境遇の方がおられたら、参考になれば幸いである。もちろん、もっとこうしたほうがいいよ、という情報も大歓迎である。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away