<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Guilherme Lira</title>
    <description>The latest articles on Forem by Guilherme Lira (@lirinha).</description>
    <link>https://forem.com/lirinha</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F325213%2F0c57b2db-2f54-4b3d-8016-ea188057cf6d.jpeg</url>
      <title>Forem: Guilherme Lira</title>
      <link>https://forem.com/lirinha</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/lirinha"/>
    <language>en</language>
    <item>
      <title>ARM vs x86 em Docker</title>
      <dc:creator>Guilherme Lira</dc:creator>
      <pubDate>Fri, 05 Apr 2024 21:50:01 +0000</pubDate>
      <link>https://forem.com/lirinha/arm-vs-x86-em-docker-3eng</link>
      <guid>https://forem.com/lirinha/arm-vs-x86-em-docker-3eng</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;Hoje bem sabemos que processadores de arquitetura ARM, vem se tornado cada vez mais presentes em servidores, notebooks e em gabinetes e até como opções de flavors para instâncias computacionais em clouds públicas. Sabendo disso meus caros amigos e amigas, vi que podemos ter alguns pequenos desafíos ao trabalhar com o nosso querido Docker. Então escrevi esse artigo pra entendermos um pouco sobre a diferença dessas arquiteturas e o que elas impactam no nosso Container Engine tão amado que é o Docker.&lt;/p&gt;

&lt;h2&gt;
  
  
  Diferença entre ARM e x86
&lt;/h2&gt;

&lt;p&gt;A principal diferença entre processadores ARM e x86 é que os precessadores do tipo ARM são RISC e os x86 são CISC. Como precisamos ter uma noção sobre essas arquiteturas para darmos seguimeto com o artigo, irei dar uma pequena expicação, nada muito profundo, sobre essas arquiteturas.&lt;/p&gt;

&lt;p&gt;RISC ( Reduced Instruction Set Computer ) o que significa que suas instruções são mais reduzidas e que tendem ser mais simples e executadas em ciclos de relógio mais curtos. Uma instrução no padrão RISC é quebrada em instruções menores para que caibam em um ciclo de relógio. Todas as instruções tem um tamanho específico. Diferente do CISC ( Complex Instruction Set Computer ). No modelo CISC temos instruções mais complexas, sendo elas sem tamanho determinado podendo assumir dimensões variáveis de acordo com a quantidade de operações que deverão ser executadas.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe2mx050hafivx3vfvdpy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe2mx050hafivx3vfvdpy.png" alt=" " width="800" height="92"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 Um ciclo de relógio é a frequência medida em Hertz que determina quantos impulsos serão realizados por segundo naquele computador.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Como buildar uma imagem para uma arquitetura específica
&lt;/h2&gt;

&lt;p&gt;Tendo em mente que a grande maioria dos notebooks, computadores de mesa e datacenters usam processadores x86, vai ser normal gerar nossas imagens nessas máquinas e isso pode acarretar em alguns problemas.&lt;br&gt;&lt;br&gt;
Também partindo do pressuposto que sabemos que um container nada mais é do que um isolamento dentro do SO ( Sistema Operacional ), e por isso ao fazer a geração de uma imagem, não adequada, para uma máquina com a CPU de arquitetura diferente de onde a imagem será executadada, vai acerretar nos problemas que veremos a seguir.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 Geralmente imagens muito usadas como RabbitMQ, Ubuntu ou até NodeJs são multi-plataforma, elas já tem imagens expecificas para cada arquitetura de CPU, então não será necessário expecificar, veremos isso mais ao decorrer do artigo.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  Possíveis erros que vão acontecer
&lt;/h3&gt;

&lt;p&gt;Bom como vimos acima para cada tipo de arquitetura as instruções são organizadas de uma maneira específica, então é claro que se executarmos um "build", dentro de uma máquina com processador x86, e tentar executar essa imagem dentro de uma máquina de processador ARM, vamos ter o seguinte erro.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker-compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;... The requested image&lt;span class="sb"&gt;`&lt;/span&gt;s platform &lt;span class="o"&gt;(&lt;/span&gt;linux/amd64&lt;span class="o"&gt;)&lt;/span&gt; does not match the detected host platform &lt;span class="o"&gt;(&lt;/span&gt;linux/arm64/v8&lt;span class="o"&gt;)&lt;/span&gt; and no specific platform was requested
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Um ponto &lt;strong&gt;muito importante&lt;/strong&gt;, mais pra frente do artigo veremos como fazer o build correto para cada arquitetura, mas devemos ter uma atenção maior para as dependências do seu código, pois, mesmo que a imagem seja criada da maneira correta, talvez as suas dependências não foram buildadas para arquitetura ARM. Para resolver esse problema em NodeJs, podemos fazer da seguinte maneira, e com um simples comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--cpu&lt;/span&gt; arm64 &lt;span class="nt"&gt;--os&lt;/span&gt; XPTO 
&lt;span class="c"&gt;# Esse é so um exemplo você pode usar o SO que quiser&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;💡 Quando der um pull na sua imagem será possível ver para qual tipo de arquitetura sua imagem foi gerada, com o seguinte comando:&lt;/p&gt;


&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker image inspect rabbitmq:latest &lt;span class="nt"&gt;--format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'{{.Architecture}}'&lt;/span&gt;
arm64 &lt;span class="c"&gt;# Retorno do comando&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Dessa maneira, antes mesmo de usar a imagem, podemos saber se será compativel com a arquitetura da CPU, evitando erros futuros.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Como saber a arquitetura da sua CPU
&lt;/h3&gt;

&lt;p&gt;Para saber qual a arquitetura da sua CPU é so digitar o camando, se você estiver em uma máquina com linux, o seguinte comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Mac M1&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;uname&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt;
arm64 

&lt;span class="c"&gt;# Maquina com processador Intel&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;uname&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt;
x86_64
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Estratégias de build
&lt;/h3&gt;

&lt;p&gt;Como vimos durante todo o artigo, imagens Docker podem suportar múltiplas plataformas. Isso significa que uma simples imagem do Docker pode conter variantes para diferentes arquiteturas. Mais acima comentei que quando imagens tem suporte a multi-pltaforma, o Docker automaticamente seleciona a imagem que corresponde a arquitetura e SO da máquina onde a imagem será baixada. Sabendo disso, vamos ver duas possibilidades de criar uma imagem multi-plataforma.&lt;/p&gt;

&lt;p&gt;Antes de começarmos preciso falar um pouco sobre nosso amigo &lt;code&gt;docker buildx&lt;/code&gt;, &lt;a href="https://github.com/moby/buildkit" rel="noopener noreferrer"&gt;Buildx&lt;/a&gt; é um componente do Docker que tem ótimas funcionalidades para geração de imagem, e uma delas é a multi-plataforma. Todas as imagens geradas por ele são executadas com o &lt;a href="https://github.com/moby/buildkit" rel="noopener noreferrer"&gt;Moby Buildkit&lt;/a&gt;.&lt;br&gt;&lt;br&gt;
Para fazer a criação de imagens multi-plataforma, antes devemos criar uma &lt;code&gt;builder instance&lt;/code&gt;, para criar segue o comando abaixo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker buildx create &lt;span class="nt"&gt;--use&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ao criar uma imagem multiplataforma a partir de um Dockerfile, efetivamente seu Dockerfile é construído uma vez para cada plataforma. No final da compilação, todas essas imagens são mescladas em uma única imagem multiplataforma.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; alpine&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Hello"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /hello
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Por exemplo, nesse caso acima onde temos um simples Dockerfile, ao executar o comando &lt;code&gt;docker buildx build --platform=linux/amd64,linux/arm64 .&lt;/code&gt;, o BuildKit vai subir duas imagens Alpine de diferentes versões, uma para cada tipo de arquitetura passada no comando, e vai executar todas as camandas para cada tipo de arquitetura. Por isso, é muito importante ter uma imagem base que tenha suporte para várias arquiteturas.&lt;/p&gt;

&lt;h4&gt;
  
  
  Emulação
&lt;/h4&gt;

&lt;p&gt;Para executar esse tipo de build é bem simples, no exemplo acima já ocorre com a estratégia de Emulação, onde seram literalmente emulados os comandos em containers preparados para a arquitetura desejada. Para esse tipo de estratégia não é preciso alteração no Dockerfile. É maneira mais simples de obter uma imagem com suporte a multi-plataforma, mas com essa facilidade vem alguns problemas. Os binários executados dessa maneira precisam converter constantemente suas instruções entre arquiteturas e, portanto, não são executados com velocidade nativa. Ocasionalmente, você também pode encontrar um caso que desencadeia um bug na camada de emulação. &lt;br&gt;
Mas o problema da estratégia de emulação não vai ocorrer na Cross Compilation, que veremos a seguir.&lt;/p&gt;
&lt;h4&gt;
  
  
  Corss Compilation
&lt;/h4&gt;

&lt;p&gt;Nessa estratégia vamos ter um pouco mais de trabalho, vamos precisar fazer algumas alterações dentro de um Dockerfile, vou usar um caso bem simples, que será a do Alpine. Para conseguirmos uma imagem do alpine que seja mutliplataforma podemos usar algumas variáveis globais pré definidas como o BUILDPLATAFORM, ela sempre corresponderá à plataforma ou ao seu sistema atual e o construtor vai preencher o valor correto para gente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; --platform=$BUILDPLATFORM alpine&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Segue a lista com todas as veriaveis:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;BUILDPLATFORM — Corresponde a plataforma da máquina atual. (linux/amd64)&lt;/li&gt;
&lt;li&gt;BUILDOS — Componente de SO da BUILDPLATFORM. (linux)&lt;/li&gt;
&lt;li&gt;BUILDARCH — Tipo de arquitetura da máquina atual. (amd64, arm64, riscv64)&lt;/li&gt;
&lt;li&gt;BUILDVARIANT — Usado para definir a variante ARM. (v7)&lt;/li&gt;
&lt;li&gt;TARGETPLATFORM — O valor definido com o flag --platform na compilação&lt;/li&gt;
&lt;li&gt;TARGETOS - SO definido na flag --platform. (linux)&lt;/li&gt;
&lt;li&gt;TARGETARCH - Tipo da arquitetura definida na --platform. (arm64)&lt;/li&gt;
&lt;li&gt;TARGETVARIANT&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Vamos ver um exemplo bem simples de uma imagem com a estratégia de cross compilation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;--platform=$BUILDPLATFORM alpine&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;build&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;apk add mycompiler
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; src src&lt;/span&gt;
&lt;span class="k"&gt;ARG&lt;/span&gt;&lt;span class="s"&gt; TARGETPLATFORM&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;compile &lt;span class="nt"&gt;-target&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$TARGETPLATFORM&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /out/mybinary /src

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; alpine&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;apk add helperapp
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=build /out/mybinary /bin&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No Dockerfile acima conseguimos ver como vai funcionar nossa imagem. É so uma imagem de exemplo, mas é possível entender que a imagem terá que ser desenvolvida para se adaptar e gerar seus binários de acordo com a arquitetura escolhida. Para cada linguagem de programação, por exemplo, existe uma maneira de gerar os pacotes ou binários, para a lingauem Go funciona da seguinte maneira, segue o exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;--platform=$BUILDPLATFORM golang:1.17-alpine&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;build&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /src&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;
&lt;span class="k"&gt;ARG&lt;/span&gt;&lt;span class="s"&gt; TARGETOS TARGETARCH&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nv"&gt;GOOS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$TARGETOS&lt;/span&gt; &lt;span class="nv"&gt;GOARCH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$TARGETARCH&lt;/span&gt; go build &lt;span class="nt"&gt;-o&lt;/span&gt; /out/app .

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; alpine&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=build /out/app /bin&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E é isso pessoal, espero que esse artigo tenha ajudado vocês de alguma maneira.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>arm</category>
      <category>devops</category>
      <category>sre</category>
    </item>
    <item>
      <title>Que danado é um pod?</title>
      <dc:creator>Guilherme Lira</dc:creator>
      <pubDate>Sun, 07 Nov 2021 03:50:00 +0000</pubDate>
      <link>https://forem.com/lirinha/que-danado-e-um-pod-part-1-8dc</link>
      <guid>https://forem.com/lirinha/que-danado-e-um-pod-part-1-8dc</guid>
      <description>&lt;p&gt;Neste post eu vou tentar destrinchar cada ponto dentro do contexto de um pod, sendo assim vamos ver um pouco de redes, politicas de rede, persistência de dados para pods, exemplos práticos e mais umas coisinhas aí. Esse primeiro post será a parte um de alguns posts sobre Kubernetes que vou soltar por aqui. Esse é a parte 1 sobre pods que eu vou postar.  &lt;/p&gt;

&lt;h3&gt;
  
  
  $ O que é um pod?
&lt;/h3&gt;

&lt;p&gt;Um &lt;a href="https://kubernetes.io/docs/concepts/workloads/pods/" rel="noopener noreferrer"&gt;pod&lt;/a&gt; nada mais é do que o menor artefato possível de implementação dentro de um cluster Kubernetes. É nele que podemos subir um ou mais containers, compartilhando storage e recursos de rede.&lt;/p&gt;

&lt;p&gt;Cada container em um pod executa no próprio &lt;a href="https://en.wikipedia.org/wiki/Cgroups" rel="noopener noreferrer"&gt;cgroup&lt;/a&gt;, mas eles compartilham alguns &lt;a href="https://en.wikipedia.org/wiki/Linux_namespaces" rel="noopener noreferrer"&gt;namespaces&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Uma característica interessante dos pods, é que eles foram criados para serem efêmeros, sendo assim quando um pod cai ele automaticamente é iniciado novamente.&lt;/p&gt;

&lt;p&gt;Podemos subir um pod de duas maneiras, usando um manifesto (.yaml) ou por linha de comando, para faze-lo é preciso ter um ambiente com um cluster k8s rodando com &lt;a href="https://kind.sigs.k8s.io/docs/user/quick-start/" rel="noopener noreferrer"&gt;kind&lt;/a&gt;, &lt;a href="https://minikube.sigs.k8s.io/docs/start/" rel="noopener noreferrer"&gt;minikube&lt;/a&gt; ou de outro modo. Tendo nosso cluster rodando e com o kubectl, kubelet, e o kubeadm instalados, podemos subir um pod somente pela linha de comando, basta executarmos o comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;k&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;kubectl
&lt;span class="c"&gt;# Como exemplo vou subir um pod com um container NGINX&lt;/span&gt;
k run nginx &lt;span class="nt"&gt;--image&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para saber se seu container subiu é so rodar o comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;k get pods

&lt;span class="c"&gt;# Ele vai retornar algo como&lt;/span&gt;
NAME        READY      STATUS       RESTARTS        AGE
nginx       1/1        Running      0               8m54s

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Caso você queira saber mais sobre seu pod, como quais containers estão rodando nele, dados de rede, condições do seu pod, volumes e mais alguns dados, é so executar o comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;k describe pod &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;nome&lt;/span&gt;&lt;span class="p"&gt; do pod&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Conseguimos subir um pod somente com o nosso &lt;strong&gt;kubectl run&lt;/strong&gt;, agora vamos subir o mesmo pod com uma manifesto. O manifesto que nada mais é do que um arquivo yaml ou json, mas o que é geralmente mais usado é o yaml. Com o nosso manifesto e tendo as configurações necessárias conseguimos deployar qualquer objeto que a API do Kubernetes consiga criar, inclusive o pod.&lt;/p&gt;

&lt;p&gt;No manifesto de um pod estão inclusos alguns campos e atributos essenciais para o deploy do nosso pod, como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Uma seção de &lt;strong&gt;metadata&lt;/strong&gt; que descreve o Pod e seus rótulos. Rótulos esse&lt;/li&gt;
&lt;li&gt;Outra seção de &lt;strong&gt;spec&lt;/strong&gt; para descrever os volumes
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="c1"&gt;# kind será o valor do tipo de objeto que vamos criar &lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Pod&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myapp&lt;/span&gt;
  &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# O label é muito importante pois é por ele que outros objetos podem achar nosso pod&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myapp&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pod-learn&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;
    &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="c1"&gt;# limits delimita o limite de CPI e memory do nosso container&lt;/span&gt;
      &lt;span class="na"&gt;limits&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;128Mi"&lt;/span&gt;
        &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;500m"&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;containerPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E para subir um pod a partir de um manifesto é so executar o comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;k apply &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;nome&lt;/span&gt;&lt;span class="p"&gt; do arquivo&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  $ Como usa-lo ?
&lt;/h3&gt;

&lt;p&gt;Ao usar manifestos o Pod pode ser usado de maneiras diferentes, por objetos diferentes, como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deployment&lt;/li&gt;
&lt;li&gt;Job&lt;/li&gt;
&lt;li&gt;DeamonSet&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vamos entender como funciona um pouquinho cada um desses carinhas&lt;/p&gt;

&lt;p&gt;~&amp;gt; Deployment&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;O objeto Deployment é uma das maneira de usar um Pod. Ao criar um deployment, o k8s cria juntamente com o pod, um &lt;code&gt;ReplicaSet&lt;/code&gt;. O Deployment existe para gerenciar o lançamento de versões. Como esse post não é focado em Deployments, por isso não vou me estender sobre ele. &lt;/li&gt;
&lt;li&gt;ReplicaSets

&lt;ul&gt;
&lt;li&gt;Os ReplicaSets, são os responsáveis por controlar e manter a quantidade de réplicas que estabelecidas para o nosso deployment. E esses pods são identificados pela metadata pertencente ao deployment.
&lt;/li&gt;
&lt;li&gt;A quantidade de réplicas são ditas na hora da criação do deployment.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Aqui está um exemplo de como criar um Deployment&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;  &lt;span class="c1"&gt;# Exemplo coletado no https://kubernetes.io/docs/concepts/workloads/controllers/deployment/&lt;/span&gt;
  &lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
  &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
  &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx-deployment&lt;/span&gt;
    &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;
  &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Replicas é a quantidade de réplicas que o ReplicaSet vai levantar e manter&lt;/span&gt;
    &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
    &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;
    &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;
      &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;
          &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx:1.14.2&lt;/span&gt;
          &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;containerPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;80&lt;/span&gt;    
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;~&amp;gt; DeamonSet  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Quando falamos de DeamonSets, vem na cabeço os processos que rodam no seu linux do tipo daemon, são processos que rodam em background, e assim que seu sistema é iniciado eles são iniciados também. Como um serviço do mysql, docker e por ai vai.
&lt;/li&gt;
&lt;li&gt;E não é muito diferente aqui no nosso Kubernetes, ao subir o DeamonSet, um pod vai rodar em "background" em um, em mais de um ou em todos os nodes do seu cluster. Com isso podemos usa-lo para subir um pod com prometheus por exemplo, para fazer a parte de monitoramento do cluster.&lt;/li&gt;
&lt;li&gt;E para entender mais de como funciona esse tal do DeamonSet é só olhar a doc oficial do Kubernetes sobre &lt;a href="https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/" rel="noopener noreferrer"&gt;DEAMONSETS&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;~&amp;gt; Job  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;O Pod também é usado quando subimos um objeto do tipo Job. O Job é responsável por criar e gerenciar Pods definidos em um template na especificação do job. Em geral, esses Pods executam até serem concluídos com sucesso, caso aconteça uma falha o controlador do job vai levantar outro pod, com base no template do pod presente.
&lt;/li&gt;
&lt;li&gt;Para entender mais sobre, como funcionam os jobs, basta olhar na doc oficial do Kubernetes sobre &lt;a href="https://kubernetes.io/docs/concepts/workloads/controllers/job/" rel="noopener noreferrer"&gt;JOBS&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Agora que conseguimos subir um pod, vamos entender de que maneiras podemos usar esse pod&lt;/p&gt;

&lt;h3&gt;
  
  
  $ Como funciona a comunicação entre pods?
&lt;/h3&gt;

&lt;p&gt;Os pods podem se comunicar facilmente tanto estando no mesmo node, quando em nodes diferentes, isso por causa de que cada pod recebe um ip ao ser criado. Porém não é muito inteligente usar o ip do pod criado, para fazer a conexão entre dois pods, pois os pods foram feitos para serem efêmeros, sendo assim, toda vez que um pod for derrubado e levantado em seguida, ele vai receber um novo ip, assim perdendo a conexão entre os pods.  &lt;/p&gt;

&lt;p&gt;Para mantermos esta conexão podemos apontar um service para o pod ou para um deployment, assim não vamos perder a conexão entre os pods. A comunicação dentro do cluster por hostname, só é possível através do servidor DNS que roda como um serviço Kubernetes. Podemos fazer a comunicação da seguinte maneira:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Namespace default ~&amp;gt; &lt;code&gt;{serviceName}.svc.cluster.local&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Em outro namespace ~&amp;gt; &lt;code&gt;{serviceName}.{namespaceName}.svc.cluster.local&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dessa maneira é possível fazer a comunicação entre pods, tanto no mesmo node, quanto em node diferentes. Para que tudo isso funcione, é preciso que no seu cluster tenha instalado ou o &lt;code&gt;kube-dns&lt;/code&gt;, que é o serviço de DNS nativo do k8s, ou configurar o core dns como o serviço de dns principal do seu cluster, vou deixar alguns links no final do artigo para quem quiser fazer a configuração.  &lt;/p&gt;

&lt;h3&gt;
  
  
  $ Conclusão
&lt;/h3&gt;

&lt;p&gt;Neste post conseguimos entender um pouco sobre o Pod, entendemos um pouco de o que é um pod, maneiras diferentes de como outros objetos do kubernetes usam ele e também uma breve passagem sobre a comunicação entre pods.&lt;br&gt;&lt;br&gt;
Na parte dois desse post, vou falar mais e adentrar mais sobre a network entre pods, e persistência de dados para um pod.&lt;br&gt;&lt;br&gt;
Agradeço quem leu todo o post, ressaltando que esse post é uma via de estudo que eu encontrei, e decidi, compartilhar com qualquer um que queira entender um pouco de Kubernetes assim como eu.  &lt;/p&gt;

&lt;p&gt;Até o próximo post!!!&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
