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


108

다른 네임 스페이스에서 실행중인 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, serviceX에 namespaceA자동이에 다른 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를 사용하는이 데이터 액세스 기능의 특성이 다르지만 성능 특성이 다르다고 상상해보십시오. 일부 테넌트는 그중 하나에 액세스하고 다른 테넌트는 다른 테넌트에 액세스 할 수 있습니다.

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

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


네임 스페이스의 요점은 격리하는 것이므로 네임 스페이스를 가로 질러야하는 경우 적어도 위치를 알아야한다고 생각합니다!
— MrE

그렇다면 선택기를 정의하지 않고 엔드 포인트를 정의함으로써 한 네임 스페이스에 정의 된 서비스가 다른 네임 스페이스의 서비스에 액세스하도록 지시 할 수 있다는 문서의 의미는 무엇입니까? 이것에 대한 유효한 사용 사례가 있습니다-그중 하나를 질문에 추가했습니다. 문서가 오해의 소지가 있거나 아직 알아 내지 못한 방법이 있습니까?
— David McKinley

잘 모르겠습니다. 죄송합니다. 내가 아는 것은 fqdn을 사용하여 여러 네임 스페이스의 서비스에 액세스한다는 것입니다. 나는 1 개의 vpn pod를 가지고 있고 그것의 모든 서비스를 통해 연결하기 때문에 특히 vpn으로 이것을한다. 그러나 네임 스페이스를 알고 fqdn을 제공해야합니다. 슬랙 채널에서 물어볼 것을 제안합니다.
— MrE

fqdn을 사용하는 것이 현재 사용하고있는 솔루션입니다. 그래도 필요하지 않은 경우 내 사용 사례가 더 잘 제공 될 것입니다 (이제 질문에 추가됨).
— David McKinley

또한 문서가 무엇을 참조하는지 궁금하지만 fqdn을 사용 사례에 대한 만족스러운 솔루션으로 사용할 수 있습니다.
— Vincent De Smet

답변:


223

나는 같은 문제를 우연히 발견하고 정적 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

2
이것은 훌륭한 솔루션입니다! 처음 질문했을 때 서비스에 "ExternalName"유형을 사용할 수 있었는지 확실하지 않지만 지금은 지원되며 문제를 깔끔하게 해결합니다. 고마워, 폴.
— 데이비드 맥킨리

1
작동합니까? 의심 스럽다. 이것이 정말로 효과가 있는지 누구든지 확인할 수 있습니까?
— debianmaster

2
네 그렇습니다. 한 포드에서 다른 네임 스페이스의 서비스와 통신하는 데는 작동하지만 수신로드 밸런서에서는 작동하지 않습니다.
— Paul

kubernetes 클러스터 내 CNAME 조회 수정으로 인해 이전 버전이 작동하지 않을 수 있습니다.
— 赵浩翔

1
이것이 kube-system 네임 스페이스의 서비스에서도 작동합니까?
— Nabheet

10

너무 간단합니다

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

다른 네임 스페이스에있는 서비스를 위해 다른 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에서 네임 스페이스는 가상 환경을 만드는 데 사용되지만 모두 서로 연결됩니다.


6
이 답변이 거의 2 년 전에 제공된 바울의 답변과 어떻게 다른지 설명해 주시겠습니까?
— Oliver

2
@Oliver 차이는 없지만 특정 장소에서 서비스 이름과 네임 스페이스를 대체 할 항목을 지정했습니다. 그가 namespace-a를 사용하는 동안 나에게는 혼란스러워 보입니다.
— 거친 Manvar

7
SO에 대한 편리한 트릭은 답변에 대한 주석을 추가하고 필요한 설명을하는 것입니다.
— Oliver

4
.svc.cluster.local기본적으로 서비스를 내부적으로 해결하기 위해 지원 되기 때문에 이것을 최상의 솔루션이라고 부를 것 입니다.
— DrKNa

1
나를 위해 또한 깨웠다. 감사합니다
— vimal prakash

0

서비스로드 밸런서 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에서는 약간 지저분합니다.


3
이 프로젝트는 현재 지원 중단되었습니다 (2018 년
— Nicola Ben

1
@Prashanth B : 그에 따라 답변을 업데이트 해 주시겠습니까!
— chaosguru
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.