Setup NFS storage class in OpenShift 4

NFS storageclass is an easy to use storage option for kubernetes and openshift platform. I will describe how to setup a nfs server, and deploy and setup nfs storage class in openshift 4 environment.

Deploy nfs server

Install and setup nfs server service on centos stream 8. selinux and firewalld service are both stoped.

Install nfs packages

# dnf install -y nfs-utils

cofigure nfs service, create export directory

# mkdir /opt/exports
# chmod 777 /opt/exports

export a shared directory

# vi /etc/exports
/opt/exports    *(rw,root_squash)
# exportfs -rv

if selinux is enabled, set virt_use_nfs to true

# setsebool -P virt_use_nfs 1

if firewall is enabled, add port 2049 to accept traffics,

# iptables -I INPUT 1 -p tcp --dport 2049 -j ACCEPT

enable and start nfs service

# systemctl enable nfs-server
# systemctl start nfs-server

Deploy nfs storage provisioner

deploy nfs storage provisioner in default namespace, first create rbac rule needed,

# oc project default
# oc apply -f rbac.yaml 
apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: default
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: nfs-client-provisioner-runner
rules:
  - apiGroups: [""]
    resources: ["persistentvolumes"]
    verbs: ["get", "list", "watch", "create", "delete"]
  - apiGroups: [""]
    resources: ["persistentvolumeclaims"]
    verbs: ["get", "list", "watch", "update"]
  - apiGroups: ["storage.k8s.io"]
    resources: ["storageclasses"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["events"]
    verbs: ["create", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: run-nfs-client-provisioner
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    # replace with namespace where provisioner is deployed
    namespace: default
roleRef:
  kind: ClusterRole
  name: nfs-client-provisioner-runner
  apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: default
rules:
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: default
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    # replace with namespace where provisioner is deployed
    namespace: default
roleRef:
  kind: Role
  name: leader-locking-nfs-client-provisioner
  apiGroup: rbac.authorization.k8s.io

add anyuid scc to serviceaccount

# oc adm policy add-scc-to-user hostmount-anyuid system:serviceaccount:default:nfs-client-provisioner

create deploy.yaml, udpate NFS_SERVER and NFS_PATH to your nfs server parameters.

# oc apply -f deploy.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nfs-client-provisioner
  labels:
    app: nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: default
spec:
  replicas: 1
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: nfs-client-provisioner
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccountName: nfs-client-provisioner
      containers:
        - name: nfs-client-provisioner
          image: k8s.gcr.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: fuseim.pri/ifs
            - name: NFS_SERVER
              value: 192.168.1.8
            - name: NFS_PATH
              value: /opt/exports
      volumes:
        - name: nfs-client-root
          nfs:
            server: 192.168.1.8
            path: /opt/exports

create storage class of nfs provisioner, set it default storageclass.

# oc apply -f sc.yaml 
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: managed-nfs-storage
  annotations:
    storageclass.kubernetes.io/is-default-class: 'true'
provisioner: fuseim.pri/ifs # or choose another name, must match deployment's env PROVISIONER_NAME'
parameters:
  archiveOnDelete: "false"

Leave a Reply

Your email address will not be published. Required fields are marked *