repl.info

OpenStack Heat再び

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

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

Every 2.0s: openstack server list takaishiryou-no-iMac.local: Mon Apr 17 22:14:28 2017



+--------------------------------------+----------------------+--------+----------------------------------------+------------+

| ID | Name | Status | Networks | Image Name |

+--------------------------------------+----------------------+--------+----------------------------------------+------------+

| a87e1500-2539-4998-85e4-b1f42a2c7f62 | scale-10.8.1.4 | ACTIVE | alpaca-internal=10.8.1.4 | cirros |

| d60adfe6-148b-48fc-a9de-61c553c16837 | scale-10.8.1.6 | ACTIVE | alpaca-internal=10.8.1.6 | cirros |

| c4cec0c2-3faf-4ecf-836d-71b17051ba02 | scale-10.8.1.7 | ACTIVE | alpaca-internal=10.8.1.7 | cirros |

| 999d6f7e-4e50-4c42-be5e-66149a0a92d5 | no-scalable-10.8.1.5 | ACTIVE | alpaca-internal=10.8.1.5, 172.24.4.233 | cirros |

+--------------------------------------+----------------------+--------+----------------------------------------+------------+

各リソースについて

main.yaml

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

heat_template_version: 2016-04-08



description: テストだよ。



parameters:

  instance_count:

    type: number

    label: Instance Count

    default: 3



resources:

  alpaca_internal:

    type: OS::Alpaca::Network

  scalable_instances:

    type: OS::Alpaca::ServerGroup

    properties:

      name: scale

      count: { get_param: instance_count }

      network: { get_attr: [alpaca_internal, network] }

  single_instance:

    type: OS::Alpaca::Server

    properties:

      name: no-scalable

      network: { get_attr: [alpaca_internal, network] }

  test_attach_fip:

    type: OS::Alpaca::AttachFloatingIP

    properties:

      server: { get_attr: [single_instance, server_id] }

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

resource_registry:

  "OS::Alpaca::Network": ./os_alpaca_network.yaml

  "OS::Alpaca::Server": ./os_alpaca_server.yaml

  "OS::Alpaca::AttachFloatingIP": ./os_alpaca_attachfloatingip.yaml

  "OS::Alpaca::ServerGroup": ./os_alpaca_servergroup.yaml

OS::Alpaca::Network

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

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

heat_template_version: 2016-04-08



description: ネットワークだよ



resources:

  my_net:

    type: OS::Neutron::Net

    properties:

      name: alpaca-internal

  my_subnet:

    type: OS::Neutron::Subnet

    properties:

      network_id: { get_resource: my_net }

      cidr: "10.8.1.0/24"

      dns_nameservers: ["8.8.8.8", "8.8.4.4"]

      ip_version: 4

  router:

    type: OS::Neutron::Router

    properties:

      external_gateway_info: { network: public }

  my_subnet_interface:

      type: OS::Neutron::RouterInterface

      properties:

        router_id: { get_resource: router }

        subnet: { get_resource: my_subnet }

outputs:

  network:

    value: { get_resource: my_net }

OS::Alpaca::Server

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

heat_template_version: 2016-04-08



description: インスタンスを定義するよ



parameters:

  name:

    type: string

    default: "aaa"

  network:

    type: string



resources:

  port:

    type: OS::Neutron::Port

    properties:

      network: { get_param: network }

  server:

    type: OS::Nova::Server

    properties:

      name: { list_join: ['-', [{ get_param: name }, { get_attr: [port, fixed_ips, 0, ip_address] } ] ] }

      key_name: r_takaishi

      image: cirros

      flavor: m1.tiny

      networks:

       - port: { get_resource: port }



outputs:

  server_id:

    value: { get_resource: server }

OS::Alpaca::AttachFloatingIP

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

heat_template_version: 2016-04-08



description: サーバーにFIPをアタッチするよ



parameters:

  server:

    type: string



resources:

  floating_ip:

    type: OS::Nova::FloatingIP

    properties:

      pool: public

  association:

    type: OS::Nova::FloatingIPAssociation

    properties:

      floating_ip: { get_resource: floating_ip }

      server_id: { get_param: server }

OS::Alpaca::ServerGroup

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

heat_template_version: 2016-04-08



description: 複数台のサーバーを管理する君



parameters:

  count:

    type: number

    default: 1

  name:

    type: string

    default: aaa

  network:

    type: string



resources:

  instances:

    type: OS::Heat::ResourceGroup

    update_policy: {

      rolling_update: { "min_in_service": 1, "max_batch_size": 2, "pause_time": 5}

    }

    properties:

      count: { get_param: count }

      resource_def:

         type: OS::Alpaca::Server

         properties:

           name: { get_param: name }

           network: { get_param: network }

まとめと感想

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

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

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