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

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

ワークロードリソース

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
        imagePullPolicy: IfNotPresent       #ローカルでイメージが見つからない場合にのみイメージをpullする。
        ports:
        - containerPort: 80

たとえば"httpd-frontend"という名前のdeploymentをデプロイすると、
"httpd-frontend-5f494775df"という名前のreplicasetが作られ、
"httpd-frontend-5f494775df-random1"
"httpd-frontend-5f494775df-random2" というように-で枝分かれしたpodが作られる
一般的なユーザーリソースの他、
k8sのデフォルトのリソースとしてはCoreDNSなどで使用されている。

RollingUpdate

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

imagePullPolicy

IfNotPresent: ローカルでイメージが見つからない場合にのみイメージをpullする。imagePullPolicy のタグが省略されていて、利用してるイメージのタグはあるが:latestでない場合にも適用される。

Always: kubeletがコンテナを起動する度に、コンテナイメージレジストリに問い合わせて、イメージのダイジェストの名前解決を行う。もし同じダイジェストのコンテナイメージをローカルにキャッシュしていたら、そのキャッシュされたイメージを利用する。そうでなければ、解決されたダイジェストのイメージをダウンロードし、そのイメージを利用してコンテナを起動する。imagePullPolicy のタグが省略されていて、利用しているイメージのタグが:latestの場合や省略されている場合にも適用される。

Never: 常にローカルでイメージを探そうとする。ない場合にもイメージはpullしない

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もそのまま消える。

代表的なものには、以下のようなコンポーネントがある

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を終了させる。

sidecarコンテナ

同じPod内でメインのアプリケーションコンテナと一緒に動作する補助的なコンテナ。
起動したコンテナはCompletedで終了せずメインコンテナと並んで稼働し続ける。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
  labels:
    app: myapp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
        - name: myapp
          image: alpine:latest
          command: ['sh', '-c', 'while true; do echo "logging" >> /opt/logs.txt; sleep 1; done']
          volumeMounts:
            - name: data
              mountPath: /opt
      initContainers:
        - name: logshipper
          image: alpine:latest
          restartPolicy: Always
          command: ['sh', '-c', 'tail -F /opt/logs.txt']
          volumeMounts:
            - name: data
              mountPath: /opt
      volumes:
        - name: data
          emptyDir: {}

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: 80      #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

# 同namespaceからのリソースであれば、coreDNSに登録されているためサービス名でもアクセスできる
http://<SERVICENAME>:8080

NodePort

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

apiVersion: v1
kind: Service
metadata:
  name: webapp-service
spec:
  type: NodePort
  ports:
    - port: 8080        #Serviceのport
      targetPort: 80    #Podが受け付けるport
      nodePort: 30080   #外部アクセス用のport.指定なしだと30000〜ランダムで割り振られる
  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)を示す

ExternalIP

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

タイプがあるわけではなく、ClusterIPのマニフェストにspec.externalIPsを追加する。

apiVersion: v1
kind: Service
metadata:
  name: webapp-service
spec:
  type: ClusterIP
  externalIPs:
  - 192.168.1.100      #ノードのIPアドレスをマッピング
  ports:
    - port: 8080
      targetPort: 80
  selector:
    app: webapp

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

http://192.168.1.100:8080

Clientからexternal IPに対して疎通ができなければならないため、あまり使われていない。
↓LoadBalancerのMetalLBでは external IPの仕組みをうまく使って通信を実現している。

LoadBalancer

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

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

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

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

serviceとしてはEXTERNAL-IPにクラウドプロバイダから割り当てられたアドレスが入る

$ kubectl get svc
NAME                      TYPE           CLUSTER-IP      EXTERNAL-IP       PORT(S)          AGE
service-loadbalancer      LoadBalancer   192.168.66.72   129.X.X.X         8080:30334/TCP   115m

なお、オンプレミスで使いたい場合、外部プロバイダーの代わりにMetalLBをデプロイすることでEXTERNAL-IPを払い出すことができる。

MetalLB

Kubernetes環境の通信の負荷分散をする場合、クラウドでしか利用できないLoadBalancerタイプのServiceリソースをオンプレ環境でも利用できるようにする機能。

あらかじめユーザーで指定した範囲のIPアドレスプールからLoadBalancer ServiceにIPアドレスを割り振って、そのIPアドレスを周辺の機器に周知する。 クラウドのロードバランサーのようにグローバルIPが割り当てられることは基本的にはない

周知に使うプロトコルはMetalLBのモードによって異なる。

L2モード
・MetalLBがARP(IPv4)とNDP(IPv6)で、クライアントに対して仮想IPアドレスを解決する
・ロードバランシングはしないため、ノードダウンしない限り常に一定のリーダーノードにトラフィックが来る

BGPモード
・MetalLBがBGPをしゃべって、外部のBGPルータとBGP peeringして仮想IPアドレスへのルーティング情報を伝える。
・ルータ側の設定によってノード間でロードバランシングが可能
・Kubernetesクラスタ外にBGPルータが必要

apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: internalapi
  namespace: metallb-system
spec:
  addresses:
    - 192.168.0.20 - 192.168.0.100   #ロードバランサーへ割り当てるアドレス。レンジで指定するほか、/24のCIDR指定でも可
  autoAssign: true
  avoidBuggyIPs: false
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: internalapi
  namespace: metallb-system
spec:
  ipAddressPools:
  - internalapi                      #AddressPoolを指定
  interfaces:
  - ens1f0                           #使用するIFを指定。

この設定で、
192.168.0.20から192.168.0.100までのIPアドレスがens1f0IF経由で同じL2NW上の他のデバイスやホストに対して広告される。
この状態でLoadBalancerTypeのサービスをデプロイすると、指定したレンジからEXTERNAL-IPが割り当てられる

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

multus

Multusは2つ以上のCNIのNetwork InterfaceをPodへアタッチする仕組み。
接続するネットワークをNetworkAttachmentDefinition(もしくはnet-attach-def)というCustom Resourceとして表現する。基本的に連携するCNIに依存している

apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
  name: macvlan-net
  namespace: namespace01
spec:
  config: |
    {
      "cniVersion": "0.3.1",
      "name": "macvlan-net",             #CNIプラグイン内で参照されるものであり、Podのアノテーションで設定する対象ではない
      "type": "macvlan",                 #CNIプラグインのタイプを指定
      "master": "eth0",                  #どの物理ネットワークインターフェースを基に仮想ネットワークを生成するかを定義
      "ipam": {
        "type": "whereabouts",           #IPAMプラグインを指定.他にはstatic,dhcp,host-local,azure-vnet-ipamなど
        "range": "172.16.0.0/24",
        "range_start": "172.16.0.30",
        "range_end": "172.16.0.70"
      }
    }

CNIプラグインのtype

bridge: 一般的なネットワークブリッジを作成して、複数のコンテナを同じネットワークセグメントに接続
ipvlan: IPアドレスを共有する複数のNWIFを作成する。物理IFと同じMACアドレスを共有する
loopback: コンテナ内のループバックデバイスを設定する。主にネットワークのテストやローカルアクセスに使用
macvlan: 物理IFを基に仮想NWIFを作成し、各仮想IFに独立したMACアドレスを割り当てる
ptp: Point-to-Point接続を使用してコンテナを物理ネットワークに接続(veth pair)
host-device: ホストのネットワークデバイスをコンテナに直接割り当てる。特殊なネットワーク設定が必要な場合に使用

pod例

apiVersion: v1
kind: Pod
metadata:
  name: multus-pod01
  namespace: namespace01
  annotations:
    k8s.v1.cni.cncf.io/networks: '[
    {
      "name": "macvlan-net",
      "ips": [ "172.16.0.31/24" ]
    }
    ]'
spec:
  containers:
  - name: centos-tools
    image: docker.io/centos/tools:latest
    command:
    - /sbin/init
    securityContext:
      privileged: true

2つ目のIFがついていることをかく

kubectl exec -it multus-pod01 -- ip a

coredns

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

・名前解決用のpodデプロイ 1hスリープさせてバックグラウンドで実行させることでコマンド実行
# kubectl run test-pod --image=busybox --restart=Never -- sleep 3600
# kubectl exec test-pod -- nslookup my-service.default.svc.cluster.local
サービス名だけでもOK

podの場合は
# kubectl exec test-pod -- nslookup 10-50-192-4.default.pod.cluster.local

適用されている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が一致していたとしてもSchedulingDisabledの方が優先される。

taint/toleration

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

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

ノードに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"
    value: "value"
    operator: "Equal"     #keyとvalueの両方が一致する場合に許容."Exists"=keyが存在する場合に許容。つまり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

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

# kubectl create role my-role --namespace=mynamespace --verb=get,list,watch,create,update,delete --resource=pods,services
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 をユーザー、グループ、またはサービスアカウントに関連付ける。

# kubectl create rolebinding my-rolebinding --namespace=mynamespace --role=my-role --user=my-user
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

権限確認は以下コマンドで行える
my-userによるhoge-ns上でservice作成ができるか

kubectl auth can-i create services --as=my-user -n=hoge-ns

yesかnoが返ってくる。

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

LivenessProbeとReadinessProbe

livenessProbe: コンテナの生存確認。このプローブが失敗すると、Kubernetesはコンテナを再起動する
readinessProbe: コンテナの準備確認。トラフィックの受け入れ可能かどうかを確認。このプローブが失敗すると、コンテナはServiceから取り除かれる。

設定方法

.spec.containersのセクションの下に設定する

・HTTP プローブ:特定のエンドポイントにHTTPリクエストを送信

    livenessProbe:
      httpGet:
        path: /healthz
        port: 80
      initialDelaySeconds: 10
      periodSeconds: 5
    readinessProbe:
      httpGet:
        path: /ready
        port: 80
      initialDelaySeconds: 5
      periodSeconds: 5

・TCP ソケットプローブ:特定のポートがオープンかどうかを確認

    livenessProbe:
      tcpSocket:
        port: 6379
      initialDelaySeconds: 15
      periodSeconds: 10
    readinessProbe:
      tcpSocket:
        port: 6379
      initialDelaySeconds: 10
      periodSeconds: 10

・コマンドプローブ:指定されたコマンドを実行し、終了コードを確認

    livenessProbe:
      exec:
        command:
        - cat
        - /tmp/healthy
      initialDelaySeconds: 5
      periodSeconds: 5
    readinessProbe:
      exec:
        command:
        - cat
        - /tmp/ready
      initialDelaySeconds: 5
      periodSeconds: 5

ETCDについて

Kubernetesクラスター内での設定情報や状態情報を保存するために広く使用されている、オープンソースの分散データストア

etcd-podの引数

k describe pod etcd-controlplane -n kube-system
etcd
      --advertise-client-urls=https://192.168.63.164:2379
      --cert-file=/etc/kubernetes/pki/etcd/server.crt  ★
      --client-cert-auth=true
      --data-dir=/var/lib/etcd
      --experimental-initial-corrupt-check=true
      --experimental-watch-progress-notify-interval=5s
      --initial-advertise-peer-urls=https://192.168.63.164:2380
      --initial-cluster=controlplane=https://192.168.63.164:2380
      --key-file=/etc/kubernetes/pki/etcd/server.key  ★
      --listen-client-urls=https://127.0.0.1:2379,https://192.168.63.164:2379  ★
      --listen-metrics-urls=http://127.0.0.1:2381
      --listen-peer-urls=https://192.168.63.164:2380
      --name=controlplane
      --peer-cert-file=/etc/kubernetes/pki/etcd/peer.crt
      --peer-client-cert-auth=true
      --peer-key-file=/etc/kubernetes/pki/etcd/peer.key
      --peer-trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt
      --snapshot-count=10000
      --trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt  ★

★は後述のバックアップコマンドに使用する

--advertise-client-urls=https://192.168.63.164:2379:
クライアント(他のサービスやアプリケーション)が接続するための URL をアドバタイズする。ここでは、接続先として https://192.168.63.164:2379 を指定

--cert-file=/etc/kubernetes/pki/etcd/server.crt:
etcd サーバーがクライアントに提供するサーバー証明書のファイルパスを指定。TLS/SSL 通信の際に使用される。
秘密鍵(--key-file)と共に使用される。

--client-cert-auth=true:
クライアント証明書認証を有効にするオプション。これを有効にすると、クライアントは有効な証明書を提供しなければならない。

--data-dir=/var/lib/etcd:
etcd のデータを保存するディレクトリを指定。ここでは /var/lib/etcd がデータディレクトリと設定されている。

--experimental-initial-corrupt-check=true:
etcd サーバーが起動時にデータの整合性チェックを行うオプション。

--experimental-watch-progress-notify-interval=5s:
ウォッチの進行状況更新の通知間隔を指定。ここでは 5 秒ごとに通知が行われる。

--initial-advertise-peer-urls=https://192.168.63.164:2380:
etcd クラスタ内の他のメンバーに対する広告 URL を指定。

--initial-cluster=controlplane=https://192.168.63.164:2380:
初期クラスタの構成を定義。この例では、クラスタには controlplane というメンバーが https://192.168.63.164:2380 でアドバタイズされていることを示す。

--key-file=/etc/kubernetes/pki/etcd/server.key:
etcd サーバーの秘密鍵ファイルのパス。TLS/SSL 通信に使用される。
サーバー証明書(--cert-file)とともに使用される

--listen-client-urls=https://127.0.0.1:2379,https://192.168.63.164:2379:
クライアント接続を受け付けるURLを指定。ここではローカルホストと特定のIPアドレスの両方で受け付ける。

--listen-metrics-urls=http://127.0.0.1:2381:
メトリクスのリスニングURLを指定。ここではローカルホストのポート 2381 でメトリクスのエンドポイントを提供

--listen-peer-urls=https://192.168.63.164:2380:

etcd クラスタ内の他のメンバーからの接続を受け入れるURLを指定。ここでは、特定のIPアドレスのポート 2380 でリスニングする。

--name=controlplane:
etcd インスタンスの名前を指定

--peer-cert-file=/etc/kubernetes/pki/etcd/peer.crt:
ピア間通信で使用される証明書ファイルのパスを指定。etcd メンバー間のTLS通信に使用される。

--peer-client-cert-auth=true:
ピア接続に対するクライアント証明書認証を有効。これが有効になっている場合、ピアは有効な証明書を提供する必要がある。

--peer-key-file=/etc/kubernetes/pki/etcd/peer.key:
ピア間通信で使用される秘密鍵ファイルのパス。

--peer-trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt:
ピア間通信で使用されるCA証明書のファイルパスを指定します。これにより、証明書の信頼性を検証する。

--snapshot-count=10000:
10,000回の操作ごとにスナップショットが作成される。

--trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt:
クライアント接続の際に使用されるCA証明書のファイルパス。これにより、クライアント証明書の信頼性を検証する。

バックアップコマンド

# ETCDCTL_API=3 etcdctl --endpoints=https://[127.0.0.1]:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
snapshot save /opt/snapshot-pre-boot.db

確認

# ETCDCTL_API=3 etcdctl --write-out=table snapshot status snapshot.db

リストア

# ETCDCTL_API=3 etcdctl --data-dir /var/lib/etcd-from-backup \
snapshot restore /opt/snapshot-pre-boot.db

2024-11-27 14:58:40.873462 I | mvcc: restore compact to 1712
2024-11-27 14:58:40.876912 I | etcdserver/membership: added member 8e9e05c52164694d [http://localhost:2380] to cluster cdf818194e3a8c32

/etc/kubernetes/manifests/etcd.yaml
を更新する必要がある

etcd スナップショットがコントロールプレーンの新しいパス (/var/lib/etcd-from-backup) に復元されたので、etcd-data ボリュームの hostPath を古いディレクトリ (/var/lib/etcd) から新しいディレクトリ (/var/lib/etcd-from-backup) に変更する。

/etc/kubernetes/manifests/etcd.yaml
volumes:
  - hostPath:
      path: /etc/kubernetes/pki/etcd
      type: DirectoryOrCreate
    name: etcd-certs
  - hostPath:
      path: /var/lib/etcd-from-backup     #ここを/var/lib/etcdから変更
      type: DirectoryOrCreate
    name: etcd-data

この変更により、コンテナ上の /var/lib/etcd はコントロールプレーン上の /var/lib/etcd-from-backup を指すようになる。
staticpodのため、ファイルが更新されると自動的に再作成される。

※元の場所と同じ場所にリストアする場合、上記手順は必要ないがetcdを一度止めてディレクトリも移す必要がある

# systemctl stop etcd
# mv /var/lib/etcd /var/lib/etcd_backup
# ETCDCTL_API=3 etcdctl --data-dir /var/lib/etcd snapshot restore /opt/snapshot-pre-boot.db
# systemctl start etcd

おまけ

忘れがちなやつリスト

・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 nodes -o jsonpath='{.items[*].status.addresses[?(@.type=="InternalIP")].address}'
192.168.1.1 192.168.1.2
→
[?(@.type=="InternalIP")]でフィルタリングしている。@は現在のオブジェクトを指す


・出力を抜き出して任意のカラムを追加して表示.名前でソート
# 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の制御下で起動、起動失敗した時に所定の回数に達するまでポッドの起動を再試行

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