using docker infrastructure
TRANSCRIPT
自己紹介
• 丹羽 絢也(にわ じゅんや) – 3年目
• 業務 – IIJ GIO ストレージ&アナリシスサービス – アナリシス部分の開発・運用
• APIサーバ • クラスタ管理サーバ • コンテナ内で動作するアプリケーション
– Hive + Hadoop • DB(MySQL + MHA)
Dockerインフラの活用
• Dockerって何? • Linux Container • Linux Namespace • Cgroup • オーケストレーション
Dockerインフラを使ったサービス開発のお話
Dockerインフラの事は hFp://www.slideshare.net/maebashi/dockeriij
storage API
ストレージ!ノード
analysis API
ユーザー
data
query 計算!ノード
data data data
IIJ GIOストレージ&アナリシスサービス
container
IIJ GIOストレージ&アナリシスサービス
• 顧客の分離方式 – Hive + Hadoopは複数ホストで分散処理 – 複数ホストを複数のユーザで共有 – 単一クラスタの共有
• セキュリティ – 顧客毎にクラスタ化
• KVM? – オーバースペック – オーバーヘッド
• – シンプル – プロセスなので、オーバーヘッドが小さい
Dockerインフラ
• HadoopクラスタをDockerで構成したい – Dockerコンテナオーケストレーション
• 複数ホストで多数のコンテナを管理 • 複数ホストをまたいだネットワークの構成 • クラスタに属するコンテナ数の増減を素早く実施
– Docker Swarm – Kubernetes – Nomad(?)
• Dockerコンテナオーケストレーションツール – doma(docker manager) – 独自開発
Dockerインフラ • doma
– master/slave型 • HTTP REST API
– クラスタリソース確保 – 設定ファイルの投入 – ネットワークの設定(通信の許可) – 起動 – 停止 – 更新(増減) – リソース解放 – 情報取得 slave slave slave
master
container container
container container container
container container container
クラスタ1
クラスタ2
クラスタ3
空き
slave slave slave
master
container container
container container container
container container container
物理ホスト
• クラスタ管理 – 作成 – コンテナの増減 – 破棄 – 情報
• ホスト名等 – 監視
• アプリレイヤ
全体の構成(絵)
slave slave slave
master
container container
container container container
container container container
Analysis API
物理ホスト
操作
空き
DB
クラスタ1
クラスタ2
クラスタ3
クエリ クラスタ管理
クエリ
監視
DB
Dockerインフラ活用における課題
• ライフサイクル管理 – 設定
• 環境依存の設定やクラスタ毎に変化する設定
– 起動/監視 • コンテナが起動 != アプリから見て利用可能 • 故障検知
• 運用
– アプリケーションの更新
Dockerインフラ活用における課題
• ライフサイクル管理 – 設定
• 環境依存の設定やクラスタ毎に変化する設定
– 起動/監視 • コンテナが起動 != アプリから見て利用可能 • 故障検知
• 運用
– アプリケーションの更新
ライフサイクル管理:設定
• コンテナ内の設定 – 環境毎に変化(APIサーバのURL) – クラスタ毎に変化(コンテナのホスト名/アドレス等)
image
api.dev.example.com api.prd.example.com
開発環境 本番環境
Container(192.0.2.2) Container(10.0.0.2)
Container(192.0.2.1) Container(10.0.0.1)
ライフサイクル管理:設定
• 課題 – 環境やクラスタによって変化する設定をどう反映するか? – 外から全てのアプリ設定ファイルをテンプレートから作成?
• コンテナ内の改修によってクラスタ管理サーバのテンプレート編集が必要に
• 現在 – 変化する項目のみをJSONでコンテナに設置 – Dockerイメージ内でアプリ固有の設定ファイルを作成
• Ruby製スクリプト(chef-‐soloみたいなやつ) • コンテナ起動時に自動呼出
– JSON例
• アプリ設定の追加/変更はDockerイメージの更新で行う事が可能に • 変化項目が増える場合はJSONに追加していけばOK
{ "storage": {"endpoint": "storage.dev.example.com"}, "cluster": {"hosts": [ "c1cluster1", "c2cluster1"]}, "instance": { "memory": 8, "logical_cores": 4} }
Dockerインフラ活用における課題
• ライフサイクル管理 – 設定
• 環境依存の設定やクラスタ毎に変化する設定
– 起動/監視 • コンテナが起動 != アプリから見て利用可能 • 故障検知
• 運用
– アプリケーションの更新
ライフサイクル管理:起動/監視
• 起動時間 – コンテナの起動は数秒 – アプリケーション
• Hive/Hadoop = Java • JVMの起動に1分
• コンテナの起動 != 利用可能 – 利用可能になったかどうかを監視する必要
ライフサイクル管理:起動/監視
• 監視 – 多数のクラスタ/動的に構成が変わる – アプリ影響の有るDockerインフラ側の故障
アプリレイヤ Docker インフラレイヤ
サービス影響の有る故障の監視
slave故障等 OOM/過負荷等
コンテナの故障等
ライフサイクル管理:起動/監視
• 監視ワーカー(Java) – Executorフレームワーク
• マルチスレッド • 定期実行
– Hive / Hadoopの機能を利用して監視 • クラスタの状態 – 10状態 – 総遷移数 46
– 初期化 -‐> 起動/異常 – 起動 -‐> 正常/異常 – 正常 -‐> 異常/起動/停止 – …
ライフサイクル管理:起動/監視
• 状態一覧 – 初期化 クラスタの情報をDBに保存 – 停止 domaに対する設定が完了 – 起動 アプリの起動中 – 正常 – 異常 アプリの故障 – 一部異常 処理継続可能なアプリの故障 – 再起動 再起動処理の排他用 – 解放中 非同期な解放処理のための状態 – 解放済 – メンテナンス
• 複雑化 – APIを介したクラスタ管理を提供すると複雑に
• 同時に叩かれた場合への対応 • レスポンス時間の短縮
– 力技
Dockerインフラ活用における課題
• ライフサイクル管理 – 設定
• 環境依存の設定やクラスタ毎に変化する設定
– 起動/監視 • コンテナが起動 != アプリから見て利用可能 • 故障検知
• 運用
– アプリケーションの更新
運用
• コンテナ内アプリケーションの更新 – 必要な作業
1. Dockerfileでイメージを更新 2. イメージの配布 3. コンテナの停止 4. 新イメージを用いた起動
• 現状 – クエリが無い時に手動実行
• 処理の有無を気にせず更新するには? – 同じ性能のクラスタを新イメージで立てる
1. 新規クエリは全て新クラスタに向ける 2. 実行中の処理が終わったら旧クラスタを落とす
– Graceful Shutdown / Blue-‐Green Deployment – 安定するなら自動化も可能
• ジレンマ – 状態が増える – リソース消費が2倍
運用
旧イメージ
新イメージ
メンテナンス開始 新規クエリ クエリ完了を検知、 旧クラスタ解放
クエリ
時間
まとめ
• Dockerインフラを活用してサービスを開発した – アプリケーション実行環境のコード化
• Githubでのインフラ管理 – 環境が異なっても同じコンテナイメージを利用可能
• 結果として環境依存を排除 • immutable container
– データは外部に持たせる – ログはfluentdで外に蓄積
• 使ってみて思った事
– アプリレイヤでの監視運用ベストプラクティス化が必要 • 複雑化
– 専用フレームワークがあっても良いのでは? • Consul、Kubernetes、Nomad • 良い所を取り入れていきたい
サービス開発サイクル
• Dockerイメージの作成 – initスクリプトの作成
• コンテナ起動時に呼び出される • 必要なサービスを起動
– Dockerfile • initスクリプトの設置 • パッケージのインストール
• イメージの配布 – 起動を高速化するため予め全ホストに配布
• Dockerインフラに起動を依頼(APIサーバ) – リソースの予約 – 設定ファイルの配布 – 通信の許可(ストレージ API、metastore) – 起動