O primeiro vulnerabilidade crítica na plataforma de orquestração de contêineres Kubernetes foi divulgada no início deste mês. Essa vulnerabilidade afeta todas as versões do Kubernetes superiores à 1.0.0. Ela também afeta as versões da plataforma RedHat OpenShift superiores à 3.0.0.

Nesta publicação, analisamos as causas, as atenuações e como isso afeta o Operador Autônomo do Couchbase.

A vulnerabilidade

Ao se conectar aos pods do Kubernetes, o usuário normalmente usará o comando:

Para os usuários do pacote de gerenciamento de contêineres do docker, isso parecerá muito familiar. Isso ocorre porque o comando é enviado primeiro para a API do Kubernetes, que atua como um proxy reverso. O proxy reverso encaminha a solicitação para o agente do Kubernetes em execução no nó em que reside o pod solicitado. Por fim, o comando é usado para se conectar diretamente ao contêiner do docker.

A vulnerabilidade é exposta no proxy reverso quando ocorre um erro com o comando exec remoto. As conexões com os serviços a jusante do proxy são deixadas abertas quando ocorre um erro. Isso, por sua vez, fornece uma maneira de os usuários aumentarem seus privilégios para o de um administrador de cluster do Kubernetes. Os usuários devem ter permissão para executar o comando por meio do controle de acesso baseado em função.

Com privilégios de nível de administrador, o usuário pode então se conectar a qualquer contêiner em execução no nó do Kubernetes comprometido. Isso permite o acesso a quaisquer segredos (normalmente nomes de usuário, senhas, chaves privadas TLS etc.) e volumes de dados montados no contêiner. Isso é ainda mais preocupante se o contêiner estiver sendo executado com privilégios elevados (raiz). Além disso, o contêiner também pode ter o sistema de arquivos do host montado no modo de leitura/gravação.

Uma segunda variante se baseia novamente na mesma vulnerabilidade de proxy reverso subjacente. Na primeira variante, o usuário teria que ser autenticado e ter direitos de acesso para executar comandos em contêineres antes que o aumento de privilégio pudesse ser realizado. Com a segunda variante, nenhuma autenticação é necessária para obter acesso administrativo. O escopo dessa vulnerabilidade é limitado à modificação de corretores de serviço. Esses são serviços gerenciados que podem ser descobertos e usados por um aplicativo.

As mitigações

Para a primeira variante da vulnerabilidade, você pode evitar o aumento de privilégios dos seus usuários removendo as permissões para usar o executar, anexar e encaminhamento de porta para pods. Essas permissões são concedidas por padrão na maioria das instalações. No entanto, os comandos são normalmente necessários na maioria dos ambientes para fins de depuração e teste, portanto, desativar o acesso pode não ser a resposta correta.

O melhor método para evitar todas as vulnerabilidades, portanto, é atualizar o cluster do Kubernetes para uma versão que tenha a vulnerabilidade corrigida. As versões corrigidas começam no Kubernetes 1.10.11, 1.11.5 e 1.12.3.

O Operador Autônomo do Couchbase é compatível com as versões 1.11.0 do Kubernetes em diante. Recomendamos uma atualização para uma das versões corrigidas aplicáveis do Kubernetes o mais rápido possível. O Operador Autônomo em si não é afetado de forma alguma por essas vulnerabilidades ou correções; no entanto, os pods do servidor Couchbase criados podem estar sujeitos à primeira vulnerabilidade, comprometendo a integridade dos dados.

Considerações sobre o operador autônomo

Embora nunca seja bom estar sujeito a uma vulnerabilidade crítica, nós nos preparamos para essas eventualidades. As instruções completas de atualização do Kubernetes são fornecidas na seção Documentação do Operator 1.1.0No entanto, discutiremos mais detalhadamente sobre eles nesta postagem.

Como um serviço com estado, é necessário tomar cuidado com a atualização do cluster do Kubernetes para manter a integridade dos dados da plataforma de dados do Couchbase.

Uma abordagem padrão de atualização contínua adotada por muitos aplicativos de gerenciamento do Kubernetes atualiza cada nó de trabalho em ordem. Para atualizar um único nó, os pods são primeiro despejados (excluídos). Se um pod fizer parte de um aplicativo, como uma implantação, o controlador que gerencia o aplicativo recriará todos os pods eliminados. Isso é feito para restaurar o dimensionamento correto. Após o despejo, o agente do Kubernetes pode ser atualizado. O host subjacente pode ser reinicializado. Esse é um bom momento para a aplicação de patches do sistema operacional. Por fim, o nó pode ser adicionado novamente ao cluster.

Para um serviço sem estado, são necessários apenas alguns segundos para recriar o pod e adicioná-lo novamente ao pool de serviços. Para um aplicativo com estado, como o servidor Couchbase, isso pode levar muito mais tempo.

O que acontece durante um despejo?

Tomemos como exemplo um cluster do Couchbase com 3 nós. O cluster do Couchbase contém um único bucket com uma única réplica.

Quando o primeiro pod do Couchbase for removido, o Operador Autônomo detectará que ele está inativo e aguardará a ocorrência do failover. O failover restaura a disponibilidade de seus dados a partir de uma réplica. Depois que o failover ocorrer, o Operador Autônomo criará um novo pod e começará a rebalancear os dados no cluster do Couchbase. Isso restaura o número correto de réplicas. É importante observar que, durante esse processo, você precisará de um nó adicional do Kubernetes para acomodar o novo pod.

Como perdemos um dos três nós, 66% de documentos contidos no bucket serão degradados com apenas uma única réplica. Para ilustrar, a tabela a seguir mostra 6 documentos mestres (em negrito) e onde residem suas réplicas. Se o servidor 1 fosse expulso, os documentos A, B, D e E teriam apenas uma única réplica.

Servidor 1 Servidor 2 Servidor 3
A A
B B
C C
D D
E E
F F

Enquanto o rebalanceamento está ocorrendo, não há nada que impeça o processo de atualização do Kubernetes de despejar outro pod do Couchbase. Se isso acontecer, há o risco de que até 33% de seus dados não tenham réplicas e sejam perdidos. No exemplo acima, o servidor 2 sendo despejado resultaria em documentos A e D irrecuperáveis.

Portanto, é fundamental controlar como e quando os nós do Kubernetes são despejados. Depois que um pod do servidor Couchbase é despejado, você deve permitir que o Operador Autônomo crie um pod substituto e que os dados sejam totalmente rebalanceados antes de fazer upgrade do próximo nó do Kubernetes.

Práticas recomendadas para operadores autônomos

Recomendamos o uso de antiafinidade de pod ao configurar seu cluster do Couchbase. Esse recurso garante que dois pods do servidor Couchbase do mesmo cluster do Couchbase não possam residir no mesmo nó do Kubernetes. Isso garante que, no máximo, uma única réplica possa ser perdida de cada vez.

Também é altamente recomendável usar volumes persistentes. Em nossa última postagem descrevemos como exigimos o uso de volumes persistentes para proteger contra a perda de dados e dar suporte ao produto. Um benefício importante é que, nos exemplos apresentados na última seção, os dados não seriam perdidos.

O Operador Autônomo pode recriar um novo pod e reutilizar o volume de dados existente. O rebalanceamento de dados nesse cluster é substancialmente mais rápido, pois somente os documentos que foram atualizados desde o failover precisam ser replicados nos pods de substituição.

Mesmo com os volumes persistentes ativados, ainda é possível que vários pods sejam despejados em uma rápida sucessão. Isso pode fazer com que determinados documentos fiquem temporariamente indisponíveis até que o Operador Autônomo possa restaurar os dados.

Olhando para o futuro

Queremos que toda a experiência de atualização do Kubernetes seja perfeita. Isso ocorre precisamente porque serão encontrados bugs na plataforma Kubernetes ou no sistema operacional. Eles precisarão ser corrigidos para garantir que seus aplicativos sejam estáveis e seguros.

Embora os volumes persistentes sejam parte da resposta, eles não são uma solução completa. Há situações em que a indisponibilidade de documentos ainda pode ocorrer. Para resolver isso, temos o prazer de anunciar que o Autonomous Operator 1.2.0 apresentará aprimoramentos para reduzir a interrupção dos seus documentos apenas durante o período de failover.

Ao aproveitar os orçamentos de interrupção de pods do Kubernetes, podemos controlar com precisão quantos pods o Operador Autônomo permitirá que sejam despejados a qualquer momento. Isso evita que várias réplicas de dados sejam despejadas ao mesmo tempo.

Além disso, as verificações de prontidão do pod usadas pelos orçamentos de interrupção foram aprimoradas para saber se os pods do servidor Couchbase estão ativos e se todos os dados estão totalmente replicados no cluster. Isso permite que o Operador Autônomo controle precisamente quando um novo despejo pode ocorrer.

Conclusão

O Couchbase Autonomous Operator foi projetado não apenas como um produto para simplificar a implantação e o gerenciamento da plataforma de dados do Couchbase. Temos uma visão mais ampla de que operar em plataformas gerenciadas de nuvem pública terá seus desafios exclusivos. A equipe trabalha continuamente para proteger seus dados e fornecer alta disponibilidade dos mesmos, tanto em situações sob nosso controle quanto fora dele.

Autor

Postado por Simon Murray, engenheiro de software sênior, Couchbase

Simon tem quase 20 anos de experiência em diversos tópicos, como programação de sistemas, desempenho de aplicativos e armazenamento em escala. A nuvem é agora seu foco atual, especializando-se em arquitetura de rede corporativa, segurança da informação e orquestração de plataformas em uma ampla gama de tecnologias.

Deixar uma resposta