Kubernetes Fargate 部署操作

Gary Ng
16 min readOct 5, 2024

--

此篇將教學如何在 AWS EKS 運行 Fargate

首先我們先透過 AWS EKS 建立 Cluster, 建立完後緊接著設定 Fargate。

  1. 建立 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 可以存取的權限

  1. 點選 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

  1. 首先建立 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 記得要配置以下網址的權限

https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/main/docs/install/iam_policy.json

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
正確結果

--

--

Gary Ng
Gary Ng

Written by Gary Ng

軟體工程師、後端工程師

No responses yet