Deploy an NFS server and client
This tutorial describes how to deploy two VMs in different namespaces, where the first VM acts as an NFS server and the other as the client, able to mount the exported share via a VirtualMachineService
.
Prerequisites
This tutorial assumes the following:
- There are two namespaces in which the user is able to deploy
VirtualMachine
resources. In this tutorial, the namespaces shall be referred to asns-1
andns-2
. - Both namespaces have access to a
VirtualMachineClass
. In this tutorial, the class used ismy-vm-class
. - Both namespaces have access to a
VirtualMachineImage
(VMI) with Ubuntu 22.04+. In this tutorial, the VMI used isvmi-0a0044d7c690bcbea
. - Both namespaces have access to a
StorageClass
. In this tutorial, the class used ismy-storage-class
.
Deploy the server
The first step is to deploy a VM that will act as the NFS server, which is achieved by applying the following YAML:
apiVersion: vmoperator.vmware.com/v1alpha3
kind: VirtualMachine
metadata:
name: nfs-server
namespace: ns-1
labels:
app: nfs-server
spec:
className: my-vm-class
imageName: vmi-0a0044d7c690bcbea # Ubuntu 22.04 (jammy)
storageClass: my-storage-class
bootstrap:
cloudInit:
rawCloudConfig:
name: nfs-server-bootstrap-data
key: user-data
---
apiVersion: v1
kind: Secret
metadata:
name: nfs-server-bootstrap-data
namespace: ns-1
stringData:
user-data: |
#cloud-config
ssh_pwauth: true
users:
- name: user
primary_group: user
sudo: ALL=(ALL) NOPASSWD:ALL
groups: users
lock_passwd: false
# Password is secret
passwd: '$1$SaltSalt$YhgRYajLPrYevs14poKBQ0'
shell: /bin/bash
runcmd:
- apt-get update --assume-no
- apt-get install --assume-yes nfs-kernel-server sudo
- mkdir -p /mnt/share
- echo 'world.' >/mnt/share/hello
- echo '/mnt/share *(rw,sync,no_subtree_check,insecure)' >>/etc/exports
- exportfs -a
Create service to access NFS exports
Great, an NFS server is up and running in namespace ns-1
! To ensure workloads outside of that namespace are able to mount the NFS server's exports, a VirtualMachineService
is used to provide a load balanced IP address that can be accessed across namespaces.
apiVersion: vmoperator.vmware.com/v1alpha3
kind: VirtualMachineService
metadata:
name: nfs-server
namespace: ns-1
spec:
selector:
app: nfs-server
type: LoadBalancer
ports:
- name: tcp-ssh
port: 22
protocol: TCP
targetPort: 22
- name: tcp-rpcbind
port: 111
protocol: TCP
targetPort: 111
- name: tcp-nfs
port: 2049
protocol: TCP
targetPort: 2049
Use kubectl
to make note of the service's external IP address, ex.:
$ kubectl -n ns-1 get service nfs-server
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nfs-server LoadBalancer 172.24.116.43 192.168.0.4 22/TCP,111/TCP,2049/TCP 2m3s
Deploy the client
With the NFS server up and running, it is time to deploy the VM that will act as the client by applying the following YAML:
apiVersion: vmoperator.vmware.com/v1alpha3
kind: VirtualMachine
metadata:
name: nfs-client
namespace: ns-2
labels:
app: nfs-client
spec:
className: my-vm-class
imageName: vmi-0a0044d7c690bcbea # Ubuntu 22.04 (jammy)
storageClass: my-storage-class
bootstrap:
cloudInit:
rawCloudConfig:
name: nfs-client-bootstrap-data
key: user-data
---
apiVersion: v1
kind: Secret
metadata:
name: nfs-client-bootstrap-data
namespace: ns-2
stringData:
user-data: |
#cloud-config
ssh_pwauth: true
users:
- name: user
primary_group: user
sudo: ALL=(ALL) NOPASSWD:ALL
groups: users
lock_passwd: false
# Password is secret
passwd: '$1$SaltSalt$YhgRYajLPrYevs14poKBQ0'
shell: /bin/bash
runcmd:
- apt-get update --assume-no
- apt-get install --assume-yes nfs-common sudo
- mkdir /var/share
- chmod 0777 /var/share
Create service to access NFS client via SSH
Just like a service is required to access the NFS exports across namespaces, the following YAML creates a service that allows external actors to access the NFS client via SSH:
apiVersion: vmoperator.vmware.com/v1alpha3
kind: VirtualMachineService
metadata:
name: nfs-client
namespace: ns-2
spec:
selector:
app: nfs-client
type: LoadBalancer
ports:
- name: tcp-ssh
port: 22
protocol: TCP
targetPort: 22
Use kubectl
to make note of the service's external IP address, ex.:
$ kubectl -n ns-2 get service nfs-client
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nfs-client LoadBalancer 172.24.204.9 192.168.0.5 22/TCP 51s
Mount the exported share
Alright, it is time to see if everything works as intended!
-
With the external IP address from the
nfs-client
service, SSH into the VM acting as the NFS client:ssh user@<NFS_CLIENT_SERVICE_EXTERNAL_IP>
-
Print the contents of the file
/var/share/hello
to the screen:cat /var/share/hello
Oops! An error occurred, because that file does not exist!
cat: /var/share/hello: No such file or directory
-
Mount the export from the NFS server:
sudo mount -t nfs <NFS_SERVER_SERVICE_EXTERNAL_IP>:/mnt/share /var/share
-
Print the contents of the file
/var/share/hello
one more time:cat /var/share/hello
If the text
world.
appeared on the screen, then congratulations, the NFS export was successfully mounted to the client!