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


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

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

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


네임 스페이스의 요점은 격리하는 것이므로 네임 스페이스를 가로 질러야하는 경우 적어도 위치를 알아야한다고 생각합니다!
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.