EKS Kubernetes クラスタ作成

それでは、ようやく Kubernetes on EKS を構築していこうと思います。一気に進めるとグチャグチャになりそうなので、こまめに分けていくよう意識していきます。

今回は、Kubernetes のクラスタを触れるようにするとこまでで、実際には何も動かないですが大事なベースです。



概要

Kubernetes on EKS を Terraform 一本勝負でゴリゴリ書いていきます。EKS も Kubernetes も Helm も全部です。あとは LaunchTemplate の user data などのいくつかのちょっとした処理でシェルスクリプトを使う程度です。

Terraform のバージョンは v0.12.0 以降を想定しており、自分の環境だと terraform も provider も常に最新にしていくよう意識しています。特に kubernetes provider は発展途上なので、古いと使えない項目があったりするので、最新にするのを推奨です。

構築手順については、要所に説明は入れていきますが、基本的な手順や解説はちゃんと公式っぽいところを見たほうがよいので、リンク貼ってくので合わせて参考にお願いします。


開発準備

Terraform, AWS CLI

以前の下記記事を参考にしてください。
  • AWSで学ぶコンテナの基礎 (1) Docker | 外道父の匠

  • Terraform のバージョンは、CHANGELOGをみて、Unreleased ではない最新のものに更新していくとよいです。

    provider は普段は aws とかしか使わないかもですが、kubernetes や helm なども出てくるので、ちょいちょい最新に更新していくのがよいです。


    kubectl

    Kubernetesを操作するためのコマンドです。公式ドキュメントは
  • Install and Set Up kubectl

  • まぁ上記リンク先に書いてあるのですが……私の場合はLinuxなのでこうじゃ。


    helm

    あまり直に操作することはないですが、あると安心するんじゃポルナレフ。
  • Installing Helm

  • こちらもこうじゃ。



    IAM Role 作成

    ここからリソースを作成していくにあたって、基本的な公式手順は下記にあるのですが
  • AWS マネジメントコンソール の開始方法 – Amazon EKS

  • 細かい説明はそちらを見てほしいものの、ぶっちゃけ管理画面とか eksctl からやっても理解しづらいです。Terraform などでリソース1つ1つを分解して関連付けを見ていった方が、圧倒的早さで身につくと思います。

    ──という感じで、早速2つRoleを作ります。

    Control Plane用

    まずはEKSそのものであるControl Plane用のRoleを作成します。まずはRole本体を作成し、

    次に既存Policyを割り当てます。ちょいと local変数 使っちゃってますが、もう1つのNodeのポリシーが多くなったので、合わせてまとめてしまいました。

    最後にカスタムポリシーです。構築中になにか足りなくなって、既存ポリシーに無いものはココに入れていくことにしましょう。


    Worker Node用

    こちらは、Pod が載るノードである EC2インスタンスに割り当てる profile と、kubernetesの方で指定する role になります。Pod が持つ権限もこれと同等になります。

    まずはRole本体を作成し、

    EC2にも使うので profile を作り、

    既存ポリシーを割り当てるのですが、こちらは私がやりたいことを実現するためにいっぱい追加しちゃってるので、最終的には真面目に精査してください。

    で、最後にお好みスパイスで、SSMなど。


    セキュリティグループ作成

    Control Plane は開発者の kubectl や WorkerNode から注文を受けるし、WorkerNode はクラスタとしての通信や Pod間の通信が行き来するので色々開けることになります。非常に大雑把に開けていますが、実は公式+α したくらいの内容です。

    ポイントは、クラスタ用通信として443番と、Ephemeral port 範囲がTCP/UDP 全部、Private内で許容されてれば良いって感じです。もっとキッチリ締めたい場合でも、最初は大きくしておいた方が構築中に無駄に詰まらないので、精査するのは後回しにしましょう。

    公式はこの辺ですね
  • クラスターセキュリティグループの考慮事項

  • Control Plane用

    こちらは443番があればって感じですが、Private Network だけじゃなく、開発環境のために自分とこ管理のGlobal Networkも追加してます。


    WorkerNode用

    こっち、色々開けてて気持ち悪いかもなので、言い訳しておきます。公式の推奨+独自判断の内容になっているのですが、重複を排除して記述すると公式部分がなにで独自がどれだかわかりづらくなるので、あえて重複無視してガツンと置いています。

    1つ重要な追加点としては、UDP を追加したところです。もっというと、UDP:53 だけでも良いです。これは、EKSクラスタを作成して、1つ目のNodeを起動した時点で、EKSが coredns というPodを2つ立ち上げるのですが、名前の通り普通にDNSサーバーとしてUDP:53 を使用します。

    ということは、1Node内でのPod間通信ならセキュリティグループ関係なく通るのですが、複数NodeでのNode間Pod通信になると、Nodeのセキュリティグループの判定を通ることになるので、UDPがないと名前解決できない問題に引っかかることになります(引っかかった:-)


    EKS用タグ

    ↑のリソースで出てきましたが、怪しげなキーのタグがあります。

    これは他のリソースでもつけるモノがあるのですが、EKSがKubernetesのリソースとして使うというマーキング、もしくは使って良いと判断するための目印になります。

    例えば、AutoscalingGroup 経由で EC2 にもつけるのですが、それによって EC2 リストから、このタグがついているインスタンスだけを Node リストに自動的に追加します。

    他に、VPC や subnet はここでは作成用コードを記述していませんが、EKSクラスタを作成した時点で、指定したVPC と subnet には自動的に同じキーのタグが付与されます。
  • クラスター VPC に関する考慮事項

  • そのため、Terraform 外からリソース操作されたことになるので、クラスタ作成後に plan を打つと、そのEKS用タグを削除しようとします。それを回避するために、aws_vpc や aws_subnet に無視コードを入れるのですが、

    残念ながら ignore_changes の配列内の値では変数を利用できないので、こういうコードが書けず、ちょっと tags の扱いがイマイチな雰囲気になります。



    EKSクラスタ作成

    ようやく、EKSリソースを作成します。いわゆる Control Plane という中心部ですが、EKSがなんとかしてくれるのはコレだけです。コレだけって言ったら怒られそうですが、それ以外は全部自分で頑張るのです、それがK8s。

    ロググループ

    私は良い子ちゃんなので、CloudWatch LogGroupを先に作っちゃいます。EKSも自動で作ってくれますが、それだと無期限なので、その辺は Lambda の扱いと一緒。


    クラスタ

    ここまで作成した地味リソースを指定して作成します。完了までに10分前後かかります。ログの種類はもっとあるのですが、あまりに意味ないログを吐き出す項目は削除しています。

    作成が完了したら、EKS管理画面でも確認したり、VPC や subnet に変なタグが付いたことを確認してきましょう。


    Kubernetes に触る準備

    Terraformでのリソース作成は今回はいったんこれで終わりにして、手動でKubernetesちゃんと戯れる準備をします。kubectl で作業するには、IAM User とクラスタ接続用の情報が必要になります。

    IAM User

    ちょっとここ曲者なのですが、EKS Kubernetes を扱えるのは、最初はEKSクラスタを実際に作成した User のみとなっています。つまり今回の場合、terraform apply を実行した IAM User …… 例えば “terraform” とかですかね。おそらく全権限持っちゃってるでしょう。

    他の User を使いたい、とかいう話はこちらにあるのですが、
  • クラスターのユーザーまたは IAM ロールの管理

  • 長くなるので今回は初期ユーザーでの実行ということでいきます。鍵を export するなり、aws configure で ~/.aws/credentials に書かれてるとして次へいきます。

    クラスタ情報取得

    クラスタから接続用の情報を引っ張ってきて保存します。eks:UpdateKubeconfig のような権限はなくて、eks:DescribeCluster があれば取得できます。


    kubectl の始まりだ

    リソースは全て Terraform で管理するとはいえ、開発にはゴリゴリ kubectl を使っていくことになります。まだNodeもPodもないので、クラスタの情報だけ確認してティータイムにしましょう。

    もしエラーが出たら、IAM Userの権限や鍵、セキュリティグループあたりが原因なので、なんとかしてください。



    ね、たいへんでしょ?