EKS on EC2にHCP Consulを接続してみる
「HCP Consulをさくっと試してみたい」
HCP Consulのサービスメッシュの機能を試してみたいことがありました。
サービスメッシュを試すのは、EKSクラスターを用意したりが必要で少し面倒です。
簡単に試せる方法はないかと思っていたら、いい感じのサンプルコードが用意されていました。
terraform-aws-hcp-consul/examples/hcp-eks-demo at main · hashicorp/terraform-aws-hcp-consul · GitHub
このサンプルコードは、EKSクラスターの作成~ConsulのインストールまでTerraformでやっています。
簡単にHCP Consulと接続したEKSクラスターを作成できたため、紹介します。
HCP Consulとは
ConsulはHashiCorpが提供しているネットワーク関連のツールです。
サービスディスカバリやサービスメッシュの機能等を提供しています。
Consulの概要については、HashiCorpのYoutubeで分かりやすく解説されています。
ConsulはOSSでも提供されていますが、HCP ConsulとしてSaas版も提供されています。
OSSのConsulは自前でKubernetesクラスター等にインストールする必要がありますが、HCP Consulではユーザー側でConsul Clusterのインフラ管理不要で使用できます。
HashiCorp Consul: Enterprise Pricing, Packages & Features
やってみた
HCPクライアントシークレット発行
サンプルコードのTerraform実行に必要なため、HCPクライアントシークレットを発行します。
クライアントシークレットは、Access control(IAM)
-> Service principals
内で作成できます。
Terraformコード確認
main.tfの中身は以下です。最新の状態やその他のファイル(variables.tf、output.tf等)はGitHubをご確認ください。
terraform-aws-hcp-consul/examples/hcp-eks-demo at main · hashicorp/terraform-aws-hcp-consul · GitHub
# Copyright (c) HashiCorp, Inc. # SPDX-License-Identifier: MPL-2.0 data "aws_availability_zones" "available" { filter { name = "zone-type" values = ["availability-zone"] } } module "vpc" { source = "terraform-aws-modules/vpc/aws" version = "2.78.0" name = "${var.cluster_id}-vpc" cidr = "10.0.0.0/16" azs = data.aws_availability_zones.available.names public_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"] private_subnets = ["10.0.4.0/24", "10.0.5.0/24", "10.0.6.0/24"] enable_nat_gateway = true single_nat_gateway = true enable_dns_hostnames = true } data "aws_eks_cluster" "cluster" { count = var.install_eks_cluster ? 1 : 0 name = module.eks[0].cluster_id } data "aws_eks_cluster_auth" "cluster" { count = var.install_eks_cluster ? 1 : 0 name = module.eks[0].cluster_id } module "eks" { count = var.install_eks_cluster ? 1 : 0 source = "terraform-aws-modules/eks/aws" version = "17.24.0" kubeconfig_api_version = "client.authentication.k8s.io/v1beta1" cluster_name = "${var.cluster_id}-eks" cluster_version = "1.25" subnets = module.vpc.private_subnets vpc_id = module.vpc.vpc_id manage_aws_auth = false node_groups = { application = { name_prefix = "hashicups" instance_types = ["t3a.medium"] desired_capacity = 3 max_capacity = 3 min_capacity = 3 } } } # The HVN created in HCP resource "hcp_hvn" "main" { hvn_id = var.hvn_id cloud_provider = "aws" region = var.hvn_region cidr_block = var.hvn_cidr_block } # Note: Uncomment the below module to setup peering for connecting to a private HCP Consul cluster # module "aws_hcp_consul" { # source = "hashicorp/hcp-consul/aws" # version = "~> 0.12.1" # # hvn = hcp_hvn.main # vpc_id = module.vpc.vpc_id # subnet_ids = module.vpc.private_subnets # route_table_ids = module.vpc.private_route_table_ids # security_group_ids = var.install_eks_cluster ? [module.eks[0].cluster_primary_security_group_id] : [""] # } resource "hcp_consul_cluster" "main" { cluster_id = var.cluster_id hvn_id = hcp_hvn.main.hvn_id public_endpoint = true tier = var.tier min_consul_version = "v1.14.0" } resource "hcp_consul_cluster_root_token" "token" { cluster_id = hcp_consul_cluster.main.id } module "eks_consul_client" { source = "hashicorp/hcp-consul/aws//modules/hcp-eks-client" version = "~> 0.12.1" boostrap_acl_token = hcp_consul_cluster_root_token.token.secret_id cluster_id = hcp_consul_cluster.main.cluster_id # strip out url scheme from the public url consul_hosts = tolist([substr(hcp_consul_cluster.main.consul_public_endpoint_url, 8, -1)]) consul_version = hcp_consul_cluster.main.consul_version datacenter = hcp_consul_cluster.main.datacenter k8s_api_endpoint = var.install_eks_cluster ? module.eks[0].cluster_endpoint : "" # The EKS node group will fail to create if the clients are # created at the same time. This forces the client to wait until # the node group is successfully created. depends_on = [module.eks] } module "demo_app" { count = var.install_demo_app ? 1 : 0 source = "hashicorp/hcp-consul/aws//modules/k8s-demo-app" version = "~> 0.12.1" depends_on = [module.eks_consul_client] }
ざっくり以下のリソースを作成しています。
- AWS
- VPC
- EKS Cluste
- HCP
- HCP Consul Cluster
- HVN
- Kubernetes
- デモアプリ用各種リソース
ちなみに、EKSとHCP Consulを接続するには、最低以下のステップが必要です。 (Consul ClusterをPrivateにする場合は、VPCピアリングなど必要)
手順 | |
---|---|
HCP Portal | 1. HVN(Hashicorp Virtual Network)とHCP Consul Cluster作成 |
2. EKSからHCP Consulに通信するためのToken発行 | |
Kubernetes(EKS) | 3. HCP ConsulのTokenをSecrets登録 |
4. HelmでHCP Consulをインストール |
Terraformのmodule等を使っていい感じに抽象化してくれていますね。
Terraform実行
発行したHCPクライアントシークレットを環境変数に設定します。
$ export HCP_CLIENT_ID=<クライアントID> $ export HCP_CLIENT_SECRET=<クライアントシークレット>
AWS認証情報を設定します。
$ export AWS_ACCESS_KEY_ID=<AWSアクセスキー> $ export AWS_SECRET_ACCESS_KEY=<AWSシークレットアクセスキー> $ export AWS_SESSION_TOKEN=<(必要に応じて)AWSセッショントークン>
terraform apply
でリソースをデプロイします。
$ git clone [email protected]:hashicorp/terraform-aws-hcp-consul.git $ cd examples/hcp-eks-demo $ terraform init $ terraform apply
サンプルアプリケーションの確認
デプロイが成功すると、以下のようなサンプルアプリケーションが表示されます。(terraformのoutputsのhashicups_url
)
Consul確認
terraformのoutputsのconsul_url
にアクセスしてみると、以下の画面が表示されます。
Serviceを選択すると、他のサービスとどう通信するかといったことも確認できます。
後片付け
以下コマンドで作成したリソースを削除します。
terraform destroy
まとめ
HCP ConsulをEKSに接続してみました。
Service Meshの製品ということで、設定が大変という印象を持っていました。
しかし、実際にやってみると思ったより導入ハードルは低いと感じました。
TerraformでHCPのProviderやConsulのModuleが提供されており、記述量を抑えつつ設定ができました。
以上、AWS事業本部の佐藤(@chari7311)でした。