kubernetesにあるIngress Controllerの一覧を挙げてみる

# はじめに

Ingress ControllerはL7 Load Balancerの機能を果たすものであり、Ingressリソースはそのルールを定義したものです。このIngress Controllerを実際に実装したものは数多作られており、環境によって、大なり小なり記述方法が違ったり、特性が違ったりしています。

そんな中で、本日はそれぞれのIngress ControllerをIntroできればと思います。 [^1]

# Ingress Controllers

## kubernetes/ingress-nginxとnginxinc/kubernetes-ingress with NGINX

Nginxを利用したIngressには2つの種類があります。Kubernetes Community管理の[kubernets/ingress-nginx](https://github.com/kubernetes/ingress-nginx)とNGINX社とそのCommunityが管理する[nginxinc/kubernetes-ingress](https://github.com/nginxinc/kubernetes-ingress)です。

下記にそれぞれの違いを挙げています。正確な情報としては[Differences Between nginxinc/kubernetes-ingress and kubernetes/ingress-nginx Ingress Controllers](https://github.com/nginxinc/kubernetes-ingress/blob/master/docs/nginx-ingress-controllers.md)を参照ください。

| 特徴 | kubernetes/ingress-nginx | nginxinc/kubernetes-ingress with NGINX | nginxinc/kubernetes-ingress with NGINX Plus |
| --- | --- | --- | --- |
| **基本機能** |
| 作者 | Kubernetes community | NGINX Inc and community |  NGINX Inc and community |
| NGINバージョン | [Custom](https://github.com/kubernetes/ingress-nginx/tree/master/images/nginx) NGINX build that includes several third-party modules | NGINX official mainline [build](https://github.com/nginxinc/docker-nginx) | NGINX Plus |
| 商用サポート | N/A | N/A | 含まれている |
| **LB設定** |
| 同一ホストに複数のIngressルールをマージする | 利用可 | 利用可 | 利用可 |
| HTTP load balancing extensions - Annotations | [supported annotations](https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/nginx-configuration/annotations.md)を参照 | [supported annotations](configmap-and-annotations.md)を参照  | [supported annotations](configmap-and-annotations.md)を参照 |
| HTTP load balancing extensions -- ConfigMap | [supported ConfigMap keys](https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/nginx-configuration/configmap.md)を参照 | [supported ConfigMap keys](configmap-and-annotations.md)を参照 | [supported ConfigMap keys](configmap-and-annotations.md)を参照 |
| TCP/UDP | ConfigMap経由 | ネイティブのNGINX設定によるConfigMap経由| ネイティブのNGINX設定によるConfigMap経由 |
| Websocket  | 利用可 | [annotation](https://github.com/nginxinc/kubernetes-ingress/tree/master/examples/websocket)経由で利用可 | [annotation](https://github.com/nginxinc/kubernetes-ingress/tree/master/examples/websocket)経由で利用可 |
| TCP SSLパススルー | ConfigMap経由で利用可 | 利用不可 | 利用不可 |
| JWT validation | 利用不可 | 利用不可 | 利用可 |
| セッション管理 | サードパーティモジュール経由で利用可 | 利用不可 | 利用可 |
| Configurationテンプレート | [template](https://github.com/kubernetes/ingress-nginx/blob/master/rootfs/etc/nginx/template/nginx.tmpl)を参照 | [templates](https://github.com/nginxinc/kubernetes-ingress/tree/master/internal/nginx/templates)を参照 | [templates](https://github.com/nginxinc/kubernetes-ingress/tree/master/internal/nginx/templates)を参照 |
| **デプロイ** |
| Command-line引数 | [arguments](https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/cli-arguments.md)を参照 | [arguments](cli-arguments.md)を参照 |[arguments](cli-arguments.md)を参照 |
| デフォルトサーバの為のTLS証明書と鍵 | command-line引数(必要に応じて)/ 自動生成 | command-line引数(必要に応じて) | command-line引数(必要に応じて) |
| Helmチャート | 利用可 | 利用可 | 利用可 |
| **運用** |
| 拡張ステータス | サードパーティのモジュール経由 | 利用不可 | 利用可 |
| エンドポイントの動的再設定(設定の再リロードはしない) | サードパーティのLuaモジュールによって利用可 | 利用不可 | 利用可 |

## Contour

ContourはEnvoyをデプロイするすることによって動作するIngress Controllerです。Traefikと同様に動的なコンフィギュレーションの更新をサポートしているのが特徴の一つかなと思います。

また、Custom Resource Definition（CRD）によって新たに実装されたIngress API（IngressRoute）も利用することで既存のIngress APIの機能を拡張しているなどの特徴があります。

その他の特徴として、

- WebSocket対応
- ヘルスチェック
- 5種類のLB algorithm(RoundRobin, WeightedLeastRequest, RingHash, Maglev, Ramdom)

また、IngressRouteの特徴としては以下のような感じになります。

- namespaceのVirtual hostsとTLS証明書の設定可否を制限する機能
- パスorドメインルーティングを別のnamespaceに委譲機能
- 単一のルート内での複数のServiceの受け入れとトラフィックの負荷分散
- annotationなしでのServiceの重み付けとロードバランシング
- 作成時のIngressRouteのバリデーションと作成後のステータスレポート

標準のIngressとの比較は次のようになります。そこまで大きな記述差はないと言った印象です。

```yaml:ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: basic
spec:
  rules:
  - host: foo-basic.bar.com
    http:
      paths:
      - backend:
          serviceName: s1
          servicePort: 80
```

```yaml:ingressroute.yaml
apiVersion: contour.heptio.com/v1beta1
kind: IngressRoute
metadata:
  name: basic
spec:
  virtualhost:
    fqdn: foo-basic.bar.com
  routes:
    - match: /
      services:
        - name: s1
          port: 80
```


## Traefik

TraefikはContainous社が手掛けるHTTPリバースプロキシ/ロードバランサで、Docker Swarm、kubernetesやMarathonなどのオーケストレータに組み込むことができます。他のIngressと違い、Circuit breakersやWeb UIを備えていたりします。

ちなみに、2018/12/11に、エンタープライズ版である[TraefikEE](https://blog.containo.us/introducing-traefik-enterprise-edition-83b78d09efeb)がpublic beta版として登場したようです。TraefikEEのクラスタ化において、TraefikEEはkubernetesのetcdのクラスタ化に使用される分散合意アルゴリズムであるRaftを使用しているそうです。これによって、TLS証明書と設定を安全に管理し、複製することができます。こちらはOSS版よりもより、HAや鍵の分散管理など分散アーキテクチャを強化しており、可用性やスケーラビリティ、安全性を確保するのに特化したみたいです。^

TraefikEEではdata planeとcontrol planeでノードを管理するみたいですね。
Istioのデジャヴを何か感じます。。。

Traefikでは`Deployment`若しくは`DeamonSet`にて、デプロイすることができます。
以下にそのサンプルを上げておきます。

```yaml:traefik-deployment.yaml
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: traefik-ingress-controller
  namespace: kube-system
---
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: traefik-ingress-controller
  namespace: kube-system
  labels:
    k8s-app: traefik-ingress-lb
spec:
  replicas: 1
  selector:
    matchLabels:
      k8s-app: traefik-ingress-lb
  template:
    metadata:
      labels:
        k8s-app: traefik-ingress-lb
        name: traefik-ingress-lb
    spec:
      serviceAccountName: traefik-ingress-controller
      terminationGracePeriodSeconds: 60
      containers:
      - image: traefik
        name: traefik-ingress-lb
        ports:
        - name: http
          containerPort: 80
        - name: admin
          containerPort: 8080
        args:
        - --api
        - --kubernetes
        - --logLevel=INFO
---
kind: Service
apiVersion: v1
metadata:
  name: traefik-ingress-service
  namespace: kube-system
spec:
  selector:
    k8s-app: traefik-ingress-lb
  ports:
    - protocol: TCP
      port: 80
      name: web
    - protocol: TCP
      port: 8080
      name: admin
  type: NodePort
```


Deploymentからデプロイする代わりに、以下のように入力することで、
`stable/traefik`のHelmチャートを利用することができます。

```bash
helm install stable/traefik
```


## Other Controllers

上記に挙げなかったIngress Controllerを以下に列挙します。

### F5 BIG-IP Controller for Kubernetes

ロードバランサの老舗であるF5のIngress Controller。サイトにある特徴を以下に列挙します。

- 動的にBIG-IPオブジェクトの作成、管理、削除ができる
- NodePortもしくはClusterIPを経由で、BIG-IPデバイスからKubernetesクラスタにトラフィックを転送する
- F5 iAppsのサポート
- kubernetesによって作られたF5特有のVirtualServerオブジェクトを処理する
- F5特有の拡張機能の使用で、標準Kubernetes Ingressを処理する

詳しくは[F5 BIG-IP Controller for Kubernetes](https://clouddocs.f5.com/products/connectors/k8s-bigip-ctlr/v1.7/)をご参照ください。

### Kong Ingress Controllerfor Kubernetes

Kongの特徴を以下に挙げます。

- Kongの設定にIngressの使用
- ロードバランスしとアクティブ＆パッシブヘルスチェックのサポート
- リクエストがサービスにプロキシされる際に、カスタムコードを実行する
- プラグインを使用することで、リクエスト/レスポンスを即座に変更可能
- 認証プラグインを使用してのサービス保護
- CRDを使用するKongの設定と宣言的なKongの管理

詳しくはGithubのレポジトリ[Kong/kubernetes-ingress-controller](https://github.com/Kong/kubernetes-ingress-controller)をご参照ください。

### nghttpx Ingress Controller

ZLab様による[zlabjp/nghttpx-ingress-lb](https://github.com/zlabjp/nghttpx-ingress-lb)はHTTP/2に対応したIngress ControllerでNginx Ingress Controllerをベースとして作られています。

### HAProxy

多機能なプロキシサーバとして有名なHAProxyをIngress Controllerとして利用したのが、[jcmoraisjr/haproxy-ingress](https://github.com/jcmoraisjr/haproxy-ingress)になります。



## GKE

GKEでは専用のIngress Controllerが既にデプロイされている為、省略。

# おわりに

きれいにまとめることができませんでしたが、皆様の新たな
情報収集としてお役に立てればと思います。

何かご指摘あればコメントにてよろしくお願いします。

今年も残りわずか、メリクリスマス。

# 参考文献

[Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress)
[Traefik Documentation](https://docs.traefik.io/)
[Differences Between nginxinc/kubernetes-ingress and kubernetes/ingress-nginx Ingress Controllers](https://github.com/nginxinc/kubernetes-ingress/blob/master/docs/nginx-ingress-controllers.md)
[[Kubernetes] オンプレでも GKE Like な Ingress を使うために 自作 Ingress Controller を実装してみた](https://adtech.cyberagent.io/techblog/archives/3758)

[^1]: ドキュメント量的に、時間を取らなかった事を大いに反省しています。