I want to integrate my vuejs app into a minikube cluster.
I used the Dockerfile from the VueJs tutorial for the production with the Nginx webserver and with the first option localhost:8080 here. I changed the ports in the yml files accordingly meaning for the localhost to 8080 and for the nginx version as seen below to 80
Then in my config/index.js
dev: {
[...]
host: 'localhost', // can be overwritten by process.env.HOST
port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
autoOpenBrowser: false,
errorOverlay: true,
notifyOnErrors: true,
poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
[...]
},
I have set the default 8080 port. For my minikube deployment and service I added
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: vuejs
spec:
selector:
matchLabels:
app: vuejs
tier: frontend
replicas: 1
template:
metadata:
labels:
app: vuejs
tier: frontend
spec:
imagePullSecrets:
- name: regcred
containers:
- name: vuejs
image: <secret registry>
ports:
- containerPort: 80
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
---
apiVersion: v1
kind: Service
metadata:
name: vuejs
labels:
app: vuejs
tier: frontend
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 80
# Replace with the IP of your minikube java / master java
# externalIPs:
# - 192.168.99.105
selector:
app: vuejs
tier: frontend
How do I connect to the vuejs/nginx webserver. Moreover since I set the DNS name of the backend to java how do I set the java REST API address in vuejs?
I set the address to 'http://java:8080/' without any response. The Java REST backend is integrated into minikube with this yml.
The curios issue is that after starting the vuejs deployment I can access the vuejs app at 127.0.0.1:8080. When I understood correctly I thought that the kubernetes cluster opens up its own network and is only accessible via external IP
Looking at my kubectl get all I would say that vuejs should be reachable 192.168.99.105:8080 - when using the dockerimage without the nginx.
NAME READY STATUS RESTARTS AGE
pod/java-fbf949cbc-rqstq 0/1 Error 4 2d
pod/maria-7b67c8ddf-xp8xx 1/1 Running 2 2d
pod/private-reg 1/1 Running 5 5d
pod/vuejs-5f4c657d74-885j9 1/1 Running 1 18h
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/java LoadBalancer 10.101.207.98 192.168.99.100 8080:31011/TCP 2d
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 5d
service/maria ClusterIP 10.99.177.228 <none> 3306/TCP 2d
service/vuejs NodePort 10.104.108.44 192.168.99.105 8080:30001/TCP 17h
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
deployment.apps/java 1 1 1 0 2d
deployment.apps/maria 1 1 1 1 2d
deployment.apps/vuejs 1 1 1 1 18h
NAME DESIRED CURRENT READY AGE
replicaset.apps/java-fbf949cbc 1 1 0 2d
replicaset.apps/maria-7b67c8ddf 1 1 1 2d
replicaset.apps/vuejs-5f4c657d74 1 1 1 18h
You can use minikube service command to get the url exposed to your own host. For your deployment, try:
minikube service vuejs --url
It would show an IP with the NodePort added to it. Copy and paste the result of that command to your browser.
Update: How it works
Minikube starts a virtual machine inside your host (your laptop) with a single-node Kubernetes cluster, assigning a local IP that you can get with minikube ip command. That’s the IP of the Kubernetes node.
When you expose a "NodePort" service inside Kubernetes, it allocates a static port from range 30000-32767 (default) so you can access that service with <NodeIP>:<NodePort>
There are two ways to expose resources from a Kubernetes cluster:
Use an Ingress. For more information, you can visit this link.
Expose a Service. You can do it in two ways:
type: LoadBalancer. However, it works only with cloud providers.
type: NodePort. And it is the easiest way in your case, you need to change spec.type from LoadBalancer to NodePort in your YAML description for the Service. After that, to access service inside the Kubernetes cluster, you need to use the IP address of your Node and the port from the field nodePort. For example, 192.168.12.34:30001
Related
I'm running my Kubernetes Cluster using Docker and not using Minikube Cluster (requires a lot of memory) however after applying the required files, I can't get an external URL (like I used to have when I used Minikube) to run it in my Chrome browser.
Consider the followings:
The Pod:
apiVersion: v1
kind: Pod
metadata:
name: webapp-release-0-5
labels:
app: webapp
release: "0-5"
spec:
containers:
- name: webapp
image: richardchesterwood/k8s-fleetman-webapp-angular:release0-5
And its Service :
apiVersion: v1
kind: Service
metadata:
name: fleetman-webapp
spec:
# This defines which pods are going to be represented by this Service
# The service becomes a network endpoint for either other services
# or maybe external users to connect to (eg browser)
selector:
app: webapp
release: "0-5"
ports:
- name: http
port: 80
nodePort: 30080
type: NodePort
After applying both from Command line (WINDOWS 10 CLI) :
>>> kubectl get services
fleetman-webapp NodePort 10.96.227.189 <none> 80:30080/TCP 5m57s
>>> kubectl get po
webapp 1/1 Running 0 12m
webapp-release-0-5 1/1 Running 0 12m
However, I don't have an external URL of this POD to put in my browser to check out the App, like I used to have in Minikube.
How can we generate such URL?
It's particularly hard to make it work in a bespoke way. I would suggest to use kind which creates kubernetes nodes as docker container. You can access NodePort service via http://<NODEIP>:<NODEPORT>. To get NODEIP use kubectl get nodes
hope you all well!
I need to see my app on the browser but I believe that I'm missing something here and hope you can help me with this.
[root#kubernetes Docker]# kubectl get all
NAME READY STATUS RESTARTS AGE
pod/my-app2-56d5c786dd-n7mqq 1/1 Running 0 19m
pod/nginx-86c57db685-bxkpl 1/1 Running 0 13h
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 31h
service/my-app2 ClusterIP 10.101.108.199 <none> 8085/TCP 12m
service/nginx NodePort 10.106.14.144 <none> 80:30525/TCP 13h
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/my-app2 1/1 1 1 19m
deployment.apps/nginx 1/1 1 1 13h
NAME DESIRED CURRENT READY AGE
replicaset.apps/my-app2-56d5c786dd 1 1 1 19m
replicaset.apps/nginx-86c57db685 1 1 1 13h
Overall you can see that everything is working fine right, looks the same to me.
To open this on my browser I'm using my IP address from Slave node where the container is allocated.
On my app I'm mapping the Hello like this #RequestMapping("/Hello")
On my dockerfile to build my image i used this:
[root#kubernetes project]# cat Dockerfile
FROM openjdk:8
COPY microservico-0.0.1-SNAPSHOT.jar microservico-0.0.1-SNAPSHOT.jar
#WORKDIR /usr/src/microservico-0.0.1-SNAPSHOT.jar
EXPOSE 8085
ENTRYPOINT ["java", "-jar", "microservico-0.0.1-SNAPSHOT.jar"]
So at the end, I think I need to call for my app this way.
---> ip:8085/Hello
[root#kubernetes project]# telnet kubeslave 8085
Trying 192.168.***.***...
telnet: connect to address 192.168.***.***: Connection refused
but I still see nothing...
Here is my deploy and service:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app2
labels:
app: app
spec:
selector:
matchLabels:
app: app
role: master
tier: backend
replicas: 1
template:
metadata:
labels:
app: app
role: master
tier: backend
spec:
containers:
- name: appcontainer
image: *****this is ok*****:my-java-app
resources:
requests:
cpu: 100m
memory: 100Mi
ports:
- containerPort: 8085
apiVersion: v1
kind: Service
metadata:
name: my-app2
labels:
app: app
role: master
tier: backend
spec:
ports:
- port: 8085
targetPort: 8085
selector:
app: app
role: master
tier: backend
You have create a service which is of type ClusterIP(default). This type of service is only for accessing from inside the kubernetes cluster.For accessing it from browser you need to expose the pod via LoadBalancer or Nodeport service. LoadBalancer only works if you are one of supported public cloud otherwise Nodeport need to be used.
https://kubernetes.io/docs/tutorials/stateless-application/expose-external-ip-address/
https://kubernetes.io/docs/tasks/access-application-cluster/service-access-application-cluster/
Other than using service you can use kubectl proxy to access it as well.
If you are on Minikube then follow this
https://kubernetes.io/docs/tutorials/hello-minikube/
Is it true that I cannot have two LoadBalancer services on a docker-desktop cluster (osx), because they would both use localhost (and all ports are forwarded)?
I created an example and the latter service is never assigned an external IP address but stays in state pending. However, the former is accessible on localhost.
> kubectl get all
NAME READY STATUS RESTARTS AGE
pod/whoami-deployment-9f9c86c4f-l5lkj 1/1 Running 0 28s
pod/whoareyou-deployment-b896ddb9c-lncdm 1/1 Running 0 27s
pod/whoareyou-deployment-b896ddb9c-s72sc 1/1 Running 0 27s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 95s
service/whoami-service LoadBalancer 10.97.171.139 localhost 80:30024/TCP 27s
service/whoareyou-service LoadBalancer 10.97.171.204 <pending> 80:32083/TCP 27s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/whoami-deployment 1/1 1 1 28s
deployment.apps/whoareyou-deployment 2/2 2 2 27s
NAME DESIRED CURRENT READY AGE
replicaset.apps/whoami-deployment-9f9c86c4f 1 1 1 28s
replicaset.apps/whoareyou-deployment-b896ddb9c 2 2 2 27s
Detailed state fo whoareyou-service:
kubectl describe service whoareyou-service
Name: whoareyou-service
Namespace: default
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"whoareyou-service","namespace":"default"},"spec":{"ports":[{"name...
Selector: app=whoareyou
Type: LoadBalancer
IP: 10.106.5.8
Port: http 80/TCP
TargetPort: 80/TCP
NodePort: http 30333/TCP
Endpoints: 10.1.0.209:80,10.1.0.210:80
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
I decided to copy my comments, as they partially explain the problem, and make a Community Wiki answer out of them so it is more clearly seen and available for possible further edits by the Community:
It works probably exactly the same way as in Minikube. As docker-desktop is unable to provision real LoadBalancer it can still "simulate" creating Service of such type using NodePort (this can easily be seen from port range it uses). I'm pretty sure you cannot use same IP address as the ExternalIP of the LoadBalancer Service and if you create one more Service of such type, your docker-desktop has no other choice than to use your localhost one more time. As it is already used by one Service it cannot be used by another one and that's why it remains in a pending state.
Note that if you create real LoadBalancer in a cloud environment, each time new IP is provisioned and there is no situation that next LoadBalancer you create gets the same IP that is already used by the existing one. Apparently here it cannot use any other IP then one of localhost, and this one is already in use. Anyway I would recommend you to simply use NodePort if you want to expose your Deployment to the external world.
Think about using Ingress controller instead.
So basically, it's 3 steps after installing docker-desktop :
Wilcard Certificate locally
SSL certificate For local env
Install Ingress Controller
Detailed here: https://github.com/kubernetes-tn/guideline-kubernetes-enterprise/blob/master/general/desktop-env-setup.md
I came across this question while looking to set up a lightweight local environment with minimal dependencies.
I found that two LoadBalancer work on localhost when using different port numbers.
---
apiVersion: v1
kind: Service
metadata:
name: webapp-one-lb
spec:
ports:
- name: 8081-tcp
port: 8081
protocol: TCP
targetPort: 8080
selector:
name: webapp-one
type: LoadBalancer
status:
loadBalancer: {}
---
apiVersion: v1
kind: Service
metadata:
name: webapp-two-lb
spec:
ports:
- name: 8082-tcp
port: 8082
protocol: TCP
targetPort: 8080
selector:
name: webapp-two
type: LoadBalancer
status:
loadBalancer: {}
As others have said, Ingress is more flexible and allows for sub-domain and path based routing without having to worry about port conflicts, but it comes with an additional learning curve.
I am using kubernetes and run one service. Service is running and is showing in service. But i am not able to access it from the public ip of the instance. Below is my deployment file.
apiVersion: v1
kind: Service
metadata:
name: apache-service
spec:
selector:
app: apache
ports:
- protocol: TCP
port: 80
targetPort: 80
type: NodePort
---
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: apache-deployment
spec:
selector:
matchLabels:
app: apache
replicas: 2 # tells deployment to run 2 pods matching the template
template:
metadata:
labels:
app: apache
spec:
containers:
- name: apache
image: mobingi/ubuntu-apache2-php7:7.2
ports:
- containerPort: 80
Here is my list of service.
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
apache-service NodePort 10.106.242.181 <none> 80:31807/TCP 9m5s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 11m
But when i check the same service from the follwing telnet with the public ip of cluster and node. It is not responding.
telnet public-ip:31807
Any type of help will be appreciable.
What do you mean by cluster IP? Do you mean the node that acts as kunernetes master? It won't work if you use master IP. Because masters don't have deployments scheduled due to security concerns.
Exposing a service via nodeport means that the service listens to a particular port in each of the worker nodes. So you can access the kunernetes worker nodes with the nodeports and get response. However if you created the cluster using cloud providers like aws, the worker nodes security groups are secured. Probably, you need to edit the security groups of worker nodes to access the service.
I'm trying to expose my api so I can send request to it. However when I used the command minikube service api --url I get nothing. All my pods are running fine according to kubectl get pods so I'm abit stuck about what this could be.
api-1007925651-0rt1n 1/1 Running 0 26m
auth-1671920045-0f85w 1/1 Running 0 26m
blankit-app 1/1 Running 5 5d
logging-2525807854-2gfwz 1/1 Running 0 26m
mongo-1361605738-0fdq4 1/1 Running 0 26m
jwl:.build jakewlace$ kubectl get services
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
api 10.0.0.194 <none> 3001/TCP 23m
auth 10.0.0.36 <none> 3100/TCP 23m
kubernetes 10.0.0.1 <none> 443/TCP 5d
logging 10.0.0.118 <none> 3200/TCP 23m
mongo 10.0.0.132 <none> 27017/TCP 23m
jwl:.build jakewlace$
jwl:.build jakewlace$ minikube service api --url
jwl:.build jakewlace$
Any help would be massively appreciated, thank you.
I realised that the question here could be perceived as being minimal, but that is because I'm not sure what more information I could show from the tutorials I've been following it should just work. If you need more information please do let me know I will let you know.
EDIT:
api-service.yml
apiVersion: v1
kind: Service
metadata:
creationTimestamp: null
labels:
io.kompose.service: api
name: api
spec:
ports:
- name: "3001"
port: 3001
targetPort: 3001
selector:
io.kompose.service: api
status:
loadBalancer: {}
api-deployment.yml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
creationTimestamp: null
labels:
io.kompose.service: api
name: api
spec:
replicas: 1
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
io.kompose.service: api
spec:
containers:
- image: blankit/web:0.0.1
name: api
imagePullPolicy: IfNotPresent
ports:
- containerPort: 3001
resources: {}
restartPolicy: Always
status: {}
Your configuration is fine, but only missing one thing.
There are many types of Services in Kubernetes, but in this case you should know about two of them:
ClusterIP Services:
Exposes the service on a cluster-internal IP. Choosing this value makes the service only reachable from within the cluster. This is the default.
NodePort:
Exposes the service on each Node’s IP at a static port (the NodePort). A ClusterIP service, to which the NodePort service will route, is automatically created. You’ll be able to contact the NodePort service, from outside the cluster, by requesting <NodeIP>:<NodePort>.
Note:
If you have a multi-node cluster and you've exposed a NodePort Service, you can access is from any other node on the same port, not necessarily the same node the pod is deployed onto.
So, getting back to your service, you should specify the service type in your spec:
kind: Service
apiVersion: v1
metadata:
...
spec:
type: NodePort
selector:
...
ports:
- protocol: TCP
port: 3001
Now if you minikube service api --url, it should return a URL like http://<NodeIP>:<NodePort>.
Note: The default Kubernetes configuration will chose a random port from 30000-32767. But you can override that if needed.
Useful references:
Kubernetes / Publishing services - service types
Kubernetes / Connect a Front End to a Back End Using a Service