I create a yaml file to create rabbitmq kubernetes cluster. I can see pods. But when I write kubectl get deployment. I cant see there. I can't access to rabbitmq ui page.
apiVersion: v1
kind: Service
metadata:
labels:
app: rabbit
name: rabbit
spec:
ports:
- port: 5672
protocol: TCP
name: mqtt
- port: 15672
protocol: TCP
name: ui
type: NodePort
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: rabbit
spec:
serviceName: rabbit
replicas: 3
selector:
matchLabels:
app: rabbit
template:
metadata:
labels:
app: rabbit
spec:
containers:
- name: rabbitmq
image: rabbitmq
nodeSelector:
rabbitmq: "clustered"
#arghya-sadhu's answer is correct.
NB I'm unfamiliar with RabbitMQ but you may need to use a different image (see 'Management Plugin`) to include the UI.
See below for more details.
You should be able to hack your way to the UI on one (!) of the Pods via:
PORT=8888
kubectl port-forward pod/rabbit-0 --namespace=${NAMESPACE} ${PORT}:15672
And then browse localhost:${PORT} (if 8888 is unavailable, try another).
I suspect (!) this won't work unless you use the image with the management plugin.
Plus
The Service needs to select the StatefulSet's Pods
Within the Service spec you should add perhaps:
selector:
app: rabbit
Presumably (!?) you are using a private repo (because you have imagePullSecrets).
If you don't and wish to use DockerHub, you may remove the imagePullSecrets section.
It's useful to document (!) container ports albeit not mandatory:
In the StatefulSet
ports:
- containerPort: 5672
- containerPort: 15672
Debug
NAMESPACE="default" # Or ...
Ensure the StatefulSet is created:
kubectl get statesfulset/rabbit --namespace=${NAMESPACE}
Check the Pods:
kubectl get pods --selector=app=rabbit --namespace=${NAMESPACE}
You can check the the Pods are bound to a (!) Service:
kubectl describe endpoints/rabbit --namespace=${NAMESPACE}
NB You should see 3 addresses (one per Pod)
Get the NodePort either:
kubectl get service/rabbit --namespace=${NAMESPACE} --output=json
kubectl describe service/rabbit --namespace=${NAMESPACE}
You will need to use the NodePort to access both the MQTT endpoint and the UI.
statefulsets and deployments are different kubernetes resources. You have created statefulsets. That's why you don't see deployments. If you do
kubectl get statefulset you should see it and also both statefulset and deployment creates pod finally so you should be able to see rabbitmq pods if you do kubectl get pods
Since you have created a Nodeport service. You should be able to access it via http://nodeip:nodeport where nodeip is ip of any worker node in your kubernetes cluster.
You can get to know what is the Nodeport(a number between 30000-32767) by
kubectl describe services rabbit
Here is the doc on accessing a Nodeport service from outside the cluster.
Related
I am new to kubernetes , I have created two ec2 ubuntu:20 instances in aws and enabled the required ports using security-groups, two nodes i mean master-node and worker-node are working fine and i deployed the webapp using yaml file, pod and svc are working fine.
However when i copy and paste master-node ip:port in browser, master-node cant able to access the application but when i use the worker-node able to access the application
if any one suggested me that would be helpfull for me
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp-deployment
spec:
selector:
matchLabels:
app: webapp
replicas: 5
template:
metadata:
labels:
app: webapp
spec:
containers:
- name: webapp
image: janaid/demoreactjs
ports:
- containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
name: webapp-service
spec:
selector:
app: webapp
type: NodePort
ports:
- protocol: TCP
port: 3000
targetPort: 3000
nodePort: 32001
hello, hope you are enjoying your kubernetes journey!
This is probably because by default, your master node is only used for the kubernetes control plane and not for your applications workloads.
That means that your webapp pod will only be deployed on your worker node
However, to enable your master node to accept workloads deployed on it, you have to remove the native taint label on the master node (not a best practice) here is a guide you can follow:
https://computingforgeeks.com/how-to-schedule-pods-on-kubernetes-control-plane-node/#:~:text=If%20you%20want%20to%20be,taint%20on%20the%20master%20nodes.&text=This%20will%20remove%20the%20node,able%20to%20schedule%20pods%20everywhere
( unless you have configured it to accept pods deployment? Btw, correct me if i am wrong but your kubectl get pod -o wide shows us 3ips but you have only two nodes right? )
Keep in touch.
I don't think I miss anything, but my angular app doesn't seem to be able to contact the service I exposed trough Kubernetes.
Whenever I try to call the exposed nodeport on my localhost, I get a connection refused.
The deployment file
apiVersion: apps/v1
kind: Deployment
metadata:
name: society-api-gateway-deployment
spec:
replicas: 1
selector:
matchLabels:
app: society-api-gateway-deployment
template:
metadata:
labels:
app: society-api-gateway-deployment
spec:
containers:
- name: society-api-gateway-deployment
image: tbusschaert/society-api-gateway:latest
ports:
- containerPort: 80
The service file
apiVersion: v1
kind: Service
metadata:
name: society-api-gateway-service
spec:
type: NodePort
selector:
app: society-api-gateway-deployment
ports:
- name: http
port: 80
targetPort: 80
nodePort: 30001
I double checked, the call doesn't reach my pod, and this is the error I get when going the call:
I'm using minikube and kubectl on my local machine.
I'm out of options, tried everything I though it could be, thanks in advance.
EDIT 1:
So after following the suggestions, i used the node IP to call the service:
I changed the IP in my angular project, now I get a connection timeout:
As for the port forward, I get a permission error:
So, as I thought, the problem was related to minikube not opening up to my localhost.
First of all I didn't need a NodePort, but the LoadBalancer also fit my need, so my API gateway became a LoadBalancer.
Second, when using minikube, to achieve what I wanted ( running kubernetes on my local machine and my angular client also being on my local machine ), you have to create a minikube tunnel, exactly how they explain it here: https://minikube.sigs.k8s.io/docs/handbook/accessing/#run-tunnel-in-a-separate-terminal
From doc, you see that the templeate will be like this <NodeIP>:<NodePort>.
NodePort: Exposes the Service on each Node's IP at a static port (the NodePort). A ClusterIP Service, to which the NodePort Service routes, is automatically created. You'll be able to contact the NodePort Service, from outside the cluster, by requesting <NodeIP>:<NodePort>.
So first, From kubectl get node -o wide comamnd take the NodeIP.
then try with the <NodeIP>:<NodePort>. For example, If the NodeIP is 172.19.0.2 then try 172.19.0.2:30001 with your sub url.
Or, Another way is with port-forwarding. In a terminal first try port-forwarding with kubectl port-forward svc/society-api-gateway-service 80:80. Then use the url you have tried with localhost.
I have a minikube cluster with two pods (with ubuntu containers). What I need to do is route test traffic from one port to another through this minikube cluster. This traffic should be sent through these two pods like in the picture. I am a beginner in this Kubernetes stuff so I really don't know how to do this and which way to go... Please, help me or give me some hints.
I am working on ubuntu server ver. 18.04.
enter image description here
I agree with an answer provided by #Harsh Manvar and I would also like to expand a little bit on this topic.
There already is an answer with a similar setup. I encourage you to check it out:
Stackoverflow.com: Questions: How to access a service from other machine in LAN
There are different drivers that could be used to run your minikube. They will have differences when it comes to dealing with inbound traffic. I missed the part that was telling about the driver used in the setup (comment). If it's the Docker shown in the tags, you could follow below example.
Example
Steps:
Spawn nginx-one and nginx-two Deployments to imitate Pods from the image
Create a service that will be used to send traffic from nginx-one to nginx-two
Create a service that will allow you to connect to nginx-one from LAN
Test the setup
Spawn nginx-one and nginx-two Deployments to imitate Pods from the image
You can use following definitions to spawn two Deployments where each one will have a single Pod:
nginx-one.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-one
spec:
selector:
matchLabels:
app: nginx-one
replicas: 1
template:
metadata:
labels:
app: nginx-one
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
nginx-two.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-two
spec:
selector:
matchLabels:
app: nginx-two
replicas: 1
template:
metadata:
labels:
app: nginx-two
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
Create a service that will be used to send traffic from nginx-one to nginx-two
You will need to use a Service to send the traffic from nginx-one to nginx-two. Example of such Service could be following:
apiVersion: v1
kind: Service
metadata:
name: nginx-two-service
spec:
type: ClusterIP # could be changed to NodePort
selector:
app: nginx-two # IMPORTANT
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
After applying this definition you will be able to send the traffic to nginx-two by using the service name (nginx-two-service)
A side note!
You can use the IP of the Pod without the Service but this is not a recommended way.
Create a service that will allow you to connect to nginx-one from LAN
Assuming that you want to expose your minikube instance to LAN with Docker driver you will need to create a service and expose it. Example of such setup could be the following:
apiVersion: v1
kind: Service
metadata:
name: nginx-one-service
spec:
type: ClusterIP # could be changed to NodePort
selector:
app: nginx-one # IMPORTANT
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
You will also need to run:
$ kubectl port-forward --address 0.0.0.0 service/nginx-one-service 8000:80
Above command (ran on your minikube host!) will expose your nginx-one-service to be available on LAN. It will map port 8000 on the machine that ran this command to the port 80 of this service. You can check it by executing from another machine at LAN:
curl IP_ADDRESS_OF_MINIKUBE_HOST:8000
A side note!
You will need root access to have your inbound traffic enter on ports lesser than 1024.
Test the setup
You will need to check if there is a communication between the objects as shown in below "connection diagram".
PC -> nginx-one -> nginx-two -> example.com
The testing methodology could be following:
PC -> nginx-one:
Run on a machine in your LAN:
curl MINIKUBE_IP_ADDRESS:8000
nginx-one -> nginx-two:
Exec into your nginx-one Pod and run command:
$ kubectl exec -it NGINX_POD_ONE_NAME -- /bin/bash
$ curl nginx-two-service
nginx-two -> example.com:
Exec into your nginx-two Pod and run command:
$ kubectl exec -it NGINX_POD_TWO_NAME -- /bin/bash
$ curl example.com
If you completed above steps you can swap nginx Pods for your own software.
Additional notes and resources:
I encourage you to check kubeadm as it's the tool to create your own Kubernetes clusters:
Kubernetes.io: Docs: Setup: Production environment: Tools: Kubeadm: Create cluster kubeadm
As you said:
I am a beginner in this Kubernetes stuff so I really don't know how to do this and which way to go... Please, help me or give me some hints.
You could check following links for more resources:
Kubernetes.io
Kubernetes: Docs: Concepts: Workloads: Controllers: Deployment
Kubernetes.io: Docs: Concepts: Services networking: Service
There are multiple options you can follow:
As you have two PODs you can expose one via service,
so service-1 is exposed and sending traffic to POD-1
POD-1 will send a request to service-2 of Kubernetes
This way traffic will get forwarded to POD-2 and from there it will Go out of cluster
There is also a container to container communication possibility if you can run both applications in a single POD.
POD-1 to POD-2 communication you can use the service option or POD URI.
I have a simple Express.js server Dockerized and when I run it like:
docker run -p 3000:3000 mytag:my-build-id
http://localhost:3000/ responds just fine and also if I use the LAN IP of my workstation like http://10.44.103.60:3000/
Now if I deploy this to MicroK8s with a service deployment declaration like:
apiVersion: v1
kind: Service
metadata:
creationTimestamp: null
name: my-service
spec:
type: NodePort
ports:
- name: "3000"
port: 3000
targetPort: 3000
status:
loadBalancer: {}
and pod specification like so (update 2019-11-05):
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
name: my-service
spec:
replicas: 1
selector:
matchLabels:
name: my-service
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
name: my-service
spec:
containers:
- image: mytag:my-build-id
name: my-service
ports:
- containerPort: 3000
resources: {}
restartPolicy: Always
status: {}
and obtain the exposed NodePort via kubectl get services to be 32750 and try to visit it on the MicroK8s host machine like so:
curl http://127.0.0.1:32750
then the request just hangs and if I try to visit the LAN IP of the MicroK8s host from my workstation at
http://192.168.191.248:32750/
then the request is immediately refused.
But, if I try to port forward into the pod with
kubectl port-forward my-service-5db955f57f-q869q 3000:3000
then http://localhost:3000/ works just fine.
So the pod deployment seems to be working fine and example services like the microbot-service work just fine on that cluster.
I've made sure the Express.js server listens on all IPs with
app.listen(port, '0.0.0.0', () => ...
So what can be the issue?
You need to add a selector to your service. This will tell Kubernetes how to find your deployment. Additionally you can use nodePort to specify the port number of your service. After doing that you will be able to curl your MicroK8s IP.
Your Service YAML should look like this:
apiVersion: v1
kind: Service
metadata:
creationTimestamp: null
name: my-service
spec:
type: NodePort
ports:
- name: http
port: 80
targetPort: 80
nodePort: 30001
selector:
name: my-service
status:
loadBalancer: {}
the LAN IP of the MicroK8s host from my workstation
That is the central source of your misunderstanding; localhost, 127.0.0.1, and your machine's LAN IP have nothing to do with what is apparently a virtual machine running microk8s (which it would have been infinitely valuable to actually include that information in your question, rather than us having to deduce it from one buried sentence)
I've made sure the Express.js server listens on all IPs with
Based on what you reported later:
at http://192.168.191.248:32750/ then the request is immediately refused.
then it appears that your express server is not, in fact, listening on all interfaces. That explains why you can successfully port-forward into the Pod (which causes traffic to appear on the Pod's localhost) but not reach it from "outside" the Pod
You can also test that theory by using another Pod inside the cluster to curl its Pod IP on port 3000 (in order to side-step the Service and thus NodePort parts)
There is a small chance that you have misconfigured your Pod and Service relationship, but since you didn't post your PodSpec, and the behavior you are describing sounds a lot more like an express misconfiguration, we'll go with that until we have evidence to the contrary
I have created a kubernetes cluster and deployed jenkins by following file
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: jenkins-ci
spec:
replicas: 1
template:
metadata:
labels:
run: jenkins-ci
spec:
containers:
- name: jenkins-ci
image: jenkins:2.32.2
ports:
- containerPort: 8080
and service by
apiVersion: v1
kind: Service
metadata:
name: jenkins-cli-lb
spec:
type: NodePort
ports:
# the port that this service should serve on
- port: 8080
nodePort: 30000
# label keys and values that must match in order to receive traffic for this service
selector:
run: jenkins-ci
Now i can access jenkins UI in my browser without any problems. My issue I came into situation in which need to restart jenkins service manually??
Just kubectl delete pods -l run=jenkins-ci - Will delete all pods with this label (your jenkins containers).
Since they are under Deployment, it will re-create the containers. Network routing will be adjusted automatically (again because of the label selector).
See https://kubernetes.io/docs/reference/kubectl/cheatsheet/
You can use command below to enter the pod container.
$ kubectl exec -it kubernetes pod -- /bin/bash
After apply service Jenkins restart command.
For more details please refer :how to restart service inside pod in kubernetes cluster.