pulumiとkubectlを用いたEKS環境構築方法をご紹介(後編)

こんにちは。フリージアの佐久間です。
Pulumiとkubectlを用いたEKS環境構築方法を2回に分けてご紹介しようと思います。

pulumiとkubectlを用いたEKS環境構築方法をご紹介(前編)

登場人物は以下の通りです。

name description
springboot Webアプリケーション
jib DockerイメージBuilder
eks awsで提供されているkubenates環境
pulumi Web技術でコーディング出来るIaCツール
kubectl Kubernetesコマンドラインツール
ecr awsのdockerレジストリー

後編では、EKS構築と、Dockerイメージのデプロイをしようと思います。

タスクは以下の通りです。

  • pulumiで、EKSを構築
  • kubectlでDockerイメージリリース
  • おまけ

それでは順番にやっていきたいと思います。

pulumiで、EKSを構築

続いて、pulumiでEKSを構築していきます。
システム運用時に変わるような部分まで、pulumiに全部任せると逆にめんどくさくなりそうなので、
clusterまではpulumiで、それ移行はkubectlでやろうかなと思います。

まずは「pulumi/eks」をインストールします。

$ yarn add @pulumi/eks

その後、先程のソースを以下のように編集します。

import * as eks from "@pulumi/eks"; // 追加
import * as pulumi from '@pulumi/pulumi'
import * as aws from '@pulumi/aws'
import * as awsx from '@pulumi/awsx'

const config = new pulumi.Config()
const repository = new aws.ecr.Repository(config.require('ECR_REPOSITORY_NAME'), {
  name: config.require('ECR_REPOSITORY_NAME'),
  imageTagMutability: 'IMMUTABLE'
})
const vpc = new awsx.ec2.Vpc(config.require('VPC_NAME'), {
  numberOfAvailabilityZones: 3,
  instanceTenancy: 'default',
  numberOfNatGateways: 1,
  cidrBlock: config.require('VPC_CIDR_BLOCK'),
  tags: { Name: config.require('VPC_NAME') }
} as VpcArgs);
// ↓追加
new eks.Cluster(config.require('EKS_CLUSTER_NAME'), {
  vpcId: vpc.id,
  privateSubnetIds: vpc.privateSubnetIds,
  publicSubnetIds: vpc.publicSubnetIds,
  nodeSubnetIds: vpc.privateSubnetIds,
  skipDefaultNodeGroup: true,
  tags: {Name: config.require('EKS_CLUSTER_NAME')}
} as eks.ClusterOptions).createNodeGroup(`${config.require('EKS_CLUSTER_NAME')}-node`, {
  instanceType: 't2.micro',
  minSize: 1,
  maxSize: 2
} as eks.ClusterNodeGroupOptions);

そして反映

$ pulumi update

これで、AWS上にEKSクラスターが作成されました。

kubectlでDockerImage反映

まずは、eksのバージョンに合わせたkubectlをインストールしていきます。

$ curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.13.10/bin/darwin/amd64/kubectl
$ chmod +x ./kubectl
$ sudo mv ./kubectl /usr/local/bin/kubectl

eksとの認証で利用するツールも入れておきます。

$ brew install aws-iam-authenticator

入れるべきものを入れたら、kubectlの向き先を確認します。

$ kubectl config get-contexts

向き先が自分のクラスターに向いていなかった場合、以下のコマンドで、ClusterConfigを作成します。

$ aws eks update-kubeconfig --name=[eksクラスタ名] --region=ap-northeast-1

再度、向き先を確認してみてください。

$ kubectl config get-contexts

向き先が変わっていたらOKです。

続いて、kubenatesにnamespaceを作成します。
namespaceはコンポーネント単位(〇〇APIとかの単位)で切ったほうが良いのかなと個人的に思ってます。
詳しい方いらっしゃったら教えて下さい。
「namespace.yml」を作成し、以下のように記述します。

apiVersion: v1
kind: Namespace
metadata:
  name: [ネームスペース名]

作成したNamespace定義を反映します。
ちなみに、kubectl先生は「dry-run」が可能です。
以下のコマンドに「--dry-run」を追加するだけで、「dry-run」として実行出来ます。

$ kubectl apply -f namespace.yml

Namespaceの作成が終わったらkubenatesのリソースを作成していきます。
作成するリソースは以下の通りです。

  • ingress
  • service
  • deployment

定義ファイルをサンプルリポジトリーにご用意していますので、参考にしてください。
今回は、手動でブルーグリーンデプロイをするために、deploymentを2つ作成しました。
serviceの向き先を変更することで、ブルーグリーンデプロイを実現出来ます。
以下のサンプルではblue環境をデプロイします。

$ kubectl apply -f ingress.yml
$ kubectl apply -f service.yml
$ kubectl apply -f deployment-blue.yml

これで、コンテナがデプロイされました。 ワンパス通すまでは色々と悩んでいましたが、意外とやることが少なく簡単に運用が出来るかと思います。 また、kubenatesでは環境変数を「.env」等のファイルに吐き出して管理することが出来ます。
「kubenates ConfigMap」で検索して頂くと出てきます。
ConfigMapを利用する際は、configをイミュータブルにして利用することを強くおすすめします。
理由としては、同じバージョンのConfigの情報を書き換えてしまうと、ロールバックなどを行う際、
想定と違うConfig情報になってしまい、事故の原因になるからです。

おまけ

色々と実運用に向けて環境を構築している際、デフォルトで用意されているコマンドだと、serviceの向き先やpodのDockerイメージバージョンを出してくれなかったので、自作しました。
以下のような感じで、プロパティをしていすれば他にも色々な情報を出すとこが出来ます。
気になる方は「-o」に「json」や「yaml」を渡して確認してみてください。

  • serviceの向き先確認
$ kubectl get svc -n [作成したnamespace] -o custom-columns=NAME:.metadata.name,VERSION:.spec.selector.version
  • podにリリースされているImage確認
$ kubectl get pods -n [作成したnamespace] -o custom-columns=CONTAINERS:.spec.containers[].name,NAME:.metadata.name,STATUS:.status.phase,VERSION:.metadata.labels.version,IMAGE:.spec.containers[].image,CONFIG:.spec.containers[].envFrom[].configMapRef.name,NODE_IP:.status.hostIP,POD_IP:.status.podIP,RESTART_POLICY:.spec.restartPolicy,RESTARTS:.status.containerStatuses[].restartCount

まとめ

弊社ではAmazonECS(Fargate)環境もAmazonEKS(Kubenates)も利用しています。
個人的には使いやすさ的な意味で、Kubenatesの方が好きですが、
AmazonEKSを立てるとクラスターを立てるだけで月間1.5万円ほど飛んでいきます(涙目)
そんなにサーバー台数が多くないうちはFargateでデプロイした方がお財布には優しいのかなという所管を持ちました。
今回は利用しなかった、「pulumi×kubectl」ですが、ドライランに対応している等、使い勝手は良さそうなのかなと思いました。
AWSがドライラン対応してないせいで、pulumi×awsもドライラン出来ないっぽいんで、 pulumi×awsのドライランはaws対応待ちって感じになりそうです。(はよぅ)

今回のサンプルは以下のURLに置いてあります。
リポジトリー
こちらを参考にしつつ、試してみてください。

最後に

本記事を見て、ご意見やご指摘等ございましたら、「[email protected]」まで是非ご連絡ください。

Twitterもやってます。ご興味ありましたら、フォローしてください。
Twitter:asakuma0401