ノードのリソース制御とスケジューリング
ハードウェアメンテナンスやアップグレードに伴い、特定のノードに対して新しいポッドの割り当てを停止する場合があります。これを「スケジューリング無効化」と呼びます。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
インフラとしてのノード追加
負荷分散のために新しいワークロードを水平方向にスケーリングする場合、クラスタールートに新たなマシンを登録する必要があります。主要な手順は以下の通りです。
- Docker および Kubernetes コンポーネント(kubelet, kube-proxy)のインストール
- マスターサーバーへのネットワーク接続設定
- 自動登録トークンを用いたジョイン処理
以下は、既存の 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
適切なコンテキスト設定の下でこのマニフェストを適用すると、指定されたネームスペース内のみでリソースが生成され、他のチームの作業領域とは干渉しません。