DEV Community

Cristiano Lemes
Cristiano Lemes

Posted on

Isolando cargas de trabalho no k8s com kata container

Introdução

Containers revolucionaram a forma como implantamos e gerenciamos aplicações, oferecendo portabilidade, escalabilidade e eficiência no uso de recursos. No entanto, apesar dessas vantagens, containers tradicionais não são projetados para fornecer isolamento total entre cargas de trabalho. Eles compartilham o kernel do sistema operacional do host, o que significa que, em cenários de ataque, vulnerabilidades no kernel ou nos próprios mecanismos de conteinerização, como namespaces e cgroups, podem ser exploradas para comprometer o ambiente do host ou outros containers.

Além disso, ataques como container escape permitem que um invasor rompa as barreiras de isolamento e obtenha acesso a recursos do host. Essa preocupação é ainda mais relevante em ambientes multi-tenant, onde múltiplas cargas de trabalho de diferentes equipes ou clientes podem estar sendo executadas lado a lado.

Por conta dessas limitações, surge a necessidade de soluções mais robustas para isolamento de cargas de trabalho. Tecnologias como Kata Containers e Firecracker oferecem maior segurança ao combinarem a leveza dos containers com o isolamento robusto de máquinas virtuais (VMs), criando uma camada adicional de proteção sem sacrificar a eficiência operacional.

Neste guia, exploraremos como integrar essas tecnologias ao Kubernetes para isolar cargas de trabalho de forma eficaz, reduzindo riscos de segurança em ambientes sensíveis.

Ferramentas Utilizadas

  • Cilium
  • Terraform
  • Ansible
  • Equinix Metal
  • Kata Container
  • Firecraker
  • Helm

Ambiente Local
Ferramentas instaladas

  • Metal Cli (Ferramenta de linha de comando da Equinix Metal)
go install github.com/equinix/metal-cli/cmd/metal@latest
Enter fullscreen mode Exit fullscreen mode
  • Ansible no Linux com pipx ou uv:
pipx install ansible-core

uvx ansible
Enter fullscreen mode Exit fullscreen mode
  • Ansible no Windows com Docker:
  • Crie os alias no seu $PROFILE
function runansible { 
  docker run -ti --rm `
    -v "$HOME\.ssh:/root/.ssh" `
    -v "$HOME\.aws:/root/.aws" `
    -v "${PWD}:/apps" `
    -w /apps `
    alpine/ansible ansible @args
}  
New-Alias -Name ansible -Value runansible

function playbook {
  docker run -ti --rm `
    -v "$HOME\.ssh:/root/.ssh" `
    -v "$HOME\.aws:/root/.aws" `
    -v "${PWD}:/apps" `
    -w /apps alpine/ansible `
   bash -c `
   "chmod -R 700 /root/.ssh && ansible-playbook $($args -join ' ')"
}
New-Alias -Name ansible-playbook -Value playbook
Enter fullscreen mode Exit fullscreen mode
  • Terraform siga a instalação para sua plataforma

Parte 1: Criando servidores

Nessa guia eu vou usar a Equinix Metal para o ambiente de servidores, você também pode usar seu provedor de Bare metal preferido, ou ambiente de virtualização local se seu ambiente suportar virtualização aninhada (Nested VT-x/AMD-V).
os requisitos são mínimo 2 servidores com 2CPU e 4GB de Ram .

Criando ambiente na Equinix Metal

1. Crie uma conta na Equinix Metal , ou caso já tenha faça login.

  • No momento eles estão oferendo um crédito de $250,00 para testar a plataforma, o suficiente para seguir esse tutorial. O uso é cobrado por hora em instancias on demand, com cobrança mínima de 1 hora (Não adianta desligar depois de 1 minuto, vai cobrar 1 hora).

2. Crie uma chave de API para acessar a Equinix.

  • No console da equinix, selecione o projeto em qual você vai criar suas maquinas, vá em project settings, e em api keys, adicione uma chave com permissão readwrite.

Api Equinix

Criando scripts Terraform para a implantação das máquinas

Siga as instruções abaixo para criar os arquivos e configurar a infraestrutura.

1. Estrutura de Arquivos

📂 k8s-metal-fire/
├── 📂 terraform/
│ ├── 📄 main.tf
│ ├── 📄 output.tf
│ ├── 📄 providers.tf
│ ├── 📄 terraform.tfvars
│ ├── 📄 variables.tf
│ └── 📝 inventory.sh
├── 📂 ansible/
....

Crie a estrutura de pastas e arquivos. Use os comandos abaixo:

mkdir -p k8s-metal-fire/terraform
mkdir -p k8s-metal-fire/ansible/{build,inventory,scripts/devmapper}

touch k8s-metal-fire/terraform/{main.tf,output.tf,providers.tf,terraform.tfvars,variables.tf}
touch k8s-metal-fire/ansible/{build/firecracker,inventory/hosts.yml,scripts/devmapper/{create.sh,reload.sh}}
touch k8s-metal-fire/{cluster_bootstrap.yml,k8s_environment.yml,k8s_firecracker.yml,main.yml}
Enter fullscreen mode Exit fullscreen mode

2. Crie o arquivo main.tf

Esse arquivo define os recursos que serão provisionados no Equinix Metal.

Conteúdo:

resource "equinix_metal_device" "k8s_master" {
  count            = var.k8s_master.num_instances
  hostname         = "k8s-master-${count.index + 1}"
  plan             = var.k8s_master.plan
  metro            = var.em_region
  operating_system = var.k8s_master.operating_system
  billing_cycle    = var.billing_cycle
  project_id       = var.em_project_id

  tags = ["kubernetes", "master"]
}

resource "equinix_metal_device" "k8s_worker" {
  count            = var.k8s_nodes.num_instances
  hostname         = "k8s-worker-${count.index + 1}"
  plan             = var.k8s_nodes.plan
  metro            = var.em_region
  operating_system = var.k8s_nodes.operating_system
  billing_cycle    = var.billing_cycle
  project_id       = var.em_project_id

  tags = ["kubernetes", "worker"]
}
Enter fullscreen mode Exit fullscreen mode

O que faz:

  • Define dois tipos de máquinas:
    • Masters: Controlam o cluster Kubernetes.
    • Workers: Executam os workloads (cargas de trabalho).

3. Crie o arquivo output.tf

Esse arquivo define as saídas dos recursos provisionados.

Conteúdo:

output "master_ips" {
  value = {
    for device in equinix_metal_device.k8s_master :
    device.hostname => {
      "public_ip"  = device.access_public_ipv4
      "private_ip" = device.access_private_ipv4
    }
  }
  description = "IP addresses of master nodes"
}

output "worker_ips" {
  value = {
    for device in equinix_metal_device.k8s_worker :
    device.hostname => {
      "public_ip"  = device.access_public_ipv4
      "private_ip" = device.access_private_ipv4
    }
  }
  description = "IP addresses of worker nodes"
}
Enter fullscreen mode Exit fullscreen mode

O que faz:

  • Mostra os IPs públicos e privados dos masters e workers após a execução do Terraform.

4. Crie o arquivo providers.tf

Esse arquivo configura o provedor do Terraform.

Conteúdo:

terraform {
  required_providers {
    equinix = {
      source  = "equinix/equinix"
      version = "2.11.0"
    }
  }
  # backend "gcs" {
  #   bucket = "cslemes-terraform"
  #}
}

provider "equinix" {
  auth_token = var.em_api_token
}
Enter fullscreen mode Exit fullscreen mode

O que faz:

  • Configura o provedor Equinix Metal para gerenciar os recursos.
  • Inclui um exemplo comentado de backend remoto para armazenar o estado do Terraform.

5. Crie o arquivo terraform.tfvars

Esse arquivo define os valores das variáveis.

Conteúdo:

em_api_token  = "xxxxxxxxxxxxxxxxxxxxxxxxx"
em_project_id = "xxxxxxxxxxxxxxxxxxxxxxxxxx"
em_region     = "da"

billing_cycle = "hourly"

k8s_master = {
  plan             = "c3.small.x86"
  ipxe_script_url  = ""
  operating_system = "ubuntu_24_04"
  num_instances    = 3
  tags             = ["k8s_master"]
}

k8s_nodes = {
  plan             = "c3.small.x86"
  ipxe_script_url  = ""
  operating_system = "ubuntu_24_04"
  num_instances    = 2
  tags             = ["k8s-nodes"]
}
Enter fullscreen mode Exit fullscreen mode

O que faz:

  • Define as credenciais (API token e ID do projeto).
  • Configura os planos e características das máquinas para os masters e workers.

6. Crie o arquivo variables.tf

Esse arquivo declara as variáveis usadas no projeto.

Conteúdo:

variable "em_api_token" {
  description = "Equinix Metal API Key"
  type        = string
}

variable "em_project_id" {
  description = "Equinix Metal Project ID"
  type        = string
}

variable "em_region" {
  description = "Equinix Metal region to use"
  type        = string
}

variable "billing_cycle" {
  description = "value of billing cycle"
  type        = string
}

variable "k8s_master" {
  description = "k8s master"
  type = object({
    plan             = string
    ipxe_script_url  = optional(string)
    operating_system = string
    num_instances    = number
    tags             = optional(list(string), [])
  })
}

variable "k8s_nodes" {
  description = "k8s nodes"
  type = object({
    plan             = string
    ipxe_script_url  = optional(string)
    operating_system = string
    num_instances    = number
    tags             = optional(list(string), [])
  })
}
Enter fullscreen mode Exit fullscreen mode

O que faz:

  • Declara as variáveis obrigatórias, como token, projeto, região, e configurações dos nós.

Com esses arquivos criados, você pode iniciar a implantação executando os seguintes comandos no diretório terraform:

terraform init      # Inicializa o projeto
terraform plan      # Exibe o plano de execução
terraform apply     # Aplica as configurações e provisiona os recursos
Enter fullscreen mode Exit fullscreen mode

7. Crie o arquivo inventory.sh

  • Esse script vai pegar o output do terraform e gerar o arquivo de inventory para o ansible.
terraform output -json | jq -r '
  .master_ips.value as $masters |
  .worker_ips.value as $workers |
  {
    all: {
      children: {
        k8s_master: {
          hosts: (
            $masters | to_entries | map({
              (.key): {
                ansible_host: .value.public_ip,
                ansible_user: "root"
              }
            }) | add
          )
        },
        k8s_workers: {
          hosts: (
            $workers | to_entries | map({
              (.key): {
                ansible_host: .value.public_ip,
                ansible_user: "root"
              }
            }) | add
          )
        }
      }
    }
  }
' | yq -P > ../ansible/hosts.yaml
Enter fullscreen mode Exit fullscreen mode

Criando manifestos Ansible para configuração do cluster Kubernetes

Você pode criar os arquivos necessários para o Ansible em uma estrutura organizada. Aqui está um guia passo a passo para criar e organizar os arquivos mencionados:


1. Estrutura de diretórios

Crie os seguintes diretórios e arquivos no seu projeto:

📂 ansible/
├── 📂 group_vars/
├── 📂 host_vars/
├── 📂 roles/
│ ├── 📂 k8s_environment/
│ │ ├── 📂 scripts/
│ │ │ ├── 📂 devmapper/
│ │ │ │ ├── 📄 create.sh
│ │ │ │ └── 📄 reload.sh
│ │ │ └── 📄 devmapper_reload.service
│ │ ├── 📂 tasks/
│ │ │ └── 📄 main.yml
│ ├── 📂 k8s_bootstrap/
│ │ ├── 📂 build/
│ │ │ └── 📄 firecraker
│ │ ├── 📂 tasks/
│ │ │ └── 📄 main.yml
│ ├── 📂 k8s_firecracker/
│ │ ├── 📂 tasks/
│ │ │ └── 📄 main.yml
│ ├── 📂 apply_kata/
│ │ ├── 📂 tasks/
│ │ │ └── 📄 main.yml
├── 📄 hosts.yml
└── 📄 playbook.yml

2. Arquivo hosts.yml

Define os grupos de hosts (master e workers), vamos cria-lo a partir do output do terraform aqui é um exemplo:

all:
  children:
    k8s_master:
      hosts:
        node1:
          ansible_host: 147.75.45.67
          ansible_user: root
    workers:
      hosts:
        node:
          ansible_host: 147.28.197.223
          ansible_user: root

Enter fullscreen mode Exit fullscreen mode

3. Arquivo playbook.yml

O ponto de entrada principal do Ansible:

- name: Setup Kubernetes cluster
  hosts: all
  become: yes
  tasks:
    - name: Install Kubernetes dependencies
      import_role:
        name: k8s_environment

- name: Configure Firecracker
  hosts: all
  become: yes
  tasks:
    - name: Configure Firecracker
      import_role:
        name: k8s_firecracker

- name: Add kube-vip
  hosts: k8s_master
  become: yes
  tasks:
    - name: Generate kube-vip manifest
      include_tasks: kube-vip.yaml

- name: Bootstrap Kubernetes cluster
  hosts: k8s_master
  become: yes
  tasks:
    - name: Bootstrap cluster
      import_role:
        name: k8s_bootstrap

- name: Apply Kata manifests
  hosts: k8s_master
  become: yes
  tasks:
    - name: Apply Kata
      import_role:
        name: apply_kata

- name: Join worker nodes
  hosts: k8s_workers
  become: yes
  tasks:
    - name: Join cluster
      command: "{{ hostvars[groups['k8s_master'][0]]['join_command'] }}"
      args:
        creates: /etc/kubernetes/kubelet.conf
Enter fullscreen mode Exit fullscreen mode

4. Arquivo roles/k8s_environment/tasks/main.yml

Responsável por configurar o ambiente do Kubernetes:

---
- name: Update apt cache
  ansible.builtin.apt:
    update_cache: yes

- name: Install required packages
  ansible.builtin.apt:
    name:
      - apt-transport-https
      - ca-certificates
      - curl
      - gnupg
      - lsb-release
      - thin-provisioning-tools
      - lvm2
      - bc
    state: present

- name: Install Container runtime
  ansible.builtin.apt:
    name:
      - containerd
    state: present

- name: Enable and start container runtime
  ansible.builtin.systemd:
    name: containerd
    state: started
    enabled: yes

- name: Create Containerd Directory
  ansible.builtin.file:
    path: /etc/containerd
    state: directory
    mode: "0755"

- name: Configure containerd default
  ansible.builtin.shell: |
    mkdir -p /etc/containerd
    containerd config default > /etc/containerd/config.toml
    sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml

- name: Reload containerd
  ansible.builtin.systemd:
    name: containerd
    state: started

- name: Download Kubernetes GPG key
  ansible.builtin.get_url:
    url: https://pkgs.k8s.io/core:/stable:/v1.31/deb/Release.key
    dest: /tmp/kubernetes-release.key

- name: Crege keyring directory
  ansible.builtin.file:
    path: /etc/apt/keyrings
    state: directory

- name: Convert and move Kubernetes GPG key
  ansible.builtin.command:
    cmd: gpg --yes --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg /tmp/kubernetes-release.key

- name: Add Kubernetes repository
  ansible.builtin.lineinfile:
    path: /etc/apt/sources.list.d/kubernetes.list
    line: "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.31/deb/ /"
    create: yes

- name: Update apt cache
  apt:
    update_cache: yes

- name: Install Kubernetes packages
  apt:
    name:
      - kubelet
      - kubeadm
      - kubectl
    state: present

- name: Hold Kubernetes packages
  dpkg_selections:
    name: "{{ item }}"
    selection: hold
  loop:
    - kubelet
    - kubeadm
    - kubectl

- name: Disable swap
  command: swapoff -a
  when: ansible_swaptotal_mb > 0

- name: Remove swap from /etc/fstab
  lineinfile:
    path: /etc/fstab
    regexp: '^[^#].*\sswap\s.*'
    state: absent

- name: Enable kernel modules
  modprobe:
    name: "{{ item }}"
    state: present
  loop:
    - overlay
    - br_netfilter

- name: Add kernel modules to load on boot
  copy:
    dest: /etc/modules-load.d/k8s.conf
    content: |
      overlay
      br_netfilter

- name: Set kernel parameters for Kubernetes
  sysctl:
    name: "{{ item.name }}"
    value: "{{ item.value }}"
    state: present
    reload: yes
  loop:
    - { name: "net.bridge.bridge-nf-call-iptables", value: "1" }
    - { name: "net.bridge.bridge-nf-call-ip6tables", value: "1" }
    - { name: "net.ipv4.ip_forward", value: "1" }

- name: Set extra args for kubelet
  ansible.builtin.lineinfile:
    path: /etc/default/kubelet
    regexp: "^KUBELET_EXTRA_ARGS="
    line: 'KUBELET_EXTRA_ARGS="--cloud-provider=external"'
    state: present
Enter fullscreen mode Exit fullscreen mode

5. Arquivo roles/k8s_bootstrap/tasks/main.yml

Responsável pelo bootstrap do cluster Kubernetes:

---
- name: Get the IP address of the master node
  set_fact:
    advertise_address: "{{ ansible_default_ipv4.address }}"
    # advertise_address: "10.70.191.131"
- name: Initialize Kubernetes cluster
  command: kubeadm init --skip-phases=addon/kube-proxy --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address {{ advertise_address }}
  register: kubeadm_init
  args:
    creates: /etc/kubernetes/admin.conf
- name: Create .kube directory
  file:
    path: /root/.kube
    state: directory
    mode: "0755"
- name: Copy admin.conf to root's kube config
  copy:
    src: /etc/kubernetes/admin.conf
    dest: /root/.kube/config
    remote_src: yes
    owner: root
    group: root
    mode: "0644"
- name: Deploy Calico
  command: kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.29.1/manifests/calico.yaml
- name: Get join command
  command: kubeadm token create --print-join-command
  register: join_command
- name: Store join command
  set_fact:
    join_command: "{{ join_command.stdout }}"
Enter fullscreen mode Exit fullscreen mode

6. Arquivo roles/k8s_firecracker/tasks/main.yml

Configura o Firecracker:

---
- name: Copy Firecracker binary
  copy:
    src: build/firecracker
    dest: /usr/local/bin/firecracker
    mode: "0755"

- name: Create DevMapper directories
  ansible.builtin.file:
    path: /var/lib/containerd/io.containerd.snapshotter.v1.devmapper
    state: directory
    mode: "0755"

- name: Move and set permissions for DevMapper scripts
  copy:
    src: "{{ item.src }}"
    dest: "{{ item.dest }}"
    mode: "0755"
  with_items:
    - {
        src: scripts/devmapper/create.sh,
        dest: /usr/local/bin/devmapper-create.sh,
      }
    - {
        src: scripts/devmapper/reload.sh,
        dest: /usr/local/bin/devmapper-reload.sh,
      }

- name: Run initial DevMapper creation script
  ansible.builtin.command: /usr/local/bin/devmapper-create.sh
  ignore_errors: yes

- name: Containerd Configuration Firecracker
  ansible.builtin.shell: |
    CONFIG_FILE="/etc/containerd/config.toml"
    sudo cp "$CONFIG_FILE" "${CONFIG_FILE}.bak"

    sudo sed -i '/\[plugins."io.containerd.snapshotter.v1.devmapper"\]/,/^$/d' "$CONFIG_FILE"
    sudo sed -i '/\[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.kata-fc\]/,/^$/d' "$CONFIG_FILE"

    cat <<EOF >> /etc/containerd/config.toml
    [plugins."io.containerd.snapshotter.v1.devmapper"]
    pool_name = "devpool"
    root_path = "/var/lib/containerd/io.containerd.snapshotter.v1.devmapper"
    base_image_size = "40GB"

    [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.kata-fc]
    snapshotter = "devmapper"
    runtime_type = "io.containerd.kata-fc.v2"
    EOF

- name: Create DevMapper reload systemd service
  copy:
    dest: /lib/systemd/system/devmapper-reload.service
    content: |
      [Unit]
      Description=Devmapper reload script
      After=network.target

      [Service]
      Type=oneshot
      ExecStart=/usr/local/bin/devmapper-reload.sh
      RemainAfterExit=yes

      [Install]
      WantedBy=multi-user.target

- name: Enable and reload systemd daemon
  systemd:
    name: devmapper-reload.service
    enabled: yes
    daemon_reload: yes

- name: Restart containerd
  systemd:
    name: containerd.service
    state: restarted

Enter fullscreen mode Exit fullscreen mode

7. Arquivo roles/apply_kata/tasks/main.yml

Aplica os manifestos Kata:

---
- name: Install Kata RBAC
  ansible.builtin.command: kubectl apply -f https://raw.githubusercontent.com/kata-containers/kata-containers/main/tools/packaging/kata-deploy/kata-rbac/base/kata-rbac.yaml
- name: Install Kata Deploy
  ansible.builtin.command: kubectl apply -f https://raw.githubusercontent.com/kata-containers/kata-containers/main/tools/packaging/kata-deploy/kata-deploy/base/kata-deploy.yaml
- name: Install Kata Runtime
  ansible.builtin.command: kubectl apply -f https://raw.githubusercontent.com/kata-containers/kata-containers/main/tools/packaging/kata-deploy/runtimeclasses/kata-runtimeClasses.yaml
- name: Install Rke LocalPath
  ansible.builtin.command: kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/v0.0.30/deploy/local-path-storage.yaml
Enter fullscreen mode Exit fullscreen mode

8. Executando o Ansible

Com tudo configurado, execute o seguinte comando para aplicar o playbook:

ansible-playbook -i hosts.yml playbook.yml
Enter fullscreen mode Exit fullscreen mode

  • Estrutura de diretórios: Usamos roles para separar as responsabilidades.
  • Playbook: Importa os roles para configurar diferentes partes do cluster.
  • Hosts: Define os grupos de servidores para os nós mestres e trabalhadores.
  • Execução: O comando ansible-playbook aplica todas as tarefas nos servidores.

Rodando tudo junto

  1. Crie um arquivo make file.
.PHONY: all init plan apply destroy ansible-lint terraform-lint ansible-deploy help

# Directories
TERRAFORM_DIR := terraform
ANSIBLE_DIR := ansible

# Default target
all: init plan apply create-inventory ansible-deploy
    @echo "Complete deployment finished successfully!"

help:
    @echo "Available targets:"
    @echo "  init           - Initialize Terraform"
    @echo "  plan           - Create Terraform plan"
    @echo "  apply          - Apply Terraform changes"
    @echo "  destroy        - Destroy Terraform infrastructure"
    @echo "  create-inventory - Generate Ansible inventory from Terraform outputs"
    @echo "  ansible-lint   - Run Ansible linter"
    @echo "  ansible-deploy - Run Ansible playbook"
    @echo "  terraform-lint - Run Terraform formatting and validation"
    @echo
    @echo "Example usage:"
    @echo "  make all       - Runs init, plan, apply, inventory, and ansible-deploy"

# Terraform targets
init:
    cd $(TERRAFORM_DIR) && terraform init

plan:
    cd $(TERRAFORM_DIR) && terraform plan

apply:
    cd $(TERRAFORM_DIR) && terraform apply -auto-approve

destroy:
    cd $(TERRAFORM_DIR) && terraform destroy -auto-approve

# Generate Ansible inventory
create-inventory:
    cd $(TERRAFORM_DIR) && ./inventory.sh

# Ansible targets
ansible-lint:
    ansible-lint $(ANSIBLE_DIR)/

ansible-deploy:
    ansible-playbook -i $(ANSIBLE_DIR)/hosts.yml $(ANSIBLE_DIR)/playbook.yml

# Terraform linting and validation
terraform-lint:
    cd $(TERRAFORM_DIR) && terraform fmt -check && terraform validate

Enter fullscreen mode Exit fullscreen mode

Este Makefile automatiza o processo de gerenciamento de infraestrutura com Terraform e Ansible, organizando os comandos em alvos específicos para facilitar o uso e manutenção. Aqui está um resumo das principais funcionalidades:

  1. Alvo Principal (all):

    Executa todo o pipeline, incluindo init, plan, apply, criação do inventário (create-inventory) e a execução do playbook Ansible.

  2. Gerenciamento com Terraform:

    • init: Inicializa o Terraform.
    • plan: Gera o plano de execução.
    • apply: Aplica as alterações na infraestrutura.
    • destroy: Destroi a infraestrutura provisionada.
  3. Inventário Dinâmico:

    • create-inventory: Gera o inventário do Ansible com base na saída do Terraform.
  4. Ansible:

    • ansible-lint: Executa o linter para validar os playbooks.
    • ansible-deploy: Executa o playbook principal (playbook.yml).
  5. Linting e Validação de Terraform:

    • terraform-lint: Valida a formatação e os arquivos de configuração do Terraform.
  6. Ajuda (help):

    Exibe os alvos disponíveis e um exemplo de uso.

    Teste

  7. Crie um manifesto para um nginx

  8. Adicione runtimeClassName: kata-fc em specs.

   apiVersion: v1
   kind: Pod
   metadata:
     creationTimestamp: null
     labels:
       run: nginx1
     name: nginx1
   spec:
     runtimeClassName: kata-fc
     containers:
     - image: nginx
       name: nginx1
       resources: {}
     dnsPolicy: ClusterFirst
     restartPolicy: Always
   status: {}
Enter fullscreen mode Exit fullscreen mode
  1. Verifique a versão do kernel do container
   $ k exec -it nginx1 -- bash -c "uname -a"
   Linux nginx1 6.1.62 #1 SMP Fri Nov 15 11:22:02 UTC 2024 x86_64 GNU/Linux
Enter fullscreen mode Exit fullscreen mode
  1. E o kernel do host
   root@k8s-master-1:~# uname -a
    Linux k8s-master-1 6.8.0-49-generic #49-Ubuntu SMP PREEMPT_DYNAMIC Mon      Nov  4 02:06:24 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
Enter fullscreen mode Exit fullscreen mode

Referências

Repositório do Projeto
Aws Firecracker Kata Containers

Top comments (0)