gcp
Concourse

Concourse構築(Lite-VM) @ GCP

概要

以前まで、Concourseを1VMで立てる方法はVagrantを使ったものだったが、最近はboshを使った構築方法に統一されたらしく、今回は手元のローカル環境ではなく、クラウドプロバイダでホスティングして常時実行させたくて、GCP上で継続的にホスティングできるような方法を調べて実行してみることにした。

構築手段の選び方

Concourseをインターネット上に構築する方法は何通りかあるが、すぐ出てくる手段としては以下3つが多い。

  1. クラウド系IaaSでVMを手動で立てて、そこにSSHしてconcourseのバイナリを放り込む
    • 流石に原始的すぎるし、ある程度手軽に運用したいとはいえ、なるだけ避けたい。
    • 最近は新しいconcourse quickstartというコマンドも出たが、継続的に使うにはやや躊躇われる。
  2. concourse-deploymentを使って、boshを使ってVMごとデプロイする
  3. helmを使ってGoogleKubenetesEngine(GKE)の上にコンテナとしてデプロイする

ということで、多少調べれば実現できそう&コスパも良さそうな 2.の手段を調べて実行してみることにした。

作業環境

  • macOS 10.13.4
    • Terminal.app / zsh
    • homebrew
    • git
  • concourse 3.11.0
  • bosh 3.0.1
  • Google Cloud Platform

作業内容

1.作業環境の構築

事前に、bosh, gcloudのCLIを手元の端末にインストールする。
Macを使っているならhomebrewだけで完結する。

brew tap cloudfoundry/tap
brew install bosh-cli google-cloud-sdk

gloud でログインし、デフォルトリージョンとゾーンをセットする。

gcloud auth login
export REGION=asia-northeast1
gcloud config set compute/region $REGION
export ZONE=asia-northeast1-a
gcloud config set compute/zone $ZONE

先述のdeploymentのrepoをDLし、liteのディレクトリまで移動したら準備完了。

git clone https://github.com/concourse/concourse-bosh-deployment.git
cd concourse-bosh-deployment/lite

2. GCPでの事前作業

GCPでの事前準備が必要なものから着手する。

i. Project作成・課金方法の登録

まずはプロジェクト作成。Project IDを決めて登録しておく。
何度も使うので環境変数に入れておくことにする。

export PROJECT_ID=your-project-id
gcloud projects create $PROJECT_ID --name $PROJECT_ID --enable-cloud-apis
gcloud config set core/project $PROJECT_ID

また、ComputeEngine APIを利用するため、Google APIsにブラウザでアクセスして、
下記からプロジェクトに支払い方法をあらかじめ登録しておく。

ii. サービスアカウントの作成、権限付与

boshからのアクセスに必要なサービスアカウントを作成し、クレデンシャルキーをDLする。
また、このサービスアカウントに対して、boshから操作ができるように編集者の権限を付与する。

gcloud iam service-accounts create concourse-keys --display-name=concourse-keys
gcloud iam service-accounts keys create gcp-state.json \
    --iam-account concourse-keys@$PROJECT_ID.iam.gserviceaccount.com

gcloud projects add-iam-policy-binding $PROJECT_ID \
        --member serviceAccount:concourse-keys@$PROJECT_ID.iam.gserviceaccount.com \
        --role roles/editor

iii. NW作成、FW設定、静的IP払出し

VPCネットワークを1つと、配下の利用するリージョンのサブネットを1つ作成する。
今回はVM1つなのでそんなにいらないよねー、ということで/28の小さめので作成。
ファイアウォールルールとして、22,8080,6868の3ポートのみを指定。
そして公開用に、グローバルの静的外部IPアドレスも忘れずに1つ確保しておく。

gcloud compute networks create concourse-network --subnet-mode custom
gcloud compute networks subnets create concourse-subnet \
    --network concourse-network --range 10.0.0.0/28 --region $REGION

gcloud compute firewall-rules create concourse-basic \
    --network concourse-network --allow tcp:22,tcp:6868,tcp:8080

gcloud compute addresses create concourse-public-ip --region $REGION

gcloud compute addresses list
NAME                 REGION           ADDRESS        STATUS
concourse-public-ip  asia-northeast1  xx.xxx.xxx.xx  IN_USE

export PUBLIC_IP=xx.xxx.xxx.xx

これでGCP側の準備は完了。

3. 秘密鍵の作成

3つの秘密鍵の作成が必要になるので、まとめてssh-keygenで作成。
その後、下記で定義されたyamlフォーマットになるように別ファイルとしてまとめて保存しておく。

mkdir -p keys \
  && cd keys \
  && ssh-keygen -t rsa -f tsa_host_key -N '' \
  && ssh-keygen -t rsa -f worker_key -N '' \
  && ssh-keygen -t rsa -f token_signing_key -N '' \
  && openssl rsa -in token_signing_key -pubout -out token_signing_key.pub \
  && cd ..

cat << EOF > key-creds.yml
token_signing_key:
  private_key: |+
$(cat keys/token_signing_key | sed -e 's/^/    /')
  public_key: |+
$(cat keys/token_signing_key.pub | sed -e 's/^/    /')
tsa_host_key:
  private_key: |+
$(cat keys/tsa_host_key | sed -e 's/^/    /')
  public_key: $(cat keys/tsa_host_key.pub)
worker_key:
  private_key: |+
$(cat keys/worker_key | sed -e 's/^/    /')
  public_key: $(cat keys/worker_key.pub)
EOF

4.DBパスワードの決定

Concourse内部で動いているPostgreSQLとmbusのパスワードを決める。
ここは自分が覚えておければ任意のものを設定して構わない。

export POSTGRES_PASSWORD=password
export MBUS_BOOTSTRAP_PASSWORD=password

5. デプロイ

  • ここまで揃ったらいよいよboshを使ったデプロイが可能になる。
  • 下記のコマンドをそのままコピペして、bosh create-envを実行。
  • LiteにはDirectorがないので、いきなりConcourseを作りに行きます。
  • ※30分くらいかかるので、飯でも食いながら気長に待ちましょう:ramen:
bosh create-env concourse.yml \
       -l ../versions.yml \
       -l ./key-creds.yml \
       -o infrastructures/gcp.yml \
       -v internal_cidr=10.0.0.0/28 \
       -v internal_gw=10.0.0.1 \
       -v internal_ip=10.0.0.3 \
       -v mbus_bootstrap_password=$MBUS_BOOTSTRAP_PASSWORD \
       -v network=concourse-network \
       -v postgres_password=$POSTGRES_PASSWORD \
       -v project_id=$PROJECT_ID \
       -v public_ip=$PUBLIC_IP \
       -v subnetwork=concourse-subnet \
       -v tags=[] \
       -v zone=$ZONE \
       --var-file gcp_credentials_json=./gcp-state.json

上記で足りない変数がある場合は、更新が入っている可能性があるので、最新の gcp.yml を参照すると良い。

6. 確認

...
Finished deploying (00:24:48)

Stopping registry... Finished (00:00:00)
Cleaning up rendered CPI jobs... Finished (00:00:00)

Succeeded

このログが出たら完了。flyをDLして、パイプラインをセットしつつ動作を確認する。

curl -o /tmp/fly "http://$PUBLIC_IP:8080/api/v1/cli?arch=amd64&platform=darwin"
chmod +x /tmp/fly
sudo mv /tmp/fly /usr/local/bin/fly
fly -t main login -c http://$PUBLIC_IP:8080

cat << EOF > hello-world-pipeline.yml
jobs:
- name: hello-world
  plan:
  - task: say-hello
    config:
      platform: linux
      image_resource:
        type: docker-image
        source: {repository: alpine}
      run:
        path: echo
        args: ["Hello, world!"]
EOF

fly -t main set-pipeline -p hello-world -c hello-world-pipeline.yml
fly -t main unpause-job -p hello-world
fly -t main trigger-job -j hello-world/hello-world
open http://$PUBLIC_IP:8080

こんな感じで動いてればOKです。お疲れ様でした。
スクリーンショット 2018-04-15 1.08.22.png

  • デプロイ時に使った環境変数は、メモってから後でunsetしておくこと。
  • 環境変数は設定を管理するレポジトリで direnv の .envrc に設定しておくと便利 → direnvを使おう - Qiita
unset REGION ZONE PROJECT_ID PUBLIC_IP MBUS_BOOTSTRAP_PASSWORD POSTGRES_PASSWORD

その他注意事項

  • Bosh Directorがいない構成なので、bosh sshやリザレクション、監視はない。
  • 作成したパイプラインの情報は外部ディスクとして保存されているため、bosh create-envで再度デプロイしても消えない仕組みになっているようだ。
  • f1-microで立てれば無料でConcourse作れるやん!と思ってカスタマイズするymlを書いて試してみたところ、正常に動作することを確認できた。ただしかなり貧弱なのは言うまでもなく、どのくらい貧弱かと言うとgo run main.goのビルドを数回繰り返したところCPUが100%振り切って死ぬ程度には貧弱です。まともなビルド環境が欲しい場合は素直にn1-standard-1使うのが良さそうです。