Ingressの概要
manifestのリソース指定:
kind: Ingress
Ingressはk8sクラスタにL7のロードバランシングなどの機能を提供します。
IngressはIngressを提供するIngress Controllerを使う必要があります。
よく使われているのは、GKE Ingress ControllerとNginx Ingress Controllerです。
- GKE Ingress Controller(外部リソース)
- k8sクラスタ外のロードバランサーを利用
- 裏では、GCEを作成され、Ingress Controllerの役割になるみたい
- k8sクラスタ外のロードバランサーを利用
- Nginx Ingress Controller(内部リソース)
- k8sクラスタ内にIngress用Podをデプロイして利用
- Nginx Ingress
- Nghttpx Ingress
- k8sクラスタ内にIngress用Podをデプロイして利用
それぞれの動きが異なります。
- 外部リソース(GCPクラウド):クライアント → 外部L7ロードバランサー → 転送先Pod
- この場合、Ingressの立場はLoadBalancer Serviceとほとんど変わらない
- k8sのServiceではないため、NodePort Service は事前に作成する必要がある
- 内部リソース(Nginx):クライアント → LoadBalancer(L4) → Nginx Pod → 転送先Pod
トラフィックの流れは文字だけではわかりにくいので、GCPのIngress場合のイメージ図を作成しました。
Ingressの機能
Ingressが実現できる機能は以下になります。
- URLのpathベースのトラフィック転送
- 例:
www.bar.com/site01
とwww.bar.com/site02
の/site0X
部分で違うNodePortへ転送させる - manifest設定:
spec.roles[].http.paths[].path
- 例:
- URLのhost名ベースのトラフィック転送:DNSの登録が必要
- 例:
www.bar.com/site01
とwww.foo.com/site01
のwww.XXX.com
部分で違うNodePortへ転送させる - manifest設定:
spec.roles[].host
- 例:
- TLS(SSL)の実装:
- 証明書を持たせることが可能(暗号化通信)
- 証明書はsecretとして作成し、Ingressに関連付けます。
- 複数証明書搭載可能
- ポート443(HTTPS)のみサポート
- HTTPのブロッキング機能
- annotationsの設定でHTTPを受け付けさせないことが可能
- 設定:
annotations.kubernetes.io/ingress.allow-http: "false"
- アクセスすると、404で返ってくる
- 設定:
- annotationsの設定でHTTPを受け付けさせないことが可能
- 証明書を持たせることが可能(暗号化通信)
- ロードバランサー
- ヘルスチェック
Ingressの実装
IngressはLoadbalancerと違って、NodePortは自動的に作成してくれません。
そのため、Ingressと紐づくためのNodePortを作成する必要があります。
IngressとNodePortを紐づく条件
- Ingressの
spec.rules[].http.paths[].backend.servicePort
が、NodePortのspec.ports[].port
が一致であること - Ingressの
spec.rules[].http.paths[].backend.serviceName
が、NodePortのmetadata.name
が一致であること
IngressはkubernetesのService(NodePort)と紐づくことで使用します。
Ingressのmanifest例
# NodePort作成
apiVersion: v1
kind: Service
metadata:
name: my-nodeport-01
spec:
type: NodePort
selector:
app: MyApp
ports:
- port: 8080
targetPort: 80
nodePort: 30080
---
# NodePort作成
apiVersion: v1
kind: Service
metadata:
name: my-nodeport-02
spec:
type: NodePort
selector:
app: MyApp
ports:
- port: 8081
targetPort: 80
nodePort: 30081
---
# Ingress作成
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: my-ingress
spec:
rules:
- host: foo-bar.com # hostは、公開用のFQDN、証明書などと併用の場合に使う、持ってない場合省略しよう
http:
paths:
- path: /foo
backend: # NodePortと紐づく
serviceName: my-nodeport-01 # NodePort名を指定
servicePort: 8080 # NodePortのPortを指定
- path: /bar
backend: # NodePortと紐づく
serviceName: my-nodeport-02
servicePort: 8081
参考:
GCPでIngressに静的IP降りたい場合
以下を満たす必要があります。
- Ingressの
apiVersion:
をextensions/v1beta1
にする annotations.kubernetes.io/ingress.global-static-ip-name
に事前に作成した静的IP(Global IP)のリソース名を指定する- リージョン IP アドレスは Ingress では機能しませんので、グローバルで作成する必要がある(プレミアム)
Ingressのbackend
Ingressのbackendは2種類あります。
- rulesで定義するbackend:ルールに従って転送する
- デフォルトのbackend:ルールに書いていないトラフィックの転送先
- デフォルトbackendを定義しない場合:
- GCPの場合、勝手にbackendが作成されるが、そのbackendは404が返ってくるように作成される
- デフォルトbackendを定義しない場合:
なので、GCPでIngressを作成する際に、backendは1個しか定義していないのに、2個作成されたときに仕様通りなので、ご安心ください。
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: my-ingress
spec:
backend: # デフォルトのbackendの定義。※ GCPの場合、省略しても作成される
serviceName: def-backend
servicePort: 80
rules: # rulesで定義するbackend
- host:
http:
paths:
- path: /foo
backend:
serviceName: my-nodeport-01
servicePort: 8080
- path: /bar
backend:
serviceName: my-nodeport-02
servicePort: 8081
Ingressのヘルスチェック
ここは結構ハマったところでした。
Loadbalancerは基本200~399の範囲のステータスコードは全部健全(ヘルス)と判断してくれますが、Ingressは200しか受け付けません。
しかも、デフォルトではサイトの/
ディレクトリにリクエストを投げます。
多くのアプリはサイトの/
ディレクトリはリダイレクトするようになるので、302が返ってくることが多いですが、これはIngressでは通信不可と判断してしまいます。
対処方法については、Podに事前にヘルスチェックのファイルを置いて(例えば/healthz)、Podのヘルスチェック(readinessProbe
)をIngress作成する前に用意することです。
ポイントは:
- Podに200で応答してくるページを用意
- Podのヘルスチェック定義を入れる:
readinessProbe
のhttpGet
- Ingress作成する前に上記を済ませる(或いはIngress再作成でも可)
最後に
今回は以前説明できなかったIngressについて、更新しました。
実際に作ってみて、色々調査しながら、この記事を成し遂げました。
作ってみたものも記事にしているので、興味ある方はぜひ参考にしていただければと思います。
Discovery & LBリソースの中でも、あんまり使わないものがあります。
個人的によく使うのは以下ですかね。
- Service
- ClusterIP
- NodePort(Ingressと併用するために)
- LoadBalancer
- Headless(None)(StatefulSetと併用するために)
- ExternalName
- Ingress
ここまで読んでいただいて、お疲れ様でした。
コメント