<?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>DEV Community: Fernando Rosa</title>
    <description>The latest articles on DEV Community by Fernando Rosa (@fernandoerosa).</description>
    <link>https://dev.to/fernandoerosa</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%2F1157921%2F7a460cdc-596a-4ef2-b9cc-134ae05183bc.jpeg</url>
      <title>DEV Community: Fernando Rosa</title>
      <link>https://dev.to/fernandoerosa</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/fernandoerosa"/>
    <language>en</language>
    <item>
      <title>CI/CD, oque é esse nome bonito no devops?</title>
      <dc:creator>Fernando Rosa</dc:creator>
      <pubDate>Mon, 18 Dec 2023 17:26:40 +0000</pubDate>
      <link>https://dev.to/fernandoerosa/cicd-oque-e-esse-nome-bonito-no-devops-22k6</link>
      <guid>https://dev.to/fernandoerosa/cicd-oque-e-esse-nome-bonito-no-devops-22k6</guid>
      <description>&lt;h3&gt;
  
  
  Onde o CI/CD se encontra naquele 8 de lado do DevOps?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--quHrihL8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mwfsfyi2x4qdm9vhx4fg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--quHrihL8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mwfsfyi2x4qdm9vhx4fg.png" alt="Descrição da imagem" width="800" height="412"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Como neste mundo tecnológico é legal falar as coisas em inglês, aqui já vai uma dica: a pronúncia é "siai-sidii" 😉&lt;/p&gt;

&lt;p&gt;CI/CD é um script que será executado no servidor Git da nossa aplicação, a partir de algum gatilho configurado. Normalmente, esses scripts rodam a cada commit que é enviado para o servidor Git ou em ações de merge, no caso do script de deploy.&lt;/p&gt;

&lt;p&gt;O nome CI vem de Continuous Integration, que é integração contínua, responsável por executar testes automatizados, scanners de qualidade de código, entre outros. Já CD, Continuous Delivery, significa entrega contínua, onde é configurado o deploy da nossa aplicação, seja por meio do Kubernetes ou algum outro software de deploy, como o Laravel Forge, por exemplo.&lt;/p&gt;

&lt;p&gt;Com isso, analisando aquele 8 de lado, podemos entender que o CI/CD vai cuidar da etapa de &lt;strong&gt;build &amp;gt; test &amp;gt; release &amp;gt; deploy&lt;/strong&gt; do nosso software.&lt;/p&gt;

&lt;h3&gt;
  
  
  Como o CI/CD roda?
&lt;/h3&gt;

&lt;p&gt;Isso irá depender de qual sistema Git você irá usar. No meu caso, eu utilizo o GitLab, então o responsável pela execução dos meus CI/CDs são os runners do GitLab.&lt;/p&gt;

&lt;p&gt;O Runner é um serviço que será vinculado com o repositório Git no GitLab, receberá as instruções e será responsável por realizar o processamento do script CI/CD. Normalmente, eles ficam em alguma VM ou podem ser configurados na máquina localmente. Nesse caso, aconselho subir um container com a imagem do GitLab Runner para evitar o acoplamento das suas dependências locais.&lt;/p&gt;

&lt;p&gt;Basicamente, o que o Runner fará é clonar o projeto para dentro e executar os scripts dentro do root do projeto.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sintaxe do CI/CD
&lt;/h3&gt;

&lt;p&gt;Agora, indo mais para a programação dele, o script do CI/CD ficará no root do projeto dentro do arquivo .gitlab-ci.yml. Só com essa nomenclatura, o GitLab já começará a executá-lo a cada commit realizado.&lt;/p&gt;

&lt;p&gt;A ideia do CI/CD é rodar cada etapa de forma isolada e sem acoplar dependências. Para isso, usamos os "stages" do CI. Vamos começar nosso arquivo assim:&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="na"&gt;stages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;test&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;sonarqube&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;build&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;deploy&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nesse momento, estamos definindo que o CI terá esses 4 estágios, um isolado do outro.&lt;/p&gt;

&lt;p&gt;Vamos escrever o primeiro estágio, o de testes:&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="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test&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;php:7.4-fpm&lt;/span&gt;
  &lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;postgres:13&lt;/span&gt;

  &lt;span class="na"&gt;before_script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;sh docker/scripts/dependencies.sh&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;php composer.phar install&lt;/span&gt;

  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;php composer.phar dump-autoload&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;cp .env.gitlab-ci .env&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;php vendor/bin/phpunit --configuration phpunit.xml --coverage-text --colors=never&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nesse estágio, definimos uma imagem do PHP para o container, como cada stage é um container ja podemos definir uma image base, e também um serviço de banco de dados com PostgreSQL. Em seguida, para deixar mais legível o entendimento, usamos o "before_script", que serve apenas para separar a preparação do estágio da sua execução final. Por fim, usando o "script", para de fato executar os testes do PHPUnit.&lt;/p&gt;

&lt;p&gt;Note que os comandos executados nos scripts são comandos que já rodamos no terminal.&lt;/p&gt;

&lt;p&gt;Seguindo essa mesma lógica, vamos escrever os próximos estágios.&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="na"&gt;variables&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;SONAR_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;seu_token_sonar"&lt;/span&gt;
  &lt;span class="na"&gt;DOCKERHUB_REPO&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;seu_usuario_dockerhub/seu_projeto"&lt;/span&gt;
  &lt;span class="na"&gt;DOCKERHUB_USERNAME&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;seu_usuario_dockerhub"&lt;/span&gt;
  &lt;span class="na"&gt;DOCKERHUB_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;seu_senha_dockerhub"&lt;/span&gt;

&lt;span class="na"&gt;sonarqube&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sonarqube&lt;/span&gt;
  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;curl -sSL https://sonarsource.bintray.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.7.1.11002-linux.zip -o /tmp/sonar-scanner.zip&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;unzip -d /opt /tmp/sonar-scanner.zip&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;rm /tmp/sonar-scanner.zip&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;export PATH=$PATH:/opt/sonar-scanner-4.7.1.11002-linux/bin&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;sonar-scanner&lt;/span&gt;

&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;build&lt;/span&gt;
  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;docker build -t $DOCKERHUB_REPO .&lt;/span&gt;

&lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deploy&lt;/span&gt;
  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "$DOCKERHUB_PASSWORD" | docker login -u "$DOCKERHUB_USERNAME" --password-stdin&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;docker push $DOCKERHUB_REPO&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Podemos notar que dessa vez usamos um novo atributo chamado "variables", onde podemos definir variáveis globais para serem utilizadas, como credenciais de bancos, tokens de autenticação, etc.&lt;/p&gt;

&lt;h3&gt;
  
  
  Por hoje é isso, pessoal!
&lt;/h3&gt;

&lt;p&gt;Bom, com isso, deixamos mais claro o que acontece no meio desse 8 de lado ou infinito do DevOps e entendemos uma das principais engrenagens para rodar toda essa esteira de desenvolvimento e integração. Agora, não esqueçam de automatizar os testes e os comandos de deploys usando essa ferramenta. Beijos, meus lindos.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Kubernetes 2: O Retorno</title>
      <dc:creator>Fernando Rosa</dc:creator>
      <pubDate>Mon, 09 Oct 2023 15:44:23 +0000</pubDate>
      <link>https://dev.to/fernandoerosa/kubernetes-2-o-retorno-lia</link>
      <guid>https://dev.to/fernandoerosa/kubernetes-2-o-retorno-lia</guid>
      <description>&lt;h2&gt;
  
  
  Relembrando o'que é o Kubernetes?
&lt;/h2&gt;

&lt;p&gt;O Kubernetes, frequentemente abreviado como K8s, é uma plataforma de código aberto desenvolvida pela Google que se tornou uma ferramenta amplamente adotada para orquestrar contêineres em ambientes de computação em nuvem e infraestruturas locais. Ele foi projetado para resolver os desafios de implantação, gerenciamento e escalabilidade de aplicativos em contêineres, como aqueles criados com Docker.&lt;/p&gt;

&lt;p&gt;Aqui estão os principais conceitos e componentes do Kubernetes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Contêineres:&lt;/strong&gt; Os contêineres são unidades leves e isoladas que empacotam um aplicativo e todas as suas dependências, garantindo que ele seja executado de maneira consistente em diferentes ambientes. O Kubernetes é altamente compatível com contêineres Docker, mas também suporta outros formatos de contêineres.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Clusters:&lt;/strong&gt; No Kubernetes, você cria um cluster que é composto por vários nós (ou máquinas) que executam o software do Kubernetes. Esses nós podem ser máquinas físicas ou virtuais em seu data center ou instâncias de máquinas virtuais em provedores de nuvem.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Pods:&lt;/strong&gt; O pod é a unidade mais básica no Kubernetes. Ele contém um ou mais contêineres que compartilham o mesmo espaço de rede e armazenamento. Os contêineres em um pod geralmente estão intimamente relacionados e precisam se comunicar entre si.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Service:&lt;/strong&gt; Os serviços são recursos do Kubernetes que permitem que os pods se comuniquem uns com os outros e com o mundo externo. Eles fornecem balanceamento de carga e uma maneira consistente de acessar os pods, independentemente de sua localização ou número de réplicas.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Deployment:&lt;/strong&gt; Os deployments permitem que você defina como os aplicativos são implantados e escalados. Eles garantem que um número especificado de réplicas de um aplicativo esteja sempre em execução e facilitam a atualização de aplicativos sem tempo de inatividade.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Namespace:&lt;/strong&gt; Os namespaces fornecem isolamento lógico dentro de um cluster Kubernetes. Eles são usados para segmentar recursos e aplicativos em diferentes ambientes ou equipes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Kubectl:&lt;/strong&gt; O kubectl é a ferramenta de linha de comando que permite interagir com clusters Kubernetes. Com o kubectl, você pode criar, modificar e gerenciar recursos no cluster.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Control Plane:&lt;/strong&gt; O control plane é o "cérebro" do Kubernetes. Ele consiste em vários componentes, como o kube-apiserver, kube-scheduler e kube-controller-manager, que gerenciam o estado do cluster e tomam decisões sobre como a implantação deve ser mantida.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Etcd:&lt;/strong&gt; O etcd é um banco de dados distribuído usado pelo Kubernetes para armazenar informações de configuração do cluster e o estado desejado dos recursos.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Ingress Controller:&lt;/strong&gt; O ingress controller permite que o tráfego externo seja roteado para serviços dentro do cluster, possibilitando a exposição de aplicativos para a Internet de maneira controlada.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Arquitetura do Kubernetes
&lt;/h2&gt;

&lt;p&gt;A arquitetura do Kubernetes é fundamental para entender como essa plataforma orquestra contêineres e gerenciar aplicativos em escala. Vamos explorar os principais componentes da arquitetura do Kubernetes em detalhes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Master Node:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;O nó mestre é o componente central do cluster Kubernetes e é responsável por coordenar todas as operações no cluster. Ele consiste em vários componentes principais:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;kube-apiserver:&lt;/strong&gt; É o ponto de entrada para a API do Kubernetes. Todas as interações com o cluster, como criar, atualizar ou excluir recursos, são realizadas por meio do kube-apiserver. Ele valida e processa as solicitações da API, interage com o etcd para armazenamento persistente e encaminha comandos para os componentes apropriados.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;etcd:&lt;/strong&gt; É um banco de dados de chave-valor consistente usado para armazenar o estado do cluster e as configurações desejadas. O etcd é altamente disponível e garante a consistência dos dados em todo o cluster.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;kube-scheduler:&lt;/strong&gt; Este componente é responsável por determinar em qual nó um novo pod deve ser implantado. Ele considera fatores como recursos disponíveis, requisitos de recursos do pod e políticas de escalabilidade ao tomar essa decisão.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;kube-controller-manager:&lt;/strong&gt; Inclui vários controladores que monitoram o estado dos recursos do Kubernetes e trabalham para manter o estado desejado. Por exemplo, há controladores para pods, serviços e replicaset, garantindo que o cluster esteja sempre convergindo para o estado desejado.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;cloud-controller-manager (opcional):&lt;/strong&gt; Este componente interage com a infraestrutura da nuvem subjacente (se aplicável) para gerenciar recursos específicos da nuvem, como balanceadores de carga e discos persistentes. É opcional e só é necessário em ambientes de nuvem.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Node (ou Worker Node):&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Os nós (nodes) são as máquinas onde os contêineres são realmente executados. Cada nó é responsável por executar os pods e relatar seu status ao mestre. Um cluster Kubernetes pode ter vários nós, criando assim a capacidade de escalabilidade horizontal. Cada nó consiste em:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Kubelet:&lt;/strong&gt; O kubelet é o agente que roda em cada nó e se comunica com o kube-apiserver. Ele garante que os pods estejam em execução nos Nodes e que seu estado seja correspondido ao estado desejado.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Kube-proxy:&lt;/strong&gt; O kube-proxy é responsável por encaminhar o tráfego de rede para os pods. Ele configura as regras de rede para permitir a comunicação entre os pods e com o mundo externo.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Container Runtime:&lt;/strong&gt; É o software responsável por executar os contêineres em um nó. Docker é a runtime mais comum, mas o Kubernetes também suporta outras, como containerd ou CRI-O.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Pods:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Os pods são a unidade básica de implantação no Kubernetes (é aqui que o nosso container da aplicação irá ficar). Eles podem conter um ou mais contêineres que compartilham o mesmo espaço de rede e armazenamento, tornando-os ideais para aplicativos intimamente relacionados. Os pods são agendados para execução em nós pelo kube-scheduler e podem ser escalados horizontalmente (podemos fazer esses agendamentos utilizando o kubectl ou até mesmo uma interface, como a do minikube).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Serviços e Ingress:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Os serviços são recursos que permitem a comunicação entre os pods. Eles fornecem uma abstração de rede estável e um balanceamento de carga para garantir que os aplicativos sejam acessíveis e escaláveis. O Ingress, por outro lado, permite que o tráfego externo seja roteado para serviços específicos dentro do cluster. Nesse ponto é muito importante configurarmos o controle se sessões para múltiplos pods, uma prática comum e usar uma configuração de sessão permanente, na qual irá garantir que um usuário sempre utilize a mesma sessão para se conectar com os pods, essa configuração normalmente é necessária quando temos múltiplos pods do mesmo sistema, que é uma amostrar na escalabilidade que o k8s nos fornece.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Namespace:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Os namespaces são usados para segmentar e isolar recursos e aplicativos dentro do mesmo cluster Kubernetes. Eles ajudam a organizar e gerenciar recursos em ambientes compartilhados ou em várias equipes.&lt;/p&gt;

&lt;p&gt;Esses são os principais componentes da arquitetura do Kubernetes. Eles trabalham juntos para fornecer orquestração, gerenciamento, escalabilidade e alta disponibilidade para aplicativos em contêineres em ambientes de nuvem e locais. Entender essa arquitetura é fundamental para usar eficazmente o Kubernetes e garantir que seus aplicativos sejam executados de forma confiável e eficiente.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementando o Kubernetes no projeto
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Ingress
&lt;/h3&gt;

&lt;p&gt;O ingress é o componente do Kubernetes que é responsável por expor nosso sistema publicamente, sendo um meio campo entre o Serviço que está nosso pod com o projeto e o público, ele serve como um balanceador de carga no cluster que joga o trafego para seus determinados pods.&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="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;networking.k8s.io/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;Ingress&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;k8s-ingress-testing&lt;/span&gt;
  &lt;span class="na"&gt;annotations&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;kubernetes.io/ingress.class&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;nginx.ingress.kubernetes.io/rewrite-target&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/&lt;/span&gt;
    &lt;span class="na"&gt;cert-manager.io/cluster-issuer&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;letsencrypt-prod&lt;/span&gt;
    &lt;span class="na"&gt;nginx.ingress.kubernetes.io/proxy-body-size&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;240m"&lt;/span&gt;
    &lt;span class="na"&gt;nginx.ingress.kubernetes.io/affinity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cookie"&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;tls&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;hosts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;fernando.com.br&lt;/span&gt;
    &lt;span class="na"&gt;secretName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;k8s-testing-tls&lt;/span&gt;
  &lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;fernando.com.br&lt;/span&gt;
    &lt;span class="na"&gt;http&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;pathType&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Prefix&lt;/span&gt;
        &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/&lt;/span&gt;
        &lt;span class="na"&gt;backend&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;service&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;meu-sistema&lt;/span&gt;
            &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;number&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;h3&gt;
  
  
  Dissecção
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;apiVersion: networking.k8s.io/v1&lt;/code&gt;: Isso especifica a versão da API do recurso Ingress que está sendo usada. No caso, é a versão 1 da API de rede do Kubernetes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;kind: Ingress&lt;/code&gt;: Define o tipo de recurso como Ingress, que é usado para controlar o tráfego de entrada para os serviços dentro do cluster Kubernetes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;metadata&lt;/code&gt;: Aqui estão metadados associados ao recurso Ingress. Estes incluem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;name&lt;/code&gt;: O nome do recurso Ingress, que é "k8s-ingress-testing".&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;annotations&lt;/code&gt;: Anotações adicionais que fornecem informações e configurações adicionais para o Ingress. Algumas anotações específicas estão sendo usadas aqui, como a definição da classe de Ingress, reescrita de destino, emissão de certificado, tamanho do corpo do proxy e afinidade.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;&lt;code&gt;spec&lt;/code&gt;: Esta seção descreve as especificações do Ingress. Aqui estão algumas partes importantes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;tls&lt;/code&gt;: Configuração para suporte a TLS (SSL) no Ingress. Isso indica que a rota para o host "&lt;a href="http://fernando.rosa.com.br/"&gt;fernando.rosa.com.br&lt;/a&gt;" deve ser acessada via TLS (HTTPS) usando o certificado armazenado em "k8s-testing-tls". Isso permite a criptografia de dados entre o cliente e o servidor.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;rules&lt;/code&gt;: Define as regras de roteamento do tráfego. No exemplo, há apenas uma regra:&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;host&lt;/code&gt;: O host pelo qual o tráfego deve ser roteado, que é "&lt;a href="http://fernando.rosa.com.br/"&gt;fernando.rosa.com.br&lt;/a&gt;".&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;http&lt;/code&gt;: Define as regras HTTP para esse host.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;paths&lt;/code&gt;: Define os caminhos sob o host que correspondem a esse Ingress. No exemplo, há uma única regra de caminho:&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pathType&lt;/code&gt;: O tipo de caminho, que é "Prefix". Isso significa que qualquer URL que comece com "/" (ou seja, todas as URLs) corresponderão a esta regra.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;path&lt;/code&gt;: O caminho em si, que é "/" neste caso, ou seja, todas as URLs.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;backend&lt;/code&gt;: Define o serviço de destino para encaminhar o tráfego. Neste caso, o tráfego será encaminhado para o serviço chamado "meu-sistema" na porta 80.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Configmap para o Nginx
&lt;/h3&gt;

&lt;p&gt;Umas das práticas que iremos adotar em nossos cluster e pods de projeto, é a separação e dinamicidade das configurações do nginx, para isso iremos utilizar o componente ConfigMap, que permite desacoplar as configurações de qualquer tipo de arquivo. Nesse caso, nosso arquivo do ConfigMap será o default.conf, que fica dentro do nginx.&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="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ConfigMap&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;v1&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-config&lt;/span&gt;
&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;default.conf&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|-&lt;/span&gt;
      &lt;span class="s"&gt;server {&lt;/span&gt;
        &lt;span class="s"&gt;listen [::]:8080 default_server;&lt;/span&gt;
        &lt;span class="s"&gt;listen 8080 default_server;&lt;/span&gt;
        &lt;span class="s"&gt;server_name _;&lt;/span&gt;

        &lt;span class="s"&gt;client_max_body_size 240m;&lt;/span&gt;

        &lt;span class="s"&gt;sendfile off;&lt;/span&gt;
        &lt;span class="s"&gt;tcp_nodelay on;&lt;/span&gt;
        &lt;span class="s"&gt;absolute_redirect off;&lt;/span&gt;

        &lt;span class="s"&gt;root /var/www/public;&lt;/span&gt;
        &lt;span class="s"&gt;index index.php index.html;&lt;/span&gt;

        &lt;span class="s"&gt;location / {&lt;/span&gt;
            &lt;span class="s"&gt;try_files $uri $uri/ /index.php?q=$uri&amp;amp;$args;&lt;/span&gt;
        &lt;span class="s"&gt;}&lt;/span&gt;

        &lt;span class="s"&gt;error_page 500 502 503 504 /50x.html;&lt;/span&gt;
        &lt;span class="s"&gt;location = /50x.html {&lt;/span&gt;
            &lt;span class="s"&gt;root /var/lib/nginx/html;&lt;/span&gt;
        &lt;span class="s"&gt;}&lt;/span&gt;

        &lt;span class="s"&gt;location ~ \\.php$ {&lt;/span&gt;
            &lt;span class="s"&gt;try_files $uri =404;&lt;/span&gt;
            &lt;span class="s"&gt;fastcgi_split_path_info ^(.+\\.php)(/.+)$;&lt;/span&gt;
            &lt;span class="s"&gt;fastcgi_pass unix:/run/php-fpm.sock;&lt;/span&gt;
            &lt;span class="s"&gt;fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;&lt;/span&gt;
            &lt;span class="s"&gt;fastcgi_param SCRIPT_NAME $fastcgi_script_name;&lt;/span&gt;
            &lt;span class="s"&gt;fastcgi_index index.php;&lt;/span&gt;
            &lt;span class="s"&gt;fastcgi_param HTTPS 'on';&lt;/span&gt;
            &lt;span class="s"&gt;include fastcgi_params;&lt;/span&gt;
        &lt;span class="s"&gt;}&lt;/span&gt;

        &lt;span class="s"&gt;location ~* \\.(jpg|jpeg|gif|png|css|js|ico|xml)$ {&lt;/span&gt;
            &lt;span class="s"&gt;expires 5d;&lt;/span&gt;
        &lt;span class="s"&gt;}&lt;/span&gt;

        &lt;span class="s"&gt;location ~ /\\. {&lt;/span&gt;
            &lt;span class="s"&gt;log_not_found off;&lt;/span&gt;
            &lt;span class="s"&gt;deny all;&lt;/span&gt;
        &lt;span class="s"&gt;}&lt;/span&gt;

        &lt;span class="s"&gt;location ~ ^/(fpm-status|fpm-ping)$ {&lt;/span&gt;
            &lt;span class="s"&gt;access_log off;&lt;/span&gt;
            &lt;span class="s"&gt;allow 127.0.0.1;&lt;/span&gt;
            &lt;span class="s"&gt;deny all;&lt;/span&gt;
            &lt;span class="s"&gt;fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;&lt;/span&gt;
            &lt;span class="s"&gt;include fastcgi_params;&lt;/span&gt;
            &lt;span class="s"&gt;fastcgi_pass unix:/run/php-fpm.sock;&lt;/span&gt;
        &lt;span class="s"&gt;}&lt;/span&gt;
      &lt;span class="s"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Dissecção
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;kind: ConfigMap&lt;/code&gt;: Define o tipo de recurso como ConfigMap. Um ConfigMap é usado para armazenar dados de configuração em um formato chave-valor que pode ser consumido por outros recursos dentro do cluster Kubernetes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;apiVersion: v1&lt;/code&gt;: Isso especifica a versão da API do recurso ConfigMap que está sendo usada. Neste caso, é a versão 1 da API principal do Kubernetes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;metadata&lt;/code&gt;: Esta seção contém metadados associados ao recurso ConfigMap. Aqui, estão os seguintes metadados:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;name&lt;/code&gt;: O nome do ConfigMap, que é "nginx-config". Isso é o identificador exclusivo do ConfigMap dentro do namespace onde está sendo criado.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;&lt;code&gt;data&lt;/code&gt;: Esta seção é onde os dados de configuração são definidos no formato chave-valor. No exemplo fornecido, há uma única chave chamada "default.conf", seguida por ":-" para indicar que o valor associado a essa chave será fornecido na próxima linha.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;default.conf&lt;/code&gt;: Este é o nome da chave no ConfigMap. Esta chave é usada para armazenar configurações específicas do Nginx, que provavelmente são arquivos de configuração ou fragmentos de configuração em texto.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Service
&lt;/h3&gt;

&lt;p&gt;O Service padrão do Kubernetes quando não especificamos nada, e o ClusterIP, que é basicamente uma exposição da porta configurada para que nossos pods possam expor os serviços necessários. Controlamos as associação de pods x service com a configuração &lt;code&gt;app: meu-sistema&lt;/code&gt;, o qual deve ser configurada posteriormente nos componentes de Deployment no Kubernetes.&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="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="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Service&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;meu-sistema&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;selector&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;meu-sistema&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;protocol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;TCP&lt;/span&gt;
      &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
      &lt;span class="na"&gt;targetPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8080&lt;/span&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Dissecção
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;apiVersion: v1&lt;/code&gt;: Isso especifica a versão da API do recurso Service que está sendo usada. Neste caso, é a versão 1 da API principal do Kubernetes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;kind: Service&lt;/code&gt;: Define o tipo de recurso como Service. Um Service no Kubernetes é usado para expor aplicativos em execução dentro do cluster para comunicação com outros recursos dentro ou fora do cluster.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;metadata&lt;/code&gt;: Esta seção contém metadados associados ao recurso Service. Aqui, está o seguinte metadado:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;name&lt;/code&gt;: O nome do Service, que é "meu-sistema". Este é o identificador exclusivo do Service dentro do namespace onde está sendo criado.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;&lt;code&gt;spec&lt;/code&gt;: Esta seção contém as especificações para o Service. As partes relevantes incluem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;selector&lt;/code&gt;: Esta seção especifica um conjunto de rótulos que são usados para selecionar os pods de destino para os quais o tráfego será direcionado. No caso, os pods de destino são selecionados com base no rótulo "app" com o valor "meu-sistema". Isso significa que este Service encaminhará o tráfego para todos os pods que têm o rótulo "app" definido como "meu-sistema".&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ports&lt;/code&gt;: Esta seção especifica as portas nas quais o Service estará disponível e para onde o tráfego será encaminhado. No exemplo:&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;protocol&lt;/code&gt;: Define o protocolo de rede a ser usado, que é "TCP". Isso indica que o Service lida com tráfego TCP.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;port&lt;/code&gt;: A porta no Service onde o tráfego será recebido, que é a porta 80.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;targetPort&lt;/code&gt;: A porta no pod de destino para onde o tráfego será encaminhado, que é a porta 8080.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Deployment
&lt;/h3&gt;

&lt;p&gt;Esse componente é oque de fato irá realizar o deploy da nossa aplicação, contanto que ela já esteja no Registry e seja acessível (Consulte Docker para mais informações). Aqui é onde realizamos a implementação de configMaps, réplicas e quais imagem e containers nosso pod irá ter. Um ponto importante a se notar é a configuração &lt;code&gt;matchLabels:&lt;/code&gt; que é onde será vinculado nossos pod a um determinado service.&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="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;meu-sistema&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;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&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;meu-sistema&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;meu-sistema&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;volumes&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-config-volume&lt;/span&gt;
          &lt;span class="na"&gt;configMap&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-config&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;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;registry.digitalocean.com/fernando/meu-sistema:alpine-php-nginx-2.0&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;meu-sistema&lt;/span&gt;
          &lt;span class="na"&gt;volumeMounts&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-config-volume&lt;/span&gt;
              &lt;span class="na"&gt;mountPath&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/etc/nginx/conf.d&lt;/span&gt;
          &lt;span class="na"&gt;envFrom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;configMapRef&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;env&lt;/span&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Dissecção
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;apiVersion: apps/v1&lt;/code&gt;: Isso especifica a versão da API do recurso Deployment que está sendo usada. Neste caso, é a versão 1 da API de aplicativos do Kubernetes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;kind: Deployment&lt;/code&gt;: Define o tipo de recurso como Deployment. Um Deployment no Kubernetes é usado para gerenciar a implantação de réplicas de pods.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;metadata&lt;/code&gt;: Esta seção contém metadados associados ao recurso Deployment. Aqui, está o seguinte metadado:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;name&lt;/code&gt;: O nome do Deployment, que é "meu-sistema". Este é o identificador exclusivo do Deployment dentro do namespace onde está sendo criado.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;&lt;code&gt;spec&lt;/code&gt;: Esta seção contém as especificações para o Deployment. As partes relevantes incluem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;replicas&lt;/code&gt;: Define o número desejado de réplicas do pod que o Deployment manterá em execução. Neste caso, está definido como 1, o que significa que deve haver uma única réplica do pod.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;selector&lt;/code&gt;: Esta seção especifica um conjunto de rótulos que são usados para selecionar os pods de destino controlados pelo Deployment. No caso, os pods de destino são selecionados com base no rótulo "app" com o valor "meu-sistema".&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;template&lt;/code&gt;: Define o modelo para a criação de pods controlados pelo Deployment.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;metadata&lt;/code&gt;: Esta seção contém rótulos associados aos pods criados pelo Deployment. No caso, o rótulo "app" com o valor "meu-sistema" é adicionado aos pods.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;spec&lt;/code&gt;: Esta seção descreve as especificações dos pods criados pelo Deployment. As partes relevantes incluem:&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;volumes&lt;/code&gt;: Esta seção especifica os volumes que podem ser montados nos pods. No exemplo, há um volume chamado "nginx-config-volume" que é um ConfigMap chamado "nginx-config". Isso permite que os pods acessem os dados de configuração do ConfigMap "nginx-config".&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;containers&lt;/code&gt;: Aqui, é definido o container que será executado nos pods. As partes relevantes do container incluem:&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;image&lt;/code&gt;: A imagem do container que será usada. Neste caso, é uma imagem específica do Docker hospedada em "&lt;a href="http://registry.digitalocean.com/fernando/meu-sistema:alpine-php-nginx-2.0"&gt;registry.digitalocean.com/fernando/meu-sistema:alpine-php-nginx-2.0&lt;/a&gt;".&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;name&lt;/code&gt;: O nome do container, que é "meu-sistema".&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;volumeMounts&lt;/code&gt;: Esta seção especifica como os volumes definidos anteriormente são montados no container. Neste caso, o volume "nginx-config-volume" é montado em "/etc/nginx/conf.d" no container.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;envFrom&lt;/code&gt;: Esta seção permite que o container obtenha variáveis de ambiente de um ConfigMap chamado "env".&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Considerações finais
&lt;/h2&gt;

&lt;p&gt;Essa é uma implementação basica de um ambiente Kubernetes, configurações como o uso de Values e Secrets para dados sensíveis não foram utilizadas, por conta desse tutorial seguir uma linha do iniciante para o avançado.&lt;/p&gt;

&lt;p&gt;Mas, assim como o primeiro, vamos ter a parte 3 deste tutorial, onde iremos implementar monitoramento utilizando o Prometheus e o Grafana para análise de desempenho de cada ingress e cada pod do nosso ambiente, juntamente com a utilização de secrets e de como utilizados da forma mais segura e correta para controle dinâmico de variáveis de ambiente.&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>docker</category>
      <category>devops</category>
      <category>cloud</category>
    </item>
    <item>
      <title>Entendendo o Kubernetes</title>
      <dc:creator>Fernando Rosa</dc:creator>
      <pubDate>Tue, 12 Sep 2023 16:08:44 +0000</pubDate>
      <link>https://dev.to/fernandoerosa/entendendo-o-kubernetes-30bn</link>
      <guid>https://dev.to/fernandoerosa/entendendo-o-kubernetes-30bn</guid>
      <description>&lt;h2&gt;
  
  
  O que é o Kubernetes?
&lt;/h2&gt;

&lt;p&gt;Para entender, precisamos saber o que é uma imagem Docker e um container.&lt;/p&gt;

&lt;p&gt;Basicamente, quando falamos de um container no meio da programação e DevOps, falamos de um ambiente totalmente isolado de onde ele está, podendo ser sua máquina local ou um servidor. Um container contém uma imagem, que é basicamente suas configurações. Por exemplo, quando falamos que temos um container com uma imagem php:8.2, quer dizer que temos um container que dentro dele temos o PHP, rodando provavelmente em um Ubuntu, exatamente como nossa máquina local quando instalamos o PHP nela.&lt;/p&gt;

&lt;p&gt;Aí que entra o Kubernetes. Imagine que, em vez de termos um container de php:8.2, teríamos um container com a imagem do nosso sistema, tipo meu-sistema:1.0, tendo todas as configurações e dependências encapsuladas em um container. O Kubernetes serve para usarmos esses containers de imagens criadas apartir do nosso sistema de forma escalável, otimizada e auto-gerenciável. Imagine rodar 4 containers idênticos, sendo orquestrados pelo Kubernetes, já com um balanceador de carga para direcionar o tráfego para cada container. Legal, não é? Mas como funciona?&lt;/p&gt;

&lt;h2&gt;
  
  
  Arquitetura do Kubernetes
&lt;/h2&gt;

&lt;p&gt;Para simplificar, podemos entender a arquitetura do Kubernetes em 3 partes.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Node&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Os nós (nodes) são as máquinas onde os contêineres são realmente executados. Cada nó é responsável por executar os pods (Nosso sistema, por exemplo). Um cluster Kubernetes pode ter vários nós, criando assim a capacidade de escalabilidade.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Pods&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Os pods são a unidade básica de implantação no Kubernetes. Eles podem conter um ou mais contêineres que compartilham o mesmo espaço de rede e armazenamento, tornando-os ideais para aplicativos intimamente relacionados (aqui estamos falando de containers que podem conter um banco de dados, por exemplo, tipo mysql:2.0, que se conectam com o container meu-sistema:2.0, por exemplo).&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Services (serviços) e Ingress&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Os serviços são recursos que permitem a comunicação entre os pods. Eles fornecem uma abstração de rede estável e um balanceamento de carga para garantir que os aplicativos sejam acessíveis e escaláveis. O Ingress, por outro lado, permite que o tráfego externo seja roteado para serviços específicos dentro do cluster, ele basicamente deixa nosso sistema acessível publicamente, e quando o Ingress recebe uma requisição de um host, por exemplo, meu-sistema.com.br, ele irá direcionar para o serviço que nosso pod do sistema está rodando.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fluxo de trabalho
&lt;/h2&gt;

&lt;p&gt;Basicamente, essas são as ferramentas necessárias para um "Kubernetes Básico", mas agora como isso fica no dia-a-dia? Primeiro de tudo, temos que ter uma imagem do nosso projeto, utilizando o Docker e um Dockerfile. Basicamente, no Dockerfile, a gente simula todo o fluxo de instalação de dependências, banco de dados, etc., tipo um script, que o Docker irá usar para montar o container. Depois disso, a ideia é que cada versão nova do nosso sistema tenha uma imagem, com o nome correto, tipo meu-sistema:1.0 e meu-sistema:2.0, assim sucessivamente. Depois disso, começamos a jogar essa imagem para dentro do nosso Kubernetes, e com as configurações corretas, o Kubernetes irá subir pods, que irão conter os containers da nossa aplicação e disponibilizar ela. (Nesse momento, nosso Kubernetes está rodando em algum servidor ou cluster, mas não se preocupe em como isso rola, só pegue bem como o Kubernetes trabalha)&lt;/p&gt;

&lt;h2&gt;
  
  
  O que vai jogar a imagem para dentro do Kubernetes?
&lt;/h2&gt;

&lt;p&gt;O que irá jogar as imagens dos containers do nosso sistema para dentro do Kubernetes são os arquivos .yaml, que irão conter as configurações do Kubernetes. Podemos dividir em 2 arquivos para entendermos melhor, vamos chamar esses arquivos de deployment.yaml e ingress.yaml.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;deployment.yaml&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Esse arquivo é responsável por criar o Service do nosso sistema, que irá abrir uma porta dentro do Kubernetes, para que nosso Ingress saiba aonde direcionar os usuários que acessarem o host meu-sistema.com.br. Quando falamos de Kubernetes, nós conseguimos realizar apontamentos em Services, utilizando o Ingress, em vez de apontamento de IPs.&lt;br&gt;
Logo após a criação do Service, iremos criar as configurações de deployment, ou deploy, que de fato irá criar os pods com os containers contendo as imagens do nosso projeto. É nessa configuração que iremos colocar quantos pods serão criados do mesmo software, configurações de servidor, volume de dados, etc., mas vamos focar no básico. Aqui embaixo temos um exemplo de um arquivo deployment.yaml, apenas para contextualizar, vamos entrar mais a fundo no que é cada configuração no próximo blog :).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: v1
kind: Service
metadata:
  name: meu-sistema-service
spec:
  selector:
    app: meu-sistema
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: ClusterIP

--- ## Esses "---" Separam o arquivo, dizendo quando começa um tipo de Service, como Deployment e o Service.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: meu-sistema-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: meu-sistema
  template:
    metadata:
      labels:
        app: meu-sistema
    spec:
      containers:
        - name: meu-sistema
          image: meu-sistema:1.0
          ports:
            - containerPort: 80
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;ingress.yaml&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;O Ingress é o cara que vai estar no topo do nosso Kubernetes, e ele que irá receber os acessos vindos de usuários que acessam nosso sistema publicamente. Ele que irá capturar essas solicitações e, dependendo do host ou domínio que solicitar, como meu-sistema.com.br, ele irá direcionar essa requisição para um Service, e esse Service irá jogar para um pod, que de fato está rodando nosso sistema. Aqui embaixo temos uma configuração básica de Ingress, que irá direcionar para o nosso Service meu-sistema-service, que configuramos ali em cima.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: meu-sistema-ingress
spec:
  rules:
    - host
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Po-po-Por hoje é isso pessoal!
&lt;/h3&gt;

&lt;p&gt;Com isso podemos entender a essencia por traz do Kube, para já saber como o Kubernetes funciona e como funciona um deploy de uma imagem nele, a ideia era contextualizar vocês, para ja terem a base, e logo mais irei postar um artigo que de fato vai explorar cada configuração, modos de deploy, erros mais comuns, boas praticar e escalabilidade e mais! Fica ligado ai que vai ter mais!!! Bejos meus lindos.&lt;/p&gt;

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