O modo Swarm em si não faz nada de diferente com os volumes, ele executa qualquer comando de montagem de volume fornecido no nó onde o contêiner está sendo executado. Se a montagem do seu volume for local para esse nó, seus dados serão salvos localmente nesse nó. Não há funcionalidade integrada para mover dados entre nós automaticamente.
Existem algumas soluções de armazenamento distribuído baseadas em software como GlusterFS, e o Docker tem uma chamada Infinit que ainda não é GA e o desenvolvimento ficou em segundo plano em relação à integração do Kubernetes em EE.
O resultado típico é que você precisa gerenciar a replicação de armazenamento em seu aplicativo (por exemplo, etcd e outros algoritmos baseados em jangada) ou realizar suas montagens em um sistema de armazenamento externo (com sorte, com seu próprio HA). A montagem de um sistema de armazenamento externo tem duas opções, baseado em bloco ou arquivo. O armazenamento baseado em bloco (por exemplo, EBS) normalmente vem com melhor desempenho, mas é limitado para ser montado apenas em um único nó. Para isso, você normalmente precisará de um driver de plugin de volume de terceiros para dar ao seu docker node acesso a esse armazenamento de bloco. O armazenamento baseado em arquivo (por exemplo, EFS) tem desempenho inferior, mas é mais portátil e pode ser montado simultaneamente em vários nós, o que é útil para um serviço replicado.
O armazenamento de rede baseado em arquivo mais comum é o NFS (este é o mesmo protocolo usado pelo EFS). E você pode montá-lo sem nenhum driver de plugin de terceiros. O driver de plug-in de volume infelizmente chamado "local" fornecido com o docker oferece a opção de passar quaisquer valores que você deseja para o comando de montagem com as opções do driver e, sem opções, o padrão é armazenar volumes no diretório docker / var / lib / docker / volumes. Com opções, você pode passar os parâmetros NFS, e ele vai até realizar uma pesquisa de DNS no nome do host NFS (algo que você não tem com NFS normalmente). Aqui está um exemplo das diferentes maneiras de montar um sistema de arquivos NFS usando o driver de volume local:
# create a reusable volume
$ docker volume create --driver local \
--opt type=nfs \
--opt o=nfsvers=4,addr=192.168.1.1,rw \
--opt device=:/path/to/dir \
foo
# 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=192.168.1.1\",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=192.168.1.1\",volume-opt=device=:/host/path \
foo
# inside a docker-compose file
...
volumes:
nfs-data:
driver: local
driver_opts:
type: nfs
o: nfsvers=4,addr=192.168.1.1,rw
device: ":/path/to/dir"
...
Se você usar o exemplo de composição de arquivo no final, observe que as alterações em um volume (por exemplo, atualizar o caminho ou endereço do servidor) não são refletidas nos volumes nomeados existentes enquanto eles existirem. Você precisa renomear seu volume ou excluí-lo para permitir que o swarm o recrie com novos valores.
O outro problema comum que vejo na maioria dos usos do NFS é o "root squash" habilitado no servidor. Isso resulta em problemas de permissão quando os containers em execução como root tentam gravar arquivos no volume. Você também tem problemas de permissão UID / GID semelhantes, em que o UID / GID do contêiner é aquele que precisa de permissões para gravar no volume, o que pode exigir a propriedade do diretório e as permissões a serem ajustadas no servidor NFS.