想定読者
- GKEで外部LB用Ingressを利用している
- IngressのAPIバージョン
extensions/v1beta1
またはnetworking.k8s.io/v1beta1
を利用している - k8sのバージョンv1.19~ を利用している
背景
k8sのバージョンv1.22からextensions/v1beta1
およびnetworking.k8s.io/v1beta1
のIngressが利用出来なくなります。
ということで早速公式の指示に従ってIngressをnetworking.k8s.io/v1
にマイグレートしましょう!
注目すべきマニフェストの変更点
今回のアップデートでIngressのAPIが以下のように変更されています。
- spec.backend -> spec.defaultBackend
- serviceName -> service.name
- servicePort -> service.port.number
- serviceName -> service.port.name
- L7ルーティングをする場合はpathTypeの指定が必須
kubectl convertによるマニフェストのマイグレート
既存のマニフェストを元に新しいバージョンのマニフェストを生成する場合は以下のコマンドを利用することが推奨されています。
> kubectl convert -f old-ingress.yaml --output-version networking.k8s.io/v1
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.allow-http: "false"
kubernetes.io/ingress.global-static-ip-name: sample-ip
creationTimestamp: null
labels:
app: app-sample
name: ingress-sample
spec:
defaultBackend:
service:
name: service-sample
port:
number: 8080
status:
loadBalancer: {}
kubectl convert
が利用出来ない場合はkubectlのバージョンを最新化した上で公式ドキュメントに従ってpluginをインストールしましょう。
Ingressリソースのマイグレート手順
一般的な方法
既にIngressリソースを作成されている場合は、前述したkubectl convert
により生成したマニフェストを再適用するだけで問題無くマイグレートが可能です。
> kubectl convert -f old-ingress.yaml --output-version networking.k8s.io/v1 > new-ingress.yaml
> kubectl apply -f new-ingress.yaml
ingress.networking.k8s.io/ingress-sample configured
確認した限りダウンタイムの発生は無いですが、トラフィックの多い本番環境に適用する場合は事前に開発環境でダウンタイムの確認をしておくことを推奨します。
カナリアリリースによる方法
先ほどのやり方は簡単ですが、やり直しやロールバックが実質的に不可能で、既にサービスインしているIngressに対して実行するのは怖いです。
そんな場合にもう一つの選択肢として「CloudDNSの重み付きラウンドロビン」を利用したカナリアリリースがあります。
重み付きラウンドロビンは重みに従ってDNSが返すAレコードを分散させる機能です。
今回の場合であれば、旧IngressのIPを99%、新しく作成したIngressのIPを1%の確率で返す、といったような設定を入れることでIngressのカナリアリリースが可能になります。
作業手順
- 外部IPを新規作成する
-
networking.k8s.io/v1
のIngressリソースを作成する- リソース名は旧Ingressリソースと異なるものを付けるようにしてください
-
kubernetes.io/ingress.allow-http:false
を指定する場合はingress.gcp.kubernetes.io/pre-shared-cert
に旧Ingressに紐付けられているマネージド証明書の名前を指定してください
- CloudDNSの重み付きラウンドロビンに2つのIngressのIPを重みとともに設定する
- 100%リリース出来たら旧Ingressのリソースを削除する
kubernetes.io/ingress.allow-http:false
の挙動は癖が強いので注意してください。
このアノテーションを作成済みのIngressにあとから追加しようとするとエラーが発生するため、つけ忘れた場合はリソースの作成を最初からやり直す羽目になったりします。。。
まとめ
- k8sのバージョンv1.22から
extensions/v1beta1
およびnetworking.k8s.io/v1beta1
のIngressが利用出来なくなる - 古いマニフェストから新しいバージョンのマニフェストを生成する場合は
kubectl convert
を使う - Ingressをカナリアリリースする場合はCloudDNSの重み付きラウンドロビンを使う