🌟

AWS で Golang の Webアプリをコンテナ基盤にデプロイする

2022/03/30に公開

AWS EKS編

コンテナ基盤でwebサービスを運用する際には、kubernetesというコンテナオーケストレーションサービスを用いることが多いそうなので、kubernetesの基本的な部分に関して学習をしたのち、
AWS EKSにてwebアプリをデプロイしてみた。

kubernetesについて

kubernetesの基本的な概念について把握をするために、まずはじめに公式のチュートリアルをざっとこなしてみた。

https://kubernetes.io/ja/docs/tutorials/

公式チュートリアルを一通りこなした後は、EKSにてデプロイすることに挑戦した。
以前、AWS ECSにてコンテナ基盤でwebアプリをデプロイしたことがあったため、
デプロイするための大まかな流れについてはイメージがしやすかった。

EKSにデプロイ

AWS EKSへのデプロイについては基本的にAWSの公式ドキュメントを参考にして試行錯誤しながら行なった。

事前準備

EKSのリソースを操作するためには、ローカル上で実行する、 kubectl , eksctl コマンドをインストールする必要がある。

(参考)AWS公式ドキュメント

https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/install-kubectl.html

https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/eksctl.html

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公式ドキュメント

https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/getting-started-eksctl.html

namespaceを作成する

namespaceを作成する。
namespaceとはクラスター内をいくつかの領域に区切るために定義するものである。
VPCをサブネットで区切るイメージに近いのかもしれない。

kubectl create namespace go-namespace

serviceとdeploymentを定義する設定ファイル作成

kubernetesではマニュフェストと言われる、設定ファイルを作成する。

ローカル上で go-service.yml を作成。
ブラウザから閲覧するためには spec 部分に type : LoadBalancer を追加する必要があるようなので忘れずに追加する。

go-service.yaml
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公式ドキュメント

https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/sample-deployment.html

(参考) DevelopersIO produced by Classmethod

https://dev.classmethod.jp/articles/aws-summit-online-2020-hol-06/

ブラウザで確認

以下コマンドの出力内容の中に 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公式ドキュメント

https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/docker-push-ecr-image.html

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公式ドキュメント

https://aws.amazon.com/jp/getting-started/hands-on/deploy-docker-containers/

クラスターを作成する

クラスターテンプレートの選択

クラスターテンプレートから「ネットワーキングのみ」を選択して、次のステップへ。

クラスターの設定

「クラスター名」を入力して「作成」へ。

サービスを作成する

サービスの設定

設定項目 入力値 説明
起動タイプ 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