オンプレミスでCircleCI Serverを動かそうシリーズの第4回です。前回までで、CircleCI Serverのコントロールプレーンは動作しました。今回は実際にジョブを実行するNomadクライアントを構築します。
Terraform設定ファイルの取得
Nomadクライアントは、EKSクラスターとは別に、EC2のノード群を用意しなくてはなりません。様々なコンポーネントが必要になりますが、これらを一発で構築できるTerraform設定ファイルが用意されています。まずはこのリポジトリをクローンします。今回はバージョン3.4.0リリースを使用します。
$ git clone -b 3.4.0 --depth 1 https://github.com/CircleCI-Public/server-terraform.git
必要なパラメーターの取得
実際に構築を行うにあたり、様々なパラメーターを指定したmain.tf
ファイルが必要となります。サンプルがクローンしたディレクトリ内のnomad-aws/examples/basic/main.tf
として用意されていますので、このファイルをベースに作成するとよいでしょう。それに先立ち、まずはmain.tf
に入力するためのパラメーターを調べます。
以下のコマンドを実行して、クラスターが動作しているVPCのIDを調べます。vpc-xxxxx
といった文字列が得られるはずです。
$ aws eks describe-cluster --name=circleci-server --query 'cluster.resourcesVpcConfig.vpcId'
以下のコマンドを実行して、VPCが持っているCIDRブロックを調べます。本ブログの設定通りにeksctlを実行していれば、10.21.0.0/16
というCIDRが得られるはずです。
$ aws ec2 describe-vpcs --filters Name=vpc-id,Values=(上で調べたVPCのID) --query 'Vpcs[0].CidrBlock'
以下のコマンドを実行して、eksctlが作成したプライベートサブネットを調べます。本ブログの設定通りにeksctlを実行していれば、subnet-xxxxxx
というサブネットIDが3つ表示されるはずです。
$ aws ec2 describe-subnets --filters "Name=tag-key,Values=Name" "Name=tag-value,Values=eksctl-circleci-server-cluster/SubnetPrivate*" --query 'Subnets[].SubnetId'
以下のコマンドを実行して、eksctlが作成したパブリックサブネットを調べます。subnet-xxxxxx
というサブネットIDが3つ表示されるはずです。
$ aws ec2 describe-subnets --filters "Name=tag-key,Values=Name" "Name=tag-value,Values=eksctl-circleci-server-cluster/SubnetPublic*" --query 'Subnets[].SubnetId'
以下のコマンドを実行して、Nomadサーバーのエンドポイントを調べます。これはnomad-server-external
というサービスの、External-IPです。xxxxxxxx.elb.ap-northeast-1.amazonaws.com
といった文字列が得られるはずです。
$ kubectl get svc nomad-server-external -n circleci-server -o jsonpath='{.status.loadBalancer.ingress[0].hostname}'
Terraformの実行
ここまでの情報が揃ったら、以下の内容でnomad-aws/examples/basic/main.tf
を書き換えます。VPCは既に作成済みですので、サンプルにあるmodule "vpc"
ブロックは不要なため、まるごと削除してしまってください。
terraform { required_version = ">=0.15.2" required_providers { aws = { source = "hashicorp/aws" version = "~>3.0" } } } provider "aws" { # EKSクラスターを作成したリージョンを指定 region = "ap-northeast-1" } module "nomad-aws" { source = "../.." # 起動するノード数を指定 nodes = 2 # Nomadクライアントが動作するパブリックサブネットのリスト subnets = [ "subnet-aaaaaa", "subnet-bbbbbb", "subnet-cccccc" ] # VPC IDを記述 vpc_id = "vpc-xxxxxx" # Nomadサーバーのエンドポイントを記述 server_endpoint = "xxxxxxxx.elb.ap-northeast-1.amazonaws.com:4647" # DNSサーバーのIPアドレスを記述 # これはVPCが使用しているCIDRの3番目のIPアドレスになる dns_server = "10.21.0.2" # ジョブ内からのアクセスをブロックしたいプライベートサブネットのリスト blocked_cidrs = [ "subnet-xxxxxx", "subnet-yyyyyy", "subnet-zzzzzz" ] nomad_auto_scaler = false max_nodes = 5 } output "nomad_module" { value = module.nomad-aws }
main.tf
が用意できたら、nomad-aws/examples/basic/
ディレクトリ内で以下のコマンドを実行します。
$ terraform init $ terraform plan $ terraform apply
Terraformの実行が正常に終了すると、以下のようにNomadサーバーの設定に必要な証明書、秘密鍵、認証局証明書が出力されます。これらを控えておいてください。
Outputs: nomad_module = { "mtls_enabled" = true "nomad_asg_arn" = "" "nomad_asg_name" = "" "nomad_asg_user_access_key" = "" "nomad_asg_user_secret_key" = "" "nomad_role" = "" "nomad_server_cert" = <<-EOT -----BEGIN CERTIFICATE----- ...略... -----END CERTIFICATE-----
CircleCI ServerにNomadを設定する
Nomadクライアントの構築が完了したら、CircleCI Serverの管理コンソールに戻ってください。ページ上部に表示されているConfig
をクリックすると、初期設定を行った画面に遷移できます。ここで先ほどmTLSを無効にしたNomadの設定を改めて行いましょう。
「Nomad Load Balancer Hostname」には、先ほど調べたNomadサーバーのエンドポイントを入力します。「Enable mTLS」をEnabled
に切替え、「Nomad Server Certificate」「Nomad Server Private Key」「Nomad Server CA Certificate」には、Terraformが出力した証明書や秘密鍵を貼り付けてください*1。なおTerraformのOutputには行頭に半角スペースが入っているため、削除しておいた方がいいかもしれません*2。
アウトプットプロセッサーを設定する
以下のコマンドを実行して、アウトプットプロセッサーのエンドポイントを取得します。Nomadサーバー同様、ELBのホスト名が得られるはずです。
$ kubectl get svc output-processor -n circleci-server -o jsonpath='{.status.loadBalancer.ingress[0].hostname}'
得られた値を「Output Processor Load Balancer Hostname」に入力してください。
変更した設定の反映
ページ最下部のSave Config
をクリックしたら、表示されるダイアログでGo to updated version
をクリックします。
コンフィグが変更されたバージョンが用意されますので、Deploy
ボタンをクリックしてください。更新が反映されます。
ジョブを実行する
Nomadクライアントが正常に接続できていれば、コンテナ内でジョブが実行できる状態になっているはずです。クラウド版のCircleCIと同様にプロジェクトをセットアップして、ジョブを実行してみましょう。もしジョブがPendingのまま進まないといったことが起きているのであれば、こちらを参考に、Nomad Podに入ってステータスを確認してみてください。
なおNomadクライアントだけでは、Remote DockerやMachine Executorを利用することができません。そこで次回は仮想マシンでジョブを実行できる、VMサービスのセットアップ方法を紹介します。