I have a simple restful django project that return 'hello world' when you GET localhost:8000. I want to run it using microk8s. Using following instruction (https://microk8s.io/docs/registry-images) i created the image and apply my yaml file
yaml file:
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-deployment
labels:
app: hello
spec:
selector:
matchLabels:
app: hello
template:
metadata:
labels:
app: hello
spec:
containers:
- name: hello
image: hello1:local
imagePullPolicy: Never
ports:
- containerPort: 8000
---
apiVersion: v1
kind: Service
metadata:
name: hello
spec:
selector:
app: hello
ports:
- name: hello
port: 8000
protocol: TCP
targetPort: 8000
The pod is running properly.
NAME READY STATUS RESTARTS AGE
pod/hello-deployment-6567ccc4f7-7j6nj 1/1 Running 0 61m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/hello ClusterIP 10.152.183.241 <none> 8000/TCP 59m
but when i want to access the 10.152.183.241:8000 nothing works.
I also connect to pod by following command
microk8s kubectl exec -it hello-deployment-6567ccc4f7-7j6nj -- bash
then install curl and test these:
root@hello-deployment-6567ccc4f7-7j6nj:/code# curl localhost:8000
Hello World
root@hello-deployment-6567ccc4f7-7j6nj:/code# curl 10.152.183.241:8000
curl: (7) Failed to connect to 10.152.183.241 port 8000: Connection refused
Obviously the program is running but there is a problem with kubernetes service. what's wrong with my yaml file?
Update 1: found that image file have problem and it's work with other images. still don't know what is the problem.
my Dockerfile:
FROM python:3
WORKDIR /code
COPY requirements.txt /code/
RUN pip install -r requirements.txt
COPY . /code/
CMD python3 manage.py runserver
EXPOSE 8000
Django doesn't respond.
change
CMD python3 manage.py runserver
with
CMD python3 manage.py runserver 0.0.0.0:8000
also add 0.0.0.0 to ALLOWED_HOSTS.
It's due to you are using the ClusterIP which is only accessible internally from CLuster.
Here you require the Nginx ingress controller to expose the service. Or you can try with the Host IP once to connect with the service.
You can also try the command
kubectl port-forward svc/hello 8080:8080
once the port is forwarded you can hit the curl
on localhost:8080.
However, for production use-case it's always suggested to use the ingress
for managing the cluster traffic.
Ingress basically work as the Proxy it's same as Nginx.
Ingress is configuration object which managed by the Ingress controller
. When you enable the ingress you require the Ingress controller in minikube it will be there however for other Cluster on GKE & EKS you have to setup manually.
Here is good example for the implementation of the ingress in minikube :
https://kubernetes.io/docs/tasks/access-application-cluster/ingress-minikube/
ingress example
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
annotations:
spec:
rules:
- host: hello-world.info
http:
paths:
- path: /
backend:
service:
name: hello
port:
number: 8080
Sounds like you need an ingress add-on, which will let you create rules to access your service via HTTPS/HTTP.
First enable ingress:
microk8s enable ingress
Then add an ingress rule to your yaml file, such as:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: http-ingress
spec:
rules:
- http:
paths:
- path: /
backend:
serviceName: hello
servicePort: 80
Alternatively, you can just expose your port 8000, since you're working locally, as explained here.