So, this is my understanding that port
is the port on which a service serves requests and targetPort
is the port where your app within the container servers requests.
targetPort
is not even required to be specified, it is usually the same as containerPort
(I got this from a StackOverflow
answer and I verified it by removing targetPort
)
Kubernetes port forwarding forwards the request received on local port to the remote port (where the service runs). I have been following this article to understand this better
In my application, the specs were created using helm
. My port
is set to 80
and my containerPort
is set to 5000
(It is a very simple Flask app).
Following the example mentioned in that link the following should work:
kubectl --namespace default port-forward $POD_NAME 7000:80
but this one works instead:
kubectl --namespace default port-forward $POD_NAME 7000:5000
Is there something I've not understood correctly? Here's the kubectl describe
of my pod:
Name: mock-python-server-9f5b557f5-klxq8
Namespace: default
Priority: 0
Node: docker-desktop/192.168.65.3
Start Time: Thu, 21 Jan 2021 13:59:40 -0800
Labels: app.kubernetes.io/instance=mock-python-server
app.kubernetes.io/name=mock-python-server
pod-template-hash=9f5b557f5
Annotations: <none>
Status: Running
IP: 10.1.2.39
Controlled By: ReplicaSet/mock-python-server-9f5b557f5
Containers:
master:
Container ID: docker://7e258d94c458f47c1add418c7969e77fbaa532c56df7405681e778d5f0e63d01
Image: <image>
Image ID: <image_id>
Port: 5000/TCP
Host Port: 0/TCP
State: Running
Started: Thu, 21 Jan 2021 13:59:43 -0800
Ready: True
Restart Count: 0
Limits:
cpu: 100m
memory: 128Mi
Requests:
cpu: 100m
memory: 128Mi
Liveness: http-get http://:http/health delay=0s timeout=1s period=10s #success=1 #failure=3
Readiness: http-get http://:http/health delay=0s timeout=1s period=10s #success=1 #failure=3
Environment:
env: LOCAL
...
Here's a snippet from deployment.yaml
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "master.fullname" . }}
labels:
{{- include "master.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "master.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "master.selectorLabels" . | nindent 8 }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "master.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
env:
- name: env
value: {{ .Values.environment }}
ports:
- name: http
containerPort: 5000 #{{ .Values.flaskPort }}
protocol: TCP
livenessProbe:
httpGet:
path: /health
port: http
readinessProbe:
httpGet:
path: /health
port: http
resources:
{{- toYaml .Values.resources | nindent 12 }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
and my service.yaml
:
apiVersion: v1
kind: Service
metadata:
name: {{ include "master.fullname" . }}
labels:
{{- include "master.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
- port: 80 #{{ .Values.service.port }}
targetPort: 5000
protocol: TCP
name: http
selector:
{{- include "master.selectorLabels" . | nindent 4 }}
Where am I going wrong?
When using port-forwarding, it tunnel to a specified resource inside your cluster, so the command kubectl --namespace default port-forward $POD_NAME 7000:80
, mean you want to connect to a resource named $POD_NAME
from your localhost port 7000 to the resource on port 80
And from your description, you actually dont want to connect to a pod but to a service (which point to the pod you want on port 5000 when there is a request from port 80 inside your cluster). So you need to specify the service name in your command, like this:
kubectl port-forward svc/{{your service name}} 7000:80
Your kubernetes(k8s) app is listening on its container port: 5000 , so to be able to access from your machine you do:
kubectl --namespace default port-forward $POD_NAME 7000:5000
that will allow you to connect outside k8s to your app on port 7000
Your app listening port is set somewhere to 5000 , not to 80 ...