Ingress 활용 예제
    • PDF

    Ingress 활용 예제

    • PDF

    기사 요약

    Ncloud Kubernetes Service(VPC) 시작에서 소개한 Kubectl CLI를 통해 Ingress를 배포하고 라우팅을 수행하는 예제입니다.

    Kubernetes에서 Ingress는 클러스터 외부의 요청을 Ingress 리소스에 정의된 규칙에 따라 클러스터 내부의 서비스로 연결합니다. Ingress에 대한 자세한 설명은 Ingress를 참고해 주십시오.


    Kubectl을 통한 Ingress 배포 예제

    Kubectl을 통해 Ingress를 배포하고 Ingress 서비스를 생성하는 예제는 다음과 같습니다.

    1. 아래 명령어를 실행하여 ingress-nginx를 설치해 주십시오.

      $ kubectl --kubeconfig $KUBE_CONFIG apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.11.2/deploy/static/provider/cloud/deploy.yaml
      
    2. 아래 명령어를 실행하여 ingress-nginx 파드의 상태를 확인해 주십시오.

      $ kubectl --kubeconfig $KUBE_CONFIG get pods -n ingress-nginx
      NAME                                       READY   STATUS      RESTARTS   AGE
      ingress-nginx-admission-create-wnkkp       0/1     Completed   0          4m32s
      ingress-nginx-admission-patch-rw4f2        0/1     Completed   0          4m32s
      ingress-nginx-controller-fd7bb8d66-wzfkd   1/1     Running     0          4m32s
      
    3. 아래 명령어를 실행하여 LoadBalancer의 생성 여부를 확인해 주십시오.

    • Load Balancer의 생성이 완료되면 EXTERNAL-IP의 값이 pending에서 실제 IP 주소로 변경됩니다.
      $ kubectl --kubeconfig $KUBE_CONFIG get svc -n ingress-nginx
      NAME                                 TYPE           CLUSTER-IP      EXTERNAL-IP       PORT(S)                      AGE
      ingress-nginx-controller             LoadBalancer   10.233.38.219   [nginx_address]   80:30033/TCP,443:31110/TCP   39s
      ingress-nginx-controller-admission   ClusterIP      10.233.33.133   <none>            443/TCP                      39s
      

    라우팅 예제

    라우팅 예제에서는 서로 다른 정보를 가진 예제용 Deployment와 Service를 사용합니다. 예제용 Deployment들은 자신의 호스트 정보를 표시하기 위한 nginx container이며, 예제용 Service들은 NodePort 타입으로 생성된 Service 들입니다.

    1. 아래 명령어를 사용하여 예제용 Deployment와 Service를 생성해 주십시오.

      kubectl --kubeconfig $KUBE_CONFIG apply -f https://raw.githubusercontent.com/NaverCloudPlatform/nks-alb-ingress-controller/main/docs/examples/fin/nks-alb-ingress-sample-services.yaml
      
    2. 아래 명령어를 실행하여 예제용 Deployment와 Service의 상태를 확인해 주십시오.

      $ kubectl --kubeconfig $KUBE_CONFIG get pods
      NAME                              READY   STATUS    RESTARTS   AGE
      cloud-8569cb49bf-k2787            1/1     Running   0          18s
      naver-7d855c949f-2wc2l            1/1     Running   0          18s
      platform-68754dccf9-8wqng         1/1     Running   0          18s
      
      $ kubectl --kubeconfig $KUBE_CONFIG get svc
      NAME              TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
      cloud             NodePort    10.233.6.109    <none>        80:31234/TCP   69s
      naver             NodePort    10.233.29.211   <none>        80:31411/TCP   69s
      platform          NodePort    10.233.2.191    <none>        80:31928/TCP   69s
      
    3. 아래 명령어를 실행하여 ingress-nginx의 로드밸런서 접속 정보를 저장합니다.

      $ export nginx_address=$(kubectl --kubeconfig $KUBE_CONFIG get svc -n ingress-nginx ingress-nginx-controller -o jsonpath='{.status.loadBalancer.ingress[*].hostname}')
      $ echo $nginx_address
      

    URI 기반 라우팅 예제

    생성한 Ingress Service의 EXTERNAL IP에 표시되는 path별로 라우팅하여 /naver, /cloud, /platform으로 요청할 때 각각 다른 서비스로 연결되도록 설정할 수 있습니다.

    URI 기반 라우팅 예제는 다음과 같습니다.

    1. 아래와 같이 Ingress의 리소스를 각 path에 따라 다른 backend를 갖도록 설정하여 파일로 저장해 주십시오.

      apiVersion: networking.k8s.io/v1
      kind: Ingress
      metadata:
        name: path-ingress
        annotations:
          nginx.ingress.kubernetes.io/rewrite-target: /
          nginx.ingress.kubernetes.io/ssl-redirect: "false"
      spec:
        ingressClassName: nginx
        rules:
        - http:
            paths:
            - path: /naver
              pathType: Prefix
              backend:
                service:
                  name: naver
                  port:
                    number: 80
            - path: /cloud
              pathType: Prefix
              backend:
                service:
                  name: cloud
                  port:
                    number: 80
            - path: /platform
              pathType: Prefix
              backend:
                service:
                  name: platform
                  port:
                    number: 80
      
    2. 아래 명령어를 실행하여 Ingress를 생성해 주십시오.

      $ kubectl --kubeconfig $KUBE_CONFIG apply -f ./path-ingress.yaml
      
      주의

      예제에서는 TLS 설정을 하지 않았기 때문에 강제 리다이렉션을 막기 위해서 Ingress의 어노테이션에 nginx.ingress.kubernetes.io/ssl-redirect: "false"를 추가하였습니다. 만약 TLS를 설정할 시에는 해당 어노테이션은 제거하십시오.

    3. 아래 명령어를 실행하여 생성된 Ingress를 확인해 주십시오.

      $ kubectl --kubeconfig $KUBE_CONFIG get ingress
      NAME           CLASS   HOSTS   ADDRESS            PORTS   AGE
      path-ingress   nginx   *       [nginx_address]    80      7s
      
    4. 아래 예시와 같이 브라우저 또는 curl을 통해 접속 결과를 확인하여 각자 다른 Service의 Pod로 접근하는 것을 확인해 주십시오.

      $ curl $nginx_address/naver
      Server address: 198.18.2.178:80
      Server name: naver-7d855c949f-hsf8q
      Date: 24/May/2022:09:17:23 +0000
      URI: /
      Request ID: dcf54d3b841e06733ae75cc08dc922d0
      
      $ curl $nginx_address/cloud
      Server address: 198.18.2.32:80
      Server name: cloud-8569cb49bf-przrt
      Date: 24/May/2022:09:17:26 +0000
      URI: /
      Request ID: 461db9ee32dc3a5e1452b426da88fce8
      
      $ curl $nginx_address/platform
      Server address: 198.18.3.182:80
      Server name: platform-68754dccf9-7przv
      Date: 24/May/2022:09:17:31 +0000
      URI: /
      Request ID: 47ae775498a2dad86ab9c9fd0ca58537
      

    호스트 기반 라우팅 예제

    동일한 EXTERNAL-IP에 대해 각각 다른 도메인으로 요청 시 각각 다른 서비스로 연결되도록 설정할 수 있습니다.

    호스트 기반 라우팅 예제는 다음과 같습니다.

    1. 아래와 같이 Ingress의 리소스를 각 host에 따라 다른 backend를 갖도록 설정하여 파일로 저장해 주십시오.

      • 아래 예시에서는 svc.naver.com으로 요청할 경우 naver로, svc.cloud.com으로 요청할 경우 cloud로, 기본 요청의 경우 platform으로 연결하도록 설정합니다.
      apiVersion: networking.k8s.io/v1
      kind: Ingress
      metadata:
        name: host-ingress
        annotations:
          nginx.ingress.kubernetes.io/rewrite-target: /
          nginx.ingress.kubernetes.io/ssl-redirect: "false"
      spec:
        ingressClassName: nginx
        rules:
        - host: "svc.naver.com"
          http:
            paths:
            - path: /
              pathType: Prefix
              backend:
                service:
                  name: naver
                  port:
                    number: 80
        - host: "svc.cloud.com"
          http:
            paths:
            - path: /
              pathType: Prefix
              backend:
                service:
                  name: cloud
                  port:
                    number: 80
        - http:
            paths:
            - path: /
              pathType: Prefix
              backend:
                service:
                  name: platform
                  port:
                    number: 80
      
    2. 아래 명령어를 실행하여 Ingress를 생성해 주십시오.

      $ kubectl --kubeconfig $KUBE_CONFIG apply -f ./host-ingress.yaml
      
    3. 아래 명령어를 실행하여 생성된 Ingress를 확인해 주십시오.

      $ kubectl --kubeconfig $KUBE_CONFIG get ingress
      NAME           CLASS   HOSTS   ADDRESS            PORTS   AGE
      host-ingress   nginx   *       [nginx_address]    80      15s
      
    4. 아래 예시와 같이 curl 명령에 -H host 옵션을 추가한 후 호스트별 접속 결과를 확인하여 각자 다른 서비스로 연결되는지 확인해 주십시오.

      $ curl -H host:svc.naver.com $nginx_address
      Server address: 198.18.2.178:80
      Server name: naver-7d855c949f-hsf8q
      Date: 24/May/2022:09:25:40 +0000
      URI: /
      Request ID: f5cb5e2f152367632ebecc9dd2ef2942
      
      $ curl -H host:svc.cloud.com $nginx_address
      Server address: 198.18.2.32:80
      Server name: cloud-8569cb49bf-przrt
      Date: 24/May/2022:09:25:50 +0000
      URI: /
      Request ID: e9203271c73a8d7e908fc5bf8613850f
      
      $ curl $nginx_address
      Server address: 198.18.3.182:80
      Server name: platform-68754dccf9-7przv
      Date: 24/May/2022:09:25:56 +0000
      URI: /
      Request ID: 751e0dc1e99b79495ada5dbb06d92c4a
      
    참고
    • 위 예제에서 호스트로 설정한 도메인은 실제로는 존재하지 않는 도메인이므로 실행하기 위해서는 curl 명령에 -H host 옵션이 포함되어야 합니다.

    • ingress-nginx에서는 이름에 _ (언더스코어)가 있는 Request Header는 강제로 삭제하므로, 해당 Request Header는 서버에서 확인할 수 없습니다. 이를 회피하기 위해서는 ConfigMap에 enable-underscores-in-headers: true를 추가하여 언더스코어 사용을 허용하도록 설정해야 합니다.

    참고

    Load Balancer에서 ingress-nginx Pod가 없는 노드는 헬스 체크에 실패한 것으로 표시됩니다.


    위 예시로 ingress-nginx Service를 생성한 경우 Service .spec.externalTrafficPolicy: Local 설정을 확인할 수 있습니다. .spec.externalTrafficPolicy는 서비스에서 외부 트래픽을 라우팅하는 설정으로, ClusterLocal 값을 사용할 수 있습니다.


    Cluster의 경우 외부 트래픽을 전체 Pod에 분산합니다. 다른 Node에 있는 Pod로 전달할 때 두 번째 홉을 유발할 수 있지만, Pod로의 트래픽은 균형있게 분산할 수 있습니다.
    Local의 경우 외부 트래픽을 로컬 Node에 있는 Pod로만 전달합니다. 다른 Node에 대한 두 번째 홉을 피하지만 불균형한 트래픽 분산이 발생할 수 있습니다.


    ingress-nginx Service의 설정이 .spec.externalTrafficPolicy: Local로 되어 있다면 ingress-nginx Pod가 동작 중인 노드만 트래픽이 전달되므로 그 외의 서버는 Health Check에 실패하는 것으로 표시됩니다.


    동작에 대한 보다 자세한 내용은 Using Source IP에서 확인할 수 있습니다.


    이 문서가 도움이 되었습니까?

    Changing your password will log you out immediately. Use the new password to log back in.
    First name must have atleast 2 characters. Numbers and special characters are not allowed.
    Last name must have atleast 1 characters. Numbers and special characters are not allowed.
    Enter a valid email
    Enter a valid password
    Your profile has been successfully updated.