Olá! Meu nome é Sergey, sou DevOps na Surf. O departamento de DevOps da Surf tem como objetivo não apenas estabelecer a interação entre especialistas e integrar fluxos de trabalho, mas também realizar pesquisas ativas e implementar tecnologias relevantes tanto em nossa infraestrutura quanto na infraestrutura dos clientes.
Abaixo, vou falar um pouco sobre as mudanças no stack tecnológico para contêineres que encontramos ao estudar a distribuição. CentOS 8 e sobre o que é CRI-O e como configurar rapidamente um ambiente executável com ele para Kubernetes.

Por que o Docker não está na instalação padrão do CentOS 8
Após a instalação das últimas grandes versões RHEL 8 ou CentOS 8 não se pode deixar de notar: nessas distribuições e repositórios oficiais, falta o aplicativo Docker, que ideológica e funcionalmente substitui os pacotes Podman, Buildah (presentes na distribuição por padrão) e CRI-O. Isso está relacionado à implementação prática dos padrões desenvolvidos, entre outros por, a empresa Red Hat no âmbito do projeto Open Container Initiative (OCI).
O objetivo da OCI, que faz parte da The Linux Foundation, é criar padrões abertos da indústria para formatos e ambientes executáveis de contêineres, que atendam a várias demandas. Primeiro, que não contrariem a filosofia do Linux (por exemplo, na parte de que cada programa deve executar uma única tarefa, enquanto Docker representa um tipo de equipamento tudo-em-um). Em segundo lugar, que possam eliminar todas as deficiências existentes no software. DockerEm terceiro lugar, que sejam totalmente compatíveis com os requisitos de negócios impostos pelas principais plataformas comerciais para implantação, gerenciamento e manutenção de aplicativos conteinerizados (por exemplo, Red Hat OpenShift).
Desvantagens Docker As qualidades do novo software já foram descritas em detalhes em , e para uma descrição detalhada de todo o stack de software oferecido no âmbito do projeto OCI e suas características arquitetônicas, você pode consultar a documentação oficial e artigos tanto da própria Red Hat (uma boa no blog da Red Hat), quanto de análises de terceiros. .
— interação direta com contêineres e armazenamento de imagens através do processo runC;
- Podman — construção e envio de imagens para o registro;
- Buildah — ambiente executável para sistemas de orquestração de contêineres (por exemplo, Kubernetes).
- CRI-O — ambiente de execução para sistemas de orquestração de containers (por exemplo, Kubernetes).
Acredito que, para compreender o esquema geral de interação entre os componentes do stack, é razoável apresentar aqui um diagrama das relações. Kubernetes c runC e bibliotecas de baixo nível com o uso de CRI-O:

CRI-O e Kubernetes mantêm o mesmo ciclo de lançamento e suporte (a matriz de compatibilidade é muito simples: versões principais Kubernetes e CRI-O coincidem), o que, com foco em testes completos e abrangentes deste stack pelos desenvolvedores, nos dá o direito de esperar a máxima estabilidade possível em qualquer cenário de uso (aqui, a relativa leveza CRI-O em comparação com Docker devido à limitação intencional de funcionalidades).
Ao instalar Kubernetes da maneira "certa" (segundo a OCI, claro) utilizando CRI-O para CentOS 8 encontramos algumas dificuldades, que, no entanto, superamos com sucesso. Ficarei feliz em compartilhar o guia de instalação e configuração, que levará no máximo 10 minutos.
Como implantar Kubernetes no CentOS 8 usando o ambiente CRI-O.
Pré-requisitos: ter pelo menos um host (2 núcleos, 4 GB de RAM, armazenamento de pelo menos 15 GB) com CentOS 8 (recomenda-se o perfil de instalação "Server"), além de uma entrada correspondente no DNS local (se necessário, pode-se usar uma entrada no /etc/hosts). E não se esqueça de .
Todas as operações no host devem ser realizadas sob o usuário root, tenha cuidado.
- No primeiro passo, configuraremos o SO, instalaremos e configuraremos as dependências preliminares para o CRI-O.
- Atualizaremos o SO:
dnf -y update
- Em seguida, precisamos configurar o firewall e o SELinux. O sucesso aqui depende do ambiente em que nosso host ou hosts operarão. Você pode ou configurar o firewall de acordo com as recomendações de , ou, se estiver em uma rede de confiança ou utilizando um firewall de terceiros, alterar a zona padrão para confiável ou desativar o firewall:
firewall-cmd --set-default-zone trusted firewall-cmd --reloadPara desativar o firewall, você pode usar o seguinte comando:
systemctl disable --now firewalldO SELinux deve ser desativado ou colocado em modo "permissivo":
setenforce 0 sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
- carregaremos os módulos do kernel e pacotes necessários, configuraremos o carregamento automático do módulo "br_netfilter" na inicialização do sistema:
modprobe overlay modprobe br_netfilter echo "br_netfilter" >> /etc/modules-load.d/br_netfilter.conf dnf -y install iproute-tc
- Para ativar o encaminhamento de pacotes e processar o tráfego corretamente, faremos as configurações necessárias:
cat > /etc/sysctl.d/99-kubernetes-cri.conf <<EOF net.bridge.bridge-nf-call-iptables = 1 net.ipv4.ip_forward = 1 net.bridge.bridge-nf-call-ip6tables = 1 EOFAplicaremos as configurações feitas:
sysctl --system
- Definiremos a versão necessária CRI-O (versão principal CRI-O, como já mencionado, coincide com a versão requerida Kubernetes), uma vez que a última versão estável Kubernetes no momento é 1.18:
export REQUIRED_VERSION=1.18Adicionaremos os repositórios necessários:
dnf -y install 'dnf-command(copr)' dnf -y copr enable rhcontainerbot/container-selinux curl -L -o /etc/yum.repos.d/devel:kubic:libcontainers:stable.repo https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/CentOS_8/devel:kubic:libcontainers:stable.repo curl -L -o /etc/yum.repos.d/devel:kubic:libcontainers:stable:cri-o:$REQUIRED_VERSION.repo https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable:cri-o:$REQUIRED_VERSION/CentOS_8/devel:kubic:libcontainers:stable:cri-o:$REQUIRED_VERSION.repo
- Agora podemos instalar CRI-O:
dnf -y install cri-oPreste atenção no primeiro ponto que encontramos durante o processo de instalação: é necessário editar a configuração CRI-O antes de iniciar o serviço, pois o componente requerido conmon tem um local de instalação diferente do especificado:
sed -i 's//usr/libexec/crio/conmon//usr/bin/conmon/' /etc/crio/crio.confAgora podemos ativar e iniciar o daemon CRI-O:
systemctl enable --now crioPodemos verificar o status do daemon:
systemctl status crio
- Atualizaremos o SO:
- Instalação e ativação Kubernetes.
- Adicionaremos o repositório necessário:
cat < /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-$basearch enabled=1 gpgcheck=1 repo_gpgcheck=1 gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg exclude=kubelet kubeadm kubectl EOFAgora podemos instalar Kubernetes (versões 1.18, como já mencionado acima):
dnf install -y kubelet-1.18* kubeadm-1.18* kubectl-1.18* --disableexcludes=kubernetes
- Um segundo ponto importante: já que não estamos usando o daemon Docker, mas sim usando o daemon CRI-O, antes de executar e inicializar Kubernetes é necessário fazer as configurações correspondentes no arquivo de configuração /var/lib/kubelet/config.yaml, criando previamente o diretório necessário:
mkdir /var/lib/kubelet cat < /var/lib/kubelet/config.yaml apiVersion: kubelet.config.k8s.io/v1beta1 kind: KubeletConfiguration cgroupDriver: systemd EOF
- Um terceiro ponto importante, que encontramos durante a instalação: apesar de termos especificado o driver utilizado cgroup, e sua configuração através de argumentos passados kubelet está obsoleta (como indicado na documentação), precisamos adicionar argumentos ao arquivo, caso contrário, nosso cluster não será inicializado:
cat /dev/null > /etc/sysconfig/kubelet cat < /etc/sysconfig/kubelet KUBELET_EXTRA_ARGS=--container-runtime=remote --cgroup-driver=systemd --container-runtime-endpoint='unix:///var/run/crio/crio.sock' EOF
- Agora podemos ativar o daemon kubelet:
sudo systemctl enable --now kubeletPara configurar control-plane ou worker nós em poucos minutos, você pode usar .
- Adicionaremos o repositório necessário:
- É hora de inicializar nosso cluster.
- Para inicializar o cluster, execute o comando:
kubeadm init --pod-network-cidr=10.244.0.0/16Certifique-se de anotar o comando de junção ao cluster "kubeadm join ..." proposto no final da saída, ou pelo menos os tokens indicados.
- Vamos instalar o plugin (CNI) para trabalhar com Pod network. Eu recomendo usar Calico. Pode ser que outros mais populares Flannel tenham problemas de compatibilidade com nftables, e também Calico é a única implementação CNI recomendada e totalmente testada pelo projeto Kubernetes:
kubectl --kubeconfig /etc/kubernetes/admin.conf apply -f https://docs.projectcalico.org/v3.15/manifests/calico.yaml
- Para conectar o nó worker ao nosso cluster, ele precisa ser configurado de acordo com as instruções 1 e 2, ou usar , em seguida executar o comando da saída "kubeadm init ..." que anotamos na etapa anterior:
kubeadm join $CONTROL_PLANE_ADDRESS:6443 --token $TOKEN --discovery-token-ca-cert-hash $TOKEN_HASH
- Vamos verificar se nosso cluster foi inicializado e começou a funcionar:
kubectl --kubeconfig=/etc/kubernetes/admin.conf get pods -A
Pronto! Você já pode implantar cargas de trabalho no seu cluster K8s.
- Para inicializar o cluster, execute o comando:
O que nos espera a seguir
Espero que as instruções acima tenham ajudado você a economizar algum tempo e nervos.
A evolução dos processos que acontecem na indústria muitas vezes depende de como são aceitos pela maioria dos usuários finais e desenvolvedores de outros softwares na respectiva área. Ainda não está claro qual será o resultado das iniciativas OCI em alguns anos, mas estaremos felizes em acompanhar isso. Você pode compartilhar sua opinião agora mesmo nos comentários.
Fique atento!
Este artigo foi possível graças às seguintes fontes:
- Seção sobre Container runtimes em
- do projeto CRI-O na Internet
- Artigos em blogs da Red Hat: , e muitos outros
Fonte: habr.com
