AWSとTerraformでKubernetesを学ぶ本を書いたので1章をまるっと公開します
この記事は、Kubernetes3 Advent Calendar 2020の25日目の投稿です。
最近AWSとTerraformを使ってKubernetesを学ぶ本を書きました。
本記事では、その内容をただ載せるだけの楽をしてしまっています。すみません。ただの宣伝です。
興味を持った方は、明日から販売開始となりますので、下記より購入して頂ければと思います。
1章の内容のほかには、ALBとの連携によるサービスの外部公開、オートスケーリングの実現、Argo CDによるデプロイの実装、監視、運用などの内容を盛り込んでいます。
それでは、1章をまるっと公開します。
第1章 セットアップ
本章では、AWSとTerraformを使って、Kubernetes環境を構築します。AWSでは、Amazon EKS(以降、EKS)を使うと、マネージドなKubernetes環境を作成できます。TerraformでEKSのリソースを作るのに、Terraform公式のモジュールレジストリにあるterraform-aws-eks*1を利用します。
Terraformを使うにはAWS CLI*2が必要になります。本書では、すでにAWS CLIをインストールしているものとします。
1.1 Terraform
本節では、Terraformのセットアップを行い、Terraformを使ってAWSのリソースを作成、削除できることを確認します。TerraformをAWSで使うには、Terraform用のIAMユーザーを作成し、アクセスキーを発行します。そのアクセスキーをAWS CLIに設定するとTerraformからAWSを操作できます。
1.1.1 セットアップ
TerraformからAWSのリソースを操作できるように、Terraformのセットアップを行います。
AWSのマネージメントコンソールのIAMからユーザーを作成します(図1.1)。
User nameを入力します。Programmatic accessをチェックして、Nextをクリックします(図1.2)。
Attach existing policies directlyを選択します。AdministratorAccessをチェックし、Nextをクリックします(図1.3)。
タグは追加せず、Nextをクリックします。Create userをクリックします(図1.4)。
アクセスキーが表示されます(図1.5)。
このあとに使用するため、Access key IDとSecret access keyをコピーしておきます。
AdministratorAccessは、AWSにおいて管理者権限となるIAMポリシーです。何でもできてしまう権限のため、アクセスキーの扱いには注意が必要です。
次のコマンドで、AWS CLIの設定を行います。設定を行うには、aws configureを利用します。本書では、すでにAWS CLIをインストール済みとしています。
$ aws configure AWS Access Key ID [None]: AKIAXXXXXXXXXXXXXXX AWS Secret Access Key [None]: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Default region name [None]: ap-northeast-1 Default output format [None]: json
AWS Access Key IDとAWS Secret Access Keyにコピーしておいたアクセスキーを入力します。
次のコマンドで、Terraformのインストールを行います。macOSではbrew*3が利用できます。
$ brew install terraform
本書では、Terraformのバージョンv0.13.5を使用しています。
次のとおりに、terraformを実行してUsageの出力が行われれば、正常にインストールされています。
$ terraform Usage: terraform [-version] [-help] <command> [args] ...
1.1.2 基本操作
TerraformでAWSリソースを作成、削除できるか一連の操作を行います。これ以降の説明では、Terraformを使用してAWSリソースを作成しますので、ここで説明するTerraformの基本操作を理解するようにしてください。
terraform init
Terraformでは、作業用のディレクトリを用意して、初期化を行います。次のようにディレクトリを用意します。
$ mkdir example $ cd example
exampleディレクトリにmain.tfファイルを用意し、リスト1.1のようにコードを書きます。
リスト1.1は、EC2インスタンスを作成するTerraformのコードになります。
Terraformのtfファイルが用意できたら、terraform initを実行して、Terraform用の実行ディレクトリとしてexampleディレクトリをセットアップします。
$ terraform init
terraform initによって、AWSを扱うためのProviderというプログラムがダウンロードされて、TerraformでAWSを操作できます。
terraform plan
自身のAWS環境に対して、TerraformがどのようにAWSリソースを作成するのかを確認します。terraform planを実行すると、次のように、どのAWSリソースに変更があるかを把握できます。
$ terraform plan An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # aws_instance.example will be created + resource "aws_instance" "example" { ... } Plan: 1 to add, 0 to change, 0 to destroy. ------------------------------------------------------------------------ Note: You didn't specify an "-out" parameter to save this plan, so Terraform can't guarantee that exactly these actions will be performed if "terraform apply" is subsequently run.
terraform planの出力結果にある「+」マークはリソースを作成することを表しています。「resource "aws_instance"」とあるので、EC2インスタンスを作成する計画だと分かります。
terraform apply
実行計画が確認できたら、次に、Terraformを使ってAWSリソースを作成します。terraform applyを実行すると、あらためてplanの結果が表示され、実行するか確認が行われます。
$ terraform apply An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # aws_instance.example will be created + resource "aws_instance" "example" { ... } Plan: 1 to add, 0 to change, 0 to destroy. Do you want to perform these actions? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value:
terraform applyの実行結果の最後に「Enter a value:」と出力され、「yes」を入力すると、EC2インスタンスが作成されます。
最後に次のように出力されれば成功です。
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
実際にEC2インスタンスが作成されているかをAWSマネージメントコンソールで確認します。AWSマネージメントコンソールからEC2の画面を表示すると、作成したインスタンスを確認できます(図1.6)。
terraform destroy
Terraformを使って、作成したリソースを削除して、元の状態に戻します。そのためには、terraform destroyを実行します。
$ terraform destroy aws_instance.example: Refreshing state... [id=i-048b8ae615444c5f5] An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: - destroy Terraform will perform the following actions: # aws_instance.example will be destroyed - resource "aws_instance" "example" { ... } Plan: 0 to add, 0 to change, 1 to destroy. Do you really want to destroy all resources? Terraform will destroy all your managed infrastructure, as shown above. There is no undo. Only 'yes' will be accepted to confirm. Enter a value: yes
terraform destroyの出力結果にある「-」マークはリソースの削除を表しています。applyコマンドと同様に実行していいか確認されますので、yesと入力して、削除を実行します。
AWSマネージメントコンソールを確認すると、EC2インスタンスがTerminatedになっていて、削除されていることが分かります(図1.7)。
ここまでがTerraformのセットアップと基本操作です。
【コラム】Terraformの学び方
本書では、AWSリソースを作るためだけにTerraformを使用していますが、実はTerraformの世界は奥が深いです。たとえば、モジュール機能を使って汎用的にTerraformリソースを定義できます。また、既存のAWSリソースをTerraformで管理できるように、インポートする機能があります。
このように、Terraformには、リソースを作る以外に学ぶと便利な機能があります。本書では言及しませんが、本格的にTerraformを学びたい場合には、『実践Terraform AWSにおけるシステム設計とベストプラクティス』*4をオススメします。
1.2 Amazon EKS
本節では、Terraformを使用して、EKSおよびEKSに必要なAWSリソースを作成します。EKSのリソースを作るのにterraform-aws-eks*1を利用します。そのほかVPCなどのネットワーク関連のAWSリソースを作成します。
まずは、次のように作業用ディレクトリを用意します。
作業用ディレクトリ内に各種tfファイルを用意します。TerraformからAWSを利用できるように、リスト1.2のように定義します。
regionでAWSリージョンを指定します。localsは、tfファイル内で使用可能な変数を定義できます。ここでは、EKSクラスタの名前やバージョンを保持しています。
EKS用のVPC作成は、リスト1.3のようにvpc.tfを用意します。
terraform-aws-modules/vpc/awsを使うとVPC、Subnetを簡潔な記述で作成できます。CIDRは10.0.0.0/16を使用します。自身の環境でCIDRが既存のVPCと被っている場合には変更が必要です。public_subnetsでSubnetを作成します。SubnetのIPアドレス数によって、Kubernetesクラスタで起動可能なPod数が制限されます。ここでは、サブネットマスクを24にしていますが、実際にはクラスタの規模に応じて調整が必要です。Podについては、第2章で説明します。EKSの決まりとして、利用するsubnetのタグに特別な指定が必要です。*5
EKSの作成は、リスト1.4のようにeks.tfを用意します。
terraform-aws-modules/eks/awsを使うとEKSを作成できます。ここでは、Clusterのバージョンにlocalsの変数を使って1.18を指定します。node_groupsを指定して、EKSのマネージドノードグループを作成します。
terraform-aws-eksではマネージドノードグループではないノードグループの作成もサポートしています。その場合は、worker_groupsフィールドを指定してノードグループを作成できます。詳細はterraform-aws-eksのドキュメントを確認してみてください。*1
Terraformの実行中にKubernetes環境へのアクセスが必要になります。リスト1.5のように、kubernetes.tfを用意して、TerraformがKubernetes環境にアクセスできるようにします。
リスト1.5のコードは、筆者が試した限りでは、terraform applyでエラーにならないために必要でした。なぜこれが必要なのか筆者もよく分かっていないのですが、おまじないと思って書きましょう。
利用するTerraformのバージョンに制限をかけるため、リスト1.6のようにversions.tfを用意します。
Terraformのバージョンを0.12以上で使用するように指定します。
ここまでできたら、EKSに関係するAWSリソースを作成する準備は完了です。
次は、これまでのtfファイルを利用して、実際にAWSリソースを作成します。まずは、次のとおりにterraform initを実行して、作業ディレクトリのセットアップを行いましょう。
$ terraform init
続いて、terraform applyでEKSを作成します。
$ terraform apply module.eks.data.aws_iam_policy_document.cluster_assume_role_policy: Refreshing state... module.eks.data.aws_partition.current: Refreshing state... module.eks.data.aws_iam_policy_document.cluster_elb_sl_role_creation[0]: Refreshing state... ... Enter a value: yes module.eks.aws_iam_policy.cluster_elb_sl_role_creation[0]: Creating... module.vpc.aws_vpc.this[0]: Creating... ... Apply complete! Resources: 33 added, 0 changed, 0 destroyed.
EKSの作成完了までには、10分ほどかかります。エラーがなく、applyが完了すればEKSリソースが作られています。
1.3 Kubernetes
本節では、EKSで作成したKubernetes環境の動作確認のために、Kubernetesリソースの取得ができるかを確認します。前節まででEKSのセットアップは完了していますが、EKSで作成したKubernetes環境に接続するための操作が必要です。
次のコマンドで、Kubernetesを操作するためのCLIツールであるkubectlをインストールします。
$ brew install kubectl
Kubernetesに接続するために必要なkubeconfigを次のコマンドのとおりに作成します。
$ aws eks --region ap-northeast-1 update-kubeconfig --name eks-example
aws eks update-kubeconfigコマンドの--nameオプションには、EKSのクラスタ名を指定します。
kubectlはkubeconfigの設定を参照してKubernetes環境にアクセスします。ここまでの操作でKubernetes環境へのアクセスが可能です。
最後に、EKSで作成したKubernetes環境にアクセスできるかを確認するために、次のとおりにkubectl get podsを実行してみます。
$ kubectl get pods --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE kube-system aws-node-5cckx 1/1 Running 0 9m37s kube-system aws-node-9rqqx 1/1 Running 0 9m37s kube-system coredns-86f7d88d77-ch98t 1/1 Running 0 23m kube-system coredns-86f7d88d77-gh9xm 1/1 Running 0 23m kube-system kube-proxy-6x6fz 1/1 Running 0 9m37s kube-system kube-proxy-shfjv 1/1 Running 0 9m37s
kubectl get podsの出力には、STATUS、AGEといった項目があります。STATUSがRunningになっていれば、正常にPodが起動しています。また、AGEはPodの起動時間を表します。
ここまででAWSとTerraformを使って、シンプルなKubernetes環境を構築できました。注意ですが、このまま環境を構築したままにしておくと、EKSでは1時間あたり、0.10USDの料金が発生します。また、別でEC2インスタンスの料金などもかかります。不要な場合、適宜terraform destroyで削除しましょう。
いかがでしたでしょうか?ここまでが1章の内容になります。
改めて、本書の内容に興味を持った方は、下記より購入をよろしくお願いします。