eksctl のインストール
ドキュメントを参考に各環境に応じた eksctl をインストールします。
eksctl がインストールされたことを確認します。
eksctl version
kubectl のインストール
ドキュメントを参考に各環境に応じた kubectl をインストールします。
kubectl がインストールされたことを確認します。
kubectl version --short --client
各ツールのインストール
必要に応じて、Kubernetes の利用の際によく使われるいくつかの便利なツールの導入と、コマンド補完の設定をします。
クラスター
次の通り、クラスターを作成するための cluster.yaml ファイルを準備します。
※コストを抑えるために小さいノードを使用しています。
また、既存の VPC に作成することも可能です、上記ドキュメントを参考にするか、記事の後半をご確認ください。
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 ファイルを作成します。
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 を追加します。
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 ファイルを準備する。
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 を作成します。
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 ファイルを作成します。
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 ファイルを作成します。
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 ファイルを作成します。
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 を作成します。
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 を準備します。
---
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=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 では次の通り、環境変数を読み込むように設定する。
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 に記載します。
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 の権限を追加したものに編集。
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
サンプルアプリケーションの準備。
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 を作成。
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 を次の通り用意。
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 は次の通り作成しておきます。
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 は保証するということになります。
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