iT邦幫忙

2021 iThome 鐵人賽

DAY 19
0
DevOps

關於我幫新公司建立整套部屬流程那檔事系列 第 19

EP19 - RE:從零開始學習本機操作 EKS 並手動部署

EP18 - 歡迎來到容器管理工具的 EKS
我們使用 Terraform 搭配 EKS module,
配置了整個 EKS(雖然還沒執行),
今天我們將執行配置,
且配置本機開發環境,
可以在本機連到 AWS 上的 EKS,
並將製作的容器部署到 EKS 中,
除了學習 kubectl 簡易操作外,
也會學習 yaml 的撰寫,
並在配置網頁服務時搭配 AWS 的 ALB。

執行配置

接續昨天寫好的一大串
今天就進行配置吧

因為配置時需要一點時間
光 cluster 本身建立就要 10 分鐘
(全部大概需要 12~15 分鐘)
更別提 autoscaling group 或其他部分
所以 vagrant 中下完指令後
我們先來看看 K8S 中的常用資源
最後再配置本機開發環境

terraform apply

認識 K8S 裡面的資源

建置雲端環境時
將雲端環境中的每個設置理解成資源
而每個實體是資源的型別(RDS、EC2)
這樣會比較好理解

同樣的
在 K8S 的世界中
你要部署一個服務任何的建置都是一個 resource
而這些 resource 有不同的種類(kind)
不同 kind 有不同的參數需要設置

常見的 kind

Namespace

K8S 在建置時
會有個預設的 Namespace
如果沒有指定 Namespace
則建立的資源會建立在 default 底下
要指定建在哪個 Namesapce
需要先建立 Namespace
通常會依據專案名稱來命名

Pod

簡單來說就是執行一個 Container
意義上跟我們在虛擬機械上執行一個容器差不多

Deployment

雖然也會執行 Container
不過用 部署策略 理解比較適合
你可以部署複數的 Pod
甚至指定這些 Pod 位於不同的 Node 上

DaemonSet

也會建立 Pod
不過和 Deployment 和 Pod 又有點不同
而是會在每個 Node 上都建立一個 Pod
通常用於監控或是資料搜集

ConfigMap

供系統使用的 config
並且以 key-value 的 Map 形式存放

Job

起一個容器執行工作
執行完容器就會 Terminate

CronJob

與虛擬機械上的 CronJob 等價
需要設定排程的執行時間
時間到的時候會起一個 Job 執行
一般來說會設置 CronJob
不太會設置 Job

Service

起一個 Web 服務
並且可以設置 Port 的轉發

Ingress

啟動 Service 後
外部並不能直接連到 K8S 內部
要打通內外連線需要靠 Ingress
以往大家很常用 Nginx 當作附載平衡器
來當作路由傳導
因此也有 Nginx Ingress Controller 可以用
有興趣的可以看看這篇
但我們會直接串接到 AWS 的 ALB

重要而且有機會用到

StorageClass

自定義硬碟種類

PersistentVolumeClaim

要硬碟空間

ServiceAccount

定義 Account

ClusterRole

定義 K8S 叢集內的角色

ClusterRoleBinding

將 ServiceAccount 和 ClusterRole 綁定

Role

定義角色

RoleBinding

將 ServiceAccount 與角色綁定

配置本機開發環境

安裝 kubectl

切回根目錄

cd ~

下载最新 kubectl 發行版本

curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"

下载 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

安裝 kubectl

sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl

執行測試確認本機版本

kubectl version --client

安裝 k9s

什麼是 k9s

k9s 是一個 terminal ui 讓我們管理 k8s 叢集

下載 k9s

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 

更改 k9s 權限

sudo chmod +x k9s

搬移到 /usr/local/bin

sudo mv ./k9s /usr/local/bin/

更新 kube config 資訊

一般來說
要維護 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

k9s -A

執行後就可以登入到 EKS 中
查看目前 EKS 的狀態
https://ithelp.ithome.com.tw/upload/images/20211001/20141518TR7QQ8JCCJ.png

其他操作

這部分的操作有點像是 vi/vim
按下 : 會跳到搜尋框
輸入 nodes 可以選擇 cluster 中的 node(也就是 EC2)
輸入 pods 會列出 pod
當然也可以輸入 namespace
來切換 namespace,並進入 namespace 底下查看其底下的資源

想要離開的話
先按下 : 再輸入 quit 即可


撰寫 yaml 並將容器部署到 EKS

前面建立 alb 的部分蠻重要的
這功能幾乎是 AWS EKS 的精髓
除了基本的 K8S 功能之外
不用再自建 Ingress Controller 處理複雜的 Route
可以直接向外打通
接上 ALB 做使用

為 alb 建立 iam role

下載 IAM 政策

curl -o iam_policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.2.0/docs/install/iam_policy.json

建立 IAM 政策

ws iam create-policy \
   --policy-name AWSLoadBalancerControllerIAMPolicy \
   --policy-document file://iam_policy.json

登入 awc cloud console

https://ithelp.ithome.com.tw/upload/images/20211001/20141518hRzvp3b3um.png

進入 IAM Dashboard

https://ithelp.ithome.com.tw/upload/images/20211001/20141518bf2rQe75Ul.png

選擇角色進入角色列表頁

https://ithelp.ithome.com.tw/upload/images/20211001/20141518xq80RJB8Hu.png

建立角色

https://ithelp.ithome.com.tw/upload/images/20211001/20141518aFewu5fPST.png

選擇 Web 身份,並選擇相對應資訊

使用 Terraform 建立時
會自動建立一個身份供應商
選擇 OIDC 開頭的身份供應商
https://ithelp.ithome.com.tw/upload/images/20211001/20141518BkHVZKiw3c.png

選擇剛剛建立的權限

https://ithelp.ithome.com.tw/upload/images/20211001/201415188dSoZ3lV3h.png

輸入標籤

https://ithelp.ithome.com.tw/upload/images/20211001/20141518WtsTK41mbw.png

輸入角色名稱並建立

https://ithelp.ithome.com.tw/upload/images/20211001/20141518IBCUQh5zTo.png

點選剛剛建立的角色檢視角色

https://ithelp.ithome.com.tw/upload/images/20211001/20141518vgisrXKRT7.png

選擇信任關係並按下編輯

https://ithelp.ithome.com.tw/upload/images/20211001/20141518kVu2KcGTqI.png

替換文字並更新

尋找看起來類似如下的行:

"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

https://ithelp.ithome.com.tw/upload/images/20211001/201415188vS5odfy0j.png

安裝cert-manager將證書配置注入到 webhook 中

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

編輯控制器規格

  • 刪除ServiceAccount的區段。刪除此區段可防止在部署控制器時覆寫具有 IAM 角色的註釋,如果您刪除控制器,則會保留剛剛建立的服務帳戶。
  • Replaceyour-cluster-name 到 Deployment spec 區段,其中包含您的叢集名稱。

執行配置

kubectl apply -f v2_2_0_full.yaml

https://ithelp.ithome.com.tw/upload/images/20211001/201415184BY6rpWqIV.png

確認控制器安裝狀態

kubectl get deployment -n kube-system aws-load-balancer-controller

https://ithelp.ithome.com.tw/upload/images/20211001/20141518ivNVuQx6OU.png

查看 cert arn

登入 aws cloud console
在搜尋框輸入 Cert Manager
可以看到之前我們使用 Terraform 要求建立的公發憑證

https://ithelp.ithome.com.tw/upload/images/20211001/20141518ytDALRvNc6.png

複製 web acl arn

登入 aws cloud console
在搜尋框輸入 WAF
並在側欄中選擇 Web ACLs

Web ACLs 列表中選擇之前建立的 fundamental-acl
在這之後在點按 Copy ARN
https://ithelp.ithome.com.tw/upload/images/20211001/20141518KhzPWcbP1U.png

撰寫部署用的 yaml 檔案

在 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 上面看到警告
https://ithelp.ithome.com.tw/upload/images/20211001/20141518K7fHLMkOsZ.png

這警告是因為 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 原文件描述來建立

參考資料:

  1. 在 Linux 系统中安装并设置 kubectl
  2. k9scli
  3. Install k9s on Ubuntu
  4. 建立kubeconfigAmazon EKS
  5. AWSLoad Balancer 控制器
  6. IngressClass
  7. Ingress v1 and v1beta1 Differences

上一篇
EP18 - 歡迎來到容器管理工具的 EKS
下一篇
EP20 - 整合 Jenkins 自動部署到 EKS
系列文
關於我幫新公司建立整套部屬流程那檔事30

尚未有邦友留言

立即登入留言