Assumptions:

  • A Kubernetes cluster is already setup
  • These are installed prior: Helm, MetalLB Load Balancer,
  • A static IP has already been excluded by the external DHCP server’s scope
  • Chosen IP also is within scope (IP Range) of the ConfigMap of metallb-system
# Installation
instanceName=clamav
helm repo add wiremind https://wiremind.github.io/wiremind-helm-charts/
helm install $instanceName wiremind/clamav

# Set static IP for the service
appName=clamav
externalIPs=10.10.10.151
kubectl patch svc $appName -p '{"spec":{"externalIPs":["'$externalIPs'"]}}'

# Reverse static IP assignment
kubectl patch svc clamav -p '{"spec":{"externalIPs":[]}}'

# How to Uninstall
# helm uninstall clamav

# Application
# NextCloud's module can make use of this service: https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/antivirus_configuration.html#configuring-clamav-on-nextcloud
Result:

rambo@masterbox:~$ helm install $instanceName wiremind/clamav
NAME: clamav
LAST DEPLOYED: Thu Jul 29 22:51:20 2021
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
1. To connect to your ClamAV instance from outside the cluster execute the following commands:
  export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=clamav,app.kubernetes.io/instance=clamav" -o jsonpath="{.items[0].metadata.name}")
  echo 127.0.0.1:3310
  kubectl port-forward $POD_NAME 3310:3310

bruce@masterbox:~$ k describe statefulsets.apps clamav 
Name:               clamav
Namespace:          default
CreationTimestamp:  Thu, 29 Jul 2021 22:51:22 +0000
Selector:           app.kubernetes.io/instance=clamav,app.kubernetes.io/name=clamav
Labels:             app.kubernetes.io/instance=clamav
                    app.kubernetes.io/managed-by=Helm
                    app.kubernetes.io/name=clamav
                    app.kubernetes.io/version=1.8
                    helm.sh/chart=clamav-2.0.0
Annotations:        meta.helm.sh/release-name: clamav
                    meta.helm.sh/release-namespace: default
Replicas:           1 desired | 1 total
Update Strategy:    RollingUpdate
  Partition:        0
Pods Status:        1 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:  app.kubernetes.io/instance=clamav
           app.kubernetes.io/name=clamav
  Containers:
   clamav:
    Image:        mailu/clamav:1.8
    Port:         3310/TCP
    Host Port:    0/TCP
    Liveness:     tcp-socket :clamavport delay=300s timeout=1s period=10s #success=1 #failure=3
    Readiness:    tcp-socket :clamavport delay=90s timeout=1s period=10s #success=1 #failure=3
    Environment:  <none>
    Mounts:
      /data from clamav-data (rw)
  Volumes:
   clamav-data:
    Type:       EmptyDir (a temporary directory that shares a pod's lifetime)
    Medium:     
    SizeLimit:  <unset>
Volume Claims:  <none>
Events:         <none>

kim@masterbox:~$ k describe service clamav 
Name:              clamav
Namespace:         default
Labels:            app.kubernetes.io/instance=clamav
                   app.kubernetes.io/managed-by=Helm
                   app.kubernetes.io/name=clamav
                   helm.sh/chart=clamav-2.0.0
Annotations:       meta.helm.sh/release-name: clamav
                   meta.helm.sh/release-namespace: default
Selector:          app.kubernetes.io/instance=clamav,app.kubernetes.io/name=clamav
Type:              ClusterIP
IP Families:       <none>
IP:                10.104.143.167
IPs:               10.104.143.167
Port:              clamavport  3310/TCP
TargetPort:        3310/TCP
Endpoints:         172.16.90.171:3310
Session Affinity:  None
Events:            <none>