NGINX Ingress Controller Documentation

NGINX Ingress Controller 및 Istio Service Mesh

Istio Service Mesh와 함께 NGINX Ingress Controller를 사용합니다.

이제 NGINX Ingress Controller를 Istio Service Mesh 내에서 실행되는 애플리케이션의 Ingress Controller로 사용할 수 있습니다. 이를 통해 해결 방법에 의존하지 않고 Istio 기반 환경에서 NGINX IC가 제공하는 고급 기능을 계속 사용할 수 있습니다. 이는 Backend에 대한 특수 설정 use-cluster-ip를 사용하여 수행됩니다.

다음은 Sidecar Proxy가 Pod에 주입되지 않은 NGINX Ingress Controller의 표준 배포입니다.

NGINX stand alone.

NGINX Ingress Controller는 Backend 서비스의 Pod을 열거하고 Backend Load Balancer 및 스틱 동작을 완전히 제어할 수 있도록 직접 트래픽 균형을 조정합니다. 서비스 Pod가 TLS를 지원하는 경우 NIC가 TLS에 대한 트래픽을 다시 암호화하고 End-to-End 간 암호화를 제공할 수 있습니다.

그러나 서비스가 이를 수행할 수 있다면 Service Mesh를 구현하지 못할 수도 있습니다.

시작하려면 클러스터에 Istio를 설치해야 합니다.

목차

1. Istio 설치
2. Install NGINX Ingress Controller
3. Istio용 NGINX Plus Ingress Controller 배포 설정
4. 추가 기술 정보 세부 정보

1. Istio 설치

Istio 설치 가이드 링크: istio 설치

NGINX Ingress Controller를 설치하기 전에 Istio를 설치해야 합니다. 이렇게 하면 Istio Sidecar가 NGINX Ingress Controller Pod에 올바르게 삽입됩니다.

선호하는 방법(helm, operator 등)으로 Istio를 설치할 수 있습니다. 이 경우 다음 명령을 실행하여 내 클러스터에 Istio를 설치했습니다.

istioctl install --set profile=minimal

테스트를 위해 Istio가 Sidecar Proxy를 Namespace에 주입하는지 확인해야 합니다. 그렇게 하려면 Sidecar를 삽입할 Namespace를 Istio에 알려야 합니다. 다음 명령으로 그렇게 할 수 있습니다.

kubectl label ns <namespace_specified> istio-injection=enabled

계속 진행하기 전, 그리고 NGINX Ingress Controller를 설치하기 전에 NGINX Ingress Controller Pod가 배포될 때 Sidecar를 주입할 것임을 Istio에 알려야 합니다.

kubectl label namespace nginx-ingress istio-injection=enabled

kubectl을 사용하면 이제 데모(nginx-ingress)의 Namespace에 istio-injection=enabled가 지정되어 있음을 확인할 수 있습니다.

kubectl get namespacess -A --show-labels


default                Active   28h   <none>
istio-system           Active   24h   istio-injection=disabled
kube-node-lease        Active   28h   <none>
kube-public            Active   28h   <none>
kube-system            Active   28h   <none>
kubernetes-dashboard   Active   16h   <none>
local-path-storage     Active   28h   <none>
nginx-ingress          Active   27h   istio-injection=enabled

Istio를 설정하고 구성한 후 Service Mesh의 일부가 될 NGINX Plus Ingress 및 애플리케이션을 배포할 수 있습니다. Istio는 이제 우리가 Istio를 구성한 방식(Namespace 구성)에 따라 Sidecar Proxy를 주입합니다.

아래 이미지는 NGINX Ingress Controller 및 Istio 배포의 모습을 보여줍니다.

NGINX with envoy sidecar.

2. Install NGINX Ingress Controller

Istio가 설치되면 NGINX Ingress Controller를 설치할 수 있습니다.

3. Istio용 NGINX Plus Ingress Controller 배포 설정

Istio와 함께 NGINX Plus Ingress Controller를 배포할 때 Istio와 함께 작동하는 데 필요한 특정 Annotation을 포함하도록 배포 파일을 수정해야 합니다. 이 네 가지 특정 라인은 다음과 같습니다.

traffic.sidecar.istio.io/includeInboundPorts: ""
traffic.sidecar.istio.io/excludeInboundPorts: "80,443" 
traffic.sidecar.istio.io/excludeOutboundIPRanges: "substitute_for_correct_subnet_range"
sidecar.istio.io/inject: 'true'

위의 Annotations에 대한 추가 정보는 Istio의 웹 사이트에서 찾을 수 있습니다. Istio Service Mesh Annotations

업데이트된 nginx-plus-ingress.yaml 파일은 Annotations이 추가된 다음과 같이 표시됩니다.

apiVersion: apps/v1    
kind: Deployment    
metadata:    
  name: nginx-ingress    
  namespace: nginx-ingress    
spec:    
  replicas: 1    
  selector:    
    matchLabels:    
      app: nginx-ingress    
  template:    
    metadata:    
      labels:    
        app: nginx-ingress    
      annotations:    
        traffic.sidecar.istio.io/includeInboundPorts: ""    
        traffic.sidecar.istio.io/excludeInboundPorts: "80,443"    
        traffic.sidecar.istio.io/excludeOutboundIPRanges: "10.90.0.0/16,10.45.0.0/16" 
        sidecar.istio.io/inject: 'true'
NGINX Ingress pod with envoy sidecar.

이제 Istio를 구성한 후 Istio Sidecar Proxy가 NGINX Ingress Controller와 동일한 Pod에 설치되었음을 확인할 수 있습니다. 이제 NGINX Ingress Controller에 대해 동일한 Pod에 NGINX Ingress Controller 컨테이너와 Istio Sidecar Proxy 컨테이너라는 두 개의 컨테이너가 있습니다.

kubectl get pods -A

NAMESPACE       NAME                                      READY   STATUS    RESTARTS   AGE
kube-system     coredns-854c77959c-h2vrq                  1/1     Running   0          60m
kube-system     metrics-server-86cbb8457f-fct86           1/1     Running   0          60m
kube-system     local-path-provisioner-5ff76fc89d-5hjbl   1/1     Running   0          60m
istio-system    istiod-7c9c9d46d4-qpgff                   1/1     Running   0          60m
nginx-ingress   nginx-ingress-5898f94c49-v4jrf            2/2     Running   1          41s

다음은 Istio Service Mesh에 대한 VirtualServer 구성입니다(use-cluster-iprequestHeaders 참조). 다음 설정은 Istio Service Mesh를 사용할 때 필요합니다.

apiVersion: k8s.nginx.org/v1    
kind: VirtualServer    
metadata:    
  name: cafe    
  namespace: nginx-ingress
spec:    
  host: cafe.example.com    
  tls:    
    secret: cafe-secret    
  upstreams:    
  - name: tea    
    service: tea-svc    
    port: 80    
    use-cluster-ip: true
  - name: coffee    
    service: coffee-svc    
    port: 80    
    use-cluster-ip: true
  routes:    
  - path: /tea    
    action:
      proxy:
        upstream: tea
        requestHeaders:
          set:
          - name: Host
            value: tea-svc.nginx-ingress.svc.cluster.local
  - path: /coffee
    action:
      proxy:
        upstream: coffee
        requestHeaders:
          set:
          - name: Host
            value: coffee-svc.nginx-ingress.svc.cluster.local

v1.11의 새로운 호스트 헤더 컨트롤을 사용하면 VirtualServer가 requestHeaders로 구성될 때 지정된 값이 사용되고 proxy_set_header $host는 사용되지 않습니다.

requestHeaders의 값은 <service.namespace.svc.cluster.local>이어야 합니다. 특정 환경에 맞 값을 조정하십시오.

use-cluster-iptrue로 설정되면 NGINX는 요청을 서비스 IP로 전달합니다. 위의 예에서 이는 tea-svccoffee-svc입니다.

다음은 virtualServer/virtualServerRoute에서 현재 upstream 섹션이 어떻게 보이는지에 대한 간단한 예입니다.

upstreams:
  - name: tea
    service: tea-svc
    port: 80
    use-cluster-ip: true
  - name: coffee
    service: coffee-svc
    port: 80
    use-cluster-ip: true

NGINX Ingress upstreamsService/cluster IP로 채워집니다. 위의 예에서 tea-svccoffee-svc에 대한 service/cluster IP는 server 주소로 upstream 구성에 추가됩니다.

이제 애플리케이션에 대한 간단한 curl 요청으로 NGINX Ingress with Istio 설정을 테스트할 수 있습니다.

curl -kI https://cafe.example.com/coffee     

HTTP/1.1 200 OK
Server: nginx/1.19.5
Date: Thu, 25 Mar 2021 18:47:21 GMT
Content-Type: text/plain
Content-Length: 159
Connection: keep-alive
expires: Thu, 25 Mar 2021 18:47:20 GMT
cache-control: no-cache
x-envoy-upstream-service-time: 0
x-envoy-decorator-operation: coffee-svc.nginx-ingress.svc.cluster.local:80/*

위 Output에서 curl 요청이 NGINX Ingress Controller에 의해 전송되고 수신되는 것을 볼 수 있습니다. 특사 Sidecar Proxy가 서비스 IP에 대한 요청을 애플리케이션(coffee)으로 보내는 것을 볼 수 있습니다. 전체 요청이 완전하고 정확합니다. 이제 Sidecar Proxy가 배포됨에 따라 Istio와 함께 완전히 작동하는 NGINX+ Ingress가 있습니다.

4. 추가 기술 정보 세부 정보

기본적으로 NGINX Ingress Controller의 경우 upstream 서버 주소를 Pod의 End-to-End IP로 채웁니다.

새로운 use-cluster-ip 기능을 사용할 때 Endpoint IP 주소 대신 service IP 주소로 upstream을 채우지 않습니다.

1.11 릴리스에서 NGINX Ingress Controller는 Ingress 구성 방법에 따라 하나의 호스트 헤더만 보냅니다. 기본적으로 NGINX Ingress Controller는 proxy_set_header $host를 보냅니다. Ingress가 action.proxy.requestHeaders로 구성된 경우 하나의 헤더 세트만 upstream 서버로 전송됩니다. 요약하면 VirtualServer CRD에서 action.proxy.requestHeaders를 설정하면 NGINX Ingress는 정의된 특정 헤더만 전송합니다.

다음은 upstream 및 proxy_set_header 값을 표시하는 nginx -T의 출력입니다.

upstream 서버 IP 주소는 해당 애플리케이션에 대한 서비스의 IP 주소입니다.

upstream vs_nginx-ingress_cafe_tea {
    zone vs_nginx-ingress_cafe_tea 256k;
    random two least_conn;
    server 10.96.222.104:80 max_fails=1 fail_timeout=10s max_conns=0;
}

upstream vs_nginx-ingress_cafe_coffee {
    zone vs_nginx-ingress_cafe_coffee 256k;
    random two least_conn;
    server 10.96.252.249:80 max_fails=1 fail_timeout=10s max_conns=0;
}

server {
    listen 80;
        
    location /tea {

        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $vs_connection_header;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Port $server_port;
        proxy_set_header X-Forwarded-Proto $scheme;
            
        proxy_set_header Host "tea-svc.nginx-ingress.svc.cluster.local";
    }
    
    location /coffee {
 
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $vs_connection_header;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Port $server_port;
        proxy_set_header X-Forwarded-Proto $scheme;
            
        proxy_set_header Host "coffee-svc.nginx-ingress.svc.cluster.local";
    }   
}