GMOペパボの近藤うちお(@udzura)です。普段は福岡に勤務しており、技術基盤チームとして、RubyやPuppetを書いています。Fukuoka.rbというコミュニティをやっていたりもします。どうぞよろしくお願いします。
今回は、今月12日〜13日に開催された RubyWorld Conference 2015 に登壇した際、お話しした内容について書かせていただきます。
RubyWorld Conferenceとは
RubyWorld Conferenceとは、今年で7回目となる、島根県松江市で開催されるRubyのカンファレンスです。毎年、Matzの基調講演を始め、様々な利用事例や技術動向の紹介がされています、そういった中で、ペパボとしては、最近全社で導入を進めているOpenStackの話しと、OpenStackを使いこなすためにペパボのエンジニアでRubyのライブラリ・ツールを開発しているお話しをしました。
スライドは以下になります。
ペパボとOpenStack、そしてRubyのツール
ペパボでは、今年度より全社のサーバーインフラ基盤としてOpenStackの採用を決定し、導入を開始しました。現在ではカラメル、JUGEMといった大きなサービスを含む、各サービスで導入が進んでおり、今後も広めていくべく開発を進めています。
その検証・開発の過程で、さまざまなOpenStackの管理ツールとライブラリを、Rubyで作成しました。スライドでは手短でしたので、この場をお借りしてもう少し詳細に説明したいと思います。
なお、ペパボでは、古くからPuppetの導入を進めているなど、サーバ状態や設定のコード化を推進しています。今回紹介するものも、そういった観点のツールが中心になります。
kaname
kaname は、OpenStack KeystoneのAPIを経由して、OpenStackのユーザ管理をするためのツールです。
具体的には以下のようなYAMLの設定ファイルをkeystone.yml
という名前で用意します。
antipop:
email: "antipop@example.com"
tenants:
kiban: "cto"
hsbt:
email: "hsbt@example.com"
tenants:
minne: "admin"
kiban: "member"
udzura:
email: "hsbt@example.com"
tenants:
minne: "member"
kiban: "member"
このファイルを元にkaname apply
コマンドを実行することで、OpenStack Keystone上のユーザがYAMLの状態に収束するよう、設定が適用されます。コマンドには--dryrun
オプションもあります。
$ kaname apply
Keystoneのユーザ設定を、設定ファイルの形で管理できるので、VCSで変更履歴を管理したり、GitHubのようなツールを用いることで変更のレビューをしたりすることが可能になりました。
kakine
kakine は、OpenStackのそれぞれのテナントごとに、Security Groupの構成を管理するためのツールです。
こちらも、以下のような設定ファイルを作成します。テナントがkibanという名前であればkiban.yaml
になります。
app:
rules:
- direction: ingress
protocol: tcp
port: 443
remote_ip: 0.0.0.0/0
- direction: ingress
protocol: tcp
port: 80
remote_ip: 0.0.0.0/0
description: app hosts
cache:
rules:
- direction: ingress
protocol: tcp
port: 11211
remote_ip: 10.10.10.0/24
description: memcached hosts
このルールを元に、kibanテナントのSecurity Groupの設定をするには、以下のようなコマンドを実行します。なお、こちらもkanameと同様--dryrun
オプションがあります。
$ kakine apply -t kiban
AWSでの運用経験がある方は共感していただけると思いますが、Security Groupの管理はなかなか罠が多く、具体的には全貌を把握するのが困難であることや、アドホックな対応により追加したルールがずっと残ってしまっていたりすることがよくあります。Security Groupをコードの形で残せることのメリットは、クラウド基盤では非常に大きいものと思います。
pec
pec はインスタンスを構築、また構成を管理するためのツールです。インストールしたら、以下のようにプロジェクトでセットアップを走らせることができます。
$ pec init
create - /Pec.yaml
create - /user_data/web_server.yaml.sample
生成されたPec.yaml
を、例えば以下のように編集して利用していきます。
# yamlのマージ記法を使うことができます
_default_: &def
os_type: centos
tenant: kiban
image: centos-7.1
flavor: m1.small
availability_zone: az001
# vm config
manage001:
<<: *def
networks:
eth0:
bootproto: static
allowed_address_pairs:
- 10.1.1.5/24
ip_address: 10.1.1.1/24
gateway: 10.1.1.254
dns1: 8.8.8.8
dns2: 8.8.8.8
eth1:
bootproto: dhcp
security_group:
- default
- ssh
templates:
- base.yaml
- webserver.yaml
user_data:
hostname: manage001
fqdn: manage001.pepabo.nyah
repo_releasever: 7.1.1503
web001:
<<: *def
networks:
....
log001:
...
設定を記述した後は、例えばmanage001
サーバを立ち上げる際は、pec up manage
をコマンドを実行すれば、manageにマッチするmanage001
を自動で検出して立ち上げてくれます。
pecの特徴として、事前にNeutron(ネットワークコンポーネント)のポート(仮想NIC)を作成してからインスタンスを立ち上げるので、いわゆるOpenStackのDHCPやL3 agentが利用できないような構成でもインスタンスを作成することが可能な点があります。
また、ロールごとのそれぞれのflavor(インスタンスタイプ)やuser-dataなどを構成管理できるようになるので、CloudFormationやTerraformのようなものと比べ、より簡易的なオーケストレーションツールとして利用することも可能です。OpenStackにはHeatというオーケストレーションのコンポーネントがありますが、ロールごとの構成を管理したい、という程度であればpecのシンプルさは便利かと思います。
YAO
YAO は、ここまでに説明してきたOpenStackのツール群のために作った、Rubyのための新しいOpenStack API Wrapperです。現在、ペパボのメンバーを中心として開発を進めています。また、ロゴも弊社の@horaotokoの作成です。
YAOの前まで、OpenStackのRuby wrapperには、以下の二つのgemがありました。
このうちのfogは、もともとOpenStackのためだけでなく、複数のクラウドにまたがった共通のレイヤーを提供するものであるため、非常にたくさんの依存gemが存在してしまっています。また、OpenStackの機能が現状では単独のgem切り出されておらず、その動きもなかなか進んでいないように見受けられ、現状ではOpenStackの機能を使うためにfog全体を利用するほかない状態です。
もう一つのRuby OpenStackは、2013年で開発が止まっており、プルリクエストも放置されている状況のようです。
一方で、OpenStackのAPI自体は、非常に綺麗なRESTful APIの規約に則っています。例として、Compute APIの一部をご紹介します。
GET /v2.1/{tenant_id}/servers List servers
POST /v2.1/{tenant_id}/servers Create server
GET /v2.1/{tenant_id}/servers/{server_id} Get server details
PUT /v2.1/{tenant_id}/servers/{server_id} Update server
DELETE /v2.1/{tenant_id}/servers/{server_id} Delete server
GET /v2.1/images List images
GET /v2.1/images/detail List images details
GET /v2.1/images/{image_id} Get image details
DELETE /v2.1/images/{image_id} Delete image
以上のことから、既存のgemを頑張って使いまわすことより、新規かつ自分たちでコントロールできる形で実装する方がコストも大きくなく、メリットも得られると判断しました。そして開発をスタートすることとしました。
YAOは、以下のような設計思想で作られています。
- 最低限の依存
- 個々のコンポーネントに依存しない、利用者から見たリソース単位での操作をする
「最低限の依存」については、現状、json
、faraday
とfaraday_middleware
にのみ依存している状態です。faraday_middleware
への依存も開発が進んで必要な機能が絞れたら外す方向で検討しています。そのため、依存関係のコンフリクト等の心配をすることなく、個々のプロジェクト内で利用できるようになっていると思います。
また、「個々のコンポーネントに依存しない、利用者から見たリソース単位での操作をする」点については、Nova、Neutronといったコンポーネントの種類ごとにRuby側の実装をするのではなく、Server、Network、Userといった、より利用者のメンタルモデルに沿ったリソース単位でのクラス分けを基本としています。
これらのリソースクラスについて、OpenStackのRESTfulなAPIを生かし、以下のような小さなDSLを書くことで定義可能となっています。
module Yao::Resources
class Flavor < Base
friendly_attributes :name, :vcpus, :disk, :swap
map_attribute_to_attribute "os-flavor-access:is_public" => :public?
map_attribute_to_attribute "OS-FLV-DISABLED:disabled" => :disabled?
self.service = "compute"
self.resource_name = "flavor"
self.resources_name = "flavors"
end
end
現在は、上述したpec、kanameのOpenStackラッパーについて、fogからYAOへの置き換えが完了しています。その他のツールでも随時利用していく予定です。
また、YAOを使ったツールはGitHubのyaocloudオーガニゼーションにOSSとして配置し、一種のショーケースとして利用可能なようにしています。
まとめ
上記で紹介したような「コード化」の推進は、昨今のDevOpsの動きの潮流に沿ったものでもありますし、何より構成管理、自動化、レビューの容易さといった様々なメリットを受けられるものですので、引き続き進めていきたいと思っています。開発にあたり、Codenize.toolsの各gemの思想を参考にしました。この場をお借りして感謝します。
また、その基盤として作り始めたOpenStackのライブラリ「YAO」ですが、自分たちで使うことにより順調に開発が進んでいるように思われます。クオリティを上げ、世界中のOpenStackユーザに届くようなライブラリに育てていきたいと思います。OpenStackを利用している方々からのプルリクエストもお待ちしております。
最後になりますが、このような、OpenStackやDevOps、オープンソース開発の分野に興味のあるエンジニアを、ペパボでは絶賛募集しております!
(Photo from https://www.flickr.com/photos/hsbt/22406887374/ by @hsbt)