コンテンツにスキップ

アップグレード@Anthos

はじめに

本サイトにつきまして、以下をご認識のほど宜しくお願いいたします。


01. Kubernetesのアップグレード (ベアメタル環境の場合)

アップグレードの仕組み

Anthos Clusterのアップグレード時、データプレーンのワーカーNodeをローリングアップグレードする。

ベアメタルのため、ワーカーNodeを再作成することはなく、コントロールプレーンコンポーネント (例:kube-apiserverなど) とワーカーNodeコンポーネント (例:kubeletなど) をそのままアップグレードしていく。


bmctlコマンドのセットアップ

(1)

bmctlコマンドをインストールする。Anthos GKE Clusterとbmctlコマンドのバージョンには対応関係がある。

$ gsutil cp gs://anthos-baremetal-release/bmctl/1.13.2/linux-amd64/bmctl bmctl-1.12.0
$ chmod a+x bmctl-1.12.0
(2)

Anthos GKE Clusterの現在のバージョンを確認する。

$ kubectl get cluster -A -o yaml
---
apiVersion: baremetal.cluster.gke.io/v1
kind: Cluster
metadata:
  name: foo-anthos-cluster
  namespace: foo-namespace
spec:
  anthosBareMetalVersion: 1.12.0 # 現在のバージョン

また、Anthos GKE ClusterのバージョンとKubernetesのバージョンの対応関係を確認する。

Anthos GKE Clusterのバージョン Kubernetesのバージョン
1.11 v1.22.8-gke
1.12 v1.23.5-gke
... ...
(3)

dockerプロセスが稼働しているかを確認する。Anthosのアップグレードの仕組みの中でKindが使われている。

ワークステーション (仮想サーバー) 上でKindを起動し、Kindを使用してAnthos K8s in Dockerを検証する。

Kindによる検証のために、dockerが必要である。dockerプロセスのデーモンが正常なことを確認する。

$ systemctl status docker


アップグレードの実施

(4)

bmctlコマンドを使用して、Anthos GKE Clusterをローリング方式でアップグレードする。

また、ログの出力先が表示されるため、このログをtailコマンドで確認する。

# カレントディレクトリは、baremetalである必要がある。
$ pwd
baremetal

$ ~/baremetal/bmctl upgrade cluster \
    -c <Cluster名> \
    --kubeconfig <kubeconfigファイルへのパス>
(5)

ログの出力先が表示されるので、tailコマンドで確認する。

$ tail -f ~/baremetal/<ログの出力先>
(6)

アップグレードが開始する。

コントロールプレーンコンポーネントやNodeコンポーネントからエラーが発生するため、アラートで確認する。


アップグレードの動作確認

(7)

アップグレードが終了する。

Anthos GKE Clusterのバージョンがアップグレードされたことを確認する。

$ kubectl get cluster -A -o yaml
---
apiVersion: baremetal.cluster.gke.io/v1
kind: Cluster
metadata:
  name: foo-anthos-cluster
  namespace: foo-namespace
spec:
  anthosBareMetalVersion: 1.12.1 # 新バージョン
(8)

各NodeのKubernetesのバージョンが新しくなったことを確認する

$ kubectl get node -o wide
(9)

Crash、Terminating、ErrorなどのPodがいないかを確認する。

また、Podの作成が始まらないと、kubectl get podコマンドにPod自体が表示されない。

そのため、kubectl get deploymentで、Podの管理リソース (例:Deployment) の全てのPodがReadyコンディションかどうかを確認しておく。

$ kubectl get pod -A -o wide

$ kubectl get deployment -A


02. Istioのアップグレード (オンプレミス環境、ベアメタル環境、他のクラウドプロバイダーの場合)

注意!!!!

Anthos Service Meshのドキュメントを確認すると、Istioをカナリア方式でアップグレードしている。

Istioのカナリア方式のアップグレードでは、新しいistio-proxyコンテナをインジェクションする方法として、istio.io/revキーのリビジョン番号を書き換える方法と、MutatingWebhookConfigurationのエイリアスの紐付けを変更する方法がある。

Anthos Service Meshのアップグレードでは、何らかの事情でこれらの両方の手順が混じっており、Istioとは方法が若干異なっている。


asmcliコマンドのセットアップ

asmcliコマンドでは、そのバージョンに応じて、アップグレード先のASMのバージョンがハードコーディングされている。

この時、ASMのマイナーバージョンを固定できず、asmcliコマンドのインストールのタイミングによってはより新しいパッチバージョンが指定されている。

そのため、各実行環境のアップグレードのたびにasmcliコマンドをインストールすると、より後に実施した実行環境の方で新しいパッチバージョンのASMをデプロイすることになってしまう。

そこで、asmcliコマンドはバージョン管理した方が良い。

(1)

asmcliコマンドをインストールする。アップグレード先のバージョン系の指定するようにする。

$ curl https://storage.googleapis.com/csm-artifacts/asm/asmcli_1.15 > asmcli
$ chmod a+x asmcli
(2)

asmcliコマンドが指定しているPOINT値とREV値を確認する。

$ grep -e 'MAJOR=' -e 'MINOR=' -e 'POINT=' -e 'REV=' asmcli

MAJOR="${MAJOR:=1}"; readonly MAJOR;
MINOR="${MINOR:=14}"; readonly MINOR;
POINT="${POINT:=0}"; readonly POINT; # POINT値
REV="${REV:=0}"; readonly REV;       # REV値
...
(3)

バイナリファイルの名前を変更する。これをバージョン管理する。

# asmcliコマンドの名前を変える。
$ mv asmcli asmcli_1140-0


アップグレードの実施

▼ 新しいIstiodコントロールプレーンをインストール

(4)

今、現在のIstioのリビジョン番号が1130-0だとする。

# Deployment
$ kubectl get pod -n istio-system -l istio.io/rev

NAME                READY   STATUS    RESTARTS   AGE
istiod-asm-1130-0   1/1     Running   0          1m  # 1130-0


# Service
$ kubectl get svc -n istio-system

NAME                  TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)                                                AGE
istiod-asm-1130-0     ClusterIP   10.32.6.58    <none>        15010/TCP,15012/TCP,443/TCP,15014/TCP,53/UDP,853/TCP   12m


# MutatingWebhookConfiguration
$ kubectl get mutatingwebhookconfigurations

NAME                                   WEBHOOKS   AGE
istio-sidecar-injector-1130-0          1          7m56s # 1130-0
istio-revision-tag-default             1          3m18s # 現在のリビジョン番号 (1130-0) を定義するdefaultタグを持つ
(5)

新しいIstiodコントロールプレーンをインストールする。

事前にバージョン管理しているasmcliコマンドを使用して、asmcliコマンドを使用して、旧バージョンを残しつつ、新バージョンのIstiodコントロールプレーンをデプロイする。

$ ./repository/asmcli-1140-0 install \
    --kubeconfig <kubeconfigファイルへのパス> \
    `# Google Cloud以外 (オンプレ、AWS、Azureなど) で稼働させることを宣言する。` \
    --platform multicloud \
    --fleet_id <フリートのグループID> \
    --output_dir ./output \
    `# オプションを全て有効化する。` \
    --enable_all \
    `# Mesh CAを有効化する。` \
    --ca mesh_ca \
    --custom_overlay ./foo/<IstioOperatorのマニフェスト>

▼ 新しいIstiodコントロールプレーンを確認

(6)

Istiodコントロールプレーンがデプロイされたことを確認する。

補足として、asmcliコマンドでは、最新のパッチバージョンがインストールするため、狙ったバージョンをインストールできない可能性がある。

# Deployment
$ kubectl get deployment -n istio-system

NAME                READY   STATUS    RESTARTS   AGE
istiod-asm-1130-0         1/1     Running   0          1m  # 1130-0
istiod-asm-1140-0         1/1     Running   0          1m  # 1140-0 (今回のアップグレード先)


# Service
$ kubectl get svc -n istio-system
NAME                  TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)                                                AGE
istiod-asm-1130-0     ClusterIP   10.32.6.58    <none>        15010/TCP,15012/TCP,443/TCP,15014/TCP,53/UDP,853/TCP   12m
istiod-asm-1140-0     ClusterIP   10.32.6.58    <none>        15010/TCP,15012/TCP,443/TCP,15014/TCP,53/UDP,853/TCP   12m # 新しい方


# MutatingWebhookConfiguration
$ kubectl get mutatingwebhookconfigurations

NAME                                   WEBHOOKS   AGE
istio-sidecar-injector-1130-0          1          7m56s # 1130-0
istio-sidecar-injector-1140-0          1          7m56s # 1140-0 (今回のアップグレード先)
istio-revision-tag-default             1          3m18s # 現在のリビジョン番号 (1130-0) を定義するdefaultタグを持つ

▼ Namespaceの.metadata.labelsキーを付け替える。

(7)

カナリア方式のため、Istiodコントロールプレーンの新バージョンのistio.io/revキーの値を取得する。

$ kubectl get pod -n istio-system -l istio.io/rev

NAME                 READY   STATUS    RESTARTS   AGE   REV
istiod-asm-1130-0    1/1     Running   0          68m   asm-1130-0 # 旧バージョン
istiod-asm-1130-0    1/1     Running   0          68m   asm-1130-0
istiod-asm-1140-0    1/1     Running   0          27s   asm-1140-0 # 今回のアップグレード先
istiod-asm-1140-0    1/1     Running   0          27s   asm-1140-0
(8)

istio.io/revキーが設定されている全てのNamespaceを確認する。

$ kubectl get namespace ingress -L istio.io/rev
NAME       STATUS    AGE     REV
ingress    Active    2d18h   1130
$ kubectl get namespace app -o yaml
---
apiVersion: v1
kind: Namespace
metadata:
  name: istio-ingress
  labels:
    istio.io/rev: default
$ kubectl get namespace app -L istio.io/rev

NAME   STATUS    AGE     REV
app    Active    2d18h   1130
$ kubectl get namespace app -o yaml
---
apiVersion: v1
kind: Namespace
metadata:
  name: app
  labels:
    istio.io/rev: default
(9)

Istioのistio.io/revキーを使用して、特定のNamespaceのistio-injectionキーを上書きする。

多くの場合、istio-proxyコンテナはIstio IngressGatewayとアプリケーションのPodのNamespaceにインジェクションしているはずである。そこで、それらのNamespaceを指定する。

これらのキーはコンフリクトを発生させるため、どちらか一方しか使用できず、Anthosではistio.io/revキーを推奨している。

もしGitOpsツール (例:ArgoCD、Flux) でNamespaceを管理している場合は、kubectl labelコマンドの代わりに、GitHub上でリビジョン番号を変更することになる。

# Istio IngressGatewayの特定のNamespace
$ kubectl label namespace ingress istio.io/rev=asm-1140-0 istio-injection- --overwrite

# アプリの特定のNamespace
$ kubectl label namespace app istio.io/rev=asm-1140-0 istio-injection- --overwriteNa
(10)

新しいラベルに変更できたことに変更できたことを確認する。

$ kubectl get namespace -L istio.io/rev

▼ Istio IngressGatewayのistio-proxyコンテナをアップグレード

(11)

Istio IngressGatewayのPodを再作成し、新バージョンのistio-proxyコンテナを自動的にインジェクションする。

カナリア方式のため、webhook-serviceがそのままで新しいistio-proxyコンテナをインジェクションできる。

$ kubectl rollout restart deployment istio-ingressgateway -n istio-ingress
(12)

新バージョンのistio-proxyコンテナがインジェクションされたことを、イメージタグから確認する。

代わりに、istioctl proxy-statusコマンドでも良い。

# 新バージョンのリビジョン番号:asm-1140-0
$ kubectl get pod \
    -n istio-ingress \
    -o jsonpath={.items[*].spec.containers[*].image} | sed 's/ /\n/g' && echo


gcr.io/gke-release/asm/proxyv2:1.14.0-asm.1


# 代わりに、istioctl proxy-statusコマンドでも良い。
$ istioctl proxy-status

▼ アプリケーションのistio-proxyコンテナをアップグレード

(13)

アプリケーションのPodを再作成し、新バージョンのistio-proxyコンテナを自動的にインジェクションする。

カナリア方式のため、webhook-serviceがそのままで新しいistio-proxyコンテナをインジェクションできる。

$ kubectl rollout restart deployment app-deployment -n app
(14)

新バージョンのistio-proxyコンテナがインジェクションされたことを、イメージタグから確認する。

代わりに、istioctl proxy-statusコマンドでも良い。

# 新バージョンのリビジョン番号:asm-1140-0
$ kubectl get pod \
    -n app \
    -o jsonpath={.items[*].spec.containers[*].image} | sed 's/ /\n/g' && echo


gcr.io/gke-release/asm/proxyv2:1.14.0-asm.1

# 代わりに、istioctl proxy-statusコマンドでも良い。
$ istioctl proxy-status

▼ webhookの向き先を新しいIstiodコントロールプレーンに完全に変更

(15)

Istioのvalidating-admission時を経由するService更新する。

ソースコードは、anthos-service-mesh-packagesリポジトリから拝借する。

$ kubectl diff -f ./asm/istio/istiod-service.yaml

$ kubectl apply -f ./asm/istio/istiod-service.yaml
---
# https://github.com/GoogleCloudPlatform/anthos-service-mesh-packages/blob/main/asm/istio/istiod-service.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    app: istiod
    istio: pilot
    istio.io/rev: asm-1140-0 # リビジョン番号を更新する。
    release: istio
  name: istiod
  namespace: istio-system
spec:
  ports:
    - name: https-webhook
      port: 443
      protocol: TCP
      targetPort: 15017
    - name: grpc-xds
      port: 15010
      protocol: TCP
      targetPort: 15010
    - name: https-dns
      port: 15012
      protocol: TCP
      targetPort: 15012
    - name: http-monitoring
      port: 15014
      protocol: TCP
      targetPort: 15014
  selector:
    app: istiod
    istio.io/rev: asm-1140-0 # リビジョン番号を更新する。
(16)

MutatingWebhookConfigurationの.metadata.labelsキーにて、エイリアスに紐づく現在のリビジョン番号を確認する。

# アップグレード前に、istiocltコマンドで確認
$ ./output/asm-1.14/istioctl tag list

TAG     REVISION    NAMESPACES
default asm-1130-0
# アップグレード前に、マニフェストを確認してみる。
$ kubectl get mutatingwebhookconfiguration istio-revision-tag-default -o yaml \
    | grep -e istio.io/rev: -e istio.io/tag:

istio.io/rev: asm-1130-0
istio.io/tag: default
(17)

Istioのmutating-admissionを設定するMutatingWebhookConfigurationのラベル値を変更する。

MutatingWebhookConfigurationの.metadata.labelsキーにあるエイリアス (istio.io/tagキーの値) の実体 (istio.io/revキーの値) が旧バージョンのままなため、新バージョンに変更する。

istioctlコマンドは、asmcliコマンドの--output_dirオプションで指定したディレクトリにある。

# asmcliコマンドのoutput_dirオプションで指定したディレクトリのistioctlコマンド
$ ./output/asm-1.14/istioctl tag set default --revision asm-1140-0 --overwrite
(18)

MutatingWebhookConfigurationの.metadata.labelsキーにて、エイリアスに紐づくリビジョン番号を変更できたことを確認する。

# アップグレード前に、istiocltコマンドで確認してみる。
$ ./output/asm-1.14/istioctl tag list

TAG     REVISION    NAMESPACES
default asm-1140-0
# アップグレード前に、マニフェストを確認してみる。
$ kubectl get mutatingwebhookconfiguration istio-revision-tag-default -o yaml \
    | grep -e istio.io/rev: -e istio.io/tag:

istio.io/rev: asm-1140-0
istio.io/tag: default

▼ 古いIstiodコントロールプレーンを削除

(19)

旧バージョンのIstiodコントロールプレーン (実体は、Service、Deployment、HorizontalPodAutoscaler、PodDisruptionBudget) を削除する。

$ kubectl get all -n istio-system


# 旧バージョンのリビジョン番号:asm-1130-0
$ kubectl delete Service,Deployment,HorizontalPodAutoscaler,PodDisruptionBudget istiod-asm-1130-0 -n istio-system --ignore-not-found=true


$ kubectl get all -n istio-system

▼ 古いIstiodコントロールプレーンを削除を削除

(20)

旧バージョンのValidatingWebhookConfigurationを削除する。

$ kubectl get validatingwebhookconfiguration -n istio-system


$ kubectl delete validatingwebhookconfiguration istio-validator-asm-1140-0-istio-system -n istio-system --ignore-not-found=true


$ kubectl get validatingwebhookconfiguration -n istio-system

▼ 古いIstioOperatorを削除を削除

(21)

旧バージョンのIstioOperatorを削除する。

$ kubectl get IstioOperator -n istio-system


# 旧バージョンのリビジョン番号:asm-1130-0
$ kubectl delete IstioOperator installed-state-asm-1130-0 -n istio-system


$ kubectl get IstioOperator -n istio-system


アップグレードの動作確認

(22)

全てのPodが正常に稼働していることを確認する。

また、Podの作成が始まらないと、kubectl get podコマンドにPod自体が表示されない。

そのため、kubectl get deploymentで、Podの管理リソース (例:Deployment) の全てのPodがReadyコンディションかどうかを確認しておく。

$ kubectl get pod -A -o wide


03. NodeのOSのアップグレード (ベアメタル環境の場合)

ベアメタル環境の場合、Google CloudはNodeのOSのバージョンを管理してくれず、Google Cloud外でアップグレードする必要がある。