Saya telah mencoba menemukan cara untuk mendefinisikan sebuah layanan dalam satu namespace yang terhubung ke sebuah Pod yang berjalan di namespace lain. Saya tahu bahwa container di dalam Pod yang berjalan namespaceA
dapat mengakses yang serviceX
didefinisikan namespaceB
dengan mereferensikannya di DNS cluster sebagai serviceX.namespaceB.svc.cluster.local
, tetapi saya lebih suka tidak memiliki kode di dalam container yang perlu diketahui tentang lokasinya serviceX
. Artinya, saya ingin kodenya hanya mencari serviceX
dan kemudian dapat mengaksesnya.
The dokumentasi Kubernetes menunjukkan bahwa ini adalah mungkin. Dikatakan bahwa salah satu alasan Anda akan menentukan layanan tanpa pemilih adalah karena Anda ingin mengarahkan layanan Anda ke layanan di Namespace atau cluster lain .
Itu menunjukkan kepada saya bahwa saya harus:
- Tentukan
serviceX
layanan masuknamespaceA
, tanpa pemilih (karena POD yang ingin saya pilih tidak adanamespaceA
). - Tentukan layanan (yang juga saya panggil
serviceX
)namespaceB
, lalu - Mendefinisikan suatu objek Endpoint di
namespaceA
titik keserviceX
dalamnamespaceB
.
Ini adalah langkah ketiga yang belum bisa saya capai.
Pertama, saya mencoba mendefinisikan objek Endpoints dengan cara ini:
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
Tampaknya itu pendekatan yang logis, dan jelas untuk apa targetRef
. Tapi, ini menyebabkan kesalahan yang mengatakan bahwa ip
bidang dalam addresses
array itu wajib. Jadi, percobaan saya selanjutnya adalah menetapkan alamat ClusterIP tetap ke serviceX
in namespaceB
, dan memasukkannya ke dalam bidang IP (perhatikan bahwa service_cluster_ip_range
dikonfigurasi sebagai 192.168.0.0/16
, dan 192.168.1.1
ditetapkan sebagai ClusterIP untuk serviceX
in namespaceB
; serviceX
in namespaceA
secara otomatis menetapkan ClusterIP yang berbeda di 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
Itu diterima, tetapi akses ke serviceX
masuk namespaceA
tidak diteruskan ke Pod masuk namespaceB
- waktu habis. Melihat pengaturan iptables, sepertinya itu harus melakukan pra-routing NAT dua kali untuk mencapai itu.
Satu-satunya hal yang saya lakukan menemukan bahwa bekerja - tapi bukan merupakan solusi yang memuaskan - adalah untuk pencarian alamat IP sebenarnya dari Pod menyediakan serviceX
dalam namespaceB
dan memasukkan alamat yang di objek Endpoint di namespaceA
. Itu tidak memuaskan, tentu saja, karena alamat IP Pod dapat berubah seiring waktu. Itulah IP layanan masalah yang ada untuk dipecahkan.
Jadi, adakah cara untuk memenuhi janji dokumentasi bahwa saya dapat mengarahkan layanan dalam satu namespace ke layanan yang berjalan di namespace berbeda?
Seorang pemberi komentar mempertanyakan mengapa Anda ingin melakukan ini - berikut adalah kasus penggunaan yang masuk akal bagi saya, setidaknya:
Katakanlah Anda memiliki sistem multi-tenant, yang juga menyertakan fungsi akses data umum yang dapat dibagikan di antara penyewa. Sekarang bayangkan bahwa ada ragam yang berbeda dari fungsi akses data ini dengan API umum, tetapi karakteristik kinerja yang berbeda. Beberapa penyewa mendapatkan akses ke salah satunya, penyewa lain memiliki akses ke yang lain.
Setiap pod tenant berjalan di namespace mereka sendiri, tetapi masing-masing perlu mengakses salah satu layanan akses data umum ini, yang tentunya akan berada di namespace lain (karena diakses oleh beberapa tenant). Namun, Anda tidak ingin penyewa harus mengubah kode mereka jika langganan mereka berubah untuk mengakses layanan yang berperforma lebih tinggi.
Solusi potensial (yang paling bersih yang dapat saya pikirkan, jika hanya berhasil) adalah dengan menyertakan definisi layanan di namespace setiap penyewa untuk layanan akses data, dengan masing-masing dikonfigurasi untuk titik akhir yang sesuai. Definisi layanan ini akan dikonfigurasi untuk menunjuk ke layanan akses data yang tepat yang berhak digunakan setiap penyewa.
sumber
Jawaban:
Saya tersandung masalah yang sama dan menemukan solusi bagus yang tidak memerlukan konfigurasi ip statis:
Anda dapat mengakses layanan melalui itu nama DNS-nya (seperti yang Anda sebutkan): servicename.namespace.svc.cluster.local
Anda dapat menggunakan nama DNS itu untuk mereferensikannya di namespace lain melalui layanan lokal :
sumber
Sangat mudah untuk melakukannya
jika Anda ingin menggunakannya sebagai host dan ingin menyelesaikannya
Jika Anda menggunakan duta besar ke gateway API lain untuk layanan yang terletak di namespace lain, selalu disarankan untuk menggunakan:
itu akan menjadi seperti:
servicename.namespacename.svc.cluster.local
ini akan mengirimkan permintaan ke layanan tertentu di dalam namespace yang telah Anda sebutkan.
contoh:
Di sini ganti
<servicename>
dan<namespace>
dengan nilai yang sesuai.Di Kubernetes, namespace digunakan untuk membuat lingkungan virtual tetapi semuanya terhubung satu sama lain.
sumber
.svc.cluster.local
secara default didukung untuk menyelesaikan layanan secara internal.Anda dapat mencapainya dengan menerapkan sesuatu pada lapisan yang lebih tinggi daripada Layanan dengan namespace, seperti layanan loadbalancer https://github.com/kubernetes/contrib/tree/master/service-loadbalancer . Jika Anda ingin membatasinya ke satu namespace, gunakan argumen "--namespace = ns" (defaultnya ke semua namespace: https://github.com/kubernetes/contrib/blob/master/service-loadbalancer/service_loadbalancer.go # L715 ). Ini bekerja dengan baik untuk L7, tetapi sedikit berantakan untuk L4.
sumber