0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ingress-nginx廃止調査検証

0
Last updated at Posted at 2026-05-24

背景

ingress-nginxが3人くらいだとメンテナンスできねえしGatewayAPIが主流になるし廃止ですとアナウンスが。
https://www.kubernetes.dev/blog/2025/11/12/ingress-nginx-retirement/
https://www.codecentric.de/en/knowledge-hub/blog/nginx-ingress-retirement-dont-panic-weve-got-you-covered
わりといろんな意味で負荷が高いとみんな思っているのでは。がんばりますけど。→3末オンスケで完了済みです(ingressコントローラ入れ替えるとこは)。

できないといけないこと

これは私が受け持たせていただいてる環境の要件
・メンテで事故を起こさない平行運用切り替え切り戻しできること(ingressClass変えるといける感じ)
・ログフォーマット、IPホワイトリスト制限(traficmanager経由)、内外複数コントローラ配置、Basic認証、サーバ証明書認証、正規表現リダイレクト、カスタムエラーページ、などの機能を完全再現移行が必要(アプリの修正なし)
・helmチャートをpullして変数とテンプレを上書きしgit管理できるようにする
・モノnamespaceとchartだけどchartsディレクトリに入れる。環境ごとの変数はpipelineで上書きさす。

大まかな経路

まんまこうではないですが雑にいうとこうという経路です

1 pubuser-443-frontDoor-80-aksIngressExternal-80-service-pod
2 menteuser-443-traficManager-443-aksIngressExternal2-80-service-pod
3 admin-exroute-privDns-443-aksIngressInternal-80-service-pod

この辺の構成を変えるとドキュメント修正が山盛りになり工数がかさみそうでgatewayApiにするまでに何しないといけないのか戦々恐々です。

候補

ingressコントローラの単純な代替えで延命の場合

  • Traefik:クライアントIPのヘッダをTraficManager等のL4のLB経由でとってこれずそれ経由のIP制限に難があり→位置が違っててspecを挟む必要性を確認できておらず実際のserviceの-o yaml結果みたらClusterになってたというオチでした。
  service:
    spec:
      externalTrafficPolicy: Local

あとLogformatもあんまり柔軟にできずでログ監視のクエリを数十件変更が必要になるのが確定してますね。結構移行元と別物だったので検証に時間を要しました。Basic認証はできてた。DefaultBackendがないので、TrraficmanagerのHostヘッダ無しアクセスを404にしないようなルーティングが必要だったりもしました(ingress-nginxだとvaluesに追記で勝手にdefaultbackend作られてた)。正規表現リダイレクトもカスタムエラーページも機能してたのでもうこれでいいです。レビューと作業MTGでダメ出ししてもらったらどうにかなった。

  • HAproxyIngress:候補として検討したが、Traefikで要件を満たせたため採用しなかった。Logformatがsyslog様にできるのは良いですがGatewayAPIにするにはなんかOLDっぽいところにListされていた。
  • Application Gateway for Containers (AGIC):オープンソースから月300ドルに移行するのはオーナーを説得できない。無理です。

GatewayAPIに変える場合

短期でGatewayAPIに移行はちょっと無理です。履修とかドキュメント整備のコストが。

traefikで機能してた定義

helmチャートをGitリポジトリで管理してパイプラインで流す派ですのでhelm upgradeでどうにかするタイプのやり方ではなくpullしたtraefikのチャートディレクトリをchartsに突っ込んで親チャートのvalues.yamlから上書きしています。

親チャートのvalues.yaml
traefik:
  enabled: true
  nameOverride: traefik
  ingressClass:
    enabled: true
    name: traefik
    isDefaultClass: false
  additionalArguments:
    - --providers.kubernetesingress=true
    - --providers.kubernetesingress.ingressClass=traefik
    #- --providers.kubernetesingressnginx=true
    #- --providers.kubernetesingressnginx.ingressClass=nginx
    #- --providers.kubernetesingressnginx.controllerClass=k8s.io/ingress-nginx
    #- --providers.kubernetesingressnginx.watchnamespace=default
    - --providers.kubernetescrd=true
    - --log.level=DEBUG #あとでINFOに戻す
    - --ping=true
    - --ping.entryPoint=traefik
    - --entrypoints.web.forwardedHeaders.trustedIPs=100.98.0.0/24,このほか前段とメンテ元の信頼さすIPを定義
    - --entrypoints.websecure.forwardedHeaders.trustedIPs=100.98.0.0/24,このほか前段とメンテ元の信頼さすIPを定義
    - --entrypoints.web.address=:8000
    - --entrypoints.websecure.address=:8443
    - --api.dashboard=true
    - --entrypoints.traefik.address=:9000/tcp
    - --entrypoints.metrics.address=:9100/tcp
  service:
    enabled: true
    type: LoadBalancer
    annotations: {}
    spec:
      externalTrafficPolicy: Local
  ports:
    web:
      port: 80
      expose:
        default: true
      exposedPort: 80
      targetPort: 8000
    websecure:
      port: 443
      expose:
        default: true
      exposedPort: 443
      targetPort: 8443
    traefik:  # /ping用
      port: 9000
      expose:
        default: true
      exposedPort: 9000  # Service の port
      targetPort: 9000
    metrics:  #とりあえずトラフィックレート等を将来的に何かで見れるように開けとく
      port: 9100  
      targetPort: 9100
  deployment:
    kind: DaemonSet #externalTrafficPolicy: Localの場合に必要だったので
    #replicas: 1
    readinessProbe:
      httpGet:
        path: /ping
        port: traefik
    livenessProbe:
      httpGet:
        path: /ping
        port: traefik
  logs:
    general:
      format: json
    access:
      enabled: true
      format: json
      fields:
        defaultMode: keep
        names:
          ClientUsername: drop
        headers:
          defaultMode: keep
          names:
            X-Forwarded-For: keep
            X-Forwarded-Proto: keep
            X-Azure-ClientIP: keep
            X-Azure-FDID: keep
            Referer: keep
            User-Agent: keep
            Authorization: drop
            Cookie: drop
  podSecurityContext:
    runAsNonRoot: true
    runAsGroup: 65532
    runAsUser: 65532
  securityContext:
    allowPrivilegeEscalation: false
    readOnlyRootFilesystem: true
    capabilities:
      drop:
        - ALL

多少こうなった理由を書いときます

  • 今後のセキュリティ的に推奨とかでsecurityContextのあたり等を入れたせいでLowPort(1024以下)がtargetPortで使えない→8443とか使う→exporseとtargetのポート番号がずれてるとhealthProbeに失敗する→kubeletからのPingに失敗してPodが延々Crashloop→キャパびりてぃのNetBindなんとかを入れるも特に改善せず→PingPortをtraefikの9000にする→Ping成功
  • アクセスログが何も設定しないと出ない→logs.access.enabled:trueを設定
  • ダッシュボードはそれ用のingressリソース定義するかPortforwardしないと有効にする設定しただけだとみられない(まあいいか)
  • isDefaultClassは平行運用中falseにしないと事故る
  • entrypoints.websecure.forwardedHeaders.trustedIPsはservice.spec.externalTrafficPolicy: Localと一緒にいれとかないとIP制限するためのリモートのIPを信頼しないせいで認識できないらしいのでいれた

あと環境ごとのやつ(pipelineのhelm upgradeコマンドの-fで渡すやつ)

test.yaml
traefik:
  service:
    annotations:
      service.beta.kubernetes.io/azure-load-balancer-resource-group: "MC_myrg"
      service.beta.kubernetes.io/azure-pip-name: "my-cluster2-ing2-pip"
    spec:
      loadBalancerIP: "135.xxx.xx.xx"

参考まで。middleware名のプレフィックスついてるのはnamespace名です。

ingress抜粋
---
# ==========================================
# 内部向け Ingress(Traefik-Internal / 80-443)
# ==========================================
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-tf-int
  namespace: default
  annotations:
    # Middlewares 適用(Basic認証 / エラーページ / リダイレクト)
    traefik.ingress.kubernetes.io/router.middlewares: "default-basic-auth-mw@kubernetescrd,default-errors-mw@kubernetescrd,default-pointfile-redirect@kubernetescrd"
    traefik.ingress.kubernetes.io/router.tls: "true"
    traefik.ingress.kubernetes.io/router.entrypoints: "websecure" #serviceのentrypointに合わせる
    #traefik.ingress.kubernetes.io/router.tls.options: "internal-mtls@kubernetescrd"  # ←クライアント証明不要
spec:
  ingressClassName: traefik-internal
  rules:
    - host: my-int.default.svc.cluster.local  # ← 内部向けホスト名に置き換え
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: my-int  # ← 内部用 Service 名
                port:
                  number: 80
  tls:
    - hosts: ["my-int.default.svc.cluster.local"]
      secretName: private-cert   # ← 内部サーバ証明書 Secret 名
middleware抜粋
# =========================
# Basic 認証(Secret + Middleware)
# =========================
apiVersion: v1
kind: Secret
metadata:
  name: basic-auth
  namespace: default
type: kubernetes.io/basic-auth
data:
  username: <base64-username>
  password: <base64-password>
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: basic-auth-mw
  namespace: default
spec:
  basicAuth:
    secret: basic-auth
    removeHeader: true
    realm: "Authentication Required"

そのた

  • networkpolicyがingress-nginxのラベルついてるやつfromで許可してた→traefikのラベルも追加した
    →kubeletからping通らないのでClusterのCIDERのfromから9000許可した
    →LBからping通らないので8443,8000も許可した(8000はsslリダイレクトのために必要)
  • あと正規表現リダイレクトはpathだけでのリダイレクトができなかったのでhttpsから全部書く必要があった
  • SSLリダイレクトのためにhttpの経路の定義もそれぞれ必要だったので設定追加した
  • logにClientIP等出すのに必要なヘッダの定義を追加した( X-Forwarded-Proto: keep、X-Azure-ClientIP: keep、X-Azure-FDID: keep)

以上です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?