Guia Prático: Como Configurar um Cluster de OpenShift Origin

Guia Prático: Como Configurar um Cluster de OpenShift Origin

Esse post tem como objetivo criar um cluster de OpenShift Origin com um master e dois nós, a fim de fazer o deploy automático e definir o fluxo de integração contínua e entrega contínua para aplicações.

Openshift Origin é um projeto de código aberto que mantém uma plataforma de aplicações baseados em contêiner, utilizando Docker, Kubernetes e Atomic. Ele é uma versão do Kubernetes otimizada para desenvolvimento contínuo de aplicações, o mesmo adiciona ferramentas para desenvolvedores e operações centralizadas nas ferramentas do Kubernetes, permitindo um rápido desenvolvimento de aplicativos, fácil implantação, escalabilidade e manutenção do ciclo de vida à longo prazo para pequenas e grandes equipes!

openshift

Instalação Openshift via Ansible

3 máquinas virtuais rodando CentOS 7:

  • Máquina 1 – IP 192.168.1.100 – Master
  • Máquina 2 – IP 192.168.1.101 – Node1
  • Máquina 3 – IP 192.168.1.102 – Node2

Criando um cluster, através do método “Advanced” com ansible.

yum install -y epel-release yum install -y centos-release-openshift-origin yum install -y atomic-openshift-utils

O arquivo /etc/ansible/hosts, deve ter o seguinte conteúdo.

[OSEv3:children]
masters
nodes

[OSEv3:vars]
ansible_ssh_user=root

deployment_type=origin

[masters]
192.168.1.100

[etcd]
192.168.1.100

[nodes]
192.168.1.100 openshift_node_labels="{'region': 'infra', 'zone': 'default'}"
192.168.1.102 openshift_node_labels="{'region': 'primary', 'zone': 'east'}"

Gerar par de chaves ssh.

ssh-keygen

Garantir acesso entre o master e os nodes sem pedir senha, para não gerar erros na execução do playbook.

ssh-copy-id root@192.168.1.100
ssh-copy-id root@192.168.1.101
ssh-copy-id root@192.168.1.102

Executar o playbook para criação do cluster.

ansible-playbook /usr/share/ansible/openshift-ansible/playbooks/byo/config.yml

Pode-se ver quantos nodes existem no cluster, com o comando:

oc get nodes

Adicione um Nó ao Cluster

Após a execução do playbook ansible, ele fará as configurações iniciais do cluster, e mostrará que existem 2 nós, logo em seguida, será adicionado mais nó no cluster, colocando o ip do mesmo na tag [nodes] do playbook, e alterando o valor de “zone”.

[OSEv3:children]
masters
nodes

[OSEv3:vars]
ansible_ssh_user=root
deployment_type=origin

[masters]
192.168.1.100

[etcd]
192.168.1.100

[nodes]
192.168.1.100 openshift_node_labels="{'region': 'infra', 'zone': 'default'}"
192.168.1.101 openshift_node_labels="{'region': 'primary', 'zone': 'east'}"
192.168.1.103 openshift_node_labels="{'region': 'primary', 'zone': 'west'}"

Executar novamente o playbook:

ansible-playbook /usr/share/ansible/openshift-ansible/playbooks/byo/config.yml

Em seguida, ele terá adicionado mais um nó, para validar:

oc get nodes

Após isso o frontend estará disponível no endereço “https://192.168.1.100:8443/console”
Por padrão, ele vem com dois usuários (system e developer), ambos com a senha “admin”, e também não há bloqueios de acesso, aceitando qualquer usuário e senha, caso haja necessidade de alterar o gerenciador de identidades, é necessário fazer as configurações no arquivo “Master Configuration File”, “/etc/origin/master/master-config.yaml”.

Deploy de um aplicação

Existem três maneiras de fazer deploy de aplicações:

  • Usando por base algum template já criado na CLI, que pode ser personalizado.
  • Usando alguma imagem docker previamente criada, ou buscando alguma no docker hub.
  • Importando o arquivo YAML ou JSON.

Para fazer o deploy da nossa aplicação de teste “newapp”, foi necessário criar um template do zero, pois se trata de uma aplicação nova e não existe esse template por default.
O template no Openshift é apenas uma lista de objetos arbitrários, ou seja, a ordem dos objetos não influencia na execução, elas apenas precisam existir no mesmo. Ele usa o formato JSON e é divido em “Blocos”, onde cada bloco tem uma função especifica, conforme explicado abaixo:

Bloco “template”:

{
"kind": "Template",
"apiVersion": "v1",
"metadata": {
"name": "newapp",
"creationTimestamp": null,
"annotations": {
"description": "Build de uma aplicacao flask + mongo",
"tags": "instant-app,python,flask",
"iconClass": "icon-python"
}
},
"labels": {
"template": "newapp"
},

“name” = Nome único para cada template,
“description” = Breve descrição do template,
“tags” = tags para agrupar o template no frontend,
“iconClass” = ícone que aparecerá no frontend para o template,
“labels” = Rotulo que outros blocos do template poderão usar como referencia.
Bloco “objects” (lista de objetos, usados no buildconfig)

{
"kind": "Secret",
"apiVersion": "v1",
"metadata": {
"name": "sshsecret"
},
"data": { "ssh-privatekey": "CHAVE_PRIVADA_SSH"
}
},
{
"kind": "Service",
"apiVersion": "v1",
"metadata": {
"name": "${NAME}",
"annotations": {
"description": "pods"
}
},
"spec": {
"ports": [
{
"name": "web",
"port": 80,
"targetPort": "newappport"
}
],

“Secret” = Objeto usado para criar dentro do container um arquivo,
“name” = Nome do arquivo a ser criado,
“data” = Valor desse arquivo (nesse caso, a chave privada para clonar o projeto do nosso gitlab),
“Service” = Objeto usado para criar uma regra de redirecionamento de portas para o container,
“name” = Nesse caso foi usado o nome como parâmetro (caso haja necessidade de alteração do nome em diferentes situações), se esse valor for omitido, o OpenShift definirá um valor por default,
“spec” = Especificações desse objeto,
“ports” = Informações das portas,
“name” = Nome do encaminhamento,
“port” = Porta do host (maquina definida como “router”, no caso o próprio master),
“targetPort” = Porta do container, nesse caso foi criado um alias para a mesma, pois isso será declarado no BuildConfig.

{
"name": "${NAME}"
}
}
},
{
"kind": "Route",
"apiVersion": "v1",
"metadata": {
"name": "${NAME}"
},
"spec": {
"host": "${APPLICATION_DOMAIN}",
"to": {
"kind": "Service",
"name": "${NAME}"
},
"tls": {
"termination": "edge",
"insecureEdgeTerminationPolicy": "Allow"
}
}
},
{
"kind": "ImageStream",
"apiVersion": "v1",
"metadata": {
"name": "${NAME}",
"annotations": {
"description": "Registra todas as alteracoes feitas na imagem da aplicacao"
}
}
},

“route” = Faz a criação da rota no node definido como master (haproxy),
“host” = Definido como variável, permitindo a personalização do domínio Ex: (newapp-hom.teste.com.br),
“tls” = Sessão onde são tratados os certificados e regras de rewrite (por default vem como Allow, permitindo o http),
“ImageStream” = Gera log da imagem utilizada, a cada alteração feita.

Bloco BuildConfig:

"kind": "BuildConfig",
"apiVersion": "v1",
"metadata": {
"name": "${NAME}",
"annotations": {
"description": "Definicao de como sera feito o build da aplicacao"
}
},
"spec": {
"source": {
"type": "Git",
"git": {
"uri": "${SOURCE_REPOSITORY_URL}",
"ref": "${SOURCE_REPOSITORY_REF}"
},
"sourceSecret": {
"name": "sshsecret"
},
"contextDir": "/"
},
"strategy": {
"type": "Source",
"sourceStrategy": {
"from": {
"kind": "ImageStreamTag",
"namespace": "openshift",
"name": "python:2.7"
}
}
},
"output": {
"to": {
"kind": "ImageStreamTag",
"name": "${NAME}:latest"
}
},

“BuildConfig” = O objeto do template responsável por criar uma imagem docker já com a aplicação, ou seja, pega uma imagem no docker hub Ex: openshift/php-55-centos7 (Centos com php5) e adiciona a nossa aplicação que o mesmo irá buscar no Gitlab,
“Source” = Local onde conterá o último commit da App,
“git” = informações referentes ao Git para garantir o build correto, na branch correta, etc.
“uri” = Nome do recurso que será feito o clone,
“ref” = Branch onde estará o recurso,
“sourceSecret” = Chave que será utilizada para baixar o código,
“ImageStreamTag” = Recebe o namespace da imagem, nome da linguagem e versão,
“ImageStreamTag” = Nome que será atribuído a essa nova imagem (com o código),
OBS: Esse bloco utiliza em background o comando s2i, portanto caso haja a necessidade de testes prévios, ele é será muito útil, segue um exemplo de utilização do mesmo.
s2i builder Newapp/ centos/python-27-centos7 newapp-teste

Triggers:

"triggers": [
{
"type": "Generic",
"generic": {
"secret": "sshsecret",
"allowEnv": true
}
}
]
}
},

“type” = Especifica de quem esse template receberá triggers Ex: (git, Gitlab, Github), a genérica geralmente é usada para git e gitlab, existe uma especifica para o Github,
“secret” = qual secret será usada quando essa trigger for acionada,
“allowEnv” = Permite o uso de variáveis de ambientes do container.
OBS: Para funcionar corretamente as “Secrets”, será necessário gerar a chave primaria no node master, conforme os passos abaixo e colocar a pública no Gitlab.

oc secrets new sshsecret ssh-privatekey=$HOME/.ssh/id_rsa secret/sshsecret

Permitir que o builder do OpenShift use a chave

oc secrets link builder sshsecret

Exportar a chave para todos os namespaces

oc export secrets

Bloco “DeploymentConfig”

Bloco “DeploymentConfig”
{
"kind": "DeploymentConfig",
"apiVersion": "v1",
"metadata": {
"name": "${NAME}",
"annotations": {
"description": "Definicao de como sera feito o build da aplicacao",
"iconClass": "icon-python"
}
},
"spec": {
"strategy": {
"type": "Rolling"
},
"triggers": [
{
"type": "ImageChange",
"imageChangeParams": {
"automatic": true,
"containerNames": [
"newapp"
],
"from": {
"kind": "ImageStreamTag",
"name": "${NAME}:latest"
}
}
},
{
"type": "ConfigChange"
}
],
"replicas": 1,
"selector": {
"name": "${NAME}"
},
"template": {
"metadata": {
"name": "${NAME}",
"labels": {
"name": "${NAME}"
}
},
"spec": {
"containers": [
{
"name": "newapp",
"image": "${NAME}",
"ports": [
{
"name": "newappport",
"containerPort": 8080,
"protocol": "TCP"
}
],
"readinessProbe": {
"timeoutSeconds": 3,
"initialDelaySeconds": 3,
"httpGet": {
"path": "/",
"port": 8080
}
},
"livenessProbe": {
"timeoutSeconds": 3,
"initialDelaySeconds": 30,
"httpGet": {
"path": "/",
"port": 8080
}
}
}
]
}
}
}
}
],

Tipos de strategy:
“Rolling” = Tipo de estratégia que mantém o ciclo de vida do container quando receber a webhook,
“Recreate” = Não mantém o clico de vida após receber a webhook ,
“trigger” = Ao receber a webhook (aviso de alteração na imagem) automaticamente ele aplicará a ação de acordo com a strategy, e garantirá que a última versão estará em produção,
“Replicas” = Número de replicas que serão criadas por default ao fazer deploy dessa imagem template,
“containers” = Lista de informações passadas para criação e recriação dessa imagem,
“name” = alias para a porta do container,
“containerPort” = porta do container que a aplicação estará ouvindo,
“protocol” = protocolo que a mesma trabalha,

Bloco de parâmetros:

"parameters": [
{
"name": "NAME",
"description": "Rota para o flask",
"value": "newapp"
},
{
"name": "SOURCE_REPOSITORY_URL",
"description": "Codigo fonte da aplicacao",
"value": "git@gitlab.teste.com.br:devops/Newapp.git"
},
{
"name": "SOURCE_REPOSITORY_REF",
"description": "Branch",
"value": "master"
},
{
"name": "NAMESPACE",
"displayName": "Namespace",
"description": "O namespace onde ficam as imagens, por default o openshift",
"value": "openshift"
},
{
"name": "APPLICATION_DOMAIN",
"description": "O hostname para a rota da sua aplicacao",
"value": "newapp.com.br"
},
{
"name": "VOLUME_CAPACITY",
"displayName": "Tamanho do Volume de dados [select:5Gi=5GB:10Gi=10GB:20Gi=20GB]",
"description": "Espaco disponivel para seus dados",
"value": "5Gi",
"required": true
}
]
}

“parameters” = Esse bloco é responsável por definir todas as variáveis utilizadas no template, caso haja necessidade de fazer deploy da mesma aplicação com diferentes parametros se torna possível com o mesmo template,
“name” = Nome do parametro, utilizado no template com ${},
“description” = aparecerá no frontend como exemplo de preenchimento,
“value” = valor que será usado por default.
Após finalizar a escrita do template, podemos criar um diretório para os templates personalizados dentro de “/usr/share/openshift/”

mkdir /usr/share/openshift/templates

Para adicionar o template criado ao cluster, no namespace openshift

oc create -f newapp.json -n openshift

Ajustes finais via frontend

Nesse momento, o template “newapp”, estará pronto para ser usado no frontend. Após selecionar, podemos fazer alteração dos parâmetros.

No frontend, podemos criar um novo projeto com o nome de deploy-newapp:

openshift 01

Logo em seguida, ele retornará todos os templates que existem no namespace “openshift”, podemos fazer um filtro pelo nosso template.

openshift 02

Após clicar no nosso template, ele irá mostras todas as opções passadas como parâmetro (variáveis).

openshift 03

Caso nenhuma alteração seja feita, ele utilizará os valores default.

openshift 04

Após a criação, podemos clicar em “Go to overview”, para verificar via web o status do nosso build.No menu a esquerda, podemos verificar cada parte do nosso template.

openshift 05

– Deployments (alterações no campo “Deploymentconfig”)
– Pods (Verificar os containers ou replicas dos mesmos)
– Services (Obter informações da aplicação como ip, porta, name, etc)
– Routes (Verificar as rotas criadas pelo próprio Openshift (haproxy) ex: https://newapp.com.br)

openshift 06

– Ciclo de vida dos builds (versionamento a cada nova webhook)

openshift 07

– Limitação de recursos no projeto
– Alterações de quais usuários podem editar e ou verificar o projeto
– Gerenciar os objetos “secrets” do projeto
– Gerenciar algum outro recurso que haja no template

Storage
– Verificar os volumes criados nesse projeto

Monitoring
– Verificar os logs do projeto

Na documentação oficial da Red Hat, é recomendado que a instalação seja feita com o SELinux em modo “enforcing” e o selinux type em modo “targeted”, caso esteja diferente disso, a execução do playbook falhará.
Com isso temos um cluster de OpenShift em produção e também uma aplicação criada. Em breve farei outro post explicando como aumentar o número de réplicas, criar o “autoscaller”, utilizar certificado para tls e criar entradas DNS com “rewrite”.

Conclusão

O cluster de Openshift é muito simples de se configurar. E após entender cada campo do template, fica muito fácil criar e personalizar os templates de acordo com a aplicação, linguagem e etc.

Por isso espero que este post lhe seja útil e que te ajude a compreender de forma fácil como funciona o Openshift. 😀
Mais informações sobre o Openshift podem ser obtidas diretamente em sua documentação oficial: https://docs.openshift.org/

Anterior Recuperação de Dados em Tempo Real com PITR e BARMAN no Postgres
Próxima Garanta Alta Disponibilidade em Projetos com Postfix: Guia Prático

About author

Edgar Filho
Edgar Filho 4 posts

Edgar da Silva Costa Filho é um sysadmin apaixonado por Linux, com foco na cultura DevOps, Formado em Redes de Computadores pela FIAP. Com 4 anos de experiência profissional em Tecnologia da Informação, atualmente atuando com desenvolvimento em python, infra ágil(Docker, Puppet, Ansible, Git, Jenkins e Rundeck), NoSQL (MongoDB) e também atuando como instrutor, ministrando cursos de Linux e suas mais diversas tecnologias, capacitando equipes de TI em sistemas Linux e soluções Open Source.

View all posts by this author →

Você pode gostar também

Infraestrutura TI

Descubra o Jitsi: a solução completa para videoconferências

Logo do Jitsi Introdução Durante o momento que vivemos, basicamente todas nossas interações se tornaram virtuais, com o home office sendo a alternativa primaria para muitas empresas, tivemos um súbito

Cloud

Gerenciando custos e projetos com Kubernetes, Terraform e AWS

Olá! Às vezes algumas empresas não têm muito conhecimento em Kubernetes e acabam criando um cluster para cada projeto, o que consequentemente aumenta os custos de forma exponencial e dificulta

Notícias

4Linux se torna A.T.O do EXIN e lança curso DEVOPS Master

A 4linux acaba de se tornar um A.T.O. (Authorized Training Organization) do EXIN e juntamente teve o conteúdo de seu treinamento ‘DEVOPS Master’ aprovado, isso significa que o material didático criado