O container é um binário que tem tudo que sua aplicação necessita, o container não possui kernel. O kernel da máquina local que é compartilhado por esses containers. O container é a emulação de sua aplicação e não da máquina como um todo.
Em uma máquina física temos uma estrutura de poucas camada kernel -> SO -> Aplicação. Máquina Virtual : Server -> SO -> Máquina virtual -> Todo uma estrutura nova de sistema Operacional. Container: temos o servidor -> SO -> Engine do Docker -> por fim a aplicação.
Vantagens:
- Portabilidade.
- Emular a aplicação e micro-serviços.
ch-root: foi o primeiro emulador de aplicação.
2008: Houve o começo da empresa.
Principais nomes:
Docker-engine : É um client-server que é aplicado a maioria dos components
- A server which is a type of long-running program called a daemon process (the
dockerd
command). - A command line interface (CLI) client (the
docker
command).
"Você tem um livro e quando você vai escrever o livro é gerado uma cópia, você não está editando a camada original mas a sua cópia."
Componentes do kernel linux que o docker faz uso:
- selinux
- cgroups: É responsável pela liberação de recursos de hardware para os containers.
- namespaces: principal responsável por separar o ambiente de cada container, evitando interferência um com o outro. ( isolamento de árvores de processo)
- PID Namespace - Cada container tem sua própria árvore de identificação de processo.
- net namespace - Isolamento de rede e responsável pela comunição. ( ip -addr)
- mnt namespace - Isolamento de file system
- uts namespace - Isolamento do hostname.
- user namespace - Isolamento de usuário, responsável pelo mapa de usuários.
- netlink
- netfilter: Um modulo de kernel do iptables , quase toda parte de rede.
- apparmor
- capabilities
-
Docker só rodará em processador 64
-
Devemos ter um kernel mínimo de versão 3.8.
uname -r
-
Seu kernel deve ter os módulo necessários.
- Primeiro vamos executar o docker, se a imagem não existir será feito o pull da imagem. Em seguida ele executará o container.
docker run hello-world
-
Para visualizamos todos os containers em execução
docker ps
-
Mostrar todas as imagens presentes, Imagem de forma grosseira é um container parado
docker images
-
Mostrar todos os containers da minha máquina
docker ps -a
-
Parâmetros fundamentais, -ti o t é para que se tenha um terminal e o i é para que tenha interatividade com o container.
docker run -ti ubuntu /bin/bash
/bin/bash é para que caia em um bash.
ip addr
-
Se colocássemos a opção -v estaríamos rodando em background.
-
Fazendo outro exemplo
docker run -ti centos:7
-
Control + D fechamos o shell e com consequência finalizamos o container.
-
Se você quiser sair do container sem matar o shell use Control+P+Q. Então volta para o host.
-
Para voltar ao container faça o seguinte:
ip addr
docker attach <Container ID>
-
Voltou !!!!
-
Usar o create não deixa o container em execução apenas criar
docker create ubuntu
-
Para paramos o container:
docker stop <Container ID>
-
Se quisermos startar
docker start <Container ID>
-
Se quisermos pausar esse container:
docker pause <Container ID>
-
Se quisermos descongelá-lo
docker unpause <Container ID>
-
Para saber o quanto este container está consumindo de recursos
docker stats <Container ID>
-
Quais os processos que rodando no container
docker top <Container ID>
-
Mostrar os logs do container
docker logs <Container ID>
-
Como remover um container pausado
docker rm <Container ID>
-
Agora se o container estiver rodando devemos fazer o seguinte, devemos forçar a remoção:
docker rm -f <Container ID>
-
Limite de utilização de memória, mostrará a quantidade de memória RAM do Host:
free -m
-
Mostrará todos os dados de recursos do container :
ip addr
docker inspect <Container ID>
-
Vamos subir um novo container:
docker run -ti --name teste debian
--name é um parâmetro para se adicionar um nome ao container criado.
-
Agora vamos ver qual é a memória atribuída a este container:
docker inspect <Container ID> | grep -i men
-
A linha Memory tem um valor 0.
-
Vamos limitar a memória deste container:
docker run -ti --memory 512m --name novo_teste debian
-
Agora vamos inspecionar o memory desse container agora:
docker inspect <Container ID> | grep -i men
-
Caso queiramos mudar a memória desse container já executado:
docker ps
docker update -m 256m <nome_do_container>
docker inspect <Container ID> | grep -i men
Se não limitarmos os recursos de um container, ele poderá usar todo o recurso do host.
Vamos criar 3 containers estipulando valores. 1024 , 512 e 512.
-
Vamos criar o primeiro:
docker run -ti --cpu-shares 1024 --name container1 debian
-
Vamos ver se foi feita a criação e configuração. CPUShares: 1024
docker inspect container1 | grep -i cpu
-
Vamos criar o segundo container:
docker run -ti --cpu-shares 512 --name container2 debian
-
Vamos criar o terceiro container:
docker run -ti --cpu-shares 512 --name container3 debian
-
Agora vamos verificar se eles estão presentes:
docker ps
-
Se o container estiver em execução vamos usar o update:
docker update --cpu-shares 512 container1
-
Podemos verificar se todos ele agora possuem 512 de recurso de cpu:
docker inspect container1 container2 container3 | grep -i cpu
-
Podemos fazer melhor
docker inspect --format='{{.RepoTags}} {{.Config.Image}}' 3a5e53f63281
É uma forma de colocarmos um diretório de dentro do container fora do container. Ele está montado no container mas não faz parte. * Parecido com um compartilhamento NFS. Quando se utiliza um volume dentro de um container é basicamente o compartilhamento de um dir do seu host docker com seu container. **Quando vc fizer uma movimentação do seu container o volume não irá junto, o volume é apenas um ponto de montagem, ele persistirá (ficará no mesmo lugar) no host docker. **
-
Vamos subir um container passando um volume:
docker run -ti -v /volume ubuntu /bin/bash
Vamos mostrar as partições
df -h
-
Vamos a este diretório em sua máquina
cd /
ls
-
Podemos verificar que existirá o diretório /volume.
-
Nossa!!! Montamos ele no nosso container, agora se modificá-lo também estaremos modificando em nosso host Docker
-
O nosso volume nada mais é que um compartilhamento entre o nosso container e nosso host Docker.
docker ps
docker inspect -f {{.Mounts}} <Container_ID>
-
Vamos encontrar o diretório de onde se encontra o nosso volume no host Docker. Assim podemos pegar o caminho gigante que aparece.
cd <Path>
-
Dentro dele podemos criar qualquer coisa que se será criado no container também
-
Vamos criar um diretório:
mkdir /root/primeiro_dockerfile
-
Agora vamos criar o volume especificando o diretório
docker run -ti -v /root/primeiro_dockerfile:/volume debian
-
Vamos verificar se foi criado:
df -h
-
Vamos verificar se o caminho corresponde:
cd /
ls
cd volume/
touch Dockerfile
Por fim criamos este arquivo e vamos sair do container:
Control+P+Q
-
Agora vamos no diretório que havíamos especificado na criação:
cd /root/primeiro_dockerfile:/
-
Pronto !
É um container que nem precisa ser executado, dentro dele teremos volumes que serão compartilhados com outros containers
-
Vamos criar este container:
docker create -v /data --name dbdados centos
-
Container criado e o volume criado iremos compartilhar com outros containers.
docker run -d -p 5432:5432 --name pgsql1 --volumes-from dbdados -e POSTGRESQL_USER=docker -e POSTGRESQL_PASS=docker -e POSTGRESQL_DB=docker kamui/postgresql
docker run -d -p 5432:5432 --name pgsql2 --volumes-from dbdados -e POSTGRESQL_USER=docker -e POSTGRESQL_PASS=docker -e POSTGRESQL_DB=docker kamui/postgresql
-
Este comando é capaz de apagar todas as imagens de uma só vez.
docker rm $(docker ps -a -q)
Vamos dar um intervalo no Jefferson e chamar o Léo. Veja, vamos empregar o docker em uma situação que tenhamos de usar o Rails.
-
Vamos fazer a criação de um container.
docker run -it --rm --user "$(id -u):$(id -g)" -v "$PWD":/usr/src/app -w /usr/src/app rails rails new --skip-bundle my_awesome_app
-
--rm : apague o container, rodando o comando uma única vez o comando rails new
-
--user "$(id -u):$(id -g)": Compartilhar usuário.
-
-v "$PWD":/urs/src/app -w /usr/src/app : Criamos um novo volume e especificamos seu caminho no host Docker
-
rails: o primeiro rails seria o nome do IMAGEM
-
Iremos criar um Dockerfile, nada mais é do que um meio que utilizamos para criar nossas próprias imagens. Em outras palavras, ele serve como a receita para construir um container, permitindo definir um ambiente personalizado e próprio para meu projeto pessoal ou empresarial.
vim Dockerfile
-
Logo após a criação iremos entrar no volume e inserir esses comando:
FROM ruby:2.3 RUN mkdir -p /usr/src/app WORKDIR /usr/src/app RUN apt-get update && apt-get install -y nodejs --no-install-recommends && rm -rf /var/lib/apt/lists/* RUN apt-get update && apt-get install -y sqlite3 --no-install-recommends && rm -rf /var/lib/apt/lists/* COPY Gemfile /usr/src/app/ RUN bundle install COPY . /usr/src/app EXPOSE 3000 CMD puma -C config/puma.rb
Explicando
- FROM : pegue a imagem ( nesse caso ruby:2.3 )
- RUN : Irá rodar um comando do shell do linux. ( Os próximos RUN são instalações)
- WORKDIR : especifica o diretório onde estaremos instalando as dependências seguintes.
- COPY : Pega um arquivo da pasta local ( host Docker ) e joga no container
- RUN bundle install : instala as dependências do Gemfile
- COPY . /usr/src/app : copia tudo da pasta ( host Docker) subindo para o container.
- EXPOSE 3000: Abrir a porta do container.
- CMD : é o comando de saída.
-
Agora iremos criar uma imagem através do Dockerfile. ( Construindo uma imagem personalizada )
docker build -t my_awesome_app .
-
Vamos testar se o server está rodando corretamente
docker run -v "$PWD":/usr/src/app -p 3000:3000 my_awesome_app
-
Tudo certo
-
Vamos remover os container criados
docker rm <Container ID>
-
Primeiro iremos cria um projeto rails
docker run -it --rm --user "$(id -u):$(id -g)" -v "$PWD":/usr/src/app -w /usr/src/app rails rails new --skip-bundle my_awesome_app2 --database=postgresql
- Vamos analisar novamente o que está sendo feito:
- docker run : Estamos rodando o docker.
- -it: parâmetro de interatividade com o console.
- -v "$PWD":/usr/src/app -w /usr/src/app: Estamos compartilhando nosso projeto com o container que será rodado.
-
Crie um arquivo Dockerfile e configure uma nova imagem para este projeto.
FROM ruby:2.3 RUN mkdir -p /usr/src/app WORKDIR /usr/src/app RUN apt-get update && apt-get install -y nodejs --no-install-recommends && rm -rf /var/lib/apt/lists/* RUN apt-get update && apt-get install -y postgresql-client --no-install-recommends && rm -rf /var/lib/apt/lists/* COPY Gemfile /usr/src/app/ RUN bundle install COPY . /usr/src/app EXPOSE 3000 CMD puma -C config/puma.rb
-
Vamos fazer o build da imagem ( Construir nossa imagem personalizada ), dentro da pasta do projeto:
docker build -t my_custom_image_2 .
-
pIremos criar um network para que um container possa acessar o outro. ( uma rede internar do docker que irá conectar nossos containers).
docker network create my_awesome_network
-
Vamos subir o container com o Postgresql dentro:
docker run --name db -d --network=my_awesome_network postgres
- --name : estamos definindo um nome para o container
- -d: daemon, dizendo para rodar em backend.
- --network : especificando nosso container network.
- postgres : acrecentando uma imagem postgres.
-
Vamos configurar o config/database.yml do nosso projeto para que possamos conectar ao banco.
default: adapter: postgresql encoding: unicode pool:<%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>; # Apenas acrescentamos o nosso container como Host host: db # E colocamos o usuário default do postgreSQL user: postgres development:
-
Vamos criar a base de dados
docker run -v "$PWD":/usr/src/app --network=my_awesome_network my_custom_image_2 rake db:create
-
Vamos
docker run -v "$PWD":/usr/src/app -p 3000:3000 --network=my_awesome_network my_custom_image_2
1 - No mesmo projeto que trabalhamos na Parte 3 (O mesmo que está dando errado ) vamos criar um arquivo chamado “docker-compose.yml” e ele vai gerenciar nossos containers para gente. Crie o arquivo e coloque o seguinte conteúdo dentro dele:
version: '2'
services:
db:
image: 'postgres:9.5'
volumes:
- 'postgres:/var/lib/postgresql/data'
website:
depends_on:
- 'db'
build: .
ports:
- '3000:3000'
volumes:
- '.:/usr/src/app'
volumes:
postgres:
2 - Para fazer o Build de todos os nossos containers basta rodar (dentro do projeto):
docker-compose build
3 - Agora como nós criamos um novo container para o PostgreSQL nós precisamos criar nosso banco de dados de novo, porém agora vamos usar os comandos do docker-compose para fazer isso de maneira fácil. No console rode:
docker-compose run web rake db:create
4 - Para subir o container rode
docker-compose up
5 - Agando todos os container
docker rm $(docker ps -a -q)
6 - Apagar todas as imagens docker
docker rmi $(docker images -q)
1 - Criar um container e roda um comando dentro:
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
2 - Visualiza os container rodando:
docker ps
3 - Visualizando todos os containers:
docker ps -a
4 - Parando um container:
docker stop id_do_container
5 - Parando todos os containers que estiverem rodando:
docker stop $(docker ps -a -q)
6 - Dando um start em um container parado:
docker start id_do_container
7 - Apagando um container:
docker rm id_do_container
8 - Apagando todos os containers:
docker rm $(docker ps -a -q)
9 - Executando um comando dentro de um container que está sendo executado:
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
10 - Vendo as imagens que você tem instalado:
docker images
11 - Apagando uma imagem
docker rm id_da_imagem
12 - Fazendo o build das imagens usando o docker compose:
docker-compose build
13 - Criando e subindo os containers via Docker Compose:
docker-compose up
14 - Parando os containers via docker compose:
docker-compose stop
15 - Executando um comando dentro do container via docker compose:
docker-compose run nome_do_servico o_comando
16 - Vendo sua configuração no docker compose
docker-compose config
17 - Vendo os logs dos containers via Docker compose:
docker-compose logs
18 - Matando os containers via Docker Compose:
docker-compose kill
19 - Escalando seus containers ( Aumentando a quantidade de container para o mesmo service ) via Docker Compose.
docker-compose scale [SERVICE=NUM...]
20 - Parando e removendo containers usando o Docker Compose:
docker-compose down
21 - Startando os containers:
docker-compose start