これは、このセクションの複数ページの印刷可能なビューです。 印刷するには、ここをクリックしてください.
クラスターデーモンの管理
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
-
(YAML)マニフェストに基づいたDaemonSetを作成します:
kubectl apply -f https://k8s.io/examples/application/basic-daemonset.yaml
-
適用すると、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
-
ホストからマウントされたログディレクトリをチェックすることで、ログに記録された
/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.type
をRollingUpdate
に設定する必要があります。
.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を削除します。
備考:
コントローラーによって制御されていないPodや、レプリケートされていないPodを削除すると、これはサービスの中断が発生する原因となります。 これはまた、PodDisruptionBudgetについても考慮しません。壊れたロールアウト
例えばコンテナがクラッシュを繰り返したり、(しばしばtypoによって)コンテナイメージが存在しないといった理由で最新のDaemonSetのテンプレートの更新が壊れた場合、DaemonSetのロールアウトは進みません。
これを修正するためには、DaemonSetのテンプレートを再度更新します。 新しいロールアウトは、前の不健全なロールアウトによってブロックされません。
クロックスキュー
DaemonSet内で.spec.minReadySeconds
が指定されると、マスターとノードの間のクロックスキューによって、DaemonSetがロールアウトの進捗を正しく認識できなくなる場合があります。
クリーンアップ
NamespaceからDaemonSetを削除します:
kubectl delete ds fluentd-elasticsearch -n kube-system