此篇將教學如何在 AWS EKS 運行 Fargate
首先我們先透過 AWS EKS 建立 Cluster, 建立完後緊接著設定 Fargate。
- 建立 EKS Fargate Pod IAM role
點選 Create Role
Trusted entity type 選擇 AWS Service
選擇 EKS Farget pod
Role 名稱命名為 AmazonEKSFargatePodExecutionRole。
2. 建立 Fargate Profile
輸入可以識別的名稱以及選擇 Private Subnet
選擇 pod 所在的 namespace, 這邊因為是範例所以都會建置在 * namespace, 都填寫完畢後點選 Create
3. 創建 Farget Profile 給 CoreDNS
基本配置都完成後緊接著設定 CoreDNS Fargate Profile
aws eks create-fargate-profile \
--fargate-profile-name coredns \
--cluster-name <cluster name> \
--pod-execution-role-arn arn:aws:iam::111122223333:role/AmazonEKSFargatePodExecutionRole \
--selectors namespace=kube-system,labels={k8s-app=kube-dns} \
--subnets <private subnet>
kubectl patch deployment coredns \
-n kube-system \
--type json \
-p='[{"op": "remove", "path": "/spec/template/metadata/annotations/eks.amazonaws.com~1compute-type"}]'
都執行完畢後檢查 coredns pod 是否正常運行
kubectl get pods -n kube-system
注意!!
EKS 在建立 Fargate 的時候 server endpoint access 記得要也須選擇 Private, 且 VPC 記得配置 NAT Gateway,因為 Fargate 是位在 private subnet。
參考資源:
https://rtfm.co.ua/en/aws-fargate-capabilities-comparison-with-lambda-ec2-and-usage-with-aws-eks/
如何刪除舊的 config users、cluster 等資訊,可以使用以下指令
kubectl config get-contexts
kubectl config get-users
kubectl config get-clusters
unset config 資料
kubectl config unset users.xxx
kubectl config unset clusters.xxx
kubectl config unset contexts.xx
注意!!
假如是重新建立一個 IAM Role For AWS CLI 的話要記得在 EKS Access 設定此 IAM Role 可以存取的權限
- 點選 Access
2. 點選 Create access entry
3. 配置 IAM ARN
4. 設定 IAM For Cluster Policy 都選擇完後點選 Create
5. 設定 eks config 至 kubectl config 裡, 我這邊的地區為東京 (ap-northeast-1) 且名稱為 demo-eks
指令說明:
aws eks update-kubeconfig --region <region> --name <cluster name>
執行
aws eks update-kubeconfig --region ap-northeast-1 --name demo-eks
確認 kubectl 是否正常
kubectl get all
假如有資訊出現即代表正常運作。
helm 安裝 AWS ALB
先增加 eks-charts repo
helm repo add eks https://aws.github.io/eks-charts
在使用 helm 安裝 load balancer 前,需要建立 k8s service account
- 首先建立 OIDC Provider
進入 IAM Console identity providers , 檢查是否已有資料
沒有的話點選 Add Provider
Provider Type: 選擇 OpenID Connect
ProviderURL: 輸入 Cluster 的 provider url
進入 EKS Overview 即可看到 Cluster 的 OIDC Provider url
Audience: 輸入 sts.amazonaws.com
2. 建立 Kubernetes Service Account 擁有 IAM Role
2–1 建立 IAM Role
policy 記得要配置以下網址的權限
2–2 建立 service-account.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: aws-load-balancer-controller # service account name
namespace: kube-system
2–3 IAM Role 配置 trusted policy
$account_id: AWS 帳號的 account id
$oid_provider: EKS oid provider url 但是要去掉 https://, 所以字串會是 oidc.eks.ap-northeast-1.amazonaws.com/id/xxxxx
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::$account_id:oidc-provider/$oidc_provider"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"$oidc_provider:aud": "sts.amazonaws.com",
"$oidc_provider:sub": "system:serviceaccount:$namespace:$service_account"
}
}
}
]
}
2–4 針對上面建立的 service account 增加 iam role annoate
$namespace: default
$service_account: 上面 service.yaml 的名稱
$account_id: AWS IAM account id
$my_role: 改成先前建立的 Role Name
kubectl annotate serviceaccount -n $namespace $service_account eks.amazonaws.com/role-arn=arn:aws:iam::$account_id:role/$my_role
除了這樣操作之外,也可以一氣呵成做設定, service-account.yaml 可以直接編寫成這樣
service-account.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
# service account naem
name: aws-load-balancer-controller
namespace: kube-system
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::<account id>:role/<iam role name>
套用 service account
kubectl apply -f service-account.yaml
檢查是否建立成功
kubectl get serviceaccounts
設定好 OIDC Provider 以及 service account 後緊接著設定 aws application load balancer
參考資料:
3. 設定 aws application load balancer
3–1 helm 安裝 load balancer
helm install aws-load-balancer-controller eks/aws-load-balancer-controller --set clusterName=<cluster name> -n kube-system --set serviceAccount.create=false --set serviceAccount.name=aws-load-balancer-controller --set region=ap-northeast-1 --set vpcId=<vpc id>
3–2 檢查 aws load balancer controller deploy
kubectl get deploy -n kube-system
3–3 檢查是否有產生 aws-load-balancer-controller 的 pod
kubectl get pods -n kube-system
3–4 過一下子後會發現 aws-load-balancer-controller deploy 已建置成功
參考資源:
ps:
ingress 刪除後卡住可以使用以下方式處理
kubectl patch ingress $Ingressname -n $namespace -p '{"metadata":{"finalizers":[]}}' --type=merge
基本配置都完成後,接著建置簡單的 nginx 搭配 load balancer
首先針對 load balancer 會使用的 public subnet 先設定 tag, 這樣 EKS 才會抓到正確的 subnet
Key, Value
kubernetes.io/cluster/<cluster name>, shared
kubernetes.io/role/elb, 1
注意!!! EKS 所預設建立的 Security Group 記得修改 Inbound 允許 ALB 的 Security Group, 否則在做 health check 的時候會失敗。
參考資料:
nginx-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
labels:
nginx: deploy
spec:
selector:
matchLabels:
nginx: pod
template:
metadata:
name: nginx-pod
labels:
nginx: pod
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- name: web-port
containerPort: 80
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 500m
memory: 1Gi
套用 nginx-deploy
kubectl apply -f ./nginx-deploy.yaml
這邊雖然 deploy 設定 1GB memory 0.5 core, 但是因為在運行的時候需要額外分配 256MB 給 Kubernetes ,所以實際 nginx-deploy 的 pod 所佔用的記憶體空間為 2G,因為記憶體規格沒有 1.256 GB 所以會直接分配 2G 給 pod。
參考資源:
nginx-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
labels:
nginx: svc
spec:
type: ClusterIP
selector:
nginx: pod
ports:
- port: 80
targetPort: 80
protocol: TCP
套用 nginx-svc
kubectl apply -f ./nginx-svc.yaml
nginx-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
labels:
nginx: ingress
annotations:
# 棄用
# kubernetes.io/ingress.class: alb
# 目標為 ip for fargate
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}]'
# 指定 security group, 不指定的話 ingress 會幫你自動創建
alb.ingress.kubernetes.io/security-groups: sg-xxx
spec:
# 啟用 aws alb
ingressClassName: alb
rules:
- http:
paths:
- backend:
service:
name: nginx-svc
port:
number: 80
path: /
pathType: Prefix
套用 ingress
kubectl apply -f nginx-ingress.yaml
套用 ingress 後在 AWS EC2 Console 點選 Load balancer 應該會看到正在建立。建立好後可以透過 kubectl 檢查
kubectl get ingress nginx-ingress
輸出:
假如 address 沒有資料的話,代表在建立的過程中發生錯誤。
可以使用 log 去盤查是否 aws-load-balancer-controller 有問題
kubectl logs -f deploy/aws-load-balancer-controller -n kube-system