What are the best solutions to replace kubernetes port-forward - kubernetes

I am working on rancher server, k3s to improve my knowledge on these solutions.
I want to expose container services on LAN network, this is why I used kubectl port-forward.
kubectl port-forward --namespace=ns-name --address LAN-IP service/hello 30104:8080
But I can see in several web resources that is not a reliable solution, just for local testing purpose.
I tried to replace them by ingress but I am a bit lost between ingress, DNS and nginx-ingress in addition to rancher component.
I understood than load balancer need a cloud provider, to have a public IP for instance, and handle the <pending> state of load balancer.
Can you highlight me on how replace port-forward in LAN without a cloud provider?
[edit #Rajesh Dutta]
I already use NodePort, but, without port-forward the service is exposed as NODE_IP:PORT, not LAN_IP:PORT. My need is to join it from outside of the cluster.
So this is what i did :
1 - create deployment
kubectl create deployment hello --image=gcr.io/google-samples/node-hello:1.0 --port=8080 --replicas=2
2 - expose deployment(create service)
kubectl expose deployment hello --type=NodePort
3 - forward service
kubectl port-forward --namespace=ns-name --address local-ip service/hello 30104:8080
IP schema
Now, considering that i will have several service, i would find the best ways to replace port-forward.

To start with I would recommend to use NodePort service. This will expose your application to a NodePort(30000-32767). Later if you want you can choose to switch to ingress.
Assuming that you are trying with a deployment type object
command:
kubectl expose deployment deployment-name --type=NodePort --port=8080 --target-port=<rancher server port>

Related

Difference between kubectl port-forwarding and NodePort service

Whats the difference between kubectl port-forwarding (which forwards port from local host to the pod in the cluster to gain access to cluster resources) and NodePort Service type ?
You are comparing two completely different things. You should compare ClusterIP, NodePort, LoadBalancer and Ingress.
The first and most important difference is that NodePort expose is persistent while by doing it using port-forwarding, you always have to run kubectl port-forward ... and kept it active.
kubectl port-forward is meant for testing, labs, troubleshooting and not for long term solutions. It will create a tunnel between your machine and kubernetes so this solution will serve demands from/to your machine.
NodePort can give you long term solution and it can serve demands from/to anywhere inside the network your nodes reside.
If you use port forwarding kubectl port forward svc/{your_service} -n {service_namespace} you just need a clusterIP, kubectl will handle the traffic for you. Kubectl will be the proxy for your traffic
If you use nodeport for access your service means you need to open port on the worker nodes.
when you use port forwarding, that is going to cause our cluster to essentially behave like it has a node port service running inside of it without creating a service. This is strictly for the development setting. with one command you will have a node port service.
// find the name of the pod that running nats streaming server
kubectl get pods
kubectl port-forward nats-Pod-5443532542c8-5mbw9 4222:4222
kubectl will set up proxy that will forward any trafic on your local machine to a port on that specific pod.
however, to create a node port you need to write a YAML config file to set up a service. It will expose the port permanently and performs load balancing.

How do I use minikube's DNS?

How do I use minikube's (cluster's) DNS? I want to receive all IP addresses associated with all pods for selected headless service? I don’t want to expose it outside the cluster. I am currently creating back-end layer.
As stated in the following answer:
What exactly is a headless service, what does it do/accomplish, and what are some legitimate use cases for it?
„Instead of returning a single DNS A record, the DNS server will return multiple A records for the service, each pointing to the IP of an individual pod backing the service at that moment.”
Thus the pods in back-end layer can communicate to each other.
I can’t use dig command. It is not installed in minikube. Eventually how do I install it? There is no apt available.
I hope this explains more accurately what I want to achieve.
You mentioned that you want to receive IP addresses associated with pods for selected service name for testing how does headless service work.
For only testing purposes you can use port-forwarding. You can forward traffic from your local machine to dns pod in your cluster. To do this, you need to run:
kubectl port-forward svc/kube-dns -n kube-system 5353:53
and it will expose kubs-dns service on your host. Then all you need is to use dig command (or alternative) to query the dns server.
dig #127.0.0.1 -p 5353 +tcp +short <service>.<namespace>.svc.cluster.local
You can also test your dns from inside of cluster e.g. by running a pod with interactive shell:
kubectl run --image tutum/dnsutils dns -it --rm -- bash
root#dns:/# dig +search <service>
Let me know it it helped.
As illustrated in kubernetes/minikube issue 4397
Containers don't have an IP address by default.
You'll want to use minikube service or minikube tunnel to get endpoint information.
See "hello-minikube/ Create a service":
By default, the Pod is only accessible by its internal IP address within the Kubernetes cluster.
To make the hello-node Container accessible from outside the Kubernetes virtual network, you have to expose the Pod as a Kubernetes Service.
Expose the Pod to the public internet using the kubectl expose command:
kubectl expose deployment hello-node --type=LoadBalancer --port=8080
The --type=LoadBalancer flag indicates that you want to expose your Service outside of the cluster.
View the Service you just created:
kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-node LoadBalancer 10.108.144.78 <pending> 8080:30369/TCP 21s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP
On Minikube, the LoadBalancer type makes the Service accessible through the minikube service command.
Run the following command:
minikube service hello-node

adding node port to an exciting istio service

I created a local kubernetes cluster with a master and 2 workers using VM(ubuntu 16.04)
I am also using calico for networking and I am exploring istio for the moment.
my problem is the ingress load balancer doesn't get an external IP. to my understanding I should use a node port to access the ingress load balancer but I can find how to do so.
should I have done it when installing, can I add it now and how?
kubernetes version : v1.11.1
calico version : v3.1
istio version : 0.8.0
If don't have a service attached to your deployment, you can use kubectl expose:
kubectl expose deployment istio --type=NodePort --name=istio-service
If you already deployed a service, you can edit the service spec and add type: "NodePort" the quickest way to do this is using kubectl patch:
kubectl patch svc istio-service -p '{"spec":{"type":"NodePort"}}'
More info about NodePort services can be found here

Exposing kubernetes service locally (without minikube)

I'm using lxc/lxd to play with the kubenetes cluster.
Is there a way to expose a deployed service locally without using minikube, so that I could access it from the local machine?
I can access it from any of the nodes in the cluster but not from outside.
Do you want to acccess the pod being served by the service? if yes, you can use kubectl port-forward to connect to your pod and access it locally
Here is an example:
If you have a service which forwards all the requests to a pod ( nginx ) at port number 80 you can configure it to your local port as follows
kubectl port-forward -n default nginx-5767f4d585-hgtfj 8081:80
Here is the syntax of the same
kubectl port-forward -n NAMESPACE ${POD} local-port:pod-port
If you want to connect to your service directly, you need to do it via kubectl proxy
Here is a reference
Hope it helps.

How do I externally access a service with kubernetes NodePort?

I've setup a NodePort service using the following config:
wordpress-service.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app: wordpress
name: wordpress
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
protocol: TCP
selector:
app: wordpress
Is this sufficient to access the service externally, if so how can I now access the service? What details do I need - and how do I determine them - for example node IP.
For Kubernetes on GCE:
We had the same question regarding services of type NodePort: How do we access node port services from our own host?
#ivan.sim 's answer (nodeIp:nodePort) is on mark however, you still wouldn't be able to access your service unless you add a firewall ingress (inbound to google cloud) traffic rule on the VPC network console to allow your host to be able to access your compute node
the above rule is dangerous and should be used only during development
You can find the node port using either the Google Cloud console or by running subsequent kubectl commands to find out the node running your pod which has your container. i.e kubectl get pods , kubectl describe pod your-pod-name, kubectl describe node node-that-runs-you-pod .status.addresses has your ExternalIP
It would be great if we could extract the node ip running our container in the pod using only a label/selector and a few line of commands, so here is what we did, in this case our selector is app: your-label:
$ nodename=$(kubectl get pods -o jsonpath='{.items[?(#.metadata.labels.app=="your-label")].spec.nodeName}')
$ nodeIp=$(kubectl get nodes -o jsonpath='{.items[?(#.metadata.name=="'$(echo $nodename)'")].status.addresses[?(#.type=="ExternalIP")].address}')
$ echo nodeIp
notice: we used json path to extract the information we desired, for more on json path see: json path
You could certainly turn this into a script that takes a label/selector as input and outputs an external ip of the node running your container !!!
To get the nodeport just type:
$ kubectl get services
under the PORT(S) columns you will see something like tagetPort:nodePort. this nodeport is what you want .
nodeIp:nodePort
When you define a service as type NodePort, every node in your cluster will proxy that port to your service. If you nodes are reachable from outside the Kubernetes cluster, you should be able to access the service at nodeIP:nodePort.
To determine nodeIP of a particular node, you can use either kubectl get no <node> -o yaml or kubectl describe no <node>. The status.Addresses field will be of interest. Generally, you will see fields like HostName, ExternalIP and InternalIP there.
To determine nodePort of your service, you can use either kubectl get svc wordpress -o yaml or kubectl describe svc wordpress. The spec.ports.nodePort is the port you need.
Service defined like this got assgned a high port number and is exposed on all your cluster nodes on that port (probably something like 3xxxx). Hard to tell the rest without proper knowledge of how your cluster is provisioned. kubectl get nodes should give you some knowledge about your nodes.
Although I assume you want to expose the service to the outside world. In the long run I suggest getting familiar with LoadBalancer type services and Ingress / IngressController