Red Hat Training

A Red Hat training course is available for RHEL 8

Capítulo 11. Usando as ferramentas do container CLI

11.1. podman

O comando podman (que significa Pod Manager) permite que você execute containers como entidades autônomas, sem exigir que Kubernetes, o Docker runtime, ou qualquer outro tempo de execução de containers esteja envolvido. É uma ferramenta que pode atuar como um substituto para o comando docker, implementando a mesma sintaxe de linha de comando, enquanto adiciona ainda mais recursos de gerenciamento de contêineres. As características do podman incluem:

  • Based on the Docker interface: Como podman é o espelho da sintaxe do comando docker, a transição para podman deve ser fácil para quem está familiarizado com docker.
  • Managing containers and images: Tanto as imagens de contêineres compatíveis com Docker como com OCI podem ser usadas com podman para:

    • Correr, parar e reiniciar containers
    • Criar e gerenciar imagens de containers (empurrar, comprometer, configurar, construir, e assim por diante)
  • Managing pods: Além de operar containers individuais, podman pode operar um conjunto de containers agrupados em uma cápsula. Um pod é a menor unidade de contêineres que a Kubernetes administra.
  • Working with no runtime: Nenhum ambiente de tempo de execução é usado por podman para trabalhar com contêineres.

Aqui estão algumas características de implementação do Podman que você deve conhecer:

  • Podman, Buildah e o motor de contêineres CRI-O usam todos o mesmo diretório de back-end, /var/lib/containers, em vez de usar o local de armazenamento Docker (/var/lib/docker), por padrão.
  • Embora Podman, Buildah e CRI-O compartilhem o mesmo diretório de armazenamento, eles não podem interagir com os containers um do outro. Essas ferramentas podem, no entanto, compartilhar imagens. Eventualmente, essas características serão capazes de compartilhar os containers.
  • O comando podman, como o comando docker, pode construir imagens de contêineres a partir de um Dockerfile.
  • O comando podman pode ser uma ferramenta útil de solução de problemas quando o serviço CRI-O não estiver disponível.
  • As opções para o comando docker que não são suportadas por podman incluem rede, nó, plugin (podman não suporta plugins), renomear (usar rm e criar para renomear containers com podman), segredo, serviço, pilha, e enxame (podman não suporta enxame de Docker Swarm). As opções de container e imagem são usadas para executar subcomandos que são usados diretamente em podman.
  • Para interagir programmaticamente com o podman, você pode usar o Podman v2.0 RESTful API, ele funciona tanto em um ambiente sem raízes quanto em um ambiente sem raízes. Para mais informações, consulte o capítulo Utilização da API de ferramentas de contêiner.

11.1.1. Usando comandos podman

Se você está acostumado a usar o comando docker para trabalhar com recipientes, você encontrará a maioria das características e opções que correspondem às do podman. A Tabela 1 mostra uma lista de comandos que você pode usar com podman (digite podman -h para ver esta lista):

Tabela 11.1. Comandos apoiados por podman

comando podman

Descrição

comando podman

Descrição

attach

Fixar a um recipiente em funcionamento

commit

Criar uma nova imagem a partir de um container modificado

build

Construir uma imagem usando as instruções do Dockerfile

create

Criar, mas não começar, um recipiente

diff

Inspecionar mudanças nos sistemas de arquivos dos contêineres

exec

Executar um processo em um contêiner em funcionamento

export

Conteúdo do sistema de arquivos do contêiner de exportação como um arquivo de alcatrão

help, h

Mostra uma lista de comandos ou ajuda para um comando

history

Mostrar o histórico de uma imagem específica

images

Listar imagens em armazenamento local

import

Importar um tarball para criar uma imagem do sistema de arquivos

info

Exibir informações do sistema

inspect

Exibir a configuração de um recipiente ou imagem

kill

Enviar um sinal específico para um ou mais recipientes em funcionamento

load

Carregar uma imagem de um arquivo

login

Login em um registro de contêineres

logout

Logout de um registro de contêineres

logs

Buscar os logs de um contêiner

mount

Montar o sistema de arquivos raiz de um contêiner em funcionamento

pause

Pausa todos os processos em um ou mais recipientes

ps

Listar recipientes

port

Lista de mapeamentos de portas ou um mapeamento específico para o contêiner

pull

Puxar uma imagem de um registro

push

Empurrar uma imagem para um destino específico

restart

Reiniciar um ou mais recipientes

rm

Remover um ou mais recipientes do hospedeiro. Adicione -f se estiver funcionando.

rmi

remove uma ou mais imagens do armazenamento local

run

executar um comando em um novo container

save

Salvar imagem em um arquivo

search

registro de busca de imagem

start

Iniciar um ou mais recipientes

stats

Exibir porcentagem de CPU, memória, E/S da rede, E/S de bloco e PIDs para um ou mais recipientes

stop

Parar um ou mais recipientes

tag

Acrescentar um nome adicional a uma imagem local

top

Mostrar os processos em andamento de um recipiente

umount, unmount

Desmontar o sistema de arquivos raiz de um contêiner em funcionamento

unpause

Despausar os processos em um ou mais recipientes

version

Exibir informações sobre a versão podman

wait

Bloqueio em um ou mais recipientes

  

11.1.2. Criação de políticas SELinux para contêineres

Para gerar políticas SELinux para contêineres, utilize a ferramenta UDICA. Para mais informações, consulte Introdução ao gerador de políticas SELinux da udica.

11.1.3. Usando podman com MPI

Você pode usar Podman com MPI (Message Passing Interface) aberto para executar containers em um ambiente de computação de alto desempenho (HPC).

O exemplo é baseado no programa ring.c retirado do Open MPI. Neste exemplo, um valor é passado por todos os processos de uma forma semelhante a um anel. Cada vez que a mensagem passa de nível 0, o valor é decrescido. Quando cada processo recebe a mensagem 0, ele a passa para o processo seguinte e depois desiste. Ao passar o 0 primeiro, cada processo recebe a mensagem 0 e pode desistir normalmente.

Procedimento

  1. Instalar MPI aberto:

    $ sudo yum instalar openmpi
  2. Para ativar os módulos do ambiente, digite:

    $ . /etc/profile.d/modules.sh
  3. Carregue o módulo mpi/openmpi-x86_64:

    $ módulo de carga mpi/openmpi-x86_64

    Opcionalmente, para carregar automaticamente o módulo mpi/openmpi-x86_64, adicione esta linha ao arquivo .bashrc:

    $ echo "module load mpi/openmpi-x86_64\" >> .bashrc
  4. Para combinar mpirun e podman, criar um recipiente com a seguinte definição:

    $ cat Containerfile
    FROM registry.access.redhat.com/ubi8/ubi
    
    RUN yum -y install openmpi-devel wget && \
        yum clean all
    
    RUN wget https://raw.githubusercontent.com/open-mpi/ompi/master/test/simple/ring.c && \
        /usr/lib64/openmpi/bin/mpicc ring.c -o /home/ring && \
        rm -f ring.c
  5. Construa o recipiente:

    $ podman build --tag=mpi-ring .
  6. Comece o recipiente. Em um sistema com 4 CPUs este comando inicia 4 contêineres:

    $ mpirun \
       --mca orte_tmpdir_base /tmp/podman-mpirun \
       podman run --env-host \
         -v /tmp/podman-mpirun:/tmp/podman-mpirun \
         --userns=keep-id \
         --net=host --pid=host --ipc=host \
         mpi-ring /home/ring
    Rank 2 has cleared MPI_Init
    Rank 2 has completed ring
    Rank 2 has completed MPI_Barrier
    Rank 3 has cleared MPI_Init
    Rank 3 has completed ring
    Rank 3 has completed MPI_Barrier
    Rank 1 has cleared MPI_Init
    Rank 1 has completed ring
    Rank 1 has completed MPI_Barrier
    Rank 0 has cleared MPI_Init
    Rank 0 has completed ring
    Rank 0 has completed MPI_Barrier

    Como resultado, mpirun inicia 4 recipientes Podman e cada recipiente está rodando uma instância do binário ring. Todos os 4 processos estão se comunicando por MPI entre si.

    As seguintes opções de mpirun são usadas para iniciar o recipiente:

    • a linha--mca orte_tmpdir_base /tmp/podman-mpirun diz à Open MPI para criar todos os seus arquivos temporários em /tmp/podman-mpirun e não em /tmp. Se utilizar mais de um nó, este diretório será nomeado de forma diferente em outros nós. Isto requer a montagem do diretório /tmp completo dentro do container, o que é mais complicado.

    O comando mpirun especifica o comando a ser iniciado, o comando podman. As seguintes opções podman são usadas para iniciar o contêiner:

    • o comandorun executa um contêiner.
    • a opção--env-host copia todas as variáveis de ambiente do host para o container.
    • -v /tmp/podman-mpirun:/tmp/podman-mpirun diz à Podman para montar o diretório onde a Open MPI cria seus diretórios e arquivos temporários para estarem disponíveis no container.
    • a linha--userns=keep-id garante o mapeamento da identificação do usuário dentro e fora do contêiner.
    • a linha--net=host --pid=host --ipc=host define a mesma rede, PID e IPC namespaces.
    • mpi-ring é o nome do recipiente.
    • /home/ring é o programa MPI no contêiner.

Para mais informações, veja o artigo Podman em ambientes HPC por Adrian Reber.

11.1.4. Criação e restauração de pontos de verificação de contêineres

Checkpoint/Restore In Userspace (CRIU) é um software que permite definir um ponto de verificação em um container em funcionamento ou em um aplicativo individual e armazenar seu estado em disco. Você pode usar os dados salvos para restaurar o contêiner após um reinício no mesmo ponto no tempo em que ele foi verificado.

11.1.4.1. Criação e restauração local de um ponto de verificação de contêineres

Este exemplo é baseado em um servidor web baseado em Python que retorna um único número inteiro que é incrementado após cada solicitação.

Procedimento

  1. Criar um servidor baseado em Python:

    # cat counter.py
    #!/usr/bin/python3
    
    import http.server
    
    counter = 0
    
    class handler(http.server.BaseHTTPRequestHandler):
        def do_GET(s):
            global counter
               s.send_response(200)
               s.send_header('Content-type', 'text/html')
               s.end_headers()
               s.wfile.write(b'%d\n' % counter)
               counter += 1
    
    
    server = http.server.HTTPServer(('', 8088), handler)
    server.serve_forever()
  2. Crie um recipiente com a seguinte definição:

    # cat Containerfile
    FROM registry.access.redhat.com/ubi8/ubi
    
    COPY counter.py /home/counter.py
    
    RUN useradd -ms /bin/bash counter
    
    RUN yum -y install python3 && chmod 755 /home/counter.py
    
    USER counter
    ENTRYPOINT /home/counter.py

    O recipiente é baseado na Imagem Base Universal (UBI 8) e utiliza um servidor baseado em Python.

  3. Construa o recipiente:

    # podman build . --contador de etiquetas

    Os arquivos counter.py e Containerfile são a entrada para o processo de construção do contêiner (podman build). A imagem construída é armazenada localmente e etiquetada com a etiqueta counter.

  4. Comece o recipiente como raiz:

    # podman run --name criu-test --detach counter
  5. Para listar todos os contêineres em funcionamento, entre:

    # podman ps
    CONTAINER ID  IMAGE  COMMAND  CREATED   STATUS  PORTS NAMES
    e4f82fd84d48  localhost/counter:latest  5 seconds ago  Up 4 seconds ago  criu-test
  6. Mostrar o endereço IP do recipiente:

    # podman inspect criu-test --format "{{.NetworkSettings.IPAddress}}"
    10.88.0.247
  7. Enviar pedidos para o container:

    # curl 10.88.0.247:8080
    0
    # curl 10.88.0.247:8080
    1
  8. Criar um ponto de controle para o contêiner:

    # podman ponto de verificação de contêineres criu-teste
  9. Reinicie o sistema.
  10. Restaurar o recipiente:

    # podman container restore -- manter criu-test
  11. Enviar pedidos para o container:

    # curl 10.88.0.247:8080
    2
    # curl 10.88.0.247:8080
    3
    # curl 10.88.0.247:8080
    4

    O resultado agora não começa novamente em 0, mas continua com o valor anterior.

Desta forma, você pode facilmente salvar o estado completo do recipiente através de uma reinicialização.

Para mais informações, consulte o artigo Adicionando ponto de verificação/restauração ao Podman por Adrian Reber.

11.1.4.2. Redução do tempo de partida usando o container restore

Você pode usar a migração de contêineres para reduzir o tempo de inicialização dos contêineres que requerem um certo tempo para serem inicializados. Usando um ponto de verificação, você pode restaurar o container várias vezes no mesmo host ou em hosts diferentes. Este exemplo é baseado no container da seção Criando e restaurando um ponto de verificação de container localmente.

Procedimento

  1. Criar um ponto de controle do container e exportar a imagem do ponto de controle para um arquivo tar.gz:

    # podman ponto de verificação criu-teste de contêineres - exportação /tmp/chkpt.tar.gz
  2. Restaurar o recipiente a partir do arquivo tar.gz:

    # podman container restore --import /tmp/chkpt.tar.gz --name counter1
    # podman container restore --import /tmp/chkpt.tar.gz --name counter2
    # podman container restore --import /tmp/chkpt.tar.gz --name counter3

    A opção --name (-n) especifica um novo nome para os contêineres restaurados a partir do ponto de controle exportado.

  3. Mostrar ID e nome de cada recipiente:

    # podman ps -a --format "{{.ID}} {{.Names}}"
    a8b2e50d463c counter3
    faabc5c27362 counter2
    2ce648af11e5 counter1
  4. Mostrar o endereço IP de cada contêiner:

    #️ podman inspect counter1 --format "{{.NetworkSettings.IPAddress}}"
    10.88.0.248
    
    #️ podman inspect counter2 --format "{{.NetworkSettings.IPAddress}}"
    10.88.0.249
    
    #️ podman inspect counter3 --format "{{.NetworkSettings.IPAddress}}"
    10.88.0.250
  5. Enviar pedidos para cada contêiner:

    #️ curl 10.88.0.248:8080
    4
    #️ curl 10.88.0.249:8080
    4
    #️ curl 10.88.0.250:8080
    4

    Note que o resultado é 4 em todos os casos, porque você está trabalhando com diferentes recipientes restaurados a partir do mesmo ponto de verificação.

Usando esta abordagem, você pode iniciar rapidamente réplicas do contêiner inicialmente marcado.

Para mais informações, consulte o artigo Migração de contêineres com Podman sobre a RHEL, de Adrian Reber.

11.1.4.3. Migração de contêineres entre sistemas

Este procedimento mostra a migração de containers em funcionamento de um sistema para outro, sem perder o estado das aplicações em funcionamento no container. Este exemplo é baseado no container da seção Criando e restaurando um ponto de verificação de container localmente etiquetado com counter.

Pré-requisitos

As seguintes etapas não são necessárias se o contêiner for empurrado para um registro, pois Podman fará automaticamente o download do contêiner de um registro se ele não estiver disponível localmente. Este exemplo não utiliza um registro, você tem que exportar o contêiner previamente construído e etiquetado (veja Criação e restauração de um ponto de verificação de contêineres localmente ) localmente e importar o contêiner no sistema de destino desta migração.

  • Exportar contêineres previamente construídos:

    # podman save --output counter.tar counter
  • Cópia da imagem do recipiente exportado para o sistema de destino (other_host):

    # scp counter.tar other_host:
  • Importação de contêineres exportados no sistema de destino:

    # ssh other_host podman load --input counter.tar

Agora o sistema de destino desta migração de contêineres tem a mesma imagem de contêiner armazenada em seu armazenamento local de contêineres.

Procedimento

  1. Comece o recipiente como raiz:

    # podman run --name criu-test --detach counter
  2. Mostrar o endereço IP do recipiente:

    # podman inspect criu-test --format "{{.NetworkSettings.IPAddress}}"
    10.88.0.247
  3. Enviar pedidos para o container:

    # curl 10.88.0.247:8080
    0
    # curl 10.88.0.247:8080
    1
  4. Criar um ponto de controle do container e exportar a imagem do ponto de controle para um arquivo tar.gz:

    # podman ponto de verificação de contêineres criu-teste - exportação /tmp/chkpt.tar.gz
  5. Copiar o arquivo do ponto de verificação para o anfitrião de destino:

    # scp /tmp/chkpt.tar.gz other_host:/tmp/
  6. Restaurar o ponto de controle no host de destino (other_host):

    # podman container restore --import /tmp/chkpt.tar.gz
  7. Enviar um pedido ao contêiner no host de destino (other_host):

    # curl 10.88.0.247:8080
    2

Como resultado, o contentor estatal foi migrado de um sistema para outro sem perder seu estado.

Para mais informações, consulte o artigo Migração de contêineres com Podman sobre a RHEL, de Adrian Reber.