前言
EKS 的建立方便快速,其中有些概念花了些時間才釐清,甚至有些拓墣一開始想錯了。經過幾週查閱文件與實驗後,寫個小的總結做個簡單的紀錄。
Architecture
- EKS 只有維護 Control Plane,Worker 有 EC2 與 Fargate 可以選擇。其中 EC2 必須由使用者自行管理。
- EKS Control Plane 的 VPC 與 Cluster 的 VPC 為不同的 VPC
- 如果 EKS 有開啟 Private Access,會在 Cluster VPC 的 subnet 中安插 EKS-managed ENI 讓 Cluster VPC 流量穿透至 EKS 中
- EKS 建立時選擇的 VPC 是為了部署 EKS-managed ENI(最少兩個)使用
- EKS-managed ENI 直接存在於 subnet 之中,非 EC2 instance(or 其他 instance)之上
Nodegroup
如果 Nodegroup 完全無法存取外網,同時也就無法拉取必要的 Container Image,導致節點無法建立成功
Nodegroup 如果落在 private subnet,可以多開一台有 public subnet 的 EC2 作為 bastion 使用(同一個 VPC 下)
API Endpoint
public access
API endpoint domain 會對應到一組 Public IP 做為 API Endpoint 入口
可以使用 kubectl cluster-info
查看
1 | [ec2-user@eks-bastion]$ kubectl cluster-info |
private access
根據官方文件描述,在 Cluster VPC 下會有 Route 53 private hosted zone 將 API endpoint 解析成該 VPC 下的 IP
This private hosted zone is managed by Amazon EKS, and it doesn’t appear in your account’s Route 53 resources.
經過實驗會發現解出兩組 VPC 中的 private IP,同時為 EKS-managed ENI 的 IP
這組介面可以透過將 Cluster VPC 的流量直接導向至 EKS VPC 之中
啟用條件為 Cluster VPC 必須將 enableDnsHostnames
, enableDnsSupport
設定為 true
並且 AmazonProvidedDNS
要在 VPC DHCP 的 domain name servers list
public and private access
外網因為沒有 Route 53 private hosted zone 所以會解析出外網 IP
Cluster VPC 下有 Route 53 private hosted zone 所以會解析出 EKS-managed ENI 的 IP
Pod Amount Limit
Pod limit 的根本問題是因為不同的 EC2 instance type 有先天的 VPC IP 數量限制
ENI 的數量有限制,每一個 ENI instance 可以指定的 IP 數量也有限制
官方有給出一份計算後的限制列表可以進行查閱 eni-max-pods.txt
突破限制前先釐清自己的叢集為何被限制,以下為幾種可能
limited by subnet CIDR
subnet 的 CIDR 一開始切太小,導致 Pod 數量超過 CIDR 範圍時,參考 VPC CNI 的 AWS_VPC_K8S_CNI_CUSTOM_NETWORK_CFG 參數,來客製化 Pod 的 CIDR。
limited by EC2 instance type
最常見的情況,達到 EC2 上的 IP 數量限制,因此 VPC CNI 無法成功索取 IP。
方法一:
直接抽換 AWS VPC CNI,換掉之後 Node 就不會再持續索取 secondary private IPv4 addresses,不過抽換後,沒有辦法讓 Pod 的 IP 直接屬於 VPC 下的 IP(理論效能會差一些,流量可能須經過 NAT 轉換)。
方法二:
使用 2021 年 EC2 新推出的功能 prefix assignment
。開啟 AWS VPC CNI 中的 ENABLE_PREFIX_DELEGATION
參數。將每一個 ENI 上原本可以附加的 secondary private IPv4 addresses 變成變為 /28 範圍(16 個 IPs)。
參考 Increase the amount of available IP addresses for your Amazon EC2 nodes
limited by insufficient IP’s
該 subnet 下的 IP 被其他節點或是其他應用索取完畢,導致某些節點的 aws-node
(VPC CNI) 沒有辦法正常索取 IP。解決方法為設定 WARM_ENI_TARGET
與 WARM_IP_TARGET
參數,來讓剛節點一被部署時就預先保留好可用的 IP,即時當時 Pod 還沒有被建立。
Customize kubelet Arguments
某些時候需要客製化我們的節點,例如修改 container runtime(EKS 1.23 已經將預設 container runtime 換成 containerd)
Amazon EKS optimized Amazon Linux AMI 在開機時會呼叫 /etc/eks/bootstrap.sh
在執行必要的初始化
然而該腳本就有提供參數可供調整,例如我想要替換 container runtime 可以在 launch template 中改寫 user-data 成
1 | !/bin/bash |
想要修改 kubelet 的啟動參數可以用 --kubelet-extra-args
來修改
後記
以上為這幾週第一次使用 EKS 的紀錄以及個人認為比較容易混淆或是模糊的點,要建構一個可信賴的 EKS 要考量的內容五花八門。這還只是一些在架構上的概念釐清而已,如果要往叢集內部鑽研,有更多要注意與可以調教的地方。這篇文章同時也給以後的自己參考,未來有機會再寫其他文章探討不同層面需要考量的議題。