NGINX Ingress Controller를 통한 IP 액세스 제어

7032 단어 AzureAKSkubernetes
Kubernetes (AKS)에 여러 웹 응용 프로그램이 배포되었으며 각각에 대해 특정 IP 주소에서만 액세스를 허용하는 방법을 시도했습니다.

대략적인 절차는 아래와 같습니다.
  • 사전 준비로 Helm에서 Ingress Controller를 배포합니다.
  • 액세스 제어로 화이트리스트가 지정된 Ingress 리소스를 배포합니다.

  • 사전 준비



    Helm 설치



    공식 단계에 따라 설치합니다.
    sudo apt-get update
    curl https://helm.baltorepo.com/organization/signing.asc | sudo apt-key add -
    sudo apt-get install apt-transport-https --yes
    echo "deb https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
    sudo apt-get update
    sudo apt-get install helm
    

    Ingress Controller 배포



    Ingress용 namespace를 만들어 둡니다.
    kubectl create namespace ingress-basic
    

    Helm에서 NGINX Ingress Controller를 배포합니다. AKS의 공식 순서에서는 nodeSelector를 지정하고 있습니다만, Node의 종류가 복수 있는 것은 아니기 때문에 생략해, 복제도 1로 줄이고 있습니다.

    또한이 때 externalTrafficPolicy = Local을 지정하는 것이 중요합니다. 이렇게하면 요청의 소스 IP를 처리 할 수 ​​있습니다. 지정하지 않으면 소스 IP를 통한 액세스 제어가 불가능합니다.
    helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
    helm repo update
    
    helm install nginx-ingress ingress-nginx/ingress-nginx \
        --namespace ingress-basic \
        --set controller.replicaCount=1 \
        --set controller.service.externalTrafficPolicy=Local
    

    배포된 리소스를 확인해 봅니다.
    kubectl --namespace ingress-basic get deployments
    
    NAME                                     READY   UP-TO-DATE   AVAILABLE   AGE
    nginx-ingress-ingress-nginx-controller   1/1     1            1           17h
    
    kubectl --namespace ingress-basic get services
    
    NAME                                               TYPE           CLUSTER-IP    EXTERNAL-IP   PORT(S)                      AGE
    nginx-ingress-ingress-nginx-controller             LoadBalancer   10.0.190.67   xx.xx.xx.xx   80:31238/TCP,443:32076/TCP   17h
    nginx-ingress-ingress-nginx-controller-admission   ClusterIP      10.0.155.88   <none>        443/TCP                      17h
    

    검증용 애플리케이션 배포



    두 개의 네임 스페이스를 만들고 각각 웹 서버 포드를 시작하고 서비스에서 클러스터에 게시합니다.
    kubectl create namespace app1
    kubectl create namespace app2
    kubectl -n app1 run webapp1 --image=nginx
    kubectl -n app2 run webapp2 --image=httpd
    kubectl -n app1 expose pod webapp1 --port=80
    kubectl -n app2 expose pod webapp2 --port=80
    

    액세스 제어 설정



    Ingress 리소스 배포



    각 네임스페이스에 웹 서버 서비스로의 라우팅을 정의한 Ingress를 만듭니다. 이 때 annotations의 whitelist-source-range에서 소스 IP의 화이트리스트를 지정할 수 있습니다.

    참고로 spec.rules의 backend.service.name에서는 Service FQDN을 지정할 수 없습니다. 따라서 Ingress를 만드는 네임스페이스는 Service와 같아야 합니다.
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      annotations:
        kubernetes.io/ingress.class: nginx
        nginx.ingress.kubernetes.io/rewrite-target: /
        nginx.ingress.kubernetes.io/whitelist-source-range: aa.aa.aa.aa/32
      name: ingress1
      namespace: app1
    spec:
      rules:
        - http:
            paths:
              - backend:
                  service:
                    name: webapp1
                    port: 
                      number: 80
                path: /app1
                pathType: Prefix
    ---
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      annotations:
        kubernetes.io/ingress.class: nginx
        nginx.ingress.kubernetes.io/rewrite-target: /
        nginx.ingress.kubernetes.io/whitelist-source-range: bb.bb.bb.bb/32
      name: ingress2
      namespace: app2
    spec:
      rules:
        - http:
            paths:
              - backend:
                  service:
                    name: webapp2
                    port: 
                      number: 80
                path: /app2
                pathType: Prefix
    

    동작 확인



    app1에 aa.aa.aa.aa의 IP 주소에서 액세스합니다.



    app2에 bb.bb.bb.bb의 IP 주소에서 액세스합니다.



    app2에 허용되지 않는 aa.aa.aa.aa의 IP 주소에서 액세스합니다.



    허용되지 않는 IP 주소에서 액세스하면 NGINX Ingress Controller가 오류를 반환하고 있음을 알 수 있습니다!

    좋은 웹페이지 즐겨찾기