Completely new do K8s here, I'm trying to deploy/connect Ingress to a sample single service on docker for local (docker for mac) and be able to hit it to run the service
1- sample service looks like this (my_service.js) :
const express = require('express')
let app = express()
app.get('/', (req, res) => {
res.send('Hello service')
})
const PORT = process.env.PORT || 9000
app.listen(
PORT,
() => console.log('Listening')
)
and I build the image (with a docker file):
docker build . -t sample-service-image
2- Now from K8s perspective:
here's the deployment file
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-service
labels:
app: sample-service
spec:
replicas: 1
selector:
matchLabels:
app: sample-service
template:
metadata:
labels:
app: sample-service
spec:
containers:
- name: sample-service
image: sample-service-image
imagePullPolicy: Never
ports:
- containerPort: 9000
kubectl apply -f deployment.yaml
and expose it as a service:
kubectl expose deploy sample-service --type=NodePort
3- Now from Ingress (ingress-sample.yaml) :
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-sample
spec:
backend:
serviceName: sample-service
servicePort: 80
kubectl create -f ingress-sample.yaml
[UPDATE] I deployed an ingress controller from here:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/provider/baremetal/service-nodeport.yaml
this is what I get
$kubectl get ingress
NAME HOSTS ADDRESS PORTS AGE
ingress-sample * localhost 80 8m
kubectl get services --all-namespaces | grep nginx
ingress-nginx ingress-nginx NodePort 10.106.47.48 <none> 80:31448/TCP,443:31512/TCP 2h
tried to hit it on http://localhost:31448/ but I get 503 from NGINX ... so I guess it's not properly connected to sample-service.
how should I hit Ingress to be able to call the sample-service?
You need to specify Host header while hitting your service. For example
curl -H "HOST: abc" http://localhost:31448/
Since your ingress definition did not specify any host configuration, you can pass any value.
For more information - see.
Related
I am going to access a Kubernetes NodePort service in MacOS in the browser, running on minikube, but I can't.
This is the Service definition file:
apiVersion: v1
kind: Service
metadata:
name: myapp-service
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
nodePort: 30004
selector:
app: myapp
And this is the Pod difinition file:
apiVersion: v1
kind: Pod
metadata:
name: nginx-2
labels:
env: production
app: myapp
spec:
containers:
- name: nginx
image: nginx
And this is the Deployment definition file:
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deployment
labels:
tier: frontend
app: myapp
spec:
selector:
matchLabels:
env: production
replicas: 6
template:
metadata:
name: nginx-2
labels:
env: production
spec:
containers:
- name: nginx
image: nginx
I cannot access the NodePort service using this URL on the browser:
http://localhost:30004
Also by entering minikube ip instead of localhost in the top command, a timeout happens.
And finally, by running the below command:
minikube service myapp-service --url
A sample output like this is generated:
http://127.0.0.1:53751
❗ Because you are using a Docker driver on darwin, the terminal needs to be open to run it.
But an the below error is shown to the user:
The connection was reset
Update : The issue is because the label app:myapp was not mentioned in the Deployment definition file -> template section
Look, your are not exposing your localhost to the nodePort. You are exposing the NodePort on your Kupernetes cluster.
So you have to access it http://nodeip:nodePort.
Think about what is localhost.
You have localhost on your Pc.
You have localhost on the VM (minkube node).
You have localhost in each container running inside your cluster.
If you want to use your Pc localhost to access the port inside a container in a Pod you can do this:
kubectl port-forward svc/serviceName reachablePortFromyourPc:containerPort
For example:
kubectl port-forward svc/serviceName 80:80
This starts a port forwarding. As long it is running you can access it from your browser.
This is good only for testing.
To access the NodePort use.
minikubeIp:NodePort
I am trying to expose a deployment I made on minikube:
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-test
labels:
app: debian
spec:
replicas: 1
selector:
matchLabels:
app: debian
strategy: {}
template:
metadata:
labels:
app: debian
spec:
containers:
- image: agracia10/debian_bash:latest
name: debian
ports:
- containerPort: 8006
resources: {}
restartPolicy: Always
status: {}
I decided to follow was is written on here
I try to expose the deployment using the following command:
kubectl expose pod deployment-test-8497d6f458-xxhgm --type=NodePort --port=8080 --target-port=80
but when I try to then access the service created by the expose command, using the url provided by
minikube service deployment-test-8497d6f458-xxhgm --url
it throws an error using packetsender to try and connect to the service:
packet sender log
Im not really sure what the reason for this could be, I think it has something to do with the fact that when I get the services it says on the external ip field. Also, when I try and retrieve the node IP using minikube ip it gives an address, but when the minikube service --url it gives the 127.0.0.1 address. In any case, using either one does not work.
it's not working due to a port configuration mismatch.
You deployment container running on the 8006 but you have exposed the 8080 and your target port is : --target-port=80
so due to this it's not working.
Ideal flow of traffic goes like :
service (node port, cluster IP or any) > Deployment > PODs
Below sharing the example for deployment and service
apiVersion: apps/v1
kind: Deployment
metadata:
name: blog-app-server-instance
labels:
app: blog-app
spec:
replicas: 1
selector:
matchLabels:
app: blog-app
template:
metadata:
labels:
app: blog-app
spec:
containers:
- name: agracia10/debian_bash:latest
image: blog-app-server
ports:
- containerPort: 8006
---
apiVersion: v1
kind: Service
metadata:
name: blog-app-service
labels:
app: blog-app
spec:
selector:
app: blog-app
type: NodePort
ports:
- port: 80
nodePort: 31364
targetPort: 8006
protocol: TCP
name: HTTP
so things I have changed are image and target port.
Once your Node port service is up and running you will send the request on Port 80 or 31364
i will redirect the request internally to the target port which is 8006 for the container also.
Using this command you exposed your deployment on wrong target point
kubectl expose pod deployment-test-8497d6f458-xxhgm --type=NodePort --port=8080 --target-port=80
ideally it should be 8006
As I know the simplest way to expose the deployment to service we can run this command, you don't expose the pod but expose the deployment.
kubectl expose deployment deployment-test --port 80
I am new to kubernetes, installed 3 nodes k8s cluster through kubeadm in my personal Laptop on top of VMware Workstation
a master and 2 worker nodes.
I have deployed nginx ingress controller through below URL, seems nginx ingress pods are working fine, I have deployed a httpd pod, service and ingress to point to the http server, but I am not able to point to the http URL, pasted all files.
But I didn't deploy any LoadBalancers(HAproxy/MetalLB), I am in a dilemma whether LoadBalancer or Proxy required to make ingress working on BareMetal multinode cluster.
# nginx-ingress
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.44.0/deploy/static/provider/baremetal/deploy.yaml
[root#kube-master01 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
kube-master01 Ready master 197d v1.19.0
kube-node01.example.com Ready worker 197d v1.19.0
kube-node02.example.com Ready worker 197d v1.19.0
[root#kube-master01 ~]# kubectl -n ingress-nginx get pods
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-5zcd5 0/1 Completed 0 41h
ingress-nginx-controller-67897c9494-pt5nl 1/1 Running 0 3h4m
[root#minikube01 httpd]# cat httpd-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpd-deployment
labels:
app: http-server
spec:
replicas: 1
selector:
matchLabels:
app: http-server
template:
metadata:
labels:
app: http-server
spec:
containers:
- name: http-server
image: httpd
ports:
- containerPort: 80
[root#minikube01 httpd]# cat httpd-service.yaml
apiVersion: v1
kind: Service
metadata:
name: httpd-service
spec:
selector:
app: http-server
ports:
- protocol: TCP
port: 8081
targetPort: 80
[root#minikube01 httpd]# cat httpd-ingress.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: httpd-ingress
spec:
rules:
- host: httpd.com
http:
paths:
- backend:
serviceName: httpd-service
servicePort: 8081
The same above files works fine in a minikube node without any issues.
Any assiatnace is appreciated.
Thanks in Advance
Niru
I am using kubernetes. I have Ingress service which talks my container service. We have exposed a webapi which works all fine. But we keep getting 502 bad gateway error. I am new to kubernetes and i have no clue how to go about debugging this issue. Server is a nodejs server connected to database. Is there anything wrong with configuration?
My Deployment file--
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: my-pod
spec:
replicas: 1
template:
metadata:
labels:
app: my-pod
spec:
containers:
- name: my-pod
image: my-image
ports:
- name: "http"
containerPort: 8086
resources:
limits:
memory: 2048Mi
cpu: 1020m
---
apiVersion: v1
kind: Service
metadata:
name: my-pod-serv
spec:
ports:
- port: 80
targetPort: "http"
selector:
app: my-pod
My Ingress Service:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: gateway
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: abc.test.com
http:
paths:
- path: /abc
backend:
serviceName: my-pod-serv
servicePort: 80
In Your case:
I think that you get this 502 gateway error because you don't have Ingress controller configured correctly.
Please try do do it with installed Ingress like in example below. It will do all automatically.
Nginx Ingress step by step:
1) Install helm
2) Install nginx controller using helm
$ helm install stable/nginx-ingress --name nginx-ingress
It will create 2 services. You can get their details via
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.39.240.1 <none> 443/TCP 29d
nginx-ingress-controller LoadBalancer 10.39.243.140 35.X.X.15 80:32324/TCP,443:31425/TCP 19m
nginx-ingress-default-backend ClusterIP 10.39.252.175 <none> 80/TCP 19m
nginx-ingress-controller - in short, it's dealing with requests to Ingress and directing
nginx-ingress-default-backend - in short, default backend is a service which handles all URL paths and hosts the nginx controller doesn't understand
3) Create 2 deployments (or use yours)
$ kubectl run my-pod --image=nginx
deployment.apps/my-pod created
$ kubectl run nginx1 --image=nginx
deployment.apps/nginx1 created
4) Connect to one of the pods
$ kubectl exec -ti my-pod-675799d7b-95gph bash
And add additional line to the output to see which one we will try to connect later.
$ echo "HELLO THIS IS INGRESS TEST" >> /usr/share/nginx/html/index.html
$ exit
5) Expose deployments.
$ kubectl expose deploy nginx1 --port 80
service/nginx1 exposed
$ kubectl expose deploy my-pod --port 80
service/my-pod exposed
This will automatically create service and will looks like
apiVersion: v1
kind: Service
metadata:
labels:
app: my-pod
name: my-pod
selfLink: /api/v1/namespaces/default/services/my-pod
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: my-pod
sessionAffinity: None
type: ClusterIP
status:
loadBalancer: {}
6) Now its the time to create Ingress.yaml and deploy it. Each rule in ingress need to be specified. Here I have 2 services. Each service specification starts with -host under rule parameter.
Ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: two-svc-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: my.pod.svc
http:
paths:
- path: /pod
backend:
serviceName: my-pod
servicePort: 80
- host: nginx.test.svc
http:
paths:
- path: /abc
backend:
serviceName: nginx1
servicePort: 80
$ kubectl apply -f Ingress.yaml
ingress.extensions/two-svc-ingress created
7) You can check Ingress and hosts
$ kubectl get ingress
NAME HOSTS ADDRESS PORTS AGE
two-svc-ingress my.pod.svc,nginx.test.svc 35.228.230.6 80 57m
8) Eplanation why I installed Ingress.
Connect to the ingress controller pod
$ kubectl exec -ti nginx-ingress-controller-76bf4c745c-prp8h bash
www-data#nginx-ingress-controller-76bf4c745c-prp8h:/etc/nginx$ cat /etc/nginx/nginx.conf
Because I have installed nginx ingress earlier, after deploying Ingress.yaml, the nginx-ingress-controller found changes and automatically added necessary code.
In this file you should be able to find whole configuration for two services. I will not copy configuration but only headers.
start server my.pod.svc
start server nginx.test.svc
www-data#nginx-ingress-controller-76bf4c745c-prp8h:/etc/nginx$ exit
9) Test
$ kubectl get svc to get your nginx-ingress-controller external IP
$ curl -H "HOST: my.pod.svc" http://35.X.X.15/
default backend - 404
$ curl -H "HOST: my.pod.svc" http://35.X.X.15/pod
<!DOCTYPE html>
...
</html>
HELLO THIS IS INGRESS TEST
Please keep in mind Ingress needs to be in the same namespace like services. If you have a few services in many namespace you need to create Ingress for each namespace.
I would need to set up a cluster in order to test your yml files.
Just to help you debugging, follow this steps:
1- get the logs of the my-pod container using kubectl logs my-pod-container-name, make sure everything is working
2- Use port-forward to expose your container and test it.
3- Make sure the service is working properly, change its type to load balancer, so you can reach it from outside the cluster.
If the three things are working there is a problem with your ingress configuration.
I am not sure if I explained it in a detailed way, let me know if something is not clear
I am learning kubernetes by playing with minikube.
This is my pod deployment file which is fine.
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deployment
spec:
replicas: 2
selector:
matchLabels:
component: web
template:
metadata:
labels:
component: web
spec:
containers:
- name: myapp
image: myid/myimage
I am exposing the above pods using NodePort. I am able to access using minikube IP at port 30002.
apiVersion: v1
kind: Service
metadata:
name: my-ip-service
spec:
type: NodePort
externalIPs:
- 192.168.99.100
selector:
component: web
ports:
- port: 3000
nodePort: 30002
targetPort: 8080
Now i would like to use ingress to access the application at port 80 which will forward the request the ip-service at port 3000. It does NOT work
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test-ingress
spec:
backend:
serviceName: my-ip-service
servicePort: 3000
If i try to access to ingress, address is blank.
NAME HOSTS ADDRESS PORTS AGE
test-ingress * 80 41m
How to use ingress with minikube? Or how to bind the minikube ip with ingress service - so that the app can be exposed outside without using nodeport
You can get your minikube node's IP address with:
minikube ip
The ingress' IP address will not populate in minikube because minikube lacks a load balancer. If you'd like something that behaves like a load balancer for your minikube cluster, https://github.com/knative/serving/blob/master/docs/creating-a-kubernetes-cluster.md#loadbalancer-support-in-minikube suggests running the following commands to patch your cluster:
sudo ip route add $(cat ~/.minikube/profiles/minikube/config.json | jq -r ".KubernetesConfig.ServiceCIDR") via $(minikube ip)
kubectl run minikube-lb-patch --replicas=1 --image=elsonrodriguez/minikube-lb-patch:0.1 --namespace=kube-system
I think you are missing the ingress controller resource on minikube itself. There are many possible ways to create an ingress-controller resource on K8s , but i think for you the best way to start on minikube is to follow this documentation.
Don't forget to read about Ingress in general once you get this working.