Cloud Penguins

Flying penguins in the cloud.

コロケ芸の実例を見せながらBOSHのops fileの書き方を解説する

Cloud Foundry Advent Calendarの19日目

前回の投稿でCFにはコロケ芸というリソース節約方法があるということを書いたのですが、記事を公開した直後に同僚making氏から速攻でツッコミが。

すみませんすみませんすみません。

前回記事を書いたとき、手元でも動作する例を用意していたのですが、それはmanifestを直接修正してデプロイする形にしていました。 BOSH v1であればこうするしかなかったんですが、もう時代はBOSH v2。BOSH v2であればmanifestを直接修正するのは古い。やはりここはops fileを使わねば。

ということで、CFをコロケする例を示しつつ、併せてops fileをどう書いていくかという話をしたいと思います。

そもそもOps fileとは

正確にはOperations fileっていいます。

https://bosh.io/docs/cli-ops-files.html

ベースとなるYAMLに対して、特定の記法でops fileを渡すことで、値のオーバーライドや削除を行うことができます。

たとえば以下のようなベースYAMLがあったとして

name: my-cf

以下のようなOps fileを加えると

- type: replace
  path: /name
  value: other-cf

以下のような出力が得られます

name: other-cf

Path

ベースとなるYAMLのどの部分を指定するかを、このpathで表現します。

/と指定するとYAMLのルートを示します。上記の書き換え例だと、ルートに連なるnameというkeyに対して操作を行いたいので、/nameと指定しています。

他にもシンタックスがあるため、ドキュメントをを参照してください。

https://bosh.io/docs/cli-ops-files.html

Operation

上記のops file例でいうと、typeの部分がoperationに当たります。ここにはreplaceもしくはremoveを指定することができます。

pathに対して、値をreplaceするのか、あるいはremoveするか。replaceする場合は、valueで指定した値に差し替わります。

Ops fileで何が嬉しいの

CFをデプロイする場合、今後はcf-deployment を使ってデプロイするのが主流になりますが、たとえばこのデプロイするCFにカスタマイズをしたいとします。

昔のBOSHですと、この中のcf-deployment.ymlを直接編集するしかありませんでした。 しかし、このやり方はcf-deploymentをフォークしてしまうことになり、upstreamが更新された際にコンフリクトを起こしてしまうことになります。これはスマートなやり方とはいえません。

そこで、カスタマイズしたい内容をops fileとして切り出すことで、ベースとなるcf-deploymentに手を加えること無く行うことができます。

cf-deploymentのリポジトリには、よくあるカスタマイズについてはあらかじめops fileが同梱されており、-o オプションで指定するだけで適用することが可能です。

cf-deployment/operations at master · cloudfoundry/cf-deployment · GitHub

コロケするOps fileを作ってみよう

ということで、今回は例としてCloud ControllerとUAAを同居させる「Control」VMを作成する例を作ってみました。 完成版Ops fileはこちらにおいてあります。

UAAとAPIの中身をマージする

以下が、単純にUAAとAPIのjobをマージしたyamlです。

https://gist.github.com/jacopen/e447fb3f409ae5935c9e69c27dcae531#file-first-yml

これで流せば無事コロケ完了・・・かというとそうはいきません。いくつか問題点があります

  • 項目かぶり -- この例でいうとstatsd_injectorやroute_registrarなどの項目が重複しています。このままではエラーになってしまうため、この中身も適切にマージしてあげる必要があります。
  • ポートかぶり -- このJobsでは明示されていませんが、実はUAAとpolicy-serverはともにデフォルトで8080で上がってしまいます。このままではポートかぶりにより、どちらかのプロセスが正常に立ち上がりません。どちらかの設定を被らないポートに変更してやる必要があります。

ということで、ここのあたりは地味ーな作業をやって良い感じにコロケできる設定を作っていきます。

既存のUAAとAPIを無効にする

ControlVMでUAAとAPIをデプロイしてしまうので、以下のようにremoveを書くことで個別のVMが作成されないようにしました。

- type: remove
  path: /instance_groups/name=uaa
- type: remove
  path: /instance_groups/name=api

1az構成にする

Multi AZにするのであればこの作業はスキップできますが、今回はコロケで極限までVMを削る、というのを試してみたいので、1AZ構成に変更したいと思います。

cf-deploymentの中の operations/scale-one-az.yml を指定すると、1AZ構成に変更されます・・・が、今回はuaa/apiをremoveしてしまったため、単純に食わせるとエラーになってしまいます。ということで、美しくないですがopsfileの中に該当ファイルからuaa/apiを抜いた項目を追加する形にしました。(もっと良い案思いついたらなんとかします)

同じ理由で、NW名を引数で渡せるようにする operations/rename-network.ymlの中身も含めてしまっています。

ということで完成版

Collocate UAA and API · GitHub

・・・なんかもっとシンプルかつスマートにずばっとコロケできるようなのを目指したんですが、何か・・・長いですね。 とはいえcf-deployment.ymlを直接弄ってしまうよりはマシなものになっている、たぶんきっと。

あとは-oオプションでこのops fileを指定してやれば、デプロイできるはずです

bosh deploy -d cf cf-deployment.yml --vars-store env-repo/deployment-vars.yml -v system_domain=example.com -v network_name=bosh-network -o collocate.yml

必要にに応じて他のops fileも読ませてデプロイしてください。ただ、/instance_groups/name=apiや/instance_groups/name=uaa を操作するops fileの場合、エラーがでちゃうかも。