Cloud9でEKSに独自コンテナをデプロイして公開する

プログラム
スポンサーリンク

前回の記事では、EKSのClusterを作って、ためにし既存のコンテナをデプロイするところまで行いました。

Cloud9でEKSのClusterの作成と削除をする
Cloud9の環境を作成し、EKSでClusterを作成します。Clusterの作成よりも環境構築が難しいはずです。

今回は、AWSに独自のコンテナをデプロイして、Web上に公開するところまでを行います。

今回も環境はCloud9前提。前回の環境を削除していなければ、そのまま使いまわします。一度削除していたら、前回の記事で行った(2.Cloud9でEKSを使う環境を整える)のと同じように環境を構築してください。

この記事でわかること
  • 自作のDockerイメージをECR(Amazon Elastic Container Registry)に保存する方法
  • EKSにECRからコンテナをデプロイする方法
  • EKSにデプロイしたコンテナをWeb上に公開する方法
前提条件
注意
  • アカウント作成後12か月以内でも無料枠外のことを行うので費用がかかる
  • 作成したEKS Clusterなどのリソースを削除し忘れるとずっと費用がかかり続けることになる

Cloud9で独自Dockerイメージを作成する

まずはEKSにデプロイするDockerイメージを作成します。

なんでもいいのですが、自分が作ったイメージであることがわかりやすいものがいいでしょう。この記事では適当な文字列を表示するWebサーバを構築します。

任意のフォルダで以下のようにファイルを配置してください。

カレントにDockerfile、htmlフォルダにindex.htmlフォルダがある

それぞれのファイルの中身はこうします。

Dockerfile

FROM nginx

COPY html /usr/share/nginx/html

index.html

Docker image that we created.

Dockerfileがあるフォルダで以下のコマンドを実行するとDockerイメージが作成されます。

# Dockerを起動
sudo service docker start
# Dockerイメージをcloud9-imageという名前で作成。最後の.(ドット)を忘れないように
sudo docker build -t cloud9-image:latest .

DockerイメージをECRに保存する

先程作ったDockerイメージをECR(Amazon Elastic Container Registry)に保存します。

まずはECR上に保存場所を定義するところから。

# dockerコマンドでECRのリポジトリを操作できるようにする
# {aws_account_id}の部分は後で説明
aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin {aws_account_id}.dkr.ecr.ap-northeast-1.amazonaws.com
# ECRにsample-containerという名前で保存場所(リポジトリ)を定義
# このコマンドでリポジトリを作ると、private(一般には未公開)になる
aws ecr create-repository --repository-name sample-container --image-scanning-configuration scanOnPush=true --region ap-northeast-1

{aws_account_id}の部分には、AWSのアカウントIDを入れます。AWSコンソールにログインすると、右上に表示されるものです。表示状はハイフンが入っていますが、ここで使うのはハイフン無しのもの。

ユーザIDをクリックすると次のような画面が出るので、アカウントID:の横にあるボタンを押してください。数字で12桁の文字列がコピーされます。

AWSのアカウントIDをクリックした際の表示

ECRにリポジトリを定義したら、そこにDockerイメージをアップロードします。アップロードするためには、Dockerイメージの名前を規定に沿ったものに変更した上でpushしなくてはなりません。

# イメージ名をECRに保存するためのルールに沿ったものに変更する
docker tag cloud9-image:latest {aws_account_id}.dkr.ecr.ap-northeast-1.amazonaws.com/sample-container:latest
# ルールに沿ったイメージをpushすると、ECRにアップロードされる
docker push {aws_account_id}.dkr.ecr.ap-northeast-1.amazonaws.com/sample-container:latest

リポジトリにはタグ名(今回だとlatest)を変更することで、複数のイメージを格納可能です。

EKSに独自Dockerイメージをデプロイする

作成したDockerイメージをEKSにデプロイします。まだEKSにClusterを作っていなかったら作成しましょう。

注意

くどいようですがEKSではClusterを作ると費用が発生します。後述のリソースの削除を忘れないようにしてください。

# Clusterの存在を確認
eksctl get cluster
# もしtestというClusterがなかったらEC2を使う設定で作成
# 使うインスタンスは無料枠のあるt2.microを2つ
eksctl create cluster --name test --node-type=t2.micro --nodes=2

続いてDockerイメージをデプロイするための設定ファイル(manifestと言います)をYAMLで作ります。ファイルの内容は、sample-containerという名前でECRに先程pushしたイメージをデプロイしなさいというものです。

sample-container.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: sample-container
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: {aws_account_id}.dkr.ecr.ap-northeast-1.amazonaws.com/sample_container:latest
        ports:
        - containerPort: 80

imageの部分は先程pushしたタグ名にしてください。このファイルを指定して以下のコマンドを実行すると、自作のDockerイメージのデプロイが行なえます。

kubectl apply -f sample-container.yaml
# デプロイできていることを確認、sample-containerという名前が出てくるはず
kubectl get deployments
# NAME               READY   UP-TO-DATE   AVAILABLE   AGE
# sample-container   1/1     1            1           15s

EKSにデプロイしたコンテナを公開する

続いて先程デプロイしたコンテナを外部に公開します。デプロイしたときと同じく、設定ファイル(manifest)をYAMLで書きます。ロードバランサを使って公開するという設定です。

もしEC2ではなくFargate前提のClusterを作っていた場合は、以下の作業ではうまくいきません。Fargateでコンテナを外部に公開するのがややこしいので、ClusterをEC2前提で作っています。

service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: sample-service
spec:
  type: LoadBalancer
  selector:
    # sample-container.yamlのmatchLabelsを指定
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

以下のコマンドで設定を有効にしましょう。

kubectl apply -f service.yaml
# 外部に公開されるドメインを確認、EXTERNAL-IPが外部に公開されるドメイン
kubectl get services

kubectl get servicesを実行すると、以下のような結果が出力されるはずです。

kubectl get servicesの実行結果、EXTERNAL-IPに外部公開用のドメインが表示される

このEXTERNAL-IPの値にブラウザでアクセスすると、先程デプロイしたコンテナの中身(nginxで適当なindex.htmlを出力したもの)が確認できます。

ロードバランサが起動するまでに少し時間が必要です。もしEXTERNAL-IPにアクセスした際にエラーになってしまったら、1分ほど時間をおいてから再度アクセスしてください。

外部公開用ドメインにブラウザでアクセスした結果

以上で独自Dockerコンテナの公開ができました。

リソースを削除する

注意

リソースの削除を忘れると、時間ごとに費用がかかります。特にEKS Clusterは個人で支払うには高額なため作業が終わったら必ずリソースを削除しましょう。

ECRからデータを削除

ECRにpushしたDockerイメージを削除します。アカウントを作ってから1年間は月500MBの無料枠があるのですが、忘れないうちに削除しましょう。

aws ecr batch-delete-image --repository-name sample-container --image-ids imageTag=latest --region ap-northeast-1

EKSからClusterを削除

EKSのClusterは無料枠がなく、1時間$0.1がかかり続けます。(ClusterだけでなくNATも使われるので実際はもっと高いです)こちらは忘れずに削除しましょう。

# 念のためサービスとデプロイしたPodを削除しておく
kubectl delete -f service.yaml 
kubectl delete -f sample_container.yaml
# Clusterの削除
eksctl delete cluster --name=test
# 念のためClusterの一覧を表示、No clusters foundのはず
eksctl get cluster

Cloud9の環境を削除

AWSのWebコンソールでサービスからCloud9を選択し、今回利用した環境を選んでDeleteボタンを押せば削除できます。

まとめ:これであなたもDockerでアプリを公開できる!(ただし高い)

今回の記事の内容が理解できれば、あなたは

  • DockerコンテナをEKSにデプロイして
  • そのコンテナを外部に公開する

ことができるようになっているはずです。ただ、単独のコンテナは公開できても複数のコンテナが連動するアプリはまだデプロイできません。

また、やはり高いのはネックです。EKSを使うと最低でも月1万円はかかります。個人の趣味で使うのは少し厳しいでしょう。規模が大きな商用アプリ向けのサービスと言えます。

とはいえ、せっかくここまで勉強してきました。引き続き目標であるGithub Actionsを使ったAWSへのDockerコンテナデプロイに向けた記事を作成していく予定です。

この記事でわからないところがあったら、Twitterお問い合わせフォームから連絡をください。記事ごとのコメント欄も開放しているので、そちらでも大丈夫です。現在勉強中の内容なのでお答えできない可能性もありますが、できる限り調べてみます。

最後に、リソースはしっかり削除しましょう。私は1週間Cluster削除を忘れていて3000円以上請求されることになりました。AWSはドルベースで請求がくるため、最近の円安で請求額は更に高くなっています。

続いてGithub ActionsでEKSにデプロイする方法です。

コメント

タイトルとURLをコピーしました