iT邦幫忙

2021 iThome 鐵人賽

DAY 19
0
DevOps

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

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

  • 分享至 

  • xImage
  •  

在 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 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言