OpenStack Heat再び

Terraformを使っているのだが、結構困ることもちょこちょこ出てきて、実はHeatの方がよかったのでは?という思いも出てきたりしているのでもうちょっと実践的な検証を行うことにした。OpenStackのバージョンはMitaka。

今回は、スケールさせるインスタンス群とそうではないシングルインスタンスを作成し、シングルインスタンスにはFloatingIPを付与する、という構成にする。インスタンス一覧はこのようになっている。

各リソースについて

main.yaml

メインはこのようになる。リソースはネットワーク類、スケールインスタンス、シングルインスタンス、シングルインスタンスへのFIP付与だ。パラメータとしては、スケールインスタンスの台数を指定できるようにしている。

ここで、”OS::Alpaca::Network” や “OS::Alpaca::Server” というタイプがあるが、これは独自に定義したリソースだ。Terraformのモジュールに似た機能といってよいだろう。独自定義リソースを使うには、”env.yaml”でリソース名とそれを定義したファイルを関連づける。詳細はドキュメントを参照するとよい。なお、拡張子が”.yml”だとうまく動かなかった。”.yaml”じゃないとダメなようだ。

OS::Alpaca::Network

必要なネットワークリソースを1つのリソースに定義した。素朴にネットワークとサブネットを作成し、Publicネットワークとはルーターを経由して接続している。

outputsでネットワークを参照できるようにしているが、これはサーバー作成時にネットワークの情報が必要なためだ。

OS::Alpaca::Server

次はサーバーだ。サービスで使うベースのインスタンスはって大体設定が共通なので、独自リソースで定義しておくと楽だ。サーバーにユニークな名前をつけようと思って、付与するIPアドレスを用いて「hoge-127-0-0-1」のような名前にしたかったが、うまくいかなかった。get_attrの結果を置換する方法が今のところないようだ。Terraformだと可能なのだが。

OS::Alpaca::AttachFloatingIP

次はサーバーにFIPを付与するためのリソース。本当は、OS::Alpaca::Serverのパラメータで「attach_fip: true」のようにするとFIPを付与するようにしたかったが、Mitakaだとconditionが使えなかった。newtonかららしい…これもTerraformだとできるので、Newtonにしたい〜!という気持ちになる。

OS::Alpaca::ServerGroup

最後はスケールさせるための独自リソース。OS::Heat::ResourceGroupとOS::Alpaca::Serverを組み合わせて、DRYにスケールさせるための記述を成立できた。これは今のところTerraformではできないことだ。

まとめと感想

より実際に使いそうな記述でHeatを使ってみた。次はCloudConfigを試すかなー。

  • 実行した時の差分がよくわからない。どう変化するのかがもうちょっとわかりやすく見られるとよいのだが…何かコマンドがあるのだろうか。サーバーが再作成されるのかどうかというのも分からないので実行が不安になる。
  • Horizonから実行履歴が見られるのはよい。
  • TerraformからHeatへ移行する場合、かなり運用フローを変えないといけないだろうと感じた。Heatを用いて複数人で開発するのはどうやるんだろう?

うーん、使ってみたらやはりTerraformなのかなー。移行するほどのメリットは感じられないかなあ。

mastodonで自分用のインスタンスを作った感想

ブームに乗っておくか〜、と思ったのと、使っている技術も割となじみのあるものであること、docker-composeで気軽に立ち上げられるようだったので日曜に軽く試してみた。

1人用なら、t2.microでもまぁ動く。本格的にスケールさせるならRDS、S3、ElastiCacheのようなマネージドサービスを使えば楽そうだ。ただ、自分がフォローした人の投稿しか見えず、負荷も高くないので使用者としても運用者としてもおもしろさは感じにくい。やはり、大量のユーザがいるといろいろ問題も発生して楽しそうだと思う。

mastodon自体は、mstdn.jpが移転する前にアカウントを作ってみていた。1ヶ月ほど前から諸事情でSNSをほとんど見ないようにしていてSNSに対する関心が薄れかけているので、mastodonでも何を投稿すればいいのだろうかと思ってしまった(これにより人付き合いがひどく減ってしまった気がするが…)。なので個人用インスタンスを作ってはみたけどそのうち消しそうだなあ。気軽に立ち上げられても運用は手軽ではないし。

cloud-initのドキュメントを読んだ

cloud-initのドキュメントを読んでいたのでメモ。なぜかこのドキュメントに今まで気づいていなかった…

今、スクリプトを書いて実現しているけどcloud-initのモジュールでもできそうなものがいくつかあった。

  • Growpart:パーティションを広げる
  • Phone Home:指定したURLにデータをPOSTする
  • Puppet:Puppetのインストールと設定、実行
  • Resizefs:ファイルシステムのリサイズ
  • Resolve Conf:resolv.confの設定

モジュールでできるならその方がすっきり書けてよいかなあ。

RancherのOpenStack Driverを試す

少し前に試したけど記録していなかったのでその記録。Rancherは2015年に RancherOSの起動時の仕組みを調べて以降あまり追っていなかったのだけど、最近話題なのとコンテナオーケストレーション周りをキャッチアップしないとな、ということで触ることにした。

構成

こんな感じの構成になる予定。OpenStackのAPIを叩くため、専用のネットワークに繋げている。

Rancher Serverの構築と準備

まずはRancherServerを構築する。今回は、OpenStack上にインスタンス(rancher-server)を1台作成し、その上のDockerに起動する。イメージは素朴にubuntu-16.04を選択し、 https://docs.docker.com/engine/installation/linux/ubuntu/ に従って、Dockerをインストールする。インストールが終わったら、rancherを起動。
ふむふむ。

rancher-serverにはFloatingIPを付与してあるので、http://floating-ip:8080/ でアクセスできる。なお、8080番ポートをSGで許可しておく必要がある。

画面が見えた。次は、ユーザを作成する。ADMIN=>AccessControllから作成できる。ユーザを作ったらKubernets用のEnvironmentを作成する。Default=>ManageEnvironmentから追加できる。EnvironmentTemplateにはKubernetesを選択し、AccessControlでは先ほど作成したユーザがownerになるようにする。作成したら、それをデフォルトにして、Environmentの準備は完了。

Kubernetes用のホスト登録

さて、次はKubernetesを動かすためのホストを追加していく。OpenStackのインスタンスをホストにしたいので、MachineDriverを有効にする。ADMIN=>MachineDriversからOpenStackをActivateしよう。

次はホストの追加を行う。画面からポチポチ作っても良いが、コマンドラインからやろう。画面右下からCLIをダウンロードできる。CLIからrancher-serverを使うため、URLとアクセス用のキーを登録する。キーはAPI=>Keysから生成できます。

さて、ホストの追加だが…こんな感じでできる。イメージにはUbuntuを使ってみる。

注意点としては、private-key-fileはrancher-serverが見える場所でないといけない、という所だ。今回はrancher-serverをコンテナで起動したので、コンテナ内に配置する。

また、rancher agentが使用するAPI用のURLを変更しておく。http://floating-ip:8080/ になっているが、これだとrancher agentがURLをうまく認識しなかった。SGまわりかもしれないが、今回はrancher-internalネットワーク内のアドレスを指定してやる。
 pemの配置とURLを変更したら、コマンドを実行する。
Rancher側にホストが追加され、インスタンスの作成やDockerのインストールが始まった!
しばらく待つと…起動した!
KUBENETES=>Dashboardからk8sのダッシュボードも開くことができるし、KUBENETES=>CLIからkubectl用のコンフィグもダウンロードできる。

ホストを増やす

しかし、これだとホストが1台だけで面白みがないので、台数を増やしてみる。ついでに、ubuntuからrancherOSに変えてみよう。イメージとssh-userを変更して、2台ほど追加する。

すると…3台にちゃんと増えた。

ダッシュボードを見ても、ちゃんと増えてますね。

どこまでKubetnetes側を触れるのか分かっていないけど、かなり手軽に試すことができるなあ。

ホストを消してみる

ここで、せっかくなのでおもむろにk8s-1を消してみて、どうなるのか試すことにした。Rancher側でホストを削除すると、OpenStack側でもインスタンスが消える。
少し時間がかかったが、消したホストでのみ動いていたものが別のホストで起動したようだ。ダッシュボードも見えるようになった!

まとめ

RancherServerをOpenStack上に用意し、OpenStack MachineDriverを使ってホストとしてOpenStackのインスタンスを使ってみた。気になる所としては、以下の3つがある。

  • Floating IPをつけないとインターネットに繋がっていないように見える
    • FIPをつけないとホストの構築がうまくいかないようだ。Rancherの問題なのか、OpenStack側の問題なのかの調査が必要そう。
  • OpenStackのAPIを使うためのパスワードが各ホストのView in APIから見えている
    • APIを使うための認証情報は見えないようにした方が安全じゃないかな…
  • ホストを消す時にキーペアが消えることがある
    • 条件がよくわかっていないけどこれも割と困るのでは。

PuppetのFacterでもrspecしたい!

そういうわけです。Rubyなので、Rubyのテストツールでテストできると複雑なCustomFacterの維持・管理がしやすいですよね。

今日は「あるFacterについてのテストを2つ以上書くときテスト毎にそのFacterの値をクリアする」ということをしたのでそれについて書きます。

まずはテストを1つ書いてみる

ホスト名からタグ(何のタグか、は気にしない)を生成するFacterのテストを書く、ということにします。最初のコードはこれ。雑…

テストはこうしましょう。CustomFacter内で別のFacterを使っているので、allowとreceiveを使ってstub化します。

テストを実行します。いいですね。

2つ以上のテストがあると?

さて、次です。いろいろなホスト名に対応したいので、安直にこうしてみます。

テストはこうなりますね。

よさそうです。テストを実行してみましょう。

うーむ、失敗してしまった。追加した「hostname の prefix が piyo の場合」がうまくいっていません。これは、1つ前のテストで一度tag facterが呼び出されたため、その値がメモリに保持されてしまっているためです。

解決策

解決策としては、テスト毎にtag facterの結果をクリアしてやればよい。ベストかどうかは自信が無いですが、今回はbefore(:each)で以下を実行して解決しました。

クリアしたいFacterをピンポイントでflushしてやります。Facter.clearというメソッドもあるのだけど、それを実行すると他のものも消えてしまって面倒だった。最終的なテストコードはこうなります。

実行すると、テストは2つとも通ることが確認できます。

これで、少ないコードでCustomFacterのテストを書けるようになりました。実際のCustomFacterは30行程度のものなので、テストがなくてもまぁ分かるのだけど、滅多に触らないのでテストがあると安心すると思います。