これは、このセクションの複数ページの印刷可能なビューです。 印刷するには、ここをクリックしてください.

このページの通常のビューに戻る.

クラスターデーモンの管理

ローリングアップデートの実行など、DaemonSetを管理するための一般的なタスクを実行します。

1 - 基本的なDaemonSetを構築する

このページでは、Kubernetesクラスターの全てのノード上でPodを実行する、基本的なDaemonSetを構築する方法について示します。 ホストからファイルをマウントし、Initコンテナを使用してその内容をログに記録して、pauseコンテナを利用するという単純なユースケースを取り上げます。

始める前に

Kubernetesクラスターが必要、かつそのクラスターと通信するためにkubectlコマンドラインツールが設定されている必要があります。 このチュートリアルは、コントロールプレーンのホストとして動作していない少なくとも2つのノードを持つクラスターで実行することをおすすめします。 まだクラスターがない場合、minikubeを使って作成するか、 以下のいずれかのKubernetesプレイグラウンドも使用できます:

DaemonSetの動作を示すために、少なくとも2つのノード(1つのコントロールプレーンと1つのワーカーノード)を持つKubernetesクラスターを用意します。

DaemonSetの定義

このタスクでは、Podのコピーが全てのノード上でスケジュールされるようにする、基本的なDaemonSetが作成されます。 PodはInitコンテナを使用してホストから/etc/machine-idの内容を読み込んでログに記録し、メインのコンテナはPodを実行し続けるpauseコンテナとなります。

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: example-daemonset
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: example
  template:
    metadata:
      labels:
        app.kubernetes.io/name: example
    spec:
      containers:
      - name: pause
        image: registry.k8s.io/pause
      initContainers:
      - name: log-machine-id
        image: busybox:1.37
        command: ['sh', '-c', 'cat /etc/machine-id > /var/log/machine-id.log']
        volumeMounts:
        - name: machine-id
          mountPath: /etc/machine-id
          readOnly: true
        - name: log-dir
          mountPath: /var/log
      volumes:
      - name: machine-id
        hostPath:
          path: /etc/machine-id
          type: File
      - name: log-dir
        hostPath:
          path: /var/log
  1. (YAML)マニフェストに基づいたDaemonSetを作成します:

    kubectl apply -f https://k8s.io/examples/application/basic-daemonset.yaml
    
  2. 適用すると、DaemonSetがクラスター内の全てのノードでPodを実行していることを確認できます:

    kubectl get pods -o wide
    

    出力には、以下のようにノード毎に1つのPodが一覧表示されます:

    NAME                                READY   STATUS    RESTARTS   AGE    IP       NODE
    example-daemonset-xxxxx             1/1     Running   0          5m     x.x.x.x  node-1
    example-daemonset-yyyyy             1/1     Running   0          5m     x.x.x.x  node-2
    
  3. ホストからマウントされたログディレクトリをチェックすることで、ログに記録された/etc/machine-idファイルの内容を調べることができます:

    kubectl exec <pod-name> -- cat /var/log/machine-id.log
    

    <pod-name>は1つのPodの名前です。

クリーンアップ

DaemonSetを削除するためには、次のコマンドを実行します:

kubectl delete --cascade=foreground --ignore-not-found --now daemonsets/example-daemonset

この単純なDaemonSetの例では、Initコンテナやホストパスボリュームなどの主要なコンポーネントを紹介しており、より高度なユースケースに応じて拡張することができます。 詳細についてはDaemonSetを参照してください。

次の項目

2 - DaemonSet上でローリングアップデートを実施する

このページでは、DaemonSet上でローリングアップデートを行う方法について説明します。

始める前に

Kubernetesクラスターが必要、かつそのクラスターと通信するためにkubectlコマンドラインツールが設定されている必要があります。 このチュートリアルは、コントロールプレーンのホストとして動作していない少なくとも2つのノードを持つクラスターで実行することをおすすめします。 まだクラスターがない場合、minikubeを使って作成するか、 以下のいずれかのKubernetesプレイグラウンドも使用できます:

DaemonSetのアップデート戦略

DaemonSetには2種類のアップデート戦略があります:

  • OnDelete: OnDeleteアップデート戦略では、DaemonSetのテンプレートを更新した後、古いDaemonSetのPodを手動で削除した時のみ、新しいDaemonSetのPodが作成されます。 これはKubernetesのバージョン1.5またはそれ以前のDaemonSetと同じ挙動です。
  • RollingUpdate: これは既定のアップデート戦略です。 RollingUpdateアップデート戦略では、DaemonSetのテンプレートを更新した後、古いDaemonSetのPodが削除され、制御された方法で自動的に新しいDaemonSetのPodが作成されます。 アップデートのプロセス全体を通して、各ノード上で稼働するDaemonSetのPodは最大で1つだけです。

ローリングアップデートの実施

DaemonSetに対してローリングアップデートの機能を有効にするには、.spec.updateStrategy.typeRollingUpdateに設定する必要があります。

.spec.updateStrategy.rollingUpdate.maxUnavailable(既定値は1)、.spec.minReadySeconds(既定値は0)、そして.spec.updateStrategy.rollingUpdate.maxSurge(既定値は0)についても設定したほうがよいでしょう。

RollingUpdateアップデート戦略によるDaemonSetの作成

このYAMLファイルでは、アップデート戦略としてRollingUpdateが指定されたDaemonSetを定義しています。

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd-elasticsearch
  namespace: kube-system
  labels:
    k8s-app: fluentd-logging
spec:
  selector:
    matchLabels:
      name: fluentd-elasticsearch
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
  template:
    metadata:
      labels:
        name: fluentd-elasticsearch
    spec:
      tolerations:
      # これらのTolerationはコントロールプレーンノード上でDaemonSetを実行できるようにするためのものです
      # コントロールプレーンノードでPodを実行すべきではない場合は、これらを削除してください
      - key: node-role.kubernetes.io/control-plane
        operator: Exists
        effect: NoSchedule
      - key: node-role.kubernetes.io/master
        operator: Exists
        effect: NoSchedule
      containers:
      - name: fluentd-elasticsearch
        image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
        volumeMounts:
        - name: varlog
          mountPath: /var/log
        - name: varlibdockercontainers
          mountPath: /var/lib/docker/containers
          readOnly: true
      terminationGracePeriodSeconds: 30
      volumes:
      - name: varlog
        hostPath:
          path: /var/log
      - name: varlibdockercontainers
        hostPath:
          path: /var/lib/docker/containers

DaemonSetのマニフェストのアップデート戦略を検証した後、DaemonSetを作成します:

kubectl create -f https://k8s.io/examples/controllers/fluentd-daemonset.yaml

あるいは、kubectl applyを使用してDaemonSetを更新する予定がある場合は、kubectl applyを使用して同じDaemonSetを作成してください。

kubectl apply -f https://k8s.io/examples/controllers/fluentd-daemonset.yaml

DaemonSetのRollingUpdateアップデート戦略の確認

DaemonSetのアップデート戦略を確認し、RollingUpdateが設定されているようにします:

kubectl get ds/fluentd-elasticsearch -o go-template='{{.spec.updateStrategy.type}}{{"\n"}}' -n kube-system

システムにDaemonSetが作成されていない場合は、代わりに次のコマンドによってDaemonSetのマニフェストを確認します:

kubectl apply -f https://k8s.io/examples/controllers/fluentd-daemonset.yaml --dry-run=client -o go-template='{{.spec.updateStrategy.type}}{{"\n"}}'

どちらのコマンドも、出力は次のようになります:

RollingUpdate

出力がRollingUpdate以外の場合は、DaemonSetオブジェクトまたはマニフェストを見直して、修正してください。

DaemonSetテンプレートの更新

RollingUpdateのDaemonSetの.spec.templateに対して任意の更新が行われると、ローリングアップデートがトリガーされます。 新しいYAMLファイルを適用してDaemonSetを更新しましょう。 これにはいくつかの異なるkubectlコマンドを使用することができます。

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd-elasticsearch
  namespace: kube-system
  labels:
    k8s-app: fluentd-logging
spec:
  selector:
    matchLabels:
      name: fluentd-elasticsearch
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
  template:
    metadata:
      labels:
        name: fluentd-elasticsearch
    spec:
      tolerations:
      # これらのTolerationはコントロールプレーンノード上でDaemonSetを実行できるようにするためのものです
      # コントロールプレーンノードでPodを実行すべきではない場合は、これらを削除してください
      - key: node-role.kubernetes.io/control-plane
        operator: Exists
        effect: NoSchedule
      - key: node-role.kubernetes.io/master
        operator: Exists
        effect: NoSchedule
      containers:
      - name: fluentd-elasticsearch
        image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
        resources:
          limits:
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 200Mi
        volumeMounts:
        - name: varlog
          mountPath: /var/log
        - name: varlibdockercontainers
          mountPath: /var/lib/docker/containers
          readOnly: true
      terminationGracePeriodSeconds: 30
      volumes:
      - name: varlog
        hostPath:
          path: /var/log
      - name: varlibdockercontainers
        hostPath:
          path: /var/lib/docker/containers

宣言型コマンド

設定ファイルを使用してDaemonSetを更新する場合は、kubectl applyを使用します:

kubectl apply -f https://k8s.io/examples/controllers/fluentd-daemonset-update.yaml

命令型コマンド

命令型コマンドを使用してDaemonSetを更新する場合は、kubectl editを使用します:

kubectl edit ds/fluentd-elasticsearch -n kube-system
コンテナイメージのみのアップデート

DaemonSetのテンプレート内のコンテナイメージ、つまり.spec.template.spec.containers[*].imageのみを更新したい場合、kubectl set imageを使用します:

kubectl set image ds/fluentd-elasticsearch fluentd-elasticsearch=quay.io/fluentd_elasticsearch/fluentd:v2.6.0 -n kube-system

ローリングアップデートのステータスの監視

最後に、最新のDaemonSetの、ローリングアップデートのロールアウトステータスを監視します:

kubectl rollout status ds/fluentd-elasticsearch -n kube-system

ロールアウトが完了すると、次のような出力となります:

daemonset "fluentd-elasticsearch" successfully rolled out

トラブルシューティング

DaemonSetのローリングアップデートがスタックする

時々、DaemonSetのローリングアップデートがスタックする場合があります。 これにはいくつかの原因が考えられます:

いくつかのノードのリソース不足

1つ以上のノードで新しいDaemonSetのPodをスケジュールすることができず、ロールアウトがスタックしています。 これはノードのリソース不足の可能性があります。

この事象が起きた場合は、kubectl get nodesの出力と次の出力を比較して、DaemonSetのPodがスケジュールされていないノードを見つけます:

kubectl get pods -l name=fluentd-elasticsearch -o wide -n kube-system

そのようなノードを見つけたら、新しいDaemonSetのPodのための空きを作るために、ノードからDaemonSet以外のいくつかのPodを削除します。

壊れたロールアウト

例えばコンテナがクラッシュを繰り返したり、(しばしばtypoによって)コンテナイメージが存在しないといった理由で最新のDaemonSetのテンプレートの更新が壊れた場合、DaemonSetのロールアウトは進みません。

これを修正するためには、DaemonSetのテンプレートを再度更新します。 新しいロールアウトは、前の不健全なロールアウトによってブロックされません。

クロックスキュー

DaemonSet内で.spec.minReadySecondsが指定されると、マスターとノードの間のクロックスキューによって、DaemonSetがロールアウトの進捗を正しく認識できなくなる場合があります。

クリーンアップ

NamespaceからDaemonSetを削除します:

kubectl delete ds fluentd-elasticsearch -n kube-system

次の項目