備忘録
- k8sのリソース
- EKSの運用
- Fargateの制限 など
簡単に試す方法
Docker DesktopでEnable Kubernetesを有効にするだけ
基本的なリソース
Container
実際に稼働しているContainer。コンテナイメージから作成される。
Pod
Containerをまとめたもの。1つ以上のContainerで構成される。Pod間で利用するストレージを含む場合もある。
ReplicaSet
レプリカ(同一構成のPod)の個数を管理するリソース。Deploymentリソースによって定義される。
Deployment
どういったコンテナが何個必要かを定義する。ここからReplicaSetやPod、Containerが作成される。
Service
Podへのアクセスを管理する。Seriveに定義された方法でアクセスすることよってPodへのアクセスを抽象化する。
基本的なリソースの簡単な検証
概要
nginxのイメージを使用してhttp://localhost:30080に接続するとどちらかのPodに接続する構成を作成する。
Serviceで接続の箇所、DeploymentでPodの箇所を定義する。
準備
下記yamlファイルを準備する。
- Deploymentリソースの定義ファイル
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx-app
replicas: 2
template:
metadata:
labels:
app: nginx-app
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
- Serviceリソースの定義ファイル
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: NodePort
ports:
- port: 8080
targetPort: 80
protocol: TCP
nodePort: 30080
selector:
app: nginx-app
作成
- Deploymentリソースの作成と確認
% kubectl apply -f nginx-deployment.yml
deployment.apps/nginx-deployment created
% kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-xxxxxxxxxx-xxxxx 1/1 Running 0 10s
nginx-deployment-xxxxxxxxxx-xxxxx 1/1 Running 0 10s
- Serviceリソースの作成と確認
% kubectl apply -f nginx-service.yml
service/nginx-service created
% kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP xx.xx.xx.xx <none> 443/TCP 18h
nginx-service NodePort xx.xx.xx.xx <none> 8080:30080/TCP 18s
- アクセス確認
ブラウザからhttp://localhost:30080にアクセス
削除
- Deployment/Serviceリソースの削除
% kubectl delete -f nginx-deployment.yml
deployment.apps "nginx-deployment" deleted
% kubectl delete -f nginx-service.yml
service "nginx-service" deleted
% kubectl get pods
No resources found in default namespace.
% kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP xx.xx.xx.xx <none> 443/TCP 18h
kubernetesのコンポーネント
-
kube-apiserver
kubectlの情報を受け取ってNodeやPodのスケジューリングを制御 -
kube-scheduler
新しいPodをどのNodeに配置するかをスケジューリング -
kube-controller-manager
複数のコントローラーから構成。Nodeで実行されるワークロードの制御 -
cloud-controller-manager
AWSなどのクラウドプロバイダが提供するサービスと連携 -
etcd
マニフェストをキーバリューストアで管理 -
kubelet
Podがマニュフェスト通りの状態であるか確認 -
kubeproxy
クラスタ内外のネットワークトラフィックの制御
上記のDeploymentをapplyするのを例に取ると
- マニフェスト(yamlファイル)を作成する
-
kubectl applyで適用することによって、kube-apiserver経由でetcdに登録される -
kube-controller-managerが必要なPodを起動するようにetcdに登録する -
kube-schedulerがetcdから情報を取得して、Podを起動するノードを決定 -
kubeletが起動すべきPodを検知してPodを起動する
その他リソース
Namespace
クラスターを論理的に分割して管理する仕組み
apiVersion: v1
kind: Namespace
metadata:
name: k8s-test
下記で確認出来る
kubectl config get-contexts
CronJob
k8s上で定期的にプログラムを実行する仕組み
1分毎にnginxコンテナが増える
apiVersion: batch/v1
kind: CronJob
metadata:
name: nginx-scheduled
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: nginx-scheduled
image: nginx
imagePullPolicy: Always
restartPolicy: OnFailure
Cronjobを消すとコンテナも消える
kubectl delete cronjob nginx-scheduled
DeamonSet
定義したPodが各ノードに1つずつ起動する
ログ収集用のPodを起動する場合、サイドカーパターンの他にDeamonSetが使用出来る。
StatefulSet
k8sクラスタ内で永続データを扱う時に使用する
安定的なネットワークIDと永続ストレージが提供される
Secret
機密情報を環境変数として引き渡し。Pod起動時にSecretに情報を取りに行く
base64エンコードされているだけなので安全ではない。kubesealで暗号化する
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: user-pass
stringData:
user-name: ${USER_NAME}
user-password: ${USER_PASSWORD}
参照する側のリソース
env:
- name: USER_NAME
valueFrom:
secretKeyRef:
key: user-name
name: user-pass
- name: USER_PASSWORD
valueFrom:
secretKeyRef:
key: user-password
name: user-pass
ConfigMap
機密情報でない情報を環境変数として引き渡し
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
app-name: web-server
app-url: http://example.co.jp
参照する側のリソース
env:
- name: APP_NAME
valueFrom:
configMapKeyRef:
key: app-name
name: app-config
- name: APP_URL
valueFrom:
configMapKeyRef:
key: app-url
name: app-config
EKS
運用時に考慮するポイントなど
セキュリティ関連
IAMを使用した認証
-
aws-auth:ユーザとGroup、IAMロールの関連付け -
RoleBinding:GroupとRoleの関連付け -
Role:許可する操作の定義
Pod Security Admission
Podの分離レベルを定義して、レベル毎にポリシーを定義。Podの振る舞いを制限する。
分離レベル:privileged,baseline,restricted
ポリシー:enforce,warn,audit
Network Policies
Pod間のIngress、Egress通信の制御が可能。セキュリティグループのような感じ
監視
DeamonSetで各ノードにCloudWatch Agent用のPodとFluentd用のPodを置く構成。ノードへのIAMロールのアタッチとPodが使用するService Accountの作成が必要。
※Fargateの場合はDeamonSet利用不可
メトリクス監視
Pod毎のメトリクス監視をする場合、CloudWatch Container Insightを使用。ノード内に配置したCloudWatch Agent経由で送信。
ログ監視
Podのログがノード内のディレクトリに出力される。Fluentdでこのディレクトリを監視してCloudWatch Logsに上げる。
リソース関連
Podのリソース制限
Deploymentの定義で制限
-
requests:Podデプロイ時にホスト側に最低限求める要求量 -
limits:Podが使用出来るリソース上限
spec:
containers:
- name: app
image: images.my-company.example/app:v4
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
オートスケーリング
Cluster AutoscalerかKarpenter。あとはサービスのオートスケールとしてHorizontal Pod Autoscaler (HPA)がある。
-
Cluster Autoscaler:Podがノード上にデプロイ出来ない時(requestsr量を確保出来ない時)にステータスがPendingとなる。この時にノード追加。
-
Horizontal Pod Autoscaler (HPA)
Podのリソース使用量に応じてPodのスケールアウト、スケールイン
Fargate利用時の制限
Log関連
Fargateではノード:Podは1:1で起動されるため、DeamonSetの利用が出来ない。
現在はFluent Bitを使用した組み込みルータを使用した方法が多い。
以前はサイドカーパターンを使用していた。
CloudWatch Container Insights の EKS Fargateに対応
Volumeの使用
EFSはサポートされている。EBSはEC2タイプのみ
Public IP
Public IPの割り当てが出来ない。そのためNodeportを使用して外部からアクセスする構成は不可
ELB
CLB/NLBは非対応でALBのみサポート。Service作成時にLoadBalancerを選択するとCLBが作成されるがこれは使用不可
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: LoadBalancer
selector:
app: nginx-service
ports:
- protocol: TCP
port: 8080
targetPort: 8080
Network Policy
使用不可。Secutiry Groupを使用する。
関連記事







