Kubernetes クラスター運用ガイド:ノード操作からコンテキスト管理まで

ノードのリソース制御とスケジューリング

ハードウェアメンテナンスやアップグレードに伴い、特定のノードに対して新しいポッドの割り当てを停止する場合があります。これを「スケジューリング無効化」と呼びます。Kubernetes は、YAML マニフェストの変更またはコマンドラインツールの両方を使用してこの操作を行うことができます。

マニフェストによるスケジュール除外

まず、対象ノードを指定した設定ファイルを作成します。spec.unschedulable の値を true に設定することで、新規ポッドの配置を禁止します。

cat > node-drain-spec.yaml << EOF
apiVersion: v1
kind: Node
metadata:
  name: worker-03
  labels:
    kubernetes.io/hostname: worker-03
spec:
  unschedulable: true
EOF

生成されたファイルを適用し、変更を反映させます。

kubectl replace --filename=node-drain-spec.yaml
kubectl get nodes | grep worker-03

代替として、パッチコマンドで即時に状態を変更することも可能です。

kubectl patch node worker-03 -p '{"spec":{"unschedulable":true}}'

注意点: ノードがスケジュール不可状態になっても、既に稼働しているポッドは自動的に削除されません。手動でのポッド移動(Drain)が必要です。

ノードの復元操作

メンテナンスが完了したら、unschedulable を false に変更して、再度クラスターに組み込みます。

cat > node-restore-spec.yaml << EOF
apiVersion: v1
kind: Node
metadata:
  name: worker-03
spec:
  unschedulable: false
EOF
kubectl replace --filename=node-restore-spec.yaml

あるいは、以下のコマンドで迅速に戻すことが可能です。

kubectl uncordon worker-03

インフラとしてのノード追加

負荷分散のために新しいワークロードを水平方向にスケーリングする場合、クラスタールートに新たなマシンを登録する必要があります。主要な手順は以下の通りです。

  1. Docker および Kubernetes コンポーネント(kubelet, kube-proxy)のインストール
  2. マスターサーバーへのネットワーク接続設定
  3. 自動登録トークンを用いたジョイン処理

以下は、既存の kubeadm クラスターへ新しい計算リソースを追加するための初期化スクリプトの例です。

#!/bin/bash
# OS Kernel パラメータ調整
cat > /etc/sysctl.d/k8s-sys.conf << EOF
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
vm.swappiness = 0
vm.overcommit_memory = 1
EOF
sysctl --system

# Docker サービス準備
yum install -y yum-utils device-mapper-persistent-data lvm2
addrepo http://mirror.centos.org/centos/7/extras/ centos-extras-rpm
yum install -y docker-ce-20.10.10-lts.el7_8

# Container Runtime Configuration
mkdir -p /etc/docker
echo '{
    "registry-mirrors": ["https://registry.example.com"],
    "exec-opts": ["native.cgroupdriver=systemd"]
}' > /etc/docker/daemon.json
systemctl enable docker --now

# Control Plane Tools Install
cat > /etc/yum.repos.d/kube-repo.conf << EOF
[kube]
name=Kubernetes Repository
baseurl=https://pkgs.k8s.io/core:/stable:/v1.23/rpm/
enabled=1
gpgcheck=0
EOF
yum install -y kubeadm-1.23.0 kubelet-1.23.0 kubectl-1.23.0
systemctl enable kubelet --now

最後に、マスターノードで発行したトークンを使用して接続します。

# Master side: Generate Token & Hash
TOKEN=$(kubeadm token create)
HASH=$(openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //')
echo $TOKEN
echo $HASH

# Worker side: Join Cluster
kubeadm join 192.168.10.100:6443 --token $TOKEN --discovery-token-ca-cert-hash sha256:$HASH

ラベルベースのグループ管理

リソースに対するカスタム属性を定義・編集するにはラベル機能を利用します。主にフィルタリングやセレクターに使用されます。

# ラベルの追加(Example: app=frontend)
kubectl label pod nginx-deploy-main app=web-tier --overwrite

# ラベル情報の確認
kubectl get pods --show-labels | grep web-tier

# ラベル値の更新
kubectl label pod nginx-deploy-main app=legacy-tier --overwrite

# ラベルの削除(キー後にハイフンを追加)
kubectl label pod nginx-deploy-main app-

論理的環境の分離:ネームスペース

単一の物理クラスター上で、開発、テスト、本番などの異なるプロジェクト環境を論理的に分離するためにネームスペースを設定します。

各環境用の YAML 定義ファイルを用意します。

# environment-staging.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: staging-area
---
# environment-production.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: prod-live

作成コマンドを実行します。

kubectl apply --filename=environment-staging.yaml
kubectl apply --filename=environment-production.yaml
kubectl get namespace

操作コンテキストの切り替え設定

管理者が複数のネームスペースを頻繁に操作する場合、現在のコンテキスト(ユーザー、クラスター、ネームスペースの組み合わせ)を設定しておくと利便性が高まります。

まず、各プロジェクト向けのコンテキストを定義し、対応するネームスペースを紐付けます。

kubectl config set-context project-alpha --namespace=staging-area --cluster=k8s-main --user=admin-role
kubectl config set-context project-beta --namespace=prod-live --cluster=k8s-main --user=admin-role

その後、必要に応じてターゲットとなるコンテキストへ遷移します。

# Alpha プロジェクト環境を選択
kubectl config use-context project-alpha

# この後のすべての kubectl コマンドは staging-area 領域で実行される
kubectl run temp-job --image=busybox --dry-run=client -o yaml --save-config

別の環境へ移る際は、再度 use-context でスイッチャーを行います。これにより、誤って本番環境にデプロイするなどの事故を防ぐことができます。

# 切り替え先の変更
kubectl config use-context project-beta

# 所属環境の確認
kubectl get deployments
# Deployment Manifest 例(特定コンテキスト内で適用時)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-service-handler
  labels:
    app: backend-api
spec:
  replicas: 3
  selector:
    matchLabels:
      app: backend-api
  template:
    metadata:
      labels:
        app: backend-api
    spec:
      containers:
      - name: primary-container
        image: gcr.io/google-samples/hello-app:1.0
        ports:
        - containerPort: 8080

適切なコンテキスト設定の下でこのマニフェストを適用すると、指定されたネームスペース内のみでリソースが生成され、他のチームの作業領域とは干渉しません。

タグ: Kubernetes kubeadm Docker cluster-administration kubectl

10月10日 08:03 投稿