kubernetes 객체의 Ingress

7678 단어

개요


클라이언트가 접근할 수 있도록 외부 네트워크에 그룹 내 서비스를 노출하는 데는 다음과 같은 몇 가지 방법이 있다. 본고는 Ingress를 중점적으로 기술하고자 한다.

LoadBalancer


LoadBalancer는 일반적으로 클라우드 서비스 공급업체가 제공하거나 사용자가 사용자 정의하여 집단 밖으로 운행합니다.서비스를 만들 때 LoadBalancer 관련 파라미터를 설정하고 외부 네트워크에서 그룹 내 servcie에 접근할 때 사용자는 LoadBalancer 서버에 직접 연결하고 LoadBalancer 서버는 데이터를 그룹 내 서비스로 전송합니다.Loadbalancer 설정 및 사용 방법은 각 클라우드 서비스 공급업체와 관련이 있으며 본고는 상세하게 설명하지 않습니다.

NodePort


이런 방식은 집단 중의 일부 노드가 외부 네트워크에 접근할 수 있는 능력을 요구한다.Kubernetes는 각 NodePort 유형의 서비스에 대해 클러스터의 각 노드에 최소한 하나의 호스트 네트워크 포트 번호를 할당합니다.고객은 외부 네트워크에서 액세스할 수 있는 노드 IP와 노드 포트를 통해 서비스에 액세스합니다.대다수 상황에서 이런 방식을 통해 집단 밖으로 서비스를 노출하지 않는 이유는 네 가지가 있다.
  • 첫째, 대부분의 상황에서 안전을 위해 집단 중의 노드는 완전한 내부 네트워크 환경에 위치하고 외부 네트워크에 직접 접근하는 능력이 없어야 한다.일반적으로 외부 네트워크 접근 집단 중의 노드는 모두 경계 서버, 예를 들어 스위치, 발판 등을 통과하는데 이런 경계 서버는 각종 방식을 통해 안전 보강을 해야 한다

  • .둘째, 만약에 집단 내 노드가 외부 네트워크에서 직접 접근할 수 있다면 집단 내 노드의 주소, 서비스 이름, 포트 번호 등 정보를 직접 외부에 노출시켜 매우 안전하지 않다
  • 셋째: 서비스 포트 번호는 일반적으로 시스템에 의해 자동으로 분배되고 고정되지 않으며 서비스 이름도 변경될 수 있다. 이때 외부 클라이언트는 변경 사항을 추적하고 수정해야 하며 재시험 결합에 속한다
  • 넷째: 이런 방식은 모든 서비스가 적어도 외부 네트워크에 하나의 포트 번호를 노출하고 서비스가 많을 때 관리하기 어렵다

  • Ingress


    Ingress는 특정한 제품, 구성 요소의 이름이 아니라 쿠베르넷이 집단 밖으로 서비스를 노출하는 사고방식, 기술이어야 한다. 사용자는 이런 사고방식에 따라 자신의 Ingress 실현을 제공할 수 있다. 물론 쿠베르넷은 기본적인 Ingress 실현을 제공했고 다른 제3자의 실현도 제공했다. 일반적으로 스스로 개발할 필요가 없다.그것의 사고방식은 이렇다. 우선 집단 내에서 서비스나pod를 실행하는 것도 용기일 수 있다. 무엇이든지 외부 네트워크가 접근할 수 있는 IP가 있어야 한다. 적어도 외부 네트워크에 포트 번호를 개방해서 역방향 프록시 서버로 삼아야 한다.외부 네트워크가 그룹 내 서비스에 접근하고자 할 때 이 역방향 프록시 서버에 접근하고 관련 파라미터를 지정하면 프록시 서버는 요청 파라미터에 따라 내부 규칙을 결합하여 요청을 서비스에 전송합니다.이런 사고방식이 Load Balancer와 다른 점은 그것이 집단 안에 있고 Load Balancer는 집단 밖에 있다는 것이다.노드포트와 다른 점은 집단은 하나의 서비스나pod 등만 밖으로 노출되고, 노드포트는 모든 서비스를 노출한다는 것이다.
    Kubernetes는nginx로 역방향 프록시 서버를 실현하는데,ingress Controller라고 불리며,pod 형식의 자원입니다.또한 Ingress 형식의 대상을 제공합니다. Ingress 대상을 만들어서 nginx 역방향 프록시 서버의 전송 규칙을 설정합니다.Nginx 역방향 프록시 서버는 외부 네트워크로부터 요청을 받은 후 요청의 URL 주소, 요청 헤더 필드로 서로 다른 서비스를 구별한 다음 요청을 전달합니다.

    Ingress Controller 배포


    Kubernetes에서 Ingress Controller는 전형적인pod 유형의 자원으로 그 배치 방식은 일반pod와 같다. Deployment, DaemonSet 등 복사본 컨트롤러를 통해 배치하는데 그 중에서 더 추천할 만한 것은 DaemonSet 방식이다.Ingress Controller는 연결망 능력을 갖춘 노드에 배치해야 한다. 먼저 목표 노드에 Ingress Controller 전용 라벨을 설치한 다음에 DaemonSet의 프로필에서 노드 선택기에서 이런 라벨을 선택하여pod 실례가 배치할 수 있는 노드를 제어한다. 노드에 관련 라벨을 추가하여 Ingress Controller의pod 실례 개수를 제어한다.Ingress Controller는 일반적으로 두 개의 노드 호스트 포트를 차지하는데 http는 80, https는 443을 사용한다.여기외부 네트워크는 http://노드 외부 네트워크 ip:80/...또는 https://노드 외부 네트워크 IP:80/...내부 서비스에 액세스할 수 있습니다. 현재 우선 Ingress 객체 구성 액세스 정책을 만들어야 합니다.

    Ingress 객체 만들기


    이 섹션에서는 다양한 Ingress 객체를 작성하여 Ingress의 일반적인 사용법을 보여 줍니다.

    Single Service Ingress


    구성 파일:
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: test-ingress
    spec:
      backend:
        serviceName: testsvc
        servicePort: 80
    

    그리고 통과kubectl create -f 창설 대상, 이것은 창설 일반 대상과 많은 차이가 없습니다. 앞에서 이미 여러 차례 언급한 바와 같이 더 이상 상세하게 설명하지 않겠습니다.
    객체 보기:
    $ kubectl get ing
    NAME                RULE          BACKEND        ADDRESS
    test-ingress        -             testsvc:80     107.178.254.228
    

    상기 설정에 구체적인 rule가 없기 때문에 http(s)://107.178.254.228/xxx 같은 요청은testsvc의 80 포트로 전송됩니다.

    URL로 전송(Simple fanout)


    다음 목표를 달성하려면 다음과 같이 하십시오.
    foo.bar.com -> 178.91.123.132 -> / foo    s1:80
                                     / bar    s2:80
    

    그중foo.bar.com은 http 요청체 머리 부분의host 필드입니다. 178.91.123.132는 Ingress Controller 외부 네트워크 주소입니다. 요청 경로가/foo와 일치할 때 s1 서비스의 80 포트로 전송되고,/bar와 일치할 때 s2 서비스의 80 포트로 전송됩니다. 가장 핵심 논리는 URL로 서로 다른 서비스를 구분하는 것입니다.
    구성은 다음과 같습니다.
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: test
      annotations:
        nginx.ingress.kubernetes.io/rewrite-target: /
    spec:
      rules:
      - host: foo.bar.com
        http:
          paths:
          - path: /foo
            backend:
              serviceName: s1
              servicePort: 80
          - path: /bar
            backend:
              serviceName: s2
              servicePort: 80
    

    객체 보기:
    $ kubectl get ing
    NAME      RULE          BACKEND   ADDRESS
    test      -
              foo.bar.com
              /foo          s1:80
              /bar          s2:80
    

    이름 기반 가상 호스트(Name based virtual hosting)


    다음 디렉토리를 실행합니다.
    foo.bar.com --|                 |-> foo.bar.com s1:80
                  | 178.91.123.132  |
    bar.foo.com --|                 |-> bar.foo.com s2:8
    

    이런 방식의 핵심 논리는 http 요청 중의host 필드로 서로 다른 서비스를 구분하는 것이지 URL이 아니다.예를 들어host:foo.bar.com의 요청은host:bar와 같은 s1 서비스 80 포트로 전송됩니다.foo.com의 요청은 s2 서비스 80 포트로 전송됩니다.
    구성:
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: test
    spec:
      rules:
      - host: foo.bar.com
        http:
          paths:
          - backend:
              serviceName: s1
              servicePort: 80
      - host: bar.foo.com
        http:
          paths:
          - backend:
              serviceName: s2
              servicePort: 80
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: test
    spec:
      rules:
      - host: foo.bar.com
        http:
          paths:
          - backend:
              serviceName: s1
              servicePort: 80
      - host: bar.foo.com
        http:
          paths:
          - backend:
              serviceName: s2
              servicePort: 80
    

    TLS


    Secret 유형의 대상을 이용하여 Ingress Controller에 개인 키와 인증서를 제공하고 통신 체인을 암호화합니다.
    Secret 구성:
    apiVersion: v1
    data:
      tls.crt: base64 encoded cert
      tls.key: base64 encoded key
    kind: Secret
    metadata:
      name: testsecret
      namespace: default
    type: Secret
    

    Ingress 객체에서 참조
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: no-rules-map
    spec:
      tls:
      - secretName: testsecret
      backend:
        serviceName: s1
        servicePort: 80
    

    ** Ingress 객체 업데이트 **
    kubectl edit 명령을 사용하여 Ingress 실시간 객체를 편집하려면 다음과 같이 하십시오.
    $ kubectl get ing
    NAME      RULE          BACKEND   ADDRESS
    test      -                       178.91.123.132
              foo.bar.com
              /foo          s1:80
    $ kubectl edit ing test
    

    팝업 편집기에서 수정:
    spec:
      rules:
      - host: foo.bar.com
        http:
          paths:
          - backend:
              serviceName: s1
              servicePort: 80
            path: /foo
      - host: bar.baz.com
        http:
          paths:
          - backend:
              serviceName: s2
              servicePort: 80
            path: /foo
    ..
    

    저장 끄기 나중에 업데이트 확인:
    $ kubectl get ing
    NAME      RULE          BACKEND   ADDRESS
    test      -                       178.91.123.132
              foo.bar.com
              /foo          s1:80
              bar.baz.com
              /foo          s2:80
    

    참조:
    $ kubectl get ing
    NAME      RULE          BACKEND   ADDRESS
    test      -                       178.91.123.132
              foo.bar.com
              /foo          s1:80
              bar.baz.com
              /foo          s2:80
    

    Ingress-NginX 전달 사용자 정의 헤더


    문제 현장:
    Ingress를 설정하면 Ingress를 통해 시스템에 정상적으로 접근할 수 있지만 사용자 이름 비밀번호를 입력하면 로그인에 실패합니다.하지만 NodePort 노출 서비스를 통해 액세스하고 로그인할 수 있습니다.다음에 디버깅을 했는데 사용자 정보를 가져오는 중 오류가 발생했습니다. Request header에서 사용자 정의 사용자 정보 필드를 찾을 수 없습니다.
    이 글을 참고하면 NginX는 기본적으로 사용자 정의 헤더를 필터합니다. underscores_를 켜지 않으면in_headers, 테스트를 거쳐 NginX에서 underscores_in_headers 이후 시스템 로그인이 정상입니다.그러면 어떻게 Ingress-NginX에서 이 항목을 열 수 있습니까?
    kind: ConfigMap
    apiVersion: v1
    metadata:
      name: nginx-configuration
      namespace: ingress-nginx
      labels:
        app: ingress-nginx
    data:
      enable-underscores-in-headers: "true"
    

    참조 링크 1:
    참조 링크 2
    kubernetes 객체의 Ingress

    좋은 웹페이지 즐겨찾기