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

<<:  Day15:关於 WebRTC

>>:  待更新

[Pytorch] torchvision.transforms()

torchvision.transforms() Transforms are common im...

【Day 3】BERT的输出与它们的意义

BERT输出了什麽? 回应上一篇关於词嵌入Token Embedding的讨论,BERT的输出就是文...

成员 14 人:如何养好一池鲨鱼水族箱

「干部不强,我身上尽是汗水味;  干部太强,我身旁满是血腥味。」 年轻时候 待过的公司,共有三个部门...

Day 11 - 那个很常用到的 useEffect

如果有错误,欢迎留言指教~ Q_Q 先说说什麽是 side effect ? 就是不在主要的程序执...

Python侦测VPN网路是否可连线 - Python练习题二

公司为跨国企业, 与工厂间的数据利用VPN进行资料交换, 利用Python配合Windows的排程记...