I’m trying kubernetes and making some progress, but I’m running into an issue with ingress when trying to make my hello world app publicly available.
SUCCESS WITH DEPLOYMENT AND SERVICE
I created a simple hello world
type of nodejs app and pushed the image to my docker hub johnlai2004/swarm2
. I successfully created a deployment and service with this yaml file:
nodejs.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nodejs-hello
labels:
app: nodejs-hello
spec:
replicas: 1
selector:
matchLabels:
app: nodejs-hello
template:
metadata:
labels:
app: nodejs-hello
spec:
containers:
- name: nodejs-hello
image: johnlai2004/swarm2
ports:
- containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
name: nodejs-hello-service
spec:
selector:
app: nodejs-hello
type: LoadBalancer
ports:
- protocol: TCP
port: 3000
targetPort: 3000
nodePort: 30000
I uploaded these files to a VPS with a new installation of ubuntu 20.04, minikube, kubectl and docker.
I ran the following commands and got the results I wanted:
minikube start --driver=docker
kubectl apply -f nodejs.yaml
minikube service nodejs-hello-service
|-----------|----------------------|-------------|---------------------------|
| NAMESPACE | NAME | TARGET PORT | URL |
|-----------|----------------------|-------------|---------------------------|
| default | nodejs-hello-service | 3000 | http://192.168.49.2:30000 |
|-----------|----------------------|-------------|---------------------------|
When I do a wget http://192.168.49.2:30000
, I get an index.html
file that says hello from nodejs-hello-556dc868-6lrdz at 12/19/2021, 10:29:56 PM
. This is perfect.
FAILURE WITH INGRESS
Next, I want to use ingress so that I can see the page at http://website.example.com
(replace website.example.com
with the actual domain that points to my server). I put this file on my server:
nodejs-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nodejs-ingress
namespace: default
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: website.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nodejs-hello-service
port:
number: 3000
And I ran the commands
minikube addons enable ingress
kubectl apply -f nodejs-ingress.yaml
kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
nodejs-ingress <none> website.example.com localhost 80 15m
But when I visit http://website.example.com
with my browser, the browser says it can’t connect. Using wget http://website.example.com
gave the same connection issue.
Can someone point out what I may have done wrong?
UPDATE
I ran these commands because I think it shows I didn’t install ingress-controller in the right name space?
kubectl get pod -n ingress-nginx
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create--1-tqsrp 0/1 Completed 0 4h25m
ingress-nginx-admission-patch--1-sth26 0/1 Completed 0 4h25m
ingress-nginx-controller-5f66978484-tmx72 1/1 Running 0 4h25m
kubectl get pod -n default
NAME READY STATUS RESTARTS AGE
nodejs-hello-556dc868-6lrdz 1/1 Running 0 40m
So does this mean my nodejs app is in a name space that doesn’t have access to the ingress controller?
UPDATE 2
I also tried following this guide step by step.
One difference I noticed was when I ran the command kubectl get ingress
, ADDRESS
says localhost
. But in the guide, it says it is supposed to be 172.17.0.15
Does this difference matter? I’m hosting things in a cloud vps called linode.com. Does that change the way I do things?
2
Answers
Can you try
kubectl get ingress nodejs-ingress
to see if the ingress resource is created successfully.Then curl with
curl -H 'HOST: <replace with HOSTS from the output of get ingress command>' http://<ADDRESS from the output of get ingress command>:<PORTS from the output of get ingress command>
The behaviour you have is expected. Let me explain why. Going point through point, and at the end I will present my tips.
First I think it’s worth to present minikube architecture. I’m assuming you have installed minikube using default driver
docker
as you have address192.168.49.2
which is standard fordocker
driver.The layers are:
192.168.49.2
on the VMSo… you can not just run
curl
on the VM using alocalhost
address to connect to the service. Thelocalhost
is referring to the device that you are making curl request (so your VM), not the docker container. That’s why you need to use the192.168.49.2
address.You can type
docker ps -a
, and you will see the container which is an actual Kubernetes cluster. You can exec into it usingdocker exec
command and then runcurl
command with the localhost address:Keep in mind that you can access this container only from the VM that is hosting this container. Without any further configuration it’s you can’t just access it from the other VMs. It is possible, but not recommended.
Good explanation in the minikube FAQ:
So I’d avoid it. I will present a better possible solution at the end of the answer.
You asked:
Your computer does not know what it is
website.example.com
. It’s not aware that this name is used by your Ingress. If your computer does not find this name in hosts file it will start looking for this over the Internet.So you have some possible solutions:
curl -H 'HOST: website.example.com' http://192.168.49.2:80
– it will work only on the VM where is minikube192.168.49.2 website.example.com
– it will work only on the VM where is minikubeEDIT:
You wrote that you have a domain pointed to the server, so please just check the sum up section of my answer.
Also you asked:
It’s absolutely normal:
Also:
It’s also normal and expected when using minikube with a docker driver.
To sum up / other tips: