4
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でInstana監視からmasterノードを除外してライセンスコストを最適化した話

4
Last updated at Posted at 2026-02-04

はじめに

Kubernetes クラスタを IBM Instana で監視していたところ、master(control-plane)ノードも Host としてカウントされ、ライセンス使用量が想定より多くなっていることが判明しました。

本記事では、masterノードを監視対象から除外し、ライセンス使用量を最適化した実装方法とエビデンスを共有します。


TL;DR

Instana AgentのDaemonSetにnodeAffinityを追加し、control-plane/masterラベルを持つノードを除外することでライセンスコストを削減します。

  • 対象: masterノードにNoSchedule taintが設定されていない環境
  • 方法: nodeAffinityでnode-role.kubernetes.io/control-planeおよびnode-role.kubernetes.io/masterラベルが存在しないノードのみに配置
  • 効果: masterノード分のHost Unitを削減、workerノードの監視は継続

⚠️ 重要: この記事の対象環境

この記事は 「masterノードにtaintが設定されていない環境」 を対象としています。

環境による違い

環境 masterのtaint設定 対応要否 備考
OpenShift デフォルトでNoSchedule 対応不要 自動的にmaster除外済み
kubeadm(標準) デフォルトでNoSchedule 対応不要 自動的にmaster除外済み
RKE2(標準構成) デフォルトでNoSchedule 対応不要 v1.21以降は自動設定
Rancher管理の検証環境 taintなし(schedulable) 対応必要 本記事の対象
カスタム構成 環境依存 要確認 taint削除している場合

今回の検証環境

  • Kubernetes: RKE2 v1.34.3
  • 管理: Rancher経由で構築
  • 構成: masterノード3台 + workerノード6台
  • masterのtaint: <none> (schedulable状態)
  • 問題: masterノードにもInstana AgentのDaemonSetが配置される

みなさんの環境で対応が必要か判断する

Step 1: masterノードのtaintを確認

kubectl describe node <master-node> | grep Taints

結果の見方:

# パターン1: taintあり(対応不要)
Taints: node-role.kubernetes.io/master:NoSchedule
Taints: node-role.kubernetes.io/control-plane:NoSchedule

# パターン2: taintなし(本記事の対応が必要)
Taints: <none>

Step 2: masterノードでのInstana Agent配置を確認

kubectl -n instana-agent get pod -o wide | grep master

結果の見方:

# 対応必要: DaemonSetのPodが存在
instana-agent-xxxxx    1/1  Running  0  10d  master01  <none>  <none>
instana-agent-yyyyy    1/1  Running  0  10d  master02  <none>  <none>

# 対応不要: k8sensorのみ(Deploymentなので問題なし)
instana-agent-k8sensor-abc123  1/1  Running  0  10d  master01  <none>  <none>

注: k8sensorはDeploymentなので、レプリカ数に応じて配置されます(DaemonSetのように全ノードには配置されません)。

Step 3: 判断

  • taintが<none> かつ masterにinstana-agent-xxxxx(DaemonSet)が存在 → 本記事の手順が必要
  • taintが設定済み または masterにDaemonSetのPodがない → 対応不要

背景と課題

Instanaのライセンス体系

Instana Observabilityは Host単位 でライセンスが課金されます:

  • 1 Host Unit = 1ノードの監視
  • DaemonSetで配置されたInstana Agentが稼働するノード数がカウント対象
  • masterノードも監視対象になると、その分のライセンスコストが発生

参考: IBM Instana Pricing

課題

一般的なKubernetes環境(OpenShift、kubeadm、RKE2標準構成など)では、masterノードにデフォルトでNoSchedule taintが設定されているため、DaemonSetは自動的にmasterを除外します。

しかし、taintが設定されていない環境(Rancher管理の検証環境、シングルノードクラスタ、taint削除環境など)では、Instana AgentのDaemonSetがmasterノードにも配置され、Host Unit消費が増加します。

実際のアプリケーションはworkerノードで動作しており、masterのOS-レベル監視は優先度が低いため、このような環境ではnodeAffinityでmasterノードを明示的に除外する必要があります。


⚠️ 重要: control-plane監視は継続されます

本記事で除外するのは「masterノードのOS-レベル監視(DaemonSet)」です。
Kubernetes API経由のcontrol-plane監視(k8sensor経由)は継続されます。

control-plane監視の詳細については、以下の記事をご参照ください:
Instanaでk8sコントロールプレーンを監視してみた


Instana AgentのコンポーネントとDaemonSet/Deploymentの違い

Instana Agentは主に2つのコンポーネントで構成されます:

コンポーネント 種類 配置単位 役割 ライセンス影響
instana-agent DaemonSet 各ノードに1つ ノード(Host)のOS・インフラ監視 Host Unit消費
k8sensor Deployment クラスタに1つ以上 Kubernetes API監視 Host Unit消費なし

重要な違い

DaemonSet(instana-agent)の動作

# DaemonSetは各ノードに1つずつ配置される
NAME                  NODE       
instana-agent-xxxxx   master01   # ← 本記事で除外する対象
instana-agent-yyyyy   master02   # ← 本記事で除外する対象
instana-agent-zzzzz   master03   # ← 本記事で除外する対象
instana-agent-aaaaa   worker01
instana-agent-bbbbb   worker02

Deployment(k8sensor)の動作

# Deploymentはレプリカ数に応じて配置(通常1つ、HA構成では複数)
NAME                              NODE
instana-agent-k8sensor-abc123     master01   # レプリカ数=1の場合
# または
instana-agent-k8sensor-abc123     master01   # レプリカ数=3の場合
instana-agent-k8sensor-def456     master02
instana-agent-k8sensor-ghi789     worker01

ポイント: k8sensorはDeploymentなので、配置ノードはレプリカ数やスケジューリング条件により異なります。masterノードに配置されていても、Host Unitは消費しません。


解決方針

DaemonSetのnodeAffinityを使用して、masterノードを監視対象から除外します。

採用する手法

affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: node-role.kubernetes.io/control-plane
          operator: DoesNotExist
        - key: node-role.kubernetes.io/master
          operator: DoesNotExist

なぜ2つのラベルを指定するのか

Kubernetesのバージョン互換性のため:

Kubernetesバージョン masterのラベル
v1.20以降 node-role.kubernetes.io/control-plane
v1.19以前 node-role.kubernetes.io/master

両方を指定することで、バージョン依存の問題を回避できます。

参考: Kubernetes Node Affinity


実装手順

事前準備: バックアップの取得

# 現在のDaemonSet設定をバックアップ
kubectl -n instana-agent get ds instana-agent -o yaml > backup_instana_ds.yaml

# 変更前のPod配置を記録
kubectl -n instana-agent get pod -o wide > before_pods.txt

手順1: DaemonSet設定の取得と編集

# 現在の設定を取得
kubectl -n instana-agent get ds instana-agent -o yaml > modified_ds.yaml

modified_ds.yamlを編集し、spec.template.specに以下を追加:

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: instana-agent
  namespace: instana-agent
spec:
  template:
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: node-role.kubernetes.io/control-plane
                operator: DoesNotExist
              - key: node-role.kubernetes.io/master
                operator: DoesNotExist
      # 以下、既存の設定が続く
      containers:
      - name: instana-agent
        # ...

手順2: 変更の適用

# DaemonSetを更新
kubectl apply -f modified_ds.yaml

# ロールアウトの確認
kubectl rollout status daemonset/instana-agent -n instana-agent

手順3: 変更後の確認

# masterノードでのPod配置を確認
kubectl -n instana-agent get pod -o wide | grep master

# DaemonSetの配置状況を確認
kubectl -n instana-agent get ds instana-agent

# 全ノードでのPod配置を確認
kubectl -n instana-agent get pod -o wide

期待される結果:

# 変更前: masterノードにDaemonSetのPodが存在
instana-agent-xxxxx              1/1  Running  0  10d  master01  <none>  <none>
instana-agent-yyyyy              1/1  Running  0  10d  master02  <none>  <none>
instana-agent-zzzzz              1/1  Running  0  10d  master03  <none>  <none>
instana-agent-k8sensor-abc123    1/1  Running  0  10d  master01  <none>  <none>

# 変更後: masterノードからDaemonSetのPodが削除
# k8sensorはDeploymentなので影響なし(配置ノードは環境依存)
instana-agent-k8sensor-abc123    1/1  Running  0  10d  master01  <none>  <none>

# workerノードには引き続きDaemonSetが配置
instana-agent-aaaaa              1/1  Running  0  1m  worker01  <none>  <none>
instana-agent-bbbbb              1/1  Running  0  1m  worker02  <none>  <none>

重要: k8sensorの配置ノードは環境により異なります。masterノードに配置されていても、それはDeploymentの通常の動作であり、Host Unitを消費しません。


変更前後の比較

アーキテクチャの変更

注: k8sensorの配置ノードはレプリカ数やスケジューリング条件により異なります。上図はレプリカ数=1でmaster01に配置された例です。

監視対象の変化

対象 変更前 変更後 影響
masterノードのOS監視 監視中(DaemonSet) 除外 Host Unit削減
workerノードのOS監視 監視中(DaemonSet) 監視継続 変更なし
Kubernetes API監視 k8sensor(Deployment) k8sensor継続 変更なし
アプリケーション監視 監視中 監視継続 変更なし

変更による効果

本手法により、以下の効果が得られます:

監視対象の変化

  • 対象: master(control-plane)ノードのHost監視を除外
  • 削減: 環境により異なりますが、本検証環境では約27%のHost Unit削減
  • 継続監視: workerノードは引き続き監視対象

具体例(参考値)

クラスタ構成が「master 3台 + worker N台」の場合:

項目 変更前 変更後
master監視(DaemonSet) 3 Hosts 0 Hosts
worker監視(DaemonSet) N Hosts N Hosts
k8sensor(Deployment) Host Unit消費なし Host Unit消費なし
効果 - master 3台分のHost Unit削減

監視への影響

  • 継続: workerノードのOS/アプリケーション監視
  • 継続: Kubernetes API監視(k8sensor経由)
  • 除外: masterノードのOS-レベル監視

注: 実際の効果は、クラスタ構成・ライセンス契約により異なります。


トラブルシューティング

Q1: nodeAffinity追加後もmasterにDaemonSetのPodが残る

原因:

  • DaemonSetの更新戦略がOnDeleteの場合、手動でPodを削除する必要がある

確認方法:

kubectl -n instana-agent get ds instana-agent -o yaml | grep updateStrategy -A 3

対処方法:

# 更新戦略がOnDeleteの場合、手動でPodを削除
kubectl -n instana-agent delete pod <pod-name>

# または、masterノード上の全instana-agent DaemonSet Podを削除
kubectl -n instana-agent get pod -o wide | grep "instana-agent-" | grep master | grep -v k8sensor | awk '{print $1}' | xargs kubectl -n instana-agent delete pod

注意: k8sensorはDeploymentなので削除対象外です。上記コマンドはgrep -v k8sensorで除外しています。

Q2: workerノードでもPodが起動しない

原因:

  • ノードラベルの誤付与
  • nodeAffinityの条件設定ミス

確認方法:

# ノードラベルを確認
kubectl get nodes --show-labels

# 特定ノードの詳細を確認
kubectl describe node <worker-node> | grep Labels -A 10

対処方法:

# 誤ってラベルを付与している場合は削除
kubectl label node <worker-node> node-role.kubernetes.io/control-plane-
kubectl label node <worker-node> node-role.kubernetes.io/master-

Q3: k8sensorまで削除されてしまう

原因:

  • 誤ってk8sensor用のDeploymentにもnodeAffinityを適用した可能性

確認方法:

kubectl -n instana-agent get deployment instana-agent-k8sensor -o yaml | grep affinity -A 20

対処方法:

k8sensorのDeploymentは別管理です。DaemonSetの変更のみを適用してください。

# DaemonSetのみを対象にしていることを確認
kubectl -n instana-agent get ds instana-agent -o yaml | grep kind
# 出力: kind: DaemonSet

# 誤ってDeploymentを変更した場合はロールバック
kubectl -n instana-agent rollout undo deployment instana-agent-k8sensor

Q4: masterノードにk8sensorが配置されているがHost Unitを消費するか心配

回答:

k8sensorはDeploymentで管理され、Kubernetes APIの監視のみを行います。Host Unitは消費しません。

根拠:

  • Instana Agentの公式ドキュメントでは、DaemonSetとして配置されるagentがHost Unit消費対象
  • k8sensorはクラスタ全体の情報収集を担当し、ノード単位の監視は行わない
  • 実務上、masterにk8sensorが配置されても請求に影響しない

参考: IBM Instana: Monitoring Kubernetes

Q5: ロールアウトが完了しない

原因:

  • リソース不足
  • イメージのpullエラー
  • ノードの状態異常

確認方法:

# Pod状態の詳細確認
kubectl -n instana-agent get pods -o wide

# 特定Podの詳細確認
kubectl -n instana-agent describe pod <pod-name>

# イベントログの確認
kubectl get events -n instana-agent --sort-by='.lastTimestamp'

対処方法:

# リソース不足の場合: 不要なPodを削除
kubectl -n instana-agent delete pod <pending-pod>

# イメージpullエラーの場合: ネットワーク/認証を確認
kubectl -n instana-agent get pod <pod-name> -o jsonpath='{.status.containerStatuses[0].state}'

ロールバック手順

変更に問題がある場合、以下の手順でロールバックできます:

# バックアップから復元
kubectl apply -f backup_instana_ds.yaml

# ロールアウトの完了を待機
kubectl rollout status daemonset/instana-agent -n instana-agent

# 復元後の確認
kubectl -n instana-agent get pod -o wide

応用例: 他のノード除外シナリオ

本手法は、master除外以外にも応用できます。

応用パターン一覧

ユースケース 除外対象 適用方法
GPU搭載ノード除外 GPU専用ノード node.kubernetes.io/instance-type NotIn [g4dn.xlarge]
開発環境除外 dev環境ノード environment NotIn [development]
特定ゾーン除外 DR用ゾーン topology.kubernetes.io/zone NotIn [us-west-2c]
メンテナンス中除外 一時的除外 maintenance DoesNotExist

応用例1: GPU搭載ノードを監視対象外にする

背景: GPUノードは高コストで監視優先度が低い

affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: node.kubernetes.io/instance-type
          operator: NotIn
          values:
          - g4dn.xlarge
          - p3.2xlarge

適用手順:

# GPUノードのインスタンスタイプを確認
kubectl get nodes -o custom-columns=NAME:.metadata.name,INSTANCE:.metadata.labels.node\\.kubernetes\\.io/instance-type

# 上記のYAMLを適用
kubectl apply -f modified_ds.yaml

応用例2: 開発環境ノードを監視対象外にする

背景: 開発環境は頻繁に再構築されるため監視不要

事前準備: ノードにラベルを付与

# 開発環境ノードにラベルを付与
kubectl label node dev-node01 environment=development
kubectl label node dev-node02 environment=development

DaemonSet設定:

affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: environment
          operator: NotIn
          values:
          - development

応用例3: 特定ゾーンを監視対象外にする

背景: DRゾーンは通常待機状態で監視優先度が低い

affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: topology.kubernetes.io/zone
          operator: NotIn
          values:
          - us-west-2c  # DRゾーン

応用例4: 複数条件の組み合わせ

背景: masterとGPUノードの両方を除外

affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: node-role.kubernetes.io/control-plane
          operator: DoesNotExist
        - key: node-role.kubernetes.io/master
          operator: DoesNotExist
        - key: node.kubernetes.io/instance-type
          operator: NotIn
          values:
          - g4dn.xlarge

まとめ

学んだこと

  1. DaemonSetはデフォルトで全ノード対象: taintがない環境ではmasterノードにも配置される
  2. nodeAffinityで制御可能: DoesNotExist演算子で特定ラベルを持つノードを除外できる
  3. バージョン互換性の考慮: control-planeとmasterの両ラベルを指定することで互換性を確保
  4. DaemonSetとDeploymentの違い: DaemonSetは各ノードに配置、Deploymentはレプリカ数に応じて配置
  5. k8sensorは別管理: DeploymentなのでDaemonSetの変更の影響を受けない
  6. エビデンスの重要性: 変更前後の差分とPod配置を記録することでトラブル時の原因究明が容易

実務での活用

  • コスト最適化: ライセンス上限に近い環境で余裕を確保
  • 柔軟な監視制御: 環境・用途に応じた監視対象の選択が可能

参考資料


本記事が同じような課題に直面している方の参考になれば幸いです。

4
0
4

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