Skip to content

Come montare direttamente una condivisione/volume NFS in un container usando docker compose v3

Dopo molte battaglie, abbiamo già trovato il risultato di questo dubbio che hanno avuto alcuni utenti di questo sito web. Se vuoi condividere qualche dettaglio, non esitare a lasciare la tua conoscenza.

Soluzione:

Dopo aver scoperto che questo non è documentato, ecco il modo corretto per montare un volume NFS usando stack e docker compose.

La cosa più importante è che si deve usare version: "3.2" o superiore. In caso contrario si avranno errori strani e non ovvi.

Il secondo problema è che i volumi sono non aggiornati automaticamente quando la loro definizione cambia. Questo può portare a pensare che le modifiche non siano corrette, quando invece non sono state applicate. Assicurarsi di docker rm VOLUMENAME ovunque possa essere, poiché se il volume esiste, non verrà convalidato.

Il terzo problema è più che altro un problema di NFS. non verrà creata sul server se non esiste. Questo è il modo in cui funziona NFS. È necessario assicurarsi che esista prima di fare qualsiasi cosa.

(Non rimuovere 'soft' e 'nolock' a meno che non si sia sicuri di sapere cosa si sta facendo: questo impedisce a docker di bloccarsi se il server NFS scompare).

Ecco un esempio completo:

[[email protected] docker-mirror]# cat nfs-compose.yml
version: "3.2"

services:
  rsyslog:
    image: jumanjiman/rsyslog
    ports:
      - "514:514"
      - "514:514/udp"
    volumes:
      - type: volume
        source: example
        target: /nfs
        volume:
          nocopy: true
volumes:
  example:
    driver_opts:
      type: "nfs"
      o: "addr=10.40.0.199,nolock,soft,rw"
      device: ":/docker/example"

[[email protected] docker-mirror]# docker stack deploy --with-registry-auth -c nfs-compose.yml rsyslog
Creating network rsyslog_default
Creating service rsyslog_rsyslog
[[email protected] docker-mirror]# docker stack ps rsyslog
ID                  NAME                IMAGE                       NODE                DESIRED STATE       CURRENT STATE                     ERROR               PORTS
tb1dod43fe4c        rsyslog_rsyslog.1   jumanjiman/rsyslog:latest   swarm-4             Running             Starting less than a second ago
[[email protected] docker-mirror]#

Ora, su swarm-4:

[email protected]:~# docker ps
CONTAINER ID        IMAGE                       COMMAND                  CREATED             STATUS              PORTS               NAMES
d883e0f14d3f        jumanjiman/rsyslog:latest   "rsyslogd -n -f /e..."   6 seconds ago       Up 5 seconds        514/tcp, 514/udp    rsyslog_rsyslog.1.tb1dod43fe4cy3j5vzsy7pgv5
[email protected]:~# docker exec -it d883e0f14d3f df -h /nfs
Filesystem                Size      Used Available Use% Mounted on
:/docker/example          7.2T      5.5T      1.7T  77% /nfs
[email protected]:~#

Questo volume verrà creato (ma non sarà distrutto) su qualsiasi nodo dello sciame su cui è in esecuzione lo stack.

[email protected]:~# docker volume inspect rsyslog_example
[
    {
        "CreatedAt": "2017-09-29T13:53:59+10:00",
        "Driver": "local",
        "Labels": {
            "com.docker.stack.namespace": "rsyslog"
        },
        "Mountpoint": "/var/lib/docker/volumes/rsyslog_example/_data",
        "Name": "rsyslog_example",
        "Options": {
            "device": ":/docker/example",
            "o": "addr=10.40.0.199,nolock,soft,rw",
            "type": "nfs"
        },
        "Scope": "local"
    }
]
[email protected]:~#

A seconda di come devo usare il volume, ho le seguenti 3 opzioni.

Innanzitutto, è possibile creare direttamente il volume con nome e utilizzarlo come volume esterno in compose, oppure come volume con nome in un file di tipo docker run o docker service create o di un comando docker service create.

  # create a reusable volume
  $ docker volume create --driver local 
      --opt type=nfs 
      --opt o=nfsvers=4,addr=nfs.example.com,rw 
      --opt device=:/path/to/dir 
      foo

Successivamente, c'è il comando --mount che funziona a partire da docker run e docker service create. Si tratta di un'opzione piuttosto lunga e quando si incorpora un'opzione delimitata da virgole all'interno di un'altra opzione delimitata da virgole, è necessario passare alcune virgolette (con escape in modo che la shell non le rimuova) al comando in esecuzione. Tendenzialmente lo uso per un contenitore unico che deve accedere a NFS (per esempio un contenitore di utilità per impostare le directory NFS):

  # or from the docker run command
  $ docker run -it --rm 
    --mount type=volume,dst=/container/path,volume-driver=local,volume-opt=type=nfs,"volume-opt=o=nfsvers=4,addr=nfs.example.com",volume-opt=device=:/host/path 
    foo

  # or to create a service
  $ docker service create 
    --mount type=volume,dst=/container/path,volume-driver=local,volume-opt=type=nfs,"volume-opt=o=nfsvers=4,addr=nfs.example.com",volume-opt=device=:/host/path 
    foo

Infine, è possibile definire il volume con nome all'interno del file di composizione. Una nota importante: il volume con nome viene creato solo una volta e non viene aggiornato con le modifiche. Pertanto, se si desidera modificare il volume con nome, è necessario assegnargli un nuovo nome.

  # inside a docker-compose file
  ...
  services:
    example-app:
      volumes:
      - "nfs-data:/data"
  ...
  volumes:
    nfs-data:
      driver: local
      driver_opts:
        type: nfs
        o: nfsvers=4,addr=nfs.example.com,rw
        device: ":/path/to/dir"
  ...

In ognuno di questi esempi:

  • Il tipo è impostato su nfs, non nfs4. Questo perché docker fornisce alcune funzionalità interessanti sull'opzione addr ma solo per il campo nfs tipo.
  • Il campo o sono le opzioni che vengono passate alla syscall di mount. Una differenza tra la syscall di mount e il comando mount di Linux è che il dispositivo ha la parte prima dell'opzione : è stata spostata in un elemento addr opzione.
  • nfsvers è usata per impostare la versione NFS. In questo modo si evitano i ritardi dovuti al fatto che il sistema operativo prova prima altre versioni NFS.
  • addr può essere un nome DNS quando si usa type=nfspiuttosto che solo un indirizzo IP. Molto utile se si dispone di più VPC con server NFS diversi che utilizzano lo stesso nome DNS, o se si desidera modificare il server NFS in futuro senza aggiornare ogni montaggio di volume.
  • Altre opzioni come rw (lettura-scrittura) possono essere passate all'opzione o .
  • L'opzione device è il percorso sul server NFS remoto. I due punti iniziali sono obbligatori. Questo è un artefatto del modo in cui il comando mount sposta l'indirizzo IP nel campo addr per la chiamata di sistema. Questa directory deve esistere sull'host remoto prima che il volume venga montato in un contenitore.
  • Nel campo --mount la sintassi dst è il percorso all'interno del contenitore. Per i volumi denominati, si imposta questo percorso sul lato destro del montaggio del volume (nella sintassi breve) sul file docker run -v del comando docker run -v.

Se si verificano problemi di permessi per l'accesso a un volume NFS remoto, una causa comune che ho riscontrato è l'esecuzione di container come root, con il server NFS impostato su root squash (cambiando tutto l'accesso di root all'utente nobody). È necessario configurare i container in modo che vengano eseguiti come un UID non root ben noto che abbia accesso alle directory sul server NFS, oppure disabilitare root squash sul server NFS.

Sì, è possibile fare riferimento a un NFS direttamente dal file di composizione:

volumes:
   db-data:
      driver: local
      driver_opts:
        type: nfs
        o: addr=$SOMEIP,rw
        device: ":$PathOnServer"

In modo analogo si può creare un volume NFS su ogni host.

docker volume create --driver local --opt type=nfs --opt o=addr=$SomeIP,rw --opt device=:$DevicePath --name nfs-docker

Hai la possibilità di aggiungere valore alle nostre informazioni aggiungendo la tua esperienza nelle spiegazioni.



Utilizzate il nostro motore di ricerca

Ricerca
Generic filters

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.