AWS で Golang の Webアプリをコンテナ基盤にデプロイする
AWS EKS編
コンテナ基盤でwebサービスを運用する際には、kubernetesというコンテナオーケストレーションサービスを用いることが多いそうなので、kubernetesの基本的な部分に関して学習をしたのち、
AWS EKSにてwebアプリをデプロイしてみた。
kubernetesについて
kubernetesの基本的な概念について把握をするために、まずはじめに公式のチュートリアルをざっとこなしてみた。
公式チュートリアルを一通りこなした後は、EKSにてデプロイすることに挑戦した。
以前、AWS ECSにてコンテナ基盤でwebアプリをデプロイしたことがあったため、
デプロイするための大まかな流れについてはイメージがしやすかった。
EKSにデプロイ
AWS EKSへのデプロイについては基本的にAWSの公式ドキュメントを参考にして試行錯誤しながら行なった。
事前準備
EKSのリソースを操作するためには、ローカル上で実行する、 kubectl
, eksctl
コマンドをインストールする必要がある。
(参考)AWS公式ドキュメント
EKSクラスターの作成
EKSクラスターを以下のコマンドで作成する。
クラスターの作成は結構時間がかかるので気長に待つ。
eksctl create cluster \
--name go-cluster \
--region us-west-2 \
--with-oidc \
--ssh-access \
--ssh-public-key <your-key> \
--managed
上記のコマンドでクラスターを作成すると、同時にクラスター内にノードが作成されるので、以下のコマンドでノードが作成されたかどうかを確認する。
コマンドをうって、以下のしょうな出力があればノードの作成が無事に完了しているのでOK。
$ kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
fargate-ip-192-168-141-147.us-west-2.compute.internal Ready <none> 8m3s v1.18.8-eks-7c9bda 192.168.141.147 <none> Amazon Linux 2 4.14.209-160.335.amzn2.x86_64 containerd://1.3.2
fargate-ip-192-168-164-53.us-west-2.compute.internal Ready <none> 7m30s v1.18.8-eks-7c9bda 192.168.164.53 <none> Amazon Linux 2 4.14.209-160.335.amzn2.x86_64 containerd://1.3.2
(参考)AWS公式ドキュメント
namespaceを作成する
namespaceを作成する。
namespaceとはクラスター内をいくつかの領域に区切るために定義するものである。
VPCをサブネットで区切るイメージに近いのかもしれない。
kubectl create namespace go-namespace
serviceとdeploymentを定義する設定ファイル作成
kubernetesではマニュフェストと言われる、設定ファイルを作成する。
ローカル上で go-service.yml
を作成。
ブラウザから閲覧するためには spec
部分に type : LoadBalancer
を追加する必要があるようなので忘れずに追加する。
apiVersion: v1
kind: Service
metadata:
name: go-service
namespace: go-namespace
labels:
app: go-app
spec:
----- 追加 ----------
type: LoadBalancer
--------------------
selector:
app: go-app
ports:
- protocol: TCP
port: 80
targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: go-deployment
namespace: go-namespace
labels:
app: go-app
spec:
replicas: 3
selector:
matchLabels:
app: go-app
template:
metadata:
labels:
app: go-app
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: beta.kubernetes.io/arch
operator: In
values:
- amd64
- arm64
containers:
- name: web
image: <自分がデプロイしたいECRにpushされている docker imageのuriを記述する>
ports:
- containerPort: 80
デプロイする
以下のコマンドで、EKSクラスターにデプロイする
kubectl apply -f go-service.yaml
(参考)AWS公式ドキュメント
(参考) DevelopersIO produced by Classmethod
ブラウザで確認
以下コマンドの出力内容の中に EXTERNAL-IP
というものがあるのでこのエンドポイントを取得して、ブラウザでwebアプリが表示されればデプロイ成功です!
$ kubectl get service -n go-namespace
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
go-namespace LoadBalancer 10.100.111.70 a988439dfjsjlfa1dca04c3e5ff60-221349856.us-west-1.elb.amazonaws.com 80:31363/TCP 10s
終わりに
自分で作成したwebアプリを何とか自力でEKSにデプロイすることができました。
今回は最低限の設定を用いてデプロイを行いましたが、細かなパラメータを設定したりして、もっと色んなことができるのだと思います。
今後も継続的にkubernetesについて学習をしてある程度習熟できるようになりたいですね。
AWS ECS編
現職の現場ではプライベートクラウドを使用していて、本番環境の運用をAWSのようなパブリッククラウドを使用して、さらにECSのようなコンテナ基盤での運用ができていない。
docker imageを使用してコンテナ基盤で運用をすると本番環境の運用及び、本番環境へのデプロイ作業がものすごく楽になりそうなので、学習してみた。
この記事では、ローカル環境でdocker imageをビルドして、AWSのECRにプッシュ、その後ECSでデプロイを完了させるところまでを解説してみる。
ローカルにて
ビルドしたいDockerfileがおいてあるディレクトリと同じ階層でビルドする
docker build -t image_name .
ビルドしたimageにタグ付けをする。
この辺りのコマンドは、ECRにてリポジトリを作成したのち、AWSのコンソール上でもわかりやすくpushコマンドが説明されているので迷うことがあんまりなさそう。
docker tag image_name aws_account_id.dkr.ecr.region.amazonaws.com/my-web-app
ECRにプッシュする。
docker push aws_account_id.dkr.ecr.region.amazonaws.com/my-web-app
(参考)AWS公式ドキュメント
ECSにてpushしたdocker imageをデプロイ
タスクを定義する
新しいタスク定義の作成
今回は「FARGATE」を選択する。
タスクとコンテナの定義の設定
「タスク定義名」を入力する。他の項目はデフォルトで。
タスクの実行 IAM ロール
「ecsTaskExcutionRole」がデフォルトで選択されているのでそのままで。
タスクサイズ
「タスクメモリ」を0.5GB、「タスクCPU」を0.25vCPUに設定する。(どちらも一番スペックが小さいやつ)
コンテナの定義
ここは結構需要だと思う。
「コンテナの追加」から、以下の設定項目を入力する。
「スタンダード」内にあるいくつかの入力項目は必ず入れる必要があるみたい。
設定項目 | 入力値 | 説明 |
---|---|---|
コンテナ名 | web | - |
イメージ | aws_account_id.dkr.ecr.region.amazonaws.com/my-web-app:latest | ECRにpushしたdocker imageのURI |
プライベートレジストリの認証 | チェックなし | - |
メモリ制限(MiB) | 300 | 300 ~ 500が推奨らしいので |
ポートマッピング | 80 | これでホスト側とコンテナ側の80ポートがマウントされる |
「詳細コンテナ設定」は省略しても大丈夫そう。
実際の運用となると、細かく設定するのだとは思いますが。
サービス統合
とりあえず省略
プロキシ設定
とりあえず省略
ログルーターの統合
とりあえず省略
ボリューム
とりあえず省略
Tags
とりあえず省略
起動ステータス
「タスク定義のステータス - 2/2 完了」となればタスク定義は完了。
(参考)AWS公式ドキュメント
クラスターを作成する
クラスターテンプレートの選択
クラスターテンプレートから「ネットワーキングのみ」を選択して、次のステップへ。
クラスターの設定
「クラスター名」を入力して「作成」へ。
サービスを作成する
サービスの設定
設定項目 | 入力値 | 説明 |
---|---|---|
起動タイプ | FARGATE | - |
タスク定義(ファミリー) | web | 先ほど定義したタスクを選択 |
タスク定義(リビジョン) | 1(latest) | 最新のタスク定義を選択 |
クラスター | sample-cluster | デフォルトで選択されるのでそのままで |
サービス名 | sample-service | 任意の名前を |
サービスタイプ | REPLICA | そのままで。設定したタスクの数を維持してくれるらしい。 |
タスクの数 | 1 | 維持したいタスクの数 |
最小ヘルス率 | 100 | デフォルトのままで |
最大率 | 200 | デフォルトのままで |
デプロイサーキットブレーカー | 向こう | デフォルトのままで |
デプロイメント
デフォルトのままで
タスクのタグ付け設定
デフォルトのままで
Tags
とりあえず省略。
ネットワーク構成
VPC とセキュリティグループ
設定項目 | 入力値 | 説明 |
---|---|---|
クラスターVPC | 任意のVPC | - |
サブネット | 任意のサブネット | - |
セキュリティグループ | デフォルト | - |
パブリックIPの自動割り当て | ENABLED | - |
セキュリティグループ | デフォルト | - |
ヘルスチェックの猶予期間
とりあえず省略
ロードバランシング
今回は「なし」を選択する。
App Mesh
とりあえず省略
サービスの検出
とりあえず省略
Auto Scaling (オプション)
「サービスの必要数を直接調節しない」を選択する。
確認
確認後、「サービスの作成」を押す。
起動ステータス
「ECSサービスのステータス - 3/3 完了」となればサービスの作成は完了。
ブラウザで確認
サービスの詳細ページから、「タスク」タブを選択後、タスク一覧からタスクの詳細を確認。
確認したパブリックIPをブラウザに入力してwebアプリが表示されたらデプロイ完了。
終わりに
AWSのコンテナ基盤を使用してデプロイすると非常に簡単で便利でした。
AWSの公式ドキュメントにも手順が丁寧に書かれていてあまり使い慣れていない私でも問題なく扱うことができました。
デプロイする過程で細かな設定項目はスキップしましたが、実際の運用では、細かい設定も行うのだと思います。
今後、コンテナ基盤で本番環境を運用している現場などで、実務での使われ方をキャッチアップしていきたいです。
Discussion