k0s: Kubernetes em um único binário

Em nosso novo artigo traduzido, oferecemos uma visão geral rápida da nova distribuição do Kubernetes. Esperamos que o artigo seja interessante para os leitores da Habr.


Há alguns dias, um amigo me contou sobre uma nova distribuição do Kubernetes da Mirantis chamada k0s . Todos nós conhecemos e amamos K8s, certo? Também fomos cativados pelo K3s , um Kubernetes leve desenvolvido pela Rancher Labs e entregue à CNCF há algum tempo. É hora de descobrir a nova distribuição k0s!







Após uma breve introdução ao k0s, criaremos um cluster de três nós seguindo estas etapas:



  • Preparando três máquinas virtuais ( Multipass em ação)
  • Instalando k0s em cada um deles
  • Configurando um arquivo de configuração de cluster k0s simples
  • Inicialização de cluster
  • Obter acesso ao cluster
  • Adicionar nós de trabalho
  • Adicionar usuário


O que é k0s?



k0s é a mais nova distribuição do Kubernetes. A versão atual é 0.8.0. Foi publicado em dezembro de 2020, e o primeiro commit de todo o projeto aconteceu em junho de 2020.



k0s é enviado como um único binário sem nenhuma dependência do sistema operacional. Assim, ele é definido como uma distribuição Kubernetes com características de atrito zero / deps zero / custo zero (fácil de configurar / sem dependências / gratuito).



Versão mais recente do k0s:



  • Fornece certificado (certificado pelo Internet Security Center) Kubernetes 1.19
  • Usa containerd como o tempo de execução do contêiner padrão
  • Suporta arquiteturas Intel (x86-64) e ARM (ARM64)
  • Usa intragrupo etcd
  • Usa o plugin de rede Calico por padrão (ativando assim as políticas de rede)
  • Inclui controlador de acesso de política de segurança de pod
  • Usa DNS com CoreDNS
  • Fornece métricas de cluster por meio do Metrics Server
  • Permite o uso de escala automática de pod horizontal (HPA).


Muitos recursos interessantes virão em versões futuras, incluindo:



  • Tempo de execução da VM compacta (estou ansioso para testar esse recurso)
  • Atualização Zero Downtime Cluster
  • Backup e recuperação de cluster


Impressionante, não é? A seguir, veremos como usar k0s para implantar um cluster de 3 nós.



Preparando máquinas virtuais



Primeiro, criaremos três máquinas virtuais, cada uma das quais será um nó em nosso cluster. Neste artigo, vou seguir um caminho rápido e fácil e usar a excelente ferramenta Multipass (adoro isso) para preparar máquinas virtuais locais no MacOS.



Os comandos a seguir criam três instâncias do Ubuntu no xhyve. Cada máquina virtual possui 5 GB de disco, 2 GB de RAM e 2 processadores virtuais (vCPU):



for i in 1 2 3; do 
  multipass launch -n node$i -c 2 -m 2G
done
      
      





Podemos então exibir uma lista de máquinas virtuais para ter certeza de que estão funcionando bem:



$ multipass list
Name      State       IPv4             Image
node1     Running     192.168.64.11    Ubuntu 20.04 LTS
node2     Running     192.168.64.12    Ubuntu 20.04 LTS
node3     Running     192.168.64.13    Ubuntu 20.04 LTS
      
      





A seguir, instalaremos k0s em cada um desses nós.



Instalando a última versão do k0s



A versão mais recente do k0s pode ser baixada do repositório GitHub .



Possui um script de instalação conveniente:



curl -sSLf get.k0s.sh | sudo sh
      
      





Usamos este script para instalar k0s em todos os nossos nós:



for i in 1 2 3; do 
  multipass exec node$i --bash -c "curl -sSLf get.k0s.sh | sudo sh"
done
      
      





O script acima instala k0s em / user / bin / k0 . Para obter todos os comandos disponíveis, você executa o binário sem argumentos.





Comandos k0s disponíveis Podemos



verificar a versão atual:



$ k0s version
v0.8.0
      
      





Usaremos alguns dos comandos nas próximas etapas.



Criação de um arquivo de configuração



Primeiro, você precisa definir um arquivo de configuração que contém as informações de que o k0s precisa para criar um cluster. No node1, podemos executar o comando default-config para obter a configuração padrão completa. Entre outras coisas, isso nos permite determinar:



ubuntu@node1:~$ k0s default-config

apiVersion: k0s.k0sproject.io/v1beta1

kind: Cluster

metadata:

  name: k0s

spec:

  api:

    address: 192.168.64.11

    sans:

    - 192.168.64.11

    - 192.168.64.11

    extraArgs: {}

  controllerManager:

    extraArgs: {}

  scheduler:

    extraArgs: {}

  storage:

    type: etcd

    kine: null

    etcd:

      peerAddress: 192.168.64.11

  network:

    podCIDR: 10.244.0.0/16

    serviceCIDR: 10.96.0.0/12

    provider: calico

    calico:

      mode: vxlan

      vxlanPort: 4789

      vxlanVNI: 4096

      mtu: 1450

      wireguard: false

  podSecurityPolicy:

    defaultPolicy: 00-k0s-privileged

  workerProfiles: []

extensions: null

images:

  konnectivity:

    image: us.gcr.io/k8s-artifacts-prod/kas-network-proxy/proxy-agent

    version: v0.0.13

  metricsserver:

    image: gcr.io/k8s-staging-metrics-server/metrics-server

    version: v0.3.7

  kubeproxy:

    image: k8s.gcr.io/kube-proxy

    version: v1.19.4

  coredns:

    image: docker.io/coredns/coredns

    version: 1.7.0

  calico:

    cni:

      image: calico/cni

      version: v3.16.2

    flexvolume:

      image: calico/pod2daemon-flexvol

      version: v3.16.2

    node:

      image: calico/node

      version: v3.16.2

    kubecontrollers:

      image: calico/kube-controllers

      version: v3.16.2

  repository: ""

telemetry:

  interval: 10m0s

  enabled: true













  • Servidor API, Gerenciador de controlador e Opções de inicialização do agendador
  • Armazenamento que pode ser usado para armazenar informações de cluster ( etcd )
  • Plugin de rede e sua configuração ( Calico )
  • Versão de imagens de contêiner com componentes de gerenciamento
  • Alguns esquemas de gerenciamento adicionais para implantar ao iniciar um cluster


Poderíamos salvar essa configuração em um arquivo e adaptá-la às nossas necessidades. Mas neste artigo, vamos usar uma configuração muito simples e salvá-la em /etc/k0s/k0s.yaml . Nota : Como estamos inicializando o cluster em node1 , este nó servirá o servidor API. O endereço IP deste nó é usado em api.address e api.sans (nomes alternativos do assunto) no arquivo de configuração acima. Se tivéssemos nós mestres adicionais e um balanceador de carga acima deles, também usaríamos api.sans nas configurações



apiVersion: k0s.k0sproject.io/v1beta1

kind: Cluster

metadata:

  name: k0s

spec:

  api:

    address: 192.168.64.11

    sans:

    - 192.168.64.11

  network:

    podCIDR: 10.244.0.0/16

    serviceCIDR: 10.96.0.0/12









O endereço IP de cada host e balanceador de carga (ou nome de domínio correspondente).



Inicialização de cluster



Primeiro, criamos uma unidade systemd em node1 para gerenciar k0s.



[Unit]
Description="k0s server"
After=network-online.target
Wants=network-online.target
 
[Service]
Type=simple
ExecStart=/usr/bin/k0s server -c /etc/k0s/k0s.yaml --enable-worker
Restart=always
      
      





O comando principal está listado aqui em ExecStart ; ele inicia o servidor k0s com a configuração que salvamos em nosso arquivo na etapa anterior. Também especificamos o parâmetro --enable-worker para que este primeiro nó mestre também funcione como um trabalhador.



Em seguida, copiamos esse arquivo para /lib/systemd/system/k0s.service , reiniciamos o systemd e iniciamos o serviço recém-criado.



ubuntu@node1:~$ sudo systemctl daemon-reload
ubuntu@node1:~$ sudo systemctl start k0s.service
      
      





Por curiosidade, você pode verificar os processos iniciados pelo servidor k0s:



ubuntu@node1:~$ sudo ps aux | awk ‘{print $11}’ | grep k0s
/usr/bin/k0s
/var/lib/k0s/bin/etcd
/var/lib/k0s/bin/konnectivity-server
/var/lib/k0s/bin/kube-controller-manager
/var/lib/k0s/bin/kube-scheduler
/var/lib/k0s/bin/kube-apiserver
/var/lib/k0s/bin/containerd
/var/lib/k0s/bin/kubelet
      
      





A partir da saída acima, podemos ver que todos os componentes principais estão em execução ( kube-apiserver , kube-controller-manager , kube-scheduler etc.), bem como componentes comuns aos nós mestre e de trabalho ( containerd , kubelet ). k0s é responsável por gerenciar todos esses componentes.



Agora temos um cluster de 1 nó. Na próxima etapa, veremos como acessá-lo.



Obter acesso ao cluster



Primeiro, precisamos obter o arquivo kubeconfig gerado durante a criação do cluster; ele foi criado em node1 em /var/lib/k0s/pki/admin.conf . Este arquivo deve ser usado para configurar o kubectl na máquina local.



Primeiro, obtemos o kubeconfig do cluster de node1 :



# Get kubeconfig file
$ multipass exec node1 cat /var/lib/k0s/pki/admin.conf > k0s.cfg
      
      





Em seguida, substituímos o endereço IP interno pelo endereço IP externo node1 :



# Replace IP address
$ NODE1_IP=$(multipass info node1 | grep IP | awk '{print $2}')
sed -i '' "s/localhost/$NODE1_IP/" k0s.cfg
      
      





Em seguida, configuramos nosso cliente kubectl local para se comunicar com o servidor da API k0s:



export KUBECONFIG=$PWD/k0s.cfg
      
      





Certamente, um dos primeiros comandos que executamos quando entramos em um novo cluster é o que exibe uma lista de todos os nós disponíveis - vamos tentar:



$ kubectl get no
NAME    STATUS   ROLES    AGE   VERSION
node1   Ready    <none>   78s   v1.19.4
      
      





Não há nada surpreendente aqui. Afinal, node1 não é apenas o principal, mas também o nó funcional de nosso primeiro cluster, graças ao sinalizador --enable-worker , que especificamos no comando start. Sem este sinalizador, node1 apenas estaria funcionando e não apareceria na lista de nós aqui.



Adicionar nós de trabalho



Para adicionar node2 e node3 ao cluster , primeiro precisamos criar um token de conexão de node1 (esta é uma etapa bastante comum, pois é usada em clusters Docker Swarm e Kubernetes criados com kubeadm).



$ TOKEN=$(k0s token create --role=worker)
      
      





O comando acima gera um token longo (muito longo). Usando-o, podemos unir node2 e node3 ao cluster :



ubuntu@node2:~$ k0s worker $TOKEN
ubuntu@node3:~$ k0s worker $TOKEN
      
      





Nota: Em um cluster real, usaríamos o systemd (ou algum outro supervisor) para gerenciar os processos k0s para os nós de trabalho como fizemos para o nó mestre.



Nosso cluster de três nós está instalado e funcionando, como podemos verificar exibindo a lista de nós e listando os nós novamente:



$ kubectl get no
NAME    STATUS  ROLES    AGE   VERSION
node1   Ready   <none>   30m   v1.19.4
node2   Ready   <none>   35s   v1.19.4
node3   Ready   <none>   32s   v1.19.4
      
      





Também podemos verificar os pods em execução em todos os namespaces:





Lista de pods em execução no cluster em todos os namespaces



Há algumas coisas a serem observadas aqui:



  • Como de costume, vemos os pods kube -proxy , os pods de plug-ins de rede (baseados no Calico), bem como os pods CoreDNS.
  • api-server, scheduler controller-manager , , .




K0s versão 0.8.0 contém o subcomando do usuário . Isso permite que você crie um kubeconfig para um usuário / grupo adicional. Por exemplo, o comando a seguir cria um arquivo kubeconfig denominado demo para um novo usuário , localizado dentro de um grupo imaginário denominado development .



Observação: no Kubernetes, os usuários e grupos são gerenciados por um administrador fora do cluster, o que significa que não há recurso usuário-não-grupo no K8s.



$ sudo k0s user create demo --groups development > demo.kubeconfig
      
      





Para um melhor entendimento, iremos extrair o certificado do cliente deste arquivo kubeconfig e decodificá-lo da representação base64:



$ cat demo.kubeconfig | grep client-certificate-data | awk '{print $2}' | base64 --decode > demo.crt
      
      





Em seguida, usamos o comando openssl para obter o conteúdo do certificado:



ubuntu@node1:~$ openssl x509 -in demo.crt -noout -text

Certificate:

    Data:

        Version: 3 (0x2)

        Serial Number:

            71:8b:a4:4d:be:76:70:8a:...:07:60:67:c1:2d:51:94

        Signature Algorithm: sha256WithRSAEncryption

        Issuer: CN = kubernetes-ca

        Validity

            Not Before: Dec  2 13:50:00 2020 GMT

            Not After : Dec  2 13:50:00 2021 GMT

        Subject: O = development, CN = demo

        Subject Public Key Info:

            Public Key Algorithm: rsaEncryption

                RSA Public-Key: (2048 bit)

                Modulus:

                    00:be:87:dd:15:46:91:98:eb:b8:38:34:77:a4:99:

                    da:4b:d6:ca:09:92:f3:29:28:2d:db:7a:0b:9f:91:

                    65:f3:11:bb:6c:88:b1:8f:46:6e:38:71:97:b7:b5:

                    9b:8d:32:86:1f:0b:f8:4e:57:4f:1c:5f:9f:c5:ee:

                    40:23:80:99:a1:77:30:a3:46:c1:5b:3e:1c:fa:5c:









  • A propriedade do emissor é kubernetes-ca , que é a CA para nosso cluster k0s.
  • O assunto é O = desenvolvimento, CN = demonstração ; esta parte é importante porque é onde o nome do usuário e o grupo entram. Como o certificado é assinado pela CA do cluster, o plug-in no api-server pode autenticar o usuário / grupo pelo nome comum (CN) e organização (O) no assunto do certificado.


Primeiro, instruímos o kubectl a usar o contexto definido neste novo arquivo kubeconfig :



$ export KUBECONFIG=$PWD/demo.kubeconfig
      
      





Em seguida, exibimos a lista de nós novamente e enumeramos os nós do cluster:



$ kubectl get no
Error from server (Forbidden): nodes is forbidden: User “demo” cannot list resource “nodes” in API group “” at the cluster scope
      
      





Esta mensagem de erro era esperada. Mesmo que api-server



o usuário seja identificado (o certificado enviado com a solicitação do usuário foi assinado pela CA do cluster), ele não tem permissão para realizar nenhuma ação no cluster.



Permissões adicionais podem ser facilmente adicionadas ao criá Role/ClusterRole



-las e atribuí-las a um usuário com RoleBinding/ClusterRoleBinding



, mas deixo esta tarefa como um exercício para o leitor.



Conclusão



definitivamente vale a pena considerar k0s. Essa abordagem, quando um único arquivo binário gerencia todos os processos, é muito interessante.



Este artigo fornece apenas uma breve visão geral do k0s, mas definitivamente rastrearei seu desenvolvimento e dedicarei artigos futuros a essa nova e promissora distribuição do Kubernetes. Alguns dos recursos futuros parecem ser realmente promissores, e estou ansioso para testá-los.



All Articles