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](http://blog.4linux.com.br/wp-content/uploads/2017/05/Logotipo.Openshift.png)
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.
1 | 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.
17 | 192.168.1.100 openshift_node_labels= "{'region': 'infra', 'zone': 'default'}" |
18 | 192.168.1.102 openshift_node_labels= "{'region': 'primary', 'zone': 'east'}" |
Gerar par de chaves ssh.
Garantir acesso entre o master e os nodes sem pedir senha, para não gerar erros na execução do playbook.
1 | ssh -copy- id root@192.168.1.100 |
2 | ssh -copy- id root@192.168.1.101 |
3 | ssh -copy- id root@192.168.1.102 |
Executar o playbook para criação do cluster.
1 | ansible-playbook /usr/share/ansible/openshift-ansible/playbooks/byo/config.yml |
Pode-se ver quantos nodes existem no cluster, com o comando:
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”.
16 | 192.168.1.100 openshift_node_labels= "{'region': 'infra', 'zone': 'default'}" |
17 | 192.168.1.101 openshift_node_labels= "{'region': 'primary', 'zone': 'east'}" |
18 | 192.168.1.103 openshift_node_labels= "{'region': 'primary', 'zone': 'west'}" |
Executar novamente o playbook:
1 | ansible-playbook /usr/share/ansible/openshift-ansible/playbooks/byo/config.yml |
Em seguida, ele terá adicionado mais um nó, para validar:
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.
1 | oc secrets new sshsecret ssh -privatekey=$HOME/. ssh /id_rsa secret/sshsecret |
Permitir que o builder do OpenShift use a chave
1 | oc secrets link builder sshsecret |
Exportar a chave para todos os namespaces
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/”
1 | mkdir /usr/share/openshift/templates |
Para adicionar o template criado ao cluster, no namespace openshift
1 | 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](http://www.fordevops.com/wp-content/uploads/2017/03/Captura-de-Tela-2017-02-20-às-16.14.34-300x200.png)
Logo em seguida, ele retornará todos os templates que existem no namespace “openshift”, podemos fazer um filtro pelo nosso template.
![openshift 02](http://www.fordevops.com/wp-content/uploads/2017/03/Captura-de-Tela-2017-02-20-às-16.18.52-300x172.png)
Após clicar no nosso template, ele irá mostras todas as opções passadas como parâmetro (variáveis).
![openshift 03](http://www.fordevops.com/wp-content/uploads/2017/03/Captura-de-Tela-2017-02-20-às-16.19.44-300x275.png)
Caso nenhuma alteração seja feita, ele utilizará os valores default.
![openshift 04](http://www.fordevops.com/wp-content/uploads/2017/03/Captura-de-Tela-2017-02-20-às-16.23.10-300x182.png)
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](http://www.fordevops.com/wp-content/uploads/2017/03/Captura-de-Tela-2017-02-20-às-16.25.24-300x254.png)
– 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](http://www.fordevops.com/wp-content/uploads/2017/03/Captura-de-Tela-2017-02-20-às-16.25.37-300x227.png)
– Ciclo de vida dos builds (versionamento a cada nova webhook)
![openshift 07](http://www.fordevops.com/wp-content/uploads/2017/03/Captura-de-Tela-2017-02-20-às-16.25.46-300x217-300x217.png)
– 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/