備忘録：kubernetes/EKS基礎②(k8sコンポーネント)

# 備忘録

* kustomizeの使用
* AWS LoadBalance Controllerを使用したALBの使用
* スケーリング　など

## 検証用クラスタ作成

```bash
eksctl create cluster \
    --region ap-northeast-1 \
	--name  eks-clu \
	--version 1.23 \
	--nodegroup-name eks-ng \
	--node-type t3.micro \
	--nodes 2 \
	--nodes-min 2
```
裏でCFnのスタックが作成されてコントロールプレーンとデータプレーン（EC2）が作成される。
```~/.kube/config```に認証情報が追加される
```kubectl get node```正しく認証されればノートの情報取得
```kubectl exec -it pod_name -- /bin/bash```でPod内のコンテナに接続
```eksctl delete cluster --name eks-clu```で削除

## ネットワーク関連
### Pod間通信
* コンテナはIPを持たない。PodがプライベートIPをもっている
* 同一コンテナ内はlocalhost+ポート番号で通信可能

### Pod外通信
Serviceを定義してPodへのアクセスを抽象化。またはIngressを使用

**Service Type**
* Cluster IP
Clusterの内部IPを使用。クラスタ外部からはアクセス不可
* NodePort
Clusterの各ポートにIPを割当て、Pod宛の通信を転送。クラスタ外部からのアクセスが可能
* LoadBalancer
AWSの場合はデフォルトでCLBが作成される。nlbの作成も可能
```
service.beta.kubernetes.io/aws-load-balancer-type: "external"
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "ip"
```
* Ingress
クラスター内のServiceに対する外部からのアクセス(主にHTTP)を管理するAPIオブジェクト
IngressはL7通信。Serviceとは別のリソース。Ingressコントローラーの作成が必要
```AWS LoadBalance Controller```はIngressコントローラーを使用する

## ストレージ関連
### Volume
Podで利用出来るストレージ領域。Pod再起動しても消えない

### Persistent Volume
外部ストレージを使用。Podと切り離して作成可能。
```volumeClaimTemplates```で作成して```volumeMounts```で紐づける。

```bash
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "my-storage-class"
      resources:
        requests:
          storage: 1Gi
```

## kustomize
マニフェストの管理ツール。ベースを作成しておいて、環境に応じて設定値を上書き出来る。例えば下記のようにベースを定義しておいて、本番環境、開発観環境用に設定を上書いて使用出来る。

```bash
.
├── base
│   ├── deployment.yml
│   ├── kustomization.yml
│   └── service.yml
└── overlays
    ├── dev
    │   └── kustomization.yml
    └── prod
        └── kustomization.yml
```
```bash:base/kustomization.yml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
  - service.yml
  - deployment.yml
```
```bash:base/deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.20
          ports:
            - containerPort: 80
```
```bash:overlays/prod/kustomization.yml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - ../../base
namespace: production
replicas:
- name: deployment
  count: 5
```

## Helm
k8sで使用するパッケージマネージャー。リポジトリではイメージは管理せず、```Chart```と呼ばれる設定ファイルのみを管理する仕組み。HelmでChartをダウンロードしてデプロイする。作成、更新、削除、ロールバックも可能。

## AWS LoadBalance Controller

### AWS LoadBalance Controllerのインストール

下記手順を実施。

https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/aws-load-balancer-controller.html

事前にクラスターのIAM OIDC IDプロバイダーを作成する必要がある。
```
eksctl utils associate-iam-oidc-provider --cluster my-cluster --approve
```

#### IAM関連設定
* IAM Policyを作成する
* IRSAを作成してIAM Policyを紐づける

IRSA（IAM Role for Service Acoount）とはk8s内で管理されているアカウントで、Podと紐づけてAWSリソースへのアクセス制御を行う機能。

下記の様な形でサービスアカウントを作成している。

![スクリーンショット 2022-12-21 10.46.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/ceca47f6-72f0-a1d7-e779-5a4874cb5e7e.png)

#### Helmを使用してChartのインストール
* Helm
k8s用のパッケージマネージャー、yumやaptのようなもの
* Chart
Helmで取得出来る設定ファイル。Chartではイメージを管理しているのではなく設定ファイルのみ管理している。Helmでこれをダウンロードしてデプロイする。

Helmの使用方法は**①リポジトリの追加②リポジトリの更新③Chartのインストール**

```shell
helm repo add eks https://aws.github.io/eks-charts
helm repo update
helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
  -n kube-system \
  --set clusterName=eks-clu \
  --set serviceAccount.create=false \
  --set serviceAccount.name=aws-load-balancer-controller 
```

#### コントローラのインストールを確認

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

NAME                           READY   UP-TO-DATE   AVAILABLE   AGE
aws-load-balancer-controller   2/2     2            2           33s
```

### Ingress作成

```shell
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress
  annotations:
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: instance
spec:
  defaultBackend:
    service:
      name: service
      port:
        number: 80

  ingressClassName: alb
  rules:
    - http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: service
                port:
                  number: 80
---
apiVersion: v1
kind: Service
metadata:
  name: service
spec:
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
  type: NodePort
  selector:
    app.kubernetes.io/name: app
```

## スケーリング関連

### Resource Request/Limits
Pod作成時、deploymentの中などで指定。Requests分リソースを確保する。MemoryのLimitsを超えた際はOOM Killerによりプロセスがkillされる。CPUのLimitsを超えた場合はパフォーマンスが落ちる。

### QoSクラス
Podの優先度を定義。Resource Request/Limitsの値を元に自動的に付与される。OOM KillerでPodがkillされる時のPodの選定などに使用

https://kubernetes.io/ja/docs/tasks/configure-pod-container/quality-service-pod/

### Horizontal Pod Autoscaler
Podをスケールアウトする。PodのCPU使用率、メモリ使用率、カスタムメトリクスを使用して監視。指定したメトリクスを下回るようにPod数を調整してスケーリングする

https://kubernetes.io/ja/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/

### Cluster Autoscaler
クラスタ内のノード数を動的に調整

https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/autoscaling.html


# 関連記事

https://qiita.com/tkubota/items/021b775e4b8b3fad9bab

https://qiita.com/tkubota/items/46b487598a49039c76c5

https://qiita.com/tkubota/items/f84468e2d65f1b27fd51