開発環境にDockerを導入しようとしたら大苦戦した話

こんにちは、cocone connectでサーバーエンジニアをしているマイヤーズです。

 

今回弊社で新しいプロジェクトを立ち上げることになり、その開発環境にコンテナを導入することとしたのですが、その結果思わぬ苦戦を強いられたので、導入にあたっての流れを順に記載していこうと思います。

Dockerの導入を検討されている方のご参考になればと思います。

そもそもDockerってなんだっけ?

まず初めにDockerについて軽く説明しようと思います。

 

DockerとはDocker社が開発したコンテナ型の仮想環境を作成・実行するためのプラットフォームで、OS上に隔離されたアプリケーションの実行環境(コンテナ)を作成し、1台のホストマシン上で複数のホストが動いているかのような環境を実現する仮想化技術です。

この説明ではイメージがつかないと思うので、VMwareやVirtualBoxをはじめとする仮想マシンと比較してみましょう。

 

仮想マシンもDockerも仮想化という意味では同じなのですが、構成が異なります。

仮装マシンではホストマシン上でハイパーバイザを利用してゲストOSを動かし、その上でミドルウェアなどを動かしています。

それに対してコンテナはホストマシンのカーネルを利用し、プロセスやユーザなどを隔離することであたかも別のマシンが動いているかのように動かすことができます。

そのためコンテナは軽量で高速に起動・停止をすることが可能です。

 

 

他にもDockerの特徴には以下のようなものがあります。

  • Dockerファイルと数回のコマンドで環境を構築できるため、環境構築が容易である
  • 起動オプションや起動手順などもDockerファイルに記載することがで可能であるため、同じDockerイメージ(Dockerファイル)を配布すれば環境差異が発生しない
  • 従来の仮想マシンと比較しディスクやメモリの消費が少ない
  • アプリケーションの3層構造(フロント、サーバー、DB)を1つのコンテナの中で実現可能
  • 1度作成したコンテナはDockerイメージを作成し、他のコンテナへ適用することで再利用が可能
  • 他Webサービスのサポートが進んでいる
    (例 : Amazon ECSやCircleCIなどのCI/CDツールなど)

Dockerの仕組みで大事なこと

Dockerを使う上で知っておくべきことはいくつかありますが、今回は重要な”マウント”と”イメージ”についてご紹介します。

マウント

マウントはホスト側(コンテナの外)にあるディレクトリ・ファイルをコンテナの中から利用できるようにする機能です。

マウントすることによりホスト側で編集・保存したものがコンテナ環境の同ファイルでも同じ編集内容が保存されるようになります。

インタプリタ言語であれば開発したものが都度Docker環境に構築されるため、開発が容易に行えます。

イメージ

イメージはDockerコンテナの実行に必要な概念としてのパッケージ(ファイルやメタ情報の集合体)です。

Dockerイメージの構成はDockerファイルに記載されている命令文がレイヤ構造になっています。

AWS環境でコンテナ環境を実現するには?

ここまではDockerを使ったローカル環境での開発について記載してきました。

ただ、実際に本番環境に上げる際には、AWSやGCPなどのクラウドサービスを使って環境を構築していくと思います。

 

そこで今回はAWSでコンテナ環境を構成する構築要素を紹介します。

AWSでコンテナ環境を作るには、コンテナの管理をする”コントロールプレーン”(ECSやEKS)と、実際にコンテナが稼働する”データプレーン”(EC2やFargate)という2つの要素が必要となります。

これらのサービスを組み合わせることでAWSでコンテナ環境を構築していきます。

AWSコンテナ関連サービスの組み合わせの検討

代表的な構成の組み合わせは以下の4つで、それぞれに違いや特徴があります。

ECS on EC2

 

メリット

  • インスタンスタイプの変更などに関するリソース拡張が容易にできる
  • 利用するイメージのキャッシュをEC2のホスト上に保持できるため、デプロイに関しては速い
  • EC2は多くのエンジニアにとって慣れ親しんだサービスであるため学習コストが低い
  • 障害対応時のリカバリ調査もしやすい

 

デメリット

  • EC2インスタンスの管理が必要となるため管理コストがかかる
  • 学習コストは低いがこの構成の選択肢は良くも悪くも無難

 

ECS on Fargate

 

メリット

  • 構築やスケールが比較的容易に行える
  • sshポートを開ける必要がないため、セキュリティリスクが少ない
  • Fargateによりインスタンスの管理が不要になり、管理コストがなくなる
  • sshログインはできないが、ecs execを使ってコンテナに入ることができるため障害対応時の調査が可能

 

デメリット

  • コンテナごとにENIがアタッチされるため、デプロイに関しては比較的遅い
  • EC2と比較して従量課金制であるが、少し割高な料金になる
  • イメージがキャッシュできないため、デプロイはEC2より少し遅い

 

EKS on EC2

 

メリット

  • 利用するイメージのキャッシュをEC2のホスト上に保持できる
  • EKS(Kubernetes)界隈のコミュニティが活発であり、エンジニアリング観点としては良い面が多い

 

デメリット

  • EKS(Kubernetes)の学習コストが比較的高い
  • ECSと比較してEKSにも課金があるため割高な料金になる
    (課金額はデータプレーンの利用料と比較したら低い)
  • EKS(Kubernetes)が定期的なバージョンアップが必要であるため、運用コストがかかる

 

EKS on Fargate

 

メリット

  • EKS on EC2と比べるとFargateを選択しているため、運用コストが低い
  • 尖った構成になるため、エンジニアリング的な観点としては良いことが多い

 

デメリット

  • EKSは導入ケースがあるが、データプレーンにFargateを使用する場合の導入ケースや参考文献が少ない
  • 現時点ではいくつかの制約事項があり、導入の障壁が高い

 

構成図の一例紹介

それぞれの構成の特徴や展開するサービス・弊社の社内エンジニアリング等々を考慮し、現時点のコンテナ環境導入のファーストチョイスは”ECS on Fargate”だと考え、採用することになりました。

そうと決まれば次はサービス構成図の作成を行います。

こちらが弊社で構築しようと考えた”ECS on Fargate”の構成図になります。

 

ハマりどころと問題点

構成図を作成し、社内調査を行い、公式ドキュメントやQiitaなどを活用し、いざコンテナ環境を構築!

と進めていたのですが、進めるたびにたくさんの問題に直面しました。

ローカル環境での開発にあたっての問題点

JVM系言語との相性が悪い

そもそもの話として起動が遅いです。

加えてイメージサイズやメモリ使用量が大きくなるという問題もあります。

また、Docker開発する際にはリモートデバッグが必要になってきますが、Docker + IntelliJ IDEAで開発する場合にはローカルデバッグ推奨のためデバッグ方法について悩みました。

 

Dockerfileで立ち上げたアプリのリモートデバッグはうまくいくのに、docker-compose.ymlを使うとうまくいかない

この問題はIntelliJ IDEAがdocker-compose.ymlをうまいことキャッシュしているせいな気がしますが、原因は調査中です……。

 

Windowsで利用するハードルが高い

弊社では開発にMacを使用したので問題はなかったのですが、参考程度に書こうと思います。

「Docker for Windows」を利用するにはHyper-Vを有効化する必要がある為Windows10 Proが必要になります。

また、Macでは動くがWindowsだと動かないという記事が散見されるというのもあります。

 

AWSコンテナ環境での開発にあたっての問題点

CodeBuildのソースプロバイダがGitLabをサポートしていない

こちらはソース管理ツールにGitLabを導入している場合に限りますが、CodeBuildのソースプロバイダはGitLabをサポートしていません。

GithubやBitbucketはサポートされているんですけどね……。

対応策としては、AWSのソース管理サービス(CodeCommit)でGitLabのソースをミラーリングする、などがあります。

 

CodePipelineがサブモジュールをサポートしていない

この問題の対応策としては、サブモジュールをCodeBuildやjenkins等のビルドツールでビルドする際に、サブモジュールを含めたアプリケーションのソースを丸ごとクローンするなどがあります。

ただ、VPCでCodeBuildを使用するにはNATゲートウェイもしくはNATインスタンスが必要となり、使用料金が高くなってしまいます。

NATはお高い……。

最後に

今回Dockerを導入するにあたって、サンプルアプリをECS環境で構築し、Hello Worldするところまでは比較的スムーズでしたが、実際の開発サイクルの検討やプロトアプリを載せた場合に問題が多発してしまいました。

とりわけデバッグ方法の模索とビルド周りは原因調査に時間がかかってしまったため、一旦コンテナ環境の構築をペンディングし、EC2とCodeDeployでアプリ側を構築する方針としました。

 

開発にあたって良い部分が多いDockerではありますが、使っているツールや展開するサービスの規模によっては問題もあります。

開発環境にコンテナ環境を選択される際の参考になればと思います。

 


 

cocone connectでは一緒に働く仲間を募集中です。

ご興味のある方は、こちらのリンクからぜひご応募ください。

 

cocone connect株式会社 採用情報

https://recruit.jobcan.jp/coconeconnect

 

cocone connect株式会社 公式サイト

https://connect.cocone.co.jp/

 

また、ココネでも一緒に働く仲間を募集中です。

ご興味のある方は、ぜひこちらの採用特設サイトをご覧ください。

https://www.cocone.co.jp/recruit/contents/

Category

Tag

%d人のブロガーが「いいね」をつけました。