ansible vmware_guest_find モジュールを用いたVM存在確認と後続タスクの制御
これは何
ansibleによるVMwareのVMインスタンス管理の話。 VMインスタンスをコマンド一つで作成して初期設定ができるようにAnsibleで管理している。すでに存在するVMについては、うっかりRebootしたりNW Restartなどが走らないように存在チェックをしてそれらのタスクをスキップしたい。
vmware_guest シリーズの module について
- vmware_guest module
- VMを作るためのモジュール。ansible version 2.2 より使用可能。
- vmware_guest_find module
- vmware_guest_facts module
コードとハマリどころ
コード
# vmware_guest_findはすでにVMがいれば戻り値としてvm_folder.foldersにVMがいるディレクトリが入る(ここで、vm_folderはregisterで定義した変数)。居ない場合もしくは認証がうまく行かなかったなどの場合にはエラーになり、vm_folder.msgにその原因が書かれる。 # 後続のタスクは、VMがまだ居ない場合にのみ実行したい。 - name: check vm exists on vsphere vmware_guest_find: hostname: VMホスト名 username: ユーザ名 password: パスワード name: VMインスタンス名 datacenter: データセンタ register: vm_folder ignore_errors: yes # とりあえず ignore_errorsにしたけどfailed_whenで制御した方が綺麗だったかも。そのうちなおすかも。 - name: create and setting vm block: - name: create vm # ここら辺の中身は今回は略 include: create_vm.yml tags: create_vm - name: setting vm include: setting_vm.yml tags: setting_vm when: (not ("folders" in vm_folder)) and (vm_folder.msg | regex_search("Unable to find folders for VM"))
解説
vmware_guest_find module の戻り値。 Debugで見てみる。
- name: debug debug: msg: "{{ vm_folder }}"
VMがいるとき
"msg": { "changed": false, "failed": false, "folders": [ # これが帰ってくるのが特徴的 "/vm/hoge/development" ] } }
VMがいないとき
TASK [../ex_roles/vsphere_vmmaker : debug] ****************************************************** ok: [test-vmmaker] => { "msg": { "changed": false, "failed": true, "msg": "Unable to find folders for VM test-vmmaker" } # msgが帰ってくる。他の原因でmodule実行が落ちると他のmsgが帰ってくるのでそれを利用する。 }
- find と言う名前がついているので戻り値にBooleanが帰ってくるかと思ったらVM Folderが帰ってくるのだった
- ない時にはFalseが帰ってくるかと思ったらErrorになってしまうのだった
- 単に「find module実行が落ちたらVM設定する」にしてしまうと、なんらかの拍子にmoduleが落ちると意図せずcreate vm, setting vmが走ってしまって嫌だったので、それを念入りに回避するためにmsgを見ている
- もっと綺麗にかければよかったけど安全策をとった形
- find moduleはまだ安定していないので後方互換を取らないかもしれない、と言う注意文言があったのでmsgは変わるかもしれない(This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface. と書かれていた)
- msgがマッチしている時にだけ設定が走るので、msg文言が変わっても実行しないという安全側に倒れるので良い
コメント
インフラエンジニアがバックエンド書けるようになるために paiza と progate を使っている感想
これは何
バックエンド開発ができるようになるためにお家でPaizaやProgateを使ってPHPやRailsをお勉強している話。
目次
背景
私はメインの専門領域はWebインフラエンジニア(サーバエンジニア)なわけですが、そろそろアプリケーションコードもそこそこ書けるレベルじゃ無いと仕事がしづらいなと思ってきた。 だいたいコードの関連箇所の概要教えてもらったらコードを読み書きできるけども、自分一人で完全に問題箇所特定して修正してチューニングする、みたいなことがちょっとしにくい気がする(感覚的なもので、まだ何が知識として足りないか分かってないのでふわっとしている)
どう学ぶか?
会社で
一番いいのは会社で仕事としてアプリケーションコードを書くのが良い。とはいえ、私のメインで関わっているシステムはレガシーすぎるので「綺麗なコード」とか「良いアーキテクチャ」というのを学ぶのがなかなか難しい。本とか読めばある程度分かるのだろうが、ベースである程度読み書きして体に染み込んで無いと辛いところはある。
インフラ領域においてはやはりレガシーなところに放り込まれたが、3年という潤沢な時間をかけて試行錯誤しながら(なんとか動くくそコードを量産しながら)なんとか良い状態とは何かというのがなんとなく分かったつもりである。同じようにアプリケーションについて試行錯誤し続けるのも無駄な気がした。
自分で
となると、まずは独自で学習するしかない。ある程度分かってきたらそこそこ新しいシステムでアプリケーションコードを書かせてもらうように交渉するのが良さそう。 というわけで教材を探すわけである。とは言っても能動的に探したというよりも、問題意識を持っていたらTwitterで流れてきたのが目についてそれに飛びついた形。 さて、前置きが長くなったがPaizaとProgateについて。
Paiza
主観的な内容
競技プログラミングを学ぶためっぽい感じの内容だった。お題が出されてそれを実装する。主に実装速度(と高レベルになると実行速度)が見られる感じ。 実装速度を求められるのは新鮮で、就職活動をするときに自分の実力を知るためにFizzBuzzを時間計って頑張って書いたのを思い出した(10分以内にかけないくそプログラマもいる、と書かれている記事を読んだ後にやって7分くらいでできたので安堵したのを覚えている)。
選んだ言語
仕事でPHP関係が多いので、まずは最低限PHPコード読むのに苦労しない程度学ぼうと思ってPHPを選ぶ。
内容とレベル感
ざっくりやってみて、Bレベルまでは解けるのは分かった。このレベルだと、想定回答時間内に終わらないことも多いが、最終的になんとか回答できる感じ。Cレベルは普通にふわっと書いて終わるレベル。
Bで苦労するものがまあまああるので、Aは無理そう。
しばらく頑張ればBがスイスイ解けるようになるだろうと思ったが、今そうなりたいかと言われるとちょっと違うと思ったのでここで終わり。
自分とマッチしているか
ところで、Paizaは求人と紐付いているだが、きている求人があわなさそうなのが多いのでちょっとないかなという感じ。提案されるお給料にコーダーとしてのお値段を実感した。コードだけ書きたいわけでもなし、ここを極めるのは自分の進む違う感じがして一旦終わり。
Progate
主観的内容
Railsの教材を選んだ。そのせいか、コードを書くというより、アプリケーションを実際に作ってみるというのに重きを置いている感じ。ちょうど何か自分で全部作りたいなと思っていた時期だったので、マッチした。他のRubyの教材とかは雰囲気違うかも。
内容とレベル感
内容としては、「一気に全てを学びましょう」ではなくて、RailsだったらRailsの機能に焦点を当てているところが特徴的。当然、見た目それっぽいアプリケーションを作るためにはHTMLやCSSの知識も欠かせないわけだが、そこらへんは「ここにもう書いてあるのでコピペして該当箇所に貼ってね」という感じで、本当に基礎のところを知っていればスムーズに学びを進められる。綺麗なWebサイトつくるために後でそのコースも取ろうかな、と思わせる作り方なのがよかった。 今の所レベル26までやって、微妙に完全脳死ではできない感じでちょうど良い。
自分とマッチしているか
今の所結構良さそう。Railsはアプリケーションを高速で作るのに適していると聞くし、後で自分のプロダクト作るときに使えそう。裏の細かい技術的なことはインフラやってる経験から後からまあまあ調べられると思うし「だいたいこんなんで作れるだろう」というレベルまでいければ御の字。しばらく頑張ってみたい。
おまけ
N予備校
ちょっとだけやってみた。環境構築からしっかり学ばせるというコンセプトが強い。そこらへんは個人的には間に合っているので別にこれじゃなくていいかなというところ。本当のエンジニア初心者には結構良いかもしれない。関係ないが、世界史とかの講義を聞いていると「なるほどそういうことだったのか」という学びが大きいので、そういう一般常識的なものを学ぶのにむしろ使いやすそう。しかし講義は1時間とか長いのでもうちょっと細切れの方が楽だなあと思いつつ、ちゃんと流れで理解するためにはそれくらいのまとまりは必要だろうなどと思ったりする。
まとめ
昔は本使ってRails触ってみて続かなかった。Webサービス使うとうまく進捗や理解を管理してくれるので楽で楽しくやれる。微妙にお金はかかるけど専門書買うのより安かったりして最近麻痺してお金をいろいろ突っ込んでいる。
DNS切り替えを伴う環境移行のハマりどころと気をつけポイント
これは何
大きくサーバ群をリプレイスする時に考えるべきこと、詰まりどころをまとめておきたい。
目次
事前リソース見積もりについて
データ取得と方針
- 継続的にデータを取得しておく
- ピーク時平均値とスパイクするポイントが重要
- 負荷について
- 新環境は負荷をかけても耐えられるか。まずは旧環境と同様の負荷
- 今後の伸びを考慮した負荷
特に気にすべき負荷
ストレージ
- ディスクサイズ
- 負荷とは少し違うかも
- 今後の伸びを考慮した割当を行う。オンライン後から追加できるならある程度攻めても良い。補足:気軽に増やしたり出来ない物理サーバで5年でリプレイスするなら、5年後に70%になる程度にするとよいかもしれない
- IOPS ランダムアクセスに対する指標である。ブロックサイズが大きいものについてはIOPSが思ったより出ないこともある。その場合はスループットが重要
ネットワーク
- 新旧環境をまたぐトラフィックが発生する場合には特に注意が必要
- レイテンシ
- サービスでどの程度まで許容できるのか
- DBなのかcacheなのかでも違う
- トラフィック量
- LB、ルータ、スイッチ、ケーブルのキャパ
- 特に環境間のルータがボトルネックになるし、影響範囲も大きい
疎通問題について
- 同じIPセグメントなら問題は起こりにくい
- 違うセグメントに新サーバを立てるなら既存サーバから/に疎通ができるか
- L7レイヤまで確認するのが望ましい
- 必要に応じてルーティング設定をいれる
- 細かく /24に対してのroutingなどを入れていっても良いが、セキュリティ的な問題がない or リスクが飲めるなら /8 でいれるのもあり
LB・FWの設定について
- Global IPは割り当てられているか
- LB設定はすべてのドメインとパスに対して入っているか
- SSL証明書は設定されているか
- 鍵と証明書は行方不明になりがち
- 鍵の置き場(秘匿情報置き場)をあらかじめ決めておくと良い
- IP直うちでアクセスした時にどういう動きをさせるのか決めておく
- 503を返していいのか、何からのデフォルトサーバに到達させて200にするか、など
- 社内外からアクセスできるか
- 特に社内だけ空いていて、社外からアクセスできないということがないか?
- 必要に応じてACL設定を行う、もしくは抜いておく
DNS設定切り替えについて
ansible のダウンロード処理のリトライ(と既存コードの書き換えスクリプト)
これは何
playbook の自動テストで各種パッケージダウンロードの処理がたまに落ちていた。コードの問題ではないところで落ちてjenkinsが赤くなると嫌なので出来るだけ通るようにしたい。 リトライ処理をいれて問題の緩和を図りたい。 微妙に詰まったのでメモを残しておく。
参考文献
- get_url のreturn valuesについて;http://docs.ansible.com/ansible/latest/get_url_module.html#return-values
- untilのところ: http://docs.ansible.com/ansible/latest/playbooks_loops.html#do-until-loops
- result|succeededのところ: http://docs.ansible.com/ansible/latest/playbooks_conditionals.html#the-when-statement
コード解説
- name: download nginx source become: no get_url: url: "http://nginx.org/download/nginx-{{ NGINX_VERSION }}.tar.gz" dest: "/usr/local/src" register: download_result until: download_result|succeeded retries: 3 delay: 5
until, reties はセットで書く必要がある。untilの記述がなければretiesは1になる。 untilでの判定をするためにregisterで変数にタスク実行結果を入れておく。
おまけ
既存コードの書き換えのためのスクリプト
沢山の場所を書き換えないといけないのでperlスクリプトを使った。
grep -r "get_url:" | awk -F':' '{print $1}' | sort | uniq | xargs perl -i -0pe 's/(get_url:(.*\n)+?)^\s*$/\1 register: download_result\n until: download_result|succeeded\n retries: 3\n delay: 5\n/m'
以下スクリプト解説のようなメモ書きのような。
基本的にyamlのブロックごとに改行を挟んでいるので、それを用いる。
オプション修飾子mは対象文字列が複数行である場合に使う。
以下のような構造のyamlになっていた場合に、^\s*$
で空行までのマッチになる。
ここで(.*\n)+?
に?をつけているのは最短一致のためで、これをつけないと最長一致になってしまって空行1までではなくて、いけるところまでいったところ(この場合は空行2)までマッチするので注意が必要。
- name: download nginx source become: no get_url: url: "http://nginx.org/download/nginx-{{ NGINX_VERSION }}.tar.gz" dest: "/usr/local/src" (空行1) - name: hoge piyo: fuga (空行2) - name: hoge piyo: fuga
便利ツール紹介
ところで、正規表現を最初からコマンドラインで書くのもありなのだけど、あまりにも辛いのでGUIツールを使うのがよい。以下のサイトが最高なのでみんな使うべき。 https://regex101.com/
社内galaxyを作ろう
これは何
自分でansible galaxy を作る。特に今回は公開のものではなくて、社内に限る共通roleを作る話。 実際に作ったroleは社内事情や秘匿情報を含むのでここには書きません。
背景
社内クラウドのリソースを管理するplaybookをある人が作った。その後それをコピーして他のサービスで同じコードを使った(以下繰り返し)。 何かミドルウェア仕様が変更になったり、設定を変えたい場合にすべてのサービスでメンテナンスコストが発生する。 この状態は最低だと思ったので、社内galaxyを作り共通roleにしようと考えた。 その時に考えたこと、ハマったことをここに記録しておきたい。
参考
- http://docs.ansible.com/ansible/latest/galaxy.html
- その他いろいろgalaxyのレポジトリ
作り方
- meta/main.yml を配置する
- 内容は
ansible-galaxy init hoge
で適当なものを作ってコピーしてくるのが楽
- 内容は
- 使う
- 上のmetaファイルだけ置いてしまえばもうansible-galaxy installで読み込める
ansible-galaxy install git+http://github.fuga.co.jp/dw-ansible/piyo.git --roles-path ./ex_roles/
- 整理する
- あくまでgalaxyはroleを共有するという感じなので、普通ansibleレポジトリにはinventoryやplaybookファイルが含まれていると思うが、それらを削除する
- defaults/* ファイルへデフォルト設定を配置する
defaults/ について
- どのようなサービスでも共通の設定はmain.ymlにおいておくと良い
- 必ず変えて使って欲しいという変数はあえてデフォルトを配置せず実行時にエラーで落ちるようにしたほうが安全かなと思った
- main.ymlは読み込まれるが他は特に指定しなければば読み込まれない。変えて欲しい値だけどテンプレートは欲しいよねというような値はtemplate-*.ymlみたいなのをおいて読み込み先のplaybookでコピーして書き換えてもらうのがよさそう
その他
- 社内共通galaxyは、作るのはそこまで難しくないことがわかった
- むしろ広報や運用が難しい。使ってもらわなければroleは育っていかないし、破壊的変更をすると困るユーザがいるはずなので合意を取って前にすすめていくのは大変。後方互換を保ったまま育てていくのもカオスになりがちだし、これからそこの悩みが出てきそう
- とはいえ、作ればみんな喜ぶので積極的に共通パーツを作って展開していきたい
netscaler LBにおいてサーバを使わずにリダイレクトする
これは何
netscaler LBにおいて特定FQDNへのアクセスをパスそのままで他のFQDNにリダイレクトする方法についてまとめる。 この資料は NetScaler version 11.0 で実験した動きを元に書いています。
目次
参考資料
https://support.citrix.com/article/CTX120664 大体これを読めばできるが以下の問題があった(この資料を作るモティベーション)
- LoadBalancing Virtual Server の設定のところがServiceと書いてあり誤植と思われる
- 設定箇所の階層が書いておらず多少読みづらい
- LoadBalancing Virtual ServerにGlobal IPを設定するパターンしか書かれていない
手順
System設定でresponderの有効化
NetScaler -> System -> Settings -> Configure Acvanced Features
responder にチェックを入れる。
Responder Actionの設定をする
- Addする(既存のActionを選択してAddするとそれをテンプレートとして使うことになる。最初から作るなら選択を外してAddする)
- TypeはRedirectを選択
- Expression
例1) http->httpsにリダイレクトするなら、スキーマのところだけhttpsと書いて後は同じ
"https://" + HTTP.REQ.HOSTNAME.HTTP_URL_SAFE + HTTP.REQ.URL.PATH_AND_QUERY.HTTP_URL_SAFE
例2) 特定の別のドメインにリダイレクトする
"http://piyo.jp" + HTTP.REQ.URL.PATH_AND_QUERY.HTTP_URL_SAFE
補足: L7で http://hoge.jp/fuga などで入ってきたLoadBalancing Virtual Server経由でこのactionで http://piyo.jp/fuga に飛ばすイメージ
* Response Status Code を設定する デフォルト 302
Responder Policy の設定をする
- さっきのActionを設定する
- Undefined-Result ActionをRESETにする
- Expressionには HTTP.REQ.IS_VALID を設定(frequently Userd Expressionから選択すると良い)
- 要するにこのpolicyでは特に何もせずに(validかチェックだけして)actionへ流すという意味か
monitor 設定をする
localhost に pingをうつmonitor設定を作る
- name: localhost_ping
- Type: PING
- destination ip: 127.0.0.1
service を作る
上で作成したmonitorを使って常にserviceがUP状態になるようにする。あくまでダミーで、LoadBalancing Virtual Serverが常にUP状態になるようにするためのものの模様
- 上記serverを紐付ける
- ProtocolとPortはHTTPと80とでも適当に設定しておく
- 作成後、Monitoring設定で先程作成したmonitorを設定し、UP状態になることを確認する
LoadBalancing Virtual Serverを作る
- IP Address: WebサイトのIPアドレスもしくはPrivate IP
- Global IPで直接受ける場合にはここに設定
- Content Switching Virtual Server通すならここはPrivate IPを指定する
- 作成後Responder Policyを設定
Content Switching Virtual Server 設定
上記でLoadBalancing Virtual ServerにPrivate IPを設定した場合にはContent Switching Virtual Serverのpolicyに紐付ける この手順はredirector特有というよりもContent Switching Virtual ServerからLoadBalancing Virtual Serverに流す手順と同じなので省略する
キャッシュサーバが遠くなるとレイテンシは上がるのか、pingとtcpdumpで考えた
これは何
私の持っているシステムではフロント系サーバからmemcached サーバへ接続回数が結構ある。
データセンタ内で今まではフロント系サーバもキャッシュサーバも同一セグメント、物理的にも近くにいた。
とある事情でサーバをリプレイスしなくてはならず一時的にそれが違うセグメントで、物理的にも遠く、間にいくつかスイッチとルータが挟まるようになる。
これにより新しいフロント系サーバから古いmemcachedサーバに接続するとレイテンシが問題になるかもしれない。
ネットワーク的に遠くなると実際にアプリケーションの応答性能の視点で問題になるのか、いまと比べて実際は大した事ないのか判断するために考えたことのメモ。
目次
測定
測定方法
ping のtimeの100回の平均を取る。 pingのtimeは何か -> https://linuxjm.osdn.jp/html/netkit/man8/ping.8.html
往復時間 (round-trip time) と消失パケットの統計が計算される。
なので、単なる往復時間。
TCPにおける遅延は? TCPの場合はパケットごとにACKするので、送りたいもののデータサイズが大きく、パケットの個数が増えると全体としてはそれだけ1パケットあたりの遅延が蓄積されていくことになる。 なので、pingのRTTの増加はそのままレスポンスタイムの遅れに繋がると考えられる。
測定実施
2台のサーバが同一セグメントにある 旧frontサーバ(hoge-old-web) => 旧cacheサーバ(hoge-cache)
[myuser@hoge-old-web ~]$ ping -c 100 xx.xx.xx.xx > ./tmp_to_hoge-cache_ping [myuser@hoge-old-web ~]$ grep "time=" ./tmp_to_hoge-cache_ping > ./tmp_to_hoge-cache_latency [myuser@hoge-old-web ~]$ awk '{print $(NF-1)}' tmp_to_hoge-cache_latency | awk -F'=' '{sum+=$2} END{print sum/NR}' 0.14284
0.14 ms くらい
新frontサーバ(hoge-new-web) => 旧cacheサーバ(hoge-cache)
[root@hoge-new-web ~]# ping -c 100 xx.xx.xx.xx > ./tmp_to_hoge-cache_ping [root@hoge-new-web ~]# grep "time=" ./tmp_to_hoge-cache_ping > ./tmp_to_hoge-cache_latency [root@hoge-new-web check_latency]# awk '{print $(NF-1)}' tmp_to_hoge-cache_latency | awk -F'=' '{sum+=$2} END{print sum/NR}' 0.16793
0.16 ms くらい
差分
0.16793 - 0.14284 = 0.02509 ms 割合ていうと 0.02509 / 0.14284 * 100 = 17%。
frontへアクセスした時にmemcachedはどれくらい叩かれている?
コードで呼ばれているcacheメソッドの回数も重要だが、遅延全体を考えるならパケットがどれくらい投げられているかが重要。なのでtcpdump でパケット数がどれくらい投げられているのか確認したい。
myuser@hoge-dev-web [~ ] $ sudo tcpdump -i eth0 > ./tmp_tcpdump_to_memcache tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes ^C7136 packets captured 7136 packets received by filter // 全部でこれだけのパケットが1リクエストで通った 0 packets dropped by kernel
その中で memcachedにつなぎにいっているのは?
myuser@hoge-dev-web [~ ] $ grep "xx.xx.xx.xx.11211 >" tmp_tcpdump_to_memcache -c 1579
memcachedから来ているパケットは1リクエスト1579回。(行きも同数。pingのtimeはRTTなので片方の道を通っている回数がわかれば良い。)
最大で増えるレイテンシはどれくらい?
毎回のパケット 0.02509 ms * 1579 = 39.6 ms。ほとんど誤差。気にしなくてもよさそう。
結論
今回の件ではレイテンシはあまり気にしなくても良い。