LoginSignup
0
0

More than 1 year has passed since last update.

『Self-managed Kubernetes in GCE』を、Terraform + Ansibleでやってみる

Last updated at Posted at 2021-12-27

Project Calicoのサンプルとして掲載されている Self-managed Kubernetes in Google Compute Engine (GCE) の構成を、Terraform + Ansibleを用いて半自動構築してみる記事です。

Ansibleでk8sクラスタを構築する方法自体は既に多数の記事がありますしkubesprayという素晴らしいツールも準備されていますが、
Raspberry piでのクラスタ構築の記事が多く、GCP上にわざわざ手でクラスタを作成するケースが少なかったので、構築にチャレンジしてみました。

  • (自分も、Raspberry piでの構築をしてみたかったのですが、Raspberry piの在庫切れで手に入らず、、、。)

TL;DR

最終的なコード類はこちら
- HirokiYoshida837/k8s-gcp-tf: Provisioning k8s cluster's infrastructure on GCP with Terraform
- HirokiYoshida837/k8s-kubeadm-ansible: setup k8s cluster's with Ansible nad kubeadm

構成図はこうなります

Frame 1.png

1. Terraformでのインフラ構築

今回はあくまで学習用と割り切り、以下の方針で構築します。

  • 手元の開発用PCから terraform plan -> terraform apply まで行う
  • tfstateの保存も手元のPC内とする
  • Terraform Provisioners は使用せず、インフラ構築の範囲に留める。インスタンス自体のプロビジョニングはAnsibleで行う

Terraformで準備する主なインフラ類は下記のようになります。OSやインスタンスのサイズ・台数、Region等は適宜好みのものとしてください。

  • VPC、VPCサブネット
  • Kubernetesクラスタ用ホスト
    • controller node 1台 (今回はHA構成にはしない)
    • worker node 2台
  • Ansible実行用ホスト
  • Ansible実行用のService Account

これらの方針で作成したterraformファイル類はこちらです。

必要な権限を持ったService Accountを作成し、実行してください。

2. Ansible + kubeadmでのk8sクラスタ構築

今回は以下の方針でクラスタを構築する

  • Ansibleを実行するホストは、GCP内のサーバー(クラスタとは別サブネット)
  • Ansible実行用/対象ホストへのSSH接続はServiceAccountを使う
  • GCPのDynamic Inventory等は使用しない(将来的にはRaspberry Piで同じことがしたかったので、環境によらないPlaybookとしたかった)
  • CRIはDockerを使用する(特に理由はないので、好きなものに変更してもOK。今後を考えるとcri-oの方がよいと思う。)

というわけで作成したPlaybook類はこちらです。

3. アプリケーションを動かしてみる

適当なdeploymentを applyしてサービスをつくって動かせばOK。好きに試してください。

気づき事項・今後の課題

Terraform関連

Ansible関連

  • Terraform provisionersとAnsible

    • 公式ドキュメントにもあるように、provisionersは最終的な手段であり、できるだけ使うべきではない。管理が複雑になりIaCで大切な冪等性が確保しづらい。
    • Provisioners | Terraform by HashiCorp
  • kubesprayの存在

    • 今回のようにAnsibleでk8sクラスタを構築する方法自体は
    • kubespray自体がAnsible + kubeadmでのk8sクラスタ構築になっている。(過去はkubeadmを使用していなかったが、v2.3 以降からは使用するように変更されている)
    • オプションとして指定できる項目も豊富であり、内部のAnsible-Playbookの内容もかなり参考になる。
    • Caclicoでのネットワークはデフォルトではフルメッシュだが、もroute reflectorsを使用した形式も指定可能。
    • CNIもFlannel, Calicoが選択可能、ランタイムも 指定可能。HA構成の指定も可能であり、k8s、Ansible自体にそれなりの知見があれば非常に強力。
    • kubernetes-sigs/kubespray: Deploy a Production Ready Kubernetes Cluster
  • Ansible-Playbookの自動テスト・CI

  • Cloud-initとAnsible、初期プロビジョニングの境界

    • 資料を探していると、k8sクラスタ用のセットアップをcloud-initを用いて実施している人もいた。
    • 今回Ansibleで行った初期プロビジョニング自体はcloud-initでも問題なくできそう。 (kubeadm join以前の設定類)
    • 同じインスタンスを継続して管理したい、冪等性を重視したい、等を考慮しながら、適宜作業内容によってcloud-initとAnsibleを使い分けるのが良いのかもしれない。
    • クラウド環境等であればPacker等で初期イメージを作成して使い回すほうが良さそうにはみえる。workerのkubeletアップデートが必要になった場合、既存のインスタンスをアップデートするのではなく、新しいイメージを作成し、そこから起動 -> kubeadm join -> 古いインスタンスを停止、とすれば比較的安全にできそう。イメージ自体を使い回せるので事前検証も十分にできるはず。
  • shell/command moduleが必要になる場合の冪等性の確保

    • 参考にした資料の中には、各種設定の変更などを sed を使ってゴリゴリにやってる人もいた。
    • 何度Ansible-Playbookを実行しても結果が変わらないようにする工夫が必要。
    • kubeadmの操作自体はshell/commandモジュールから操作する必要がありそうなので、工夫しないと冪等性(厳密には違う気がするけど)が確保できない。

kubernetes関連

  • kubeadmでのクラスタ構築は意外と簡単

    • 手順にしたがってそのままやるだけなら、ある程度の知識があれば超簡単。k8s公式にもドキュメントがある。
    • kubernetesの各コンポーネントや、周辺環境についての知識はある程度得られるはず。
    • 実はminikube も内部ではkubeadmを使用している。
    • より詳しく学びたい、より愛着を持ったクラスタにしたいのであれば、kubernetes-the-hard-wayをやってみよう。
  • クラスタ自体の管理・アップグレードが厳しそう

    • 各種のトラブルシューティング必要になるので、手ですべて管理するのは厳しそう。(経験しないとトラブルシューティングはできるようにならないと思うが、、、)
    • どんなものに対しても言えることだが、仮に業務で使うことになる場合、十分に調査してから、構成を検討し、根気よくメンテナンス・情報収集していくことが大事そう。
    • Kubeadmによるクラスタアップグレード・その光と闇 - Speaker Deck
  • アプリケーションのデプロイ、管理

    • 今回はサンプルレベルのアプリケーションのデプロイで終わった。
    • 早く自宅でKubernetesクラスタを構築してHelmの使用、ArgoCDの導入までやってウキウキになりたい。
  • 構築したkubernetesクラスタ自体の管理や監視はどうするのか

    • 複数のk8sクラスタがお互いに監視しあう構成の記事を見かけて、非常に面白かった。
    • セルフホスティングなので管理・監視の手間が増えることを考えると、マネージド・サービスの力強さを改めて感じる。
  • HA構成について

    • 今回はシングルControllerなので、明らかに単一障害点。
    • controller はHA構成にしても良かったと思う。この場合は Hostの台数を奇数(etcdの分散合意を機能させるため)にするべき、など色々考慮が必要そう。

GCP関連

  • Ansibleを実行するホストから他のホストへどう接続するかにかなり悩んだ。

    • GCPのコンソール画面上から、自分のアカウントでSSH -> 他ホストにSSHでjumpみたいなことを試したりしたが、エラーが出ることがありハマった。
    • コンソール画面から入るときにつかうSSHキーの期限は5分ほどなので、一時的に他のホストにはいれてしまうのが問題だった。最終的に、プロジェクトのsshキーを使用しないように設定変更してSAのOS Loginで接続するようにした。この辺りがややこしかった。インスタンス自体に権限を与えたほうが良かったもしれない。この辺りは詳しい人に相談してみたい。
    • Cloud-initでユーザ作成などをやればよかったかも。
  • SAの鍵を GCP Secret Manager にいれてTerraform実行ホストから渡す、みたいなことをしてみた。

    • 適切なやり方なのかは十分に調べられていない。

まとめ

特に真新しいことをしたわけではかったが、今までほぼTerraform、Ansibleには触れてこなかったが、今回、一から自分で実践してみることで非常に勉強になりました。
特にAnsible-Playbookの作成は、ちょうどよい難易度であり、 (より凝ったものにしようとすれば、いくらでもできる。kubesprayがあるので、そこまでやるか感はあるかも) Kubesprayなどの中身みて、何をしようとしているのかがある程度把握できるようになったのも大きいです。

また、k8sに関しても、内部構成や実装について興味を持つ機会となり、コレをきっかけに知人と勉強会などを開いて輪読やハンズオンなどをやってみています。

年末年始に暇な方はぜひお手製k8sクラスタを構築してニンマリしてみてください。

参考資料

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0