Upgrade to Pro — share decks privately, control downloads, hide ads and more …

地雷を避けながら進むEKS - 俺の屍を超えていけ -

地雷を避けながら進むEKS - 俺の屍を超えていけ -

2021年3月11日〜12日で開催の「CloudNative Days Spring 2021 Online」における発表資料です。

3月12日 15:20-16:00 Track B
「地雷を避けながら進むEKS - 俺の屍を超えていけ -」
https://event.cloudnativedays.jp/cndo2021/talks/491

ーーー

サクッとK8sクラスターを作れるAmazon Elastic Kubernetes Service(以下EKS)ですが、ちょっと真面目に使おうとすると色々と「あるぇ?」ってなることにもポツポツ出くわします。

今回は、EKSが持つ機能もちょこちょこ紹介しつつ、地雷っぽいところ(私が踏み抜いたもの)とかTipsなんかをお話しします。主に初級〜中級あたりの視聴者をターゲットにしています。

これからちょっと本気出してEKS使っていくかぁ!っていう方のお役に立てば幸いです。

大丈夫!その地雷、僕が踏んどいたよ!

Masataka Tsukamoto

March 02, 2021
Tweet

More Decks by Masataka Tsukamoto

Other Decks in Technology

Transcript

  1. 2 • 名前︓ 塚本 正隆 • 通称︓ _・) つかまん (@tsukaman)

    • 会社︓ ⽇本ヒューレット・パッカード株式会社 • 所属︓ HPE GreenLake Hybrid Cloud Global Competency Center • 役割︓ 打楽器、Cloud Solution Architect • 書籍︓ Ansible実践ガイド 第3版、Raspberry Pi〔実⽤〕⼊⾨ • 好き︓ せがれいじり、ガジェットIYH、眼鏡、楽しいことをする。 • 参加︓ Cloud Native Days 実⾏委員会 • 最近︓ またダイエットしています。毎⽇体重Tweetしてるよ。 誰?
  2. これから話すこと • EKSのおさらい – EKSの特徴 – eksctlコマンド – コマンドの実⾏環境 –

    Managed NodeGroupの仕組み – K8s RBACとIAMの関係 – AWSサービスのPV利⽤ – EKSのPod Network – EKSでELBを使う • 踏み抜いた地雷のおもひで – レベル︓ (遭遇度︓⾼) • Cloud9でk8sの認証ができない問題 • VPC CNIとIP枯渇問題 – レベル︓ (遭遇度︓中) • CSIドライバー対応バージョン間違い問題 • Managed NodeGroupのTaint問題 – レベル︓ (遭遇度︓低) • aws-node起動しない問題 4
  3. EKSのおさらい ま ぁ 、 み ん な 知 っ て

    る か も し れ な い け ど 。 5
  4. Amazon EKSの特徴 Amazon Elastic Kubernetes Service 7 • AWSが提供するKubernetes準拠のマネージドK8sサービス –

    Distro、Anyware(今年提供予定)等、提供形態もモリモリ拡⼤中 – マネージド型ワーカーノード(Managed NodeGroup)も利⽤可能 • ⾃⼰管理型ワーカーノードやFargateを組み合わての利⽤もできる • 既存の多くのAWSサービスと⾼度に連携︕ – EC2、IAM、VPC、EFS、CloudWatch、EKSなどのAWSサービスと直接連携 – その他の多くのAWSサービスを組み合わせて効率よく運⽤ができる – すでにAWSの運⽤経験がある組織へのK8s導⼊に最適︕ • 他のAWSサービス同様、APIを介して様々な⼿法での管理が可能 – AWS Management Console、AWS CLI、eksctl、Terraform、Ansible など
  5. eksctl コマンド と っ て も 便 利 。 な

    る ほ ど パ ワ フ ル 。 8
  6. eksctlコマンド AWS公式のEKS管理CLIツール 9 • Weaveworks社がスポンサーしているOSSツール – https://eksctl.io / https://github.com/weaveworks/eksctl –

    AWSのEKSドキュメント内でも案内される公式なCLIツール • https://docs.aws.amazon.com/eks/latest/userguide/getting-started-eksctl.html – シンプルでお⼿軽にEKS K8sクラスターを構築/管理できる • AWS CloudFormationと連携しEKSクラスター構築のスタックを作成する • オプションまたは設定ファイル(YAML)を利⽤して複雑な構成の管理も可能 • VPCやIAMなどの必要となる各種AWSリソースも同時に作成できる
  7. eksctlコマンド AWS公式のEKS管理CLIツール 10 • 例えば、こんな使い⽅ができる – コマンド⼀発でVPCも含めてのESK K8sクラスターを⾃動構成 • 削除時は

    “delete” のサブコマンドで⼀発削除もできる – 構成定義ファイルを読み込ませてESK K8sクラスターを⾃動構成 • Config file schema: https://eksctl.io/usage/schema/ – クラスターのK8sバージョンアップデート $ eksctl create cluster $ eksctl create cluster -f cluster.yaml $ eksctl upgrade cluster --name demo-cluster --version=1.19
  8. コマンドの 実⾏環境 a w s / e k s c

    t l コ マ ン ド 、 ど こ で 実 ⾏ す る ︖ 11
  9. CLIコマンドどこで実⾏する︖ ローカル︖EC2マシン︖それとも・・・︖ 12 • awsやeksctlなどのCLIコマンドをどこで実⾏するか︖ – ローカルホスト(⾃分のノートPCなど) • IAMのAccess KeyとSecret

    Access Keyを利⽤する • AWS APIはインターネット公開されているPublic Endpointを利⽤ – VPC内のEC2インスタンス • 安全な経路を経由してSSHログイン • Systems Managerを利⽤してブラウザ上からログイン • VPC Private Linkを利⽤することでPrivate なAWS APIを利⽤可能
  10. CLIコマンドどこで実⾏する︖ ローカル︖EC2マシン︖それとも・・・︖ 13 • awsやeksctlなどのCLIコマンドをどこで実⾏するか︖ – ローカルホスト(⾃分のノートPCなど) • IAMのAccess KeyとSecret

    Access Keyを利⽤する • AWS APIはインターネット公開されているPublic Endpointを利⽤ – VPC内のEC2インスタンス • 安全な経路を経由してSSHログイン • Systems Managerを利⽤してブラウザ上からログイン • VPC Private Linkを利⽤することでPrivate なAWS APIを利⽤可能 セキュリティルール的にも 使わせたくない(使えない)ケースが多い コマンド実⾏環境が欲しいだけなのに EC2インスタンス(仮想サーバ)運⽤に 様々な管理コストが発⽣してしまう・・・
  11. CLIコマンドどこで実⾏する︖ ローカル︖EC2マシン︖それとも・・・︖ 14 • awsやeksctlなどのCLIコマンドをどこで実⾏するか︖ – ローカルホスト(⾃分のノートPCなど) • IAMのAccess KeyとSecret

    Access Keyを利⽤する • AWS APIはインターネット公開されているPublic Endpointを利⽤ – VPC内のEC2インスタンス • 安全な経路を経由してSSHログイン • Systems Managerを利⽤してブラウザ上からログイン • VPC Private Linkを利⽤することでPrivate なAWS APIを利⽤可能 セキュリティルール的にも 使わせたくない(使えない)ケースが多い コマンド実⾏環境が欲しいだけなのに EC2インスタンス(仮想サーバ)運⽤に 様々な管理コストが発⽣してしまう・・・ !"#
  12. CLIコマンドどこで実⾏する︖ eksctlの実⾏に「AWS Cloud9」 15 • AWS Cloud9 – Cloud9はブラウザ内で利⽤化な統合開発環境 •

    AWS外のサーバにインストールして利⽤もできる • Terminalも同梱されているのでShellが利⽤可能 – AWS上では実体としてEC2インスタンスが⾃動構成される • 作成時にアクセス⽅法、Instance Type、VPC/Subnet等を指定可能 • 利⽤量はEC2インスタンスの利⽤料のみ – 作成後は⾃動起動されるが利⽤がないと⾃動停⽌(待機時間は設定可)
  13. CLIコマンドどこで実⾏する︖ eksctlの実⾏に「AWS Cloud9」 16 • AWS Cloud9 – eksctlの実⾏環境として適している理由 •

    特別な設定をしなければ外部からログインができない – 実体がEC2なので設定そのものは⾃由度が⾼い点は注意が必要 • Cloud9に接続したユーザのIAM権限が⾃動で引き継がれる – 設定を変更をすれば、EC2 Role(Profile)も利⽤可能 • 環境を他ユーザに共有して使わせることも可能 – 管理者が準備した環境をユーザに使わせることなども可能 • 必要な時だけ作成して、作業後に削除という運⽤がしやすい
  14. CLIコマンドどこで実⾏する︖ AWS CLIの実⾏に「AWS CloudShell」 19 • AWS CloudShell – 2020年にリリースされた新機能

    • ⽐較的安定してるが機能は必要最低限(その分シンプル) – AWS Management Consoleから簡単にShell環境を起動できる︕ • AWS管理のPrivateネットワーク上に環境(AL2)がデプロイ • 同⼀Regionに10個まで同時にShellを起動できる • 1分程度で⾼速起動(20分操作しないと⾃動で停⽌) • 1GB分の永続化可能なディスクスペースも付くが利⽤は無料︕ • パッケージの追加インストールも可能
  15. CLIコマンドどこで実⾏する︖ AWS CLIの実⾏に「AWS CloudShell」 20 • AWS CloudShell – AWS

    CLIの実⾏環境として適している理由 • 外部からログインができない – Cloud9と違ってほとんどカスタマイズもできない • CloudShellを起動したユーザのIAM権限が⾃動で引き継がれる • 必要な時に⽐較的⾼速に環境を⽴ち上げて利⽤することができる • 利⽤終了後は⾃動で環境が終了する
  16. Managed NodeGroup の仕組み ど ん な 管 理 が さ

    れ ち ゃ っ て る の か 理 解 し よ う 24
  17. あなたのPodはどこで動く︖ 3つのNode Typeをおさらい 25 • Maneged Node Group – デプロイやライフサイクル管理が⾃動化されたマネージドワーカーノード

    – ワーカーノード⾃体はEC2 Auto Scaling Group配下のインスタンスとして作成 – 通常のEC2利⽤料の他は特に追加費⽤なし • Self-Managed Node – ユーザ⾃⾝が管理するワーカーノード – AWS OutpostやAWS Inferentiaなど、他のタイプよりも利⽤可能なサービスや機能が多い – 柔軟性が⾼い分、管理コストはどうしても掛かってしまう • AWS Fargate – ワーカーノードの管理が不要なサーバーレスなコンピュートサービス – 1 Podにつき1 Nodeがデプロイされるような動作となる – ノードが無いので、DaemonSetが使えない、HostPortが使えないなどの制約も多い • 参考︓ https://docs.aws.amazon.com/eks/latest/userguide/eks-compute.html
  18. Managed Node Groupの仕組み 特徴と制限を抑えておこう 26 • 様々なデプロイ⽅法が⽤意されている – マネジメントコンソール、AWS CLI、eksctl等、主要ツールが対応

    • eksctlの場合の作成⽅法 – 構成定義ファイルを利⽤して、さらに詳細な指定も可能 • https://eksctl.io/usage/eks-managed-nodes/ • https://eksctl.io/usage/schema/#managedNodeGroups • Self-Managed Nodeと⽐較して対応できない機能などもある • https://eksctl.io/usage/eks-managed-nodes/#feature-parity-with-unmanaged-nodegroups • 例えば、Managed Node Groupのワーカーノードに⾃動でTaintを付加できない 等 $ eksctl create nodegroup --cluster=cluster名 --region=Region名
  19. Managed Node Groupの仕組み 特徴と制限を抑えておこう 27 • 使⽤上での注意点 – ノードのヘルスチェックはEC2のものを利⽤する •

    EC2ヘルスチェックに失敗 → Auto Scaling Group(ASG)の働きで再⽣成 – 例えば・・・ – 確認すべきログが広範囲に及ぶ可能性がある • EKS(K8s)上のログだけでは状況が分かりにくい → EC2(ASG)等も確認 – ノード再⽣成による影響度を把握していく必要がある • 直接Podオブジェクトとして配置されている場合、ノードと共に削除される • あとから⼿動でNodeに対して⾏った設定が巻き戻ってしまう 1. メンテナンスとしてEC2インスタンスを停⽌ 2. EC2ヘルスチェックに失敗 → ASGが当該EC2インスタンスを削除 3. ASGが新しいEC2インスタンスを作成
  20. K8s RBACと IAMの関係 k 8 s の 権 限 管

    理 、 E K S だ と ど う な っ て る ︖ 28
  21. K8s RBACとIAMの関係 EKSにおける認証認可の仕組みを理解しよう 29 • EKS K8sクラスターの認証認可はIAMと連携する形で構成される – https://docs.aws.amazon.com/eks/latest/userguide/managing-auth.html –

    K8sクラスター構築時のIAMユーザ/ロールがK8s管理者( system:masters )として設定される – 次のAWS CLIコマンドによりkubeconfigを更新できる – AWS CLIを実⾏しているIAMユーザ/ロールに対してのRBAC定義を元にK8sを操作 $ aws eks --region リージョン名 update-kubeconfig --name クラスター名
  22. K8s RBACとIAMの関係 EKSにおける認証認可の仕組みを理解しよう 30 • 他のIAMユーザ/ロールに対してRBAC定義を追加したい場合 – ”aws-auth” のConfigMapに定義を追記する •

    https://docs.aws.amazon.com/eks/latest/userguide/add-user-role.html • 右の追記例ではIAMユーザ/ロールを 2つ追加している • K8sのユーザやグループへの権限の 定義は別途、Role/RoleBindingや、 ClusterRole/ClusterRoleBindingを ⽤いて設定を⾏う – 他のK8sクラスターとこの部分は同様 $ kubectl edit -n kube-system configmap/aws-auth apiVersion: v1 data: (…snip…) mapUsers: | - userarn: <追加するIAMユーザ/ロールのARN1> username: <K8sでのユーザ名1> groups: - <所属させるK8sでのグループ1> - userarn: <追加するIAMユーザ/ロールのARN2> username: <K8sでのユーザ名2> groups: - <所属させるK8sでのグループ2>
  23. AWS サービスの PV利⽤ E B S や E F S

    を C S I ド ラ イ バ ー 経 由 で 使 お う 31
  24. 各種AWSサービスをPVで使う EKSにおける永続ストレージ 32 • EKSで各種AWSサービスをPV利⽤する⽅法は⼤きく分けて2通り – https://docs.aws.amazon.com/eks/latest/userguide/storage.html 1. In-Tree Plugin(EBS)を利⽤する

    • EKS(K8s)の内蔵プラグインで準備なしにすぐ使える • デフォルトのストレージクラス(gp2)が利⽤している • 将来的には廃⽌される 2. 各サービス向けのCSI Driverを利⽤する • EKSデプロイ後に、追加作業でドライバーを導⼊する必要がある(⼿動) – EKS K8sとCSI Driverでライフサイクルを分離できる点は⼤きなメリット • EBSの他、EFSやFSx for LustreのCSI Driverもリリースされている • EBSおよびFSx for LustreのCSI Driverはまだベータだがサポートはされる
  25. 各種AWSサービスをPVで使う EBS, EFS, FSx for LustreのCSI Driver 33 • 各AWSサービス向けCSI

    Driverの特徴 – Amazon EBS CSI Driver • 現時点で推奨される利⽤バージョンは “v0.9.0” • Dynamic Provisioningに対応 • AZを跨ぐ形で利⽤ができない点は注意が必要 – Amazon EFS CSI Driver • 現時点で推奨される利⽤バージョンは “release-1.0(v1.0.0)” • ReadWriteManyのアクセスモードでの利⽤が可能 • 単⼀FileSystemでもPath分割して複数のPVオブジェクトを作成可能 – Amazon FSx for Lustre CSI Driver • 現時点で推奨される利⽤バージョンは “v0.4.0” • ReadWriteManyのアクセスモードでの利⽤が可能 • FargateやArmノードで利⽤できない、対応K8sバージョンが1.19のみ 等、制約が多い
  26. 各種AWSサービスをPVで使う EBS, EFS, FSx for LustreのCSI Driver 34 • 各CSI

    Driverのドキュメント及びGithubリポジトリ – Amazon EBS CSI Driver • https://docs.aws.amazon.com/eks/latest/userguide/ebs-csi.html • https://github.com/kubernetes-sigs/aws-ebs-csi-driver – Amazon EFS CSI Driver • https://docs.aws.amazon.com/eks/latest/userguide/efs-csi.html • https://github.com/kubernetes-sigs/aws-efs-csi-driver – Amazon FSx for Lustre CSI Driver • https://docs.aws.amazon.com/eks/latest/userguide/fsx-csi.html • https://github.com/kubernetes-sigs/aws-fsx-csi-driver
  27. 各種AWSサービスをPVで使う EBS, EFS, FSx for LustreのCSI Driver 35 • 各CSI

    Driverのデプロイ⼿順(概要) 1. 各CSI Driverの要件を確認 • AWS CLIやeksctlなども細かくバージョン指定があるので注意 2. 【EBS/FSxのみ】IAM OIDC(OpenID Connect)Providerの作成 3. 【EBS/FSxのみ】CSI DriverのControllerに利⽤させるIAM Policy/IAM Roleの作成 4. Kustomize(kubectl apply -k)を利⽤してCSI Driverをデプロイ • Private ClusterではImageをECRにUploadしKustmize構成ファイルのImage情報を書き換える 5. 【EBS/FSxのみ】CSI DriverのController⽤のIRSA (IAM Role ServiceAccount)に 対してAnnotationを追加し、ControllerのPodを再起動 • ⼿順3で作成したIAM RoleのARNを指定する
  28. EKSの Pod Network E B S や E F S

    を C S I ド ラ イ バ ー 経 由 で 使 お う 36
  29. EKSのPod Networking K8s標準のContainer Network Interfaceに対応 37 • EKSではAmazon VPC CNI

    Pluginをサポート – https://docs.aws.amazon.com/eks/latest/userguide/pod-networking.html – https://github.com/aws/amazon-vpc-cni-k8s – VPCネットワークをネイティブにサポートする • このプラグインによりVPC SubnetのIPアドレスが直接Podに割り当てられる – 1 Podにつき 1 IPアドレスを消費する点には注意が必要 • 従来のVPCの知⾒を⽤いてネットワーク運⽤が可能 • Security Groupはノード全体に適⽤するほか、Pod単位での定義も可能 • AWSによるサポートはないが他のCNIプラグインも利⽤可能 – Calico、Cilium、Weave Net、AntreaなどのAWSパートナーによる商⽤CNI Pluginがある – https://docs.aws.amazon.com/eks/latest/userguide/alternate-cni-plugins.html
  30. EKSのPod Networking Amazon VPC CNI Pluginの詳細 38 • EC2ノードにはAmazon VPC

    CNI Pluginが標準でデプロイされる – DaemonSet として、各ノードに ”aws-node” のPodが配置される • aws-node内では”L-IPAM (Local IP Address Management)”デーモンが稼働 – L-IPAMDはノードに割り当てられたEC2 Profile(EC2 Role)⼜はIRSAを⽤いて Pod⽤のIPアドレスの準備/割当てなどの管理を⾏う 1. ENI(Elastic Network Interface)の作成 2. EC2ノードへ作成したENIをアタッチ 3. 各ENIへセカンダリIPアドレスの割当て 4. 作成したセカンダリIPをPodに割当て • EC2インスタンスタイプによってENI及びセカンダリIPの最⼤数が違う – https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html#AvailableIpPerENI – この制限により、各インスタンスタイプの最⼤配置可能Pod数に差が⽣じる • 例︓ m5.large の場合は最⼤ 29 Pod / m5.4xlarge の場合は最⼤ 234 Pod
  31. EKSでELB を使う K 8 s か ら E L B

    を 利 ⽤ し よ う 39
  32. ELBを経由してアクセスしよう まずはELBの種類をおさらい 40 • Elastic Load Balancing(ELB) – ELBには複数のロードバランサータイプがある •

    詳細 : https://aws.amazon.com/jp/elasticloadbalancing/features/ – 次のロードバランサーがEKSからは利⽤可能 • Classic Load Balancer(CLB)・・・旧世代 L4/L7 Load Balancer(少機能) • Network Load Balancer(NLB) ・・・⾼パフォーマンス L4 Load Balancer – インスタンス ターゲット ・・・ EC2インスタンスを利⽤時に使⽤ – IPアドレス ターゲット ・・・ EC2インスタンス及びFargate利⽤時に使⽤ • Application Load Balancer(ALB)・・・新世代 L4/L7 Load Balancer(多機能)
  33. ELBを経由してアクセスしよう EKSからELBを作成して利⽤する 41 • タイプによって利⽤する仕組みが変わる – Kubernetes In-Tree Controller •

    EKS(K8s)の内蔵コントローラで準備なしにすぐ使える • 利⽤出来るLBタイプ – Classic Load Balancer(CLB) – Network Load Balancer(NLB)の インスタンス ターゲット – AWS Load Balancer Controller • EKSデプロイ後に、追加作業でコントローラーを導⼊する必要がある(⼿動) • 利⽤出来るLBタイプ – Network Load Balancer(NLB)の IPアドレス ターゲット – Application Load Balancer(ALB)
  34. ELBを経由してアクセスしよう EKSからELBを作成して利⽤する 42 • それぞれのLBの利⽤⽅法 – Kubernetes In-Tree Controller •

    EKS(K8s)の内蔵コントローラで準備なしにすぐ使える • Serviceオブジェクトで .spec.type に “LoadBalancer” を指定する – https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer • ELBの細かな動作設定はannotationで指定する – NLBのデプロイ(デフォルトはCLB) • https://docs.aws.amazon.com/eks/latest/userguide/load-balancing.html#load-balancer-instance – 参考︓ https://kubernetes.io/docs/concepts/services-networking/service/#other-elb-annotations service.beta.kubernetes.io/aws-load-balancer-type: nlb
  35. ELBを経由してアクセスしよう EKSからELBを作成して利⽤する 43 • それぞれのLBの利⽤⽅法 – AWS Load Balancer Controller

    • EKSデプロイ後に、追加作業でコントローラーを導⼊する必要がある(⼿動) – 詳細 • https://kubernetes-sigs.github.io/aws-load-balancer-controller/ • https://docs.aws.amazon.com/eks/latest/userguide/aws-load-balancer-controller.html – デプロイ⼿順(概要) 1. IAM OIDC(OpenID Connect)Providerの作成 2. Controllerに利⽤させるIAM Policy/IAM Roleの作成 3. Controller⽤のIRSA (IAM Role ServiceAccount)を作成 4. HelmまたはManifestYamlファイルを利⽤してのデプロイ – Private ClusterではImageをECRにUploadしManifestファイルのImage情報を書き換える
  36. ELBを経由してアクセスしよう EKSからELBを作成して利⽤する 44 • それぞれのLBの利⽤⽅法 – AWS Load Balancer Controller

    • NLB(IPアドレス ターゲット) – https://docs.aws.amazon.com/eks/latest/userguide/load-balancing.html#load-balancer-ip – Serviceオブジェクトで .spec.type に “LoadBalancer” 及び annotation で指定する – その他の細かな動作設定はannotationで指定する • https://Kubernetes-sigs.github.io/aws-load-balancer-controller/latest/guide/service/annotations/ • ALB – https://docs.aws.amazon.com/eks/latest/userguide/load-balancing.html#load-balancer-ip – Ingressオブジェクトを作成することで利⽤できる – 動作設定は annotation および spec で指定する • https://kubernetes-sigs.github.io/aws-load-balancer-controller/latest/guide/ingress/annotations/ • https://kubernetes-sigs.github.io/aws-load-balancer-controller/latest/guide/ingress/spec/ service.beta.kubernetes.io/aws-load-balancer-type: nlb-ip
  37. Cloud9でkubectlがエラーになる どうやらIAM認証ができてない・・・︖ 48 • kubeconfigを正しくUpdateしているのにkubectlが実⾏できない • 確認ポイント – Cloud9に接続したIAMユーザ/ロールの権限が引き継がれる –

    IAMユーザ/ロールがEKSを利⽤する為に必要な権限を持っている • 最低でも “eks:DescribeCluster” および “eks:ListCluster” が必要 – 「aws eks update-kubeconfig」でkubeconfigの更新ができている 全部問題ないのに認証することができない・・・︕ $ kubectl get svc error: You must be logged in to the server (Unauthorized)
  38. Cloud9でkubectlがエラーになる どうやらIAM認証ができてない・・・︖ 49 • Kubeconfigを正しくUpdateしているのにkubeectlが実⾏できない • 確認ポイント – Cloud9に接続したIAMユーザ/ロールの権限が引き継がれる –

    IAMユーザ/ロールがEKSを利⽤する為に必要な権限を持っている • 最低でも “eks:DescribeCluster” および “eks:ListCluster” が必要 – 「aws eks update-kubeconfig」でkubeconfigの更新ができている 全部問題ないのに認証することができない・・・︕ $ kubectl get svc error: You must be logged in to the server (Unauthorized) ,/*0
  39. Cloud9でkubectlがエラーになる 原因︓デフォルト有効のAMTCの制約 • Cloud9のデフォルトの⼀時認証⽅式(AMTC)の制約 – AWS Managed Temporary Credentials •

    https://docs.aws.amazon.com/cloud9/latest/user-guide/how-cloud9- with-iam.html#auth-and-access-control-temporary-managed- credentials • 接続したIAMユーザ/ロールの権限を引き継ぐ仕組み • ただし⼀部の権限は制限を受けて引き継がれない – Cloud9、IAM、STSに対する⼀部のアクションが許可されない 50
  40. Cloud9でkubectlがエラーになる デフォルト有効のAMTCが原因でした • Cloud9のデフォルトの⼀時認証⽅式(AMTC)の制約 – AWS Managed Temporary Credentials •

    https://docs.aws.amazon.com/cloud9/latest/user-guide/how-cloud9- with-iam.html#auth-and-access-control-temporary-managed- credentials • 接続したIAMユーザ/ロールの権限を引き継ぐ仕組み • ただし⼀部の権限は制限を受けて引き継がれない – Cloud9、IAM、STSに対する⼀部のアクションが許可されない 51 1234.
  41. Cloud9でkubectlがエラーになる オマケ︓AMTC有効時のPrivate Link利⽤ • Cloud9でAMTC有効時、Private Linkを利⽤するAPIアクセスが失敗 • これはCloud9のセキュリティ仕様によるもの – Cloud9のGlobal

    IP以外のアドレスからのAPIアクセスは拒否される • 参考︓https://dev.classmethod.jp/articles/cloud9-ide-network-condition/ • この制約を回避するにはProfileを利⽤するかCloudShellで実⾏する 53 An error occurred (AuthFailure) when calling the DescribeInstances operation: AWS was not able to validate the provided access credentials
  42. Nodeを増やしたらIPが枯渇した 原因︓L-IPAMDのWarm Poolのせい 57 • VPC CNI PluginのL-IPAMDにおけるデフォルト設定動作によるもの – デフォルトでENI⼀枚分の余剰IPアドレスをWarm

    Poolとして確保する • m5.4xlargeのインスタンスの場合、ENI⼀枚分は 50 IP • 元々もつENIでも50個のIPアドレスを持つので合計 100 IP • さらにノード⾃⾝のプライマリIPアドレスも消費する • さらにさらにこれらのIPアドレス消費がノード台数分かかる – Warm PoolはPodに迅速にIPアドレスを割り当てる為のもの – 参考︓ https://betterprogramming.pub/amazon-eks-is-eating-my-ips-e18ea057e045
  43. Nodeを増やしたらIPが枯渇した 原因︓L-IPAMDのWarm Poolのせい 58 • VPC CNI PluginのL-IPAMDにおけるデフォルト設定動作によるもの – デフォルトでENI⼀枚分の余剰IPアドレスをWarm

    Poolとして確保する • m5.4xlargeのインスタンスの場合、ENI⼀枚分は 50 IP • 元々もつENIでも50個のIPアドレスを持つので合計 100 IP • さらにノード⾃⾝のプライマリIPアドレスも消費する • さらにさらにこれらのIPアドレス消費がノード台数分かかる – Warm PoolはPodに迅速にIPアドレスを割り当てる為のもの – 参考︓ https://betterprogramming.pub/amazon-eks-is-eating-my-ips-e18ea057e045 1234.
  44. Nodeを増やしたらIPが枯渇した 解決法︓L-IPAMDの設定を変更する 59 • aws-nodeの設定を変更する – Warm Poolで確保する余剰IPアドレスの計算⽅式を変更できる – aws-node

    DaemonSetの環境変数を設定 • WARM_ENI_TARGET ・・・ ENI単位での余剰IP確保(無効にする) • WARM_IP_TARGET ・・・ ノードで確保しておく余剰IP数 • MINIMUM_IP_TARGET ・・・ ノードで最低限もつIP数 $ kubectl -n kube-system set env daemonset aws-node WARM_ENI_TARGET- $ kubectl -n kube-system set env daemonset aws-node WARM_IP_TARGET=2 $ kubectl -n kube-system set env daemonset aws-node MINIMUM_IP_TARGET=5
  45. レベル う っ か り 踏 ん じ ゃ う

    こ と も あ る か も ︖ 60
  46. なんか変なError Podが・・・ Error→CrashLoopBackOffを繰り返してる・・・ 62 • Amazon EFS CSI Driverをデプロイしたら・・・efs-csi-controllerがなん かCrashLoopBackOffになってるんだけど・・・︖

    • 確認ポイント – DaemonSetで各ノードに配布される ”efs-csi-node“ Podは正常か︖ – EFSをPVとして利⽤できるか︖ あれ・・・︖動作的には問題ないぞ︖ kube-system efs-csi-controller-9867cfb5c-rbcbh 2/3 CrashLoopBackOff 13 51m kube-system efs-csi-controller-9867cfb5c-x9zxp 2/3 CrashLoopBackOff 13 51m
  47. なんか変なError Podが・・・ Error→CrashLoopBackOffを繰り返してる・・・ 63 • Amazon EFS CSI Driverをデプロイしたら・・・efs-csi-controllerがなん かCrashLoopBackOffになってるんだけど・・・︖

    • 確認ポイント – DaemonSetで各ノードに配布される ”efs-csi-node“ Podは正常か︖ – EFSをPVとして利⽤できるか︖ あれ・・・︖動作的には問題ないぞ︖ kube-system efs-csi-controller-9867cfb5c-rbcbh 2/3 CrashLoopBackOff 13 51m kube-system efs-csi-controller-9867cfb5c-x9zxp 2/3 CrashLoopBackOff 13 51m ,5"6.
  48. なんか変なError Podが・・・ 原因︓デプロイVersionが間違っていた 64 • 各CSI Driverは推奨バージョンがAWSドキュメントで指定される – Amazon EBS

    CSI Driver︓”v0.9.0” – Amazon FSx for Lustre CSI Driver︓”v0.4.0” – Amazon EFS CSI Driverだけは説明⽂中にでは明⽰されてない • 実⾏コマンド内容的には ”release-1.0 (v1.0.0) ” • 特にEFI CSI DriverはReleaseとmasterでArchitectureが違うので注意 – そもそも現⾏ReleaseではControllerを使⽤していない(IRSAもなし) • 解決法︓⼀旦CSI Driverを削除して正しいVersionでデプロイする – そのままでも動作するにはするんだけどね・・・
  49. なんか変なError Podが・・・ 原因︓デプロイVersionが間違っていた 65 • 各CSI Driverは推奨バージョンがAWSドキュメントで指定される – Amazon EBS

    CSI Driver︓”v0.9.0” – Amazon FSx for Lustre CSI Driver︓”v0.4.0” – Amazon EFS CSI Driverだけは説明⽂中にでは明⽰されてない • 実⾏コマンド内容的には ”release-1.0 (v1.0.0) ” • 特にEFI CSI DriverはReleaseとmasterでArchitectureが違うので注意 – そもそも現⾏ReleaseではControllerを使⽤していない(IRSAもなし) • 解決法︓⼀旦CSI Driverを削除して正しいVersionでデプロイする – そのままでも動作するにはするんだけどね・・・ !"#$%&'( )*+,,"- .-/01,23
  50. Taintが気づいたら消えてた・・・ 特定AZのノードでだけ消えてるぞ︖ 67 • 気づいたら⼿動で設定していたTaintが無くなってしまっていた – これによりそのノードに配置したくないPodが配置されてしまった • 確認ポイント –

    どのようなノードのTaintが消えてしまっているか︖ – 各ノードやPodの稼働時間(AGE)はどの程度か︖ – 配置のおかしいPodはないか︖ 特定のAZのノード/Podがおかしい・・・︖
  51. Taintが気づいたら消えてた・・・ 特定AZのノードでだけ消えてるぞ︖ 68 • 気づいたら⼿動で設定していたTaintが無くなってしまっていた – これによりそのノードに配置したくないPodが配置されてしまった • 確認ポイント –

    どのようなノードのTaintが消えてしまっているか︖ – 各ノードやPodの稼働時間(AGE)はどの程度か︖ – 配置のおかしいPodはないか︖ 特定のAZのノード/Podがおかしい・・・︖ 7%888
  52. Taintが気づいたら消えてた・・・ 原因︓AZ障害でEC2ノードが再⽣成された 71 • 特定AZの障害でEC2インスタンスとの通信ができなくなった – 結果、EC2ヘルスチェックに失敗 → その後、ASGがEC2インスタンス再⽣成 →

    ⼿動で設定していたTaintが再⽣成で消失する • この事象を回避するにはノードにTaintを⾃動設定する仕組みが必要 – だが現段階ではManaged Node Group配下のノードに⾃動付与できない • Self-Managed Node GroupならKubeletのカスタマイズで対応できる – ⼒業でCronjobでtaint付与のコマンドを定期実⾏する等を検討・・・
  53. Taintが気づいたら消えてた・・・ 原因︓AZ障害でEC2ノードが再⽣成された 72 • 特定AZの障害でEC2インスタンスとの通信ができなくなった – 結果、EC2ヘルスチェックに失敗 → その後、ASGがEC2インスタンス再⽣成 →

    ⼿動で設定していたTaintが再⽣成で消失する • この事象を回避するにはノードにTaintを⾃動設定する仕組みが必要 – だが現段階ではManaged Node Group配下のノードに⾃動付与できない • Self-Managed Node GroupならKubeletのカスタマイズで対応できる – ⼒業でCronjobでtaint付与のコマンドを定期実⾏する等を検討・・・ 9:;, 1234.
  54. Taintが気づいたら消えてた・・・ 解決法︓userdataでkubeletのカスタム設定 73 • eksctlに ”managedNodeGroups.preBootstrapCommands” という パラメータが⽤意されている – ノードでのBootstrap処理に先駆けてコマンドを実⾏が可能

    – 実体としては、指定したコマンドがASGの利⽤する起動テンプレート のuserdataに登録され、インスタンス起動時で実⾏される • これを利⽤しBootstrapスクリプトにKubeletカスタマイズ設定を挿⼊ – 参考︓https://github.com/aws/containers-roadmap/issues/864#issuecomment-760168725 preBootstrapCommands: - sed -i '/^KUBELET_EXTRA_ARGS=/a KUBELET_EXTRA_ARGS+=" --register-with-taints=<key1>=<value1>:<effect1>"' /etc/eks/bootstrap.sh
  55. レベル 滅 多 に 踏 ま な い と は

    想 う け ど ・ ・ ・ 74
  56. Private Clusterでaws-node起動に失敗 PodへIPアドレス割り当てできずPendingに・・・ 76 • Managed Node GroupをPrivate Subnetへデプロイ –

    デプロイ時点ではNAT Gatewayを配置していた • その後、NAT Gatewayを削除して完全Private Cluster化 – ナレッジセンターにも削除可能である内容の記載がある • https://aws.amazon.com/jp/premiumsupport/knowledge-center/eks-cluster-node- group-private-network/ • しかしそれ以降、aws-node Podの起動が完了しなくなる – 状態が Running → CrashLoopBackOff を繰り返し Ready とならない • この症状はNAT Gatewayを再配置すると改善する
  57. Private Clusterでaws-node起動に失敗 原因の調査も微妙に難航・・・ 77 • 確認ポイント – aws-node Podに何かログがでていないか︖ –

    aws-node Pod の Event ログはどうか︖ $ kubectl logs aws-node-nqz4r -n kube-system {"level":"info","ts":"2021-02-17T02:18:32.559Z","caller":"entrypoint.sh","msg":"Install CNI binary.."} {"level":"info","ts":"2021-02-17T02:18:32.573Z","caller":"entrypoint.sh","msg":"Starting IPAM daemon in the background ... "} {"level":"info","ts":"2021-02-17T02:18:32.574Z","caller":"entrypoint.sh","msg":"Checking for IPAM connectivity ... "} Warning Unhealthy 43s kubelet, ip-10-1-1-9.ap-northeast-1.compute.internal Readiness probe failed: {"level":"info","ts":"2021-02-17T02:18:42.682Z","caller":"/usr/local/go/src/runtime/proc.go:203","msg":"timeout: failed to connect service ¥":50051¥" within 1s"} → んー︖ L-IPAMDとの接続性チェックで⽌まってるな︖ → あー、HealthCheckに引っかかってPod再起動されてそうだ・・・
  58. Private Clusterでaws-node起動に失敗 原因の調査も微妙に難航・・・ 78 • 確認ポイント – aws-node の HealthCheck

    を確認 livenessProbe: exec: command: - /app/grpc-health-probe - -addr=:50051 failureThreshold: 3 initialDelaySeconds: 60 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 1 readinessProbe: exec: command: - /app/grpc-health-probe - -addr=:50051 failureThreshold: 3 initialDelaySeconds: 1 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 1 → 50051ポートへのヘルスチェックができてなさそうだなぁ
  59. Private Clusterでaws-node起動に失敗 原因の調査も微妙に難航・・・ 79 • 確認ポイント – ⼀旦 HealthCheck を無効化し、L-IPAMDのログをノードから確認

    • /var/log/aws-routed-eni/ipamd.log にログが出⼒される {"level":"error","ts":"2021-02-22T02:17:07.763Z","caller":"aws-k8s- agent/main.go:28","msg":"Initialization failure: ipamd: can not initialize with AWS SDK interface: refreshSGIDs: unable to update the ENI's SG: WebIdentityErr: failed to retrieve credentials¥ncaused by: RequestError: send request failed¥ncaused by: Post https://sts.amazonaws.com/: dial tcp 52.94.241.129:443: i/o timeout"} → ん︖GlobalのSTSエンドポイントを⾒に⾏ってない︖︖
  60. Private Clusterでaws-node起動に失敗 原因の調査も微妙に難航・・・ 80 • 確認ポイント – ⼀旦 HealthCheck を無効化し、L-IPAMDのログをノードから確認

    • /var/log/aws-routed-eni/ipamd.log にログが出⼒される {"level":"error","ts":"2021-02-22T02:17:07.763Z","caller":"aws-k8s- agent/main.go:28","msg":"Initialization failure: ipamd: can not initialize with AWS SDK interface: refreshSGIDs: unable to update the ENI's SG: WebIdentityErr: failed to retrieve credentials¥ncaused by: RequestError: send request failed¥ncaused by: Post https://sts.amazonaws.com/: dial tcp 52.94.241.129:443: i/o timeout"} → ん︖GlobalのSTSエンドポイントを⾒に⾏ってない︖︖ !<= >?1@
  61. Private Clusterでaws-node起動に失敗 原因︓AWS SDK for GoがGlobal STS Endpointを利⽤するため 81 •

    今回は完全Private ClusterでInternetへ出ることができない → にも関わらずL-IPAMD内でGlobal STS Endpointを利⽤する → 到達できないので接続待ちでTimeoutとなる • ナレッジセンターには完全Private化できると書いてあった – AWSサポートからも完全Private Clusterであっても 「問題なくaws-nodeは起動し、同様の事象は再現しない」との回答 – しかし別VPC環境で再度テストしても⾃環境では再現してしまう
  62. Private Clusterでaws-node起動に失敗 原因︓AWS SDK for GoがGlobal STS Endpointを利⽤するため 82 •

    今回は完全Private ClusterでInternetへ出ることができない → にも関わらずL-IPAMD内でGlobal STS Endpointを利⽤する → 到達できないので接続待ちでTimeoutとなる • ナレッジセンターには完全Private化できると書いてあった – AWSサポートからも完全Private Clusterであっても 「問題なくaws-nodeは起動し、同様の事象は再現しない」との回答 – しかし別VPC環境で再度テストしても⾃環境では再現してしまう ,A#BCA
  63. Private Clusterでaws-node起動に失敗 なぜAWS SDK for GoがGlobal STS Endpointを利⽤するのか︖ 83 •

    そもそも何故STS Endpointを利⽤しようとするのか︖ – 考えられるのはPodがIRSAを使うケース – eksctlの構成定義YAMLでは aws-node(L-IPAMD) に対して、 特別なカスタマイズ設定はしてないつもり・・・ • IAM(STS)に関連してそうな部分を⼀旦削除してみる – 他のPod⽤のIRSAの定義の削除 – OIDC Provider有効化の削除 → おっ︕︖再現しなくなったぞ︕
  64. Private Clusterでaws-node起動に失敗 なぜAWS SDK for GoがGlobal STS Endpointを利⽤するのか︖ 84 •

    そもそも何故STS Endpointを利⽤しようとするのか︖ – 考えられるのはPodがIRSAを使うケース – eksctlの構成定義YAMLでは aws-node(L-IPAMD) に対して、 特別なカスタマイズ設定はしてないつもり・・・ • IAM(STS)に関連してそうな部分を⼀旦削除してみる – 他のPod⽤のIRSAの定義の削除 – OIDC Provider有効化の削除 → おっ︕︖再現しなくなったぞ︕ D- >?1@
  65. Private Clusterでaws-node起動に失敗 真の原因︓aws-nodeがIRSAを利⽤しているから 85 • デフォルトではaws-nodeはIRSAを利⽤しない • しかし、eksctlはOIDC Providerを有効化する場合において ⾃動的にaws-nodeがIRSAを利⽤するように構成してしまう

    – https://eksctl.io/usage/security/#withoidc • 結果、aws-nodeがIRSAの認証でGlobal STS Endpointに問合せをする Enable “withOIDC” to automatically create an IRSA for the amazon CNI plugin and limit permissions granted to nodes in your cluster, instead granting the necessary permissions only to the CNI service account.
  66. Private Clusterでaws-node起動に失敗 真の原因︓aws-nodeがIRSAを利⽤しているから 86 • デフォルトではaws-nodeはIRSAを利⽤しない • しかし、eksctlはOIDC Providerを有効化する場合において ⾃動的にaws-nodeがIRSAを利⽤するように構成してしまう

    – https://eksctl.io/usage/security/#withoidc • 結果、aws-nodeがIRSAの認証でGlobal STS Endpointに問合せをする Enable “withOIDC” to automatically create an IRSA for the amazon CNI plugin and limit permissions granted to nodes in your cluster, instead granting the necessary permissions only to the CNI service account. EFGHIJ KLM+NO
  67. Private Clusterでaws-node起動に失敗 真の原因︓aws-nodeがIRSAを利⽤しているから 87 • デフォルトではaws-nodeはIRSAを利⽤しない • しかし、eksctlはOIDC Providerを有効化する場合において ⾃動的にaws-nodeがIRSAを利⽤するように構成してしまう

    – https://eksctl.io/usage/security/#withoidc • 結果、aws-nodeがIRSAの認証でGlobal STS Endpointに問合せをする Enable “withOIDC” to automatically create an IRSA for the amazon CNI plugin and limit permissions granted to nodes in your cluster, instead granting the necessary permissions only to the CNI service account. 456!7849 :;<=>3???
  68. Private Clusterでaws-node起動に失敗 解決法︓aws-nodeの動作を変更する環境変数を設定 88 • AWSサポートから解決法を教えてもらいました❗ – aws-nodeがRegionalなSTS Endpointを利⽤する為の環境変数定義⽅法 –

    サポートからドキュメント化されるように働きかけてくれる様⼦ $ kubectl edit ds -n kube-system aws-node (...snip...) containers: - env: - name: AWS_REGION value: ap-northeast-1 - name: AWS_STS_REGIONAL_ENDPOINTS value: regional (...snip...)