Google Kubernetes Engine(GKE)クラスターのメンテナンス除外を設定するシェルスクリプトを作成してみた

 2024.12.09 XIMIX 山田

はじめに

この記事では、GKEクラスターの詳細設定の1つであるメンテナンス除外について説明します。
メンテナンス除外の設定が必要である背景を説明したあとに、メンテナンス除外の内容について説明します
続いて、メンテナンス除外の設定をするためのシェルスクリプトについて詳しく解説します。
このシェルスクリプトを利用することで、メンテナンス除外の設定作業を効率化することが可能となります。

背景

なぜメンテナンス除外の設定を行うのか、その背景を説明します。
まず前提として、私たちはGKE Autopilotクラスタでアプリケーションを構築・運用しています。リリースチャネルをStableに設定して、GKEのバージョンアップはGoogle Cloudに任せています。
しかし、自動的なアップデートにより、動作仕様に変更が発生し、本番環境で動作するアプリケーションの挙動に影響が出ることがありました。現在の保守体制では、アップデートによる変更に迅速に対応し、アプリケーションを修正する余裕がない状況です。
そのため、本番環境と同じようにGKEを構成しているテスト環境で、まずアップデートと動作確認を行い、その後本番環境でもアップデートを実施することが望ましいと判断しました。
当初は手動で設定を行い運用していましたが、運用の手間を減らすために自動化することにしました。

メンテナンス除外とは

GKEの自動メンテナンスの実行が禁止される、特定の時間枠のことです。
主に設定するパラメータは2つあります。
  • 除外の期間
    • 自動メンテナンスの実行が禁止される期間
  • 除外するアップグレードの範囲
    • アップグレードなし(デフォルト)
    • マイナーアップグレードなし
    • マイナー・ノードアップグレードなし

メンテナンス除外設定をシェルスクリプトで実行しよう

仕様

  • 除外期間:20日
    • 開始日:設定日
    • 終了日:設定日の20日後
  • 除外するアップグレードの範囲:アップグレードなし(デフォルト)
  • 既に除外設定が存在する場合は、新規で除外設定を作成したのちに既存の除外設定を削除する(除外設定が1つもない状態にしない)

 スクリプト

#!/bin/bash

#エラー検知でスクリプト停止
set -e

CLUSTER_NAME="gke-maintenance-ex" #クラスターの名前
ZONE="asia-northeast1" #ゾーン
NEW_EXCLUSION_NAME="exclusion-$(date '+%Y%m%d')" #除外の名前
PERIOD="20 days" #除外期間

#メンテナンス除外期間を新規作成
gcloud container clusters update $CLUSTER_NAME \
--zone $ZONE \
--add-maintenance-exclusion-name $NEW_EXCLUSION_NAME \
--add-maintenance-exclusion-start $(date +"%Y-%m-%dT%H:%M:%S%z") \
--add-maintenance-exclusion-end $(date -d "$PERIOD" +"%Y-%m-%dT%H:%M:%S%z")

echo "New maintenance exclusion created successfully."

# メンテナンス除外期間の名前を取得
EXCLUSION_NAMES=$(gcloud container clusters describe $CLUSTER_NAME \
    --zone $ZONE \
    --format="json" | jq -r '.maintenancePolicy.window.maintenanceExclusions | keys[]' )

# 新規以外のメンテナンス除外期間を削除
EXCLUSION_NAMES_ARRAY=($EXCLUSION_NAMES)
if [ "${#EXCLUSION_NAMES_ARRAY[@]}" -ge "2" ]; then
    for EXCLUSION_NAME in $EXCLUSION_NAMES; do
        if [ "$EXCLUSION_NAME" != "$NEW_EXCLUSION_NAME" ]; then
            echo "Removing maintenance exclusion: $EXCLUSION_NAME"
            gcloud container clusters update $CLUSTER_NAME \
            --zone $ZONE \
            --remove-maintenance-exclusion $EXCLUSION_NAME
        fi
    done
fi

エラー検知でスクリプト停止

#エラー検知でスクリプト停止
set -e

メンテナンス除外設定の新規作成に失敗したときに既存の設定が削除されないようにするためです。

変数設定

CLUSTER_NAME="gke-maintenance-ex" #クラスターの名前
ZONE="asia-northeast1" #ゾーン
NEW_EXCLUSION_NAME="exclusion-$(date '+%Y%m%d')" #除外の名前
PERIOD="20 days" #除外期間

  • CLUSTER_NAME:対象とするGKEクラスターの名前
  • ZONE:クラスターが存在するゾーン(リージョン指定でも大丈夫です)
  • NEW_EXCLUSION_NAME:除外の名前。名前に一意性をもたせるため設定日を付けています(例:exclusion-20241209)
  • PERIOD:除外期間(本当は30日にしたかったんですが、メンテナンスポリシーによる制約があったので20日に変更)

     

メンテナンスポリシーの制約:32 日間のローリング ウィンドウ内で少なくとも 48 時間はメンテナンスが可能な状態にする必要があります。メンテナンスに 4 時間以上連続する時間を用意してください。ERROR: (gcloud.container.clusters.update) ResponseError: code=400, message=Error validating maintenance policy: maintenance policy would go longer than 32d without 48h maintenance availability of >= 4h contiguous duration (in time range [2024-11-04T02:20:43Z, 2024-12-06T02:20:43Z]).


メンテナンス除外の新規作成

#メンテナンス除外期間を新規作成
gcloud container clusters update $CLUSTER_NAME \
--zone $ZONE \
--add-maintenance-exclusion-name $NEW_EXCLUSION_NAME \
--add-maintenance-exclusion-start $(date +"%Y-%m-%dT%H:%M:%S%z") \
--add-maintenance-exclusion-end $(date -d "$PERIOD" +"%Y-%m-%dT%H:%M:%S%z")

echo "New maintenance exclusion created successfully."

対象クラスターの名前、クラスターが存在するゾーン、除外の名前、開始日、終了日を指定して更新しています。メンテナンス除外作成成功を示すメッセージを出力しています。

現存するメンテナンス除外設定の名前を取得

# メンテナンス除外期間の名前を取得
EXCLUSION_NAMES=$(gcloud container clusters describe $CLUSTER_NAME \
    --zone $ZONE \
    --format="json" | jq -r '.maintenancePolicy.window.maintenanceExclusions | keys[]' )

メンテナンス除外の情報をjson形式で出力し、jqコマンドでkey(メンテナンス除外の名前)だけ取ってきてます。

既存のメンテナンス除外の削除

# 新規以外のメンテナンス除外期間を削除
EXCLUSION_NAMES_ARRAY=($EXCLUSION_NAMES)
if [ "${#EXCLUSION_NAMES_ARRAY[@]}" -ge "2" ]; then
    for EXCLUSION_NAME in $EXCLUSION_NAMES; do
        if [ "$EXCLUSION_NAME" != "$NEW_EXCLUSION_NAME" ]; then
            echo "Removing maintenance exclusion: $EXCLUSION_NAME"
            gcloud container clusters update $CLUSTER_NAME \
            --zone $ZONE \
            --remove-maintenance-exclusion $EXCLUSION_NAME
        fi
    done
fi

先ほど取得したメンテナンス除外の名前を配列に変換し、除外が2つ以上ある場合にメンテナンス除外を削除します。
このときメンテナンス除外の名前を確認し、新規に作成されたメンテナンス除外を削除対象から除いています。

実行結果

結果はコンソールでGKEクラスターの詳細画面から確認します。先にコンソール上、またはコマンドでメンテナンス除外を作成します。

before

この設定では、2024/11/04 10:20~2024/11/24 10:20の期間、自動メンテナンスの実行が禁止されます。この状態でシェルスクリプトを実行します。

Updating gke-maintenance-ex...done.                                                                                                                                                                                                               
Updated [https://container.googleapis.com/v1/projects/[プロジェクトID]/zones/asia-northeast1/clusters/gke-maintenance-ex].
To inspect the contents of your cluster, go to: https://console.cloud.google.com/kubernetes/workload_/gcloud/asia-northeast1/gke-maintenance-ex?project=[プロジェクトID]
Removing maintenance exclusion: blackout-1
Updating gke-maintenance-ex...done.                                                                                                                                                                                                               
Updated [https://container.googleapis.com/v1/projects/[プロジェクトID]/zones/asia-northeast1/clusters/gke-maintenance-ex].
To inspect the contents of your cluster, go to: https://console.cloud.google.com/kubernetes/workload_/gcloud/asia-northeast1/gke-maintenance-ex?project=[プロジェクトID]

2回更新されていますが、1回目がメンテナンス除外の新規作成、2回目が既存のメンテナンス除外の削除です。コンソールでメンテナンス除外を設定したときは名前をつけることはできず、blackout-1といった名前になります。
コンソールでクラスターの詳細を確認すると...

after

設定日(2024/11/11)から20日間のメンテナンス除外が設定され、以前の設定は削除されています!🎉

まとめ 

GKEクラスターの設定項目の1つであるメンテナンス除外では、GKEの自動アップデートを禁止する期間とその範囲を指定できます。アプリケーションの挙動が自動アップデートによって変わることを避けたい場合に、メンテナンス除外が役立ちます。この設定はコマンドで実行することができます。今回は、新規のメンテナンス除外作成および既存設定の削除を行うコマンドをまとめたシェルスクリプトを作成しました。また、今回作成したシェルスクリプトをCronJobに組み込むことで、定期的にメンテナンス除外の設定を実施することができます。

参考


Google Cloud、Google Workspace に関するご相談はXIMIXへ!

Google Cloud、Google Workspaceに関する お問い合わせはこちら


Google Kubernetes Engine(GKE)クラスターのメンテナンス除外を設定するシェルスクリプトを作成してみた

BACK TO LIST