Cara Expose Protocol TCP/UDP via Nginx Ingress di Kubernetes

Andri Muhyidin
Andri #DevOps
Published in
3 min readFeb 14, 2021

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.

Konsep Ingress Objek
Konsep Ingress

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

--

--