Creating a service to expose a virtual machine
You can expose a virtual machine within the cluster or outside the cluster by using a Service
object.
About services
A Kubernetes service exposes network access for clients to an application running on a set of pods. Services offer abstraction, load balancing, and, in the case of NodePort and LoadBalancer, exposure to the outside world.
Services can be exposed in the VirtualMachine details → Details tab of the web console or by specifying a spec.type
in the Service
object:
ClusterIP
Exposes the service on an internal IP address and as a DNS name to other applications within the cluster. A single service can map to multiple virtual machines. When a client tries to connect to the service, the client’s request is load balanced among available backends. ClusterIP
is the default service type
.
NodePort
Exposes the service on the same port of each selected node in the cluster. NodePort
makes a service accessible from outside the cluster.
LoadBalancer
Creates an external load balancer in the current cloud (if supported) and assigns a fixed, external IP address to the service.
For on-premise clusters, you can configure a load balancing service by using the MetalLB Operator in layer 2 mode. The BGP mode is not supported. The MetalLB Operator is installed in the |
Additional resources
Dual-stack support
If IPv4 and IPv6 dual-stack networking is enabled for your cluster, you can create a service that uses IPv4, IPv6, or both, by defining the spec.ipFamilyPolicy
and the spec.ipFamilies
fields in the Service
object.
The spec.ipFamilyPolicy
field can be set to one of the following values:
SingleStack
The control plane assigns a cluster IP address for the service based on the first configured service cluster IP range.
PreferDualStack
The control plane assigns both IPv4 and IPv6 cluster IP addresses for the service on clusters that have dual-stack configured.
RequireDualStack
This option fails for clusters that do not have dual-stack networking enabled. For clusters that have dual-stack configured, the behavior is the same as when the value is set to PreferDualStack
. The control plane allocates cluster IP addresses from both IPv4 and IPv6 address ranges.
You can define which IP family to use for single-stack or define the order of IP families for dual-stack by setting the spec.ipFamilies
field to one of the following array values:
[IPv4]
[IPv6]
[IPv4, IPv6]
[IPv6, IPv4]
Exposing a virtual machine as a service
Create a ClusterIP
, NodePort
, or LoadBalancer
service to connect to a running virtual machine (VM) from within or outside the cluster.
Procedure
Edit the
VirtualMachine
manifest to add the label for service creation:apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
name: vm-ephemeral
namespace: example-namespace
spec:
running: false
template:
metadata:
labels:
special: key (1)
# ...
1 Add the label special: key
in thespec.template.metadata.labels
section.Labels on a virtual machine are passed through to the pod. The
special: key
label must match the label in thespec.selector
attribute of theService
manifest.Save the
VirtualMachine
manifest file to apply your changes.Create a
Service
manifest to expose the VM:apiVersion: v1
kind: Service
metadata:
name: vmservice (1)
namespace: example-namespace (2)
spec:
externalTrafficPolicy: Cluster (3)
ports:
- nodePort: 30000 (4)
port: 27017
protocol: TCP
targetPort: 22 (5)
selector:
special: key (6)
type: NodePort (7)
1 The name of the Service
object.2 The namespace where the Service
object resides. This must match themetadata.namespace
field of theVirtualMachine
manifest.3 Optional: Specifies how the nodes distribute service traffic that is received on external IP addresses. This only applies to NodePort
andLoadBalancer
service types. The default value isCluster
which routes traffic evenly to all cluster endpoints.4 Optional: When set, the nodePort
value must be unique across all services. If not specified, a value in the range above30000
is dynamically allocated.5 Optional: The VM port to be exposed by the service. It must reference an open port if a port list is defined in the VM manifest. If targetPort
is not specified, it takes the same value asport
.6 The reference to the label that you added in the spec.template.metadata.labels
stanza of theVirtualMachine
manifest.7 The type of service. Possible values are ClusterIP
,NodePort
andLoadBalancer
.Save the
Service
manifest file.Create the service by running the following command:
$ oc create -f <service_name>.yaml
Start the VM. If the VM is already running, restart it.
Verification
Query the
Service
object to verify that it is available:$ oc get service -n example-namespace
Example output for
ClusterIP
serviceNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
vmservice ClusterIP 172.30.3.149 <none> 27017/TCP 2m
Example output for
NodePort
serviceNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
vmservice NodePort 172.30.232.73 <none> 27017:30000/TCP 5m
Example output for
LoadBalancer
serviceNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
vmservice LoadBalancer 172.30.27.5 172.29.10.235,172.29.10.235 27017:31829/TCP 5s
Choose the appropriate method to connect to the virtual machine:
For a
ClusterIP
service, connect to the VM from within the cluster by using the service IP address and the service port. For example:$ ssh fedora@172.30.3.149 -p 27017
For a
NodePort
service, connect to the VM by specifying the node IP address and the node port outside the cluster network. For example:$ ssh fedora@$NODE_IP -p 30000
For a
LoadBalancer
service, use thevinagre
client to connect to your virtual machine by using the public IP address and port. External ports are dynamically allocated.