How to expose nginx on public Ip using NodePort service in Kubernetes? - kubernetes

I'm executing kubectl create -f nginx.yaml which creates the pods successfully. But the PODS aren't exposed on Public IP of my instance. Following is the YAML used be me with service type as nodeport:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
name: nginx
spec:
type: NodePort
ports:
- port: 80
nodePort: 30080
name: http
- port: 443
nodePort: 30443
name: https
selector:
name: nginx
What could be in-correct in my approach or above YAML file to expose the pod on deployment to the public IP?
PS: Firewall and ACLs are open to internet on all TCP

The endpoint was not getting added. On debugging I found the label between deployment and Service has a mismatch. Hence changed the label type from "app" to "name" and it worked.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
name: nginx
spec:
replicas: 3
selector:
matchLabels:
name: nginx
template:
metadata:
labels:
name: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
name: nginx
spec:
type: NodePort
ports:
- port: 80
nodePort: 30080
name: http
selector:
name: nginx

Jeel is right. Your Service selector is mismatch with Pod labels.
If you fix that like what Jeel already added in this answer
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
name: nginx
spec:
type: NodePort
ports:
- port: 80
nodePort: 30080
name: http
selector:
name: nginx
Your Service will be exposed in Node IP address. Because your Service Type is NodePort.
If your Node IP is, lets say, 35.226.16.207, you can connect to your Pod using this IP and NodePort
$ curl 35.226.16.207:30080
In this case, your node must have a public IP. Otherwise, you can't access
Second option, you can create LoadBalancer Type Service
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
name: nginx
spec:
type: LoadBalancer
ports:
- port: 80
name: http
selector:
name: nginx
This will provide you a public IP.
For more details, check this

Related

Kubernetes service not exposed on minikube

I'm new to k8 and i'm trying to figure out how to deploy my first docker image on minikube.
My k8.yaml file is:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deployment
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-docker-image
image: my-docker-image:1.0
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: my-service
namespace: default
spec:
type: LoadBalancer
selector:
app: my-service
ports:
- port: 8080
targetPort: 8080
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: my-ingress
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-service
port:
number: 8080
Everything seems fine to me, however, I'm not able to reach my service on cluster.
I tried to create a tunnel using the minikube tunnel command and i have this result if i execute kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-service LoadBalancer 10.109.154.236 127.0.0.1 8080:30558/TCP 2m53s
However, if i try to call my service at 127.0.0.1:30588 host is unreachable.
Can someone help me?
There is an issue in the service selector as well, so first, we need to fix this service selector and it should match with with deployment label
replicas: 1
selector:
matchLabels:
app: my-app
and the service should refer to this selector
the selector should be my-app in the service or same as above for deployment
type: LoadBalancer
selector:
app: my-app
ports:
- port: 8080
targetPort: 8080
to access from the host
minikube service my-service
and here you go
kubectl delete -f myapp.yaml
kubectl apply -f myapp.yaml
deployment manifest
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deployment
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-docker-image
image: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: my-service
namespace: default
spec:
type: LoadBalancer
selector:
app: my-app
ports:
- port: 80
targetPort: 80
Also worth considering the service type for Minikube.
What's the difference between ClusterIP, NodePort and LoadBalancer service types in Kubernetes?

IP provided by metallb is not accessible

I have a bare-metal Kubernetes cluster with metal LB.
I have used a GCP external Load balancer for an IP that I have assigned to Metallb.
Metallb has assigned that IP to service but still I am not able to access my service on that IP from outside Cluster.
apiVersion: v1
kind: Service
metadata:
name: nginxlb
spec:
type: LoadBalancer
selector:
app: nginx
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
- name: default
protocol: layer2
addresses:
- 34.149.177.23-34.149.177.23

tunnel for service target port empty kubernetes and can't access pod from local browser

apiVersion: apps/v1
kind: Deployment
metadata:
name: identityold-deployment
spec:
selector:
matchLabels:
app: identityold
replicas: 1
template:
metadata:
labels:
app: identityold
spec:
containers:
- name: identityold
image: <image name from docker hub>
ports:
- containerPort: 8081
---
apiVersion: v1
kind: Service
metadata:
labels:
app: identityold
name: identityold-svc
namespace: default
spec:
type: NodePort # use LoadBalancer as type here
ports:
- port: 80
targetPort: 8081
nodePort: 30036
selector:
app: identityold
The above code is my deployment YAML file.
and cant access from the browser the service
Exposing a service in minikube cluster is little bit different than in normal kubernetes cluster.
Please follow this guide from kubernetes documentation and use minikube service command in order to expose it properly.

GKE NodePort service refusing incoming traffic

I have created a Node port service in Google cloud with the following specification... I have a firewall rule created to allow traffic from 0.0.0.0/0 for the port '30100' ,I have verified stackdriver logs and traffic is allowed but when I either use curl or from browser to hit http://:30100 I am not getting any response. I couldn't proceed how to debug the issue also... can someone please suggest on this ?
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginxv1
template:
metadata:
labels:
app: nginxv1
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: nginxv1
namespace: default
spec:
ports:
- port: 80
protocol: TCP
targetPort: 8080
nodePort: 30100
selector:
app: nginxv1
type: NodePort
Thanks.
You need to fix the container port, it must be 80 because the nginx container exposes this port as you can see here
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginxv1
template:
metadata:
labels:
app: nginxv1
spec:
containers:
- name: nginx
image: nginx:latest
---
apiVersion: v1
kind: Service
metadata:
name: nginxv1
namespace: default
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
nodePort: 30100
selector:
app: nginxv1
type: NodePort
Also, you need to create a firewall rule to permit the traffic to the node, as mentioned by #danyL in comments:
gcloud compute firewall-rules create test-node-port --allow tcp:30100
Get the node IP with the command
kubectl get nodes -owide
And them try to access the nginx page with:
curl http://<NODEIP>:30100

How create service on minikube with yaml configuration,which accessible from host?

How correct write yaml configuration for kubernetes pod and service in minikube cluster with driver on docker with one requirement: 80 port of container must be accessible from host machine. Solution with nodePort doesn't work as excepected:
type: NodePort
ports:
- port: 80
targetPort: 8006
selector:
app: blogapp
Label app: blogapp set on container. Can you show correct configuration for nginx image for example with port accessible from host.
You should create a Kubernetes deployment instead of creating a NodePort. Once you create the deployment(which will also create a ReplicaSet and Pod automatically), you can expose it. The blogapp will not be available to the outside world by default, so you must expose it if you want to be able to access it from outside the cluster.
Exposing the deployment will automatically create a service as well.
deployment.yml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: blogapp
labels:
app: blogapp
spec:
replicas: 1
strategy: {}
template:
metadata:
labels:
app: blogapp
spec:
containers:
- image: <YOUR_NGINX_IMAGE>
name: blogapp
ports:
- containerPort: 8006
resources: {}
restartPolicy: Always
status: {}
Create the deployment
kubectl create -f deployment.yml
Expose the deployment
kubectl expose deployment blogapp --name=blogapp --type=LoadBalancer --target-port=8006
Get the exposed URL
minikube service blogapp --url
You can use the below configuration:
---
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: blog-app-server-instance
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
I guess you were missing spec.ports[0].nodePort.