3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ROSA で Nginx Ingress Operator を使ってみる

Last updated at Posted at 2023-06-24

はじめに

ROSA(Red Hat OpenShift on AWS) には、標準の Ingress Controller が存在していますが、標準の Ingress の代わりに NginxIngress Operator を使用して、NginxIngress Controller を使用してみます。

ROSA(Red Hat OpenShift on AWS) とは?

ROSA は、Red Hat OpenShiftAWS 上で提供されているマネージド・サービスです。名前のフォーマットは違いますが、簡単に言うと、AKSEKSGKERed Hat 版です。

Red Hat の Kubernetes Districution である OpenShift が使われています。

参考資料

以下の Git Hub のレポを参考にしました。

Nginx Ingress Operator のインストール

Operator Hub より Ingress Operator をインストールします。

image.png

ここは特に何の設定もせず、デフォルのままインストールボタンをクリックします。
image.png

インストール完了です。
image.png

Operatorインストール後の観察

Pod を見てみます。インストールされた Operator が Pod として稼働しています。

$ oc project nginx-ingress
Now using project "nginx-ingress" on server "https://api.f5cluster.m51o.p1.openshiftapps.com:6443".
$ oc get pods
NAME                                                         READY   STATUS    RESTARTS   AGE
nginx-ingress-operator-controller-manager-85b49c485b-p89sp   2/2     Running   0          90s
$ 

今度は Service リソースを見てみます。
名前からして、metrics を提供するもののようです。

$ oc get svc
NAME                                                        TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
nginx-ingress-operator-controller-manager-metrics-service   ClusterIP   172.30.208.138   <none>        8443/TCP   38s
$ 

Nginx Ingress Controller の作成

Nginx Ingress Controller を作成していきます。NginxIngress リソースを作成する事で、Nginx Ingress Controller の Pod が生成されます。

SCC の作成と観察

Ingress Controller の作成前に、OpenShift では、以下の SCC(Security Context Cosntrain) が必要になります。

kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-ingress-helm-operator/main/resources/scc.yaml

一応、apply した yaml の中身を確認しておきます。 nginx-ingress-admin という SCC を作成している事がわかります。

$   curl https://raw.githubusercontent.com/nginxinc/nginx-ingress-helm-operator/main/resources/scc.yaml
# Create SCC for IC resources
kind: SecurityContextConstraints
apiVersion: security.openshift.io/v1
metadata:
  name: nginx-ingress-admin
allowPrivilegedContainer: false
runAsUser:
  type: MustRunAs
  uid: 101
seLinuxContext:
  type: MustRunAs
fsGroup:
  type: MustRunAs
supplementalGroups:
  type: MustRunAs
allowHostNetwork: false
allowHostPID: false
allowHostPorts: false
allowHostDirVolumePlugin: false
allowHostIPC: false
readOnlyRootFilesystem: false
seccompProfiles:    
- runtime/default
volumes:
 - secret
requiredDropCapabilities:
 - ALL
users:
 - 'system:serviceaccount:*:nginx-ingress'
allowedCapabilities:
  - NET_BIND_SERVICE
$ 

NginxIngess リソース (Ingress Controller) の作成

「Nginx Ingress Controller」というタブをクリックして、「Create NginxIngess」をクリックします。
image.png

殺風景ですが、とりあえずデフォルトのままNginxIngress というカスタムリソースを作ります。
image.png

Namespace nginx-ingress 内に nginxingress-sample という名前の NginxIngress リソースが作成されました。
image.png

nginxingress-sample-nginx-ingress-controller-788b95fb47-gdt2j という Pod が新しくできています。名前からもわかるように、この新しくできた Pod(下の行) が Nginx Ingress Controller です。

$  oc get pods
NAME                                                            READY   STATUS    RESTARTS   AGE
nginx-ingress-operator-controller-manager-85b49c485b-p89sp      2/2     Running   0          9m50s
nginxingress-sample-nginx-ingress-controller-788b95fb47-27fcj   1/1     Running   0          6s
$ 

また Serivce も確認してみます。Type=LoadbalancerServiceリソースが作成されています。

$ oc get svc
NAME                                                        TYPE           CLUSTER-IP       EXTERNAL-IP                                                                   PORT(S)                      AGE
nginx-ingress-operator-controller-manager-metrics-service   ClusterIP      172.30.208.138   <none>                                                                        8443/TCP                     15m
nginxingress-sample-nginx-ingress-controller                LoadBalancer   172.30.108.226   a231a916ac00948919cea40dbc043dfd-866973151.ap-northeast-1.elb.amazonaws.com   80:30936/TCP,443:32344/TCP   5m24s
$ 

この Service Type=LoadBalancer をもう少し詳しく見てみましょう。

$ oc describe service nginxingress-sample-nginx-ingress-controller
Name:                     nginxingress-sample-nginx-ingress-controller
Namespace:                nginx-ingress
Labels:                   app.kubernetes.io/instance=nginxingress-sample
                          app.kubernetes.io/managed-by=Helm
                          app.kubernetes.io/name=nginx-ingress
                          app.kubernetes.io/version=3.1.1
                          helm.sh/chart=nginx-ingress-0.17.1
Annotations:              meta.helm.sh/release-name: nginxingress-sample
                          meta.helm.sh/release-namespace: nginx-ingress
Selector:                 app.kubernetes.io/instance=nginxingress-sample,app.kubernetes.io/name=nginx-ingress
Type:                     LoadBalancer
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       172.30.108.226
IPs:                      172.30.108.226
LoadBalancer Ingress:     a231a916ac00948919cea40dbc043dfd-866973151.ap-northeast-1.elb.amazonaws.com
Port:                     http  80/TCP
TargetPort:               80/TCP
NodePort:                 http  30936/TCP
Endpoints:                10.128.2.71:80
Port:                     https  443/TCP
TargetPort:               443/TCP
NodePort:                 https  32344/TCP
Endpoints:                10.128.2.71:443
Session Affinity:         None
External Traffic Policy:  Local
HealthCheck NodePort:     31957
Events:
  Type    Reason                Age   From                Message
  ----    ------                ----  ----                -------
  Normal  EnsuringLoadBalancer  45m   service-controller  Ensuring load balancer
  Normal  EnsuredLoadBalancer   45m   service-controller  Ensured load balancer
$ 

トラフィックの流れは、以下のようになっているようです。
新規に ELB (Classic Load Balancer) が、デプロイされていました。

ELB(NGINX専用) Node Port Pod Network (Ingress Controller Pod)
80/TCP => 30396/TCP => 10.128.2.71:80/TCP
443/TCP => 32344/TCP => 10.128.2.71:443/TCP

この最後の Pod Network の IP (Ednpoint) の持ち主を調べてみると、NginxIngress Controller Pod である事がわかります。

$ oc get endpoints
NAME                                                        ENDPOINTS                        AGE
nginx-ingress-operator-controller-manager-metrics-service   10.131.0.121:8443                59m
nginxingress-sample-nginx-ingress-controller                10.128.2.71:443,10.128.2.71:80   49m
$ 

ここで Nginx Ingress Controller 用に作成されてい ELB は、ROSA のものとは別に専用に作成されていました。(一番上のハイライトした行)
image.png

サンプルのアプリケーションのデプロイ

アプリケーションをデプロイするための 新しいプロジェクト (namespace)、 hello-openshift を作成します。

oc new-project hello-openshift

アプリケーションをデプロイします。

oc new-app --image=docker.io/openshift/hello-openshift  --labels=test=app

Service リソースも作成されている事を確認します。

$ oc get svc
NAME              TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)             AGE
hello-openshift   ClusterIP   172.30.126.194   <none>        8080/TCP,8888/TCP   10s
$ 

Ingress リソースを使ったサンプル・アプリの公開

アプリケーションのプロジェクト(namespace)、hello-openshift 内に Ingress リソースを作成します。

宛先は、先ほど作成された hello-openshift という Service リソースです。

OpenShift は、標準で Ingress リソースRoute リソースも処理できるようになっています。

Nginx Ingress Controller に作成した Ingress リソースを処理させるためには、以下の annotation が必要になるようです。

  annotations:
    kubernetes.io/ingress.class: "nginx"

全体として以下のようになります。

ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  defaultBackend:
    service:
      name: hello-openshift
      port:
        number: 8080
  rules:
  - host: test.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: hello-openshift
            port:
              number: 8080
oc apply -f ingress.yaml

ingress リソースが作成されているのを確認します。

$ oc get ingress
NAME           CLASS    HOSTS              ADDRESS                                                                       PORTS   AGE
test-ingress   <none>   test.example.com   a231a916ac00948919cea40dbc043dfd-866973151.ap-northeast-1.elb.amazonaws.com   80      6s
$ 

-H で Host ヘッダーを test.example.com に偽装してアクセスしてみます。

$  curl -H 'Host:test.example.com' a231a916ac00948919cea40dbc043dfd-866973151.ap-northeast-1.elb.amazonaws.com
Hello OpenShift!
$

無事アクセスできました。

補則 : annotation: kubernetes.io/ingress.class

Ingress リソースに以下の

 annotations:
    kubernetes.io/ingress.class: "nginx"

annoation を付けた場合、Ingress リソース作成時に Nginx Ingress ControllerDeployment のログに、この annotation は DEPRECATED なので、無視されると Warning が出ます。

W0624 05:10:44.855157       1 controller.go:3915] Using the DEPRECATED annotation 'kubernetes.io/ingress.class'. The 'ingressClassName' field will be ignored.

一方で、この annotation を付けないで Ingres リソースを作成した場合、OpenShift の標準の Ingress として処理されるようです。そのため、Nginx Ingress ControllerIngress を処理させたい場合は、annotation を付ける必要がありそうです。

以下の test-ingress は、annotation 付き、 test-ingress2 は、annotation 無しで Ingress リソースを作成した例です。

$ oc get ingress
NAME            CLASS    HOSTS               ADDRESS                                                                       PORTS   AGE
test-ingress    <none>   test.example.com    a231a916ac00948919cea40dbc043dfd-866973151.ap-northeast-1.elb.amazonaws.com   80      59m
test-ingress2   <none>   test2.example.com   router-default.apps.f5cluster.m51o.p1.openshiftapps.com                       80      14s
$ 

annotation の部分と名前以外は同じ Ingressリソースですが、下の方は ROSA の標準のアプリケーションドメインと紐付いている事がわかります。

Nginx Ingress Controller Pod を増やす

デフォルトでは1個の Nginx Ingress ControllerPod がデプロイされます。

冗長化を図るために、Nginx Ingress ControllerPod を2つに増やしてみます。
これは、NginxIngress リソースの replicaCaount 数を編集する事で増やす事ができました。

$ oc get nginxingress 
NAME                  AGE
nginxingress-sample   104m
$

replicaCount を探します。

# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: charts.nginx.org/v1alpha1
kind: NginxIngress
metadata:
  annotations:
    operator-sdk/primary-resource: /nginx
    operator-sdk/primary-resource-type: IngressClass.networking.k8s.io
  creationTimestamp: "2023-06-24T04:00:23Z"
  finalizers:
  - helm.sdk.operatorframework.io/uninstall-release
  generation: 2
  name: nginxingress-sample
  namespace: nginx-ingress
  resourceVersion: "1326212"
  uid: 9f9a09ac-b916-4779-9b6b-a86c688e3105
spec:
  controller:
    affinity: {}
    annotations: {}
    appprotect:
      enable: false

<省略>

    pod:
      annotations: {}
      extraLabels: {}
    podDisruptionBudget:
      annotations: {}
      enabled: false
    readyStatus:
      enable: true
      initialDelaySeconds: 0
      port: 8081
    replicaCount: 2  ## ここを 1=> 2 に増やす
    reportIngressStatus:
      annotations: {}
      enable: true
      enableLeaderElection: true
      ingressLink: ""

<省略>

Ingress ControllerPod が増えました。(下の2行)

$ oc get pods -o wide
NAME                                                            READY   STATUS    RESTARTS   AGE    IP             NODE                                              NOMINATED NODE   READINESS GATES
nginx-ingress-operator-controller-manager-85b49c485b-p89sp      2/2     Running   0          132m   10.131.0.121   ip-10-0-225-101.ap-northeast-1.compute.internal   <none>           <none>
nginxingress-sample-nginx-ingress-controller-788b95fb47-27fcj   1/1     Running   0          123m   10.128.2.71    ip-10-0-225-132.ap-northeast-1.compute.internal   <none>           <none>
nginxingress-sample-nginx-ingress-controller-788b95fb47-rx6gx   1/1     Running   0          13s    10.131.0.136   ip-10-0-225-101.ap-northeast-1.compute.internal   <none>           <none>
$ 

Service Type=LoadBalancer の EndPoint も増えている事が確認できます。

$ oc get svc
NAME                                                        TYPE           CLUSTER-IP       EXTERNAL-IP                                                                   PORT(S)                      AGE
nginx-ingress-operator-controller-manager-metrics-service   ClusterIP      172.30.208.138   <none>                                                                        8443/TCP                     133m
nginxingress-sample-nginx-ingress-controller                LoadBalancer   172.30.108.226   a231a916ac00948919cea40dbc043dfd-866973151.ap-northeast-1.elb.amazonaws.com   80:30936/TCP,443:32344/TCP   123m
$ oc describe svc nginxingress-sample-nginx-ingress-controller
Name:                     nginxingress-sample-nginx-ingress-controller
Namespace:                nginx-ingress
Labels:                   app.kubernetes.io/instance=nginxingress-sample
                          app.kubernetes.io/managed-by=Helm
                          app.kubernetes.io/name=nginx-ingress
                          app.kubernetes.io/version=3.1.1
                          helm.sh/chart=nginx-ingress-0.17.1
Annotations:              meta.helm.sh/release-name: nginxingress-sample
                          meta.helm.sh/release-namespace: nginx-ingress
Selector:                 app.kubernetes.io/instance=nginxingress-sample,app.kubernetes.io/name=nginx-ingress
Type:                     LoadBalancer
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       172.30.108.226
IPs:                      172.30.108.226
LoadBalancer Ingress:     a231a916ac00948919cea40dbc043dfd-866973151.ap-northeast-1.elb.amazonaws.com
Port:                     http  80/TCP
TargetPort:               80/TCP
NodePort:                 http  30936/TCP
Endpoints:                10.128.2.71:80,10.131.0.136:80
Port:                     https  443/TCP
TargetPort:               443/TCP
NodePort:                 https  32344/TCP
Endpoints:                10.128.2.71:443,10.131.0.136:443
Session Affinity:         None
External Traffic Policy:  Local
HealthCheck NodePort:     31957
Events:
  Type    Reason                Age   From                Message
  ----    ------                ----  ----                -------
  Normal  EnsuringLoadBalancer  124m  service-controller  Ensuring load balancer
  Normal  EnsuredLoadBalancer   123m  service-controller  Ensured load balancer
$ 


[おまけ] Routeリソースを使用したサンプル・アプリの公開

今度は同じ Service を、OpenShift の Route リソースで公開できるか確認してみます。
OpenShift の Route リソースは、Ingress の元になった OpenShift 独自の実装です。

アプリケーションのプロジェクト(namespace) hello-openshift 内に Routeリソースを作成します。
Route を使って HTTPで Service を公開する場合は oc expose を使用するのが簡単です。

$ oc expose service  hello-openshift 
route.route.openshift.io/hello-openshift exposed
$ 

作成された Route リソースを確認します。

$ oc get route
NAME              HOST/PORT                                                                  PATH   SERVICES          PORT       TERMINATION   WILDCARD
hello-openshift   hello-openshift-hello-openshift.apps.f5cluster.m51o.p1.openshiftapps.com          hello-openshift   8080-tcp                 None
$ 

アクセスできる確認してみます。特に Hostname を指定しなければ、ROSA のサービスが標準で持っている Red Hat が取得済みのパブリック・ドメインが、ベースのドメインとしてデフォルトで使用されているのがわかります。

curl コマンドでアクセスできる確認してみます。

$ curl http://hello-openshift-hello-openshift.apps.f5cluster.m51o.p1.openshiftapps.com
Hello OpenShift!
$ 

同じ Service に対して、IngressRoute を作成し、それぞれのリソースが公開する URL経由でアクセスできる事が確認できました。

3
2
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
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?