RKEでAWS上にKubernetes(v1.10)をデプロイする
Rancher Blogに新しい記事(RKE+AWS)が投稿されてた
今月半ばにRancher Labsのブログに以下の記事が投稿されていました。
Rancher Blog: How To Deploy Kubernetes Clusters On AWS Using RKE
AWS上にRKEを用いてKubernetesクラスタを構築するという内容です。
でもRKEの最新版だと動かない…
手順が丁寧に書かれていてわかりやすい内容なのですが、利用しているRKEのバージョン(v0.1.5)が古く、最新版を利用するとうまく動きませんでした。
そこで、最新版できちんと動かすために必要な作業についてこの記事にまとめてみました。
ついでにTerraformでコード化しました
記事を書くついでにこの構成を手軽に試せるようにTerraformとTerraformのRKEプロバイダーを利用してコマンド一発で構築できるようにもしました。
ということで早速RKEの最新版での動かし方をみていきます。
RKE(v0.1.7) + AWSでKubernetes
TL;DR
- 基本はRancher Blogに記載の手順でOK
- RKEの最新版であるv0.1.7はデフォルトではKubernetes v1.10がデプロイされる
- Kubernetes v1.10でAWS向けのCloud Controller Managerを利用する場合、ClusterIDが指定されていないとkubeletの起動に失敗する
- なので以下リソースにClusterID用のタグを付与すればOK
- サブネット
- セキュリティグループ
- EC2インスタンス
解説
RKEの最新版であるv0.1.7はデフォルトではKubernetes v1.10がデプロイされる
まず、Rancher Blogの該当記事で利用されているRKEのバージョンはv0.1.5です。
このバージョンではrke up
を実行すると(デフォルトでは)Kubernetes v1.8がデプロイされていました。
なので、後述するClusterIDが設定されていなくても問題なく利用できていたようですね。
Kubernetes v1.10でAWS向けのCloud-Controller-Managerを利用する場合、ClusterIDが指定されていないとkubeletの起動に失敗する
Kubernetes v1.10のCHANGE LOGを見ると、以下のPRによるものです。
対応: 各リソースにClusterID用のタグを付与する
ということで、Kubernetes v1.10を使う場合はClusterIDを指定すればOKということですね。
タグの付け方についてはRancherのドキュメントに記載がありました。
Rancher docs: Kubernetes - Cloud Providers / Configuring the ClusterID
このドキュメントによると、
- サブネット
- セキュリティグループ
- EC2インスタンス
に対してkubernetes.io/cluster/CLUSTERID=owned
のようなタグをつければ良いとのことでした。
IDはCLUSTERID
の部分を任意の値に書き換えることで設定可能です。
Terraform + RKEプロバイダーで構築する
ClusterID用のタグをつけるのは割と面倒な作業なのでTerraformでコード化しました。
以下のリポジトリでコードを公開しています。
なお、このコードではRKEプロバイダーを利用して、RKEでのKubernetesクラスタ構築までを一気に行なっています。
RKEプロバイダーについては以下の記事を参照ください。
以下コードのポイントを解説しておきます。
IAMプロファイルの作成
この辺りは以下のtfファイルにまとめています。
https://github.com/yamamoto-febc/k8s_on_aws_with_terraform/blob/master/aws/iam.tf
ClusterID用のタグ付与
サブネット/セキュリティグループ/EC2インスタンスに対してタグを指定しています。
以下のような感じです。
# タグの定義 locals { cluster_id_tag = "${map("kubernetes.io/cluster/${var.cluster_id}", "owned")}" } # 利用するリージョン内の全AZのデフォルトサブネットを対象にClusterID用のタグを付与 data "aws_availability_zones" "az" {} resource "aws_default_subnet" "default" { availability_zone = "${data.aws_availability_zones.az.names[count.index]}" count = "${length(data.aws_availability_zones.az.names)}" tags = "${local.cluster_id_tag}" #タグの指定 }
サブネットについてはデフォルトサブネットに対してタグ付与しています。
また、セキュリティグループについてはRancher Blogと同じく全許可のルールとしています。
ノードのプロビジョニング
Dockerをインストールして、SSH接続の際に利用するユーザー(記事ではubuntu
)をDockerグループに入れる必要があります。
tfファイル上はremote-exec
を利用して以下のようにしています。
resource "aws_instance" "rke-node" { count = 4 ami = "${data.aws_ami.ubuntu.id}" instance_type = "${var.instance_type}" key_name = "${aws_key_pair.rke-node-key.id}" iam_instance_profile = "${aws_iam_instance_profile.rke-aws.name}" vpc_security_group_ids = ["${aws_security_group.allow-all.id}"] tags = "${local.cluster_id_tag}" provisioner "remote-exec" { connection { user = "ubuntu" private_key = "${tls_private_key.node-key.private_key_pem}" } # Dockerのインストールとdockerグループへの追加 inline = [ "curl releases.rancher.com/install-docker/1.12.sh | bash", "sudo usermod -a -G docker ubuntu", ] } }
なお、インスタンスタイプは記事ではt2.large
が推奨されていますが、軽く試すだけならt2.micro
で十分でした。
(tfファイル上はデフォルトでt2.micro
にしました)
RKEの実行
RKEの実行はRKEプロバイダーに任せます。
以下のようなtfファイルとなります。
module "nodes" { source = "./aws" } resource rke_cluster "cluster" { cloud_provider { name = "aws" } nodes = [ { address = "${module.nodes.addresses[0]}" user = "${module.nodes.ssh_username}" ssh_key = "${module.nodes.private_key}" role = ["controlplane", "etcd"] }, { address = "${module.nodes.addresses[1]}" user = "${module.nodes.ssh_username}" ssh_key = "${module.nodes.private_key}" role = ["worker"] }, { address = "${module.nodes.addresses[2]}" user = "${module.nodes.ssh_username}" ssh_key = "${module.nodes.private_key}" role = ["worker"] }, { address = "${module.nodes.addresses[3]}" user = "${module.nodes.ssh_username}" ssh_key = "${module.nodes.private_key}" role = ["worker"] }, ] }
RKEコマンドを直接実行する場合は、rke up
実行後にカレントディレクトリにkube_config_cluster.yml
ファイルが作成されます。
RKEプロバイダーの場合はデフォルトでは作成されませんので、以下のようにlocal-file
機能でファイル出力しています。
resource "local_file" "kube_cluster_yaml" { filename = "./kube_config_cluster.yml" content = "${rke_cluster.cluster.kube_config_yaml}" }
terraform apply
実行後にexport KUBECONFIG=$PWD/kube\_config\_cluster.yml
を実行しておけばkubectl
が利用できるはずです。
後はRancher Blogの内容をそのまま進めていけるはずです。
ということでRancher Blogの補足をしつつ、Terraform + RKEプロバイダーで環境構築してみました。
なおこの構成は全通信許可などのガバガバ設定になっていますので検証などでのみ利用してくださいね!!
以上です。