在 EP18 - 歡迎來到容器管理工具的 EKS,
我們使用 Terraform 搭配 EKS module,
配置了整個 EKS(雖然還沒執行),
今天我們將執行配置,
且配置本機開發環境,
可以在本機連到 AWS 上的 EKS,
並將製作的容器部署到 EKS 中,
除了學習 kubectl 簡易操作外,
也會學習 yaml 的撰寫,
並在配置網頁服務時搭配 AWS 的 ALB。
接續昨天寫好的一大串
今天就進行配置吧
因為配置時需要一點時間
光 cluster 本身建立就要 10 分鐘
(全部大概需要 12~15 分鐘)
更別提 autoscaling group 或其他部分
所以 vagrant 中下完指令後
我們先來看看 K8S 中的常用資源
最後再配置本機開發環境
terraform apply
建置雲端環境時
將雲端環境中的每個設置理解成資源
而每個實體是資源的型別(RDS、EC2)
這樣會比較好理解
同樣的
在 K8S 的世界中
你要部署一個服務任何的建置都是一個 resource
而這些 resource 有不同的種類(kind)
不同 kind 有不同的參數需要設置
K8S 在建置時
會有個預設的 Namespace
如果沒有指定 Namespace
則建立的資源會建立在 default 底下
要指定建在哪個 Namesapce
前
需要先建立 Namespace
通常會依據專案名稱來命名
簡單來說就是執行一個 Container
意義上跟我們在虛擬機械上執行一個容器差不多
雖然也會執行 Container
不過用 部署策略
理解比較適合
你可以部署複數的 Pod
甚至指定這些 Pod 位於不同的 Node 上
也會建立 Pod
不過和 Deployment 和 Pod 又有點不同
而是會在每個 Node 上都建立一個 Pod
通常用於監控或是資料搜集
供系統使用的 config
並且以 key-value 的 Map 形式存放
起一個容器執行工作
執行完容器就會 Terminate
與虛擬機械上的 CronJob 等價
需要設定排程的執行時間
時間到的時候會起一個 Job 執行一般來說會設置 CronJob
不太會設置 Job
起一個 Web 服務
並且可以設置 Port 的轉發
啟動 Service 後
外部並不能直接連到 K8S 內部
要打通內外連線需要靠 Ingress
以往大家很常用 Nginx 當作附載平衡器
來當作路由傳導
因此也有 Nginx Ingress Controller 可以用
有興趣的可以看看這篇
但我們會直接串接到 AWS 的 ALB
自定義硬碟種類
要硬碟空間
定義 Account
定義 K8S 叢集內的角色
將 ServiceAccount 和 ClusterRole 綁定
定義角色
將 ServiceAccount 與角色綁定
cd ~
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
curl -LO "https://dl.k8s.io/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl.sha256"
echo "$(<kubectl.sha256) kubectl" | sha256sum --check
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
kubectl version --client
k9s 是一個 terminal ui 讓我們管理 k8s 叢集
curl -L https://github.com/derailed/k9s/releases/download/v0.24.15/k9s_Linux_x86_64.tar.gz --output k9s.tar.gz
sudo tar zxvf k9s.tar.gz
sudo chmod +x k9s
sudo mv ./k9s /usr/local/bin/
一般來說
要維護 K8S 需要 kubeconfig 這東西
通常在建立 K8S 時就會產生
但是使用 EKS 後
K8S 外面會被 AWS 再包一層
透過 IAM 的方式來認證權限
這時候我們就可以下 aws cli
透過 command line 來抓取並更新 kubeconfig 資訊
aws eks --region ap-northeast-1 update-kubeconfig --name aws-stage-cluster
k9s -A
執行後就可以登入到 EKS 中
查看目前 EKS 的狀態
這部分的操作有點像是 vi/vim
按下 :
會跳到搜尋框
輸入 nodes 可以選擇 cluster 中的 node(也就是 EC2)
輸入 pods 會列出 pod
當然也可以輸入 namespace
來切換 namespace,並進入 namespace 底下查看其底下的資源
想要離開的話
先按下 :
再輸入 quit
即可
前面建立 alb 的部分蠻重要的
這功能幾乎是 AWS EKS 的精髓
除了基本的 K8S 功能之外
不用再自建 Ingress Controller 處理複雜的 Route
可以直接向外打通
接上 ALB 做使用
curl -o iam_policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.2.0/docs/install/iam_policy.json
ws iam create-policy \
--policy-name AWSLoadBalancerControllerIAMPolicy \
--policy-document file://iam_policy.json
使用 Terraform 建立時
會自動建立一個身份供應商
選擇 OIDC 開頭的身份供應商
尋找看起來類似如下的行:
"oidc.eks.us-west-2.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E:aud": "sts.amazonaws.com"
替換為
"oidc.eks.region-code.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E:sub": "system:serviceaccount:kube-system:aws-load-balancer-controller"
請記下角色的 ARN,以便在稍後步驟中使用。
cd ~
sudo touch aws-load-balancer-controller-service-account.yaml
將 eks.amazonaws.com/role-arn
替換為前一步驟建立的 role
aws-load-balancer-controller-service-account.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/name: aws-load-balancer-controller
name: aws-load-balancer-controller
namespace: kube-system
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::111122223333:role/AmazonEKSLoadBalancerControllerRole
kubectl apply -f aws-load-balancer-controller-service-account.yaml
kubectl apply \
--validate=false \
-f https://github.com/jetstack/cert-manager/releases/download/v1.1.1/cert-manager.yaml
curl -o v2_2_0_full.yaml https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.2.0/docs/install/v2_2_0_full.yaml
kubectl apply -f v2_2_0_full.yaml
kubectl get deployment -n kube-system aws-load-balancer-controller
登入 aws cloud console
在搜尋框輸入 Cert Manager
可以看到之前我們使用 Terraform 要求建立的公發憑證
登入 aws cloud console
在搜尋框輸入 WAF
並在側欄中選擇 Web ACLs
Web ACLs 列表中選擇之前建立的 fundamental-acl
在這之後在點按 Copy ARN
在 portal 專案的根目錄底下建立 deploy.yaml
這個檔案
apiVersion: v1
kind: Namespace
metadata:
name: ithome-ironman
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: portal
namespace: ithome-ironman
spec:
replicas: 1
selector:
matchLabels:
app: portal
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
minReadySeconds: 10
template:
metadata:
name: portal
labels:
app: portal
spec:
containers:
- name: portal
image: 你的 ECR repository
ports:
- name: portal
containerPort: 31000
resources:
limits:
memory: "512M"
cpu: "300m"
requests:
memory: "200M"
cpu: "100m"
---
apiVersion: v1
kind: Service
metadata:
name: portal
namespace: ithome-ironman
annotations:
prometheus.io/scrape: 'true'
prometheus.io/port: '80'
spec:
selector:
app: portal
type: ClusterIP
ports:
- name: portal
port: 80
protocol: TCP
targetPort: 80
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: portal-ingress
namespace: ithome-ironman
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/wafv2-acl-arn: "你的 WEB ACL ARN"
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/healthcheck-path: '/'
alb.ingress.kubernetes.io/subnets: '公開的 subnet id'
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP":80}, {"HTTPS":443}]'
alb.ingress.kubernetes.io/certificate-arn: "剛剛查到 certification 的 arn"
alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
spec:
rules:
- http:
paths:
- path: /*
backend:
serviceName: ssl-redirect
servicePort: use-annotation
- path: /*
backend:
serviceName: portal
servicePort: 80
kubectl apply -f deploy.yaml
執行完後
會在 console 上面看到警告
這警告是因為 networking.k8s.io/v1beta1
從 1.20 版開始就開始不建議使用
1.22 版以後就會拿掉
但目前無論是參考 IngressClass 或是 Ingress v1 and v1beta1 Differences
都還沒有一個建議的寫法
在 Github 上也有相關的討論
但是仍舊沒有結果
因此目前就暫時不使用 networking.k8s.io/v1
繼續維持此寫法
今天我們展示了如何手動部署到 EKS
為了要能夠使用 ALB 以及掛載憑證
我們還要另外建立一個角色
讓這角色是有權限可以進入到 EKS 中
建立一個 Ingress Controller 並綁定這角色
好像我們在建立 Ingress 的時候
可以自動建立 ALB 而且自動綁定 Web ACLs
美中不足的地方是建立 Ingress Controller 的時候
我們是透過手動
雖然知道如何建立 IAM Policy
不過建立 Web 服務的 IAM Role 的時候有點當機
因此還是按照 AWS 原文件描述來建立
參考資料: