前回の記事では、EKSのClusterを作って、ためにし既存のコンテナをデプロイするところまで行いました。
今回は、AWSに独自のコンテナをデプロイして、Web上に公開するところまでを行います。
今回も環境はCloud9前提。前回の環境を削除していなければ、そのまま使いまわします。一度削除していたら、前回の記事で行った(2.Cloud9でEKSを使う環境を整える)のと同じように環境を構築してください。
Cloud9で独自Dockerイメージを作成する
まずはEKSにデプロイするDockerイメージを作成します。
なんでもいいのですが、自分が作ったイメージであることがわかりやすいものがいいでしょう。この記事では適当な文字列を表示するWebサーバを構築します。
任意のフォルダで以下のようにファイルを配置してください。
それぞれのファイルの中身はこうします。
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桁の文字列がコピーされます。
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を作っていなかったら作成しましょう。
# 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で書きます。ロードバランサを使って公開するという設定です。
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を実行すると、以下のような結果が出力されるはずです。
このEXTERNAL-IPの値にブラウザでアクセスすると、先程デプロイしたコンテナの中身(nginxで適当なindex.htmlを出力したもの)が確認できます。
以上で独自Dockerコンテナの公開ができました。
リソースを削除する
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にデプロイする方法です。
コメント