備忘録
- 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を使用する。
関連記事