Atualize o contêiner Docker sem tempo de inatividade

Digamos que eu tenha um contêiner Docker com um servidor da web (como o Apache 2). Agora eu quero atualizar o sistema operacional sob ele. Esta resposta SF diz que a melhor maneira é reconstruir a imagem base e minha imagem Apache. Mas implantar a imagem significa tempo de inatividade porque tenho que excluir o contêiner antigo antes de poder criar o novo, então há apenas um contêiner que está vinculado à porta 80/443.

Mas como posso implantar essa atualização com tempo de inatividade zero? Devo usar um balanceador de carga e usar a comunicação entre contêineres? E como faço para atualizar o balanceador de carga?

O cenário alvo ideal

Sim, você deve usar um balanceador de carga e atualizar uma instância por vez. Não tenho certeza de onde entra a comunicação entre contêineres.

Como exemplo, imagine que você tem um balanceador de carga que atende ao seu site A. Os usuários se conectam apenas a ele como e só o conhecem como "A". O balanceador de carga sabe que existem dois ou mais backends (B, C, etc.), e se eles são VMs ou contêineres não importa.

Em seguida, você deseja atualizar os back-ends, que neste caso são instâncias do Apache.

  1. tire B dos back-ends elegíveis para o balanceador de carga para que ele não aceite mais nenhum tráfego.
  2. aguarde até que as solicitações atuais sejam atendidas e as conexões existentes sejam fechadas.
  3. atualize o contêiner ou VM subjacente que serve B
  4. reinicie B, espere que ele carregue e comece a trabalhar
  5. teste B para se certificar de que está atendendo a novas solicitações corretamente
  6. adicionar B de volta ao pool de back-end do balanceador de carga para reativar o tráfego

Em seguida, faça o mesmo processo para C, D, etc.

Observe que há um solicitação aberta para atualizações In-loco de contêineres Docker, a partir de Novembro de 2013, mas não parece ter muito progresso, então a solução acima é o que você deve fazer nesse meio tempo.

O que fazer para um site ao vivo existente

Presumivelmente, você está perguntando isso porque já está executando um site ao vivo neste modelo e gostaria de atualizá-lo sem tempo de inatividade. Então, precisamos chegar ao estado alvo ideal acima, mas de forma incremental.

Vamos supor que:

  • você tem um nome DNS apontando para o seu contêiner
  • seu contêiner é executado em algum endereço IP
  • seus usuários não sabem o endereço IP do contêiner e não é codificado em nenhum lugar

Se essas suposições forem falsas, você deve primeiro corrigi-las de forma que isso esteja correto.

Em seguida, siga estas etapas:

  1. crie um balanceador de carga em um novo IP e aponte-o para o contêiner existente como seu único back-end
  2. altere o DNS para apontar para o balanceador de carga em vez do IP do contêiner diretamente
  3. adicione um back-end Apache idêntico com a mesma configuração de contêiner VM +
  4. agora você tem um balanceador de carga com dois backends B E C, então siga as instruções na seção "cenário de destino ideal" para atualizá-los um de cada vez

Como atualizar um balanceador de carga

A maneira fácil (hospedada)

A opção mais fácil é não executar seu próprio balanceador. Por exemplo, se você estiver usando uma plataforma de nuvem que fornece balanceamento de carga como um serviço, considere usá-lo e, em seguida, a manutenção e atualização do balanceador de carga não é um problema.

A maneira manual

Se você estiver executando seu próprio balanceador de carga, adicionar outra camada de indireção (ou seja, DNS) ajudará. Vamos supor o seguinte:

  • que temos um nome de host resolvendo para o IP do nosso balanceador de carga A que gostaríamos de atualizar
  • nosso balanceador de carga tem um pool de back-end de P1, P2, etc.

Procedemos da seguinte forma:

  • crie um novo balanceador de carga B com a nova versão do software
  • adicione todas as instâncias do pool de back-end P1, P2, etc. para o nosso novo balanceador de carga B como backends
  • adicione o endereço IP de B à resolução DNS junto com A

    • agora estamos efetivamente usando o DNS como um balanceador de carga
    • se as entradas Para A E B não forem ponderadas, elas serão efetivamente 50-50
    • agora Assista para ver como B executa, se há algum erro, etc.
    • se algo estiver errado com B, desfazer da seguinte forma:

      1. remover B da configuração DNS
      2. aguarde até que a entrada B no DNS desapareça (ou seja, aguarde UTIL expirar)
      3. vire para baixo B
  • suponha que você tenha feito o teste "burn-in" para B e está tudo bem
  • atualizar o prioridade e peso para B no DNS gradualmente
  • remover um do DNS inteiramente
  • aguarde até que o DNS TTL expire; a não deve receber mais solicitações
  • abaixe um

e acabaste.

Detalhes, diagramas e ferramentas

Veja esses write-ups e ferramentas que podem ajudá-lo a automatizar o processo, mas a ideia geral é a mesma:

moral

"Todos os problemas na ciência da computação podem ser resolvidos por outro nível de indireção, exceto, é claro, pelo problema de muitas indireções."David Wheeler