Ingress configuration issue in Docker kubernetes cluster - docker

I am recently new to Kubernetes and Docker in general and am experiencing issues.
I am running a single local Kubernetes cluster via Docker and am using skaffold to control the build up and teardown of objects within the cluster. When I run skaffold dev the build seems successful, yet when I attempt to make a request to my cluster via Postman the request hangs. I am using an ingress-nginx controller and I feel the bug lies somewhere here. My request handling logic is simple and so I feel the issue is not in the route handling but the configuration of my cluster, specifically with the ingress controller. I will post below my skaffold yaml config and my ingress yaml config.
Any help is greatly appreciated as I have struggled with this bug for sometime.
ingress yaml config :
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-service
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/use-regex: 'true'
spec:
rules:
- host: ticketing.dev
http:
paths:
- path: /api/users/?(.*)
pathType: Prefix
backend:
service:
name: auth-srv
port:
number: 3000
Note that I have a redirect in my /etc/hosts file from ticketing.dev to 127.0.0.1
Auth service yaml config :
apiVersion: apps/v1
kind: Deployment
metadata:
name: auth-depl
spec:
replicas: 1
selector:
matchLabels:
app: auth
template:
metadata:
labels:
app: auth
spec:
containers:
- name: auth
image: conorl47/auth
---
kind: Service
metadata:
name: auth-srv
spec:
selector:
app: auth
ports:
- name: auth
protocol: TCP
port: 3000
targetPort: 3000
skaffold yaml config :
apiVersion: skaffold/v2alpha3
kind: Config
deploy:
kubectl:
manifests:
- ./infra/k8s/*
build:
local:
push: false
artifacts:
- image: conorl47/auth
context: auth
docker:
dockerfile: Dockerfile
sync:
manual:
- src: 'src/**/*.ts'
dest: .
For installing the ingress nginx controller I followed the installation instructions at https://kubernetes.github.io/ingress-nginx/deploy/ , namely the Docker desktop installation instruction.
After running that command I see the following two Docker containers running in Docker desktop
The two services created in the ingress-nginx namespace are :
❯ k get services -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller LoadBalancer 10.103.6.146 <pending> 80:30036/TCP,443:30465/TCP 22m
ingress-nginx-controller-admission ClusterIP 10.108.8.26 <none> 443/TCP 22m
When I kubectl describe both of these services I see the following :
❯ kubectl describe service ingress-nginx-controller -n ingress-nginx
Name: ingress-nginx-controller
Namespace: ingress-nginx
Labels: app.kubernetes.io/component=controller
app.kubernetes.io/instance=ingress-nginx
app.kubernetes.io/managed-by=Helm
app.kubernetes.io/name=ingress-nginx
app.kubernetes.io/version=1.0.0
helm.sh/chart=ingress-nginx-4.0.1
Annotations: <none>
Selector: app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx
Type: LoadBalancer
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.103.6.146
IPs: 10.103.6.146
Port: http 80/TCP
TargetPort: http/TCP
NodePort: http 30036/TCP
Endpoints: 10.1.0.10:80
Port: https 443/TCP
TargetPort: https/TCP
NodePort: https 30465/TCP
Endpoints: 10.1.0.10:443
Session Affinity: None
External Traffic Policy: Local
HealthCheck NodePort: 32485
Events: <none>
and :
❯ kubectl describe service ingress-nginx-controller-admission -n ingress-nginx
Name: ingress-nginx-controller-admission
Namespace: ingress-nginx
Labels: app.kubernetes.io/component=controller
app.kubernetes.io/instance=ingress-nginx
app.kubernetes.io/managed-by=Helm
app.kubernetes.io/name=ingress-nginx
app.kubernetes.io/version=1.0.0
helm.sh/chart=ingress-nginx-4.0.1
Annotations: <none>
Selector: app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.108.8.26
IPs: 10.108.8.26
Port: https-webhook 443/TCP
TargetPort: webhook/TCP
Endpoints: 10.1.0.10:8443
Session Affinity: None
Events: <none>

As it seems, you have made the ingress service of type LoadBalancer, this will usually provision an external loadbalancer from your cloud provider of choice. That's also why It's still pending. Its waiting for the loadbalancer to be ready, but it will never happen.
If you want to have that ingress service reachable outside your cluster, you need to use type NodePort.
Since their docs are not great on this point, and it seems to be by default like this. You could download the content of https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.0.0/deploy/static/provider/cloud/deploy.yaml and modify it before applying. Or you use helm, then you probably can configure this.
You could also do it in this dirty fashion.
kubectl apply --dry-run=client -o yaml -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.0.0/deploy/static/provider/cloud/deploy.yaml \
| sed s/LoadBalancer/NodePort/g \
| kubectl apply -f -
You could also edit in place.
kubectl edit svc ingress-nginx-controller-admission -n ingress-nginx

Related

Kubernetes: Unable to configure Nginx Ingress to access an internal service

I am following a tutorial to access a pod running inside a Kubernetes cluster behind a service. This Kubernetes cluster is running on Windows 10 using Desktop Docker (by enabling the Kubernetes option)
I am unable to access it using this https://local.ticket.dev/api/users/currentuser it always says "Site can't be reached: local.ticket.dev unexpectedly closed the connection."
I have disabled the redirect but it still redirects HTTP to HTTPs
Request URL: http://local.ticket.dev/api/users/currentuser
Request Method: GET
Status Code: 307 Internal Redirect
Referrer Policy: strict-origin-when-cross-origin
Location: https://local.ticket.dev/api/users/currentuser
Non-Authoritative-Reason: HSTS
Here is visually what I want
kubectl get ing
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress-service <none> local.ticket.dev 80 29s
kubectl get services
Please note it's running on local machine windows 10 with Docker Desktop. and the LoadBalancer external IP always remain pending even after 6 hours
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
auth-srv ClusterIP 10.96.254.94 <none> 3000/TCP 45s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 5h17m
nginx-ingress-1629401528-controller LoadBalancer 10.110.199.210 <pending> 80:31430/TCP,443:32346/TCP 5h13m
nginx-ingress-1629401528-default-backend ClusterIP 10.108.79.252 <none> 80/TCP 5h13m
kubectl get pods
NAME READY STATUS RESTARTS AGE
auth-depl-c98cdf66f-txqxt 1/1 Running 0 54s
nginx-ingress-1629401528-controller-569576ddbd-2htxz 1/1 Running 0 5h13m
nginx-ingress-1629401528-default-backend-69c7fc6549-xxf8w 1/1 Running 0 5h13m
How I configured it is as follows
1 - Installation of Nginx by the following command
helm install stable/nginx-ingress --generate-name
2 - Skaffold dev
Listing files to watch...
- billo/ticket_auth
Generating tags...
- billo/ticket_auth -> billo/ticket_auth:latest
Some taggers failed. Rerun with -vdebug for errors.
Checking cache...
- billo/ticket_auth: Found Locally
Starting test...
Tags used in deployment:
- billo/ticket_auth -> billo/ticket_auth:d869228....
Starting deploy...
- deployment.apps/auth-depl created
- service/auth-srv created
- ingress.networking.k8s.io/ingress-service created
Waiting for deployments to stabilize...
- deployment/auth-depl is ready.
Deployments stabilized in 2.302 seconds
Waiting for deployments to stabilize...
Deployments stabilized in 6.9904ms
Press Ctrl+C to exit
Watching for changes...
[auth]
[auth] > auth#1.0.0 start
[auth] > ts-node-dev --poll src/index.ts
[auth]
[auth] [INFO] 00:59:23 ts-node-dev ver. 1.1.8 (using ts-node ver. 9.1.1, typescript ver. 4.3.5)
[auth] Auth!!!! listen to 3000 port
if I look at the last line it seems that my Auth Pod is running on 3000 port.
auth-depl.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: auth-depl
spec:
replicas: 1
selector:
matchLabels:
app: auth
template:
metadata:
labels:
app: auth
spec:
containers:
- name: auth
image: billo/ticket_auth
imagePullPolicy: Never
---
apiVersion: v1
kind: Service
metadata:
name: auth-srv
spec:
selector:
app: auth
ports:
- name: auth
protocol: TCP
port: 3000
targetPort: 3000
ingress-srv.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-service
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
rules:
- host: local.ticket.dev
http:
paths:
- path: /api/users/?(.*)
pathType: Prefix
backend:
service:
name: auth-srv
port:
number: 3000
Configuration in the Host file
# Added by Docker Desktop
127.0.0.1 host.docker.internal
127.0.0.1 gateway.docker.internal
# To allow the same kube context to work on the host and the container:
127.0.0.1 kubernetes.docker.internal
# End of section
127.0.0.1 ingress.local
127.0.0.1 local.ticket.dev
First Disable the HTTPS redirect first
nginx.ingress.kubernetes.io/ssl-redirect: "false"
add annotation into the ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-service
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
rules:
- host: local.ticket.dev
http:
paths:
- path: /api/users/?(.*)
pathType: Prefix
backend:
service:
name: auth-srv
port:
number: 3000
Did you get the external IP for Nginx controller svc? it's showing pending as you are on the Local system.
You might also need to add entries into host file
manually adding your ingresses' hostnames to /etc/hosts:
127.0.0.1 ingress.local
127.0.0.1 local.ticket.dev
OR
Host IP local.ticket.dev

Kubernetes, can't reach Pod with external IP address

I'm new to Kubernetes and I live some problems.
I have a ubuntu server and I working on it. I created pods and services, also I have an API-Gateway pod and service. And I want to reach this pod with my ubuntu server IP address from my PC.
But I cannot reach this pod from outside of the server.
My app on the docker image is running on 80 port.
My api-gateway.yaml file is like that:
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-gateway
spec:
replicas: 1
selector:
matchLabels:
app: api-gateway
template:
metadata:
labels:
app: api-gateway
spec:
containers:
- name: api-gateway
image: myapi/api-gateway
---
apiVersion: v1
kind: Service
metadata:
name: api-gateway
spec:
selector:
app: api-gateway
ports:
- name: api-gateway
protocol: TCP
port: 80
targetPort: 80
nodePort: 30007
type: NodePort
externalIPs:
- <My Ubuntu Server IP Adress>
and when I type kubectl get services api-gateway, I get
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
api-gateway NodePort 10.104.42.32 <MyUbuntuS IP> 80:30007/TCP 131m
also when I type kubectl describe services api-gateway, I get
Name: api-gateway
Namespace: default
Labels: <none>
Annotations: <none>
Selector: app=api-gateway
Type: NodePort
IP Families: <none>
IP: 10.104.42.32
IPs: 10.104.42.32
External IPs: <My Ubuntu Server IP Adress>
Port: api-gateway 80/TCP
TargetPort: 80/TCP
NodePort: api-gateway 30007/TCP
Endpoints: 172.17.0.4:80
Session Affinity: None
External Traffic Policy: Cluster
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Type 30m service-controller ClusterIP -> LoadBalancer
Normal Type 6m10s service-controller NodePort -> LoadBalancer
Normal Type 77s (x2 over 9m59s) service-controller LoadBalancer -> NodePort
So, how can I reach this pod on my PC's browser or Postman?

Not able to login to kubernetes dashboard from hhtp url since local host of the master is a vm

i need create an https url from my dash board using kubectl proxy is only generating http url how to create an https url what command should we run for that token is grtting generated but not login dashboards stays static with no response on entering the token
You can expose your kubernetes-dashboard service via NodePort.
To achieve this, the simplest way would be to edit the current kubernetes-dashboardservice configuration and change ClusterIP parameter to NodePort:
kubectl edit services kubernetes-dashboard -n kube-system
apiVersion: v1
kind: Service
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"k8s-app":"kubernetes-dashboard"}
,"name":"kubernetes-dashboard","namespace":"kube-system"},"spec":{"ports":[{"port":443,"targetPort":8443}],"select
or":{"k8s-app":"kubernetes-dashboard"}}}
creationTimestamp: null
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
selfLink: /api/v1/namespaces/kube-system/services/kubernetes-dashboard
spec:
externalTrafficPolicy: Cluster
ports:
- port: 443
protocol: TCP
targetPort: 8443
selector:
k8s-app: kubernetes-dashboard
sessionAffinity: None
type: NodePort
status:
loadBalancer: {}
Kubernetes then allocates some port from range (30000-32767) and each node should proxy that port to your target service.
You can now check kubernetes-dashboard and look for the port reference:
kubectl describe svc kubernetes-dashboard -n kube-system
Name: kubernetes-dashboard
Namespace: kube-system
Labels: k8s-app=kubernetes-dashboard
Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"v1","kind":"Service","me
tadata":{"annotations":{},"labels":{"k8s-app":"kubernetes-dashboard"},"name":"kubernetes-dashboard","namespace":..
.
Selector: k8s-app=kubernetes-dashboard
Type: NodePort
IP: XX.XX.XX.XX
Port: <unset> 443/TCP
TargetPort: 8443/TCP
NodePort: <unset> 31605/TCP
Endpoints: XX.XX.XX.XX:8443
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
Finally, you can check whether kubernetes-dashboard would be accessible:
curl -k https://localhost:31605
If you consider to secure a way to talk to your Kubernetes dashboard via Bearer token then take a look at this guideline.

Kubernetes Nginx Ingress Controller expose Nginx Webserver

I basically want to access the Nginx-hello page externally by URL. I've made a (working) A-record for a subdomain to my v-server running kubernetes and Nginx ingress: vps.my-domain.com
I installed Kubernetes via kubeadm on CoreOS as a single-node cluster using these tutorials: https://kubernetes.io/docs/setup/independent/install-kubeadm/, https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/, and nginx-ingress using https://kubernetes.github.io/ingress-nginx/deploy/#bare-metal.
I also added the following entry to the /etc/hosts file:
31.214.xxx.xxx vps.my-domain.com
(xxx was replaced with the last three digits of the server IP)
I used the following file to create the deployment, service, and ingress:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 1
strategy:
type: Recreate
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
ports:
- name: http
containerPort: 80
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: my-nginx
labels:
run: my-nginx
spec:
type: ClusterIP
ports:
- name: http
port: 80
protocol: TCP
targetPort: http
selector:
run: my-nginx
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-nginx
annotations:
kubernetes.io/ingress.class: "nginx"
ingress.kubernetes.io/ssl-redirect: "False"
spec:
rules:
- host: vps.my-domain.com
http:
paths:
- backend:
serviceName: my-nginx
servicePort: 80
Output of describe ing:
core#vps ~/k8 $ kubectl describe ing
Name: my-nginx
Namespace: default
Address:
Default backend: default-http-backend:80 (<none>)
Rules:
Host Path Backends
---- ---- --------
vps.my-domain.com
my-nginx:80 (<none>)
Annotations:
kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"extensions/v1beta1",...}
kubernetes.io/ingress.class: nginx
ingress.kubernetes.io/ssl-redirect: False
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal UPDATE 49m (x2 over 56m) nginx-ingress-controller Ingress default/my-nginx
While I can curl the Nginx hello page using the nodeip and port 80 it doesn't work from outside the VM. Failed to connect to vps.my-domain.com port 80: Connection refused
Did I forgot something or is the configuration just wrong? Any help or tips would be appreciated!
Thank you
EDIT:
Visiting "vps.my-domain.com:30519` gives me the nginx welcome page. But in the config I specified port :80.
I got the port from the output of get services:
core#vps ~/k8 $ kubectl get services --all-namespaces | grep "my-nginx"
default my-nginx ClusterIP 10.107.5.14 <none> 80/TCP 1h
I also got it to work on port :80 by adding
externalIPs:
- 31.214.xxx.xxx
to the my-nginx service. But this is not how it's supposed to work, right? In the tutorials and examples for kubernetes and ingress-nginx, it worked always without externalIPs. Also the ingress rules doesn't work now (e.g. if I set the path to /test).
So apparently I was missing one part: the load balancer. I'm not sure why this wasn't mentioned in those instructions as a requirement. But i followed this tutorial: https://kubernetes.github.io/ingress-nginx/deploy/baremetal/#a-pure-software-solution-metallb and now everything works.
Since metallb requires multiple ip addresses, you have to list your single ip-adress with the subnet \32: 31.214.xxx.xxx\32

How to access kubernetes service on localhost with Docker for Windows

I have Windows 10 Pro with Docker for Windows v18.06.1-ce with kubernetes enabled.
Using kubectl create -f, I've created rc.yml:
apiVersion: v1
kind: ReplicationController
metadata:
name: hello-rc
spec:
replicas: 9
selector:
app: hello-world
template:
metadata:
labels:
app: hello-world
spec:
containers:
- name: hello-ctr
image: nigelpoulton/pluralsight-docker-ci:latest
ports:
- containerPort: 8080
svc.yml
apiVersion: v1
kind: Service
metadata:
name: hello-svc
labels:
app: hello-world
spec:
type: NodePort
ports:
- port: 8080
nodePort: 30001
protocol: TCP
selector:
app: hello-world
How do I access the website behind the service?
I would expect localhost:8080 to be working, but it isn't, nor is 10.108.96.27:8080
> kubectl describe service/hello-svc
Name: hello-svc
Namespace: default
Labels: app=hello-world
Annotations: <none>
Selector: app=hello-world
Type: NodePort
IP: 10.108.96.27
LoadBalancer Ingress: localhost
Port: <unset> 8080/TCP
TargetPort: 8080/TCP
NodePort: <unset> 30001/TCP
Endpoints: 10.1.0.10:8080,10.1.0.11:8080,10.1.0.12:8080 + 6 more...
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
There are two ways to expose a service to the outer world from a Kubernetes cluster:
type: LoadBalancer. However, it works only with cloud providers.
type: NodePort. As you used in this case. Now, to access service inside Kubernetes cluster, you need to use the IP address of one of your Nodes and the port from the field nodePort
For example, 12.34.56.78:30001
For more information, look through the official documentation.
For local development:
kubectl port-forward <my-pod-name> 8080:8080
Your pod will be accessible on localhost:8080.
More about port forwarding here.
This might help someone (it took me 1/2 a day to work it out!)
You can use the built in "port-forward" utility (as #aedm suggests), but this will only make your service accessible locally, as it binds to the loopback network. But you can also bind to all networks and make the service accessible externally:
kubectl port-forward <service/name> 80:8080 --address='0.0.0.0'
This will make it accessible to a browser (http) from the outisde.

Resources