Cara Expose Protocol TCP/UDP via Nginx Ingress di Kubernetes
Background
Pernahkah anda mengalami atau memiliki kebutuhan untuk meng-expose protocol/port selain HTTP melalui ingress? Misalkan domain.com:53
(DNS), atau domain.com:22
(SSH), dan sebagainya. Namun sayangnya metode akses ingress (khususnya nginx) secara default tidak mendukung hal tersebut. Lalu bagaimana supaya berbagai macam service yang menggunakan custom port tertentu dapat diakses melalui ingress? Serta mengapa hal ini perlu dipahami dan diketahui oleh anda yang membangun infrastruktur aplikasi di atas Kubernetes. Simak penjelasan berikut ini.
Overview
Ingress adalah suatu objek API kubernetes yang berfungsi untuk mengatur akses eksternal terhadap service yang ada di dalam cluster. Umumnya dalam bentuk request HTTP. Ingress juga menyediakan layanan lain seperti load balancing, SSL termination, dan name based virtual hosting.
Beberapa manfaat ingress diantaranya adalah menghemat IP Load Balancer, terlebih jika anda menggunakan IP Public yang berbayar. Karena dengan Ingress, satu IP Load Balancer dapat digunakan untuk banyak domain name.
Method
Ingress (Nginx) menyediakan pengaturan flags --tcp-services-configmap
untuk protokol TCP dan --udp-services-configmap
untuk protokol UDP yang harus ditambahkan pada objek deployment nginx-controller serta patching port pada configmap, deployment, dan service nginx.
Implementation
Prerequisite
Penulis berasumsi bahwa anda sudah mengetahui fungsional objek kubernetes serta sudah siap secara konfigurasi cluster, aplikasi, dan nginx ingress. Namun perlu dipastikan kembali bahwa anda menginstall nginx ingress versi controller. Jika belum menginstall nginx ingress, anda dapat menggunakan helm untuk melakukan instalasi dengan perintah berikut.
$helm install nginx-ingress stable/nginx-ingress — set controller.publishService.enabled=true
Atau dengan mengupgrade instalasi yang sudah dilakukan dan belum ada controller-nya dengan cara sebagai berikut.
$ helm upgrade <release-name> stable/nginx-ingress — set controller.publishService.enabled=true
Sample Service
Anda dapat menggunakan service yang sudah terinstall di atas kubernetes cluster. Namun jika anda ingin mencoba di luar existing service, anda dapat melakukan instalasi dengan sampel yaml berikut.Filename: sample-app.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
namespace: default
labels:
app: redis
spec:
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- image: redis
imagePullPolicy: Always
name: redis
ports:
- containerPort: 6000
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: redis
namespace: default
spec:
selector:
app: redis
type: ClusterIP
ports:
- name: tcp-port
port: 6000
targetPort: 6000
protocol: TCP
Apply file tersebut dengan perintah berikut:
$kubectl apply -f sample-app.yaml
Create Configmap for TCP/UDP
Dengan metode embed tcp/udp service pada configmap, maka anda harus membuat config map baru untuk TCP/UDP. Berikut contohnya.
File: tcp-services.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: tcp-services
namespace: ingress-nginx
data:
6000: "default/redis:6000"
File: udp-services.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: udp-services
namespace: ingress-nginx
data:
53: "kube-system/kube-dns:53"
Lalu apply file tersebut sesuai dengan kebutuhan. Misalkan untuk apply konfigurasi TCP, maka anda dapat menggunakan perintah berikut.
$kubectl apply -f tcp-services.yaml -n ingress-nginx
Add Flags into Ingress Controller Deployment
Anda dapat memperbaharui objek deployment nginx controller anda dengan menambahkan flags tcp/udp service configmap berikut ini:
$kubectl edit deployment -n <ingress-namespace> <deployment-name>spec:
containers:
- args:
- /nginx-ingress-controller
...
- --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
- --udp-services-configmap=$(POD_NAMESPACE)/udp-services
Add Port into Ingress Controller Deployment
Tambahkan protocol dan port yang anda ingin expose pada objek deployment nginx controller pada bagian ports nginx controller seperti pada cuplikan yaml berikut.
$kubectl edit deployment -n <ingress-namespace> <deployment-name>name: nginx-ingress-controller
ports:
...
- containerPort: 6000
hostPort: 6000
protocol: TCP
Testing
Service Port Listing
Cek pada objek service nginx controller anda dan pastikan bahwa port yang di expose (6000) sudah listing pada ports bersama port 80 dan 443.
$kubectl get svc -n <ingress-namespace>
Telnet
Untuk memastikan apakah protokol tcp dengan port listing yang dikehendaki dapat diakses, anda dapat menggunakan perintah telnet berikut. Pastikan respon telnet sudah berhasil atau escape.
$telnet domain.com 6000Trying domain.com...
Connected to domain.com.
Escape character is '^]'.
Terimakasih sudah membaca, semoga bermanfaat. Jika anda membutuhkan konsultasi tentang DevOps Solutions. Anda dapat menghubungi saya via email andrimuhyidin55@gmail.com