Packer で OpenStack のイメージを作ってみた

Packer で OpenStack のイメージを作ってみた

Packer で OpenStack のイメージを作ってみたので,その知見を共有します。

Packer とは

かんたんに, Packer について説明します。 Packer とは, Json で記述された template を元に,クラウドなどで動作するイメージを作ってくれる子です。

Packer のために,記述する Template には Builder と Provisioner というセクションがあります。 それぞれについて,説明していきます。

Builder

これは,イメージを作成するために,どんな環境を,どのように利用するのかを指定します。 環境には, OpenStack や Amazon EC2, Docker などがあります。 そして,それぞれの環境にどのようにアクセスするのかを指定します。

Provisioner

これは,作成したイメージにプロビジョニングするための設定を書くセクションです Puppet や Chef 等を利用できます。

作ってみるぞ!

それでは,上で説明した事を利用して,イメージを実際に作っていきます。 利用したコードは,下記のようになります。

{
  "builders": [
    {
      "type": "openstack",
      "flavor": "m1.small",
      "networks": "xxxxxxxxxxxxxxxxx",
      "ssh_interface": "eth0",
      "floating_ip" : "xxxxxxxxxxxxxxxxx",
      "security_groups": ["xxxxxxxxxxxxxxxxx", 
                          "xxxxxxxxxxxxxxxxx"],
      "availability_zone": "xxxx",
      "ssh_username": "centos",
      "image_name": "{{user `role`}}_centos7_{{user `date`}}",
      "source_image": "xxxxxxxxxxxxxxxxx",
      "user_data_file": "user_data"
    }

  ],

  "provisioners": [
    {
      "type": "puppet-server",
      "puppet_bin_dir": "/opt/puppetlabs/bin/",
      "puppet_server": "puppetserver.xxx.com",
      "options": "--test --certname={{uuid}} --environment={{user `environment`}}",
      "facter": {
         "role": "{{user `role`}}"
      }
    }
  ]
}

Builder セクションの type に OpenStack を指定すると,source_image に指定したイメージで,OpenStackにインスタンスが起動します。 その後,起動したインスタンスに対して, SSH でログインし, Provisioner セクションで指定した方法でプロビジョニングしていきます。

ですので, Builder セクションでは, Packer を利用した場所から SSH ができるような設定が必用で, ssh_username や ssh_interface , security_groups などがその設定に当たります。

Provisioner セクションでは, puppet を利用するために必用な設定を行います。

注意事項として, Provisioner ではプロビジョニングに利用するツールをインストールしてくれるわけではないので,もととなるイメージに Puppet が含まれているか, cloud-init などでインストールする必要があります。

今回は cloud-init でインストールしました。

#cloud-config
bootcmd:
    - rpm -Uvh https://yum.puppetlabs.com/puppetlabs-release-pc1-el-7.noarch.rpm
    - yum install -y puppet-agent

また, Packer には, User Variable という機能があって,コマンドライン引数や,環境変数から Packer templateに情報を渡すことができます。

今回は,コマンドライン引数から渡したいので

 "options": "--test --certname={{uuid}} --environment={{user `environment`}}",

の用に書いています。

packer build -var 'role=xxx' -var 'environment=xxx' -var \
       'date=`date +"%Y-%m-%d-%H-%M-%S"`' template.json

などのように実行すると,コマンドライン引数で指定した値が {{user environment}} などのようにかれた箇所で利用されます。

{{uuid}}

にはランダムな値が入ります。 こうしておかないと, 同じ証明書が Puppet で使いまわされることになり,Puppet で怒られます。


幾つか, Packer Template の記法で悩むことはありましたが,割とシュッとできたな,という所感です。 今は,最低限のプロビジョニングが施された,基本となるイメージしか作成できていませんが,Role ごとにプロビジョニングされたイメージを作ることで スケールアウトのために時間が短縮できたらな,と考えています。

以上です。

mruby-maxminddb という mgem を作った話

このブログは mruby Advent Calendar 2016 の 21 日めの記事です。

最近,と言っても少し前ですが,mgem を作りました.

作った mgem の名前は mruby-maxminddb って言います.

GioIP の DB である maxminddb を読み書きする Gem です.

MaxMindDbDat = "/tmp/GeoLite2-City.mmdb"
IPAddr = '8.8.8.8'

maxminddb = MaxMindDB.new MaxMindDbDat

maxminddb.lookup_string IPAddr

maxminddb.country_code       #=> US
maxminddb.region             #=> CA
maxminddb.region_name        #=> California
maxminddb.city               #=> Mountain View
maxminddb.postal_code        #=> 94035
maxminddb.latitude           #=> 37.386
maxminddb.longitude.round(4) #=> -122.0838
maxminddb.metro_code         #=> 807
maxminddb.time_zone          #=> America/Los_Angeles

などのように利用します。

例えば,Webサーバーやメールサーバーのスパム対策に利用できるかと思います。

幸いにも maxminddb を利用するための C 言語のライブラリがあったので,こちらをラップする形で実装していきました。 libmaxmind と言います。

libmaxmind はドキュメントが充実しており,それらを参考に実装していきました。

また, maxminddb をダンプするための mmdblookup というツールも同梱されており,そちらのコードはとても参考になりました。 ほぼ,このツールの動作を模倣する形で実装を進めていきました。

static mrb_value mrb_maxminddb_lookup_string(mrb_state *mrb, mrb_value self) {
  mrb_maxminddb_data *data = DATA_PTR(self);
  char *ipaddr = NULL;

  mrb_get_args(mrb, "z", &ipaddr);
  data->host = ipaddr;

  data->lookup_result_s =
      MMDB_lookup_string(&(data->mmdb), data->host, &(data->gai_error),
                         &(data->mmdb_lookup_error));

  if (0 != data->gai_error) {
    mrb_raise(mrb, E_RUNTIME_ERROR, gai_strerror(data->gai_error));
  }

  if (MMDB_SUCCESS != data->mmdb_lookup_error) {
    mrb_raise(mrb, E_RUNTIME_ERROR, "Lookup Error");
  }

  return self;
}

例えば,上記のようなコードは, mmdblookup.c の似た関数を模倣して実装しています。

mgem として実装するので,エラーが発生したときに mrb_raise を返すところや, 構造体に MMDB_lookup_string の戻り値を格納しているところが違うぐらいです。

その構造体は mruby で C 言語の構造体をラップしたオブジェクトを作る正しい方法 を参考にして mruby のオブジェクトとしてラップしています。

mruby-maxminddb は初めて C 言語で mgem を作るには手頃なお題でした。 libmaxminddb というライブラリもあり,ドキュメントも充実しており,参考にできるコードも同梱されていました。

mgem を作るにあたって参考になるブログもありました。

来年も,幾つか mgem を開発していきたいと思います。

以上です。

障害対応 ~ あるいはポケットに手を入れて走ることの危険性について ~

こんにちは, GMO ペパボの @mickey と申します。 この記事は,Pepabo Advent Calendar 2016 の 5 日目の記事になります。

さて,僕は GMO ペパボでインフラエンジニアをやっています。 インフラエンジニアの重要な仕事の1つに障害対応があります。

そこで,先日の障害対応について書いていこうと思います。

障害が起きたのは自分です。

チームでの楽しい飲み会の後,僕は終電に向けて走っておりました。 原因については,定かではありませんが,気がついたら僕の顔は地面に衝突していました。 ポケットに手を突っ込んでいたため,顔から地面に突っ込んでしまいました。

この記事では,自分に起きた障害,怪我,に対して僕がどのように対処したのかを記述していこうと思います。

これからの忘年会シーズンで同じような事象に遭遇する方々もいらっしゃるかと思います。

体験を記す事で,似たような体験をした方々にスムーズに治療を受けてもらうことができればと思います。

さて,顔から地面に突っ込んだ後ですが,もちろん,終電は逃しました。 タクシーを拾い,なんとか自宅へ帰宅しました。

帰宅後,顔を点検したところ,大きな擦過傷と,そして,腫れがありました。

酔いも冷め,段々痛みが強くなってきます。

できれば,病院で治療をしてもらいたい,しかし,夜中なので空いている病院もないですし,救急病院に心当たりもありません。

未経験の障害に遭遇したときにどうするか,まずは,検索です。

Web は広いので自分しか経験したことがないと思うようなことでも,対処方法が乗っていたりするものです。

google 先生にお伺いを立てると,こういった相談を受け付けてくれる電話番号があるとのことでした。

7119 番 (携帯電話だと 23 区なら 03-3212-2323) です。 この電話では,

  • 症状に基づく緊急性の有無のアドバイ
  • 受診の必要性に関するアドバイ
  • 医療機関案内

等をしてくれます。

電話をし,受付の看護師さんと相談しました。

基本的な個人情報,年齢や住所,を聞かれ,症状について説明し助言をいただきました。

  • 顔というか頭を打っているので脳に異常がないかどうか CT を撮ってもらったほうが良い
  • 左腕に痛みがあるそうだが,そちらも,骨折の有無について検査したほうが良い

とのことでした。

また,頭部への打撲ということもあるので,このまま救急車を手配することもできるがどうするか,と聞かれました。

救急車を呼ぶかどうか,割りと真剣に悩みましたが,さすがにそこまでするのはどうだろうと思い,病院を紹介していただき,自力で病院を探しました。

混み具合などで 2 件ほど断られた後,治療してくれる病院が見つかりました。

病院では 20 分ほど待たされた後,CT と左腕のレントゲンを撮影していただき,骨折や脳の出血が無いことが確認されました。

検査の合間に,看護師さんに「こういった怪我で受診する人はどれくらい居るのか」と聞いてみたところ,割といるとのことでした。

さて,治療も済み,大きな怪我も無いことが判明したので,会計して帰宅します。 しかし,夜間では病院の精算業務が停止しているため,何円か預けて,後日精算する流れになるとのことでした。

僕の体験は以上になります。

最後に知見をまとめます。

  • 急な怪我や病気で緊急性の有無の判断や医療機関案内をしてほしいときは 7119 番に電話すると良い
  • 夜間に病院にかかるときは,少し多めの現金があると良い
  • ポケットに手を入れない
  • 飲みすぎない

これからの忘年会シーズン,怪我に気をつけて無事に今年を乗り切りましょう。

以上です。

(技術的な話も準備してあるのですが,ちょっと,上記の経験のインパクトが大きすぎてこちらを書き残すことにしました)

ペパボテックカンファレンスに登壇してきました

ペパボテックカンファレンスに登壇しました。 空気を読まずに,詩を朗読したり,作曲したり,ラップしたりせずに,情報通信技術の話をしてきました。

このテックカンファレンス,IT の話をするほうがマイノリティだったんですよ…。

いろいろな意味ですごいテックカンファレンスでした,伝説の夜でした…。

ニャロメのおもしろコンピュータ探検

ニャロメのおもしろコンピュータ探険 (パシフィカの本)

ニャロメのおもしろコンピュータ探険 (パシフィカの本)

「ニャロメのおもしろコンピュータ探検」という本を読みました. 後輩から頂いた本です.

奇遇にも,この本は 1982 年,僕が生まれた年に発売された本です.

コンピュータ,という観点で見ると,1982 年に比べて 2016 年はだいぶ進歩しました.

モニタは薄くなりましたし,カラーになりましたし,処理速度も相当大きくなりました.

ただ,コンピュータの基本原理は変わっておらず,その点に関しては,割りと信頼できる記述がなされています.

これってすごいことですよね,知らない人が見たら,1982 年のコンピュータと 2016 年のコンピュータはおんなじものには見えないでしょう,でも,その後ろ側で動いている基本的な原理に差はないんです.

チューリングノイマンは偉大です.


コンピュータは進歩しました.

しかし,です. この本から読み取れる 1982 年と,2016 年って「生活」という面から見るとそんなに差はありませんでした.

人間はおでんを食べて,冷酒を飲んで,電車や車に乗ります.

人間の生き方というのは,たかだか,34 年程度では変わんないんだなぁという感じました.

しかし,変わる部分はあるんですよね. その,どこは変化してどこが変化しないのかを考察してみるのは面白そうです.


あと,バカチョンソフトって,おい....

以上,感想でした.

ひとりごと

優しい言葉を使いたい.

僕は,勢いで発言することが多いような気がする.

できるだけ,相手にわかってもらえるような言葉を使いたいんだけど,これはホゲだ!これはフガだ!みたいに端的な強い言葉で発言してしまうくせがあるように思う.

思慮深く,丁寧な言葉で発言しようとすると,声に出す前にまぁいいかってなっちゃうんだよね.

意識の高い話

シニアエンジニアに立候補して,面談を受けてきました.

うちの会社には,engineer の階級として「シニア」というものがあります. そして,シニアエンジニアになるためには,自薦で立候補得する必要があります.

そして,僕はシニアに立候補して,今日,面談を受けてきました.

うちの会社がシニアに求めていることには,色いろあるんですが,その辺の話は,ここではしません. もっとちゃんと書いてある記事があるので.

シニアに立候補してから,面談を受けるまでに強く感じたことがいくつかあるので,それについて書いていきます.

シニアに立候補することで,それまでの自分の行動を振り返って,自分はシニアに足る人間なのか,そうでないのかを考えさせられます. これは,今,シニアである方と自分との差を見つめて,足りている部分,足りていない部分を振り返る作業です.

この作業をすることで,自分の弱さ・強さを認識することができました. 今回の結果がどうなるにせよ,シニアエンジニアの基準と自分との差については,定期的に振り返っていきたいです.

また,「自薦」である,自分で「シニア」を目指すことを選択するということについてもいろいろ考えさせられました. 明文化しきれない部分が多々あるので,ここでは,「考えた」というだけにとどめます.

ちなみに,「シニア」への立候補以外についても,基本的に,まず,自分で自分を評価してから,上の人に評価してもらうというスタンスです. 必ず,自分で自分が過ごしてきた半年を振り返る必要があります.

こういった,年に2回,自分の職業人生について振り返る機械を与えてくれる,弊社の評価制度は割と好きです.

意識高い感じの回でした.