[kubernetes] 다른 네임 스페이스에있는 서비스

다른 네임 스페이스에서 실행중인 Pod에 연결되는 한 네임 스페이스에서 서비스를 정의하는 방법을 찾으려고했습니다. 에서 실행되는 Pod의 컨테이너 는 클러스터 DNS 에서 를 참조하여에서 정의 된 namespaceA액세스 권한 을 가질 수 있다는 것을 알고 있지만 컨테이너 내부의 코드가 . 즉, 코드를 조회 한 다음 액세스 할 수 있기를 원합니다 .serviceXnamespaceBserviceX.namespaceB.svc.cluster.localserviceXserviceX

는 Kubernetes 문서는 이 가능하다는 것을 의미한다. 선택기없이 서비스를 정의하는 이유 중 하나 는 서비스를 다른 네임 스페이스 또는 다른 클러스터에있는 서비스로 지정하기 때문 입니다.

그것은 내가 다음을해야한다고 제안합니다.

  1. 선택기없이 serviceX에서 서비스를 정의합니다 namespaceA(선택하려는 POD가에 없기 때문에 namespaceA).
  2. 에서 서비스 (라고도 함 serviceX)를 정의한 namespaceB다음
  3. 에 엔드 포인트 오브젝트 정의 namespaceA에 지점 serviceX에서 namespaceB.

제가 이룰 수 없었던 세 번째 단계입니다.

먼저 다음과 같이 Endpoints 개체를 정의 해 보았습니다.

kind: Endpoints
apiVersion: v1
metadata:
  name: serviceX
  namespace: namespaceA
subsets:
  - addresses:
      - targetRef:
          kind: Service
          namespace: namespaceB
          name: serviceX
          apiVersion: v1
    ports:
      - name: http
        port: 3000

그것은 논리적 접근으로 보였고 분명히 그것이 무엇 targetRef을위한 것인지에 대한 것입니다. 그러나 이로 인해 어레이 의 ip필드 addresses가 필수 라는 오류가 발생했습니다 . 그래서, 내 다음 시도는에 고정 ClusterIP 주소를 할당하는 것이었다 serviceX에서 namespaceB, 그리고 IP 필드에 있음을 넣어합니다 (이 점에 유의 service_cluster_ip_range로 구성 192.168.0.0/16하고, 192.168.1.1의 ClusterIP로 할당 된 serviceX의를 namespaceB, serviceXnamespaceA자동이에 다른 ClusterIP를 할당 된 192.168.0.0/16서브넷) :

kind: Endpoints
apiVersion: v1
metadata:
  name: serviceX
  namespace: namespaceA
subsets:
  - addresses:
        - ip: 192.168.1.1
          targetRef:
            kind: Service
            namespace: namespaceB
            name: serviceX
            apiVersion: v1
    ports:
      - name: http
        port: 3000

수락되었지만 serviceXin에 대한 액세스가 namespaceAPod in으로 전달되지 않았습니다 namespaceB. 시간이 초과되었습니다. iptables 설정을 살펴보면이를 수행하기 위해 NAT 사전 라우팅을 두 번 수행해야하는 것 같습니다.

하지만 만족스러운 해결책이 아니다 – – 나는 일을 발견했던 유일한 것은 제공하는 포드의 실제 IP 주소를 조회하는 것입니다 serviceX에를 namespaceB하고있는 엔드 포인트 오브젝트에 그 주소를 넣어 namespaceA. 물론 이는 Pod IP 주소가 시간이 지남에 따라 변경 될 수 있기 때문에 만족스럽지 않습니다. 이것이 바로 서비스 IP가 해결해야 할 문제입니다.

그렇다면 한 네임 스페이스의 서비스를 다른 네임 스페이스에서 실행중인 서비스를 가리킬 수 있다는 문서의 약속을 충족하는 방법이 있습니까?

한 댓글 작성자가이 작업을 원하는 이유에 대해 질문했습니다. 여기에 적어도 저에게 의미가있는 사용 사례가 있습니다.

테넌트간에 공유 할 수있는 공통 데이터 액세스 기능도 포함하는 다중 테넌트 시스템이 있다고 가정 해 보겠습니다. 이제 공통 API를 사용하는이 데이터 액세스 기능의 특성이 다르지만 성능 특성이 다르다고 상상해보십시오. 일부 테넌트는 그중 하나에 액세스하고 다른 테넌트는 다른 테넌트에 액세스 할 수 있습니다.

각 테넌트의 포드는 자체 네임 스페이스에서 실행되지만 각 포드는 이러한 공통 데이터 액세스 서비스 중 하나에 액세스해야하며, 이는 반드시 다른 네임 스페이스에 있어야합니다 (여러 테넌트가 액세스하기 때문에). 그러나 고성능 서비스에 액세스하기 위해 구독이 변경되는 경우 테넌트가 코드를 변경하지 않아도됩니다.

잠재적 인 솔루션 (내가 생각할 수있는 가장 깔끔한 솔루션)은 데이터 액세스 서비스에 대한 각 테넌트의 네임 스페이스에 서비스 정의를 포함하고 각각 적절한 엔드 포인트에 대해 구성하는 것입니다. 이 서비스 정의는 각 테넌트가 사용할 수있는 적절한 데이터 액세스 서비스를 가리 키도록 구성됩니다.



답변

나는 같은 문제를 우연히 발견하고 정적 IP 구성이 필요하지 않은 멋진 솔루션을 찾았습니다.

귀하가 언급 한대로 DNS 이름을 통해 서비스에 액세스 할 수 있습니다 . servicename.namespace.svc.cluster.local

해당 DNS 이름을 사용 하여 로컬 서비스를 통해 다른 네임 스페이스 에서 참조 할 수 있습니다 .

kind: Service
apiVersion: v1
metadata:
  name: service-y
  namespace: namespace-a
spec:
  type: ExternalName
  externalName: service-x.namespace-b.svc.cluster.local
  ports:
  - port: 80


답변

너무 간단합니다

호스트로 사용하고 해결하려는 경우

다른 네임 스페이스에있는 서비스를 위해 다른 API 게이트웨이에 대한 앰배서더를 사용하는 경우 항상 다음을 사용하는 것이 좋습니다.

            Use : <service name>
            Use : <service.name>.<namespace name>
            Not : <service.name>.<namespace name>.svc.cluster.local

다음과 같습니다. servicename.namespacename.svc.cluster.local

그러면 언급 한 네임 스페이스 내의 특정 서비스에 요청이 전송됩니다.

예:

kind: Service
apiVersion: v1
metadata:
  name: service
spec:
  type: ExternalName
  externalName: <servicename>.<namespace>.svc.cluster.local

여기를 교체 <servicename>하고 <namespace>적절한 값.

Kubernetes에서 네임 스페이스는 가상 환경을 만드는 데 사용되지만 모두 서로 연결됩니다.


답변

서비스로드 밸런서 https://github.com/kubernetes/contrib/tree/master/service-loadbalancer 와 같이 네임 스페이스가 지정된 서비스보다 상위 계층에 무언가를 배포하여이를 달성 할 수 있습니다 . 단일 네임 스페이스로 제한하려면 “–namespace = ns”인수를 사용하십시오 (기본값은 모든 네임 스페이스 : https://github.com/kubernetes/contrib/blob/master/service-loadbalancer/service_loadbalancer.go). # L715 ). 이것은 L7에서는 잘 작동하지만 L4에서는 약간 지저분합니다.


답변