2016-05-14 51 views
15

Tôi đã cố gắng tìm cách xác định dịch vụ trong một không gian tên liên kết đến một Pod đang chạy trong một không gian tên khác. Tôi biết rằng các thùng chứa trong một Pod đang chạy trong "namespaceA" có thể truy cập "serviceX" được định nghĩa trong "namespaceB" bằng cách tham chiếu nó trong cụm DNS như "serviceX.namespaceB.svc.cluster.local", nhưng tôi không muốn có mã bên trong container cần biết về vị trí của "serviceX". Đó là, tôi muốn mã chỉ tra cứu "serviceX" và sau đó có thể truy cập nó.kubernetes: Dịch vụ nằm trong một không gian tên khác

Kubernetes documentation cho thấy điều này là có thể. Nó nói rằng một trong những lý do mà bạn sẽ xác định một dịch vụ mà không có một bộ chọn là "Bạn muốn trỏ dịch vụ của bạn đến một dịch vụ trong Không gian tên khác hoặc trên một cụm khác."

Đó gợi ý với tôi rằng tôi nên:

  1. Xác định một "serviceX" dịch vụ trong "namespaceA", mà không có một bộ chọn (kể từ khi POD Tôi muốn chọn không có trong "namespaceA").
  2. Xác định dịch vụ (mà tôi cũng gọi là "serviceX") trong "namespaceB" và sau đó
  3. Xác định đối tượng Điểm cuối trong "không gian tênA" để trỏ đến "serviceX" trong "namespaceB".

Đây là bước thứ ba mà tôi không thể thực hiện được.

Trước tiên, tôi cố gắng xác định các thiết bị đầu cuối đối tượng theo cách này:

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 

Đó dường như là cách tiếp cận hợp lý, và "rõ ràng" những gì "targetRef" đã cho. Tuy nhiên, điều này dẫn đến một lỗi nói rằng trường "ip" trong mảng "địa chỉ" là bắt buộc. Vì vậy, lần thử tiếp theo của tôi là gán một địa chỉ ClusterIP cố định cho "serviceX" trong "namespaceB" và đặt nó vào trường IP (lưu ý rằng service_cluster_ip_range được cấu hình là 192.168.0.0/16 và 192.168.1.1 được gán làm ClusterIP cho "serviceX" trong "namespaceB"; "serviceX" trong "namespaceA" đã được tự động gán một ClusterIP khác nhau trên 192.168.0.0/16 subnet):

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 

đó đã được chấp nhận, nhưng truy cập để "serviceX" trong "namespaceA" không được chuyển tiếp tới Pod trong "namespaceB" - chúng đã hết thời gian chờ. Nhìn vào thiết lập iptables, có vẻ như nó đã phải làm NAT định tuyến trước hai lần để thực hiện điều đó. Điều duy nhất tôi đã tìm thấy rằng đã làm việc - nhưng không phải là một giải pháp thỏa đáng - là tra cứu địa chỉ IP thực tế của Pod cung cấp "serviceX" trong "namespaceB" và đặt địa chỉ đó trong đối tượng Endpoints trong "namespaceA" ("namespaceA"). . Đó không phải là thỏa đáng, tất nhiên, bởi vì địa chỉ IP của Pod có thể thay đổi theo thời gian. Đó là vấn đề dịch vụ IP đang có để giải quyết. Vì vậy, có cách nào để đáp ứng những gì có vẻ là lời hứa của tài liệu hướng dẫn mà tôi có thể chỉ một dịch vụ trong một không gian tên cho một dịch vụ chạy trong một không gian tên khác không? Không.

Một commenter câu hỏi tại sao bạn sẽ muốn làm điều này - đây là một trường hợp sử dụng có ý nghĩa với tôi, ít nhất là:

Giả sử bạn có một hệ thống đa thuê bao, trong đó cũng bao gồm một phổ biến dữ liệu truy cập chức năng có thể được chia sẻ giữa người thuê nhà. Bây giờ hãy tưởng tượng rằng có những hương vị khác nhau của hàm truy cập dữ liệu này với các API phổ biến, nhưng các đặc tính hiệu suất khác nhau. Một số người thuê có quyền truy cập vào một trong số họ, người thuê nhà khác có quyền truy cập vào một người khác.

Mỗi nhóm của người thuê chạy trong không gian tên riêng của họ, nhưng mỗi người cần truy cập vào một trong các dịch vụ truy nhập dữ liệu chung này, nhất thiết phải ở trong một không gian tên khác (vì nó được nhiều người thuê truy cập). Tuy nhiên, bạn sẽ không muốn người thuê phải thay đổi mã của họ nếu đăng ký của họ thay đổi để truy cập dịch vụ có hiệu suất cao hơn.

Một giải pháp tiềm năng (giải pháp sạch nhất mà tôi có thể nghĩ đến, nếu nó chỉ hoạt động) là bao gồm định nghĩa dịch vụ trong không gian tên của mỗi đối tượng thuê dịch vụ truy nhập dữ liệu, với mỗi thiết bị được định cấu hình cho điểm cuối thích hợp. Định nghĩa dịch vụ này sẽ được định cấu hình để trỏ đến dịch vụ truy cập dữ liệu thích hợp mà mỗi người thuê có quyền sử dụng.

+0

bạn đã thử sử dụng tên miền fullqualified cho dịch vụ, như 'service.namespace.s vc.cluster.local ' – MrE

+0

Có, như đã đề cập trong câu hỏi, hoạt động tốt. Nhưng, mục tiêu là mã trong vùng chứa không cần phải biết không gian tên nơi dịch vụ thực sự được tải. –

+0

điểm của không gian tên là để cô lập, vì vậy tôi nghĩ rằng nếu bạn cần phải đi qua các không gian tên bạn cần phải biết ít nhất là nơi nó nằm! – MrE

Trả lời

25

tôi stumbled trên cùng một vấn đề và tìm ra giải pháp tốt đẹp mà không cần bất kỳ cấu hình tĩnh ip:

Bạn có thể truy cập vào một dịch vụ thông qua nó DNS name (như đã đề cập bởi bạn): servicename.namespace.svc. cluster.local

bạn có thể sử dụng tên miền đó để tham khảo nó trong another namespace via a local service:

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 
+1

Đây là một giải pháp tuyệt vời! Tôi không chắc liệu loại "ExternalName" có sẵn cho các dịch vụ khi tôi hỏi câu hỏi ban đầu hay không, nhưng nó được hỗ trợ ngay bây giờ và giải quyết vấn đề một cách gọn gàng. Cảm ơn Paul. –

+0

Tính năng này có hoạt động không? tôi nghi ngờ. bất cứ ai có thể xác nhận nếu điều này thực sự làm việc, không làm việc cho tôi. – debianmaster

+0

Có. Nó hoạt động cho một nhóm để nói chuyện với một dịch vụ trong một không gian tên khác, nhưng không phải cho một loadbalancer. – Paul

2

Bạn có thể đạt được điều này bằng cách triển khai một cái gì đó ở một lớp cao hơn so với các dịch vụ không gian tên, như bộ cân bằng tải dịch vụ https://github.com/kubernetes/contrib/tree/master/service-loadbalancer. Nếu bạn muốn hạn chế nó vào một không gian tên duy nhất, hãy sử dụng đối số "--namespace = ns" (mặc định là tất cả các không gian tên: https://github.com/kubernetes/contrib/blob/master/service-loadbalancer/service_loadbalancer.go#L715). Điều này hoạt động tốt cho L7, nhưng hơi lộn xộn đối với L4.

Các vấn đề liên quan