KubectlコマンドによるKubernetes管理のDevOps実践

Linux・CLI・DevOpsカテゴリを表すパンダのイラスト Linux・CLI・DevOps

KubectlコマンドによるKubernetes管理のDevOps実践

要件と前提

DevOpsにおいてKubernetesの管理は、単なる手動操作ではなく、自動化され、再現性があり、安全なプロセスとして構築されるべきです。本稿では、kubectl コマンドを核に、jq、curl といったツールを組み合わせ、systemd を用いた自動化の例を提示します。

前提条件:

  • Kubernetesクラスターが利用可能であること (Minikube, Kind, GKE, EKS, AKSなど)。

  • クライアント環境に kubectl, jq, curl がインストールされていること。

  • systemd を利用可能なLinux環境であること。

  • sudo 権限を持つユーザー、または systemd サービスを管理できる権限。

  • root権限の扱いと権限分離の原則:

    • Kubernetesへのアクセスは、最小権限の原則に基づき、必要な権限のみを持つService Accountやユーザーを使用すべきです。

    • kubectl コマンドを実行するスクリプト自体は、可能な限り非rootユーザーで実行されるべきです。

    • systemd サービスとして実行する場合も、専用の非rootユーザーとグループを設定し、ProtectSystem=true や PrivateTmp=true などを用いてセキュリティを強化します。

    • KUBECONFIG 環境変数や -kubeconfig オプションを使って、個別のクレデンシャルファイルを指定することで、権限分離をさらに徹底できます。

実装

DevOpsの自動化スクリプトは、冪等性(idempotent)を保ち、エラーハンドリングを適切に行うことが不可欠です。

1. 安全なBashスクリプトのフレームワーク

#!/usr/bin/env bash


# Strict mode: Exit immediately if a command exits with a non-zero status.


# Exit immediately if a pipeline command fails.


# Treat unset variables as an error when substituting.

set -euo pipefail

# Function to clean up temporary directory upon script exit or error

_cleanup() {
    if [ -n "${TMP_DIR:-}" ] && [ -d "${TMP_DIR}" ]; then
        echo "INFO: Cleaning up temporary directory: ${TMP_DIR}" >&2
        rm -rf "${TMP_DIR}"
    fi
}

# Register the cleanup function to be executed on EXIT (normal exit) or ERR (error exit)

trap '_cleanup' EXIT ERR

# Create a unique temporary directory

TMP_DIR=$(mktemp -d)
echo "INFO: Using temporary directory: ${TMP_DIR}" >&2

# --- ここに実際の処理を記述 ---


# 例: Kubernetesマニフェストファイルを一時ディレクトリに作成し適用

MANIFEST_FILE="${TMP_DIR}/nginx-deployment.yaml"

cat <<EOF > "${MANIFEST_FILE}"
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-example
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:

      - name: nginx
        image: nginx:1.14.2
        ports:

        - containerPort: 80
EOF

echo "INFO: Applying Kubernetes manifest: ${MANIFEST_FILE}" >&2
kubectl apply -f "${MANIFEST_FILE}"

echo "INFO: Waiting for deployment 'nginx-example' to be ready..." >&2
kubectl rollout status deployment/nginx-example --timeout=300s

echo "SUCCESS: Deployment 'nginx-example' is ready." >&2

# --- 処理終わり ---

2. jq を用いたKubernetesリソースのJSON処理

kubectl get -o json で取得したJSON出力を jq でパースし、必要な情報を抽出します。

#!/usr/bin/env bash

set -euo pipefail

# ... (trap, TMP_DIR の設定は上記と同様に含める) ...

NAMESPACE="default"
DEPLOYMENT_NAME="nginx-example" # 前のステップで作成したデプロイメント

echo "INFO: Fetching pod information for deployment '${DEPLOYMENT_NAME}' in namespace '${NAMESPACE}'..." >&2

# 1. Running状態のPod名とIPアドレスを抽出

kubectl get pods -n "${NAMESPACE}" -l app=nginx -o json | \
    jq -r '.items[] | select(.status.phase == "Running") | "\(.metadata.name) (\(.status.podIP))"' || {
        echo "ERROR: Failed to retrieve or parse pod information." >&2
        exit 1
    }

echo "INFO: Fetching container images for deployment '${DEPLOYMENT_NAME}'..." >&2

# 2. デプロイメントが使用しているコンテナイメージ名を抽出

kubectl get deployment "${DEPLOYMENT_NAME}" -n "${NAMESPACE}" -o json | \
    jq -r '.spec.template.spec.containers[].image' || {
        echo "ERROR: Failed to retrieve or parse deployment container images." >&2
        exit 1
    }

echo "SUCCESS: Successfully extracted Kubernetes resource information." >&2

3. curl を用いたAPI連携(TLS/再試行/バックオフ)

kubectl proxy を利用してローカルプロキシを立て、Kubernetes APIに curl でアクセスする例です。本番環境では、適切な認証情報(Service Accountトークンなど)とTLS証明書検証が必要です。

#!/usr/bin/env bash

set -euo pipefail

# ... (trap, TMP_DIR の設定は上記と同様に含める) ...

# Ensure kubectl proxy is running in a background process


# In a real scenario, you'd use a secure KUBECONFIG with appropriate RBAC.


# For demonstration, we'll start a proxy and clean it up.

echo "INFO: Starting kubectl proxy in background..." >&2
kubectl proxy --port=8001 > /dev/null 2>&1 &
PROXY_PID=$!

# Ensure proxy is killed on script exit

trap "kill ${PROXY_PID} || true; _cleanup" EXIT ERR

# Wait for proxy to be ready

echo "INFO: Waiting for kubectl proxy to be ready..." >&2
sleep 3 # Give it a few seconds to start

API_SERVER="http://localhost:8001"
NAMESPACE="default"
MAX_RETRIES=5
INITIAL_RETRY_INTERVAL=2 # seconds

_get_pods_via_api_with_retry() {
    local url="${API_SERVER}/api/v1/namespaces/${NAMESPACE}/pods"
    local attempt=0
    local current_retry_interval="${INITIAL_RETRY_INTERVAL}"

    while true; do
        echo "INFO: Attempt $((attempt + 1)): Fetching pods from ${url}..." >&2

        # --fail: HTTPステータスコードが400以上の場合に失敗


        # --insecure: TLS証明書の検証をスキップ (開発/テスト用, 本番では非推奨)


        # --max-time: 最大実行時間

        response=$(curl --silent --show-error --fail --insecure --max-time 10 "${url}")

        if [ $? -eq 0 ]; then
            echo "${response}"
            return 0
        else
            echo "WARNING: Curl failed on attempt $((attempt + 1)). Error: $response" >&2
        fi

        attempt=$((attempt + 1))
        if [ "${attempt}" -ge "${MAX_RETRIES}" ]; then
            echo "ERROR: Failed to fetch pods after ${MAX_RETRIES} attempts." >&2
            return 1
        fi

        echo "INFO: Retrying in ${current_retry_interval} seconds (exponential backoff)..." >&2
        sleep "${current_retry_interval}"
        current_retry_interval=$((current_retry_interval * 2)) # Exponential backoff
        if [ "${current_retry_interval}" -gt 30 ]; then # Cap max retry interval
            current_retry_interval=30
        fi
    done
}

echo "INFO: Calling Kubernetes API via curl..." >&2
_get_pods_via_api_with_retry | jq -r '.items[].metadata.name' || {
    echo "ERROR: Failed to get or parse pods via API." >&2
    exit 1
}

echo "SUCCESS: Successfully fetched pods via Kubernetes API." >&2

検証

デプロイメントが意図通りに動作しているかを確認します。

#!/usr/bin/env bash

set -euo pipefail

# ... (trap, TMP_DIR の設定は上記と同様に含める) ...

DEPLOYMENT_NAME="nginx-example"
NAMESPACE="default"

echo "INFO: Verifying deployment status for '${DEPLOYMENT_NAME}'..." >&2

# 1. デプロイメントのロールアウトステータスを確認

kubectl rollout status deployment/${DEPLOYMENT_NAME} -n "${NAMESPACE}" --timeout=120s || {
    echo "ERROR: Deployment '${DEPLOYMENT_NAME}' did not become ready." >&2
    exit 1
}

echo "INFO: Describing deployment '${DEPLOYMENT_NAME}' to check events and status..." >&2

# 2. 詳細情報を取得 (イベントやコンディションを確認)

kubectl describe deployment "${DEPLOYMENT_NAME}" -n "${NAMESPACE}"

echo "INFO: Checking logs of a pod in deployment '${DEPLOYMENT_NAME}'..." >&2

# 3. Podのログを確認 (最初のRunning Podのログを取得)

POD_NAME=$(kubectl get pods -n "${NAMESPACE}" -l app=nginx -o json | \
           jq -r '.items[] | select(.status.phase == "Running") | .metadata.name' | head -n 1)

if [ -z "${POD_NAME}" ]; then
    echo "WARNING: No running pods found for deployment '${DEPLOYMENT_NAME}' to check logs." >&2
else
    echo "INFO: Fetching logs for pod '${POD_NAME}'..." >&2
    kubectl logs "${POD_NAME}" -n "${NAMESPACE}"
fi

echo "SUCCESS: Deployment verification complete." >&2

運用

Kubernetesリソースの定期的な監視や管理タスクには systemd unit/timer が非常に有効です。

1. 監視スクリプトの作成

systemd から実行される監視スクリプトは、必要な情報のみをログに出力し、エラー際には適切なステータスコードを返すように設計します。

/usr/local/bin/monitor_kubernetes_pods.sh

#!/usr/bin/env bash

set -euo pipefail

# KUBECONFIGパスを指定することで、systemdサービスに特定のkubeconfigを適用できる


# 例: KUBECONFIG=/etc/kubernetes/systemd-monitor-kubeconfig.yaml


# ここではデフォルトの~/.kube/configを使用


# export KUBECONFIG="/etc/kubernetes/monitor_kubeconfig"

# Get non-running pods, exclude completed jobs (e.g., cronjobs)

NOT_RUNNING_PODS=$(kubectl get pods --field-selector=status.phase!=Running -o json 2>/dev/null | \
                   jq -r '.items[] | select(.status.phase != "Succeeded") | .metadata.name')

if [ -n "${NOT_RUNNING_PODS}" ]; then

    # systemd-cat を使用してjournaldにログを出力

    echo "WARNING: Non-running pods detected: ${NOT_RUNNING_PODS}" | systemd-cat -t kubernetes-monitor -p warning
    exit 1 # Non-zero exit code indicates an issue
else
    echo "INFO: All application pods are running." | systemd-cat -t kubernetes-monitor -p info
    exit 0 # Zero exit code indicates success
fi

sudo chmod +x /usr/local/bin/monitor_kubernetes_pods.sh で実行権限を付与します。 権限分離の注意点: このスクリプトがアクセスする kubeconfig は、get pods の最小限の権限を持つService Accountのトークンを使用するよう、RBACを設定することが重要です。

2. systemd Unitファイルの作成

/etc/systemd/system/kubernetes-monitor.service

[Unit]
Description=Kubernetes Pod Status Monitor
Documentation=https://example.com/kubernetes-monitor-doc

# ネットワークが利用可能になってからサービスを開始

Wants=network-online.target
After=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/monitor_kubernetes_pods.sh

# サービス実行ユーザーとグループを指定 (非rootユーザーが推奨)


# 必要に応じて、専用のユーザー/グループを作成:


# sudo useradd -r -s /bin/false kubernetes-monitor-user


# User=kubernetes-monitor-user


# Group=kubernetes-monitor-group

# セキュリティ強化設定

ProtectSystem=full      # /usr, /boot などのシステムディレクトリをリードオンリーにマウント
ProtectHome=true        # /home, /root ディレクトリへのアクセスを禁止
PrivateTmp=true         # サービス専用の/tmpと/var/tmpを作成
NoNewPrivileges=true    # 子プロセスが追加の特権を取得することを禁止

# 必要に応じて環境変数 (例: KUBECONFIG) を設定


# Environment="KUBECONFIG=/etc/kubernetes/systemd-monitor-kubeconfig.yaml"

# エラー時の再起動ポリシー


# OnFailure: 失敗した場合にのみ再起動


# OnSuccess: 成功した場合にのみ再起動


# Always: 終了コードに関わらず常に再起動


# Restart=on-failure


# RestartSec=5s

# ログ出力制限


# StandardOutput=journal


# StandardError=journal

[Install]
WantedBy=multi-user.target

3. systemd Timerファイルの作成

/etc/systemd/system/kubernetes-monitor.timer

[Unit]
Description=Run Kubernetes Pod Status Monitor every 5 minutes

[Timer]

# システム起動から1分後に初めて実行

OnBootSec=1min

# サービスがアクティブになってから5分後に次の実行をスケジュール

OnUnitActiveSec=5min

# サービスファイルを指定

Unit=kubernetes-monitor.service

[Install]
WantedBy=timers.target

4. systemd サービスとタイマーの有効化・起動・ログ確認

sudo 権限が必要です。

# 1. systemdデーモンをリロードして新しいユニットファイルを認識させる

sudo systemctl daemon-reload

# 2. タイマーを有効化 (システム起動時に自動開始されるようにする)

sudo systemctl enable kubernetes-monitor.timer

# 3. タイマーを今すぐ起動

sudo systemctl start kubernetes-monitor.timer

# 4. タイマーのステータスを確認

systemctl status kubernetes-monitor.timer

# 5. サービスの実行ログを確認 (systemd-catで出力されたログがjournaldに記録される)

journalctl -u kubernetes-monitor.service --since "10 minutes ago"

# (任意) 必要に応じて、手動でサービスを実行してテスト


# sudo systemctl start kubernetes-monitor.service

トラブルシュート

Kubernetes環境での問題解決には、各種ツールの連携が重要です。

  • kubectl コマンド:

    • kubectl get events: クラスタ全体のイベント履歴を確認し、問題の発生源を特定します。

    • kubectl describe <resource_type>/<name>: リソースの詳細な状態、関連イベント、コンディション、設定を確認します。

    • kubectl logs <pod_name>: 特定のPodのコンテナログをチェックします。-f でリアルタイム追跡、-p で以前のコンテナログ。

    • kubectl exec -it <pod_name> -- /bin/bash: Pod内でシェルを実行し、内部からデバッグします。

    • kubectl top pod/node: リソース使用率を監視し、ボトルネックを特定します。

  • curl デバッグ:

    • curl -v: 詳細なリクエスト/レスポンスヘッダ情報を表示します。

    • curl --trace-ascii debug.log: すべてのネットワーク通信をファイルに記録します。

  • systemd ログ:

    • journalctl -u kubernetes-monitor.service -f: systemd サービスによって生成されたログをリアルタイムで監視します。

    • journalctl -t kubernetes-monitor: systemd-cat -t kubernetes-monitor で指定したタグでログをフィルタリングします。

まとめ

DevOpsエンジニアが kubectl を中心に、jq、curl、systemd を活用してKubernetesクラスターを効果的に管理するための実践的なアプローチを紹介しました。冪等性を保った安全なBashスクリプトの書き方から、JSON処理、API連携、そして systemd による自動監視まで、一連のワークフローをカバーしました。

特に、root権限の最小化と権限分離の原則はDevOpsの重要な柱であり、systemd ユニットファイルのセキュリティ強化設定やKubernetesのRBACを適切に設定することで、より堅牢な運用環境を構築できます。これらのプラクティスを通じて、Kubernetesの管理作業を自動化し、安定性と効率性を向上させることが可能です。

graph TD
    A["DevOps Engineer"] -->|"Initiates"| B("Idempotent Bash Script")
    B -->|"Create/Update Manifests"| C{"Kubernetes API"}
    C -->|"Apply/Validate"| D[Kubectl]
    D -->|"Resource Changes"| E["Kubernetes Cluster"]
    B -->|"Monitor Rollout Status"| F("Kubectl Rollout Status")
    F -->|"Confirmation"| B
    subgraph mermaid_group_7["Automated Monitoring with Systemd"]
        G["Systemd Timer"] -->|"Triggers Periodically"| H("Monitor Script")
        H -->|"Check K8s Status('get -o json')"| D
        D -->|"Return JSON Data"| H
        H -->|"Process with JQ"| I["Log/Alert Service"]
        I -->|"Notify/Store Alerts"| A
    end
    E -->|"Resource State"| D
    click A "https://kubernetes.io/docs/concepts/security/rbac-good-practices/" "Best Practices for RBAC"
    click B "https://kubernetes.io/docs/reference/kubectl/overview/" "kubectl Overview"

この記事の更新履歴

この記事は、生成AIを活用した自動レビュー・更新フローにより内容を見直し、必要な修正を反映しています。

2026年9月14日

  • 削除冒頭の未検証ドラフトである旨の注記を削除しました。
  • 変更まとめ冒頭の不要な読点を修正しました。

文書情報

記事タイトル
KubectlコマンドによるKubernetes管理のDevOps実践
作成日
更新日
Source URL
https://papanda925.com/?p=3477

ライセンス: 本記事のうち、当サイトが権利を有する本文・自作図表は、特記なき限り CC BY 4.0 で利用できます。生成AIを活用して作成・編集した内容を含みます。コードについて、別途ライセンス表示またはリンク先GitHubリポジトリのライセンスがある場合は、その条件を優先します。引用・第三者資料・画像・商標等は本ライセンスの対象外です。 利用ポリシー

タイトルとURLをコピーしました