This is the full map of EKS and we’ll go through how to install EKS and plugins in this post, as well as the troubles I got. Let’s go!
Quick Start an EKS with ADD-ONs
git clone https://github.com/davidh83110/eks-quickstart
cd terraform && make plan && make apply
cd ansible-playbooks
ansible-playbook ./
You will get an EKS cluster
and Node Group
, also has
metrics-server
/ k8s-dashboard
/ ALB-Ingress controller
/ Cluster-Autoscaler (CA)
/ Prometheus
/ Grafana
/ Weave
.
Pre-Create Cluster
What EKS Cluster needs:
eksServiceRole
- Subnets (Including Public and Private Subnets)
- Additional Security Groups
- Endpoint Access
- Secrets Encryption
最容易有疑問的大概是上述這幾個參數了,一一詳細記錄下來,其他沒有寫的應該都能很輕易的選擇。
-
eksServiceRole
這個有用過ECS應該都不陌生,EKS也需要一個類似的東西。
需要兩個Policies.AmazonEKSServicePolicy
&AmazonEKSClusterPolicy
-
Subnets
Cluster的Subnets務必要選擇Public & Private Subnets, 不能只選Private.
所謂Private就是要給你的Node用的; Public就是要給ALB-Ingress用的。 -
Additional Security Group
這個是用來控制誰可以存取代管的MASTER.
EKS會在創建的時候,自動幫你的Cluster掛上代管的Security Group,當你在啟動新的ALB-Ingress/NodeGroup的時候,這個代管的SG會自行變動Rules.
Additional就是指除了這個代管的之外,你可以選擇其他你自由控制的SG附加上去。BUT, 一但建立之後就不能改變附加的SG了
-
Endpoint Access
這個是控制誰可以使用Kubernetes API, 也就是誰可以用kubectl去控制這個cluster.
For instance: 如果你希望要開VPN才可以使用,你就只需要勾選Private Access
.
但如果希望可以不要這麼麻煩的還要開VPN, 可以同時勾選Public Access
&Private Access
, 並指定Source to public access endpoint
.
如果勾選了Public Access, 一定要給Source IP.
因為如果不給的會會套用預設值,也就是 0.0.0.0/0. 非常危險,你的cluster就裸奔了。
-
Secrets Encryption
這是可以讓你綁定KMS Key去加密Kubernetes Secrets.
因為Kubernetes Secrets眾所皆知就是做base64 ENCODE 而已
所謂Encode就是可以直接Decode (base64 -d), 是編碼的一種,並不算是加密!
之前常見的做法會是使用Hashicorp的
Vault
, 然後掛Sidecar在Runtime的時候去取.
現在EKS提供和KMS的整合,讓我們在存進去的時候他就用KMS再做一層加密了,
只是我還不知道怎麼去驗證AWS確實有幫我們做加密, 這也是滿tricky的地方
。 -
AWS Auth
之前會需要applyaws-auth.yaml
這個ConfigMap, 但現在(1.15)似乎EKS已經自己幫我們Apply了。
如果要修改或新增 IAM User/Roles, 可以再去編輯這個 ConfigMap 就好。
What else do I need to do after create an EKS cluster ?
先進到EKS Console, 來看看有什麼相關資訊。 以下列舉幾個比較可能有疑問的。
-
Platform version
AWS自己給的eks版本號碼,基本上不太需要理他。 -
API server endpoint & Certificate authority
你的Master API Endpoint跟Cert. 不過透過aws cli去做授權的話,也不太需要管這個。 -
OpenID Connect provider URL
OIDC. 這是讓EKS可以結合IAM使用做授權管理的關鍵,會需要拿這個ID去IAM OIDC那邊建立一個新的Identity providers
.
後面會詳細講到如何建立。 主要是在建立 ALB-Ingress Controller的時候會需要去做建立。 -
Node Group
在之前要建立EKS的Nodes, 會需要自己去建立Auto Scaling Group(ASG)並連結到EKS, 還要打一些Tags.
現在透過Node Group可以半代管ASG, 他會自動根據你給的資訊去建立ASG, 並自動連結到EKS. (雖然常常有些問題)。
後面也會詳細講到建立過程。 -
Fargate Profiles
Fargate with EKS是沒有Node(worker)的概念的。就像ECS沒有ECS Instance一樣。
所以這邊會去指定Fargate所在的Subnets和Role,提供給Pod在上面跑的資訊而已。
比較值得說的是Fargate的使用模式
Fargate with EKS是有限制的,請以Serverless的角度來思考。
Fargate features with EKS:
- No Daemonset
- No statefulset that require PV or File Systems (EFS also no supported)
- Maximum 4vCPU and 30G Memory per pod
- No CLB/NLB (cuz no NodePort in Fargate)
More Information: AWS Blog - Fargate with EKS
第一件要做的事 - TAGGING
由於EKS繼承了Kops的模式,大量使用Tags來控制EKS的相關資源,也很容易被忽略,一定要做好這部分的控制。
kubernetes.io/cluster/${CLUSTER_NAME}
是最廣泛使用的Tag, 會需要Tag在Subnets, Instances上。 可以Assign的值有兩個 - owned
OR shared
。
一般來說在Subnets都會給owned
, 因為會需要與其他EKS Cluster共用, 除非你希望這個Subnet是給某個cluster專用。
shared
顧名思義就是共用subnet。
elb
OR internal-elb
這個分別要Tag在Public & Private Subnet上面,讓EKS知道他們是什麼類型的子網,
這樣ALB-Ingress才能根據Tag放到正確的子網。
需要被Tag的有以下資源:
-
Public Subnets
kubernetes.io/cluster/${CLUSTER_NAME} = shared kubernetes.io/role/elb = 1
-
Private Subnets
kubernetes.io/cluster/${CLUSTER_NAME} = shared kubernetes.io/role/internal-elb = 1
-
Security Group / Instances / NodeGroup
這些理論上EKS會自動去檢查,然後幫我們tag上去,不要手賤去刪都行。 而我相信EKS也是往這個方向努力,之後會自己幫我們檢查TAG並自動做掉這部分,讓我們拭目以待。
Create Nodes
建立Nodes有兩種方式
- 自行建立Auto Scaling Group(ASG) & ASG Configuration & Register to EKS
- 使用EKS Node Group
過去通常都要自行註冊與建立ASG, 是有點麻煩。 現在可以使用Node Group來幫我們半代管
這個Nodes。
為什麼是半代管
?
當Node Group出現註冊問題或是有錯誤時,你還是得要進去這台機器手動排除錯誤。
建立Node Group的注意事項:
-
VPC (務必檢查,很容易忽略)
MUST ENABLE enableDnsHostnames, enableDnsSupport
- Check Documentation Here
-
Subnets
選擇Private Subnets -
eksNodeRole
Attach 3 Policies:- AmazonEC2ContainerRegistryReadOnly
- AmazonEKS_CNI_Policy
- AmazonEKSWorkerNodePolicy
-
Remote Access Security Group
要注意的是這裡指的是允許Remote Access
的SG, 不是要掛在Instance上面的SG。 -
Labels
這邊指的是Node Group的TAG, 不是Instance的TAG
Kubectl
做完以上那些大概要花10-20min去跑,跑完都是 Active
的狀態差不多就完成了。
接下來我們實際 Access 這個 cluster 看看。
首先,需要安裝 kubectl
. (自行安裝)
然後需要建立相對應的 kubeconfig
, EKS 會使用 aws-iam-authenticator
來幫我們完成這部分。
過程如下:
➜ ~ aws eks --region ${REGION} update-kubeconfig --name ${CLUSTER_NAME} <aws:dev>
Updated context arn:aws:eks:ap-northeast-1:34323434:cluster/development in /Users/davidhsu/.kube/config
➜ ~ <aws:dev>
➜ ~ kubectl get nodes <aws:dev>
NAME STATUS ROLES AGE VERSION
ip-10-10-11-141.ap-northeast-1.compute.internal Ready <none> 125m v1.15.10-eks-bac369
ip-10-10-12-203.ap-northeast-1.compute.internal Ready <none> 126m v1.15.10-eks-bac369
➜ ~
Reference Official Documentation - EKS kubeconfig
到這裡這個 EKS Cluster 就算是完成囉,但是還需要一些額外設定跟 Add-ons 的安裝。
ADD-ONs of EKS
這邊詳列要裝的 Add-ons 並附上官方的資料來源(官方怎不幫我裝一裝就好?)
-
Metrics-Server
收集 kubernetes cluster 內各項指標,以便提供給 Prometheus/K8s Dashboard 收集使用,或做圖表的呈現。
安裝 Kubernetes 指標伺服器 -
Kubernetes Dashboard
Kubernetes Web UI, 提供視覺化的操作以及資源的監控,必須要先建立eks-admin
這個 ServiceAccount。
部署 Kubernetes Web UI (儀表板) -
Cluster Autoscaler (CA)
用來自動擴展 Node 數量的套件,當有資源需要 Node 而 Node 不夠的時候會自動加開新的 Nodes。這和
ASG
是連動的,會自動調整 Desired & Minimum Count,但是受到 Maximum 的限制,也就是說自動成長到定義的 Maximum 之後就不會再長了。
EKS - Cluster Autoscaler -
ALB Ingress Controller
與ALB連接的Ingress Controller,可以直接在 ingress yaml 裡直接定義 ALB 的參數。比較可怕的是如果自定義 Security Group 的 ID ,會造成 Master SG 沒有自動加入這個 ALB 的 SG 到 Inbound,就會一直是 unhealthy 的狀態,可以透過指定 inbound rule 的方式來避免這個 Bug。
alb.ingress.kubernetes.io/security-group-inbound-cidrs: 61.67.11.22/32
-
Prometheus
控制平面指標與 Prometheus -
Grafana
EKS Workshop - DEPLOY GRAFANA
Troubleshooting
Q: Node cannot join to cluster? ( cni config uninitialized
)
A: Please make sure subnets are well-tagging and all selected in EKS cluster.
If you’re using NodeGroup then it won’t has any problem on your instances basically,
so what you need to check is the resources about VPC and Subnets.
- Subnets tags
kubernetes.io/role/elb
=1
(For Public Subnets (Ingress Subnets))kubernetes.io/role/internal-elb
=1
(For Private Subnets (Nodes Subnets))kubernetes.io/cluster/${CLUSTER_NAME}
=shared
(ALL Subnets including for ingress and nodes)
- You must selected
PUBLIC & PRIVATE
subnets in EKS control plane. - VPC DNS Hostname
enabled
- VPC DNS Support
enabled
Also, you can use journalctl -u kubelet
on nodes to check the logs.
Q: error: You must be logged in to the server (Unauthorized)
A: Your identity might be wrong. Please check the current identity by the following command.
- $ aws sts get-caller-identity
{
"Account": "000012345",
"UserId": "dawdwwfwefewfefwef",
"Arn": "arn:aws:iam::000012345:user/david"
}
Then rerun the kubeconfig setup.
- $ aws eks --region ap-northeast-1 update-kubeconfig --name test-cluster <aws:dev>
Updated context arn:aws:eks:ap-northeast-1:000012345:cluster/test-cluster in /Users/davidhsu/.kube/config
Q: Security Group on EKS Control Plane?
A: EKS Control plane has 2 kinds of subnets.
- EKS Master Managed SG
- Additional SG
When we are creating some AWS resources such as ALB-Ingress’s SG, it will be automatically added to Master managed SG, so we don’t have to worry about it.
Additional SG is for other source you trust, you can add them to the SG so that they can access the EKS Master as well.
Q: API server endpoint access?
A: If you are using private access
for the connectivity between nodes and master, then you must enable VPC DNS hostname and support
. Otherwise, it will still go with public route.
Q: Fargate with EKS
A: Fargate is a serverless service.
It doesn’t support daemonset
/ statefulset
/ EFS
.
Only 10G
volume can be used per Fargate; and the maximum of vCPU and Memory are 4vCPU and 30G RAM.
To use Fargate on EKS, you need to create Fargate Profile
first.
Q: Can I specify Security Group for ALB-Ingress?
A: Yes. But the EKS Managed SG might not be changed and it means you have to change by yourself.
The alternative way would be specify the SG rules for ALB Ingress.
Example:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: "weave-scope-ingress"
namespace: "weave"
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/security-group-inbound-cidrs: 61.220.65.15/32
...(skip)
Q: Cluster Autoscler didn’t trigger scale down
A: Don’t worry, normally it would cost around 10min to let the CA calculate which Pods should be moved to which Node. It really takes time bus I can’t really realize why, seems the calculation not complicated at all.