diff --git a/docs/day-4/README.md b/docs/day-4/README.md new file mode 100644 index 0000000..5b418b1 --- /dev/null +++ b/docs/day-4/README.md @@ -0,0 +1,73 @@ +# O que são volumes e seus tipos + +Volumes no Docker são um componente crucial do ecossistema que armazena e gerencia dados persistentes gerados por contêineres efêmeros. Eles permitem que os dados persistam mesmo após a remoção ou atualização de um contêiner, evitando que dados essenciais do aplicativo sejam perdidos durante operações de rotinas. + +- Bind-mounts: São montagens de diretório do sistema host para um contêiner. Você precisa vincular as montagens de associação a um diretório específico no sistema host. + +- Volume-volume: São volumes criados e gerenciados pelo Docker + +- tmpfs: O tmpfs é um sistema de arquivos baseado em memória que permite armazenar dados de forma temporária na memória RAM. No Docker, quando você cria um contêiner com uma montagem tmpfs, o contêiner pode criar arquivos fora da camada gravável do contêiner. Ao contrário dos volumes e das montagens de associação, uma montagem tmpfs é temporária e persiste apenas na memória do host. Quando o contêiner para, a montagem tmpfs é removida e os arquivos escritos lá não serão persistidos. **Isso é útil para armazenar temporariamente arquivos sensíveis que você não deseja persistir** nem na camada gravável do host nem do contêiner. + +## Criando um volume do tipo bind + +Para criar um volume do tipo bind, siga estes passos: + +1. Crie um diretório na máquina hospedeira onde você deseja armazenar o volume. Neste exemplo, o diretório é criado usando o comando `sudo mkdir /volume`. + +2. Execute um container Docker com a flag `--mount` para especificar o tipo de volume como `bind`. O parâmetro `src` especifica o caminho do diretório na máquina hospedeira, e o parâmetro `dst` especifica o caminho do diretório dentro do container. Neste exemplo, o comando é `docker container run -ti --mount type=bind,src=/volume,dst=/volume ubuntu`. + +## Criando e gerenciando um volume do tipo volume + +1. Listando os volumes: `docker volume ls`. + +2. Criando um volume: `docker volume create giropops`. + +3. Removendo um volume: `docker volume rm giropops`. + +4. Obtendo detalhes do volume: `docker volume inspect giropops`. + +5. Localizando o diretório dos volumes: `cd /var/lib/docker/volumes/`. + +6. Removendo volumes não-utilizados: `docker volume prune`. + +7. Montando um volume criado em algum container: `docker container run -d --mount type=volume,source=giropops,destination=/var/opa nginx`. + +8. Containers utilizando o mesmo volume: `docker run -d --name testando-volumes-1 --mount type=volume,source=giropops,target=/giropops debian`. + +9. Localizando volumes: `docker volume inspect --format '{{ .Mountpoint }}' giropops`. + +## Outras formas de montar volumes e storage drivers + +Os drivers de armazenamento no Docker controlam como as imagens e os contêineres são armazenados e gerenciados no seu host Docker. O Docker suporta vários drivers de armazenamento, usando uma arquitetura plugável. Aqui estão alguns dos drivers de armazenamento disponíveis: + +1. **overlay2**: É o driver de armazenamento preferido para todas as distribuições Linux atualmente suportadas e não requer nenhuma configuração extra. + +2. **fuse-overlayfs**: É preferido apenas para a execução do Docker sem raiz em um host que não oferece suporte para overlay2 sem raiz. + +3. **btrfs e zfs**: Esses drivers de armazenamento permitem opções avançadas, como a criação de “snapshots”, mas requerem mais manutenção e configuração. + +4. **vfs**: O driver de armazenamento vfs é destinado a fins de teste e para situações em que nenhum sistema de arquivos com cópia na gravação pode ser usado. + +5. **aufs**: Era o driver preferido para versões anteriores do Docker, quando executado em uma versão anterior do Ubuntu. + +6. **devicemapper**: Requer direct-lvm. + +Cada driver de armazenamento tem suas próprias vantagens e desvantagens, e a escolha do driver de armazenamento a ser usado depende das necessidades específicas do seu aplicativo. + +## Criando um volume do tipo tmpfs + +``` +docker container run -d --mount type=tmpfs,target=/strigus -p 8081:80 nginx +``` + +Este comando executa um contêiner Docker com a imagem do Nginx e configura um volume temporário (tmpfs) montado no diretório "/strigus". O contêiner é executado em segundo plano (-d) e expõe a porta 8081 do host para a porta 80 do contêiner (-p 8081:80). + +### Volume Temporário (tmpfs) + +O volume temporário (tmpfs) é um tipo de volume no Docker que é armazenado na memória RAM em vez de ser armazenado no disco. Ele é útil para armazenar dados temporários que não precisam ser persistentes entre as reinicializações do contêiner. + +Ao usar um volume temporário, os dados são gravados diretamente na memória RAM, o que proporciona um acesso mais rápido aos dados. No entanto, é importante ter em mente que os dados armazenados em um volume temporário serão perdidos quando o contêiner for reiniciado ou desligado. + +No exemplo acima, o volume temporário é montado no diretório "/strigus" dentro do contêiner. Qualquer dado gravado nesse diretório será armazenado na memória RAM e será perdido quando o contêiner for reiniciado ou desligado. + +Para mais informações sobre volumes no Docker, consulte a documentação oficial: [Docker Volumes](https://docs.docker.com/storage/volumes/) diff --git a/docs/day-4/VOLUMES.md b/docs/day-4/VOLUMES.md new file mode 100644 index 0000000..08f95f9 --- /dev/null +++ b/docs/day-4/VOLUMES.md @@ -0,0 +1,188 @@ + +# Introdução a volumes no Docker + +Bom, volumes nada mais são que diretórios externos ao container, que são montados diretamente nele, e dessa forma `bypassam` seu `filesystem`, ou seja, não seguem aquele padrão de camadas que falamos. Decepcionei você? Que bom, sinal de que é bem simples e você não vai ter problemas para entender. :) + +A principal função do volume é persistir os dados. Diferentemente do `filesystem` do container, que é volátil e toda informação escrita nele é perdida quando o container morre, quando você escreve em um volume aquele dado continua lá, independentemente do estado do container. + +Existem algumas particularidades entre os volumes e containers que valem a pena ser mencionadas: + +- O volume é inicializado quando o container é criado. + +- Caso ocorra de já haver dados no diretório em que você está montando como volume, ou seja, se o diretório já existe e está "populado" na imagem base, aqueles dados serão copiados para o volume. + +- Um volume pode ser reusado e compartilhado entre containers. + +- Alterações em um volume são feitas diretamente no volume. + +- Alterações em um volume não irão com a imagem quando você fizer uma cópia ou snapshot de um container. + +- Volumes continuam a existir mesmo se você deletar o container. + +# Volumes do tipo bind + +Primeiro, vamos ver como funciona da maneira antiga, que ainda é suportada, porém não é elegante. :) + +Essa maneira é muito utilizada quando se quer montar um diretório específico do host dentro do container. Isso é ruim quando estamos trabalhando em cluster, uma vez que teríamos que garantir esse diretório criado em todos os hosts do cluster. Não seria legal. + +Porém, podemos aprender como funciona e utilizar em algum momento, caso se faça necessário. Para evitar erros, primeiro crie o diretório "/volume" na sua máquina. + +``` +root@linuxtips:~# mkdir /volume +root@linuxtips:~# docker container run -ti --mount type=bind,src=/volume,dst=/volume ubuntu +root@7db02e999bf2:/# df -h + +Filesystem Size Used Avail Use% Mounted on +none 13G 6.8G 5.3G 57% / +tmpfs 999M 0 999M 0% /dev +tmpfs 999M 0 999M 0% /sys/fs/cgroup +/dev/mapper/ubuntu--vg-root 13G 6.8G 5.3G 57% /volume +shm 64M 0 64M 0% /dev/shm + +root@7db02e999bf2:/# ls +bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var volume +``` + +No exemplo anterior, conhecemos um novo parâmetro do comando "docker container run", o "--mount". + +O parâmetro "--mount" é o responsável por indicar o volume, que em nosso exemplo é o "/volume", e onde ele será montado no container. Perceba que, quando passamos o parâmetro "--mount type=bind,src=/volume,dst=/volume", o Docker montou esse diretório no container, porém sem nenhum conteúdo. + +Podemos também montar um volume no container linkando-o com um diretório do host já com algum conteúdo. Para exemplificar, vamos compartilhar o diretório "/root/primeiro_container", que utilizamos para guardar o nosso primeiro dockerfile, e montá-lo no container em um volume chamado "/volume" da seguinte forma: + +``` +# docker container run -ti --mount type=bind,src=/root/primeiro_container,dst=/volume ubuntu + +root@3d372a410ea2:/# df -h +Filesystem Size Used Avail Use% Mounted on +none 13G 6.8G 5.3G 57% / +tmpfs 999M 0 999M 0% /dev +tmpfs 999M 0 999M 0% /sys/fs/cgroup +/dev/mapper/ubuntu--vg-root 13G 6.8G 5.3G 57% /volume +shm 64M 0 64M 0% /dev/shm + +``` + +Com isso, estamos montando o diretório "/root/primeiro_dockerfile" do host dentro do container com o nome de "/volume". + +No container: + +``` +root@3d372a410ea2:/# ls /volume/ +Dockerfile + +``` + +No host: + +``` +root@linuxtips:~# ls /root/primeiro_dockerfile/ +Dockerfile + +root@linuxtips:~# +``` + +Caso eu queira deixar o volume no container apenas como read-only, é possível. Basta passar o parâmetro "ro" após o destino onde será montado o volume: + +``` +# docker container run -ti --mount type=bind,src=/root/primeiro_container,dst=/volume,ro ubuntu +root@8d7863b1d9af:/# df -h + +Filesystem Size Used Avail Use% Mounted on +none 13G 6.8G 5.3G 57% / +tmpfs 999M 0 999M 0% /dev +tmpfs 999M 0 999M 0% /sys/fs/cgroup +/dev/mapper/ubuntu--vg-root 13G 6.8G 5.3G 57% /volume +shm 64M 0 64M 0% /dev/shm + +root@8d7863b1d9af:/# cd /volume/ +root@8d7863b1d9af:/volume# ls +Dockerfile + +root@8d7863b1d9af:/volume# mkdir teste +mkdir: cannot create directory 'teste': Read-only file system + +``` + +Assim como é possível montar um diretório como volume, também é possível montar um arquivo: + +``` +# docker container run -ti --mount type=bind,src=/root/primeiro_container/Dockerfile,dst=/Dockerfile ubuntu + +root@df0e3e58280a:/# df -h + +Filesystem Size Used Avail Use% Mounted on +none 13G 6.8G 5.3G 57% / +tmpfs 999M 0 999M 0% /dev +tmpfs 999M 0 999M 0% /sys/fs/cgroup +/dev/mapper/ubuntu--vg-root 13G 6.8G 5.3G 57% /Dockerfile +shm 64M 0 64M 0% /dev/shm + +root@df0e3e58280a:/# cat Dockerfile +FROM debian +RUN /bin/echo "HELLO DOCKER" + +root@df0e3e58280a:/# +``` + +Isso faz com que o arquivo "/root/primeiro_dockerfile/Dockerfile" seja montado em "/Dockerfile" no container. + +# Volumes do tipo volume + +Agora vamos criar os volumes da maneira mais elegante e atual. Hoje temos a possibilidade de realizar o gerenciamento de volumes de maneira muito simples e inteligente. + +Sempre que criamos um volume, ele cria um diretório com o mesmo nome dentro de "/var/lib/docker/volumes/". + +No exemplo a seguir, o volume "giropops" seria então criado em "/var/lib/docker/volumes/giropops"; com isso, todos os arquivos disponíveis nesse diretório também estariam disponíveis no local indicado no container. Vamos aos exemplos! :D + +É possível fazer a criação de volumes e toda a sua administração através do comando: + +``` +docker volume create giropops +``` + +É possível removê-lo através do comando: + +``` +docker volume rm giropops +``` + +Para verificar detalhes sobre esse volume: + +``` +docker volume inspect giropops +``` + +Para remover os volumes que não estão sendo utilizados (use com extrema moderação! :D): + +``` +docker volume prune +``` + +Para que você possa montar o volume criado em algum container/service, basta executar o seguinte comando: + +``` +docker container run -d --mount type=volume,source=giropops,destination=/var/opa nginx +``` + +Onde: + +**--mount** -- Comando utilizado para montar volumes. + +**type=volume** -- Indica que o tipo é "volume". Ainda existe o tipo "bind", onde, em vez de indicar um volume, você indicaria um diretório como source. + +**source=giropops** -- Qual o volume que pretendo montar. + +**destination=/var/opa** -- Onde no container montarei esse volume. + +## Localizando volumes + +Caso você queira obter a localização do seu volume, é simples. Mas para isso você precisa conhecer o comando "docker volume inspect". + +Com o "docker volume inspect" você consegue obter detalhes do seu `container`, como, por exemplo, detalhes do volume. + +A saída do comando "docker volume inspect" retorna mais informação do que somente o `path` do diretório no `host`. Vamos usar a opção "--format" ou "-f" para filtrar a saída do "inspect". + +``` +docker volume inspect --format '{{ .Mountpoint }}' giropops +/var/lib/docker/volumes/giropopos/_data +```