OSSのAI開発基盤KAMONOHASHIのデプロイツールの解説記事です。
インフラ部分
kubespray + ansibleを使用
kubesprayとは
- ansibleベースのKubernetes自動構築ツール
- kubeadmの構築に加え、手動で行う必要のあるカスタマイズをいろいろやってくれる
- masterをinventoryにマシン名複数台書いておけば勝手に冗長化設定もろもろやってくれる
- ipvsロードバランス構築
- ...etc
- ansibleのgroup_varsやextra_varsで構築内容をカスタマイズできる
- DNSの設定
- dockerのオプション
- insecure-registry
- http proxy
- ...etc
kubesprayにansibleで独自処理を追加
- kubesprayをimportして自分のansible playbookから呼び出す
- デフォルトで書き換えたい内容はあらかじめgroup_varsに書いておく
- 自分のansible playbookでは主に次のことを行っている
- Minio・NFSの構築
- nvidia-dockerのインストール
アプリ部分
Helmを使用
Helmとは
- k8sのyaml群をテンプレート化
- 設定箇所を変数化しておいて、構築時には変数のみ指定すればKAMONOHASHIが構築できるようにする
- 複数のyamlをまとめて置ける。バージョン管理できる
- デプロイしたyaml群のバージョン管理・切り戻し
- 複数のyamlをまとめたバージョン管理ができる
- デプロイの履歴が取れる
- デプロイの切り戻しができる
- 複数のyamlをまとめたバージョン管理ができる
上記だけだとk8sなどの知識がない人にデプロイのハードルが高いため、
決め打ちの構成で設定してkubespray, helm実行するbashスクリプトを提供しているdeploy-basic-cluster.sh
このスクリプトを使わずにansible,Helmの設定ファイルを手で書けば自由にカスタマイズできる。
たぶんHelmだけを使えばGKEなどを利用することもできるが試したことはない。
ツールを使う理由
- 構築・移行が頻繁のため自動化したい
- マシン変更、IP変更、新規構築で動くかのテスト、客先、・・・
- kubespray: 当時オンプレはkubeadmかkubesprayぐらい。nvidia-dockerの対応も必要なので、kubespray+ansibleとした。
- 今ではkubesprayでnvidia-dockerも入れられそうだが未検証
- Helm: 当時kustomizeがなかったため、一番メジャーなHelmにした
使ってみた感想
- kubespray+ansibleは変数の上書きや変数中で別の変数の参照ができるので挙動をカスタマイズしやすい。変数を変数を使って組み立てられる。
- 例えば、dockerのセグメント変更を可能にするために自作のdocker_bipの変数を追加している。それをkubesprayに組み込むのには、kubesprayのdocker_optionsh変数を次のようにgroup_varsで上書きしている。ユーザーは設定ファイル(extra_vars)にdocker_bipだけ定義すればよい。
デプロイツール側
docker_options: >-
{%- if docker_bip is defined %}
--bip={{ docker_bip }}
{%- endif -%}
{%- if docker_insecure_registries is defined %}
{{ docker_insecure_registries | map('regex_replace', '^(.*)$', '--insecure-registry=\1' ) | list | join(' ') }}
{%- endif %}
--live-restore --graph={{ docker_daemon_graph }} {{ docker_log_opts }}
設定ファイルに書く内容
docker_bip: 192.168.1.1
- 一方Helmは変数を変数を使って組み立てるということができない(変数中で変数を参照できない)。変数の上書き自体はできるが、yamlのネストが深い場合にそのyamlのオブジェクト構造ごと上書きしないといけない. kubespray+ansibleでやっているようなデプロイツールで組み立て処理を書いておき、ユーザーの設定項目を簡単にするということができない
ingressのHelmチャートの変数上書き。ユーザーの設定ファイルでネスト構造を丸ごとコピーしないと上書きできない
ingress:
controller:
nodeSelector:
kubernetes.io/hostname: "${INGRESS_NODE}"
service:
externalIPs:
- "${INGRESS_NODE_IP}"
- kubesprayは最新のk8sの機能をいろいろ取り込んでいてかつ勝手にやってくれる。ありがたい反面、デフォルトの構築内容が変わるので、kubesprayのバージョンアップでkamonohashiが動かないことも(k8sの新機能のバグ?)。バージョンアップの際に明示的に古いバージョンと同じ構成にするオプションをkubesprayに入れたりしている。
- Helmは書き方の学習コストが高いかつかゆいところに手が届かない(変数の組み立てなど)のであまり気に入っていない