I do not understand how to configure ports correctly for a k8s deployment.
Assume there is a nextJS application which listens to port 3003 (default is 3000). I build the docker image:
FROM node:16.14.0
RUN apk add dumb-init
# ...
EXPOSE 3003
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
CMD npx next start -p 3003
So in this Dockerfile there are two places defining the port value 3003
. Is this needed?
Then I define this k8s manifest:
apiVersion: apps/v1
kind: Deployment
metadata:
name: example
spec:
spec:
containers:
- name: example
image: "hub.domain.com/example:1.0.0"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 3003
---
apiVersion: v1
kind: Service
metadata:
name: example
spec:
ports:
- protocol: TCP
port: 80
targetPort: 3003
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example
namespace: default
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
kubernetes.io/ingress.class: nginx
kubernetes.io/tls-acme: "true"
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
spec:
tls:
- hosts:
- domain.com
secretName: tls-key
rules:
- host: domain.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: example
port:
number: 80
The deployment is not working correctly. Calling domain.com shows me a 503 Service Temporarily Unavailable
error.
If I do a port forward on the pod, I can see the working app at localhost:3003. I cannot create a port forward on the service.
So obviously I'm doing something wrong with the ports. Can someone explain which value has to be set and why?
CodePudding user response:
You are missing labels from the deployment and the selector from the service. Try this:
apiVersion: apps/v1
kind: Deployment
metadata:
name: example
labels:
app: example
spec:
selector:
matchLabels:
app: example
template:
metadata:
labels:
app: example
spec:
containers:
- name: example
image: "hub.domain.com/example:1.0.0"
imagePullPolicy: IfNotPresent
ports:
- containerPort: 3003
---
apiVersion: v1
kind: Service
metadata:
name: example
spec:
selector:
app: example
ports:
- protocol: TCP
port: 80
targetPort: 3003
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example
namespace: default
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
kubernetes.io/ingress.class: nginx
kubernetes.io/tls-acme: "true"
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
spec:
tls:
- hosts:
- domain.com
secretName: tls-key
rules:
- host: domain.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: example
port:
number: 80
Deployment: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
Service: https://kubernetes.io/docs/concepts/services-networking/service/
Labels and selectors: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
You can name your label keys and values anything you like, you could even have a label as whatever: something
instead of app: example
but these are some recommended labels: https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/
https://kubernetes.io/docs/reference/labels-annotations-taints/