I want to deploy a simple nginx app on my own kubernetes cluster.
I used the basic nginx deployment. On the machine with the ip 192.168.188.10. It is part of cluster of 3 raspberries.
NAME STATUS ROLES AGE VERSION
master-pi4 Ready master 2d20h v1.18.2
node1-pi4 Ready <none> 2d19h v1.18.2
node2-pi3 Ready <none> 2d19h v1.18.2
$ kubectl create deployment nginx --image=nginx
deployment.apps/nginx created
$ kubectl create service nodeport nginx --tcp=80:80
service/nginx created
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
my-nginx-8fb6d868-6957j 1/1 Running 0 10m
my-nginx-8fb6d868-8c59b 1/1 Running 0 10m
nginx-f89759699-n6f79 1/1 Running 0 4m20s
$ kubectl describe service nginx
Name: nginx
Namespace: default
Labels: app=nginx
Annotations: <none>
Selector: app=nginx
Type: NodePort
IP: 10.98.41.205
Port: 80-80 80/TCP
TargetPort: 80/TCP
NodePort: 80-80 31400/TCP
Endpoints: <none>
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
But I always get a time out
$ curl http://192.168.188.10:31400/
curl: (7) Failed to connect to 192.168.188.10 port 31400: Connection timed out
Why is the web server nginx not reachable? I tried to run it from the same machine I deployed it to? How can I make it accessible from an other machine from the network on port 31400?
As mentioned by #suren, you are creating a stand-alone service without any link with your deployment.
You can solve using the command from suren answer, or creating a new deployment using the follow yaml spec:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- name: http
containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
type: NodePort
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
After, type kubectl get svc to get the nodeport to access your service.
nginx-svc NodePort 10.100.136.135 <none> 80:31816/TCP 34s
To access use http://<YOUR_NODE_IP>:31816
so is 192.168.188.10 your host ip / your vm ip ?
you have to check it first if any service using that port or maybe you haven't add it into your security group if you using cloud platform.
just to make sure you can create a pod and access it using fqdn like my-svc.my-namespace.svc.cluster-domain.example
Related
I'm using k8s provided with docker desktop (windows).
My deployment.yml file is
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx-app
spec:
replicas: 1
selector:
matchLabels:
app: nginx-app
template:
metadata:
labels:
app: nginx-app
spec:
containers:
- name: nginx-container
image: nginx:stable-alpine
ports:
- containerPort: 80
and my service yml file is
apiVersion: v1
kind: Service
metadata:
name: my-service
labels:
app: nginx-app
spec:
selector:
app: nginx-app
type: NodePort
ports:
- nodePort: 31000
port: 80
targetPort: 80
all are up and running but I'm unable to access the application.
>curl localhost:31000
curl: (7) Failed to connect to localhost port 31000: Connection refused
>kubectl get all
NAME READY STATUS RESTARTS AGE
pod/nginx-deployment-685658ccbf-g84w5 1/1 Running 0 8s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 14h
service/my-service LoadBalancer 10.96.210.40 localhost 80:31000/TCP 4s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx-deployment 1/1 1 1 8s
NAME DESIRED CURRENT READY AGE
replicaset.apps/nginx-deployment-685658ccbf 1 1 1 8s
Note: created the Inbound/Outbound rule for this 31000 port in windows firewall to make sure it won't block
There are some questions you can try to answer in order to Debug Services:
Does the Service exist?: In your case we see that it does.
Does the Service work by DNS name?: One of the most common ways that clients consume a Service is through a DNS name.
Does the Service work by IP?: Assuming you have confirmed that DNS works, the next thing to test is whether your Service works by its IP address.
Is the Service defined correctly?: You should really double and triple check that your Service is correct and matches your Pod's port. Also:
Is the Service port you are trying to access listed in spec.ports[]?
Is the targetPort correct for your Pods (some Pods use a different port than the Service)?
If you meant to use a numeric port, is it a number (9376) or a string "9376"?
If you meant to use a named port, do your Pods expose a port with the same name?
Is the port's protocol correct for your Pods?
Does the Service have any Endpoints?: Check that the Pods you ran are actually being selected by the Service.
Are the Pods working?: Check again that the Pods are actually working.
Is the kube-proxy working?: Confirm that kube-proxy is running on your Nodes.
Going through the above steps will help you find the cause of this and possible future issues with services.
I'm doing some tutorials using k3d (k3s in docker) and my yml looks like this:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
app: nginx
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
type: NodePort
selector:
app: nginx
ports:
- name: http
port: 80
targetPort: 80
With the resulting node port being 31747:
:~$ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 18m
nginx NodePort 10.43.254.138 <none> 80:31747/TCP 17m
:~$ kubectl get endpoints
NAME ENDPOINTS AGE
kubernetes 172.18.0.2:6443 22m
nginx 10.42.0.8:80 21m
However wget does not work:
:~$ wget localhost:31747
Connecting to localhost:31747 ([::1]:31747)
wget: can't connect to remote host: Connection refused
:~$
What have I missed? I've ensured that my labels all say app: nginx and my containerPort, port and targetPort are all 80
The question is, is the NodePort range mapped from the host to the docker container acting as the node. The command docker ps will show you, for more details you can docker inspect $container_id and look at the Ports attribute under NetworkSettings. I don't have k3d around, but here is an example from kind.
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1d2225b83a73 kindest/node:v1.17.0 "/usr/local/bin/entr…" 18 hours ago Up 18 hours 127.0.0.1:32769->6443/tcp kind-control-plane
$ docker inspect kind-control-plane
[
{
# [...]
"NetworkSettings": {
# [...]
"Ports": {
"6443/tcp": [
{
"HostIp": "127.0.0.1",
"HostPort": "32769"
}
]
},
# [...]
}
]
If it is not, working with kubectl port-forward as suggested in the comment is probably the easiest approach. Alternatively, start looking into Ingress. Ingress is the preferred method to expose workloads outside of a cluster, and in the case of kind, they have support for Ingress. It seems k3d also has a way to map the ingress port to the host.
Turns out I didn't expose the ports when creating the cluster
https://k3d.io/usage/guides/exposing_services/
maybe, your pod is running on the other work node, not localhost. you should use the correct node ip.
I have a corporate network(10.22..) which hosts a Kubernetes cluster(10.225.0.1). How can I access some VM in the same network but outside the cluster from within the pod in the cluster?
For example, I have a VM with IP 10.22.0.1:30000, which I need to access from a Pod in Kubernetes cluster. I tried to create a Service like this
apiVersion: v1
kind: Service
metadata:
name: vm-ip
spec:
selector:
app: vm-ip
ports:
- name: vm
protocol: TCP
port: 30000
targetPort: 30000
externalIPs:
- 10.22.0.1
But when I do "curl http://vm-ip:30000" from a Pod(kubectl exec -it), it returns "connection refused" error. But it works with "google.com". What are the ways of accessing the external IPs?
You can create an endpoint for that.
Let's go through an example:
In this example, I have a http server on my network with IP 10.128.15.209 and I want it to be accessible from my pods inside my Kubernetes Cluster.
First thing is to create an endpoint. This is going to let me create a service pointing to this endpoint that will redirect the traffic to my external http server.
My endpoint manifest is looking like this:
apiVersion: v1
kind: Endpoints
metadata:
name: http-server
subsets:
- addresses:
- ip: 10.128.15.209
ports:
- port: 80
$ kubectl apply -f http-server-endpoint.yaml
endpoints/http-server configured
Let's create our service:
apiVersion: v1
kind: Service
metadata:
name: http-server
spec:
ports:
- port: 80
targetPort: 80
$ kubectl apply -f http-server-service.yaml
service/http-server created
Checking if our service exists and save it's clusterIP for letter usage:
user#minikube-server:~$$ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
http-server ClusterIP 10.96.228.220 <none> 80/TCP 30m
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 10d
Now it's time to verify if we can access our service from a pod:
$ kubectl run ubuntu -it --rm=true --restart=Never --image=ubuntu bash
This command will create and open a bash session inside a ubuntu pod.
In my case I'll install curl to be able to check if I can access my http server. You may need install mysql:
root#ubuntu:/# apt update; apt install -y curl
Checking connectivity with my service using clusterIP:
root#ubuntu:/# curl 10.128.15.209:80
Hello World!
And finally using the service name (DNS):
root#ubuntu:/# curl http-server
Hello World!
So, in your specific case you have to create this:
apiVersion: v1
kind: Endpoints
metadata:
name: vm-server
subsets:
- addresses:
- ip: 10.22.0.1
ports:
- port: 30000
---
apiVersion: v1
kind: Service
metadata:
name: vm-server
spec:
ports:
- port: 30000
targetPort: 30000
I’m running Kubernetes on GKE, this was working before but about 2 days ago something changed. I don’t think I changed anything to my configuration. My services do not seem to work anymore. None of my services can talk to each other. When SSHing into a running pod I cannot ping them via their service name but also not via their internal IP addresses. The external IP of the load balancer is not approachable. Here is an example of how I define the deployment:
apiVersion: apps/v1beta1
kind: Deployment
metadata:
labels:
ksonnet.io/component: app-name
name: app-name
spec:
replicas: 1
template:
metadata:
labels:
app: app-name
And here the service:
apiVersion: v1
kind: Service
metadata:
labels:
ksonnet.io/component: app-name
name: app-name
spec:
loadBalancerIP: x.x.x.x
ports:
- port: 4999
targetPort: 5000
selector:
app: app-name
type: LoadBalancer
I am fairly new to Kubernetes and networking and I have no clue where to look or how to debug this issue.
EDIT:
Here are the relevant kubectl get services -n test
dashboard ClusterIP 10.47.242.176 <none> 5000/TCP 1h
app-name LoadBalancer 10.47.246.63 x.xxx.xx.xx 4999:31439/TCP 1h
Then here is the kubectl describe service app-name -n test
Name: app-name
Namespace: test
Labels: app.kubernetes.io/deploy-manager=ksonnet
ksonnet.io/component=app-name
Annotations: ksonnet.io/managed: {pristine...}
Selector: app=app-name
Type: LoadBalancer
IP: 10.47.246.63
IP: xx.xxx.xx.x
LoadBalancer Ingress: xx.xxx.xx.x
Port: <unset> 4999/TCP
TargetPort: 5000/TCP
NodePort: <unset> 31439/TCP
Endpoints: 10.44.1.141:5000
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
EDIT 2: I tried the curl command on the default port and it timed out:
curl: (7) Failed to connect to app-name port 80: Connection timed out
When trying it on the full endpoint it got a connection refused:
curl: (7) Failed to connect to app-name port 4999: Connection refused
When looking at the deployment I get the following pod template:
Pod Template:
Labels: app=app-name
Containers:
model-manager:
Image: gcr.io/ns-delay/app-name:0.1
Port: 5000/TCP
Host Port: 0/TCP
As i see your selector in service is not matching the labels in Deployment , change to
metadata:
labels:
app: app-name
in your Deployment and it should work then.
Created a headless service:
myapp-service-headless.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp-service-headless
spec:
ports:
- port: 8000
selector:
app: myapp
clusterIP: None
After create it to Kubernetes cluster, check its service status:
$ kubectl create -f myapp-service-headless.yaml
$ kubectl describe service myapp-service-headless
Name: myapp-service-headless
Namespace: default
Labels: <none>
Annotations: <none>
Selector: app=myapp
Type: ClusterIP
IP: None
Port: <unset> 8000/TCP
TargetPort: 8000/TCP
Endpoints: 172.17.0.11:8000,172.17.0.9:8000
Session Affinity: None
Events: <none>
Try to connect 172.17.0.11:8000 or 172.17.0.9:8000, pending and no result.
Here using kube-dns: myapp-service-headless.default.svc.cluster.local in the application. Now it's in the container of pods.
So how to connect to these applications from other application via API? Which IP can been used?
Did you expose your container port inside your Endpoint (Pod)?
From what i knew, the headless service can be used to generate entries in kube-dns based on how you configure the Service, as discussed in this doc.
However, you can create another Service with type: NodePort that selects your backend Pods, and expose them on a NodePort/LB.