Kubeadm: Kubeadm quebrado em armv6l

Criado em 23 abr. 2017  ·  21Comentários  ·  Fonte: kubernetes/kubeadm

Tentei instalar o kubeadm no meu raspberry pi zero W, mas recebi uma "instrução ilegal"
Em uma framboesa pi 3 (armv7) funciona muito bem.

Comentários muito úteis

É possível discusa uma reintegração de suporte armv6l. Encontrei muitos posts que mostram o interesse em usar o Kubernetes no Pi Zero e em outros dispositivos armv6l Pi. P Zero é bom para hospedar microsserviços em ambientes de cluster Kubernetes ou Swarm. Docker Swarm funciona bem para mim. Portanto, seria bom se alguém pudesse reciclar a discussão. O cluster Pi é propriamente uma boa infraestrutura de demonstração.

Todos 21 comentários

Estou enfrentando o mesmo problema com o kubeadm 1.6.1 em um Raspberry Pi Model B +, também armv6.

$ kubelet --help
Illegal instruction

$ uname -a
Linux pi1 4.4.50-hypriotos+ #2 PREEMPT Sun Mar 19 14:44:01 UTC 2017 armv6l GNU/Linux

Fiz o downgrade para o kubeadm 1.5.6 e funciona. 1.6.0 dá o mesmo erro que 1.6.1.

@clabu sim, fazer o downgrade para 1.5.6 funciona, mas não pode se juntar a um cluster 1.6+.

Em primeiro lugar, obrigado por usar o Kubernetes no ARM: smile :!

Este é um problema conhecido; foi discutido em https://github.com/kubernetes/kubernetes/issues/38067 e abandonamos o suporte armel (que parte do RPi 1 usa na compilação cruzada).

Basicamente armhf (GOARM = 7) não pode ser executado no Pi 1, então usamos armel com GOARM = 6 em -v1.5 para suportar RPi 1. No entanto, usamos todos armhf em v1.6, portanto, não está funcionando o Pi 1.

Desprezar armel e usar imagens armhf em vez e usar GOARM = 7 em vez de GOARM = 6
Motivação:

  • A única placa GOARM = 6 que Go suportará em go1.8 é o Raspberry Pi 1, que é muito lento para executar versões mais recentes do Kubernetes.
  • Pequenas melhorias de desempenho ao usar GOARM = 7
  • As imagens armel (http://hub.docker.com/u/armel) não são atualizadas com a mesma frequência que as imagens armhf (http://hub.docker.com/u/armhf).

Por exemplo, https://hub.docker.com/r/armel/debian/ foi atualizado 8 meses atrás, o que é muito ruim do ponto de vista de segurança, vs https://hub.docker.com/r/armhf/debian/ que foi atualizado 3 dias atrás.

Além disso, com a opção armhf, pudemos usar https://hub.docker.com/r/armhf/alpine , o que é ótimo.

Espero que ajude, mas sinto muito por não poder mais apoiar o RPi 1.

Se você quiser ajudar a documentar / espalhar a palavra, por favor, faça ou venha com sugestões

Estou tendo o mesmo problema em um Pi Zero

Linux p1 4.9.59+ #1047 Sun Oct 29 11:47:10 GMT 2017 armv6l GNU/Linux

É possível discusa uma reintegração de suporte armv6l. Encontrei muitos posts que mostram o interesse em usar o Kubernetes no Pi Zero e em outros dispositivos armv6l Pi. P Zero é bom para hospedar microsserviços em ambientes de cluster Kubernetes ou Swarm. Docker Swarm funciona bem para mim. Portanto, seria bom se alguém pudesse reciclar a discussão. O cluster Pi é propriamente uma boa infraestrutura de demonstração.

Olhando para a compilação docker.io atual para o pi zero,
Versão Go: go1.9.3
e versão docker: 18.02.0-ce

Parece estar usando uma versão recente do go.

Eu concordo que não há memória RAM suficiente para usar o k8s nele em um modo autônomo, mas sendo um escravo em um mestre maior, ele deve ter recursos suficientes para fazer algumas coisas úteis ainda.

Alguém sabe se é possível apenas construir a partir da fonte para usar meus pi zeros como nós k8s?

Por exemplo, https://hub.docker.com/r/armel/debian/ foi atualizado 8 meses atrás, o que é muito ruim do ponto de vista de segurança, vs https://hub.docker.com/r/armhf/debian/ que foi atualizado 3 dias atrás.

Isso não é verdade hoje, pois as imagens oficiais em diferentes arquiteturas são atualizadas simultaneamente. Por exemplo https://hub.docker.com/r/arm32v5/debian/ , https://hub.docker.com/r/arm32v7/debian/ e https://hub.docker.com/r/amd64/ debian / foram todos atualizados 9 dias atrás.

Além disso, com a opção armhf, pudemos usar https://hub.docker.com/r/armhf/alpine , o que é ótimo.

https://hub.docker.com/r/arm32v6/alpine/ funciona bem no Pi Zero.

Espero que você reconsidere isso. Impedir que o Pi Zero execute o k8s mais recente é tão decepcionante.

@luxas

+1. alguma confusão aconteceu porque o hub foi reorganizado e os repositórios mais antigos ainda estão por aí. Os mais novos parecem estar recebendo atualizações frequentes.

Olá @juliancheal ,

Ainda estou no meio da construção de k8s no ClusterHAT, mas consegui compilar e construir binários para Pi Zero.

Basicamente, segui o seguinte com algumas modificações:
https://povilasv.me/raspberrypi-kubelet/

Eu trabalhei no wsl:
Linux DESKTOP-6GRDDIN 4.4.0-17134-Microsoft # 48-Microsoft Sex. 27 de abril 18:06:00 PST 2018 x86_64 x86_64 x86_64 GNU / Linux

1 instale gcc-arm-linux-gnueabi em vez de gcc-arm-linux-gnueabihf

sudo apt-get install gcc-arm-linux-gnueabi <- change

2 antes de compilar para linux / arm, faça duas modificações em set_platform_envs () em hack / lib / golang.sh

* adicionar GOARMexportar GOOS = $ {platform% / }export GOARCH = $ {platform ## /}export GOARM = 5 <- adicionar* mudar CC
caso "$ {platform}" em
"linux / arm")
exportar CGO_ENABLED = 1
export CC = arm-linux-gnueabi-gcc <-change
;;

GOARM deve ser 5. Se você especificar 6, obterá um erro de vinculador durante a compilação. (Que eu não consegui resolver.)

@ shinichi-hashitani Funciona para o meu Pi Zero! Obrigado!

Também resolvi seu problema de erro do vinculador. Para Pi Zero, defina GOARM = 6 e mantenha gcc-arm-linux-gnueabihf. No entanto, para Pi 1, você deve definir GOARM = 5 e usar gcc-arm-linux-gnueabi.

@ shinichi-hashitani isso é ótimo! Vou tentar, obrigado!

@ shinichi-hashitani Você usou make all KUBE_BUILD_PLATFORMS=linux/arm para construí-lo? E se você usou kubeadm para configurar seu cluster, como fez isso? Você copiou kubelet , o script de inicialização que o povilasv mencionou, kubeadm e kubectl ? Funcionou?

@dbwest Sim, usei make all para construir binários. Os comandos exatos que usei foram:

make all WHAT=cmd/kube-proxy KUBE_VERBOSE=5 KUBE_BUILD_PLATFORMS=linux/arm
make all WHAT=cmd/kubelet KUBE_VERBOSE=5 KUBE_BUILD_PLATFORMS=linux/arm
make all WHAT=cmd/kubectl KUBE_VERBOSE=5 KUBE_BUILD_PLATFORMS=linux/arm

Eu precisava de binários para nós, então apenas esses três binários eram necessários.

Eu não usei o kubeadm. Eu estava acompanhando "Kubernetes the Hard Way", de Kelsey Hightower. Conforme descrito aqui , você só precisa colocar esses binários no local apropriado.

@ shinichi-hashitani tem alguma ideia de qual versão do kubernetes você estava construindo?

Eu não tive sorte fazendo isso para arm v6 (esperando rodar em um pi zero w).

Nas versões >= 1.12.0 eu recebo algo assim ...

vendor/github.com/google/cadvisor/accelerators/nvidia.go:30:2: build constraints exclude all Go files in /private/var/folders/hn/gt2l8vq56vx9slvwry43xmz40000gn/T/tmp.A83ZihlF/_output/local/go/src/k8s.io/kubernetes/vendor/github.com/mindprince/gonvml
!!! [0511 07:36:41] Call tree:
!!! [0511 07:36:41]  1: /private/var/folders/hn/gt2l8vq56vx9slvwry43xmz40000gn/T/tmp.A83ZihlF/hack/lib/golang.sh:601 kube::golang::build_some_binaries(...)
!!! [0511 07:36:41]  2: /private/var/folders/hn/gt2l8vq56vx9slvwry43xmz40000gn/T/tmp.A83ZihlF/hack/lib/golang.sh:736 kube::golang::build_binaries_for_platform(...)
!!! [0511 07:36:41]  3: hack/make-rules/build.sh:27 kube::golang::build_binaries(...)
!!! Error in /private/var/folders/hn/gt2l8vq56vx9slvwry43xmz40000gn/T/tmp.A83ZihlF/hack/lib/golang.sh:561
  Error in /private/var/folders/hn/gt2l8vq56vx9slvwry43xmz40000gn/T/tmp.A83ZihlF/hack/lib/golang.sh:561. 'go install "${build_args[@]}" "$@"' exited with status 1

E de >= 1.10.0 & < 1.12.0 ( 1.10.0 foi o primeiro que tentei até agora), recebo algo assim ...

F0511 07:39:30.480641   26683 openapi.go:116] Failed loading boilerplate: open /private/var/folders/hn/gt2l8vq56vx9slvwry43xmz40000gn/T/tmp.A83ZihlF/_output/local/go/src/k8s.io/gengo/boilerplate/boilerplate.go.txt: no such file or directory
!!! Error in ./hack/run-in-gopath.sh:33
  Error in ./hack/run-in-gopath.sh:33. '"${@}"' exited with status 255
Call stack:
  1: ./hack/run-in-gopath.sh:33 main(...)
Exiting with status 1
make[1]: *** [pkg/generated/openapi/zz_generated.openapi.go] Error 1
make: *** [generated_files] Error 2

EDIT: Deixa pra lá ... parece que se eu construir em uma máquina Linux, ele funciona. Eu estava tentando fazer isso do meu mac

@ammmze ,

Não tenho certeza do que está causando problemas do seu lado, mas abaixo estão os detalhes do meu lado:
Kubernetes - 1.10.2
Go - 19,4
Usei WSL (provavelmente Ubuntu 16.x) para compilar esses binários.

Novamente, segui o seguinte com algumas modificações:
https://povilasv.me/raspberrypi-kubelet/
Você pode consultar isso para confirmar as etapas a serem seguidas.

Eu preparei minha nota e as etapas exatas que segui, mas sinto muito, isso está disponível apenas em japonês:
https://qiita.com/ShinHashitani/items/ea9ffdefce8ca5786da6

Algum movimento ao adicionar suporte de braço traseiro para pi zero? Tenho alguns disponíveis e adoraria fazer um cluster de baixo custo / energia para fins de demonstração

Algum movimento ao adicionar suporte de braço traseiro para pi zero? Tenho alguns disponíveis e adoraria fazer um cluster de baixo custo / energia para fins de demonstração

oi, como você pode ver na discussão acima, o Kubernetes principal retirou o suporte para armv6l.
portanto, não acho que haja uma chance desse suporte ser adicionado novamente.

se quiser usar k8s / kubeadm no armv6l, você deve recompilar tudo (incluindo imagens CNI).

Estou apenas entrando na conversa para dizer que compilei com sucesso o K8s 1.18.3 a partir da fonte, compilando-o na imagem docker golang: 1.13-alpine, que é uma imagem com vários arcos e inclui um armv6. (Eu tenho o Docker configurado para usar QEMU para emulação e posso executar contêineres para outras arquiteturas.)

Simplesmente clonando o repositório git e seguindo o processo de criação de 4 etapas na página leia-me (ou seja, apenas faça tudo WHAT = cmd / componente), todos os componentes k8s, exceto kubelet, foram compilados estaticamente e executados como executáveis ​​autônomos no meu pi zero, sem dependências. (E se golang-alpine parar de funcionar, posso simplesmente inicializar o ARM do Arch Linux do zero, que deve funcionar bem para a compilação.)

O único problema é que a compilação do kubelet ainda se vincula dinamicamente à biblioteca glibc do sistema, e eu ainda não descobri como consertar isso. Não sou um programador go, e nenhum dos sinalizadores de compilação que adicionei para go ou para gcc pareceu fazer diferença. (Kubelet tem algum código C, eu acho, porque ele precisa do gcc para compilar.) Na pior das hipóteses, posso inicializar uma imagem docker para cada tipo de sistema operacional que executo, então os links dinâmicos glibc funcionarão, mas eu não quero faça isso.

O Debian ainda suporta oficialmente armel e tem pacotes com uma versão kubelet vinculada estaticamente, então minha solução hacky atualmente é apenas usar seu binário estático de dentro do pacote armel deb.

Por último, você deve fazer seu próprio repositório com imagens que tenham esses binários (assim como as outras versões) e configurar o kubeadm para extraí-los. E ainda mais divertido, embora o Docker execute no arm6, ele extrai incorretamente imagens arm7 (um bug conhecido há mais de 3 anos), então você precisa alterar a imagem arm7 para apenas executar a versão armel ou fazer arm6 e arm7 no mesma imagem e apenas ter como ponto de entrada um script de shell que determina em tempo de execução se deve iniciar o programa arm6 ou arm7. Os nós não mestres precisam apenas executar kubelet e kube-proxy, portanto, essas são provavelmente as únicas imagens para as quais você precisa fazer isso. (Outro hack que li sobre as pessoas usando é puxar a imagem correta e, em seguida, remarcá-la localmente para ser a imagem que o kubeadm deseja puxar, então ele usará apenas a versão local.)

Na verdade, estou apenas usando o ansible para configurar o k8s "da maneira mais difícil", mas pretendo ainda fazer imagens compatíveis do Docker que possam ser substituições imediatas para que o kubeadm funcione com elas. Se e quando eu conseguir fazer o kubelet compilar estaticamente de maneira correta, automatizarei o processo em um Dockerfile e colarei as imagens no Docker Hub. Essas imagens terão tantas arquiteturas quantas eu puder usar, então, idealmente, poderemos usar o kubeadm em um cluster com várias arquiteturas. Por exemplo, amd64, arm64, arm6 e arm7. Eu estimo que a produção total do Docker e K8s no Pi Zero (como nós de trabalho) ainda deixa pelo menos 50 MB a 100 MB de RAM para rodar pequenas imagens. E se eu remover o kernel, provavelmente poderei liberar outros 30 ou 40 megas. Mas isso está muito longe no futuro. Se eu conseguir obter uma única página estática servida por um contêiner nginx gerenciado por K8s em meu Pi Zero, estou chamando isso de vitória por enquanto.


Edição de 7 de agosto: consegui fazer tudo funcionar e, atualmente, tenho um cluster K8s composto de arm6, arm7, arm8 e amd64. Eu estarei escrevendo sobre meu processo em breve aqui, mas por enquanto, a lição importante é fazer uma instalação do kubeadm em um dispositivo arm6 como um nó de trabalho, você precisa de binários para kubeadm e kubelet, e apenas dois contêineres, o contêiner de pausa e o contêiner kube-proxy. Você pode construir os binários nativamente com buildx se tiver QEMU e apenas modificar meu Dockerfile . (No momento, esse Dockerfile não funciona completamente - a compilação kube-controller-manager continua congelando. Mas você pode compilar kubelet, kubeadm, pause, kube-proxy e os plug-ins CNI.)

Como alternativa, você pode obter os binários estáticos do diretório / usr / bin nos pacotes Arch que criei para kubelet . Eu instalei o Arch Linux ARM no meu Pi Zero, e então os plug-ins CNI foram instalados no meu sistema por um pacote, mas você pode construí-los com meu Dockerfile (ou extraí-los do pacote ARM do Arch Linux) e colocar os binários CNI em o diretório "/ opt / cni / bin /" em seu sistema. Se você tiver esses binários CNI nessa pasta e tiver o kubelet instalado e pronto como um serviço , basta executar o kubeadm no dispositivo e deve funcionar bem. O único requisito é que você precisa do kube-proxy correto e pause os contêineres já disponíveis para seu mecanismo de contêiner.

Em meus Pi Zeroes, instalei o Stock Docker e usei os binários que criei do arquivo Docker, combinados com a análise dos contêineres K8s oficiais para construir um contêiner arm6 compatível para kube-proxy e pausa . Especificar a versão do Kubernetes como v1.18.6 no kubeadm exigia marcar novamente esses contêineres como "k8s.gcr.io/kube-proxy:v1.18.6" e "k8s.gcr.io/pause:3.2" respectivamente, mas se esses os contêineres já estão presentes e marcados corretamente em seu sistema, então o kubeadm terá sucesso sem reclamar.

O único outro problema é uma rede de sobreposição em funcionamento. Eu não queria passar por mais um inferno de compilação, então usei Flannel, cuja variante "arm" funciona em arm6 e arm7. Você pode instalá-lo com seu arquivo yaml padrão . No entanto, você deve adicionar um env var para todas as seções chamadas FLANNEL_MTU e defini-lo como 1430 ou inferior. O padrão, 1500, causa alguns problemas com o servidor de métricas. Além disso, eu combinei todas as imagens de Flannel em uma imagem de múltiplos arcos, se você quiser usar isso. Isso permitirá que você faça o que eu fiz e reduza o arquivo de instalação padrão do yaml a apenas uma seção.

Com esta instalação "completa" do K8s usando kubeadm e Docker CE, meu Pi Zeroes fica ocioso em cerca de 55% do uso da CPU e tem cerca de 160 MB de memória livre. Se assumirmos que quero deixar pelo menos 25% para a capacidade de burst, isso ainda deixa cerca de 20%, o que equivale a 200 millis. (Pi Zero tem uma CPU de 1 GHz de núcleo único.) Para dar algum espaço de manobra extra, arredondei para baixo e defini minha solicitação e limite de contêiner para 120 m e RAM para 100 MB. Até agora, tudo está funcionando bem. O único problema é o calor, já que meus zeros estão todos amontoados em uma linda caixa empilhável que não tem muito espaço de ar.

(E, claro, o nó gerenciador não é um Pi Zero, é um Pi 4.)


Editar de 1 de dezembro de 2020: Esta será minha última atualização. Na verdade, não há muito a acrescentar. O Kubeadm tem um arquivo de configuração yaml, assim como todos os outros componentes do k8s, nenhum dos quais está tão bem documentado ... mas você pode mexer nele se tentar.

Uma das opções do kubeadm é usar um registro personalizado para suas imagens, para que você possa criar uma imagem de vários arquivos e enviá-la para um registro privado e, em seguida, usá-lo para sua configuração, em vez de simplesmente remarcar uma imagem no docker. Isso é o que eu fiz para me livrar do docker e apenas usar o straight containerd.

Eu ainda não descobri como obter os componentes do plano de controle compilados para arm6. Tanto o QEMU quanto os dispositivos nativos não permitem mais de 1 gb de RAM, o que não é suficiente para que Go compile a maior parte do plano de controle. Estou ciente de que o Go teoricamente pode compilar para outras arquiteturas, então devo ser capaz de compilar arm6 em minha máquina amd64, usando toda a sua memória RAM. Mas, pela minha vida, não consigo fazer isso funcionar, então fico compilando coisas nativamente no QEMU ou nos próprios dispositivos. O que significa que não há componentes do plano de controle arm6.

Mas esse é o único soluço. Kubelet e kubeadm compilam, e os contêineres pause container e kube-proxy também podem ser construídos com buildx. Portanto, ainda é fácil fazer com que os componentes do nó de trabalho funcionem para arm6. Se você estiver criando um cluster com pi zeros, definitivamente leia o arquivo de configuração do kubelet para ajustá-lo para o uso de recursos. (Ou, você sabe, use k3s ou outra distro leve em vez de k8s de estoque completo.)

Tenho binários para modelos antigos de framboesas publicados aqui https://github.com/aojea/kubernetes-raspi-binaries
Eles são criados com um trabalho de ações do github, então sinta-se à vontade para reutilizá-lo

Esta página foi útil?
0 / 5 - 0 avaliações