1
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?

【Kubernetes】リソース整理メモ

Last updated at Posted at 2024-11-12

(アホなので)各用途でリソースが何だったかわからなくなる…のでまとめた。

Deployment/Daemonset/Staticpodリソース

Deployment

ReplicaSetを管理してローリングアップデートやロールバックを実現する。

deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sample-deployment
spec:
  selector:
    matchLabels:               #templateセクションの設定が自動設定
      app: my-nginx
  strategy:
    type: RollingUpdate        #1podずつ更新する
  replicas: 3                  #pod数
  template:                    #podの仕様
    metadata:
      labels:                  #ここに設定したラベルがselectorにも適用されることでグループ化
        app: my-nginx
    spec:
      containers:
      - name: nginx-container
        image: nginx
        ports:
        - containerPort: 80

たとえば"httpd-frontend"という名前のdeploymentをデプロイすると、
"httpd-frontend-5f494775df"という名前のreplicasetが作られ、
"httpd-frontend-5f494775df-random1"
"httpd-frontend-5f494775df-random2" というように-で枝分かれしたpodが作られる

deploymentのreplicasの数をeditで変えるとreplicasetの数も同時に変更される。※逆は不可
マニフェストの内容としてはkind以外はreplicasetと同じ
strategyはRollingUpdateで1podずつ更新。Recreateは全pod一気に削除→再作成

一般的なユーザーリソースの他、
k8sのデフォルトのリソースとしてはCoreDNSなどで使用されている。

Daemonset

daemonset
apiVersion: apps/v1
kind: DaemonSet
metadata:
  labels:
    app: elasticsearch
  name: elasticsearch
  namespace: kube-system
spec:
  selector:
    matchLabels:
      app: elasticsearch    #templateのラベルと一致させる
  template:
    metadata:
      labels:
        app: elasticsearch
    spec:
      containers:
      - image: registry.k8s.io/fluentd-elasticsearch:1.20
        name: fluentd-elasticsearch

数関係なくWorkerNodeに1ずつたてるpod
ワーカーノードを管理するデーモンをpodで動作させたい場合に使用
システムリソースのモニタリングツールやログ収集(fluentd)など。ノードが消えるとpodもそのまま消える。

KubernetesクラスタでデフォルトでDaemonSetとしてデプロイされる代表的なものには、以下のようなコンポーネントがある

1. Node Exporter(Prometheus用)
Prometheusによって各ノードのメトリクスを収集するために使用されるエージェント。システムのリソース使用状況(CPU、メモリ、ディスクなど)をモニタリングする

2. Fluentd(またはその他のログ収集エージェント)
ログデータを集約し、中央のログ集約システム(例:Elasticsearch、Splunk)に送信するためのエージェント。ノード上のすべてのコンテナのログを収集できる

3. Node Problem Detector
ノードの健康状態を監視するためのコンポーネント。ノードのハードウェアやオペレーティングシステムレベルの問題を検出できる

4. Kube-proxy
Kubernetesのネットワークプロキシで、サービスのエンドポイント間の通信を管理する。主要な役割は、ネットワークトラフィックを適切なサービスエンドポイントにルーティングすること

5. CNIプラグイン(例えば、Cilium、Weave Net、Calico)
CNI(Container Network Interface)プラグインは、コンテナ間のネットワークを管理するために使用されるネットワークプラグイン。pod間の通信を制御・管理

6. ログ収集ユーティリティ(例:fluent-bit, logdna-agent)
これらのエージェントは、各ノードからログデータを収集し、集中管理するために使用される。

7. システムメトリクスコレクター(例:metrics-server)
metrics-serverは、クラスタ内の各ノードからシステムメトリクスを収集し、Kubernetes APIサーバに提供するエージェント

Staticpod

通常の方法でDeploymentやReplicaSetなどkube-apiserverを介して各コントローラーで処理されるのではなく、コントロールプレーンの影響を受けずに特定のノードのkubeletプロセスによってのみ直接管理・処理されるpod
そのため、
・そもそもコントロールプレーンのコンポーネントをデプロイするのに使用されている
・両者ともkube-schedulerからは無視される

#コマンドでのデプロイ
kubectl run --restart=Never --image=busybox:1.28.4 static-busybox --dry-run=client -o yaml --command -- sleep 1000 > /etc/kubernetes/manifests/static-busybox.yaml

Static Podの名前には末尾に"-node名"が付く。
kubeletが監視している特定のディレクトリ(デフォルトでは /etc/kubernetes/manifests)に配置される
※定義ファイルの場所は各ノードのkubelet設定ファイル /var/lib/kubelet/config.ymlstaticPodPath: で確認できる

#デフォルトでデプロイされているstaticpod群(例)↓:

/etc/kubernetes/manifests/kube-apiserver.yaml
/etc/kubernetes/manifests/kube-controller-manager.yaml
/etc/kubernetes/manifests/kube-scheduler.yaml
/etc/kubernetes/manifests/etcd.yaml

これらのStatic Podマニフェストファイルを編集することで、直接これらのコンポーネントの設定を変更することができる。Kubeletはこのディレクトリを監視しており、ファイルの変更を検知すると対応するPodを再作成し、ファイルが削除されるとpodを終了させる。

Networkリソース

ClusterIP

デフォルトのサービスタイプで、クラスタ内の内部トラフィックのみが対象
・クラスタ内部トラフィック用の仮想IPを提供
・外部からのアクセスはできない
・クラスター内部の通信に使用される

Serviceリソースに振られるNWは
/etc/kubernetes/manifests/kube-apiserver.yaml
- --service-cluster-ip-range=10.96.0.0/12
で確認できる。

apiVersion: v1
kind: Service
metadata:
  name: webapp-service
spec:
  type: ClusterIP
  ports:
    - port: 8080          #serviceが受け付けるport
      targetPort: 8080    #podがリッスンしているport
  selector:               #ServiceがトラフィックをどのPodにルーティングするかを決定
    app: webapp

podのmetadata.labels: にapp: webapp
と設定されているものだけが対象になる。
対象になったpodのアドレスがEndpointとして表示される

コマンドで設定したい場合は以下

#podを指定してデプロイ(svcが受け付けるportを6379で指定)
kubectl expose pod redis --port=6379 --name redis-service

#podデプロイ+ClusterIP(podと同じ名前のsvcが一緒にデプロイされる)
kubectl run httpd --image=httpd:alpine --port=80 --expose

クラスタ内部からアクセスできる

http://<ClusterIP>:8080

NodePort

各クラスタノードの特定のポートを開放し、そのポート番号を通じて外部トラフィックをノードにルーティング
・クラスタ外部からアクセスできる
・ノードのIPアドレス上の指定ポートにアクセス
デプロイすると自動的にClusterIPも払い出される

apiVersion: v1
kind: Service
metadata:
  name: webapp-service
spec:
  type: NodePort
  ports:
    - port: 8080        #Serviceのport
      targetPort: 8080  #Podが受け付けるport
      nodePort: 30080   #外部アクセス用のport
  selector:
    app: webapp

アクセス(クラスタ外部から)

http://<NodeIP>:30080

get出力例

NAME             TYPE       CLUSTER-IP    EXTERNAL-IP   PORT(S)          AGE
webapp-service   NodePort   10.43.80.67   <none>        8080:30080/TCP   10m

CLUSTER-IP: 10.43.80.67 は自動的に割り当てられたClusterIP
PORT(S): 8080:30080/TCP は、ClusterIPのポート(8080)と、各ノードのNodePort(30080)を示す

LoadBalancer

外部ロードバランサーを利用し、外部トラフィックをKubernetesクラスタ内のサービスにルーティング
・クラウドプロバイダー(AWSなど)が外部ロードバランサーをプロビジョニングし、設定を管理
・自動的に負荷分散IPが割り当てられる

apiVersion: v1
kind: Service
metadata:
  name: webapp-service
spec:
  type: LoadBalancer
  ports:
    - port: 8080
      targetPort: 8080
  selector:
    app: webapp

アクセス方法(クラウドプロバイダーによる外部IP)

# クラウドプロバイダーが割り当てた外部IPアドレスでアクセス
http://<LoadBalancerIP>:8080

ExternalIP

特定の外部IPから直接アクセスを受ける必要がある場合、特定のノードIPを外部トラフィックのエントリーポイントとして使用する
・外部のIPアドレスをノードに直接マッピングして、外部トラフィックを特定のサービスにルーティング
・ClusterIPと連携して外部からアクセスを提供

apiVersion: v1
kind: Service
metadata:
  name: webapp-service
spec:
  type: ClusterIP      #NodePort,LoadBalancerも指定できる
  externalIPs:
  - 192.168.1.100      #外部IPアドレス
  ports:
    - port: 8080
      targetPort: 8080
  selector:
    app: webapp

アクセス方法(外部から指定されたExternalIP)

http://192.168.1.100:8080

Ingress

複数のHTTPおよびHTTPSルータを定義し、クラスタ内の異なるサービスにトラフィックをルーティング
・ドメイン名やパスを基にしたルーティング
・SSL/TLS終端を管理できる

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /         #リクエストパスを指定したターゲットにリライトする。例えば、リクエストが/wear/somethingの場合、このリクエストは/somethingにリライトされてwear-serviceに送られる。
    nginx.ingress.kubernetes.io/ssl-redirect: "false"     #HTTPリクエストをHTTPSにリダイレクトするが、falseに設定されていると無効になる
  name: ingress-wear-watch
  namespace: app-space
spec:
  rules:
  - http:
      paths:
      - backend:
          service:
            name: wear-service                            #アプリケーションのserviceを指定
            port:
              number: 8080                                #serviceが受け付けるport
        path: /wear                                       #URLにつけるpath
        pathType: Prefix                                  #例えば、path: /wearと指定した場合、/wear, /wear/, /wear/somethingのようなパスにマッチする。
      - backend:
          service:
            name: video-service
            port:
              number: 8080
        path: /watch
        pathType: Prefix

アプリ例

apiVersion: v1
kind: Service
metadata:
  name: wear-service
  namespace: app-space
spec:
  ports:
  - port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    app: webapp-wear
  type: ClusterIP
apiVersion: apps/v1
kind: Deployment
metadata:
  name: webapp-wear
  namespace: app-space
spec:
  replicas: 1
  selector:
    matchLabels:
      app: webapp-wear
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: webapp-wear
    spec:
      containers:
      - image: kodekloud/ecommerce:apparels
        name: simple-webapp
        ports:
        - containerPort: 8080
          protocol: TCP

アクセス(DNSが設定された場合)

http://webapp.example.com/wear
http://webapp.example.com/watch

Ingress Controller

Ingressリソースは単なるルールの定義なので、実際のトラフィックルーティングを行うにはそれらのルールを実行するためのコンポーネント(Ingressコントローラ)が必要
#有名なIngressコントローラには以下のようなものがあり、URLから引っ張ってきてデプロイする

・NGINX Ingress コントローラ
・Traefik
・HAProxy
・Envoy
・Istio(サイドカープロキシとIngressゲートウェイとして)

Deployment/service例

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
    app.kubernetes.io/version: 1.1.2
    helm.sh/chart: ingress-nginx-4.0.18
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/component: controller
      app.kubernetes.io/instance: ingress-nginx
      app.kubernetes.io/name: ingress-nginx
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app.kubernetes.io/component: controller
        app.kubernetes.io/instance: ingress-nginx
        app.kubernetes.io/name: ingress-nginx
    spec:
      containers:
      - args:
        - /nginx-ingress-controller
        - --publish-service=$(POD_NAMESPACE)/ingress-nginx-controller
        - --election-id=ingress-controller-leader
        - --watch-ingress-without-class=true
        - --default-backend-service=app-space/default-backend-service
        - --controller-class=k8s.io/ingress-nginx
        - --ingress-class=nginx
        - --configmap=$(POD_NAMESPACE)/ingress-nginx-controller
        - --validating-webhook=:8443
        - --validating-webhook-certificate=/usr/local/certificates/cert
        - --validating-webhook-key=/usr/local/certificates/key
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.namespace
        - name: LD_PRELOAD
          value: /usr/local/lib/libmimalloc.so
        image: registry.k8s.io/ingress-nginx/controller:v1.1.2@sha256:28b11ce69e57843de44e3db6413e98d09de0f6688e33d4bd384002a44f78405c
        imagePullPolicy: IfNotPresent
        lifecycle:
          preStop:
            exec:
              command:
              - /wait-shutdown
        livenessProbe:
          failureThreshold: 5
          httpGet:
            path: /healthz
            port: 10254
            scheme: HTTP
          initialDelaySeconds: 10
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 1
        name: controller
        ports:
        - containerPort: 80
          name: http
          protocol: TCP
        - containerPort: 443
          name: https
          protocol: TCP
        - containerPort: 8443
          name: webhook
          protocol: TCP
        readinessProbe:
          failureThreshold: 3
          httpGet:
            path: /healthz
            port: 10254
            scheme: HTTP
        resources:
          requests:
            cpu: 100m
            memory: 90Mi
        securityContext:
          allowPrivilegeEscalation: true
          capabilities:
            add:
            - NET_BIND_SERVICE
            drop:
            - ALL
          runAsUser: 101
        volumeMounts:
        - mountPath: /usr/local/certificates/
          name: webhook-cert
          readOnly: true
      dnsPolicy: ClusterFirst
      nodeSelector:
        kubernetes.io/os: linux
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      serviceAccount: ingress-nginx
      serviceAccountName: ingress-nginx
      terminationGracePeriodSeconds: 300
      volumes:
      - name: webhook-cert
        secret:
          defaultMode: 420
          secretName: ingress-nginx-admission

Service

k get svc -n ingress-nginx
NAME                                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx-controller             NodePort    172.20.43.138    <none>        80:30080/TCP,443:32103/TCP   9m48s
ingress-nginx-controller-admission   ClusterIP   172.20.165.224   <none>        443/TCP                      9m48s
apiVersion: v1
kind: Service
metadata:
  name: ingress-nginx-controller
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
    app.kubernetes.io/version: 1.1.2
    helm.sh/chart: ingress-nginx-4.0.18
spec:
  externalTrafficPolicy: Local
  internalTrafficPolicy: Cluster
  ports:
  - appProtocol: http
    name: http
    nodePort: 30080
    port: 80
    protocol: TCP
    targetPort: http
  - appProtocol: https
    name: https
    nodePort: 32103
    port: 443
    protocol: TCP
    targetPort: https
  selector:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
  type: NodePort
apiVersion: v1
kind: Service
metadata:
  name: ingress-nginx-controller-admission
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
    app.kubernetes.io/version: 1.1.2
    helm.sh/chart: ingress-nginx-4.0.18
spec:
  internalTrafficPolicy: Cluster
  ports:
  - appProtocol: https
    name: https-webhook
    port: 443
    protocol: TCP
    targetPort: webhook
  selector:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
  sessionAffinity: None
  type: ClusterIP

coredns

kube-dnsというserviceとcorednsというdeploymentで構成されており、クラスタ内のリソースを名前解決してくれる。同namespaceであればPod名 or Service名で通信できる。
別のnamespaceへはPod名 or Service名.NameSpace名(.svc or .svc.デフォルトドメイン)で通信できる。
適用されているconfigmapでdns設定を確認できる。

Storageリソース

PV作成(static)

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-log
 #labels:
   #type: log-storage                     #PVCで直接このPVを指定したい場合、ラベル付与
spec:
  persistentVolumeReclaimPolicy: Retain   #PVCが削除された後、PVがどのように扱われるかを制御するポリシー(Retain=そのまま残る,Delete=ボリュームもボリューム内のデータも削除)
  accessModes:
    - ReadWriteMany                       #ボリュームは複数ノードで読み書き可。ReadWriteOnce=単一ノードによって読み書き可、ReadOnlyMany=複数ノードで読み取り専用
  capacity:
    storage: 100Mi
  hostPath:                               #node上の領域を使用する
    path: /pv/log                         #node上の/pv/logを使う
# kubectl get pv -o wide
NAME     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                 STORAGECLASS   VOLUMEATTRIBUTESCLASS   REASON   AGE   VOLUMEMODE
pv-log   100Mi      RWX            Retain           Bound    default/claim-log-1                  <unset>                          16m   Filesystem

PV作成(自動)

StorageClassを作成する。
PVCに伴って自動でPVが作成される。動的プロビジョニング

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: volume-sc
provisioner: kubernetes.io/portworx-volume         #プロビジョナー(kubernetes.io/no-provisioner = local手動管理で動的プロビジョニングをサポートしていない)。外部ストレージなら/aws-ebsや/azure-diskなど
allowVolumeExpansion: true                         #ボリュームの拡張を許可
volumeBindingMode: WaitForFirstConsumer            #PVとPVCのバインディングの振る舞いを制御.PVC作成→PV作成ではなく、PVCを使用するPodが作成されるのを待機。(Immediate = PVC作成→すぐPV作成)

PVC作成

作成されると、クラスタ上で要件(accsessmodeや容量)に一致するPVを探し、自動的にバインドする。(複数PVが一致する場合は、容量の大きいものから使われる)
StorageClassを指定した場合はBindingModeに応じてPVが作成される

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: claim-log-1
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 50Mi
 #selector:
   #matchLabels:
     #type: log-storage                   #ラベル付きのPVを直接指定する場合
 #volumeName: pv-log                      #直接PV名を指定でも可
  storageClassName: volume-sc             #StorageClassを指定する場合.SCのbindingmodeにより即時またはPVC呼び出し時にPV作成
# kubectl get pvc -o wide
NAME          STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   VOLUMEATTRIBUTESCLASS   AGE   VOLUMEMODE
claim-log-1   Bound    pv-log   100Mi      RWX                           <unset>                 11m   Filesystem

PVがない場合、STATUSはPendingになる

Podで利用

apiVersion: v1
kind: Pod
metadata:
  name: webapp
spec:
  containers:
  - name: event-simulator
    image: kodekloud/event-simulator
    env:
    - name: LOG_HANDLERS
      value: file
    volumeMounts:
    - mountPath: /log
      name: log-volume

  volumes:
  - name: log-volume
    persistentVolumeClaim:
      claimName: claim-log-1
   #hostpath:                        #nodeの領域を使う.シングルノードや一時利用専用
   #  path: /data                    #node上の/dataを使う
   #  type: directory                #/dataはディレクトリで存在する必要がある

PVCを削除した場合

ReclaimPolicyがRetainの場合、PVCを削除すると...

# kubectl get pv
NAME     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                 STORAGECLASS   VOLUMEATTRIBUTESCLASS   REASON   AGE
pv-log   100Mi      RWX            Retain           Bound    default/claim-log-1                  <unset>                          17m
# 
# kubectl get pvc
NAME          STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   VOLUMEATTRIBUTESCLASS   AGE
claim-log-1   Bound    pv-log   100Mi      RWX                           <unset>                 3m9s
# 
# kubectl delete pvc claim-log-1
persistentvolumeclaim "claim-log-1" deleted
#
# kubectl get pvc
NAME          STATUS        VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   VOLUMEATTRIBUTESCLASS   AGE
claim-log-1   Terminating   pv-log   100Mi      RWX                           <unset>                 6m59s
#
# kubectl get pv
NAME     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                 STORAGECLASS   VOLUMEATTRIBUTESCLASS   REASON   AGE
pv-log   100Mi      RWX            Retain           Bound    default/claim-log-1                  <unset>                          21m


podがpvcを呼び出しているため、terminatingになる.PVは残るが、使用できない
podを削除↓
# kubectl delete pod webapp
pod "webapp" deleted
#
# kubectl get pvc
No resources found in default namespace.
#
# kubectl get pv
NAME     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS     CLAIM                 STORAGECLASS   VOLUMEATTRIBUTESCLASS   REASON   AGE
pv-log   100Mi      RWX            Retain           Released   default/claim-log-1                  <unset>                          25m

pvcを呼び出しているpodが消えるとpvcも削除される。pvは残っており、STATUSはReleasedになっている

スケジューリングを制御するリソース

drain/cordon

ノード再起動や一時的なメンテナンス用

drain = 指定したノードからpodを退避する
cordon = 指定したノードへのスケジューリングを無効にする

kubectl drain host03 --ignore-daemonsets --delete-local-data --force

--ignore-daemonsets: DaemonSet で管理されている Pod は退避の対象外
--delete-local-data: ノード上のローカルストレージを使用している Pod を強制的に削除
--force: 静的 Pod を強制的に削除

drainすると自動でcordonも設定される

#設定
kubectl cordon host03

#解除
kubectl uncordon host03

ノードにSchedulingDisabledというステータスがつく
ノード上の既存のPodはそのまま継続して実行されるが、それ以上新しいPodがスケジュールされることはない

taint/toleration

ノードの役割管理、特定の用途に対するノードの使用制限用途
特定のノードには特定のポッドしかスケジュールしないようにしたい場合(高性能ノードを特定のワークロード専用にする等)

taint = ノードにカスタムラベルを付与し、特定の条件を満たさない場合にPodのスケジュールを制限
toleration = Pod に toleration を設定することで選択的にそのノードにスケジュールする

ノードにtaint付与

#設定
kubectl taint nodes host03 key=value:NoSchedule

#解除
kubectl taint nodes host03 key-

NoSchedule: このtaintを持つノードにPodをスケジュールできない
PreferNoSchedule: なるべくこのノードにPodをスケジュールしないようにする
NoExecute: すでにノード上で動作しているPodも追い出し、再配置

podにtoleration設定
apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mycontainer
    image: nginx
  tolerations:
  - key: "key"
    operator: "Equal"
    value: "value"
    effect: "NoSchedule"

後述のAffinity設定との差異としては、ノードに対して直接設定されるため、全てのpodに対して適用される

Affinity

こちらはノードにラベルを付与して指定する方法
同じ種類のpodを異なるノードに分散して配置する等で、単一のノード障害時の影響を最小化する場合

Podに適用され、どのノードにスケジュールされるかを制御
affinity設定に基づき、スケジューラーはpodを特定のlabelを持つノードに優先的に配置する

ノードにラベル付与

#ラベル付与
kubectl label node node01 color=blue

#確認
kubectl get node --show-labels

nodeSelectorまたはnodeAffinityでlabelのついたnodeにのみデプロイされるようにする

podに設定(ノードセレクタ)
    spec:
      containers:
      - image: nginx
        name: nginx
      nodeSelector:
        color: blue
podに設定(ノードアフィニティ)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: blue
  labels:
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
      affinity:
       nodeAffinity:
        requiredDuringSchedulingIgnoredDuringExecution:
          nodeSelectorTerms:
           - matchExpressions:
              - key: color
                operator: In
                values:
                 - blue

operatorは
"Exists": keyに対する値が存在する場合に一致する(value値はなくてもよい)
"In": keyに対する値が指定したvaluesの一部と一致する場合に一致する。(valueが必須)

Securityリソース

NetworkPolicy

リソース単体でACLをかけたい場合

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: internal-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      name: internal
  policyTypes:
  - Egress
  - Ingress
  ingress:
    - {}
  egress:
  - to:
    - podSelector:
        matchLabels:
          name: mysql
    ports:
    - protocol: TCP
      port: 3306

  - to:
    - podSelector:
        matchLabels:
          name: payroll
    ports:
    - protocol: TCP
      port: 8080

  - ports:
    - port: 53
      protocol: UDP
    - port: 53
      protocol: TCP

Role

特定の名前空間内でアクセス制御を定義
リソースへのアクセス権限(例えば、読み取り、書き込み、削除など)が含まれる。

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: mynamespace
  name: pod-reader
rules:
- apiGroups: [""]             #コアAPIグループ(v1)の範囲。kubectl api-resources で確認
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

RoleBinding

特定のnamespace内で、Role または ClusterRole をユーザー、グループ、またはサービスアカウントに関連付ける。

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods
  namespace: mynamespace
subjects:
- kind: User                  #Group や ServiceAccount も指定できる
  name: jane                  #kubectl get pod --as=jane でなりすまして実行できる
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader            #roleリソース名を指定
  apiGroup: rbac.authorization.k8s.io

ClusterRole

クラスタ全体でアクセス制御を定義。namespaceに限定されないため、クラスター全体のリソースに対するアクセス権限を付与できる。

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: cluster-admin
rules:
- apiGroups: ["*"]             #すべてのAPIグループ
  resources: ["*"]             #すべてのリソース
  verbs: ["*"]                 #すべての動作。つまりこれはフルアクセスになる

ClusterRoleBinding

クラスタ全体で、ClusterRole をユーザー、グループ、またはサービスアカウントに関連付ける。

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: cluster-admin-binding
subjects:
- kind: User
  name: jane
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io

ServiceAccount

podからの通信に使用するアカウント。podをdescribeすると使用されているアカウントを確認できる。

アカウント作成

# kubectl create sa testsa

role、rolebindingで権限付与し、deploymentで指定

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
  namespace: default
spec:
  selector:
    matchLabels:
      name: web-app
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        name: web-app
    spec:
      serviceAccountName: testsa
      containers:
      ...

情報を別出しするリソース

マニフェストファイルが似ており、どちらも用途としては同じ。

Configmap

apiVersion: v1
data:
  APP_COLOR: darkblue              # 格納する KEY: VALUE
  APP_OTHER: disregard
kind: ConfigMap
metadata:
  name: webapp-config-map          # ConfigMap名。適用時に使用する
  namespace: default

podに適用(環境変数)

apiVersion: v1
kind: Pod
metadata:
  labels:
    name: webapp-color
  name: webapp-color
  namespace: default
spec:
  containers:
  - env:
    - name: APP_COLOR
      valueFrom:
        configMapKeyRef:
         name: webapp-config-map     # この値を取得するConfigMap名
         key: APP_COLOR              # 取得するKEY
    image: webapp
    imagePullPolicy: Always
    name: webapp-color

podに適用(ボリュームマウント)

apiVersion: v1
kind: Pod
metadata:
  labels:
    name: webapp-color
  name: webapp-color
  namespace: default
spec:
  containers:
  - name: webapp-color
    image: webapp
    imagePullPolicy: Always
    volumeMounts:
    - mountPath: /etc/config         # マウントするパスを指定
      name: config-volume
  volumes:
  - name: config-volume
    configMap:
      name: webapp-config-map        # このConfigMapからデータを取得

Podが起動すると、ConfigMapの各キーは指定されたディレクトリ内にファイルとして表示される。

/etc/config/
├── APP_COLOR     #ファイルの内容は darkblue
└── APP_OTHER     #ファイルの内容は disregard

Secret

機密情報(パスワード、OAuthトークン、SSHキーなど)を保存するためのリソース
Pod内のコンテナにマウントされ、アプリケーションが機密情報に安全にアクセスできるようにする。
マニフェストの場合、値ベタ書きだとダメ。base64エンコードが必要

# echo -n "XXX" |base64
apiVersion: v1
kind: Secret
metadata:
  name: db-secret
type: Opaque
data:                                # stringDataというフィールドにすればエンコード不要。作成後に自動でエンコードされた値が入る
  DB_Host: c3FsMDE=                  # base64エンコードされた値を入れる.sql01
  DB_User: cm9vdA==                  # root
  DB_Password: cGFzc3dvcmQxMjM=      # password123

以下でも作成できる。--from-literalでOpaque形式。エンコードは不要

# kubectl create secret generic --from-literal=DB_Host=sql01 --from-literal=DB_User=root --from-literal=DB_Password=password123

pod適用(環境変数利用)

apiVersion: v1
kind: Pod
metadata:
  name: db-pod
spec:
  containers:
    - name: app-container
      image: mysql
      env:
        - name: DB_HOST
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: DB_Host
        - name: DB_USER
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: DB_User
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: DB_Password

pod適用(ボリュームマウント)

apiVersion: v1
kind: Pod
metadata:
  name: db-pod
spec:
  containers:
  - name: app-container
    image: mysql
    command:
     - sleep
     - "4800"
    volumeMounts:
    - name: secret-volume             # ボリュームの名前
      mountPath: /etc/db-secret       # マウントするパス
      readOnly: true                  # 読み取り専用
  volumes:
  - name: secret-volume               # ボリュームの定義
    secret:
      secretName: db-secret           # 使用するSecretの名前

Podが起動すると、ConfigMapの各キーは指定されたディレクトリ内にファイルとして表示される。
内容はデコード済みの値(DB_Hostならsql01)

/etc/db-secret/
├── DB_Host
├── DB_User
└── DB_Password

おまけ

忘れがちなやつリスト

・namespace固定
# kubectl config set-context --current -namespace=NAMESPACE


・APIリソース確認
# kubectl api-resources


・コンテナのシェルへログイン。(-c なしでpodへログイン)
# kubectl exec -it my-pod -c my-container -- /bin/bash


・json整形(出力を抜き出して表示)
# kubectl get pod -o=jsonpath='{.items[*].metadata.name}'
nginx redis


・出力を抜き出して任意のカラムを追加して表示.名前でソート
# kubectl get deployment -n admin -o custom-columns="DEPLOYMENT:metadata.name,CONTAINER_IMAGE:spec.template.spec.containers[].image,REPLICAS:status.replicas,NAMESPACE:metadata.namespace" --sort-by=.metadata.name
DEPLOYMENT   CONTAINER_IMAGE   REPLICAS   NAMESPACE
deploy1      nginx             1          admin
deploy2      nginx:alpine      1          admin
deploy3      nginx:1.16        1          admin
deploy4      nginx:1.17        1          admin
deploy5      nginx:latest      1          admin2


・Pod作成
# kubectl run 名 --restart=Never nginx --image=nginx:alpine
  --restartで挙動を設定できる
   Always: デプロイコントローラで起動、要求を待ち続け終了せず、異常終了したら再起動する(デフォ)
   Never: podを直接起動、podが停止したときにリスタートしない
   OnFailure: jobの制御下で起動、起動失敗した時に所定の回数に達するまでポッドの起動を再試行


・Pod/Serviceをまとめて作成
# kubectl expose pod redis --port=6379 --name redis-service
# kubectl run httpd --image=httpd:alpine --port=80 --expose
  →podと同じ名前のsvcになる


・Deployment作成
kubectl create deployment redis-deploy --image=redis --replicas=2 -n dev-ns

参考

kodecloud

1
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
1
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?