k8s_overview
date
Nov 18, 2023
slug
k8s-overview
status
Published
tags
k8s
summary
k8s overview
type
Post
k8s overview
tools
- kubectl
- helm (k8sのパッケージマネージャ)
- stern は、複数のPodのログを一括で表示することができる
- kubespy は、k8sのリソースの変更を監視することができる
- dlv は、k8sのPodにデバッガをアタッチすることができる
- kubesquash は、k8sのPodにデバッガをアタッチすることができる
- kubectx は、k8sのコンテキストを切り替えることができる
- kubens は、k8sのNamespaceを切り替えることができる
- envsubst は、環境変数を置換することができる
- kubetail は、複数のPodのログを一括で表示することができる
- selfhosted-prometheus は、k8sのPrometheusをデプロイすることができる
- Envoy は、k8sのサービスメッシュを提供することができる
- clairは、k8sのコンテナイメージのセキュリティスキャンを行うことができる
- aqua secruiyは、k8sのコンテナイメージのセキュリティスキャンを行うことができる
aqua security利用ADD https//get.aquasec.com/aquasec-latest.tar.gz /tmp RUN tar -xvf /tmp/aquasec-latest.tar.gz -C /tmp RUN /tmp/aquasec install -k <license_key>
- veles は、k8sのリソースの変更を監視することができる
kubectl
k8s Deploymentとは
- imageを指定し、Podを作成する
- Podのレプリカ数を指定し、Podのスケールアウトを行う
k8s Podとは
- コンテナの実行環境
- コンテナの実行に必要なリソースを持つ
- コンテナのスケジューリングの単位
- 複数のコンテナを持つことができる
- ベストプラクティスとして、
1つのPodに1つのコンテナを持つことが推奨されているpodのリソース要求と制限を設定することで、Podのスケジューリングを制御することができる
k8s Serviceとは
- Podに対してアクセスするための方法を提供する
- PodのIPアドレスは動的に変わるため、Serviceを経由してアクセスする
- ServiceはPodのIPアドレスをラベルで指定する
- ServiceはPodのレプリカ数を考慮してロードバランシングを行う
k8s Ingressとは
- serviceの前に配置し、外部からのアクセスをPodにルーティングする
graph TB A[Ingress] -->|ルーティング| B[Service] B -->|ルーティング| C[Pod] B -->|ルーティング| D[Pod]
- 外部からのアクセスをPodにルーティングする
- Ingress Controllerを使用することで、Ingressリソースを解釈し、ルーティングを行う
- Ingress ControllerはNginxやTraefikなどがある
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-ingress spec: backend: serviceName: my-service servicePort: 80
service と Ingressの違い
- ServiceはPodに対してアクセスするための方法を提供する(クラスタ内部のトラフィックを制御する)
- IngressはServiceの前に配置し、外部からのアクセスをPodにルーティングする(クラスタ外部のトラフィックを制御する)
Ingress ルール
- hostを指定することで、特定のドメインにアクセスすることができる
- pathを指定することで、特定のパスにアクセスすることができる
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-ingress spec: rules: - host: my-domain.com http: paths: - path: / pathType: Prefix backend: service: name: my-service port: number: 80 - path: /api pathType: Prefix backend: service: name: my-api-service port: number: 80
- TLSを指定することで、HTTPSでアクセスすることができる
- 同じドメイン上で、多くのこのなるサービスやアプリケーションを証明書を共有することができる
- 証明書実体は,Secretリソースに格納される
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-ingress spec: tls: - hosts: secretName: my-tls-secret
- Secretリソースに証明書を格納する
apiVersion: v1 kind: Secret metadata: name: my-tls-secret type: kubernetes.io/tls data: tls.crt: base64 encoded cert tls.key: base64 encoded key
cert-managerを利用して、証明書を自動で発行することができる
- cert-managerを使用することで、Let's Encryptなどの証明書を自動で発行することができる
- クラスタ内にcert-managerをデプロイすることで、証明書がないTLS Ingressを自動的に検出し、証明書を発行することができる
k8s Ingrees Controllerとは
- Ingressリソースを解釈し、ルーティングを行う
- NginxやTraefikなどがある
k8s Istioとは
- サービスメッシュを提供する
- サービス間の通信を暗号化する
- ネットワークのトラフィックを制御する、ログ、メトリクスを収集する、ロードバランシングを行う
複数のアプリケーションが相互に通信する場合、Istioを利用価値がある
k8s ConfigMapとは
- Podの設定情報を管理する
- Podの設定情報を環境変数やファイルとして提供する
- ConfigMapを使用することで、Podの設定情報を外部化することができる
apiVersion: v1 kind: ConfigMap metadata: name: my-configmap data: config.yaml: | key1: value1 key2: value2
# configmap.yaml ke1: value1 key2: value2
より簡単の方法は、kubectlを利用するkubectl create configmap my-configmap --from-file=config.yaml --namespace=my-namespace
マニフェストファイルを生成kubectl get configmap my-configmap -o yaml --export > configmap.yaml
- 設定変更により、PODの更新
Helmを利用することで、設定変更により、PODの更新を行うことができる Deployment側で、AnnotationをSpec側に追加することで、ConfigMapの変更により、PODの更新を行うことができるapiVersion: apps/v1 kind: Deployment metadata: name: my-deployment annotations: checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} spec: containers: - name: my-container image: my-image envFrom: - configMapRef: name: my-configmap
- Helmを利用することで、設定変更により、PODの更新を行うことができる
helm upgrade my-release my-chart
k8s Secretとは
- Podのシークレット情報を管理する
- シークレット情報を環境変数やファイルとして提供する
- Secretを使用することで、Podのシークレット情報を外部化することができる
apiVersion: v1 kind: Secret metadata: name: my-secret type: Opaque data: username: yyffmmtt password: MWYyZDFlMmU2N2Rm
data vs stringData
- dataはbase64エンコードされた値を指定する
- stringDataを使用することで、base64エンコードされた値を指定することなく、値を指定することができる
apiVersion: v1 kind: Secret metadata: name: my-secret type: Opaque stringData: username: ywsrock password: MWYyZDFlMmU2N2Rm
- 簡単な方法は、kubectlを利用する
kubectl create secret generic my-secret --from-literal=username=yyffmmtt --from-literal=password=MWYyZDFlMmU2N2Rm --namespace=my-namespacekubectl create secret generic my-secret --from-file=my-secret.txt --namespace=my-namespace
- Secretの利用
# ファイル全体を指定する場合 envFrom: - secretRef: name: my-secret
# 特定の値を指定する場合 env: - name: MY_ENV valueFrom: secretKeyRef: name: my-secret key: my-key
- ファイルシステムにマウントする場合
# mount先にmy-secretをマウントする apiVersion: v1 kind: Deployment metadata: name: my-deployment spec: replicas: 3 selector: matchLabels: app: my-app template: spec: containers: - name: my-container image: my-image volumeMounts: - mountPath: /etc/secret name: my-secret readOnly: true volumes: - name: my-secret secret: secretName: my-secret
- secretの内容の確認
# データは表示されません(機密情報のため) kubectl describe secret my-secret
# データはbase64エンコードされて表示されます kubectl get secret my-secret -o yaml
ベストプラクティス:機密データが表示されあいように、特定のNamespaceにSecretを作成することが推奨されている パーミッションも設定することが推奨されている
apiVersion: v1 kind: Secret metadata: name: my-secret namespace: my-namespace type: Opaque data: username: yyffmmtt password: MWYyZDFlMmU2N2Rm
- 保存データの暗号化
- k8sのデータを暗号化することで、データのセキュリティを確保することができる
暗号化されたかどうかを確認する,encription-provider-config存在しない場合、データは暗号化されていない GKEの場合、別の方式で暗号化されているため、該当のファイルが存在しない
ption-provider-config kubectl describe pod -n kube-system -l component=kube-apiserver | grep Encryption --encription-provider-config
Secretの保持 Helmを利用することで、Secretを誤って削除することを防ぐことができるkind: Secret metadata: annotations: "helm.sh/resource-policy": keep
k8s Namespaceとは
- k8sのリソースをグループ化する
kubectl create namespace my-namespace
あるいは
apiVersion: v1 kind: Namespace metadata: name: my-namespace
ResourceQuotaとは
- Namespaceのリソース使用量を制限することで、リソースの使用量を制御することができる
apiVersion: v1 kind: ResourceQuota metadata: name: my-resourcequota namespace: my-namespace spec: hard: pods: "10" requests.cpu: "4" requests.memory: 4Gi limits.cpu: "10" limits.memory: 10Gi
- NamespaceにResourceQuottaを設定
kubectl apply --namespace=my-namespace -f resourcequota.yaml
LimitRangeとは
- Podのリソース要求と制限を制御することで、Podのスケジューリングを制御することができる
apiVersion: v1 kind: LimitRange metadata: name: my-limitrange namespace: my-namespace spec: limits: - default: memory: 512Mi cpu: 500m defaultRequest: memory: 256Mi cpu: 250m type: Container
- NamespaceにLimitRangeを設定
kubectl apply --namespace=my-namespace -f limitrange.yaml
ベストプラクティスとして、NamespaceとLimitRangeを設定することが推奨されている、ただし、あくまで最後の砦として扱いする、常に、コンテナのスペック自体で明示的に要求と制限を指定するようにします。
k8s PersistentVolumeとは
- Podの永続化ストレージを管理する
- Podの永続化ストレージを提供する
- PersistentVolumeを使用することで、Podの永続化ストレージを外部化することができる
k8s PersistentVolumeClaimとは
- Podの永続化ストレージを要求する
- PersistentVolumeClaimを使用することで、Podの永続化ストレージを要求することができる
k8s リソース要求と制限
- Podのリソース要求と制限を設定することで、Podのスケジューリングを制御することができる
- リソース要求と制限を設定することで、Podのスケジューリングを制御することができる
resources: requests: memory: "64Mi" cpu: "250m" limits: memory: "128Mi" cpu: "500m"
k8s LivenessProbeとは
- PodのLivenessProbeを設定することで、Podのヘルスチェックを行うことができる
- ベストプラスティスとして、PodのLivenessProbeを設定することが推奨されている
initialDelaySecondsを指定することで、Podの起動後にLivenessProbeを実行するまでの時間を指定する,死のルールを回避する。periodSecondsを指定することで、LivenessProbeを実行する間隔を指定する(波状攻撃ようなリクエスト負担掛けないようにする)minReadySecondsを指定することで、新しいPodが起動してから、古いPodが削除されるまでの時間を指定することで、Podのスケールアウトを制御することができる
livenessProbe: httpGet: path: /healthz port: 80 initialDelaySeconds: 30 periodSeconds: 10 minReadySeconds: 30
k8s その他のprobeとは
- ReadinessProbe/liveProbe/StartupProbe
- Podがリクエストを受け付ける準備ができているかを確認する
- 失敗した場合、再び成功するまで、Podがリクエストを受け付けない
- ReadinessProbeは、必ず200番台のステータスコードを返すように設定する(ロードバランサ利用した場合,301(redirect)返したら、PODが不健全のフラグが立ってる可能性があります。)
readinessProbe: httpGet: path: /healthz port: 80 initialDelaySeconds: 5 periodSeconds: 10
- tcpSocket
- Podが指定したポートでリクエストを受け付けることができるかを確認する
readinessProbe: tcpSocket: port: 80 initialDelaySeconds: 5 periodSeconds: 10
- exec
- Podが指定したコマンドを実行し、終了コードを確認する
readinessProbe: exec: command: - cat - /tmp/healthy initialDelaySeconds: 5 periodSeconds: 10
- grpc HealthCheckの場合、grpc-health-probeツールをインストールして、execを使用して、チェックできます。
k8s Pod disruption budgetとは
- Podのスケールアウトを制御することで、Podのスケールアウトを制御することができる
- minAvailableを指定することで、Podの最小数を指定することができる
apiVersion: policy/v1beta1 kind: PodDisruptionBudget metadata: name: nginx-pdb spec: minAvailable: 2 selector: matchLabels: app: nginx
- maxUnavailableを指定することで、Podの最大数を指定することができる
apiVersion: policy/v1beta1 kind: PodDisruptionBudget metadata: name: nginx-pdb spec: maxUnavailable: 1 selector: matchLabels: app: nginx
ベストプラクティスとして、PodDisruptionBudgetを設定することが推奨されている> POdが退去しても、サービス維持に十分なレプリカ常に確保されるようにします。
imagePullPolicy
- Always
- イメージが常に最新のものであることを保証する
- IfNotPresent(default)
- イメージがローカルに存在しない場合、それを使用する
- Never
- イメージがローカルに存在する場合、それを使用する
- ベストプラクティスとして、imagePullPolicyをAlwaysに設定することが推奨されている
k8s 環境変数
- Podの環境変数を設定することで、Podの設定情報を外部化することができる
containers: - name: my-container image: my-image env: - name: MY_ENV value: my-value
- ConfigMapを使用することで、Podの環境変数を外部化することができる
envFrom: - configMapRef: name: my-configmap
# 特定の値を指定する場合 env: - name: MY_ENV valueFrom: configMapKeyRef: name: my-configmap key: my-key
envFromとenvを併用することができる、同じ名前の環境変数がある場合、envが優先される Deploymentでコマンドライン引数として、configmapの値を渡すことができる
# コマンドライン引数として、configmapの値を渡す containers: - name: my-container image: my-image command: ["/bin/sh"] args: ["-c", "echo $(MY_ENV)"] env: - name: MY_ENV valueFrom: configMapKeyRef: name: my-configmap key: my-key
# エントリーポイントとして、configmapの値を渡す containers: - name: my-container image: my-image args: - "Greetings" - "$(MY_ENV)" # configmapの環境変数を使用する env: - name: MY_ENV valueFrom: configMapKeyRef: name: my-configmap key: my-key
k8s ConfigMapから設定ファイルを生成
- ConfigMapから設定ファイルを生成することで、Podの設定情報を外部化することができる
apiVersion: v1 kind: ConfigMap metadata: name: my-configmap data: config | # configキーを作成 key1: value1 key2: value2
# deploymentを用意 # etc/config/config.yaml のファイルを作成 apiVersion: apps/v1 kind: Deployment metadata: name: my-deployment spec: replicas: 3 selector: matchLabels: app: my-app template: metadata: labels: app: my-app spec: containers: - name: my-container image: my-image volumeMounts: - mountPath: /etc/config name: my-config readOnly: true volumes: - name: my-config configMap: name: my-configmap items: - key: config path: config.yaml
- Secretを使用することで、Podの環境変数を外部化することができる
envFrom: - secretRef: name: my-secret
k8s ConfigMapとSecretのマウント
- ConfigMapをマウントする
volumes: - name: my-configmap configMap: name: my-configmap
- Secretをマウントする
volumes: - name: my-secret secret: secretName: my-secret
k8s DeamonSetの利用
- DeamonSetを使用することで、全てのノードにPodを配置することができる
- 認証やログ収集などのノードレベルのタスクを実行することができる
- ベストプラクティスとして、DeamonSetを使用することが推奨されている
apiVersion: apps/v1 kind: DeamonSet metadata: name: my-deamonset spec: containers: - name: my-container image: my-image
k8s StatefulSetとは
- StatefulSetを使用することで、Podに一意な識別子を割り当てることができる
- PODを順番に起動する/終了することができる
- ベストプラクティスとして、StatefulSetを使用することが推奨されている
apiVersion: apps/v1 kind: StatefulSet metadata: name: my-statefulset spec: selector: matchLabels: app: my-app serviceName: my-service replicas: 3 template: metadata: labels: app: my-app spec: containers: - name: my-container image: my-image
k8s Jobとは
- Jobを使用することで、一度だけ実行するタスクを実行することができる
- タスクが完了するまで、Podを起動し続けることができる
apiVersion: batch/v1 kind: Job metadata: name: my-job spec: parallelism: 1 completions: 1 template: metadata: name: my-pod spec: containers: - name: my-container image: my-image
- completionsを指定することで、タスクの完了数を指定することができる
- parallelismを指定することで、タスクの並列数を指定するこができる
k8s CronJobとは
- CronJobを使用することで、定期的に実行するタスクを実行することができる
- タスクが完了するまで、Podを起動し続けることができる
apiVersion: batch/v1beta1 kind: CronJob metadata: name: my-cronjob spec: schedule: "*/1 * * * *" jobTemplate: spec: template: metadata: name: my-pod spec: containers: - name: my-container image: my-image
- scheduleを指定することで、タスクの実行スケジュールを指定することができる
- jobemplateを指定することで、タスクのテンプレートを指定するこができる
k8s horizontalPodAutoscalerとは HPA
- Podのスケールアウトを制御することで、Podのスケールアウトを制御することができる
apiVersion: autoscaling/v1 kind: HorizontalPodAutoscaler metadata: name: my-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: my-deployment minReplicas: 1 maxReplicas: 10 metrics: - type: Resource resource: name: cpu targetAverageUtilization: 50
- scaleTargetRefを指定することで、Podのスケールアウトを制御することができる
- minReplicasを指定することで、Podの最小数を指定することができる
- maxReplicasを指定することで、Podの最大数を指定することができる
- metricsを指定することで、Podのスケールアウトのメトリクスを指定することができる
- targetCPUUtilizationPercentageを指定することで、CPU使用率の目標値を指定することができる
k8s admission controllerとは
- Podの作成や更新を制御することで、Podの作成や更新を制御することができる
k8s PodPresetsとは(試験段階で、アルファ版)
- Podの設定情報を提供することで、Podの設定情報を提供することができる
- Pod作成時点で、情報を注入することができる
- admission controllerの一種
apiVersion: settings.k8s.io/v1alpha1 kind: PodPreset metadata: name: my-podpreset spec: selector: matchLabels: app: my-app volumeMounts: - mountPath: /etc/config name: my-config volumes: - name: my-config emptyDir: {}
- PodRreset適応方法
podpreset.admission.k8s.io/podpreset-add-cahce "resource": "namespaces"
- PodRreset削除方法
podpreset.admission.k8s.io/exclude: "true"
k8s CustomResourceDefinitionとは
- カスタムリソースを定義することで、カスタムリソースを定義することができる
apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: my-crd spec: group: my-group version: v1 scope: Namespaced names: plural: my-crds singular: my-crd kind: MyCrd shortNames: - mc
k8s ロールベースのアクセス制御RBAC
- ロールベースのアクセス制御を使用することで、ユーザーのアクセス権限を制御することができる
- RBAC 有効確認
kubectl api-versions | grep rbac
kubectl describe pod -n kube-system -l component=kube-apiserver
ロールの作成
- ローはnamespace全体、あるいは特定のリソースに対してアクセス権限を設定することができる
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: my-clusterrole rules: - apiGroups: - "" resources: - pods - sercets verbs: - get - list - watch
ロールの割り当て
- ロールをユーザーに割り当てることで、ユーザーにアクセス権限を設定することができる
- 特定のNamespaceにロールを割り当てることができる
- k8sのロールはAdditiveである,追加行くことができる、削減はできない
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: my-rolebinding namespace: my-namespace subjects: - kind: User name: my-user apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole name: my-clusterrole apiGroup: rbac.authorization.k8s.io
ロール必要な判定kubectl describe clusterrole/edit
ベストプラクティスとして、必要最小限の権限を割り当てることが推奨されている