The Hardest Problem In Computer Science is Opening a Port
Table of Contents
All I wanted was to open port 1935 so that I could run my MovieNight instance in a cluster. But I couldn’t find anywhere describing all the steps to actually open a port on Kubernetes. But #ShePersisted or whatever.
NB: a non-http port (like 1935 for RTMP, or 21 for FTP, or) can only be made accessible to one (1) service in your entire cluster. So choose wisely. Yes, this is batshit.
1. Configuration the Application
If you’re deploying your application with a Helm chart, make sure that its
service type is NodePort, and specify each port you want accessible in its
service.yaml
:
apiVersion: v1 kind: Service metadata: name: {{ include "movienight.fullname" . }} labels: {{- include "movienight.labels" . | nindent 4 }} spec: type: NodePort ports: - port: 80 targetPort: http protocol: TCP name: http - port: 1935 targetPort: rtmp protocol: TCP name: rtmp selector: {{- include "movienight.selectorLabels" . | nindent 4 }}
List the same additional ports in your application’s deployment.yaml
(here 8089 is what we are exposing as port 80, since that’s what MovieNight
binds to by default):
containers: - name: {{ .Chart.Name }} securityContext: {{- toYaml .Values.securityContext | nindent 12 }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" imagePullPolicy: {{ .Values.image.pullPolicy }} ports: - name: http containerPort: 8089 protocol: TCP - name: rtmp containerPort: 1935 protocol: TCP
2. Configure the Ingress Controller
Find your ingress controller service and deployments in the cluster:
$ kubectl get all NAME READY STATUS RESTARTS AGE pod/ingress-ingress-nginx-controller-7555b9d446-r5l46 1/1 Running 0 89s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/ingress-ingress-nginx-controller LoadBalancer 10.128.94.66 [not telling] 80:31896/TCP,443:31855/TCP,1935:32249/TCP 36h service/ingress-ingress-nginx-controller-admission ClusterIP 10.128.105.144 <none> 443/TCP 36h service/kubernetes ClusterIP 10.128.0.1 <none> 443/TCP 37h NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/ingress-ingress-nginx-controller 1/1 1 1 36h NAME DESIRED CURRENT READY AGE replicaset.apps/ingress-ingress-nginx-controller-7555b9d446 1 1 1 89s
To open port 1935 like you see above, first edit the deployment definition:
kubectl edit deployment.apps/ingress-ingress-nginx-controller
And add two things:
in
spec.containers.ports
, add the port you want open (I want 1935, which is RTMP):ports: - containerPort: 80 name: http protocol: TCP - containerPort: 443 name: https protocol: TCP - containerPort: 1935 name: rtmp protocol: TCP - containerPort: 8443 name: webhook protocol: TCP
in
spec.containers.args
, add a line fortcp-services-configmap
:spec: containers: - args: - /nginx-ingress-controller - --publish-service=default/ingress-ingress-nginx-controller - --election-id=ingress-controller-leader - --ingress-class=nginx - --configmap=default/ingress-ingress-nginx-controller - --tcp-services-configmap=default/tcp-services - --validating-webhook=:8443 - --validating-webhook-certificate=/usr/local/certificates/cert - --validating-webhook-key=/usr/local/certificates/key
default/tcp-services
refers to the namespace and name of the ConfigMap you’re
about to create:
--- apiVersion: v1 kind: ConfigMap metadata: name: tcp-services namespace: default data: 1935: "movienight/trashcloud-movienight:1935"
Here movienight/trashcloud-movienight
refers to the namespace and
service name of your application.
Install your ConfigMap:
kubectl apply -f tcp-services.yaml
Then, edit the service definition of the ingress controller:
kubectl edit service/ingress-ingress-nginx-controller
In spec.ports
, add an entry for the new port, and assign it an unused
NodePort between 30000 and 32767:
spec: clusterIP: 10.128.94.66 externalTrafficPolicy: Cluster ports: - name: http nodePort: 31896 port: 80 protocol: TCP targetPort: http - name: https nodePort: 31855 port: 443 protocol: TCP targetPort: https - name: rtmp nodePort: 32249 port: 1935 protocol: TCP targetPort: 1935
And that should do it! I’m very sleep deprived on account of this nonsense so if I’ve forgotten a step let me know.