Layanan Kubernetes merespons pada port yang berbeda dari port yang ditetapkan

Dec 16 2020

Saya telah menerapkan beberapa layanan dan menemukan satu layanan berperilaku berbeda dengan yang lain. Saya mengonfigurasinya untuk mendengarkan pada port 8090 (yang memetakan ke 8443 secara internal), tetapi permintaan hanya berfungsi jika saya mengirim pada port 8080. Ini file yaml saya untuk layanan (dipreteli hingga penting) dan ada penerapan yang merangkum layanan dan wadah

apiVersion: v1
kind: Service
metadata:
  name: uisvc
  namespace: default
  labels:
    helm.sh/chart: foo-1
    app.kubernetes.io/name: foo
    app.kubernetes.io/instance: rb-foo
spec:
  clusterIP: None
  ports:
    - name: http
      port: 8090
      targetPort: 8080
  selector:
    app.kubernetes.io/component: uisvc

Setelah memasang helm, ketika saya menjalankan kubectl get svc, saya mendapatkan output berikut

fooaccess       ClusterIP   None         <none>        8888/TCP   119m
fooset          ClusterIP   None         <none>        8080/TCP   119m
foobus          ClusterIP   None         <none>        6379/TCP   119m
uisvc           ClusterIP   None         <none>        8090/TCP   119m

Namun, ketika saya ssh ke salah satu container yang sedang berjalan dan mengeluarkan permintaan curl pada 8090, saya mendapatkan "Sambungan ditolak". Jika saya curl ke "http: // uisvc: 8080", maka saya mendapatkan respon yang benar. Kontainer menjalankan aplikasi boot musim semi yang secara default mendengarkan pada 8080. Satu-satunya penjelasan yang bisa saya dapatkan adalah entah bagaimana port / targetPort diabaikan dalam konfigurasi ini dan pod lain secara langsung menjangkau layanan musim semi di dalamnya.

Apakah perilaku ini benar? Mengapa tidak mendengarkan di 8090? Bagaimana saya harus membuatnya bekerja seperti ini?

Edit: Keluaran untuk kubectl describe svc uisvc

Name:              uisvc
Namespace:         default
Labels:            app.kubernetes.io/instance=foo-rba
                   app.kubernetes.io/managed-by=Helm
                   app.kubernetes.io/name=rba
                   helm.sh/chart=rba-1
Annotations:       meta.helm.sh/release-name: foo
                   meta.helm.sh/release-namespace: default
Selector:          app.kubernetes.io/component=uisvc
Type:              ClusterIP
IP:                None
Port:              http  8090/TCP
TargetPort:        8080/TCP
Endpoints:         172.17.0.8:8080
Session Affinity:  None
Events:            <none>

Jawaban

1 thomas Dec 16 2020 at 20:39

Ini adalah perilaku yang diharapkan sejak Anda menggunakan headless service.

Layanan Headless digunakan untuk mekanisme penemuan layanan, jadi alih-alih menampilkan satu per satu DNS A records, mereka DNS serverakan mengembalikan beberapa A recordsuntuk layanan Anda yang masing-masing mengarah ke IP dari masing-masing pod yang mendukung layanan. Jadi Anda melakukan DNS A recordspencarian sederhana dan mendapatkan IP dari semua pod yang merupakan bagian dari layanan.

Karena headless servicetidak membuat iptablesaturan melainkan membuat dns records, Anda dapat berinteraksi langsung dengan pod Anda alih-alih proxy. Jadi Jika Anda memutuskan, <servicename:port>Anda akan mendapatkannya <podN_IP:port>dan kemudian koneksi Anda akan langsung masuk ke pod. Selama semua ini berada dalam namespace yang sama, Anda tidak harus menyelesaikannya dengan nama dns lengkap.

Dengan beberapa pod, DNS akan memberi Anda semuanya dan hanya menempatkannya dalam urutan acak (atau dalam urutan RR). Urutannya tergantung pada implementasi dan pengaturan server DNS.

Untuk bacaan lebih lanjut silakan kunjungi:

  • Services-netowrking / headless-services
  • Ini tumpukan pertanyaan dengan jawaban bagus yang menjelaskan cara kerja layanan tanpa kepala