概要

以前まで、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
$ gcloud config set compute/region asia-northeast1
$ gcloud config set compute/zone asia-northeast1-a

先述の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 --mode custom
$ gcloud compute networks subnets create concourse-subnet \
    --network concourse-network --range 10.0.0.0/28 --region asia-northeast1

$ 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 asia-northeast1

$ 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 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=asia-northeast1-a \
       --var-file gcp_credentials_json=./gcp-state.json

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しておくこと。
$ unset PROJECT_ID PUBLIC_IP MBUS_BOOTSTRAP_PASSWORD POSTGRES_PASSWORD

更新時の手順とか

  • 基本的にBosh Directorがいないため、boshのウリであるbosh sshやリザレクション、監視は働いていない。
  • そのため、アップデートなども一度VMを消した後、再度立て直すことになる。
    • つまりアップデート時は、VM内のジョブデータなどが全て消去される/(^o^)\
  • ここら辺やだなーって人はMulti-Cluster版でBOSH Diredtorを立てて、
    DBバックアップなどを取りながらインストールした方が良さそうですね。この辺はまた時間があれば。
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.