0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

EKS を触って何となく仕組みを理解する

Posted at

eksctl のインストール

ドキュメントを参考に各環境に応じた eksctl をインストールします。

eksctl がインストールされたことを確認します。

eksctl version

kubectl のインストール

ドキュメントを参考に各環境に応じた kubectl をインストールします。

kubectl がインストールされたことを確認します。

kubectl version --short --client

各ツールのインストール

必要に応じて、Kubernetes の利用の際によく使われるいくつかの便利なツールの導入と、コマンド補完の設定をします。

クラスター

次の通り、クラスターを作成するための cluster.yaml ファイルを準備します。

※コストを抑えるために小さいノードを使用しています。
また、既存の VPC に作成することも可能です、上記ドキュメントを参考にするか、記事の後半をご確認ください。

cluster.yaml
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: eks-cluster
  region: ap-northeast-1
  version: "1.25"

nodeGroups:
  - name: eks-ng
    instanceType: t3.small
    desiredCapacity: 1 

次のコマンドを実行する事でクラスターが作成されます。

eksctl create cluster -f cluster.yaml

動いているノードを確認。

$ kubectl get node
NAME                                                STATUS   ROLES    AGE     VERSION
ip-192-168-92-235.ap-northeast-1.compute.internal   Ready    <none>   2m40s   v1.25.7-eks-a59e1f0

EC2 の料金が課金されるので利用しない場合は次のコマンドで、ノードを削除できます。

$ eksctl delete nodegroup -f cluster.yaml --approve

Pod

nginx コンテナを起動する nginx.yaml ファイルを作成します。

nginx.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - image: nginx:latest
    name: nginx
  restartPolicy: Always

kubectl apply で pod をデプロイします。

$ kubectl apply -f nginx.yaml 
pod/nginx created

実際に、pod が起動したことを確認します。

$ kubectl get pods
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          89s

NodePort

nginx。yaml ファイルに Service を追加します。

nginx.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  # selector に合わせることで そのリソースと紐づく
  labels:
    app: nginx
spec:
  containers:
  - image: nginx:latest
    name: nginx
  restartPolicy: Always


apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  ports:
  - name: 80-80
    port: 80
    protocol: TCP
    targetPort: 80
  # labels に合わせることで そのリソースと紐づく
  selector:
    app: nginx
  type: NodePort

kubectl apply で service をデプロイします。

$ kubectl apply -f nginx.yaml 
service/nginx created

NodePort が起動したことを確認します。

$ kubectl get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.100.0.1       <none>        443/TCP        7h43m
nginx        NodePort    10.100.178.212   <none>        80:31142/TCP   7s

以下コマンドで node の詳細な情報を確認し、X.X.X.X:31142 にアクセスする事で nginx の画面が表示されるということになります。(セキュリティグループでポート解放する必要有り)

$ kubectl get node -o wide
NAME                                                STATUS   ROLES    AGE     VERSION               INTERNAL-IP      EXTERNAL-IP     OS-IMAGE         KERNEL-VERSION                  CONTAINER-RUNTIME
ip-192-168-42-127.ap-northeast-1.compute.internal   Ready    <none>   7h39m   v1.25.7-eks-a59e1f0   192.168.42.127   X.X.X.X   Amazon Linux 2   5.10.178-162.673.amzn2.x86_64   containerd://1.6.19

AWS Load Balancer Controller

ノードにIAMポリシーを追加した cluster.yaml ファイルを準備する。

cluster.yaml
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: eks-cluster
  region: ap-northeast-1
  version: "1.25"

nodeGroups:
  - name: eks-ng
    instanceType: t3.small
    desiredCapacity: 1
    # AWS Load Balancer Controller を動かすための IAMポリシーを設定します。
    iam: 
      withAddonPolicies: 
        awsLoadBalancerController: true

ノードをデプロイする。

$ eksctl create nodegroup -f cluster.yaml

Pod をデプロイする。

$ kubectl apply -f nginx.yaml 
pod/nginx created

次のページを参考に AWS Load Balancer Controller をインストールする。

AWS Load Balancer Controller が作成されたことを確認する。

$ kubectl get pods -n kube-system
NAME                                            READY   STATUS    RESTARTS   AGE
aws-load-balancer-controller-7b66fb998b-twkgf   1/1     Running   0          20m

ALB をデプロイするための Ingress を作成します。

nginx-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx
  annotations:
    # AWS Load Balancer Controller の設定内容を記述する
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/scheme: internet-facing
spec:
  rules:
  - http:
      paths:
      - backend:
          service:
            name: nginx
            port:
              number: 80
        path: /
        pathType: Prefix

kubectl apply で Ingress をデプロイします。

$ kubectl apply -f nginx-ingress.yaml
ingress.networking.k8s.io/nginx created

次のコマンドでALBのDNS名を確認し、curl やブラウザなどでアクセスできることを確認します。

aws elbv2 describe-load-balancers --query 'LoadBalancers[].DNSName[]'

ヘルスチェック

次の通り nginx.yaml ファイルを作成します。

nginx.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  containers:
  - image: nginx:latest
    name: nginx
    # Pod が正常に起動しているか確認する。
    livenessProbe:
      httpGet:
        path: /
        port: 80
      initialDelaySeconds: 5
      timeoutSeconds: 1
      periodSeconds: 10
      failureThreshold: 3
    # Pod がサービスインする準備ができているかを確認する。
    readinessProbe:
      httpGet:
        path: /
        port: 80
      initialDelaySeconds: 5
      timeoutSeconds: 1
      periodSeconds: 10
      failureThreshold: 3
  restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  ports:
  - name: 80-80
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx
  type: NodePort

kubectl apply で pod をデプロイします。

$ kubectl apply -f nginx.yaml

kubectl describe で Pod の詳細設定を確認します。

$ kubectl describe pods nginx
    Liveness:       http-get http://:80/ delay=5s timeout=1s period=10s #success=1 #failure=3
    Readiness:      http-get http://:80/ delay=5s timeout=1s period=10s #success=1 #failure=3

動作確認をするために、別タブで -w オプションで、Pod の状態を確認します。

$ kubectl get pods -w
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          7m33s

kubectl exec で、Pod の中に入り、擬似的に、Pod を終了させます。

$ kubectl exec nginx -it /bin/sh
# rm /usr/share/nginx/html/index.html

別のタブで開いていた、Pod の状態を確認すると新しい Pod が起動したことが確認できます。

$ kubectl get pods -w
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          7m33s
nginx   0/1     Running   0          8m
nginx   0/1     Running   1 (2s ago)   8m3s
nginx   1/1     Running   1 (9s ago)   8m10s

Deployment

次の通り nginx.yaml ファイルを作成します。

nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  # nginx という Deployment が作成されます。
  name: nginx
spec:
  # 1 つのレプリカ Pod を作成します。
  replicas: 1
  selector:
    # Deployment が管理する Pod のラベルを定義。
    matchLabels:
      app: nginx
  strategy: {}
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:latest
        name: nginx
        livenessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 5
          timeoutSeconds: 1
          periodSeconds: 10
          failureThreshold: 3
        readinessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 5
          timeoutSeconds: 1
          periodSeconds: 10
          failureThreshold: 3
      restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  ports:
  - name: 80-80
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx
  type: NodePort

kubectl apply で デプロイします。

$ kubectl apply -f nginx.yaml

Deployment と Pod の状態を確認します。

$ kubectl get deployment
NAME    READY   UP-TO-DATE   AVAILABLE   AGE
nginx   1/1     1            1           81s

$ kubectl get pods
NAME                     READY   STATUS    RESTARTS   AGE
nginx-84fdd6fdbd-lqzj5   1/1     Running   0          60s

HPA

下記のページを参考に、metrics-server をインストールします。

kubectl top コマンドで、ノードの CPU や memory の状態が見れることを確認します。

$ kubectl top node
NAME                                                CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%   
ip-192-168-37-209.ap-northeast-1.compute.internal   45m          2%     635Mi           43%  

次の通り nginx.yaml ファイルを作成します。

nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  strategy: {}
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:latest
        name: nginx
        livenessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 5
          timeoutSeconds: 1
          periodSeconds: 10
          failureThreshold: 3
        readinessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 5
          timeoutSeconds: 1
          periodSeconds: 10
          failureThreshold: 3
        # 1 コア の 1/10 の値を要求する。
        resources:
          requests:
            cpu: 100m
      restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  ports:
  - name: 80-80
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx
  type: NodePort

Pod レプリカ数を 1 から 10 の間に維持する HPA を作成します。

$ kubectl autoscale deployment nginx --cpu-percent 50 --min 1 --max 10
horizontalpodautoscaler.autoscaling/nginx autoscaled

HPA の状態を確認します。

$ kubectl get hpa
NAME    REFERENCE          TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
nginx   Deployment/nginx   1%/50%    1         10        1          21m

apache-bench コンテナで負荷をかけ、Pod がスケールするか確認します。

$ kubectl run apache-bench -i --tty --rm --image httpd -- /bin/sh 
If you don't see a command prompt, try pressing enter.
while true;
> do ab -n 10 -c 10 http://nginx.default.svc.cluster.local/ > /dev/null;
> done

Pod または HPA の動作を確認します。

$ kubectl get pod -w
NAME                     READY   STATUS    RESTARTS   AGE
apache-bench             1/1     Running   0          3m47s
nginx-6c85484665-t9n4g   1/1     Running   0          14m
nginx-6c85484665-xb5jv   0/1     Pending   0          0s
nginx-6c85484665-xb5jv   0/1     Pending   0          0s

$ kubectl get hpa -w
NAME    REFERENCE          TARGETS    MINPODS   MAXPODS   REPLICAS   AGE
nginx   Deployment/nginx   150%/50%   1         10        4          34m
nginx   Deployment/nginx   162%/50%   1         10        4          34m
nginx   Deployment/nginx   163%/50%   1         10        4          35m

Cluster Autoscaler

次の通り、1〜3 までスケールする、cluster.yaml を作成します。

cluster.yaml
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: eks-cluster
  region: ap-northeast-1
  version: "1.22"

nodeGroups:
  - name: eks-ng
    instanceType: t3.small
    desiredCapacity: 1
    # 最小1/最大のノード数を指定。
    minSize: 1
    maxSize: 3
    iam:
      withAddonPolicies:
        awsLoadBalancerController: true
        # AutoScaler を利用できるように設定を追加。
        autoScaler: true

次のページにある通り、cluster-autoscaler.yaml を準備します。

cluster-autoscaler-autodiscover.yaml
---
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    k8s-addon: cluster-autoscaler.addons.k8s.io
    k8s-app: cluster-autoscaler
  name: cluster-autoscaler
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: cluster-autoscaler
  labels:
    k8s-addon: cluster-autoscaler.addons.k8s.io
    k8s-app: cluster-autoscaler
rules:
  - apiGroups: [""]
    resources: ["events", "endpoints"]
    verbs: ["create", "patch"]
  - apiGroups: [""]
    resources: ["pods/eviction"]
    verbs: ["create"]
  - apiGroups: [""]
    resources: ["pods/status"]
    verbs: ["update"]
  - apiGroups: [""]
    resources: ["endpoints"]
    resourceNames: ["cluster-autoscaler"]
    verbs: ["get", "update"]
  - apiGroups: [""]
    resources: ["nodes"]
    verbs: ["watch", "list", "get", "update"]
  - apiGroups: [""]
    resources:
      - "pods"
      - "services"
      - "replicationcontrollers"
      - "persistentvolumeclaims"
      - "persistentvolumes"
    verbs: ["watch", "list", "get"]
  - apiGroups: ["extensions"]
    resources: ["replicasets", "daemonsets"]
    verbs: ["watch", "list", "get"]
  - apiGroups: ["policy"]
    resources: ["poddisruptionbudgets"]
    verbs: ["watch", "list"]
  - apiGroups: ["apps"]
    resources: ["statefulsets", "replicasets", "daemonsets"]
    verbs: ["watch", "list", "get"]
  - apiGroups: ["storage.k8s.io"]
    resources: ["storageclasses", "csinodes"]
    verbs: ["watch", "list", "get"]
  - apiGroups: ["batch", "extensions"]
    resources: ["jobs"]
    verbs: ["get", "list", "watch", "patch"]
  - apiGroups: ["coordination.k8s.io"]
    resources: ["leases"]
    verbs: ["create"]
  - apiGroups: ["coordination.k8s.io"]
    resourceNames: ["cluster-autoscaler"]
    resources: ["leases"]
    verbs: ["get", "update"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: cluster-autoscaler
  namespace: kube-system
  labels:
    k8s-addon: cluster-autoscaler.addons.k8s.io
    k8s-app: cluster-autoscaler
rules:
  - apiGroups: [""]
    resources: ["configmaps"]
    verbs: ["create","list","watch"]
  - apiGroups: [""]
    resources: ["configmaps"]
    resourceNames: ["cluster-autoscaler-status", "cluster-autoscaler-priority-expander"]
    verbs: ["delete", "get", "update", "watch"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: cluster-autoscaler
  labels:
    k8s-addon: cluster-autoscaler.addons.k8s.io
    k8s-app: cluster-autoscaler
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-autoscaler
subjects:
  - kind: ServiceAccount
    name: cluster-autoscaler
    namespace: kube-system

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: cluster-autoscaler
  namespace: kube-system
  labels:
    k8s-addon: cluster-autoscaler.addons.k8s.io
    k8s-app: cluster-autoscaler
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: cluster-autoscaler
subjects:
  - kind: ServiceAccount
    name: cluster-autoscaler
    namespace: kube-system

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: cluster-autoscaler
  namespace: kube-system
  labels:
    app: cluster-autoscaler
spec:
  replicas: 1
  selector:
    matchLabels:
      app: cluster-autoscaler
  template:
    metadata:
      labels:
        app: cluster-autoscaler
      annotations:
        prometheus.io/scrape: 'true'
        prometheus.io/port: '8085'
    spec:
      serviceAccountName: cluster-autoscaler
      containers:
        # kubernetes のバージョンに合わせる。
        - image: k8s.gcr.io/autoscaling/cluster-autoscaler:v1.25.6
          name: cluster-autoscaler
          resources:
            limits:
              cpu: 100m
              memory: 600Mi
            requests:
              cpu: 100m
              memory: 600Mi
          command:
            - ./cluster-autoscaler
            - --v=4
            - --stderrthreshold=info
            - --cloud-provider=aws
            - --skip-nodes-with-local-storage=false
            - --expander=least-waste
            # 環境のクラスター名前に変更。
            - --node-group-auto-discovery=asg:tag=k8s.io/cluster-autoscaler/enabled,k8s.io/cluster-autoscaler/eks-cluster
          volumeMounts:
            - name: ssl-certs
              mountPath: /etc/ssl/certs/ca-certificates.crt #/etc/ssl/certs/ca-bundle.crt for Amazon Linux Worker Nodes
              readOnly: true
          imagePullPolicy: "Always"
      volumes:
        - name: ssl-certs
          hostPath:
            path: "/etc/ssl/certs/ca-bundle.crt"

kubectl apply で  cluster-autoscaler をデプロイします。

$ kubectl apply -f cluster-autoscaler-autodiscover.yaml

cluster-autoscaler が作成されたことを確認します。

$ kubectl get pods -n kube-system
NAME                                            READY   STATUS             RESTARTS   AGE
cluster-autoscaler-7c44b7fc58-7pllg             0/1     ImagePullBackOff   0          106s

kubectl apply で Pod をデプロイしておく。

$ kubectl apply -f nginx.yaml

Podレプリカを、10 にスケールさせてクラスターがスケールするか確認してみます。

$ kubectl scale deployment --replicas 10 nginx
deployment.apps/nginx scaled

クラスターがスケールしていることを確認します。

$ kubectl get node
NAME                                                STATUS   ROLES    AGE   VERSION
ip-192-168-35-58.ap-northeast-1.compute.internal    Ready    <none>   30m   v1.25.7-eks-0a21954
ip-192-168-77-129.ap-northeast-1.compute.internal   Ready    <none>   32s   v1.25.7-eks-0a21954

ConfigMap

.env ファイルに環境変数を作成する。

.env
ENV=dev

configmap を作成する。

$ kubectl create configmap eks-cluster --from-env-file=.env
configmap/eks-cluster created

作成された configmap を確認する。

$ kubectl describe configmap eks-cluster
Name:         eks-cluster
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
ENV:
----
dev

nginx.yaml では次の通り、環境変数を読み込むように設定する。

nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  strategy: {}
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:latest
        name: nginx
        # 環境変数を設定する。
        envFrom:
          - configMapRef:
              name: eks-cluster
        livenessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 5
          timeoutSeconds: 1
          periodSeconds: 10
          failureThreshold: 3
        readinessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 5
          timeoutSeconds: 1
          periodSeconds: 10
          failureThreshold: 3
        resources:
          requests:
            cpu: 100m
      restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  ports:
  - name: 80-80
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx
  type: NodePort

nginx.yaml をデプロイする。

$ kubectl apply -f nginx.yaml

Pod名を確認する。

$ kubectl get pods
NAME                    READY   STATUS    RESTARTS   AGE
nginx-c97746c48-785dz   1/1     Running   0          18s

Pod に exec でコンテナの中に入り、環境変数を確認する。

$ kubectl exec -it nginx-c97746c48-785dz env
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=nginx-c97746c48-785dz
TERM=xterm
ENV=dev

なお、envファイルを編集した場合は、Pod を再起動する必要がある。

$ kubectl rollout restart deployment/nginx

Pod名を確認する。

$ kubectl get pods
NAME                    READY   STATUS    RESTARTS   AGE
nginx-b9d6884ff-qrgbr   1/1     Running   0          32s

Pod に exec でコンテナの中に入り、環境変数が変更されているか確認する。

$ kubectl exec -it nginx-b9d6884ff-qrgbr env
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=nginx-b9d6884ff-qrgbr
TERM=xterm
ENV=stg

Secret

secret情報を作成する。ここでは、DB の USER と PASS を作成してみます。

$ kubectl create secret generic eks-cluster --from-literal=DB_USER=root --from-literal=DB_PASS=pass
secret/eks-cluster created

secret情報を確認する。

$ kubectl describe secret eks-cluster
DB_PASS:  4 bytes
DB_USER:  4 bytes

secret 情報は以下のコマンドで確認できます。

$ kubectl get secret eks-cluster -o yaml
apiVersion: v1
data:
  DB_PASS: cGFzcw==
  DB_USER: cm9vdA==
kind: Secret
metadata:
  creationTimestamp: "2023-05-21T05:53:26Z"
  name: eks-cluster
  namespace: default
  resourceVersion: "576461"
  uid: afc2cee0-7e84-4fdc-9985-04d79993ddf3
type: Opaque

base64 にデコードする事で、Secret の実際の value を確認できます。

$ echo 'cGFzcw==' | base64 --decode 
pass

nginx.yaml ファイルには、configMap と同じように、secret に記載します。

nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  strategy: {}
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:latest
        name: nginx
        # 環境変数を設定する。
        envFrom:
          - configMapRef:
              name: eks-cluster
          - secretRef:
              name: eks-cluster
        livenessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 5
          timeoutSeconds: 1
          periodSeconds: 10
          failureThreshold: 3
        readinessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 5
          timeoutSeconds: 1
          periodSeconds: 10
          failureThreshold: 3
        resources:
          requests:
            cpu: 100m
      restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  ports:
  - name: 80-80
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx
  type: NodePort

kubectl apply で デプロイします。

$ kubectl apply -f nginx.yaml
deployment.apps/nginx configured
service/nginx unchanged

Pod名を確認する。

$ kubectl get pods
NAME                    READY   STATUS    RESTARTS   AGE
nginx-c98f99b4c-ppg5x   1/1     Running   0          13s

Pod に exec でコンテナの中に入り、環境変数が設定されているか確認する。

$ kubectl exec -it nginx-c98f99b4c-ppg5x env
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=nginx-c98f99b4c-ppg5x
TERM=xterm
ENV=stg
DB_PASS=pass
DB_USER=root

CloudWatch Container Insights

cluster.yaml を cloudWatch の権限を追加したものに編集。

cluster.yaml
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: eks-cluster
  region: ap-northeast-1
  version: "1.24"

nodeGroups:
  - name: eks-ng
    instanceType: t3.small
    desiredCapacity: 1
    minSize: 1
    maxSize: 3
    iam:
      withAddonPolicies:
        awsLoadBalancerController: true
        autoScaler: true
        # cloudWatch の権限を追加。
        cloudwatch: true

次のページの通り、Container Insights をデプロイする。

後は、CloudWatch から Container Insights でメトリクス、ロググループなどを確認してみましょう。

なお、ロググループには次のようなロググループが作成されるようです。

/aws/containerinsights/eks-cluster/application /aws/containerinsights/eks-cluster/dataplane /aws/containerinsights/eks-cluster/host /aws/containerinsights/eks-cluster/performance

アプリケーションのデプロイ

自身で作成したアプリケーションをデプロイしてみたいと思います。

まず、必要な環境を準備します。

$ node -v
v16.20.0

$ mkdir nodejs && cd nodejs

$ npm init -y

$ npm install express --save

サンプルアプリケーションの準備。

app.js
const express = require('express');
const app = express();

app.get('/', (req, res) => res.send('Hello World!'));
app.listen(3000, () => console.log('Example app listening on port 3000'));

ローカルで動作確認。

$ node app.js

$ curl http://localhost:3000

Dockerfile を作成。

Dockerfile
FROM node:14-alpine
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD [ "node", "app.js" ]

コンテナの準備と動作確認。

$ docker build -t node-web-app:latest

$ docker images
REPOSITORY     TAG         IMAGE ID       CREATED              SIZE
node-web-app   latest      df7248480cfc   About a minute ago   122MB

$ docker run -d -p 3000:3000 node-web-app:latest
f28581312123a0e95c0fac891c4b0fb1fcad4f2ff876394e104314af3a68218a

$ curl http://localhost:3000
Hello World!

コンテナイメージの作成、ログイン、push。

$ docker build -t XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/node-web-app:1.0 .

$ aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com 

$ aws ecr create-repository --repository-name node-web-app --region ap-northeast-1

$ docker push XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/node-web-app:1.0

node-web-app.yaml を次の通り用意。

node-web-app.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: node-web-app
  name: node-web-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: node-web-app
  strategy: {}
  template:
    metadata:
      labels:
        app: node-web-app
    spec:
      containers:
        #ECRにpushしたイメージを指定。
      - image: XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/node-web-app:1.0
        name: node-web-app
        resources: {}

apply し、pod の起動を確認。

$ kubectl apply -f node-web-app.yaml
deployment.apps/node-web-app created

$ kubectl get pod
NAME                            READY   STATUS    RESTARTS   AGE
node-web-app-5fdc988f58-4ljj2   1/1     Running   0          2m38s

ユーザー管理

EKS のリソースを作成したIAMユーザーやIAMロールには、Kubernetess上の管理者権限が付与されます。他のIAMユーザーやIAMロールにKubernetessの権限を与えるには、別途操作が必要です。

現状を確認してみます。

$ eksctl get iamidentitymapping --cluster eks-cluster
ARN                                                                                             USERNAME                                GROUPS                                  ACCOUNT
arn:aws:iam::XXXXXXXXXXXX:role/eksctl-eks-cluster-nodegroup-eks-NodeInstanceRole-XXXXXXXXXXXX  system:node:{{EC2PrivateDNSName}}       system:bootstrappers,system:nodes

現在は、cloudshell から、eks-user で操作。

$ aws sts get-caller-identity 
{
    "Account": "XXXXXXXXXXXX", 
    "UserId": "XXXXXXXXXXXX", 
    "Arn": "arn:aws:iam::XXXXXXXXXXXX:user/eks-user"
}

別に、cloud9 を起動し、eks-role を別途用意。

$ aws sts get-caller-identity                                                                                                                                                        
{
    "Account": "XXXXXXXXXXXX", 
    "UserId": "AXXXXXXXXXXXX:i-0XXXXXXXXXXX", 
    "Arn": "arn:aws:sts::XXXXXXXXXXXX:assumed-role/eks-role/i-0XXXXXXXXXX"
}

ID マッピングを作成。

$ eksctl create iamidentitymapping --cluster eks-cluster --arn arn:aws:iam::XXXXXXXXXXXX:role/eks-role --group system:masters --username eks-admin

設定できたか確認。

$ eksctl get iamidentitymapping --cluster eks-cluster
ARN                                                                                             USERNAME                                GROUPS                                  ACCOUNT
arn:aws:iam::XXXXXXXXXXXX:role/eksctl-eks-cluster-nodegrou-NodeInstanceRole-XXXXXXXXXXXX system:node:{{EC2PrivateDNSName}}       system:bootstrappers,system:nodes
arn:aws:iam::XXXXXXXXXXXX:role/ekshandson-admin                                                 eks-admin                               system:masters

context を作成。

$ aws eks update-kubeconfig --region ap-northeast-1 --name eks-cluster
Added new context arn:aws:eks:ap-northeast-1:XXXXXXXXXXXX:cluster/eks-cluster to /home/ec2-user/.kube/config

cloud9 の eks-role から操作可能なことを確認。

$ kubectl get pods
NAME                     READY   STATUS    RESTARTS   AGE
nginx-6c85484665-qsxkn   1/1     Running   0          63s

なお、次のようなエラーが表示された場合は、aws-cli のバージョンが古いため、ドキュメントを参考にaws-cli をアップデートしましょう。

$ kubectl get pods
error: exec plugin: invalid apiVersion "client.authentication.k8s.io/v1alpha1"
$ aws --version
aws-cli/2.11.26 Python/3.11.3 Linux/4.14.314-238.539.amzn2.x86_64 exe/x86_64.amzn.2 prompt/off

既存のVPCに構築する

既存の VPC にタグづけをしておきましょう。

  • プライベートサブネット:kubernetes.io/role/elb=1
  • パブリックサブネット:kubernetes.io/role/internal-elb=1

cluster.yaml は次の通り作成しておきます。

cluster.yaml
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: eks-cluster
  region: ap-northeast-1
  version: "1.25"

# vpc と サブネットIDを指定。 
vpc:
  id: "vpc-XXX"
  subnets:
    private:
      eks-private-1:
        id: "subnet-XXX"
      eks-private-2:
        id: "subnet-XXX"
    public:
      eks-public-1:
        id: "subnet-XXX"
      eks-public-2:
        id: "subnet-XXX"

nodeGroups:
  - name: eks-ng
    instanceType: t3.small
    desiredCapacity: 1
    # プライベートサブネットに作成するように指定。
    privateNetworking: true
    minSize: 1
    maxSize: 3
    iam:
      withAddonPolicies:
        awsLoadBalancerController: true
        autoScaler: true
        cloudWatch: true

クラスターを作成します。

$ eksctl create cluster -f cluster.yaml

EKSのアップデート

PDB(PodDisruptionBudget) 
アップデートなどで意図的にノードを終了させる際に、最低限起動しておくべきPodの数を保証できる機能を作成しておきます。次の設定では最低限 1 は保証するということになります。

pdb.yaml
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: nginx
spec:
  minAvailable: 1
  selector:
    matchLabels:
      app: nginx

pdb をデプロイ。

$ kubectl apply -f pdb.yaml

作成されている事を確認。

$ kubectl get poddisruptionbudget.policy
NAME    MIN AVAILABLE   MAX UNAVAILABLE   ALLOWED DISRUPTIONS   AGE
nginx   1               N/A               1                     2m21s

現在の Version を確認。

$ kubectl version --short
Flag --short has been deprecated, and will be removed in the future. The --short output will become the default.
Client Version: v1.26.4-eks-0a21954
Kustomize Version: v4.5.7
Server Version: v1.25.10-eks-c12679a

各アップデート。

$ eksctl upgrade cluster --name eks-cluster --approve

$ eksctl utils update-aws-node --name eks-cluster --approve

$ eksctl utils update-coredns --name eks-cluster --approve

$ eksctl utils update-kube-proxy --name eks-cluster --approve
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?