狠狠撸
Submit Search
Ansible 2.0を使って組む kubernetesクラスタ vol.1
?
17 likes
?
11,757 views
H
Hidetoshi Hirokawa
Follow
Ansible Meetup in Tokyo 2015.09 発表資料
Read less
Read more
1 of 61
Download now
Downloaded 51 times
More Related Content
Ansible 2.0を使って組む kubernetesクラスタ vol.1
1.
Ansible 2.0を使って組む kubernetesクラスタ vol.1 Ansible
Meetup in Tokyo 2015.09 廣川英寿@realglobe Inc.
2.
自己紹介 ? 廣川英寿 ? Github:
h-hirokawa ? 技師@realglobe Inc. (2011.9~) ? メイン言語はPython、とりわけDjango ? ansibleは2012末から利用中
3.
ansibleとコンテナ周り 結構やってますよアピール ? NiftyCloud C4SA
(2012) ? ウェブアプリ開発+運用環境構築PaaS ? LXCコンテナベース ? C4SA エクスポート機能 (2013) ? コンテナ上に展開されたアプリケーション環境をIaaSに移行 ? 移行機能はpure-ansible ? Deplow (2015) ? AaaS (Ansible as a Service) ? Dockerコンテナで切り分けられたAnsible環境と管理UIを提供 ? 毎月の無料Ansible勉強会主催やCI導入支援、プレイブック代 書もやってます
4.
Kubernetesって 何者? Kubernetesの説明を駆け足で
5.
Kubernetes(略称: k8s)とは ? Google主導で開発された、コンテナ用クラスタ管理ツール ?
コンテナ群を用いた大きな実環境の運用を実現 ? やってくれること ? コンテナを組み合わせてのアプリケーション環境構築 ? Pod: 1アプリケーションを構成するコンテナの組 ? Rep. Controllers: Podを冗長構成で稼働。死活監視付きで自動増減する。 ? Service: 冗長化されたPodに接続を振り分けてくれるLB的なもの ? ノードのクラスタ管理 ? ノード間コンテナ通信
6.
やりたい事 ? Ansible v2でk8sクラスタを自動構築する ?
CoreOSで作る ? 複数IaaS対応(今回はgce & idcf) ? 1クラスタを複数基盤にのせる ? 非推奨パターンなので今回はやめました ? クラスタ間の接続をPrivate IPからGlobalに変えれば可能
7.
CoreOSとは? ? コンテナ稼働専用の軽量ディストリビューション ? etcd,
?eet等、k8sのクラスタリング基板が組み込み済 ? いずれもCoreOS社がオープンソースで開発 ? rktなどのDockerに代わるコンテナ基盤も作っている ? コンテナ専用だから、/usr 以下はReadOnly ? コンテナ専用だから、パッケージマネージャも無い
8.
极め付けに
9.
笔测迟丑辞苍が入っていない!
10.
Pythonないのに何故Ansible? ? Ansibleには rawがある ?
SSHログイン?シェル上で直接コマンドを実行 ? scriptモジュールでも同様に生スクリプトを実行でき る ? モジュールがどんな言語でも書ける ? SSHで繋がる以外に事前準備は「一切」不要
11.
Pythonがホストになくたって自動化できる そう、Ansibleならね
12.
とは言ったものの… ? 全部rawでやるのはキツい ? 返り値を直接読んで処理しなければならない ?
rc, stdout, stderror ? 冪等性を守るも守らないも自分次第 ? register, whenの嵐で見通しも悪い ? v2のblockディレクティブである程度は緩和出来る ? いっそscriptで全部やっちゃう? ? あれ、何でAnsible使ってるんだっけ
13.
そんなあなたに笔测笔测
14.
PyPyとは ? RPythonで書かれたPythonの実装系(かっこいい) ? JITコンパイルされるのでCPythonより高速(かっこい い) ?
任意のパスで実行可能なバイナリが配布されている(かっ こいい) * RPython: バイナリコンパイル可能な制約付きPython
15.
CoreOSにPyPyを入れるメリット ? いつも通りにAnsibleが使えるようになる ? pipや他のpythonパッケージも問題なく使用可能 ?
どのAnsibleモジュールでも問題なく動くかは未確認 ? とは言え、CPythonとの違いはGCの方式などのプリミティブな所 なので、ほとんどの場合問題ないはず ? /opt等に置いてそのままCoreOSホスト上で動かせる ? バイナリパッケージを配置するだけなので、デプロイが短時間で済む
16.
CoreOS上でPyPyを動かす注意点 ? ansible_python_interpreterでpypyへのパスを指定する必要あり ? pypy/lib/libtinfo.so.5
=> /lib64/libncurses.so.5.9 のsymlinkが必要 ? PyPy 2.4.0を使う ? CPython 2.7.8互換 ? 最新のPyPy 2.6.1だと現段階では動いてくれない ? “no version information available” 警告が出てしまうのは諦める
17.
Let’s playbook!
18.
Playbook 今回作ったサンプルをgithubで公開してます https://github.com/h-hirokawa/ansible-kubernetes-coreos
19.
方針 1. IaaS上にCoreOSノードを作成 2. CoreOSにPyPyをインストール 3.
CoreOSにkubernetesをインストール ? master: kubernetesのAPIを立てる(今回は1台) ? minion: 各コンテナを稼働させるノード(複数台)
20.
迟颈辫蝉やハマりどころを解説
21.
1. IaaS上にCoreOSノードを作成 ~Ansibleからの効率的なIaaS操作~
22.
? これはCoreOSに限った話ではないですが、御存知の通 りAnsibleからはデプロイ対象ホストの操作に留まらず、 IaaSの操作も簡単に行えます。 ? 組み込みクラウド?モジュール例 AWS,
Azure, Cloudstack, Google, Openstack, Vmware…
23.
ただし、注意が必要なポイントも
24.
? IaaS操作は、localhostからクラウドのAPIを操作する事 になります ということは、 並列化が効かない!
25.
? 何も気にせずに複数台にまたがるIaaS操作を実行する と、1台1台のVMインスタンス作成リクエストからVM作 成(起動)完了までが同期で進んでしまうため、APIを 叩いて待つだけの操作に大幅な時間がかかってしまいま す。
26.
? 実はほとんどのクラウド操作モジュールには、操作完了 までの待機をせず、APIリクエストを送った時点で次の タスクに進んでくれるオプションがあります。
27.
各モジュールとパラメータの対応 ? ec2 ? wait:
no ? azure ? wait: no ? cs_instance ? poll_async: no ? gce ? なし… ? os_server ? wait: no ? vca_vapp ? wait: no
28.
CloudStackの場合 - name: まとめてインスタンス作成リクエスト cs_instance: name:
"{{ item }}" hypervisor: VMware template: MyOwnImage service_offering: xLarge ssh_key: ssh-key poll_async: no # ここが肝 with_items: [ vm1, vm2, vm3 ] ## 必要ならここで待っている間の処理 - name: インスタンス作成完了するまで待つ cs_instance: name: "{{ item }}" with_items: [ vm1, vm2, vm3 ]
29.
gceの場合 ? 待機制御用のパラメ?タが無いけれど、どうするの? ? 自分でカスタム?モジュール作れば良いじゃん
30.
そうだ、补蝉测苍肠があった!
31.
asyncを使った非同期タスク - name: 非同期処理開始 command:
sleep 60 async: 100 # 最大待機時間。pollが0の場合は正の数であればなんでも良い poll: 0 # ポーリング間隔。タスクを非同期に先に進める場合は0 register: async_job ## 間の処理 - name: 非同期処理終了待機 async_status: jid: "{{ async_job.ansible_job_id }}" register: job_result until: job_result.finished # ジョブ終了までループ retries: 30 # 最大試行回数 delay: 10 # 試行間隔
32.
asyncを使うと ? 時間がかかる処理を非同期で実行可能 ? 各非同期タスク毎に個別プロセスが立つ ?
poll を 0 に設定すると、タスクを実行した後、即時タス クを次に進められる ? 非同期実行しているタスクの結果は async_status 経由 で取得が可能。
33.
v2ではループも使える - name: 複数ジョブを同時実行 command:
sleep 60 async: 100 poll: 0 with_sequence: count=5 register: async_jobs - name: ループで全ジョブの終了を待機 async_status: jid: "{{ item.ansible_job_id }}" register: jobs_result with_items: "{{ async_jobs.results }}" until: jobs_result.finished retries: 5 delay: 30
34.
asyncでgceインスタンス作成 - name: 非同期インスタンス作成 gce: instance_names:
vm-name machine_type: g1.small image: coreos async: 1000 poll: 0 register: create_instances_job with_items: [ vm1, vm2, vm3 ] - name: インススタンス作成終了待機 async_status: jid: "{{ item.ansible_job_id }}" register: job_result until: job_result.finished retries: 30 with_items: create_instances_job.results
35.
これを実行すると!
36.
動かない… TASK [非同期インスタンス作成] ok:
[localhost] => (item=vm1) ok: [localhost] => (item=vm2) ok: [localhost] => (item=vm3) TASK [インススタンス作成終了待機] * fatal: [localhost]: FAILED! => {"failed": true, "msg": "ERROR! The conditional check 'job_result.finished' failed. The error was: ERROR! error while evaluating conditional: job_result.finished ({% if job_result.finished %} True {% else %} False {% endif %})"}
37.
? 下記のようなstderrがjobの実行結果ファイルに含まれているのが 原因 ? 出力をJSONとしてパース出来ないためエラー ?
ansibleのバグか? ? stdout、stderrを別ファイルに吐くようにするのが望ましいと 思われる ? モジュールがstderrを吐いていること自体微妙なので、今回はロ グハンドラーを追加したgce-modをplaybook中に含める対応を とった No handlers could be found for logger "libcloud.common.google"
38.
1. まとめ IaaSのインスタンス操作には 非同期処理を上手く使おう!
39.
2. CoreOSのセットアップ① ~Ansible v2での非Pythonモジュール~
40.
Ansibleモジュールの自由度 ? Ansibleの大きな特徴の一つが、どんな言語でも 1. shebang(#!/bin/bashなど)でインタプリタ指 定可能、もしくは実行可能なバイナリに事前コンパ イル可能 2.
JSONで入出力可能 ? 入力: モジュールに与えられた引数 ? 出力: Ansibleが解釈する実行結果 上記条件を満たせば、ansibleモジュールに出来る所です
41.
raw_stat モジュール ? 今回はPyPyインストールの手順中で複数回実行される、 「あるパスが存在するかどうか」を判定するモジュールを ShellScriptで書いてみました ?
statモジュールの入出力を意識して、raw_statとしています が、今回実装しているのは最低限必要な存在チェックのみ ? 因みに、ShellScriptでのJSON操作には jq コマンドが便利 ? 最近のCoreOS(717.0.0以降)ではjqが組み込まれてます
42.
raw_stat #!/bin/bash # WANT_JSON ANSIBLE_VERSION="<<ANSIBLE_VERSION>>" # jqがなかったらエラー if
! type jq >/dev/null 2>&1; then echo "{"failed": true, "msg": "jq not found."}" exit 1 fi # v1の場合は$1に引数ファイルのパスが入る if [[ $ANSIBLE_VERSION == 1.* ]]; then MODULE_COMPLEX_ARGS=$(cat $1) # v2の場合はINCLUDE_ANSIBLE_MODULE_WINDOWS_ARGSを使う else MODULE_COMPLEX_ARGS=$(cat << 'EOF' <<INCLUDE_ANSIBLE_MODULE_JSON_ARGS>> EOF ) fi path=$(echo $MODULE_COMPLEX_ARGS | jq -r '.path') if [ -e $path ]; then exists="true" else exists="false" fi echo $MODULE_COMPLEX_ARGS | jq -r ".changed=false | .stat.exists=$exists"
43.
raw_stat解説 ? 実はAnsible v2では、現在の公式ドキュメントで解説され ている、モジュールへの引数を「hoge=fuga
foo=bar」の 様なスペース区切りファイル経由で渡す方法は使われなく なっています ? 代わりに、モジュールファイル内のリプレイサー文字列を 経由して引数を埋め込む形式を使わなければなりません ? リプレイサー文字列は、template モジュールでの変数 と同じ様なものだと考えてください
44.
リプレイサー文字列 ? <<ANSIBLE_VERSION>> ? 使っているAnsibleのバージョンで置換される ?
v1でも使えるので、v2との互換モジュールで必要 ? <<INCLUDE_ANSIBLE_MODULE_WINDOWS_ARGS>> ? モジュール引数がJSONとして置換される ? 引用符などもエスケープされていないので、heredoc経由で読む様 にするなどの工夫が必要 ? 最新develブランチでは <<INCLUDE_ANSIBLE_MODULE_JSON_ARGS>> も使える(プル リク出したら通りました) ? 他にもあるが、とりあえず非Pythonモジュールで使うのは上記2つ位
45.
v1では WANT_JSON を使おう ?
これもドキュメントでは触れられていないが、v1では、モジュール内 に WANT_JSON と言うコメントを入れると、引数ファイルの形式がス ペース区切りからJSONに代わる ? この形式を使うと、v1とv2での引数処理がJSONの処理として同様に 書ける。 ? そもそも、元のスペース区切り形式だと複雑な文字列処理がとても厄 介(場合によっては対応不能)なので、積極的に WANT_JSON を使っ て行くのが良いと思います hoge=fuga foo=bar #これが {"hoge": "fuga", "foo": "bar"} #こうなる
46.
2. まとめ ? Ansibleでのモジュール実装は言語を問わない ?
v2で非Pythonモジュールに引数を埋め込むには <<INCLUDE_ANSIBLE_MODULE_JSON_ARGS>> を使う ? v1-v2互換モジュールを作るには <<ANSIBLE_VERSION>> で場合分け ? v1でも WANT_JSON を積極的に使っていこう
47.
3. CoreOSのセットアップ② ~Cloud-Con?g with
Ansible~
48.
Cloud-Con?gとは ? IaaS上のインスタンスの各種設定変更やサービス起動な どを起動時に自動で実行するための仕組み ? 設定ファイルはyamlで書く(やったね) ?
CoreOSでは専用の coreos-cloudinit コマンドが使われる #cloud-config coreos: units: - name: "etcd2.service" command: "start" - name: "fleet.service" command: "start"
49.
k8s用のCloud-Con?g ? k8sの公式リポジトリ内で、master用のmaster.yaml、 minion用のnode.yamlが提供されており、ほぼそのまま 使える ? サンプルプレイブックでは、node.yaml中で使うmaster のIPアドレスなどを変数化したテンプレートにしました
50.
Cloud-Con?gの問題点 ? 設定が正常に完了したかを確認するのに別の機構が必要 ? ベンダー毎に設定の渡し方が違う ?
ec2: UserDataにyamlを入れる ? gce: Metadata中のuser-dataキーにyamlを入れる ? idcf: UserDataにyamlを入れられるが2KB制限あり
51.
2碍叠じゃ足りない…
52.
全部Ansibleでやっちゃおう ? 折角Ansibleを使っているんだから、Cloud-Con?gで やっていることもAnsibleで置き換えれば、どんな環境で もセットアップ可能になるはず!
53.
やってみた結果 ? 1つのyamlが10以上の設定ファイルテンプレートに増殖 ? Cloud-Con?g上の設定項目と実設定ファイルの対応は、 coreos-cloudinitのソースを見ないとわからない ?
かなりの苦行な上、プレイブックの見通しも悪くなって しまった
54.
既存の资产はうまく使うべき
55.
結論: いいとこ取り ? 最終的に、ブート完了後にAnsibleでログインしてCloud- Con?g用のyamlをCoreOS内に設置し、Ansibleから coreos-cloudinitを実行する様にした ?
Ansibleがyamlを配置するので、ベンダーの実装を気に する必要なし ? coreos-cloudinit実行後のサービス正常起動確認まで、 まとめて実施可能
56.
master用playbook --- - name: Set
cloud-config.yml. template: src: master.yml dest: /opt/cloud-config.yml register: set_cloud_config - name: Run cloudinit. command: /usr/bin/coreos-cloudinit -from-file=/opt/cloud-config.yml when: set_cloud_config|changed - name: Start required services. service: name: "{{ item.name }}" state: started with_items: - name: generate-serviceaccount-key.service - name: setup-network-environment.service - name: fleet.service - name: flanneld.service - name: docker.service - name: kube-apiserver.service - name: kube-controller-manager.service - name: kube-scheduler.service
57.
3. まとめ ? AnsibleからCloud-Con?gを扱うことで、IaaSベンダー の制約を気にしないで良くなった ?
Ansibleなら動作確認までをワンストップで実施できる ? 「Ansibleだけで」にこだわる必要は無い。どんなツール や手法とも上手く連携出来るのがAnsible
58.
今後やりたいこと ? minionノードのオートスケールをAnsibleから組む ? オートスケール操作はgce系モジュールでは未提供 ?
k8sの操作自体をAnsibleから実施できるようにする ? kubectlかkubernetes-apiを操作するモジュールが必要 ? k8s内のコンテナ内をAnsibleから操作可能にする ? v2で登場したdocker connection plugin を kubectl execコマンドとつなげることができるか
59.
vol. 2に続く?
60.
ご静聴ありがとうございました
61.
Ansible本 年内発表予定
Download