Openshift - Instalação Manual
O Openshift é uma família de softwares voltados para contêineres, mas normalmente estamos nos referindo ao Openhsift Container Platform ou OCP. Para facilitar o entendimento deste texto o termo Openshift será utilizado para fazer referência ao OCP.
Podemos dizer que o Openshift é uma implementação do Kubernetes, e segundo a própria Red Hat, o Openshift é uma plataforma de desenvolvimento de aplicações.
A versão conhecida como enterprise - embora o nome correto seja downstream - chama-se Openshift, já a versão que as vezes chamamos de community - embora o nome correto seja upstream - chama-se OKD.
Para tornar este guia o mais abrangente possível, utilizaremos o OKD no lugar do Openshift, desta forma não precisaremos fazer nenhum cadastro, e por questões de simplicidade, sempre que possível, utilizarei o nome Openshift para fazer referência ao OKD.
Sobre o Ambiente
Este ambiente será instalado utilizando o libvirt, coisas como criar discos, máquinas e outros comandos farão uso de ferramentas do próprio projeto, no entanto nada o impede de seguir os passos de forma similar em sua ferramenta preferida como o VirtualBox.
A instalação manual do Openshift, também conhecida como UPI (User Provisioned Infrastructure), é relativamente complexa mas preciso deixar claro que ela não reflete a maioria das instalações. A maioria das instalações utiliza um método chamado IPI (Installer Provisioned Infrastructure) que automatiza e simplifica o processo de instalação drásticamente.
Normalmente utilizamos este método quando vamos instalar o Openshift em alguma infraestrutura não suportada pelo IPI e por alguma razão não queremos utilizar a instalação baseada em agente.
Um conceito importante
Antes de começarmos é preciso entender como funciona a instalação do Openshift 4, que muito difere da instalação utilizada no Openshift 3, através de playbooks do Ansible.
A maior diferença entre o Kubernetes padrão e o Openshift está no provisionamento das máquinas. No Openshift 4 nós não configuramos as máquinas para então iniciar a instalação da aplicação, a instalação do cluster e a configuração do sistema operacional acontecem como um único processo.
No geral, o Openshift utiliza CoreOS em suas máquinas, já o OKD utiliza o Fedora CoreOS FCOS e em suas versões mais recentes o CentOS Stream CoreOS SCOS. Para facilitar o entendimento, chamaremos todas estas versões de CoreOS.
Inicialização do CoreOS
Quando uma máquina com CoreOS é iniciada pela primeira vez, um processo durante o carregamento
do initramfs
chamado ignition é responsável pela configuração inicial da máquina,
o ignition
executa apenas no primeiro boot, similar ao cloud-init.
Esse processo procura por arquivos conhecidos como ignition configs, estes arquivos podem ser locais ou estar acessíveis em algum endereço de rede, nos passos a seguir utilizaremos um servidor web para fornecer estes arquivos para as máquinas.
Bootstrap
Na maioria das instalações do Openshift uma máquina temporária é criada para dar segmento a configuração do cluster, essa máquina é chamada de bootstrap.
Por debaixo dos panos o bootstrap inicia um cluster Kubernetes e adiciona as máquinas que fazem parte da configuração inicial automaticamente. Uma vez que este processo esteja terminado, o bootstrap pode ser removido.
Requisitos
Instalar o Openshift manualmente pode parecer uma tarefa hercúlea, principalmente com toda a informação disponível na documentação oficial, mas se nos atentarmos aos requisitos necessários antes de iniciar o processo de instalação, provavelmente não teremos problemas sérios.
Serviços
Precisaremos dos seguintes serviços para provisionar o cluster:
- DNS
- O DNS será utilizado para indicar endereços importantes do cluster como
api
,api-int
e*.apps
. Utilizaremos odnsmasq
.
- O DNS será utilizado para indicar endereços importantes do cluster como
- Balanceador
- O balanceador será utilizado para redirecionar as requisições para as máquinas corretas.
No Openshift mais de uma máquina responde pela mesma aplicação.
Utilizaremos o
haproxy
.
- O balanceador será utilizado para redirecionar as requisições para as máquinas corretas.
No Openshift mais de uma máquina responde pela mesma aplicação.
Utilizaremos o
- Servidor Web
- O servidor web disponibilizará os arquivos de configuração que as máquinas utilizarão durante
a inicialização para se configurarem automaticamente. Utilizaremos o
apache
.
- O servidor web disponibilizará os arquivos de configuração que as máquinas utilizarão durante
a inicialização para se configurarem automaticamente. Utilizaremos o
É possível iniciar a instalação através de PXE e utilizar DHCP para simplificar toda a configuração, mas utilizaremos a menor quantidade de conceitos externos ao próprio Openshift para facilitar o entendimento de tudo o que é apresentado.
Máquinas
A exigência de hardware do Openshift assusta um pouco, é possível criar um cluster de uma única máquina mas em produção utilizamos no 3 máquinas no papel control plane (antigamente conhecidas como masters) e 2 ou mais máquinas no papel de compute node (antigamente conhecidas como workers).
Além disso, a máquina bootstrap possui as mesmas exigências mínimas do control plane:
Tipo | CPU | Memória | Disco |
---|---|---|---|
Bootstrap | 4 | 16G | 120G |
Control Plane | 4 | 16G | 120G |
Compute Node | 2 | 8G | 120G |
Services | 1 | 1G | 10G |
A máquina services conterá todos os serviços que precisaremos, ela não faz parte de uma instalação do Openshift e sim da nossa própria infraestrutura.
Isso significa que para instalar manualmente um Openshift contendo tudo em uma única máquina, o mínimo necessário seria 32GB de memória RAM, já que o bootstrap faz parte da instalação, mesmo que temporariamente.
Como hypervisors trabalham com overcommit de memória não é necessário ter exatamente 32GB livres.
É possível trabalhar com apenas uma única máquina como control plane e adicionar outros workers, tudo depende do que almeja, este guia, no entanto, seguirá com as recomendações oficiais.
Rede
Utilizaremos a rede 192.168.100.0/24
para nossas máquinas virtuais.
Esta rede não deve possuir nenhum serviço de DHCP habilitado.
Configurando a Rede
Podemos criar a rede pela interface gráfica, mas o intuito é fazer tudo de maneira programática.
O seguinte arquivo definirá a rede sem DHCP:
openshift-network.xml
<network>
<name>openshift</name>
<forward mode="nat">
<nat>
<port start="1024" end="65535"/>
</nat>
</forward>
<bridge name="virbr0" stp="on" delay="0"/>
<mac address="52:54:00:42:14:8b"/>
<domain name="openshift"/>
<ip address="192.168.100.1" netmask="255.255.255.0">
</ip>
</network>
Em seguida criamos a rede baseada neste arquivo e a configuramos para inicializar automaticamente:
vish net-define openshift-network.xml
virsh net-autostart openshift
virsh net-start openshift
Services - Provisionamento
Em uma instalação deste tipo, precisaremos dos serviços de DNS e balanceamento além de servir arquivos via HTTP.
Todos estes serviços serão instalados em uma máquina chamada services.
Curiosidade: Nas instalações IPI uma máquina extra, normalmente chamada de bastion é utilizada para executar os comandos de instalação.
A configuração da máquina services
está separada do restante do Openshift justamente porque ela
não faz parte instalação e normalmente estes serviços já existem em nossa rede.
Disco
Para a máquina services
utilizaremos um disco QCOW2 do CentOS 9, com um sistema base já instalado.
Como podemos utilizar este disco no futuro, vamos utilizá-lo como base ao invés de diretamente.
# como root
cd /var/lib/libvirt/images/
CENTOS_QCOW2='cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-GenericCloud-9-latest.x86_64.qcow2'
curl -L ${CENTOS_QCOW2} > centos9.qcow2
# Troca a senha do root e remove/instala pacotes
virt-customize \
-a centos9.qcow2 \
--root-password password:centos \
--uninstall cloud-init \
--install vim,git
# Cria uma imagem baseada na imagem `centos9.qcow2`
qemu-img create -f qcow2 -F qcow2 -b centos9.qcow2 services.qcow2 20G
Hardware
Vamos utilizar o virt-install
para definir a nossa máquina, podemos criar pela interface gráfica
mas a intenção é automatizar:
virt-install \
--name=services \
--vcpus=1 \
--memory=1024 \
--disk path=/var/lib/libvirt/images/services.qcow2 \
--network network=openshift \
--virt-type kvm \
--os-variant=centos-stream9 \
--boot hd \
--noautoconsole \
--noreboot
virsh start services
Rede
Entre na máquina e defina um endereço IP fixo, neste nosso caso utilizaremos 192.168.100.99
, e habilite
o acesso SSH para o usuário root através de senha:
# como root
virsh console services
# dentro da máquina
hostnamectl set-hostname services.openshift.local
nmcli con mod 'System eth0' ipv4.method static ipv4.address 192.168.100.99/24 ipv4.dns 192.168.100.1 ipv4.gateway 192.168.100.1
nmcli con reload
sed -i 's,#PermitRootLogin.*,PermitRootLogin yes,' /etc/ssh/sshd_config
sed -Ei 's,#(PasswordAuthentication yes),\1,' /etc/ssh/sshd_config
systemctl restart sshd
timedatectl set-timezone 'America/Sao_Paulo'
Se prefereir, saia do virsh console
com exit
seguido de CTRL+]
e logue-se na máquina
através de SSH no endereço 192.168.100.99
com usuário root
e senha centos
.
DNS
O DNS será controlado pelo dnsmasq.
É possível burlar a necessidade de um DNS, mas não é algo que encontraremos por aí e também perderemos toda a alta disponibilidade e balanceamento do próprio Kubernetes. Como isso é uma má prática, não espere encontrar nada do tipo por aqui.
O DNS precisa direcionar as chamadas de api
, api-int
e *.apps
para as máquinas corretas.
Neste nosso exemplo a máquina services
também é o balanceador que receberá essas requisições
redirecionando-as para as máquinas corretas.
Os endereços do Openshift são configurados durante a instalação, no nosso caso o endereço da API
será api.openshift.local
mas isso será feito mais adiante.
Vamos instalar o dnsmasq
e configurar o DNS. O dnsmasq
lê as entradas no arquivo /etc/hosts
e passa a servir as requisiçoẽs para aqueles endereços como um servidor DNS comum.
dnf install -y dnsmasq
cat > /etc/dnsmasq.conf <<'EOF'
# *.apps.openshift.local
address=/.apps.openshift.local/192.168.100.99
interface=eth0
server=192.168.100.1
EOF
cat >> /etc/hosts <<'EOF'
192.168.100.99 api.openshift.local api-int.openshift.local
192.168.100.10 bootstrap bootstrap.openshift.local
192.168.100.100 control0 control0.openshift.local
192.168.100.101 control1 control1.openshift.local
192.168.100.102 control2 control2.openshift.local
192.168.100.200 compute0 compute0.openshift.local
192.168.100.201 compute1 compute1.openshift.local
EOF
systemctl enable --now dnsmasq
nmcli con modify 'System eth0' ipv4.dns 127.0.0.1
nmcli con up 'System eth0'
Balanceador
O balanceamento é feito através do HAProxy.
Para o HAProxy iniciar, todos os endereços devem ser conhecidos, como já configuramos nosso servidor DNS isso não será um problema.
Não há firewall configurado na imagem do CentOS, por isso não mexeremos com firewalld
.
dnf install -y haproxy
cat > /etc/haproxy/haproxy.cfg <<'EOF'
global
log 127.0.0.1 local2
pidfile /var/run/haproxy.pid
maxconn 4000
daemon
defaults
mode http
log global
option dontlognull
option http-server-close
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
frontend stats
mode http
bind *:8080
stats enable
stats uri /stats
stats refresh 10s
stats admin if TRUE
#stats auth <username:password>
listen api-server-6443
bind *:6443
mode tcp
option httpchk GET /readyz HTTP/1.0
option log-health-checks
balance roundrobin
server control0 control0:6443 weight 1 verify none check check-ssl inter 10s fall 2 rise 3
server control1 control1:6443 weight 1 verify none check check-ssl inter 10s fall 2 rise 3
server control2 control2:6443 weight 1 verify none check check-ssl inter 10s fall 2 rise 3
server bootstrap bootstrap:6443 verify none check check-ssl inter 10s fall 2 rise 3 backup
listen machine-config-server-22623
bind *:22623
mode tcp
server control0 control0:22623 check inter 1s
server control1 control1:22623 check inter 1s
server control2 control2:22623 check inter 1s
server bootstrap bootstrap:22623 check inter 1s backup
listen ingress-router-443
bind *:443
mode tcp
balance source
server compute0 compute0:443 check inter 1s
server compute1 compute1:443 check inter 1s
server control0 control0:443 check inter 1s
server control1 control1:443 check inter 1s
server control2 control2:443 check inter 1s
listen ingress-router-80
bind *:80
mode tcp
balance source
server compute0 compute0:80 check inter 1s
server compute1 compute1:80 check inter 1s
server control0 control0:80 check inter 1s
server control1 control1:80 check inter 1s
server control2 control2:80 check inter 1s
EOF
# atente-se a configuração de selinux
setsebool -P haproxy_connect_any=1
systemctl enable --now haproxy
Será possível acompanhar o status de cada porta do HAProxy através do endereço services:8080/stats, isso será muito útil para detectar possíveis enganos cometidos.
Webserver
Para servir os arquivos ignition
vamos instalar o Apache e como vamos utilizar a porta 80 para o HAProxy
balancear conexões HTTP para o Openshift, utilizaremos o Apache na porta 81.
dnf install -y httpd
sed -i 's,Listen 80,Listen 81,' /etc/httpd/conf/httpd.conf
systemctl enable --now httpd
Utilizaremos novamente a máquina services
mais adiante, por hora vamos configurar as demais máquinas.
Control Plane - Provisionamento
O tutorial fará uma instalação com 3 control planes, mas é possível utilizar 1 caso não exista hardware suficiente.
Discos
# máquina hospedeira, como root
cd /var/lib/libvirt/images/
qemu-img create -f qcow2 control0.qcow2 120G
qemu-img create -f qcow2 control1.qcow2 120G
qemu-img create -f qcow2 control2.qcow2 120G
qemu-img create -f qcow2 bootstrap.qcow2 120G
Este comando cria os discos thin
, eles apenas ocuparão o espaço efetivamente utilizado e não os 120GB.
Harware
Utilizando-se de um comando similar ao do services
, vamos criar o bootstrap, e os 3 controllers de uma única vez.
Aqui nós utilizaremos um truque do Libvirt (QEMU na realidade) e poderemos copiar e colar comandos no console das máquinas
virtuais, mas caso esteja utilizando outro hypervisor como VirtualBox, terá de:
- Criar as máquinas pela interface
- Adicionar a ISO como opção de boot
- Configurar a ordem de boot
- Digitar todos os comandos manualmente na janela da VM.
O truque consiste em modificar os parâmetro do kernel da ISO com a intenção de habilitar um console de texto
e, por conta disso, nossa máquina iniciará automaticamente - é o padrão do virt-install
- e mesmo
que a reiniciemos após a instalação, ela será desligada, portanto precisaremos religá-la.
# máquina hospedeira, como root
for VM in bootstrap control0 control1 control2; do
virt-install \
--name=$VM \
--vcpus=4 \
--memory=16384 \
--os-variant=fedora-coreos-stable \
--disk path=/var/lib/libvirt/images/$VM.qcow2 \
--network network=openshift \
--virt-type kvm \
--noautoconsole \
--noreboot \
--location '/var/lib/libvirt/images/fedora-coreos-39.20231101.3.0-live.x86_64.iso,kernel=/images/pxeboot/vmlinuz,initrd=/images/pxeboot/initrd.img' \
--extra-args 'mitigations=auto,nosmt coreos.liveiso=fedora-coreos-39.20231101.3.0 ignition.firstboot ignition.platform.id=metal console=ttyS0'
done
Caso queira fazer um cluster de um único compute modifique o laço
for
.
Compute Nodes - Provisionamento
O tutorial utilizará 2 compute nodes, mas é possível ter apenas os controller nodes.
Discos
# máquina hospedeira, como root
cd /var/lib/libvirt/images/
qemu-img create -f qcow2 compute0.qcow2 120G
qemu-img create -f qcow2 compute1.qcow2 120G
Este comando cria os discos thin
, eles apenas ocuparão o espaço efetivamente utilizado e não os 120GB.
Harware
Utilizando-se do mesmo comando anterior, vamos substituir os valores para nome, memória e CPU.
Lembre-se que a máquina iniciará automaticamente e se desligará independente do comando utilizado após a instalação.
# máquina hospedeira, como root
for VM in compute0 compute1; do
virt-install \
--name=$VM \
--vcpus=2 \
--memory=8192 \
--os-variant=fedora-coreos-stable \
--disk path=/var/lib/libvirt/images/$VM.qcow2 \
--network network=openshift \
--virt-type kvm \
--noautoconsole \
--noreboot \
--location '/var/lib/libvirt/images/fedora-coreos-39.20231101.3.0-live.x86_64.iso,kernel=/images/pxeboot/vmlinuz,initrd=/images/pxeboot/initrd.img' \
--extra-args 'mitigations=auto,nosmt coreos.liveiso=fedora-coreos-39.20231101.3.0 ignition.firstboot ignition.platform.id=metal console=ttyS0'
done
Configuração do Openshift
Voltando para a services
, vamos baixar os binários do Openshift, a ISO de instalação do CoreOS e criar o
arquivo de configuração do cluster.
Binários
Na máquina services
, instale o openshift-install
e o oc
disponíveis em https://github.com/okd-project/okd/releases:
# vm services
OC=github.com/okd-project/okd/releases/download/4.17.0-okd-scos.0/openshift-client-linux-4.17.0-okd-scos.0.tar.gz
curl -L https://$OC | tar -xz -C /usr/local/bin oc kubectl
OPENSHIFT_INSTALL=github.com/okd-project/okd/releases/download/4.17.0-okd-scos.0/openshift-install-linux-4.17.0-okd-scos.0.tar.gz
curl -L https://$OPENSHIFT_INSTALL | tar -xz -C /usr/local/bin openshift-install
Imagem - ISO
Para iniciarmos o CoreOS precisaremos da ISO de instalação, lembre-se que não vamos configurá-lo como estamos
habituados, a instalação acontecerá através do ignition
.
Não podemos utilizar qualquer imagem do CoreOS, precisamos usar a imagem configurada no próprio binário, e
para isso vamos extrair a versão executendo openshift-install
dentro da máquina services
:
# vm services
openshift-install coreos print-stream-json | grep 'x86_64.iso'
# saída
"location": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/39.20231101.3.0/x86_64/fedora-coreos-39.20231101.3.0-live.x86_64.iso",
"signature": "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/39.20231101.3.0/x86_64/fedora-coreos-39.20231101.3.0-live.x86_64.iso.sig",
Baixe esta ISO no diretório /var/lib/libvirt/images
de sua máquina hospedeira, utilizaremos essa ISO para inicializar as demais máquinas.
# máquina hospedeira, como root
cd /var/lib/libvirt/images
FCOS=builds.coreos.fedoraproject.org/prod/streams/stable/builds/39.20231101.3.0/x86_64/fedora-coreos-39.20231101.3.0-live.x86_64.iso
curl -L https://$FCOS > fedora-coreos-39.20231101.3.0-live.x86_64.iso
Configuração do Cluster
Crie dois diretórios, openshift
e install
, um dentro do outro, aí ficarão nossas
configurações. Acesse o diretório openshift
:
# vm services
mkdir -p ~/openshift/install
cd ~/openshift
install-config.yaml
Os arquivos de configuração das máquinas e do próprio cluster são gerados através
de um arquivo chamado install-config.yaml
. Este arquivo define alguns parâmetros como
o endereço de rede dos pods, dos serviços, o nome do cluster e o domínio base, além de
uma chave ssh para logar-se nas máquinas e um “segredo” para baixar imagens de repositórios
privados - que não é o caso para o OKD.
Um exemplo do arquivo install-config.yaml
pode ser criado com o comando openshift-install create install-config
mas para entendê-lo, precisamos colocá-lo aqui:
install-config.yaml
apiVersion: v1
baseDomain: local
compute:
- hyperthreading: Enabled
name: worker
replicas: 0
controlPlane:
hyperthreading: Enabled
name: master
replicas: 3
metadata:
name: openshift
networking:
clusterNetwork:
- cidr: 10.128.0.0/14
hostPrefix: 23
networkType: OVNKubernetes
serviceNetwork:
- 172.30.0.0/16
platform:
none: {}
pullSecret: '{"auths":{"fake":{"auth":"aWQ6cGFzcwo="}}}'
sshKey: 'ssh-ed25519 AAAA...'
Salve este arquivo em
~/openshift/install-config.yaml
Em instalações manuais - ou UPI - devemos sempre manter as réplicas dos computes
como 0.
Atente-se a chave sshKey
pois precisaremos substituí-la. O valor de pullSecret
normalmente
é um JSON extraído de do console da própria Red Hat, como não precisamos dele, vamos utilizar
um pullSecret
falso.
A chave platform
terá uma outra chave de valor none
pois não estamos instalando em nenhuma
cloud ou hypervisor com suporte a IPI.
Crie uma chave ssh para substituir o valor do arquivo install-config.yaml
:
# vm services
ssh-keygen -t ed25519 -N '' -f /root/.ssh/id_ed25519
cat ~/.ssh/id_ed25519.pub
# saída de exemplo:
# ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK+mwd/AwikbtqBDSJ+oZfLxcE9G+XSaHShKfzogDIaJ root@services
Substitua o valor da chave ssh no arquivo pela saída do comando executado em sua máquina services
,
e em seguida copie o arquivo para o diretório install
. Faremos uma cópia deste arquivo pois
ele desaparecerá após a execução dos comandos de instalação:
# vm services
cp install-config.yaml install
Manifestos
Agora vamos gerar os arquivos de configuração, são eles os manifestos
e os ignitions
. É possível
gerar os ignitions de uma vez, mas vamos fazer as duas etapas para entender melhor.
# vm services
cd ~/openshift
openshift-install create manifests --dir install
Este comando criará os manifestos do Kubernetes/Openshift que definirão como será nosso cluster.
Nesta etapa é possível fazer modificações como tornar os control planes
não “agendáveis”,
configurações específicas de rede, etc.
tree install
# saída:
# install
# ├── manifests
# │ ├── cluster-config.yaml
# │ ├── cluster-dns-02-config.yml
# │ ├── cluster-infrastructure-02-config.yml
# │ ├── cluster-ingress-02-config.yml
# │ ├── cluster-network-02-config.yml
# │ ├── cluster-proxy-01-config.yaml
# │ ├── cluster-scheduler-02-config.yml
# │ ├── cvo-overrides.yaml
# │ ├── kube-cloud-config.yaml
# │ ├── kube-system-configmap-root-ca.yaml
# │ ├── machine-config-server-tls-secret.yaml
# │ └── openshift-config-secret-pull-secret.yaml
# └── openshift
# ├── 99_feature-gate.yaml
# ├── 99_kubeadmin-password-secret.yaml
# ├── 99_openshift-cluster-api_master-user-data-secret.yaml
# ├── 99_openshift-cluster-api_worker-user-data-secret.yaml
# ├── 99_openshift-machineconfig_99-master-ssh.yaml
# ├── 99_openshift-machineconfig_99-worker-ssh.yaml
# └── openshift-install-manifests.yaml
Observação: Existem dois diretórios,
manifests
eopenshift
, eles estão aí apenas por questões históricas, não há distinção entre um ou outro para o instalador.
Ignitions
Agora vamos gerar os ignitions
:
# vm services
cd ~/openshift
openshift-install create ignition-configs --dir install
Após este comando, todos os manifestos serão condensados em alguns poucos arquivos de extensão .ign
:
tree install
# saída:
# install
# ├── auth
# │ ├── kubeadmin-password
# │ └── kubeconfig
# ├── bootstrap.ign
# ├── master.ign
# ├── metadata.json
# └── worker.ign
Note que já temos um kubeconfig
e uma senha para o usuário kubeadmin
no arquivo kubeadmin-password
, utilizaremos
estes arquivos para conversar com a API do Openshift através do kubectl
ou do oc
, ou mesmo do painel.
Com os ignitions prontos, precisamos agora copiá-lo para dentro do diretório do apache. As máquinas, quando
inciadas, serão configuradas para buscar os ignitions em http://192.168.100.99:81/<tipo>.ign
.
# vm services
cp install/*.ign /var/www/html
chown apache: /var/www/html/*.ign
Teste o acesso aos arquivos:
curl -I 192.168.100.99:81/worker.ign
# saída:
# HTTP/1.1 200 OK
# Date: Thu, 06 Mar 2025 20:48:45 GMT
# Server: Apache/2.4.62 (CentOS Stream)
# Last-Modified: Thu, 06 Mar 2025 20:47:24 GMT
# ETag: "6b5-62fb29cf2d0ac"
# Accept-Ranges: bytes
# Content-Length: 1717
# Content-Type: application/vnd.coreos.ignition+json
Antes de iniciarmos as máquinas, podemos deixar um comando rodando em services
para observar o progresso
da primeira parte da instalação, no entanto isso é completamente opcional:
# vm services
cd ~/openshift
openshift-install wait-for bootstrap-complete --dir install --log-level debug
A saída de level debug pode ser um pouco assustadora, mas também pode ser bastante útil. Haverá um tempo
limite de 20 minutos e após isso, caso a API do Kubernetes que o bootstrap
irá provisionar não esteja
pronta, a instalação falhará. Após a API responder um novo limite de 45 minutos será considerado para
que os controllers
estejam prontos.
A saída completa, sem debug
será similar a seguinte:
INFO Waiting up to 20m0s (until 12:48AM -03) for the Kubernetes API at https://api.openshift.local:6443...
INFO API v1.30.6-dirty up
INFO Waiting up to 45m0s (until 1:13AM -03) for bootstrapping to complete...
INFO It is now safe to remove the bootstrap resources
INFO Time elapsed: 0s
Se ainda estiver configurando as máquinas, ou estiver com uma conexão de internet ruim, não há problema, apenas execute o comando novamente.
Hora de configurar as máquinas.
Instalação do Openshift
As máquinas já foram iniciadas com os comandos anteriores do virt-install
, isso nos poupou bastante
trabalho de ter que iniciar as máquinas manualmente, modificar a ordem de boot para ler a ISO primeiro
e então acessar o console.
Caso esteja utilizando outro hypervisor, ou uma infraestrutura física, adicione a ISO como opção de boot para as máquinas, ligue-as uma a uma.
De agora em diante vamos utilizar virsh console
para executar os comandos com maior facilidade,
poderemos copiar e colar os comandos, mas caso esteja em outro hypervisor, será necessário
digitar tudo manualmente - o que não deixa de ser uma boa opção para aprender.
Nota: Outras formas de instalação não precisam destes passos, seja utilizando DHCP+PXE ou mesmo a instalação baseda em agente. Esta forma manual, no entanto, deixa todo o processo explícito.
Bootstrap
# máquina hospedeira, como root
virsh console bootstrap
sudo -i
# os próximos três comandos podem ser executados de uma vez
hostnamectl set-hostname bootstrap.openshift.local
nmcli con modify 'Wired connection 1' ipv4.method static ipv4.address 192.168.100.10/24 ipv4.gateway 192.168.100.1 ipv4.dns 192.168.100.99
nmcli con reload
# espere a máquina pegar ip
coreos-installer install --ignition-url http://192.168.100.99:81/bootstrap.ign --insecure-ignition --copy-network /dev/vda
Modificamos o nome do nó para facilitar sua identificação por dentro do Openshift, e definimos um endereço IP
fixo baseado nas informações que configuramos no /etc/hosts
da máquina services.
Note que utilizamos o ignition
chamado bootstrap.ign
, as outras máquinas utilizarão outros ignitions, também atente-se
ao fato de utilizarmos o DNS da máquina services.
Os parâmetros de configuração do coreos-installer
são autoexplicativos, mas podemos substituí-los por versões
abreviadas como -I
para o endereço do ignition
e -n
para copiar as configurações de rede. O último parâmetro
é o disco no qual instalaremos o CoreOS.
Após o comando finalizar, reinicie da máquina da forma que achar melhor, por exemplo: reboot
dentro do console
ou virsh reboot bootstrap
, e lembre-se que precisaremos religá-la.
Uma vez que o nó esteja inicializado, podemos acessá-lo através de SSH com a chave especificada no install-config.yaml
e acompanhar mais de perto a instalação:
# vm services, -i é opcional
ssh -i ~/.ssh/id_ed25519 core@192.168.100.10
# vm bootstrap via ssh
journalctl -b -f -u release-image.service -u bootkube.service
Enquanto o bootstrap sobe, podemos inicializar as demais máquinas.
Control Plane
Precisamos acessar cada uma das máquinas separadamente, trocando o hostname, o endereço IP para coincidirem com os especificados
em /etc/hosts
da máquina services além de usar o ignition file
chamado master.ign
.
O processo de configuração do control plane é similar ao do bootstrap:
# máquina hospedeira, como root
virsh console control0
sudo -i
# os próximos três comandos podem ser executados de uma vez, lembre-se de atualizá-los!
hostnamectl set-hostname control0.openshift.local
nmcli con modify 'Wired connection 1' ipv4.method static ipv4.address 192.168.100.100/24 ipv4.gateway 192.168.100.1 ipv4.dns 192.168.100.99
nmcli con reload
# espere a máquina pegar ip
coreos-installer install --ignition-url http://192.168.100.99:81/master.ign --insecure-ignition --copy-network /dev/vda
Note que estamos utilizando o DNS presente na máquina
services
. Faça isso para o control0, control1 e control2.
Com estas máquinas configuradas, o comando openshift-install wait-for bootstrap-complete
deve finalizar sozinho.
Após a finalização a máquina bootstrap poderá ser removida por completo. Não precisa se preocupar
pois o openshift-install
lhe avisará quando isso for possível.
Para acompanhar o processo de finalização do cluster, podemos executer:
openshift-install wait-for install-complete --dir install --log-level debug
Há um limite de tempo de 40 minutos para finalizar o básico da instalação, e depois mais 30 minutos
para todos os Operators finalizarem, se por alguma razão acreditar que precisará de mais
tempo que isso, basta executar o comando novamente, o processo é automático e não tem relação com o binário openshift-install
.
A saída do comando sem debug
é similar a seguinte:
INFO Waiting up to 40m0s (until 1:23AM -03) for the cluster at https://api.openshift.local:6443 to initialize...
INFO Waiting up to 30m0s (until 1:13AM -03) to ensure each cluster operator has finished progressing...
INFO All cluster operators have completed progressing
INFO Checking to see if there is a route at openshift-console/console...
INFO Install complete!
INFO To access the cluster as the system:admin user when using 'oc', run 'export KUBECONFIG=/root/openshift/install/auth/kubeconfig'
INFO Access the OpenShift web-console here: https://console-openshift-console.apps.openshift.local
INFO Login to the console with user: "kubeadmin", and password: "k36qp-X7uus-tW6tz-s3AW5"
INFO Time elapsed: 0s
Outra coisa que podemos fazer é utilizar o kubeconfig
e o comando oc
dentro da máquina services
para observar o estado de todos os pods do cluster, mesmo que o comando wait-for bootstrap-install
não tenha terminado:
export KUBECONFIG=/root/openshift/install/auth/kubeconfig
oc get nodes
watch "oc get pods -A | grep -Ev 'Running|Completed'"
O processo de instalação ocorre por conta própria após a criação das máquinas,
openshift-install
é utilizado apenas para criar os arquivos de configuração e iniciar o processo, após isso ele apenas acompanha o progresso, caso o comando seja interrompido ou falhe, não há problema em executá-lo novamente.
Compute Nodes
Os mesmos passos anteriores devem ser executados para os compute nodes, porém com os endereços IPs corretos
e também utilizando o ignition file
chamado worker.ign
.
# máquina hospedeira, como root
virsh console compute0
sudo -i
# os próximos três comandos podem ser executados de uma vez, lembre-se de atualizá-los!
hostnamectl set-hostname compute0.openshift.local
nmcli con modify 'Wired connection 1' ipv4.method static ipv4.address 192.168.100.200/24 ipv4.gateway 192.168.100.1 ipv4.dns 192.168.100.99
nmcli con reload
# espere a máquina pegar ip
coreos-installer install --ignition-url http://192.168.100.99:81/worker.ign --insecure-ignition --copy-network /dev/vda
Faça isso para o compute0 e para o compute1.
A maior diferença aparecerá agora, uma vez que a máquina se configure ela não ingressará automaticamente
no cluster, ao invés disso o kubelet
criará dois CSR para obter um
certificado X.509 válido do Openshift, estes dois CSRs serão criados um após a aceitação do outro.
Para listar e aceitar certificados no cluster, devemos usar o comando oc
de dentro da máquina services
:
export KUBECONFIG=/root/openshift/install/auth/kubeconfig
oc get csr | grep Pending
# saída
oc get csr | grep Pending
csr-9vmkg 16s kubelet node-bootstrapper <none> Pending
csr-t7tlg 27s kubelet node-bootstrapper <none> Pending
oc adm certificate approve <certificado>
Fazer isso para os dois certificados que cada
compute
gerará.
Após aceitar os certificados, poderemos visualizar os computes
ingressando no cluster:
oc get nodes
# saída
NAME STATUS ROLES AGE VERSION
compute0 NotReady worker 23s v1.30.6
compute1 NotReady worker 17s v1.30.6
control0 Ready control-plane,master,worker 42m v1.30.6
control1 Ready control-plane,master,worker 43m v1.30.6
control2 Ready control-plane,master,worker 43m v1.30.6
Depois de algum tempo passarão do estado NotReady
para Ready
, assim como os controllers
.
Interagindo com o Openshift
Os comandos executados de dentro da máquina services
acontecerão como esperamos, sem nenhum problema.
Caso queira utilizar o oc
ou mesmo o kubectl
fora da máquina services
o arquivo
/root/openshift/install/auth/kubeconfig
deverá ser copiado para a máquina em questão.
É possível utilizar o DNS da máquina services
, por exemplo, apontando a máquina hospedeira para o mesmo,
mas isso pode tornar as coisas um pouco confusas caso a máquina esteja desligada, sendo assim
caso queira acessar o painel do Openshift através da sua máquina hospedeira é possível adicionar
as seguintes entradas no /etc/hosts
:
192.168.100.99 api.openshift.local
192.168.100.99 oauth-openshift.apps.openshift.local
192.168.100.99 console-openshift-console.apps.openshift.local
Os hostnames podem ficar todos na mesma linha, separados por espaço, sem repetir o endereço IP.
Normalmente não utilizamos o endereço da API diretamente, pois ele já está configurado no kubeconfig
.
Já os outros dois, oauth-openshift
e console-openshift-console
são necessários para acessar o painel.
Quando fazemos um login no Openshift com usuário e senha, o servidor OAuth é chamado para validar o nosso usuário, mesmo que o console seja acessado, seremos redirecionados para a URL do OAuth, por isso também precisaremos saber do endereço dela.
Lembre-se que o DNS configurou .app.openshift.local
apontando para 192.168.100.99
, isso significa
que qualquer aplicação criada no Openshift, será automaticamente “encontrada” por nossas pesquisas,
desde que utilizemos o DNS de services
ou adicionemos a URL em /etc/hosts
.
Uma outra forma de validar aplicações sem modificar o /etc/hosts
é utilizar o curl
aliado ao
cabeçalho Host
:
curl -k -H 'Host: console-openshift-console.apps.openshift.local' https://192.168.100.99
Para acessar o painel, utilizaremos inicialmente o usuário kubeadmin
com a senha presente em
/root/openshift/install/auth/kubeadmin-password
.
Última coisa
Esta é a última coisa do tutorial, mas não é nem de longe a última coisa sobre Openshift. Para o cluster tornar-se “utilizável” precisaremos configurar um volume para o registry interno, sem ele, nenhuma aplicação do usuário poderá ser provisionada.
A documentação do Openshift
ensina como utilizar um emptydir
para isso, mas como provavelmente iremos provisionar mais aplicações,
precisaremos de uma solução um pouco mais robusta e que possa ser utilizada por outras aplicações.
Para isso podemos adicionar um Ceph, NFS ou qualquer outro tipo de armazenamento ao Openshift, para este tutorial, no entanto, manteremos a simplicidade e criaremos um volume que não dependa de nenhum outro serviço externo ao Openshift.
Acesse o painel do Openshift em https://console-openshift-console.apps.openshift.local, clique no menu esquerdo
em Operators
e em seguida Operator Hub
.
Procure por um operator chamado OpenEBS
, clique em seu cartão, ignore a mensagem sobre operadores da comunidade
e em seguida no botão azul Install
. Aceite as opções padrão e clique em Install
novamente.
Na próxima página, após a instalação clique em View Operator
e em seguida clique em Create Instance
no cartão
chamado OpenEBS Install Template. Deixe as opções padrão e clique em Create
.
Na página do próprio objeto podemos observar mensagens de problemas com permissões, vamos permitir que o OpenEBS utilize diretórios nas próprias máquinas para criar volumes para as aplicações.
As permissões a seguir não são recomendadas para ambientes produtivos, estamos utilizando apenas a forma mais simples possível para atingirmos nossos objetivos:
oc adm policy add-scc-to-user hostaccess -z openebs-operator -n openshift-operators
oc adm policy add-scc-to-user privileged -z openebs-maya-operator -n openshift-operators
oc adm policy add-cluster-role-to-user cluster-admin -z openebs-operator -n openshift-operators
Feito isso, vamos adicionar um volume para o registry local:
oc patch configs.imageregistry/cluster --type merge --patch '{"spec":{"managementState":"Managed"}}'
oc patch configs.imageregistry.operator.openshift.io cluster --type merge --patch '{"spec":{"storage":{"pvc":{"claim":"registry"}}}}'
Agora precisamos criar o volume:
oc create -f - <<EOF
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: registry
namespace: openshift-image-registry
finalizers:
- kubernetes.io/pvc-protection
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
storageClassName: openebs-hostpath
volumeMode: Filesystem
EOF
Para testar o storage, vamos pedir para o Openshift criar uma imagem para nós, e salvar no registry interno.
Vamos criar um namespace
(ou project
) e disparar uma nova aplicação:
oc new-project ola-openshift
oc new-app httpd~https://github.com/sclorg/httpd-ex.git --name apache
A saída do último comando será semelhante a seguinte:
warning: Cannot check if git requires authentication.
--> Found image ea6b623 (4 days old) in image stream "openshift/httpd" under tag "2.4-ubi9" for "httpd"
Apache httpd 2.4
----------------
Apache httpd 2.4 available as container, is a powerful, efficient, and extensible web server. Apache supports a variety of features, many implemented as compiled modules which extend the core functionality. These can range from server-side programming language support to authentication schemes. Virtual hosting allows one Apache installation to serve many different Web sites.
Tags: builder, httpd, httpd-24
* A source build using source code from https://github.com/sclorg/httpd-ex.git will be created
* The resulting image will be pushed to image stream tag "apache:latest"
* Use 'oc start-build' to trigger a new build
--> Creating resources ...
imagestream.image.openshift.io "apache" created
buildconfig.build.openshift.io "apache" created
deployment.apps "apache" created
service "apache" created
--> Success
Build scheduled, use 'oc logs -f buildconfig/apache' to track its progress.
Application is not exposed. You can expose services to the outside world by executing one or more of the commands below:
'oc expose service/apache'
Run 'oc status' to view your app.
Isso fará com que o Openshift baixe a imagem base para a construção de uma nova imagem que terá
o conteúdo do repositório https://github.com/sclorg/httpd-ex.git
.
Podemos acompanhar a construição através do comando:
oc logs -f buildconfig/apache
E por último, podemos expor a nossa aplicação publicamente:
oc expose svc/apache
Precisaremos adicionar o endereço apache-ola-openshift.apps.openshift.local
em nosso /etc/hosts
ou utilizar o curl:
curl -H 'Host: apache-ola-openshift.apps.openshift.local' 192.168.100.99
Com isso, temos uma infraestrutura de Openshift muito próxima ao que é utilizado em máquinas físicas pelo mundo afora.