1.4. Exposing VM Ports
In the previous chapter, we accessed our VM console using the virtctl tool. In this section we will expose the SSH port
of our VM and access it directly.
Note
This can be done for any port you want to use. For example, if your virtual machine provides a webserver, you can expose the webserver port.Checking available Services resources
As you see with the following command, creating the VM does not create any Kubernetes Service for it.
kubectl get service --namespace lab-<username>
In your namespace you should only see the service of your webshell:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
<username>-webshell ClusterIP 10.43.248.212 <none> 3000/TCP 1d
Exposing the SSH port inside the Kubernetes cluster
To access the SSH port from the Kubernetes default pod network we have to create a simple Service resource.
For this, we use a Service of type ClusterIP.
Create a file svc_lab01-firstvm-ssh.yaml in the labs/lab01 directory and write the following Service configuration to it:
apiVersion: v1
kind: Service
metadata:
name: lab01-firstvm-ssh
spec:
ports:
- port: 22
protocol: TCP
targetPort: 22
selector:
kubevirt.io/domain: lab01-firstvm
kubevirt.io/size: small
type: ClusterIP
Apply the Service with:
kubectl apply -f labs/lab01/svc_lab01-firstvm-ssh.yaml --namespace lab-<username>
You may now log in from your webshell terminal to the ssh port of the virtual machine using the following command (password: gocubsgo):
ssh cirros@lab01-firstvm-ssh.lab-<username>.svc.cluster.local
Note
We could also use the virtctl command to create a service for us. The command for the service above would be:
virtctl expose vmi lab01-firstvm --name=lab01-firstvm-ssh --port=22 --namespace lab-<username>
We will use this approach in the next section.
Exposing the SSH port for external use
Our exposed Service with type ClusterIP is only reachable from within the Kubernetes cluster. On our Kubernetes
cluster, we can expose ports such as the one for SSH as a NodePort Service to access it from the outside of the cluster.
This time we will use the virtctl command to expose the port as type NodePort. Us this command to create the Service:
virtctl expose vmi lab01-firstvm --name=lab01-firstvm-ssh-np --port=22 --type=NodePort --namespace lab-<username>
You should now see both Services you just created for your VM:
kubectl get service --namespace lab-<username>
Which should produce a similar output:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
lab01-firstvm-ssh ClusterIP 10.43.89.29 <none> 22/TCP 17m
lab01-ssh-np NodePort 10.43.223.242 <none> 22:32664/TCP 49s
<username>-webshell ClusterIP 10.43.248.212 <none> 3000/TCP 1d
With this, our service is reachable from every node on the indicated port. You may check the PORT(S) column for the
assigned port. In this example, our assigned NodePort is 32664/TCP, which then targets port 22 on our VM.
To connect to the port indicated by the NodePort Service, we need to know the worker nodes’ IP addresses. You can get them with:
kubectl get nodes --selector=node-role.kubernetes.io/master!=true -o jsonpath={.items[*].status.addresses[?\(@.type==\"ExternalIP\"\)].address} --namespace lab-<username>
Which will produce a similar output to this:
188.245.73.202 116.203.61.242 159.69.207.154
Note
You could also see the nodes’ IP addresses nodes using:
kubectl get nodes -o wide
Since the NodePort Service is accessible on any worker node, you can simply pick one IP address and issue the following command from within your webshell (make sure you replace the IP address and the assigned NodePort to match your details):
ssh cirros@<node's IP address> -p <port number>
You should be able to use the same command from outside your webshell, e.g., from your computer.