How to access to the services in kubernetes cluster when ssh to another VMs via proxy? - kubernetes

Consider if we build two VMs in a bare-metal server through a network, one is master and another is worker. I ssh to the master and construct a cluster using kubeadm which has three pods and a service with type: ClusterIP. So when I want access to the cluster I do kubectl proxy in the master. Now we can explore the API with curl and wget in the VM which we ssh to it, like this :
$ curl http://localhost:8080/api/
So far, so good! but I want access to the services by my laptop? The localhost which comes above is refer to the bare-metal server! How can access to the services through proxy by my laptop when cluster is placed in another machine?
When I do $ curl http://localhost:8080/api/ in my laptop it says :
127.0.0.1 refused to connect
which make sense! But what is the solution to this?

If you forward the port 8080 when sshing to master, you can use localhost on your laptop to access the apis on the cluster.
You can try adding the -L flag to your ssh command:
$ ssh -L 8080:localhost:8080 your.master.host.com
Then the curl to localhost will work.

You can also specify an extra arguments to the kubectl proxy command, to let your reverse-proxy server listening on non-default ip address (127.0.0.1) - expose outside
kubectl proxy --port=8001 --address='<MASTER_IP_ADDRESS>' --accept-hosts="^.*$"
You can get your Master IP address by issuing following command: kubectl cluster-info

Related

How to forward a k8 pod's port via jumphost

I can ssh into a jumphost from where I can accesss k8 cluster.
there is a particular pod which has a UI exposed on port 4040, how can I view that on my local browser ?
What I have figured out so far, by executing the below command
kubectl port-forward podName 4040:4040
I can now access the UI (by text based browser) on jumphost
Had to be done in two steps
1st run kubectl port-forward podName 4040:4040 from jumpbox
2nd run ssh -L 4040:localhost:4040 -i some_key.pem user#jumpbox-server from the local machine
access http://localhost:4040 using browser
Even though there is an accepted answer, my situation is little different. After connecting to the jumphost with ssh, I have tried the above port forwarding command and it was working fine but for some reason I can't access these exposed port using step 2 from my local machine.
Here is what I did. Added --address 0.0.0.0 to the existing port forward command.
Inside the Jumphost
kubectl port-forward podname --address 0.0.0.0 7000:8080 -n namespace
From my local machine, created a tunnel because I can't access our jumphost with user#jumphostname. So I have to use the resource id to specify the jumphost id, so I followed this command.
az network bastion tunnel --name hubname --resource-group
resourcegroupname --subscription subscriptionid --target-resource-id
vmresourceid --resource-port 7000 --port 8000
From local machine you can start using via postman or browser with http://localhost:8000
It might be useful to someone. :)

Access Kubernetes Dashboard using kubectl proxy remotly for multiple user

I have setup kubernetes cluster in EKS. API server access is in private mode. I have bastion host from which i can run kubectl commands. I want to access kubernetes dashboard remotly.
One thing i can do is ssh -L localhost:8001:127.0.0.1:8001 # kubectl proxy. this wil provide me an access remotly.
If somone else will execute ssh -L localhost:8001:127.0.0.1:8001 # kubectl proxy then it will get an error. "error: listen tcp 127.0.0.1:8001: bind: address already in use". Because somebody else is accessing kubectl proxy.
How to solve this issue. I want to access kubernetes dashboard on multiple machine at the same time.

Expose Kubernetes Ingress to LAN computers

I have computer A and B on LAN:
A at IP 192.168.0.104
B at IP 192.168.0.110
On computer B I have a Kubernetes service with ingress:
path hello
host hello-node.com
minikube ip is 192.168.49.2
/etc/hosts has a line:
192.168.49.2 hello-node.com
On B I see the service response to hello-node.com/hello but not to
192.168.49.2/hello. On 192.168.49.2/hello I see 404 error from nginx.
How do I access either hello-node.com/hello or 192.168.49.2/hello from computer A?
I do not want to rely on any 3rd party service (load balancer etc)
info:
minikube version: v1.16.0
$ kubectl cluster-info
Kubernetes control plane is running at https://192.168.49.2:8443
KubeDNS is running at https://192.168.49.2:8443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
Workaround without using ingress, but NodePort expose command. From link from #mariusz-k
kubectl expose deployment/hello-node --type="NodePort" --port 8080
SERVICE_NODE_IP=$(minikube ip)
FORWARD_PORT=8090
SERVICE_NODE_PORT=$(kubectl get services/hello-node -o go-template='{{(index .spec.ports 0).nodePort}}')
ssh -i ~/.minikube/machines/minikube/id_rsa docker#$SERVICE_NODE_IP -NL \*:$FORWARD_PORT:0.0.0.0:$SERVICE_NODE_PORT
You need to get the address of Computer B (the cluster ip) and then connect to it.
# Get the cluster "master" ip
$ kubectl cluster-info
Kubernetes master is running at https://<the desired ip/DNS record>......:443
# use the above ip to get the content of your service
curl -vsI <ip>/hello
You can access your minikube service from another machine by following steps from this github issue:
service_name=web # This is what you need to replace with your own service
service_port=$(minikube service $service_name --url | cut -d':' -f3)
ssh -i ~/.minikube/machines/minikube/id_rsa docker#$(minikube ip) -NL \*:${service_port}:0.0.0.0:${service_port}
After that your service will be available under `<minikube's-host-ip>:

kubectl port-forward to another endpoint

Is there a corresponding command with kubectl to:
ssh -L8888:rds.aws.com:5432 example.com
kubectl has port-forward you can also specify --address but that strictly requires an IP address.
The older answer is valid.
Still, a workaround would be to use something like
https://hub.docker.com/r/marcnuri/port-forward
kubectl run --env REMOTE_HOST=your.service.com --env REMOTE_PORT=8080 --env LOCAL_PORT=8080 --port 8080 --image marcnuri/port-forward test-port-forward
Run it on the cluster and then port forward to it.
kubectl port-forward test-port-forward 8080:8080
Short answer, No.
In OpenSSH, local port forwarding is configured using the -L option:
ssh -L 80:intra.example.com:80 gw.example.com
This example opens a connection to the gw.example.com jump server, and forwards any connection to port 80 on the local machine to port 80 on intra.example.com.
By default, anyone (even on different machines) can connect to the specified port on the SSH client machine. However, this can be restricted to programs on the same host by supplying a bind address:
ssh -L 127.0.0.1:80:intra.example.com:80 gw.example.com
You can read the docs here.
The port-forward in Kubernetes works only within the cluster, you can forward traffic that will hit specified port to Deployment or Service or a Pod
kubectl port-forward TYPE/NAME [options] [LOCAL_PORT:]REMOTE_PORT [...[LOCAL_PORT_N:]REMOTE_PORT_N]
--address flag is to specify what to listen on 0.0.0.0 means everything localhost is as name and you can set an IP on which it can be listening on.
Documentation is available here, you can also read Use Port Forwarding to Access Applications in a Cluster.
One workaround you can use if you have an SSH server somewhere on the Internet is to SSH to your server from your pod, port-forwarding in reverse:
# Suppose a web console is being served at
# http://my-service-8f6717ab-e.default:8888/
# inside your cluster:
kubectl exec -it my-job-f523b248-7htj6 -- ssh -R8888:my-service-8f6717ab-e.default:8888 user#34.23.1.2
Then you can connect to the service inside Kubernetes from outside of it. If the SSH server is not local to you, you can SSH to it from your local machine with a normal port forward:
me#my-macbook-pro:$ ssh -L8888:localhost:8888 user#34.23.1.2
Then point your browser to http://localhost:8888/

SSH to Kubernetes pod using Bastion

I have deployed Google cloud Kubernetes cluster. The cluster has internal IP only.
In order to access it, I created a virtual machine bastion-1 which has external IP.
The structure:
My Machine -> bastion-1 -> Kubernetes cluster
The connection to the proxy station:
$ ssh bastion -D 1080
now using kubectl using proxy:
$ HTTPS_PROXY=socks5://127.0.0.1:1080 kubectl get pods
No resources found.
The Kubernetes master server is responding, which is a good sign.
Now, trying to ssh a pod:
$ HTTPS_PROXY=socks5://127.0.0.1:1080 kubectl exec -it "my-pod" -- /bin/bash
error: error sending request: Post https://xxx.xxx.xxx.xxx/api/v1/namespaces/xxx/pods/pod-xxx/exec?command=%2Fbin%2Fbash&container=xxx&container=xxx&stdin=true&stdout=true&tty=true: EOF
Question:
How to allow ssh connection to pod via bastion? What I'm doing wrong?
You can't do this right now.
The reason is because the connections used for commands like exec and proxy use SPDY2.
There's a bug report here with more information.
You'll have to switch to using a HTTP proxy