25 Implantações air-gapped com o Edge Image Builder #
25.1 Intro #
Este guia mostrará como implantar vários dos componentes SUSE Edge de forma totalmente air-gapped no SUSE Linux Micro 6.2 utilizando o Edge Image Builder(EIB) (Chapter 8, Edge Image Builder). Com isso, você poderá inicializar em uma imagem personalizada e pronta para inicializar (CRB) criada pelo EIB e ter os componentes especificados implantados em um cluster RKE2 ou K3s sem uma conexão com a Internet ou quaisquer etapas manuais. Esta configuração é altamente desejável para clientes que desejam pré-incorporar todos os artefatos necessários para a implantação em sua imagem do SO, de modo que fiquem imediatamente disponíveis na inicialização.
Abordaremos uma instalação air-gapped de:
O EIB analisará e fará o pré-download de todas as imagens referenciadas nos Helm charts e manifestos do Kubernetes fornecidos. No entanto, algumas delas podem estar tentando baixar imagens de contêiner e criar recursos do Kubernetes com base nelas em tempo de execução. Nestes casos, temos que especificar manualmente as imagens necessárias no arquivo de definição se quisermos configurar um ambiente completamente air-gapped.
25.2 Pré-requisitos #
Se você está seguindo este guia, presume-se que você já esteja familiarizado com o EIB (Chapter 8, Edge Image Builder). Caso contrário, siga o guia de início rápido (Chapter 2, Clusters autônomos com o Edge Image Builder) para entender melhor os conceitos mostrados na prática abaixo.
25.3 Configuração de rede Libvirt #
Para demonstrar a implantação air-gapped, este guia será feito usando uma rede libvirt air-gapped simulada e a seguinte configuração será adaptada para isso. Para suas próprias implantações, você pode ter que modificar a configuração host1.local.yaml que será apresentada na próxima etapa.
Se você quiser usar a mesma configuração de rede libvirt, siga as instruções. Se não quiser, vá para Section 25.4, “Configuração do diretório de base”.
Vamos criar uma configuração de rede isolada com um intervalo de endereços IP 192.168.100.2/24 para DHCP:
cat << EOF > isolatednetwork.xml
<network>
<name>isolatednetwork</name>
<bridge name='virbr1' stp='on' delay='0'/>
<ip address='192.168.100.1' netmask='255.255.255.0'>
<dhcp>
<range start='192.168.100.2' end='192.168.100.254'/>
</dhcp>
</ip>
</network>
EOFAgora, a única coisa que resta é criar a rede e iniciá-la:
virsh net-define isolatednetwork.xml
virsh net-start isolatednetwork25.4 Configuração do diretório de base #
A configuração do diretório de base é a mesma em todos os diferentes componentes, então vamos configurá-la aqui.
Primeiro, criaremos os subdiretórios necessários:
export CONFIG_DIR=$HOME/config
mkdir -p $CONFIG_DIR/base-images
mkdir -p $CONFIG_DIR/network
mkdir -p $CONFIG_DIR/kubernetes/helm/valuesCertifique-se de adicionar qualquer imagem base que você planeja usar no diretório base-images. Este guia focará na ISO de auto-instalação encontrada aqui.
Vamos copiar a imagem baixada:
cp SL-Micro.x86_64-6.2-Base-SelfInstall-GM.install.iso $CONFIG_DIR/base-images/slemicro.isoO EIB nunca modificará a entrada da imagem base.
Vamos criar um arquivo contendo a configuração de rede desejada:
cat << EOF > $CONFIG_DIR/network/host1.local.yaml
routes:
config:
- destination: 0.0.0.0/0
metric: 100
next-hop-address: 192.168.100.1
next-hop-interface: eth0
table-id: 254
- destination: 192.168.100.0/24
metric: 100
next-hop-address: 192.168.122.1
next-hop-interface: eth0
table-id: 254
dns-resolver:
config:
server:
- 192.168.100.1
- 8.8.8.8
interfaces:
- name: eth0
type: ethernet
state: up
mac-address: 34:8A:B1:4B:16:E7
ipv4:
address:
- ip: 192.168.100.50
prefix-length: 24
dhcp: false
enabled: true
ipv6:
enabled: false
EOFEsta configuração garante que os seguintes estejam presentes nos sistemas provisionados (usando o endereço MAC especificado):
uma interface Ethernet com um endereço IP estático
roteamento
DNS
hostname (
host1.local)
A estrutura de arquivos resultante deve ficar assim:
├── kubernetes/
│ └── helm/
│ └── values/
├── base-images/
│ └── slemicro.iso
└── network/
└── host1.local.yaml25.5 Arquivo de definição de base #
O Edge Image Builder está usando arquivos de definição para modificar as imagens do SUSE Linux Micro. Esses arquivos contêm a maioria das opções configuráveis. Muitas dessas opções serão repetidas nas diferentes seções de componentes, portanto, listaremos e explicaremos essas aqui.
A lista completa de opções de personalização no arquivo de definição pode ser encontrada na documentação upstream
Daremos uma olhada nos seguintes campos que estarão presentes em todos os arquivos de definição:
apiVersion: 1.3
image:
imageType: iso
arch: x86_64
baseImage: slemicro.iso
outputImageName: eib-image.iso
operatingSystem:
users:
- username: root
encryptedPassword: $6$jHugJNNd3HElGsUZ$eodjVe4te5ps44SVcWshdfWizrP.xAyd71CVEXazBJ/.v799/WRCBXxfYmunlBO2yp1hm/zb4r8EmnrrNCF.P/
kubernetes:
version: v1.35.4+rke2r1
embeddedArtifactRegistry:
images:
- ...A seção image é obrigatória e especifica a imagem de entrada, sua arquitetura e tipo, bem como a imagem de saída será chamada.
A seção operatingSystem é opcional e contém a configuração para habilitar o login nos sistemas provisionados com o nome de usuário/senha root/eib.
A seção kubernetes é opcional e define o tipo e a versão do Kubernetes. Vamos usar a distribuição RKE2. Use kubernetes.version: v1.35.4+k3s1 se o K3s for desejado. A menos que configurado explicitamente através do campo kubernetes.nodes, todos os clusters que inicializarmos neste guia serão de nó único.
A seção embeddedArtifactRegistry incluirá todas as imagens que são apenas referenciadas e baixadas em tempo de execução para o componente específico.
25.6 Instalação do Rancher #
A implantação do Rancher (Chapter 4, Rancher) que será demonstrada será bastante reduzida para fins de demonstração. Para suas implantações reais, artefatos adicionais podem ser necessários, dependendo da sua configuração.
Os ativos de lançamento do Rancher 2.14.2 contêm um arquivo rancher-images.txt que lista todas as imagens necessárias para uma instalação air-gapped.
Há mais de 600 imagens de contêiner no total, o que significa que a imagem CRB resultante teria aproximadamente 30 GB. Para nossa instalação do Rancher, reduziremos essa lista para a menor configuração funcional. A partir daí, você pode adicionar novamente quaisquer imagens que possa precisar para suas implantações.
Criaremos o arquivo de definição e incluiremos a lista de imagens reduzida:
apiVersion: 1.3
image:
imageType: iso
arch: x86_64
baseImage: slemicro.iso
outputImageName: eib-image.iso
operatingSystem:
users:
- username: root
encryptedPassword: $6$jHugJNNd3HElGsUZ$eodjVe4te5ps44SVcWshdfWizrP.xAyd71CVEXazBJ/.v799/WRCBXxfYmunlBO2yp1hm/zb4r8EmnrrNCF.P/
kubernetes:
version: v1.35.4+rke2r1
manifests:
urls:
- https://github.com/cert-manager/cert-manager/releases/download/v1.15.3/cert-manager.crds.yaml
helm:
charts:
- name: rancher
version: 2.14.2
repositoryName: rancher-prime
valuesFile: rancher-values.yaml
targetNamespace: cattle-system
createNamespace: true
installationNamespace: kube-system
- name: cert-manager
installationNamespace: kube-system
createNamespace: true
repositoryName: jetstack
targetNamespace: cert-manager
version: 1.20.1
repositories:
- name: jetstack
url: https://charts.jetstack.io
- name: rancher-prime
url: https://charts.rancher.com/server-charts/prime
embeddedArtifactRegistry:
images:
- name: registry.rancher.com/rancher/backup-restore-operator:v10.0.2
- name: registry.rancher.com/rancher/compliance-operator:v1.4.1
- name: registry.rancher.com/rancher/fleet-agent:v0.15.2
- name: registry.rancher.com/rancher/fleet:v0.15.2
- name: registry.rancher.com/rancher/hardened-addon-resizer:1.8.23-build20260413
- name: registry.rancher.com/rancher/hardened-calico:v3.31.5-build20260415
- name: registry.rancher.com/rancher/hardened-cluster-autoscaler:v1.10.3-build20260414
- name: registry.rancher.com/rancher/hardened-cni-plugins:v1.9.1-build20260415
- name: registry.rancher.com/rancher/hardened-coredns:v1.14.2-build20260416
- name: registry.rancher.com/rancher/hardened-dns-node-cache:1.26.8-build20260416
- name: registry.rancher.com/rancher/hardened-etcd:v3.6.7-k3s1-build20260415
- name: registry.rancher.com/rancher/hardened-flannel:v0.28.4-build20260415
- name: registry.rancher.com/rancher/hardened-k8s-metrics-server:v0.8.1-build20260413
- name: registry.rancher.com/rancher/hardened-kubernetes:v1.35.4-rke2r1-build20260416
- name: registry.rancher.com/rancher/hardened-multus-cni:v4.2.4-build20260310
- name: registry.rancher.com/rancher/hardened-multus-dynamic-networks-controller:v0.3.7-build20260310
- name: registry.rancher.com/rancher/hardened-multus-thick:v4.2.4-build20260310
- name: registry.rancher.com/rancher/hardened-traefik:v3.6.13-build20260416
- name: registry.rancher.com/rancher/hardened-whereabouts:v0.9.3-build20260408
- name: registry.rancher.com/rancher/k3s-upgrade:v1.35.4-k3s1
- name: registry.rancher.com/rancher/klipper-helm:v0.9.17-build20260422
- name: registry.rancher.com/rancher/klipper-lb:v0.4.16
- name: registry.rancher.com/rancher/kubectl:v1.35.2
- name: registry.rancher.com/rancher/kuberlr-kubectl:v7.0.3
- name: registry.rancher.com/rancher/local-path-provisioner:v0.0.35
- name: registry.rancher.com/rancher/machine:v0.15.0-rancher142
- name: registry.rancher.com/rancher/nginx-ingress-controller:v1.14.5-hardened2
- name: registry.rancher.com/rancher/prom-prometheus:v3.8.1
- name: registry.rancher.com/rancher/prometheus-federator:v6.0.0
- name: registry.rancher.com/rancher/pushprox:v0.1.10
- name: registry.rancher.com/rancher/rancher-agent:v2.14.2
- name: registry.rancher.com/rancher/rancher-csp-adapter:v9.0.0
- name: registry.rancher.com/rancher/rancher-webhook:v0.10.6
- name: registry.rancher.com/rancher/rancher:v2.14.2
- name: registry.rancher.com/rancher/remotedialer-proxy:v0.7.2
- name: registry.rancher.com/rancher/rke2-cloud-provider:v1.35.4-0.20260415195656-e51c0636351d-build20260415
- name: registry.rancher.com/rancher/rke2-runtime:v1.35.4-rke2r1
- name: registry.rancher.com/rancher/rke2-upgrade:v1.35.4-rke2r1
- name: registry.rancher.com/rancher/scc-operator:v0.4.1
- name: registry.rancher.com/rancher/security-scan:v0.9.1
- name: registry.rancher.com/rancher/shell:v0.1.24
- name: registry.rancher.com/rancher/supportability-review-app-frontend:v0.19.0
- name: registry.rancher.com/rancher/supportability-review-internal:latest
- name: registry.rancher.com/rancher/supportability-review-operator:v0.19.0
- name: registry.rancher.com/rancher/supportability-review:latest
- name: registry.rancher.com/rancher/system-agent-installer-k3s:v1.35.4-k3s1
- name: registry.rancher.com/rancher/system-agent-installer-rke2:v1.35.4-rke2r1
- name: registry.rancher.com/rancher/system-agent:v0.3.16-suc
- name: registry.rancher.com/rancher/system-upgrade-controller:v0.19.1
- name: registry.rancher.com/rancher/turtles:v0.26.2
- name: registry.rancher.com/rancher/ui-plugin-catalog:4.15.0
- name: registry.rancher.com/rancher/kubectl:v1.20.2
- name: registry.rancher.com/rancher/mirrored-ingress-nginx-kube-webhook-certgen:v1.6.7Em comparação com a lista completa de mais de 600 imagens de contêiner, esta versão reduzida contém apenas ~60, o que torna a nova imagem CRB com apenas cerca de 7 GB.
Também precisamos criar um arquivo de valores Helm para o Rancher:
cat << EOF > $CONFIG_DIR/kubernetes/helm/values/rancher-values.yaml
hostname: 192.168.100.50.sslip.io
replicas: 1
bootstrapPassword: "adminadminadmin"
systemDefaultRegistry: registry.rancher.com
useBundledSystemChart: true
EOFDefinir systemDefaultRegistry como registry.rancher.com permite que o Rancher procure automaticamente por imagens no registro de artefatos incorporado iniciado dentro da imagem CRB na inicialização. A omissão deste campo pode resultar em falha ao encontrar as imagens de contêiner no nó.
Vamos criar a imagem:
podman run --rm -it --privileged -v $CONFIG_DIR:/eib \
registry.suse.com/edge/3.6/edge-image-builder:1.3.3.1 \
build --definition-file eib-iso-definition.yamlA saída deve ser similar ao seguinte:
Downloading file: dl-manifest-1.yaml 100% |██████████████████████████████████████████████████████████████████████████████| (583/583 kB, 12 MB/s)
Pulling selected Helm charts... 100% |███████████████████████████████████████████████████████████████████████████████████████████| (2/2, 3 it/s)
Generating image customization components...
Identifier ................... [SUCCESS]
Custom Files ................. [SKIPPED]
Time ......................... [SKIPPED]
Network ...................... [SUCCESS]
Groups ....................... [SKIPPED]
Users ........................ [SUCCESS]
Proxy ........................ [SKIPPED]
Rpm .......................... [SKIPPED]
Os Files ..................... [SKIPPED]
Systemd ...................... [SKIPPED]
Fips ......................... [SKIPPED]
Elemental .................... [SKIPPED]
Suma ......................... [SKIPPED]
Populating Embedded Artifact Registry... 100% |███████████████████████████████████████████████████████████████████████████| (56/56, 8 it/min)
Embedded Artifact Registry ... [SUCCESS]
Keymap ....................... [SUCCESS]
Configuring Kubernetes component...
The Kubernetes CNI is not explicitly set, defaulting to 'cilium'.
Downloading file: rke2_installer.sh
Downloading file: rke2-images-core.linux-amd64.tar.zst 100% |███████████████████████████████████████████████████████████| (644/644 MB, 29 MB/s)
Downloading file: rke2-images-cilium.linux-amd64.tar.zst 100% |█████████████████████████████████████████████████████████| (400/400 MB, 29 MB/s)
Downloading file: rke2.linux-amd64.tar.gz 100% |███████████████████████████████████████████████████████████████████████████| (36/36 MB, 30 MB/s)
Downloading file: sha256sum-amd64.txt 100% |█████████████████████████████████████████████████████████████████████████████| (4.3/4.3 kB, 29 MB/s)
Kubernetes ................... [SUCCESS]
Certificates ................. [SKIPPED]
Cleanup ...................... [SKIPPED]
Building ISO image...
Kernel Params ................ [SKIPPED]
Build complete, the image can be found at: eib-image.isoUma vez que um nó usando a imagem criada seja provisionado, podemos verificar a instalação do Rancher:
/var/lib/rancher/rke2/bin/kubectl get all -n cattle-system --kubeconfig /etc/rancher/rke2/rke2.yamlA saída deve ser semelhante à seguinte, mostrando que tudo foi implantado com sucesso:
NAME READY STATUS RESTARTS AGE
pod/helm-operation-6l6ld 0/2 Completed 0 107s
pod/helm-operation-8tk2v 0/2 Completed 0 2m2s
pod/helm-operation-blnrr 0/2 Completed 0 2m49s
pod/helm-operation-hdcmt 0/2 Completed 0 3m19s
pod/helm-operation-m74c7 0/2 Completed 0 97s
pod/helm-operation-qzzr4 0/2 Completed 0 2m30s
pod/helm-operation-s9jh5 0/2 Completed 0 3m
pod/helm-operation-tq7ts 0/2 Completed 0 2m41s
pod/rancher-99d599967-ftjkk 1/1 Running 0 4m15s
pod/rancher-webhook-79798674c5-6w28t 1/1 Running 0 2m27s
pod/system-upgrade-controller-56696956b-trq5c 1/1 Running 0 104s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/rancher ClusterIP 10.43.255.80 <none> 80/TCP,443/TCP 4m15s
service/rancher-webhook ClusterIP 10.43.7.238 <none> 443/TCP 2m27s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/rancher 1/1 1 1 4m15s
deployment.apps/rancher-webhook 1/1 1 1 2m27s
deployment.apps/system-upgrade-controller 1/1 1 1 104s
NAME DESIRED CURRENT READY AGE
replicaset.apps/rancher-99d599967 1 1 1 4m15s
replicaset.apps/rancher-webhook-79798674c5 1 1 1 2m27s
replicaset.apps/system-upgrade-controller-56696956b 1 1 1 104sE quando vamos para https://192.168.100.50.sslip.io e fazemos login com a senha adminadminadmin que definimos anteriormente, somos recebidos com o painel do Rancher:
25.7 Instalação do SUSE Security #
Ao contrário da instalação do Rancher, a instalação do SUSE Security não requer nenhum tratamento especial no EIB. O EIB fará automaticamente o air-gap de cada imagem necessária pelo seu componente subjacente NeuVector.
Criaremos o arquivo de definição:
apiVersion: 1.3
image:
imageType: iso
arch: x86_64
baseImage: slemicro.iso
outputImageName: eib-image.iso
operatingSystem:
users:
- username: root
encryptedPassword: $6$jHugJNNd3HElGsUZ$eodjVe4te5ps44SVcWshdfWizrP.xAyd71CVEXazBJ/.v799/WRCBXxfYmunlBO2yp1hm/zb4r8EmnrrNCF.P/
kubernetes:
version: v1.35.4+rke2r1
helm:
charts:
- name: neuvector-crd
version: 109.0.2+up2.10.2
repositoryName: rancher-charts
targetNamespace: neuvector
createNamespace: true
installationNamespace: kube-system
valuesFile: neuvector-values.yaml
- name: neuvector
version: 109.0.2+up2.10.2
repositoryName: rancher-charts
targetNamespace: neuvector
createNamespace: true
installationNamespace: kube-system
valuesFile: neuvector-values.yaml
repositories:
- name: rancher-charts
url: https://charts.rancher.io/Também criaremos um arquivo de valores Helm para o NeuVector:
cat << EOF > $CONFIG_DIR/kubernetes/helm/values/neuvector-values.yaml
controller:
replicas: 1
manager:
enabled: false
cve:
scanner:
enabled: false
replicas: 1
k3s:
enabled: true
crdwebhook:
enabled: false
EOFVamos criar a imagem:
podman run --rm -it --privileged -v $CONFIG_DIR:/eib \
registry.suse.com/edge/3.6/edge-image-builder:1.3.3.1 \
build --definition-file eib-iso-definition.yamlA saída deve ser similar ao seguinte:
Pulling selected Helm charts... 100% |███████████████████████████████████████████████████████████████████████████████████████████| (2/2, 4 it/s)
Generating image customization components...
Identifier ................... [SUCCESS]
Custom Files ................. [SKIPPED]
Time ......................... [SKIPPED]
Network ...................... [SUCCESS]
Groups ....................... [SKIPPED]
Users ........................ [SUCCESS]
Proxy ........................ [SKIPPED]
Rpm .......................... [SKIPPED]
Os Files ..................... [SKIPPED]
Systemd ...................... [SKIPPED]
Fips ......................... [SKIPPED]
Elemental .................... [SKIPPED]
Suma ......................... [SKIPPED]
Populating Embedded Artifact Registry... 100% |██████████████████████████████████████████████████████████████████████████████| (5/5, 13 it/min)
Embedded Artifact Registry ... [SUCCESS]
Keymap ....................... [SUCCESS]
Configuring Kubernetes component...
The Kubernetes CNI is not explicitly set, defaulting to 'cilium'.
Downloading file: rke2_installer.sh
Kubernetes ................... [SUCCESS]
Certificates ................. [SKIPPED]
Cleanup ...................... [SKIPPED]
Building ISO image...
Kernel Params ................ [SKIPPED]
Build complete, the image can be found at: eib-image.isoUma vez que um nó usando a imagem criada seja provisionado, podemos verificar a instalação do SUSE Security:
/var/lib/rancher/rke2/bin/kubectl get all -n neuvector --kubeconfig /etc/rancher/rke2/rke2.yamlA saída deve ser semelhante à seguinte, mostrando que tudo foi implantado com sucesso:
NAME READY STATUS RESTARTS AGE
pod/neuvector-cert-upgrader-job-bxbnz 0/1 Completed 0 3m39s
pod/neuvector-controller-pod-7d854bfdc7-nhxjf 1/1 Running 0 3m44s
pod/neuvector-enforcer-pod-ct8jm 1/1 Running 0 3m44s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/neuvector-svc-admission-webhook ClusterIP 10.43.234.241 <none> 443/TCP 3m44s
service/neuvector-svc-controller ClusterIP None <none> 18300/TCP,18301/TCP,18301/UDP 3m44s
service/neuvector-svc-crd-webhook ClusterIP 10.43.50.190 <none> 443/TCP 3m44s
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
daemonset.apps/neuvector-enforcer-pod 1 1 1 1 1 <none> 3m44s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/neuvector-controller-pod 1/1 1 1 3m44s
NAME DESIRED CURRENT READY AGE
replicaset.apps/neuvector-controller-pod-7d854bfdc7 1 1 1 3m44s
NAME SCHEDULE TIMEZONE SUSPEND ACTIVE LAST SCHEDULE AGE
cronjob.batch/neuvector-cert-upgrader-pod 0 0 1 1 * <none> True 0 <none> 3m44s
cronjob.batch/neuvector-updater-pod 0 0 * * * <none> False 0 <none> 3m44s
NAME STATUS COMPLETIONS DURATION AGE
job.batch/neuvector-cert-upgrader-job Complete 1/1 7s 3m39s25.8 Instalação do SUSE Storage #
A documentação oficial do Longhorn contém um arquivo longhorn-images.txt que lista todas as imagens necessárias para uma instalação air-gapped.
Incluiremos suas contrapartes espelhadas do registro de contêineres do Rancher em nosso arquivo de definição.
Vamos criá-lo:
apiVersion: 1.3
image:
imageType: iso
arch: x86_64
baseImage: slemicro.iso
outputImageName: eib-image.iso
operatingSystem:
users:
- username: root
encryptedPassword: $6$jHugJNNd3HElGsUZ$eodjVe4te5ps44SVcWshdfWizrP.xAyd71CVEXazBJ/.v799/WRCBXxfYmunlBO2yp1hm/zb4r8EmnrrNCF.P/
packages:
sccRegistrationCode: [reg-code]
packageList:
- open-iscsi
kubernetes:
version: v1.35.4+rke2r1
helm:
charts:
- name: suse-storage
releaseName: longhorn
repositoryName: rancher-application-collection
targetNamespace: longhorn-system
createNamespace: true
version: 1.11.2
repositories:
- name: rancher-application-collection
url: oci://dp.apps.rancher.io/charts
authentication:
username: $APPS.RANCHER.IO_USERNAME
password: $APPS.RANCHER.IO_ACCESS_TOKEN
embeddedArtifactRegistry:
registries:
- uri: dp.apps.rancher.io
authentication:
username: $APPS.RANCHER.IO_USERNAME
password: $APPS.RANCHER.IO_ACCESS_TOKEN
- name: dp.apps.rancher.io/containers/kubernetes-csi-external-attacher:4.11.0-13.2
- name: dp.apps.rancher.io/containers/kubernetes-csi-external-provisioner:5.3.0-14.1
- name: dp.apps.rancher.io/containers/kubernetes-csi-external-resizer:2.1.0-6.2
- name: dp.apps.rancher.io/containers/kubernetes-csi-external-snapshotter:8.5.0-13.2
- name: dp.apps.rancher.io/containers/kubernetes-csi-livenessprobe:2.18.0-13.2
- name: dp.apps.rancher.io/containers/kubernetes-csi-node-driver-registrar:2.16.0-13.2
- name: dp.apps.rancher.io/containers/longhorn-backing-image-manager:1.11.2-4.1
- name: dp.apps.rancher.io/containers/longhorn-engine:1.11.2-4.2
- name: dp.apps.rancher.io/containers/longhorn-instance-manager:1.11.2-4.3
- name: dp.apps.rancher.io/containers/longhorn-manager:1.11.2-4.2
- name: dp.apps.rancher.io/containers/longhorn-share-manager:1.11.2-4.1
- name: dp.apps.rancher.io/containers/longhorn-ui:1.11.2-4.1
- name: dp.apps.rancher.io/containers/rancher-support-bundle-kit:0.0.84-9.4Você notará que o arquivo de definição lista o pacote open-iscsi. Isso é necessário, já que o Longhorn depende de um daemon iscsiadm sendo executado nos diferentes nós para fornecer volumes persistentes ao Kubernetes.
Vamos criar a imagem:
podman run --rm -it --privileged -v $CONFIG_DIR:/eib \
registry.suse.com/edge/3.6/edge-image-builder:1.3.3.1 \
build --definition-file eib-iso-definition.yamlA saída deve ser similar ao seguinte:
Setting up Podman API listener...
Pulling selected Helm charts... 100% |██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| (2/2, 3 it/s)
Generating image customization components...
Identifier ................... [SUCCESS]
Custom Files ................. [SKIPPED]
Time ......................... [SKIPPED]
Network ...................... [SUCCESS]
Groups ....................... [SKIPPED]
Users ........................ [SUCCESS]
Proxy ........................ [SKIPPED]
Resolving package dependencies...
Rpm .......................... [SUCCESS]
Os Files ..................... [SKIPPED]
Systemd ...................... [SKIPPED]
Fips ......................... [SKIPPED]
Elemental .................... [SKIPPED]
Suma ......................... [SKIPPED]
Populating Embedded Artifact Registry... 100% |███████████████████████████████████████████████████████████████████████████████████████████████████████████| (15/15, 20956 it/s)
Embedded Artifact Registry ... [SUCCESS]
Keymap ....................... [SUCCESS]
Configuring Kubernetes component...
The Kubernetes CNI is not explicitly set, defaulting to 'cilium'.
Downloading file: rke2_installer.sh
Downloading file: rke2-images-core.linux-amd64.tar.zst 100% (782/782 MB, 108 MB/s)
Downloading file: rke2-images-cilium.linux-amd64.tar.zst 100% (367/367 MB, 104 MB/s)
Downloading file: rke2.linux-amd64.tar.gz 100% (34/34 MB, 108 MB/s)
Downloading file: sha256sum-amd64.txt 100% (3.9/3.9 kB, 7.5 MB/s)
Kubernetes ................... [SUCCESS]
Certificates ................. [SKIPPED]
Cleanup ...................... [SKIPPED]
Building ISO image...
Kernel Params ................ [SKIPPED]
Build complete, the image can be found at: eib-image.isoUma vez que um nó usando a imagem criada seja provisionado, podemos verificar a instalação do Longhorn:
/var/lib/rancher/rke2/bin/kubectl get all -n longhorn-system --kubeconfig /etc/rancher/rke2/rke2.yamlA saída deve ser semelhante à seguinte, mostrando que tudo foi implantado com sucesso:
NAME READY STATUS RESTARTS AGE
pod/csi-attacher-787fd9c6c8-sf42d 1/1 Running 0 2m28s
pod/csi-attacher-787fd9c6c8-tb82p 1/1 Running 0 2m28s
pod/csi-attacher-787fd9c6c8-zhc6s 1/1 Running 0 2m28s
pod/csi-provisioner-74486b95c6-b2v9s 1/1 Running 0 2m28s
pod/csi-provisioner-74486b95c6-hwllt 1/1 Running 0 2m28s
pod/csi-provisioner-74486b95c6-mlrpk 1/1 Running 0 2m28s
pod/csi-resizer-859d4557fd-t54zk 1/1 Running 0 2m28s
pod/csi-resizer-859d4557fd-vdt5d 1/1 Running 0 2m28s
pod/csi-resizer-859d4557fd-x9kh4 1/1 Running 0 2m28s
pod/csi-snapshotter-6f69c6c8cc-r62gr 1/1 Running 0 2m28s
pod/csi-snapshotter-6f69c6c8cc-vrwjn 1/1 Running 0 2m28s
pod/csi-snapshotter-6f69c6c8cc-z65nb 1/1 Running 0 2m28s
pod/engine-image-ei-4623b511-9vhkb 1/1 Running 0 3m13s
pod/instance-manager-6f95fd57d4a4cd0459e469d75a300552 1/1 Running 0 2m43s
pod/longhorn-csi-plugin-gx98x 3/3 Running 0 2m28s
pod/longhorn-driver-deployer-55f9c88499-fbm6q 1/1 Running 0 3m28s
pod/longhorn-manager-dpdp7 2/2 Running 0 3m28s
pod/longhorn-ui-59c85fcf94-gg5hq 1/1 Running 0 3m28s
pod/longhorn-ui-59c85fcf94-s49jc 1/1 Running 0 3m28s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/longhorn-admission-webhook ClusterIP 10.43.77.89 <none> 9502/TCP 3m28s
service/longhorn-backend ClusterIP 10.43.56.17 <none> 9500/TCP 3m28s
service/longhorn-conversion-webhook ClusterIP 10.43.54.73 <none> 9501/TCP 3m28s
service/longhorn-frontend ClusterIP 10.43.22.82 <none> 80/TCP 3m28s
service/longhorn-recovery-backend ClusterIP 10.43.45.143 <none> 9503/TCP 3m28s
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
daemonset.apps/engine-image-ei-4623b511 1 1 1 1 1 <none> 3m13s
daemonset.apps/longhorn-csi-plugin 1 1 1 1 1 <none> 2m28s
daemonset.apps/longhorn-manager 1 1 1 1 1 <none> 3m28s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/csi-attacher 3/3 3 3 2m28s
deployment.apps/csi-provisioner 3/3 3 3 2m28s
deployment.apps/csi-resizer 3/3 3 3 2m28s
deployment.apps/csi-snapshotter 3/3 3 3 2m28s
deployment.apps/longhorn-driver-deployer 1/1 1 1 3m28s
deployment.apps/longhorn-ui 2/2 2 2 3m28s
NAME DESIRED CURRENT READY AGE
replicaset.apps/csi-attacher-787fd9c6c8 3 3 3 2m28s
replicaset.apps/csi-provisioner-74486b95c6 3 3 3 2m28s
replicaset.apps/csi-resizer-859d4557fd 3 3 3 2m28s
replicaset.apps/csi-snapshotter-6f69c6c8cc 3 3 3 2m28s
replicaset.apps/longhorn-driver-deployer-55f9c88499 1 1 1 3m28s
replicaset.apps/longhorn-ui-59c85fcf94 2 2 2 3m28s25.9 Instalação do KubeVirt e CDI #
Os gráficos Helm para KubeVirt e CDI instalam apenas seus respectivos operadores. Cabe aos operadores implantar o restante dos sistemas, o que significa que teremos que incluir todas as imagens de contêiner necessárias em nosso arquivo de definição. Vamos criá-lo:
apiVersion: 1.3
image:
imageType: iso
arch: x86_64
baseImage: slemicro.iso
outputImageName: eib-image.iso
operatingSystem:
users:
- username: root
encryptedPassword: $6$jHugJNNd3HElGsUZ$eodjVe4te5ps44SVcWshdfWizrP.xAyd71CVEXazBJ/.v799/WRCBXxfYmunlBO2yp1hm/zb4r8EmnrrNCF.P/
kubernetes:
version: v1.35.4+rke2r1
helm:
charts:
- name: kubevirt
repositoryName: suse-edge
version: 306.0.2+up0.7.0
targetNamespace: kubevirt-system
createNamespace: true
installationNamespace: kube-system
- name: cdi
repositoryName: suse-edge
version: 306.0.2+up0.7.0
targetNamespace: cdi-system
createNamespace: true
installationNamespace: kube-system
repositories:
- name: suse-edge
url: oci://registry.suse.com/edge/charts
embeddedArtifactRegistry:
images:
- name: registry.suse.com/suse/sles/15.7/cdi-apiserver:1.64.0-150700.9.6.1
- name: registry.suse.com/suse/sles/15.7/cdi-controller:1.64.0-150700.9.6.1
- name: registry.suse.com/suse/sles/15.7/cdi-operator:1.64.0-150700.9.6.1
- name: registry.suse.com/suse/sles/15.7/cdi-uploadproxy:1.64.0-150700.9.6.1
- name: registry.suse.com/suse/sles/15.7/virt-api:1.7.0-150700.3.16.2
- name: registry.suse.com/suse/sles/15.7/virt-controller:1.7.0-150700.3.16.2
- name: registry.suse.com/suse/sles/15.7/virt-handler:1.7.0-150700.3.16.2
- name: registry.suse.com/suse/sles/15.7/virt-launcher:1.7.0-150700.3.16.2
- name: registry.suse.com/suse/sles/15.7/virt-operator:1.7.0-150700.3.16.2Vamos criar a imagem:
podman run --rm -it --privileged -v $CONFIG_DIR:/eib \
registry.suse.com/edge/3.6/edge-image-builder:1.3.3.1 \
build --definition-file eib-iso-definition.yamlA saída deve ser similar ao seguinte:
Pulling selected Helm charts... 100% |███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| (2/2, 48 it/min)
Generating image customization components...
Identifier ................... [SUCCESS]
Custom Files ................. [SKIPPED]
Time ......................... [SKIPPED]
Network ...................... [SUCCESS]
Groups ....................... [SKIPPED]
Users ........................ [SUCCESS]
Proxy ........................ [SKIPPED]
Rpm .......................... [SKIPPED]
Os Files ..................... [SKIPPED]
Systemd ...................... [SKIPPED]
Fips ......................... [SKIPPED]
Elemental .................... [SKIPPED]
Suma ......................... [SKIPPED]
Populating Embedded Artifact Registry... 100% |██████████████████████████████████████████████████████████████████████████████████████████████████████████| (15/15, 4 it/min)
Embedded Artifact Registry ... [SUCCESS]
Keymap ....................... [SUCCESS]
Configuring Kubernetes component...
The Kubernetes CNI is not explicitly set, defaulting to 'cilium'.
Downloading file: rke2_installer.sh
Kubernetes ................... [SUCCESS]
Certificates ................. [SKIPPED]
Cleanup ...................... [SKIPPED]
Building ISO image...
Kernel Params ................ [SKIPPED]
Build complete, the image can be found at: eib-image.isoUma vez que um nó usando a imagem criada seja provisionado, podemos verificar a instalação do KubeVirt e do CDI.
Verify KubeVirt:
/var/lib/rancher/rke2/bin/kubectl get all -n kubevirt-system --kubeconfig /etc/rancher/rke2/rke2.yamlA saída deve ser semelhante à seguinte, mostrando que tudo foi implantado com sucesso:
NAME READY STATUS RESTARTS AGE
pod/virt-api-59cb997648-mmt67 1/1 Running 0 2m34s
pod/virt-controller-69786b785-7cc96 1/1 Running 0 2m8s
pod/virt-controller-69786b785-wq2dz 1/1 Running 0 2m8s
pod/virt-handler-2l4dm 1/1 Running 0 2m8s
pod/virt-operator-7c444cff46-nps4l 1/1 Running 0 3m1s
pod/virt-operator-7c444cff46-r25xq 1/1 Running 0 3m1s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubevirt-operator-webhook ClusterIP 10.43.167.109 <none> 443/TCP 2m36s
service/kubevirt-prometheus-metrics ClusterIP None <none> 443/TCP 2m36s
service/virt-api ClusterIP 10.43.18.202 <none> 443/TCP 2m36s
service/virt-exportproxy ClusterIP 10.43.142.188 <none> 443/TCP 2m36s
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
daemonset.apps/virt-handler 1 1 1 1 1 kubernetes.io/os=linux 2m8s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/virt-api 1/1 1 1 2m34s
deployment.apps/virt-controller 2/2 2 2 2m8s
deployment.apps/virt-operator 2/2 2 2 3m1s
NAME DESIRED CURRENT READY AGE
replicaset.apps/virt-api-59cb997648 1 1 1 2m34s
replicaset.apps/virt-controller-69786b785 2 2 2 2m8s
replicaset.apps/virt-operator-7c444cff46 2 2 2 3m1s
NAME AGE PHASE
kubevirt.kubevirt.io/kubevirt 3m1s DeployedVerificar CDI:
/var/lib/rancher/rke2/bin/kubectl get all -n cdi-system --kubeconfig /etc/rancher/rke2/rke2.yamlA saída deve ser semelhante à seguinte, mostrando que tudo foi implantado com sucesso:
NAME READY STATUS RESTARTS AGE
pod/cdi-apiserver-5598c9bf47-pqfxw 1/1 Running 0 3m44s
pod/cdi-deployment-7cbc5db7f8-g46z7 1/1 Running 0 3m44s
pod/cdi-operator-777c865745-2qcnj 1/1 Running 0 3m48s
pod/cdi-uploadproxy-646f4cd7f7-fzkv7 1/1 Running 0 3m44s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/cdi-api ClusterIP 10.43.2.224 <none> 443/TCP 3m44s
service/cdi-prometheus-metrics ClusterIP 10.43.237.13 <none> 8080/TCP 3m44s
service/cdi-uploadproxy ClusterIP 10.43.114.91 <none> 443/TCP 3m44s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/cdi-apiserver 1/1 1 1 3m44s
deployment.apps/cdi-deployment 1/1 1 1 3m44s
deployment.apps/cdi-operator 1/1 1 1 3m48s
deployment.apps/cdi-uploadproxy 1/1 1 1 3m44s
NAME DESIRED CURRENT READY AGE
replicaset.apps/cdi-apiserver-5598c9bf47 1 1 1 3m44s
replicaset.apps/cdi-deployment-7cbc5db7f8 1 1 1 3m44s
replicaset.apps/cdi-operator-777c865745 1 1 1 3m48s
replicaset.apps/cdi-uploadproxy-646f4cd7f7 1 1 1 3m44s25.10 Instalação do SUSE Private Registry #
Para incluir o SUSE Private Registry em uma implantação air-gapped, devemos atualizar o arquivo de definição para incluir o gráfico helm necessário, bem como os artefatos incorporados para as novas imagens.
Vamos atualizar o arquivo de definição:
apiVersion: 1.3
image:
imageType: iso
arch: x86_64
baseImage: slemicro.iso
outputImageName: eib-image.iso
operatingSystem:
users:
- username: root
encryptedPassword: $6$jHugJNNd3HElGsUZ$eodjVe4te5ps44SVcWshdfWizrP.xAyd71CVEXazBJ/.v799/WRCBXxfYmunlBO2yp1hm/zb4r8EmnrrNCF.P/
kubernetes:
version: v1.35.4+rke2r1
helm:
charts:
- name: metallb
version: 306.0.2+up0.15.3
targetNamespace: metallb-system
createNamespace: true
repositoryName: suse-edge-charts
installationNamespace: kube-system
- name: suse-storage
releaseName: longhorn
repositoryName: rancher-application-collection
targetNamespace: longhorn-system
createNamespace: true
version: 1.11.2
- name: private-registry-helm
createNamespace: true
installationNamespace: kube-system
repositoryName: privateregistry
targetNamespace: suse-private-registry
valuesFile: privateregistry.yaml
version: 1.1.1
repositories:
- name: privateregistry
authentication:
username: ${PRIVATE_REGISTRY_USERNAME}
password: ${PRIVATE_REGISTRY_PASSWORD}
plainHTTP: false
skipTLSVerify: false
url: oci://registry.suse.com/private-registry
- name: rancher-application-collection
url: oci://dp.apps.rancher.io/charts
authentication:
username: $APPS.RANCHER.IO_USERNAME
password: $APPS.RANCHER.IO_ACCESS_TOKEN
embeddedArtifactRegistry:
registries:
- uri: registry.suse.com
authentication:
username: ${PRIVATE_REGISTRY_USERNAME}
password: ${PRIVATE_REGISTRY_PASSWORD}
- uri: dp.apps.rancher.io
authentication:
username: $APPS.RANCHER.IO_USERNAME
password: $APPS.RANCHER.IO_ACCESS_TOKEN
images:
- name: registry.suse.com/private-registry/harbor-core:1.1.1-1.19
- name: registry.suse.com/private-registry/harbor-jobservice:1.1.1-1.19
- name: registry.suse.com/private-registry/harbor-portal:1.1.1-1.20
- name: registry.suse.com/private-registry/harbor-registry:1.1.1-1.19
- name: registry.suse.com/private-registry/harbor-registryctl:1.1.1-1.19
- name: registry.suse.com/private-registry/harbor-trivy-adapter:1.1.1-1.24Você precisará de certas credenciais, que podem ser obtidas seguindo a documentação oficial do SUSE Private Registry.
Você também deve modificar as variáveis ${PRIVATE_REGISTRY_USERNAME} e ${PRIVATE_REGISTRY_PASSWORD}. Certifique-se de listar as imagens que contêm as versões dos componentes de que você precisa.
Agora precisamos adicionar os manifestos do Kubernetes necessários para configurar corretamente o SUSE Private Registry.
Você precisa modificar o ${MGMT_CLUSTER_REGISTRY_IP} com um IP estático reservado para o SUSE Private Registry nos seguintes arquivos:
kubernetes/manifests/metallb-registry.yamlapiVersion: metallb.io/v1beta1 kind: L2Advertisement metadata: name: private-registry namespace: metallb-system spec: ipAddressPools: - private-registry-pool --- apiVersion: metallb.io/v1beta1 kind: IPAddressPool metadata: name: private-registry-pool namespace: metallb-system spec: addresses: - ${MGMT_CLUSTER_REGISTRY_IP}/32 serviceAllocation: namespaces: - suse-private-registrykubernetes/helm/values/privateregistry.yamlcore: secretName: suse-registry-tls expose: tls: certSource: secret enabled: true secret: secretName: suse-registry-tls type: loadBalancer externalURL: https://${MGMT_CLUSTER_REGISTRY_IP} persistence: persistentVolumeClaim: registry: size: 20Gi
Finalmente, o kubernetes/manifests/suse-private-registry-creds.yaml deve ser criado com o seguinte conteúdo:
apiVersion: v1
kind: Secret
metadata:
name: suse-registry
namespace: suse-private-registry
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: ${DOCKER_CONFIG_JSON_BASE64}
---
apiVersion: v1
kind: Secret
metadata:
name: suse-registry-tls
namespace: suse-private-registry
type: kubernetes.io/tls
data:
tls.crt: ${TLS_CRT_BASE64}
tls.key: ${TLS_KEY_BASE64}Para configurar corretamente o json de configuração do docker (base64) para o ${DOCKER_CONFIG_JSON_BASE64}, execute:
# ${DOCKER_CONFIG_JSON_BASE64} CONTENT
echo -n '{"auths": {"<MGMT_CLUSTER_REGISTRY_IP>": {"username": "<USERNAME>", "password": "<PASSWORD>", "auth": "<AUTH>"}}}' | base64Onde o IP é o mesmo que o ${MGMT_CLUSTER_REGISTRY_IP} configurado anteriormente, e o username, password e auth podem ser obtidos na documentação oficial do SUSE Private Registry.
Para gerar o certificado TLS e a chave codificados em base64 (tls.crt e tls.key) para ${TLS_CRT_BASE64} e ${TLS_KEY_BASE64}, você pode criar os seus próprios executando:
# Generate a self-signed certificate and key
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 -nodes
# Convert them to base64 for the suse-private-registry-creds.yaml file
cat cert.pem | base64 -w 0
cat key.pem | base64 -w 0Verificar SUSE Private Registry:
/var/lib/rancher/rke2/bin/kubectl get pods -n suse-private-registry --kubeconfig /etc/rancher/rke2/rke2.yamlA saída deve ser semelhante à seguinte, mostrando que tudo foi implantado com sucesso:
NAME READY STATUS RESTARTS AGE
pod/private-registry-harbor-core-588fd4876f-8tqnv 1/1 Running 0 4m30s
pod/private-registry-harbor-database-0 1/1 Running 0 4m30s
pod/private-registry-harbor-jobservice-7658f97fbc-4vq6n 1/1 Running 0 4m30s
pod/private-registry-harbor-portal-5455ccc4bc-jpmt5 1/1 Running 0 4m30s
pod/private-registry-harbor-redis-0 1/1 Running 0 4m30s
pod/private-registry-harbor-registry-5648b9d89-wdswz 2/2 Running 0 4m30s
pod/private-registry-harbor-trivy-0 1/1 Running 0 4m30s25.11 Solução de problemas #
Se você encontrar problemas ao criar as imagens ou quiser testar e depurar ainda mais o processo, consulte a documentação do upstream.
