# K8s on Amazon EKS ###### tags: `AWS`,`EKS`,`Kubernetes` 整理在 Amazon EKS 運行 k8s v1.28 的學習資料,以下範例內容需要先安裝下列指令工具 - [kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl) - [helm](https://helm.sh/docs/intro/install/) - [aws cli](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) ## Kubernetes(K8s) 自動部署、擴充和管理「容器化應用程式」的開源系統。 ### Deployment 演進 ![](https://i.imgur.com/a7d098f.png) ### K8s 架構 - K8s cluster 是由節點(node)所構成的,每個節點可運作多個 containers。 - 分成兩個 Components:Control Plane(Master) 及 worker node(s)。 - 最小部署單位是 pod,pod 可含多個 containers,同一個 pod 會共享 storage 及 network,one-container-per-Pod 是 k8s 常見使用方式。 - 支援符合 [Kubernetes CRI(Container Runtime Interface)](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-node/container-runtime-interface.md) 的 container runtime 應用軟體(EX: Docker(Dockershim 實作)、containerd、CRI-O) ![](https://i.imgur.com/TUF46zv.png) ![](https://i.imgur.com/fLMl8sd.png) ### Control Plane(Master) Components k8s 核心 pods,監聽事件、管理各節點等等工作 #### kube-apiserver - 所有的 K8s 內部操作都是透過 Kubernetes API - HTTP-based RESTful API,目前有支援 HTTPS,但不會進行驗證跟解密,須確保內部通訊是在安全非公開的網路環境,另有提供 TCP level proxy 的 [Konnectivity service](https://kubernetes.io/docs/tasks/extend-kubernetes/setup-konnectivity/) 擴展取代現有的 HTTP-based 機制(v1.20 還是 beta) #### etcd 儲存 cluster 資料,key–value database。 #### kube-scheduler 分配最適合的 node 來執行 pod。 #### kube-controller-manager 管理 nodes、tasks、endpoints、service account & token #### 其他插件 - DNS: Kubernetes 内部域名的解析 - Web UI (Dashboard): web-based UI for Kubernetes clusters ### Node(Worker node) Components #### kubelet 安裝於每一個 Node 上,負責與 API Server 溝通,也包含初始化並且將自己納入到整個 Cloud Cluster 的管理 ##### Dockershim - Docker 原生不支援 k8s CRI,為了讓 kubelet 可執行 docker 指令,出現 Dockershim 讓 kubelet 與 Docker 可透過 k8s CRI 溝通,kubelet 包含 Dockershim 程式碼 - k8s v1.20 之後將棄用 Dockershim,預計 [v1.23 會從 kubelet 移除](https://kubernetes.io/blog/2020/12/02/dockershim-faq/#when-will-dockershim-be-removed) ![](https://i.imgur.com/fZchQBc.png) #### kube-proxy 安裝於每一個 Node 上,維護 Node 上的 network rules,負責內外部通訊 service 會在節點建立一組虛擬 clusterIP 和 port,並透過 kube-proxy 連線至多個 pods,下圖是 User space proxy mode 運作模式 ![](https://i.imgur.com/vUAnyQM.png) ### Kubernetes Objects - Objects 內容會存在 k8s 系統裡頭,k8s 會確保 objects 內設定的東西正常運作,可透過 Kubernetes API 針對 objects 進行 CRUD 操作 - kubectl 指令可將 `.yaml` 設定檔轉成 JSON 並對 Kubernetes API 發出請求,目前常見是以這種方式操作 k8s 設定(`kubectl apply -f xxx.yml`) - 每個 object 都會有一組 UUID ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: ... ``` #### apiVersion and kind k8s object kind 有分成很多種,例如 Pod、Deployment、Namespace、Role 等等,這些種類會對應到不同 api version,例如 `v1`、`apps/v1`、`v1`、`rbac.authorization.k8s.io/v1` 等等,要去官網確認 #### metadata 為 object 設定一些屬性 - name: 為 object 命名 - namespace: 在一個實體 cluster 下可用 namespace 區隔不同 virtual clusters,k8s 系統相關的服務會在 `kube-system` namespace 下運行 - labels: 可設定一組或多組標籤識別 object,EX: `app: my-nginx` ```yaml apiVersion: v1 kind: Pod metadata: name: label-demo namespace: my-test labels: app: my-nginx spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80 ``` 取得標籤 environment=production 的 pods ``` kubectl get pods -l environment=production ``` - selector: 指定 NodePort service 80 port 通往 label 為 `app: my-nginx` 的 pod ```yaml apiVersion: v1 kind: Service metadata: name: label-demo-service namespace: my-test spec: type: NodePort selector: app: my-nginx ports: - port: 80 targetPort: 80 protocol: TCP ``` ### Kubernetes Object kinds k8s object 有很多 kinds,以下列出常見的 #### Pod - Kubernetes 最小運作單位 - 可包含一個或多個 contianers,彼此會共享 network 、namespaces & filesystem volumes,pod 內可透過 localhost 與其他 contianers 連線 - 每個 pod 都會分配到一個唯一的 ip - 查看 pod state: `kubectl describe pod <name-of-pod>` #### Deployment & ReplicaSet - 可將 Pod 做橫向擴展,並監控 Pod,有問題時會重新啟動 - Rolling Update pod,可做到 Zero Downtime,Rolling Update 時會新建 ReplicaSet,新啟動的 pod 會綁定到新的 ReplicaSet,之後再關閉舊的 ReplicaSet,這是由 replication controller 負責 - 有 Rolling Back 機制 ![](https://i.imgur.com/4L26cQ3.png) 透過 Deployment 建立三個 nginx pod ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx spec: replicas: 3 template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80 ``` #### ConfigMap 可設定 config 參數,然後 map 到 pod 環境變數 ```yaml apiVersion: v1 kind: ConfigMap metadata: name: web-env namespace: my-test data: APP_ENV: dev DB_HOST: xxx DB_DATABASE: ooo DB_USERNAME: vvv DB_PASSWORD: abc ``` #### HorizontalPodAutoscaler [Horizontal Pod Autoscaler](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale) 是基於 Pod 某個指標(EX: CPU、Memery)使用率的水平擴充,Controller Manager 會進行監控 ![](https://i.imgur.com/OlwTbHA.png) 必須在每個 container 的 `resources.requests` 設定佔用資源請求數量,並且在 HPA 設定達到某個比例或上限值時要自動擴展,下面是設定 pod 佔用 100m(0.1 vCPU) ```yaml apiVersion: v1 kind: Pod metadata: name: test spec: containers: - name: test image: nginx resources: requests: cpu: 100m ``` HPA 的擴展門檻是依據 pod 佔用資源的平均值,假設 ReplicaSet 設定 2 個 pods,而 HPA 設定 CPU `averageUtilization` 為 80%,當一個 pod 使用率達 100%,另一個為 0 % 時,因平均起來是 50%,未達水平擴展門檻 #### Service Network service,執行 service discovery & load-balance,主要可分成無 `selectors` 跟有 `selectors` #### 無 `selectors` service 無 `selectors`,無 `selectors` 不會產生 endpoints ,要自行指定 endpoints - Service object ```yaml apiVersion: v1 kind: Service metadata: name: my-service spec: ports: - protocol: TCP port: 80 targetPort: 9376 ``` - Endpoints object ```yaml apiVersion: v1 kind: Endpoints metadata: name: my-service subsets: - addresses: - ip: 192.0.2.42 ports: - port: 9376 ``` #### 有 `selectors` service service 會為 pods 分配 ip 及 DNS name,透過 selector 綁定這些 pod 的連線及存取,建立 pod 之間負載均衡 - Service object ```yaml apiVersion: v1 kind: Service metadata: name: my-service spec: selector: app: MyApp ports: - protocol: TCP port: 80 targetPort: 80 ``` - Deployment object ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx spec: replicas: 3 selector: matchLabels: app: MyApp template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80 ``` 以下介紹 service 的三種 type: - ClusterIP:預設此種 type,僅能由 cluster 內部透過虛擬的 ClusterIP 存取 - NodePort:在節點(node)上開一個 port(30000-32767),cluster 外部可以透過這 node port 映射到設定的 pods(`<CLUSTER-IP>:<node port>`) ![](https://i.imgur.com/Rcp4Clu.png) - LoadBalancer:要與外部的 load balancer 服務整合,EX: AWS ELB ![](https://i.imgur.com/GCiX7vg.png) #### Ingress 反向代理的概念,透過 HTTP and HTTPS routes (domain or path),從外連線到 cluster 內的 service,讓 service 保持在 private network,不暴露在外 k8s 內有多種服務可以可慮使用這方式,EX:不同的子網域對應到不同專案 ![](https://i.imgur.com/2elA7Kn.png) - 使用 Ingress 需搭配 Ingress Controllers,不同服務商有自己的實現方式,可參考 [Additional controllers](https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/#additional-controllers) - Ingress 搭配的 Service type 為 NodePort,Ingress 會對應到某個 cluster 配發的 node port ## Helm K8S 會有很多種 Object kind 的 yaml 設定檔,而 Helm 會將 K8S 的服務中的各種 yaml 檔案打包成一個叫做 chart 的集合,並且接受**帶入參數**的方式管理 K8S yaml 檔案,讓 K8S 在管理上更加彈性,不需要一個一個 yaml 部署。 ![](https://i.imgur.com/eRVKKql.png) 當 chart 安装到 k8s 後會創建一個 release,每次更新時 release 的版本數就會加 1。同一個chart 可以部署多次。 ### Values 透過 Values.yaml 可將參數傳遞給 k8s yaml - Values.yaml: ```yaml favoriteDrink: coffee ``` - k8s 設定 `{{ .Values.favoriteDrink }}` 即可取到 Values 參數 ```yaml apiVersion: v1 kind: ConfigMap metadata: name: {{ .Release.Name }}-configmap data: myvalue: "Hello World" drink: {{ .Values.favoriteDrink }} ``` - 也可透過 `--set` 去複寫參數 ``` helm install --set favoriteDrink=beer <release name> <chart dir> ``` ### 安裝 ``` helm install <自訂的 release name> <chart 資料夾> helm get manifest <自訂的 release name> EX: helm install --set laravel.app.env=dev --set laravel.db.password=xxxxx --set laravel.redis.password=ooooo burgess-backend ./burgess-backend helm get manifest burgess-backend ``` ### 更新 ``` helm upgrade --set image.tag=0.0.1 burgess-backend ./burgess-backend ``` ### 更新 or 沒有該 release 的話執行安裝 ``` helm upgrade --instal --set laravel.app.env=dev --set laravel.db.password=xxxxx --set laravel.redis.password=ooooo burgess-backend ./burgess-backend ``` ### 移除 ``` helm uninstall <自訂的 release name> helm uninstall burgess-backend ``` ## Amazon EKS ### 架構 EKS Cluster 會建立 master(control plane),並整合了 Log(CloudWatch) 及 IAM認證,而我們可以針對應用得 pods 進行部署,部署可以選擇使用 EC2 or Fargate ![](https://i.imgur.com/5rpG7mp.png) ### Cluster log - API server - Controller manager - Scheduler - Audit:記錄了由用戶、管理員或系統 security 相關的活動‘ - Authenticator:AWS 各服務間認證授權的紀錄 ### Cluster authentication 若其他 client 端要操作 k8s cluster,一般來說會建立 [Service Account](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#service-account-tokens),取得 token 後可進行某個 namespaces 下的 cluster 操作。而 EKS 做法有些不同,是先經過 AWS identity 驗證後,再透過 k8s API 與 RBAC 做認證 ![](https://i.imgur.com/rq9iwom.png) 必須為 client 準備一組 iam user,並且在 cluster aws-auth 中註冊該 user 的 ARN,細節可參考 [管理叢集的使用者或 IAM 角色](https://docs.aws.amazon.com/zh_tw/eks/latest/userguide/add-user-role.html) 和 [MAP AN IAM USER TO K8S](https://www.eksworkshop.com/beginner/090_rbac/map_iam_user_to_k8s_user/) #### kubectl patch 方式修改 aws-auth ConfigMap 若要寫成指令方式,可以用 kubectl patch 去修改,準備一個 `aws-auth-user.yml` ```yml data: mapUsers: | - userarn: <iam user 的 ARN> username: burgess-backend-deployer groups: - system:masters ``` 接著執行下列指令即完成註冊,該 iam user 就可操作 EKS cluster ``` kubectl patch configmap/aws-auth -n kube-system --patch "$(cat ./aws-auth-user.yml)" ``` ### Nodes(Worker Nodes) #### EKS managed node groups - 可選擇 EC2 Instance Types、DiskSize,要注意每種可執行的 pods 數目上限,可參考 [eni-max-pods](https://github.com/awslabs/amazon-eks-ami/blob/master/files/eni-max-pods.txt)。(每個 pod 都佔用一個私有 IP,不同 Instance Type 因 network interfaces 上限,可提供的私有 IP 數量不一樣) - 每個 node 至少會佔用 2 個 kube-system 的 pods:aws-node & kube-proxy,其他基本的 pod 須依需求自行安裝,如果有使用 Horizontal Pod Autoscaler、Kubernetes Dashboard.,必須加裝 metrics-server pod 搜集數據;使用 Cluster Autoscaler 需安裝 cluster-autoscaler-autodiscover 監控 pod 使用狀況 - 可設定 node scaling 範圍,會自動擴展或減少 #### Self-managed nodes 自己維運 node,node 依附在 EKS cluster 介接,設定較複雜,請參考 [Self-managed nodes](https://docs.aws.amazon.com/eks/latest/userguide/worker.html) #### Fargate - 僅需設定 CPU 跟 memery - 可設定 Scaling 範圍,會自動擴展或減少,擴展速度比 EC2 快 - 不需要管理 nodes ![](https://i.imgur.com/pJPNw2d.png) ### 其他需自行安裝的 Add-ons(pod) #### Cluster Autoscaler 當 Pod 出現故障或重新調度到其他節點時,Kubernetes Cluster Autoscaler 會自動調整 cluster 中的 nodes 數量,EKS managed node groups 是透過 Amazon EC2 Auto Scaling Groups 進行管理 安裝步驟可參考 [Cluster Autoscaler](https://docs.aws.amazon.com/eks/latest/userguide/cluster-autoscaler.html) #### Horizontal Pod Autoscaler on EKS HPA 是 Kubernetes 中的標準 API 資源,在 EKS 需額外安裝 metrics server,它監控 HPA 需要的 pod 指標 檢查有沒有安裝 metrics server ``` kubectl -n kube-system get deployment/metrics-server ``` 安裝步驟可參考 [Horizontal Pod Autoscaler](https://docs.aws.amazon.com/zh_tw/eks/latest/userguide/horizontal-pod-autoscaler.html) #### AWS Load Balancer Controller 如果我們想要透過 Load Balancer 連至我們部署的 pods,需要安裝 [aws-load-balancer-controller](https://docs.aws.amazon.com/eks/latest/userguide/aws-load-balancer-controller.html),EKS 支援 Network Load Balancer(NLB) 及 Application Load Balancer(ALB) 兩種 Load Balancer,差異可參考 [Elastic Load Balancing 功能](https://aws.amazon.com/tw/elasticloadbalancing/features/) #### Network Load Balancer(NLB) - 將 k8s `Service` type 設定為 `LoadBalancer` 會用此種 Load Balancer 處理 network traffic - L4 of the OSI model,根據 IP + port 做負載均衡 - 安裝設定請參考 [Network load balancing on Amazon EKS](https://docs.aws.amazon.com/eks/latest/userguide/network-load-balancing.html) #### Application Load Balancer(ALB) - 建立 k8s Ingress 會用此種 Load Balancer 處理 network traffic,`Service` Type 可設定為 `NodePort` 或指定 pod ip - L7 of the OSI model,可根據域名、內文做負載均衡,會做 TCP 交握,比較耗時 - listener 定義的規則,決定請求到目標的方法 - target group 使用指定的協議和 port,將請求導到一個或多個目標。可以針對每個 target group 運作狀態做檢查 - 安裝設定可參考 [Application load balancing on Amazon EKS](https://docs.aws.amazon.com/eks/latest/userguide/alb-ingress.html) ![](https://i.imgur.com/DmK7vi2.png) 注意:subnet tag 務必加入 `kubernetes.io/cluster/<cluster-name> = shared or owned`,ingress 不會自動加入,必須手動 #### Kubernetes Dashboard (web UI) Kubernetes Dashboard 透過 web UI 介面查看 k8s 運作情形,參考 [Deploy the Kubernetes Dashboard](https://docs.aws.amazon.com/eks/latest/userguide/dashboard-tutorial.html) 安裝 ### CloudFormation 部署 EKS Cluster 範例 AWS CloudFormation 是透過 yaml 檔建置 AWS 服務的工具,達到 Infrastructure as Code (IaC)的目的,類似的工具有 Terraform、Ansible、Puppet、AWS CDK、Azure Resource Manager、Google Cloud Deployment Manager 等等 #### EKS Cluster - 建立一個 master(control plane) - 會在 subnet 加必要的 tag ```yaml= Type: AWS::EKS::Cluster Properties: Name: !Ref ClusterName ResourcesVpcConfig: SubnetIds: - subnet-879a6bcf - subnet-7502c313 RoleArn: !GetAtt [EKSClusterRole, Arn] Version: !Ref K8SVersion ``` #### EKS Nodegroup - 建立一個 EC2 Worker Node 以及 Amazon EC2 Auto Scaling Group - AWS 會在每個 node(EC2) 運行基本必要的 pods(aws node、proxy) - DesiredSize 兩台以上會自動跨 AZ ```yaml= Type: AWS::EKS::Nodegroup Properties: ClusterName: !Ref EKSCluster DiskSize: 4 InstanceTypes: - t2.small Labels: app: burgess-laravel NodeRole: !GetAtt [EKSNodeInstanceRole, Arn] ScalingConfig: DesiredSize: 1 MinSize: 1 MaxSize: 10 Subnets: - subnet-879a6bcf - subnet-7502c313 ``` ### 部署服務 #### 部署 EKS ``` aws --region ap-southeast-1 cloudformation deploy --template-file eks.yml --stack-name cf-eks-demo --parameter-overrides ClusterName=<cluster name> K8SVersion=<version> ``` #### 設定 kubectl 與 EKS cluster 連結 ``` aws eks --region ap-southeast-1 update-kubeconfig --name <cluster name> ``` #### 設定 aws auth user 1. 建立 aws-auth-user.yml 以下可以建立某個 user or role 具有 master 權限 ```yml data: mapUsers: | - userarn: arn:aws:iam::xxxxxx:user/EKSDeployer username: eks-deployer groups: - system:masters - userarn: arn:aws:iam::xxxxx:user/burgess username: burgess groups: - system:masters ``` 2. 部署 aws-auth-user 下列指令將 aws-auth-user 設定至 EKS,就可以用該 user or role 進行 cluster 操作 ``` kubectl apply -f aws-auth-user.yaml kubectl get configmap -n kube-system aws-auth -o yaml ``` 3. 透過 helm 部署自己的 pod 下列指令將 `./my-app` 資料夾下的 k8s yaml 設定檔案部署到 worker node ``` helm upgrade --install --set clusterName=<cluster name> my-app ./my-app ``` ### 移除部署 ``` aws --region ap-southeast-1 cloudformation delete-stack --stack-name cf-eks-demo ``` ### 常用指令 - 查看所有 namespace 下的 pods ``` kubectl get pods --all-namespaces ``` - 查看 pod 設定細節 ``` kubectl describe pod <pod name> -n=<namespace> ``` - 進入某個 pod ``` kubectl exec -it -n=<namespace> <pod name> –- /bin/sh ``` - 刪除 pod ``` kubectl delete pods <pod name> ``` - 刪除 Evicted pod ``` kubectl get pod -n <namespace> | grep Evicted | awk '{print $1}' | xargs kubectl delete pod -n <namespace> ``` - 查看所有 namespaces ``` kubectl get namespace ``` - 查看 namespace 下所有服務 ``` kubectl get all -n <namespace> ``` - 查看某個 pod 的 log ``` kubectl logs <pod name> -n <namespace> ``` ### 注意事項 #### helm 設定檔名問題 helm 使用的 Chart.yaml 跟 values.yaml 副檔名名稱必須為 `.yaml`,改成 `.yml` 將不會載入 #### configmap 只收字串 pod env 設定必須為字串,使用 configmap 時若為數字 or boolen 記得轉為字串(quote) EX: ``` data: APP_DEBUG: {{ .Values.laravel.app.debug | quote }} DB_PORT: {{ .Values.laravel.db.port | quote }} ``` #### GET / 保持暢通 kube-proxy 會一直 call pods...請保持 `GET /` 暢通... #### k8s namespace 綁定 helm release 同一 cluster 中,如果某個 k8s 服務的某個 namespace 給 helm release A 部署,helm release B 將無法部署那個 namespace ### k8s 升級 k8s 版本升級很快,常常會有相容性問題,[Amazon EKS Kubernetes versions](https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-versions.html) 有說明各版本相容問題,最好的做法是升級 k8s 前先把相關 kinds 的 apiVersion 升級,否則可能遇到新版 k8s 不支援舊版 kinds 的 apiVersion 以下列出遇到的錯誤 #### 執行 eksctl 指令遇到 `error: exec plugin: invalid apiVersion "<出問題的版本>"` eksctl 取 EKS 資料發生問題,試著升級 kubectl & aws-cli,kubectl 升級至對應的 k8s 版本,運行 aws eks update-kubeconfig --region <your region> --name <EKS cluster name> 重新取得認證資料 #### helm upgrade 時發生 `Error: UPGRADE FAILED: current release manifest contains removed kubernetes api(s) for this kubernetes version and it is therefore unable to build the kubernetes objects for performing the diff.` Helm upgrade 時會比對前後 release 差異,helm 是以當前 k8s 版本支援的 apiVersion 為準,當進行 k8s 升級及 apiVersion 更新時,可能會發生舊版支援,但新版不支援,這時做 diff 會顯示舊版設定不支援的錯誤 EX: k8s v1.22 起不支援 `apiregistration.k8s.io/v1beta1`,要改成 `apiregistration.k8s.io/v1`,如果先把 k8s 升級,當執行 helm upgrade 時,會比對出當前 k8s 版本不支援舊 release 的 `v1beta1` 版本設定而發生 UPGRADE FAILED 這時要先去修改舊 release 設定,可參考 [Updating API Versions of a Release Manifest](https://helm.sh/docs/topics/kubernetes_apis/#updating-api-versions-of-a-release-manifest),安裝 helm mapkubeapis 調整或手動調整,調整原 release 中的無效版本後再執行 helm upgrade #### Service EXTERNAL-IP 一直是 pending 狀態 執行 `kubectl get svc --all-namespaces`,如果要 public 的 service 的 EXTERNAL-IP 一直是 pending 狀態,代表 service 跟 load balancer 串接有異常,可以執行 `kubectl describe svc <service name> -n <namespace>` 查看異常原因,並參考 https://aws.amazon.com/tw/premiumsupport/knowledge-center/eks-load-balancer-webidentityerr/ 解決問題 ## 參考資料 - [k8s 官方文件](https://kubernetes.io/docs/home/) - [Getting Started with Kubernetes (K8s)](https://medium.com/@bhargavshah2011/getting-started-with-kubernetes-k8s-6e84ec4f76a4) - [Kubernetes 只有淺出沒有深入 (K8s 架構介紹)](https://blog.toright.com/posts/6416/kubernetes-intro.html) - [Kubernetes 基礎教學系列](https://medium.com/@C.W.Hu/kubernetes-basic-concept-tutorial-e033e3504ec0) - [透過 Kubernetes Deployments 實現滾動升級](https://tachingchen.com/tw/blog/kubernetes-rolling-update-with-deployment/) - [Kubernetes NodePort vs LoadBalancer vs Ingress? When should I use what?](https://medium.com/google-cloud/kubernetes-nodeport-vs-loadbalancer-vs-ingress-when-should-i-use-what-922f010849e0) - [Amazon EKS User Guide](https://docs.aws.amazon.com/eks/latest/userguide/what-is-eks.html) - [Deploying a Kubernetes Cluster with Amazon EKS](https://logz.io/blog/amazon-eks-cluster/) - [AWS Elastic Load Balancing 文件](https://docs.aws.amazon.com/elasticloadbalancing/index.html) - [Elastic Load Balancing 功能](https://aws.amazon.com/tw/elasticloadbalancing/features/) - [AWS CloudFormation EKS](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/AWS_EKS.html) - [如何利用 Managed Node Group 高效管理 Amazon EKS 集群](https://aws.amazon.com/cn/blogs/china/how-to-manage-amazon-eks-clusters-with-managed-node-group-preface/) - [如何在 Amazon EKS 中的 Amazon EC2 节点上设置 ALB 入口控制器?](https://aws.amazon.com/cn/premiumsupport/knowledge-center/eks-alb-ingress-controller-setup/) - [Kubernetes Ingress 与 AWS ALB Ingress 控制器的配合使用](https://aws.amazon.com/cn/blogs/china/kubernetes-ingress-aws-alb-ingress-controller/) - [AWS ALB Ingress Controller](https://kubernetes-sigs.github.io/aws-alb-ingress-controller/) - [troubleshoot pod status in Amazon EKS](https://aws.amazon.com/tw/premiumsupport/knowledge-center/eks-pod-status-troubleshooting/) - [CoreDNS 系列](https://hansedong.github.io/2018/11/20/9/) - [Kubernetes Rolling Update Configuration](https://www.bluematador.com/blog/kubernetes-deployments-rolling-update-configuration) - [Helm 官方文件](https://helm.sh/docs/) - [使用Helm管理kubernetes应用](https://jimmysong.io/kubernetes-handbook/practice/helm.html) - [MAP AN IAM USER TO K8S](https://www.eksworkshop.com/beginner/090_rbac/map_iam_user_to_k8s_user/)