Instalação do chef server, chef worstation, instalação do chef client via bootstrap e criação do primeiro cookbook

Chef-Logo

1. Introdução

Bom, comecei a brincar com o Chef, estou achando bem interessante, tem um monte de features que quero explorar, principalmente o fluxo de Integração contínua, delivery e pipeline com Chef.

O Chef tem uma ferramenta de administração muito legal, se chama Knife, e é uma mão na roda, toda administração de nodes e cookbooks se faz através do Knife.

Achei interessante a boa quantidade de plugins para aumentar a extensão de funcionalidades do Chef, como por exemplo plugins para a gerencia e criação de instâncias nos maiores provedores de Cloud como Amazon EC2, Azure, Google CE, Rackspace, Digital Ocean, e também plugins para virtualização como Xen e Vmware-vsphere. Também tem plugin para o Docker.

Confesso que estou bastante empolgado com o Chef.

Neste tutorial vou compartilhar algumas coisas que fiz, então vamos instalar o Chef Server, Workstation “ChefDK”, configurar alguns nodes, e a criação de um cookbook/receita.

Para quem não sabe, de forma bem resumida, o Chef é um gerenciador de configurações e automação. Com ele é possível automatizar tarefas repetitivas, como deploys de novos servidores, instalação de pacotes e aplicações, execução de comandos, padronização de arquivos e configurações e orquestração de clientes. Através da orquestração você consegue executar tarefas e comandos em clientes. Os clientes serão referenciados como nodes.

Vamos conhecer alguns componentes do Chef
Chef Server → O Chef Server é core da infraestrutura de gerenciamento e automação, é nele que serão armazenados os cookbooks e receitas, assim como a comunicação e aplicação de receitas nos nodes.

Chef Client → Cada node precisa ter um cliente do Chef instalado; e este vai falar com o Chef Server, procurar por cookbooks e aplicá-los nos nodes.

Workstation → Workstation são os clientes administrativos do Chef Server.
Um Workstation pode ser seu próprio desktop, ou uma vm dedicada apenas para isto. É através do Workstation que criaremos nossos cookbooks e receitas e enviaremos para o Chef Server. Toda interação com o Chef Server será através do Workstation. Diferente de outros gerenciadores de configuração como Puppet e Ansible, da qual você se loga no servidor central (Puppet e Ansible) e faz as configurações diretamente no servidor, no Chef esta interação acontece da seguinte forma: Workstation → Chef Server.

Geralmente é um Workstation por administrador, cada integrante da equipe que vai trabalhar gerenciando o Chef pode ter seu próprio cliente workstation. Sua equipe tem 10 Sysadmins/Devops? Então você terá que ter 10 workstations, a não ser que queira dividir sua máquina com outras pessoas ;).

Nodes → Nodes são os clientes que receberão as configurações e automação. Neste caso são seus servidores, talvez desktops que você queira gerenciar as configurações, sua infra na nuvem, enfim, qualquer equipamento que você queira gerenciar.

Cookbook e Recipes → Cookbook e Receitas são as configurações que serão aplicadas nos nodes. Os cookbooks e receitas serão criadas nas máquinas de Workstation e enviadas para o Chef Server. Uma vez no Chef Server, as receitas serão enviadas e aplicadas nos nodes, sendo assim quando você quiser automatizar algum recurso nos nodes, você vai criar um cookbook com uma receita.
Exemplo: Vou criar um cookbook Pacotes, e dentro deste cookbook Pacotes, eu vou escrever uma receita, por exemplo install-mysql.rb, e dentro desta receita vou criar os passos necessários para instalar o mysql nos nodes.
Sendo assim eu tenho um cookbook chamado “Pacote”, e uma receita de instalação chamada “install-mysql.rb”.

Knife → É o command-line “CLI” tool do Chef, é com ele que você vai interagir com o Chef Server.

2. Pré-requisitos e infraestrutura

Chef-Infra
Dê uma olhada neste link para saber o quanto de memória, CPU, disco e etc para sua infraestrutura.
https://docs.chef.io/chef_system_requirements.html

Sistema Operacional:
Ubuntu 14.04 x86_64 – instalação mínima.

Versões utilizadas neste tutorial:
Chef server – 12.6.0-1
Chef DK – 0.14.25-1
Chef client – 12.10.24-1

Hostname
Todos os nodes precisam estar configurados com o correto FQDN.

# cat /etc/hosts | grep chef
10.0.2.40	chef-server-01.devopslab.com.br	chef-server-01

# cat /etc/hostname 
chef-server-01 

# hostname
chef-server-01

# hostname -d
devopslab.com.br

# hostname -f
chef-server-01.devopslab.com.br

Hosts
Chef Server
chef-server-01.devopslab.com.br

Chef Workstation
chef-workstation-01.devopslab.com.br

Chef nodes
chef-client-01.devopslab.com.br
chef-client-02.devopslab.com.br
chef-client-03.devopslab.com.br

3. Preparação do ambiente – Instalação do repositório apt

Os repositórios serão instalados tanto no chef-server como no chef workstation.

Ative o apt-get para poder buscar pacotes em urls https.

# apt-get install apt-transport-https

Adicione a Chave pública do Chef.

# wget -qO - https://downloads.chef.io/packages-chef-io-public.key | sudo apt-key add -

Crie um repositório Apt.

#cd /etc/apt/sources.list.d/
# echo "deb https://packages.chef.io/<CHANNEL>-apt <DISTRIBUTION> main" > chef-<CHANNEL>.list

Onde:
Substitua o CHANNEL por stable.
E DISTRIBUTION pelo o nome da sua distribuição Debian/Ubuntu.
Debian 6: squeeze
Debian 7: wheezy
For Debian 8: jessie
For Ubuntu 10.04: lucid
For Ubuntu 12.04: precise
For Ubuntu 14.04: trusty

# echo "deb https://packages.chef.io/stable-apt trusty main" > chef-stable.list

# cat chef-stable.list 
deb https://packages.chef.io/stable-apt trusty main

Atualize o cache do apt-get.

# apt-get update

4. Chef Server – Instalação do Servidor Chef – Chef Server

Antes da instalação verifique o hostname.

# hostname -f
chef-server-01.devopslab.com.br

# hostname
chef-server-01

Para prosseguir você precisa ter os repositórios instalados, coisa que já foi feito em um passo anterior.

# apt-get update
# apt-get install chef-server-core

Instalação de todos os serviços do Chef.

# chef-server-ctl reconfigure

Vai demorar alguns minutos, pois serão instalados vários componentes, como PostgreSQL, Redis, Nginx, RabbitMQ, Solr e Chef Server. O resultado será algo parecido como este:

Recipe: private-chef::partybus
  * execute[set initial migration level] action run
    - execute cd /opt/opscode/embedded/service/partybus && ./bin/partybus init
  * ruby_block[migration-level file sanity check] action run (skipped due to not_if)
Recipe: private-chef::opscode-chef-mover
  * execute[restart_opscode-chef-mover_log_service] action run
    - execute /opt/opscode/embedded/bin/sv restart /opt/opscode/sv/opscode-chef-mover/log
Recipe: private-chef::redis_lb
  * execute[restart_redis_lb_log_service] action run
    - execute /opt/opscode/embedded/bin/sv restart /opt/opscode/sv/redis_lb/log
Recipe: private-chef::nginx
  * execute[restart_nginx_log_service] action run
    - execute /opt/opscode/embedded/bin/sv restart /opt/opscode/sv/nginx/log

Running handlers:
Running handlers complete

Deprecated features used!
  An attempt was made to change sysvinit_id from "SV" to nil by calling sysvinit_id(nil). In Chef 12, this does a get rather than a set. In Chef 13, this will change to set the value to nil. at 1 location:
    - /var/opt/opscode/local-mode-cache/cookbooks/enterprise/recipes/runit.rb:31:in `block in from_file'

Chef Client finished, 394/461 resources updated in 05 minutes 47 seconds
Chef Server Reconfigured!

4.1. Criação de um usuário administrativo do Chef e uma organização

Você pode criar quantos usuários forem necessários. Este usuário será utilizado no chef workstation que vamos configurar depois deste passo.

Organização geralmente é um por empresa, mas nada te impede de criar mais.

Usuário
Sintaxe:
chef-server-ctl user-create NOME_USUARIO PRIMEIRO_NOME ULTIMO_NOME EMAIL ‘SENHA’ –filename USUARIO_CHAVE

# mkdir /root/.chef
# chef-server-ctl user-create adminleonardo Leonardo Admin leonardo@devopslab.com.br 'senha12345' --filename /root/.chef/adminleonardo.pem

Organização
Sintaxe:
chef-server-ctl org-create short_name ‘full_organization_name’ –association_user user_name –filename ORGANIZACAO-CHAVE.pem

# chef-server-ctl org-create devopslab 'DevOpsLab Technology ltda.' --association_user adminleonardo --filename /root/.chef/orgdevopslab.pem

Verificando o status do Chef Server.

root@chef-server-01:/# chef-server-ctl status
run: bookshelf: (pid 866) 1475s; run: log: (pid 842) 1475s
run: nginx: (pid 864) 1475s; run: log: (pid 840) 1475s
run: oc_bifrost: (pid 877) 1475s; run: log: (pid 876) 1475s
run: oc_id: (pid 862) 1475s; run: log: (pid 835) 1475s
run: opscode-erchef: (pid 863) 1475s; run: log: (pid 836) 1475s
run: opscode-expander: (pid 871) 1475s; run: log: (pid 868) 1475s
run: opscode-solr4: (pid 865) 1475s; run: log: (pid 843) 1475s
run: postgresql: (pid 872) 1475s; run: log: (pid 833) 1475s
run: rabbitmq: (pid 875) 1475s; run: log: (pid 869) 1475s
run: redis_lb: (pid 870) 1475s; run: log: (pid 839) 1475s

Sucesso!!!.

5. Chef Workstation – Instalação Chef Workstation

Instale o repositório do Chef.
O Workstation provavelmente será o seu próprio Desktop ou uma máquina virtual pequena, fica a seu critério.
Eu vou utilizar uma VM em Virtualbox só para ser meu chef workstation.

Instalação do Chef Development Kit.

# apt-get install chefdk

Verificação de todos os componentes instalados.

root@chef-workstation-01:~# chef verify
Running verification for component 'berkshelf'
Running verification for component 'test-kitchen'
Running verification for component 'tk-policyfile-provisioner'
Running verification for component 'chef-client'
Running verification for component 'chef-dk'
Running verification for component 'chef-provisioning'
Running verification for component 'chefspec'
Running verification for component 'generated-cookbooks-pass-chefspec'
Running verification for component 'rubocop'
Running verification for component 'fauxhai'
Running verification for component 'knife-spork'
Running verification for component 'kitchen-vagrant'
Running verification for component 'package installation'
Running verification for component 'openssl'
Running verification for component 'inspec'
Running verification for component 'delivery-cli'
Running verification for component 'git'
Running verification for component 'opscode-pushy-client'
Running verification for component 'chef-sugar'
Running verification for component 'knife-supermarket'
.................................................................................
Verification of component 'fauxhai' succeeded.
Verification of component 'kitchen-vagrant' succeeded.
Verification of component 'openssl' succeeded.
Verification of component 'delivery-cli' succeeded.
Verification of component 'inspec' succeeded.
Verification of component 'knife-supermarket' succeeded.
Verification of component 'berkshelf' succeeded.
Verification of component 'git' succeeded.
Verification of component 'opscode-pushy-client' succeeded.
Verification of component 'test-kitchen' succeeded.
Verification of component 'knife-spork' succeeded.
Verification of component 'chef-sugar' succeeded.
Verification of component 'tk-policyfile-provisioner' succeeded.
Verification of component 'chefspec' succeeded.
Verification of component 'generated-cookbooks-pass-chefspec' succeeded.
Verification of component 'rubocop' succeeded.
Verification of component 'package installation' succeeded.
Verification of component 'chef-client' succeeded.
Verification of component 'chef-dk' succeeded.
Verification of component 'chef-provisioning' succeeded.

Criação de um repositório para o Chef
Crie um repositório Chef, que será seu diretório de trabalho, pois serão armazenados todas as suas receitas do Chef (cookbooks).

# chef generate repo chef-repo

Configuração do Knife
Knife é uma ferramenta que faz uma interface entre o seu repositório local “chef-repo” e o Chef Server.
Quando você cria uma nova receita “cookbook”, você vai utilizar o Knife para jogar a configuração para o Chef Server.

Crie o diretório .chef.

# mkdir -p ~/chef-repo/.chef

Copie as 2 chaves que foi criada na instalação do Chef Server para a pasta .chef.
Lembra desta 2 chaves? Uma chave foi criada para a organização e uma para o usuário admin do Chef.

Chaves:
Admin: adminleonardo.pem
Organization: orgdevopslab.pem

root@chef-workstation-01:~# scp root@chef-server-01:/root/.chef/*.pem /root/chef-repo/.chef/
root@chef-server-01's password: 
adminleonardo.pem                                                                                                                                           100% 1678     1.6KB/s   00:00    
orgdevopslab.pem 100% 1674     1.6KB/s   00:00   

root@chef-workstation-01:~# ls /root/chef-repo/.chef
adminleonardo.pem  orgdevopslab.pem

Criação do arquivo knife.rb.
# cd /root/chef-repo/.chef
# knife configure

# knife configure
WARNING: No knife configuration file found
Where should I put the config file? [/root/.chef/knife.rb] /root/chef-repo/.chef/knife.rb        
Please enter the chef server URL: [https://chef-workstation-01:443] https://chef-server-01/organizations/devopslab
Please enter an existing username or clientname for the API: [leonardo] adminleonardo
Please enter the validation clientname: [chef-validator] devopslab-validator
Please enter the location of the validation key: [/etc/chef-server/chef-validator.pem] /root/chef-repo/.chef/orgdevopslab.pem
Please enter the path to a chef repository (or leave blank): /root/chef-repo 
*****

You must place your client key in:
  /root/chef-repo/.chef/adminleonardo.pem
Before running commands with Knife

*****

You must place your validation key in:
  /root/chef-repo/.chef/orgdevopslab.pem
Before generating instance data with Knife

*****
Configuration file written to /root/chef-repo/.chef/knife.rb

Vou explicar cada linha.
1.
Where should I put the config file? [/root/.chef/knife.rb] /root/chef-repo/.chef/knife.rb
Aqui é a localização do arquivo knife.rb.

2.
Please enter the chef server URL: [https://chef-workstation-01:443] https://chef-server-01/organizations/devopslab

Url do Chef Server + organização. Para verificar esta url, faça o login no Chef Server e rode o comando:
chef-server-ctl org-show

# chef-server-ctl org-show
devopslab: https://127.0.0.1/organizations/devopslab

Substitua o 127.0.0.1 pelo nome fqdn no seu servidor Chef.

3.
Please enter an existing username or clientname for the API: [leonardo] adminleonardo

Aqui você coloca o usuário criado na instalação do Chef Server, no meu caso é o usuário “adminleonardo”. Substitua pelo usuário que você definiu na instalação.

4.
Please enter the validation clientname: [chef-validator] devopslab-validator

Aqui é um nome para identificar o Chef Server, definido ao seu critério. Eu sugiro algo como
ORGNIZATION-NAME-validator.

5.
Please enter the location of the validation key: [/etc/chef-server/chef-validator.pem] /root/chef-repo/.chef/orgdevopslab.pem

Nesta linha é definido o caminho da chave criada para a organização. Esta chave foi criada na instalação do Chef Server, e no meu caso é a chave: “orgdevopslab.pem”.

6.
Please enter the path to a chef repository (or leave blank): /root/chef-repo

Simplesmente Informe a localização do seu repositório; que foi criado logo acima em “chef generate repo chef-repo”.

knife.rb completo.

# cat knife.rb
log_level                :info
log_location             STDOUT
node_name                'adminleonardo'
client_key               '/root/chef-repo/.chef/adminleonardo.pem'
validation_client_name   'devopslab-validator'
validation_key           '/root/chef-repo/.chef/orgdevopslab.pem'
chef_server_url          'https://chef-server-01/organizations/devopslab'
syntax_check_cache_path  '/root/chef-repo/.chef/syntax_check_cache'
cookbook_path [ '/root/chef-repo/cookbooks' ]

Importando o certificado SSL do Chef Server.
Você precisa estabelecer uma relação de confiança com o Chef Server importando o certificado SSL do mesmo.

# knife ssl fetch

root@chef-workstation-01:~/chef-repo# cd /root/chef-repo
root@chef-workstation-01:~/chef-repo# knife ssl fetch
WARNING: Certificates from chef-server-01 will be fetched and placed in your trusted_cert
directory (/root/chef-repo/.chef/trusted_certs).

Knife has no means to verify these are the correct certificates. You should
verify the authenticity of these certificates after downloading.

Adding certificate for chef-server-01 in /root/chef-repo/.chef/trusted_certs/chef-server-01.crt

Validação
Para validar a comunicação com o Chef Server execute o comando “knife client list”.

root@chef-workstation-01:~/chef-repo# knife client list
devopslab-validator

5.1. Ruby

Ao instalar o ChefDK, será instalado um versão do Ruby, no entando este Ruby não estará no PATH dos usuários, ou seja você não vai conseguir utilizar.

Sendo assim, configure a variável $PATH da Workstation de forma que o Ruby possa ser encontrado. Então logue na Workstation, com o usuário que vai administar o chef (knife e etc) e execute:

# echo ‘eval “$(chef shell-init bash)”‘ >> ~/.bash_profile
# source ~/.bash_profile

Para verificar se esta tudo ok faça:
# which ruby
/opt/chefdk/embedded/bin/ruby

O Ruby está mapeado no PATH.

5.2. Definindo um Editor

Ao editar cookbooks, recieitas, e outras configurações do Chef, será necessário ter um editor de texto definido.
Aí você escolhe o que você preferir, eu gosto do Vim.
# export EDITOR=’vim’

Ser for um nano
# export EDITOR=’nano’

6. Chef-client bootstrap – Instalação do cliente chef via bootstrap

Nossos clientes, ou seja todos os servidores, desktops, e qualquer máquina que será gerenciada pelo Chef-server será tratada como Nodes.

Chef-client é o agente que será instalado nos Nodes para fazer a comunicação com o Chef-Server. Todos os Nodes precisam ter um Chef-client instalado.

Vamos fazer uma instalação do Chef-client remotamente, via Bootstrap, ou seja, o próprio Chef vai fazer a instalação dos clientes nos Nodes.

A ferramenta que vai disparar o bootstrap é o Knife, que acabamos de configurar.
O Knife utiliza o SSH para fazer a instalação do Chef-client nos Nodes.
Você precisa ter um usuário com permissões de sudo.

Pode ser usado tanto SSH com senha ou SSH com chave de identificação para fazer a autenticação nos Nodes, tudo depende de como você utiliza o SSH na sua infraestrutura.

6.1. Instalação do Chef-client em um Ubuntu-Server-14.04 – Bootstrap chef client em Ubuntu 14

Vamos fazer a instalação do Chef-client no Ubuntu-Server-14.04 utilizando um usuário e senha com permissões de sudo.

Comando:
#knife bootstrap 192.168.0.21 -x username -P password –sudo
#knife bootstrap chef-client-02.devopslab.com.br -x meu_usuario -P minha_senha –sudo

# root@chef-workstation-01:~# cd chef-repo/

root@chef-workstation-01:~/chef-repo# knife bootstrap chef-client-02.devopslab.com.br -x meu_usuario -P minha_senha --sudo
Doing old-style registration with the validation key at /root/chef-repo/.chef/orgdevopslab.pem...
Delete your validation key in order to use your user credentials instead

Connecting to chef-client-02.devopslab.com.br
chef-client-02.devopslab.com.br -----> Installing Chef Omnibus (-v 12)
chef-client-02.devopslab.com.br downloading https://omnitruck-direct.chef.io/chef/install.sh
chef-client-02.devopslab.com.br   to file /tmp/install.sh.1081/install.sh
chef-client-02.devopslab.com.br trying curl...
chef-client-02.devopslab.com.br ubuntu 14.04 x86_64
chef-client-02.devopslab.com.br Getting information for chef stable 12 for ubuntu...
chef-client-02.devopslab.com.br downloading https://omnitruck-direct.chef.io/stable/chef/metadata?v=12&p=ubuntu&pv=14.04&m=x86_64
chef-client-02.devopslab.com.br   to file /tmp/install.sh.1086/metadata.txt
chef-client-02.devopslab.com.br trying curl...
chef-client-02.devopslab.com.br sha1	7d30b300f95f00036919ee8bf3b95ab73429e57e
chef-client-02.devopslab.com.br sha256	663d6c42c90bbb9463bc02a7c5d777f7aa6ebd52c071a0c1963bc8c4db76dea2
chef-client-02.devopslab.com.br url	https://packages.chef.io/stable/ubuntu/14.04/chef_12.10.24-1_amd64.deb
chef-client-02.devopslab.com.br version	12.10.24
chef-client-02.devopslab.com.br downloaded metadata file looks valid...
chef-client-02.devopslab.com.br downloading https://packages.chef.io/stable/ubuntu/14.04/chef_12.10.24-1_amd64.deb
chef-client-02.devopslab.com.br   to file /tmp/install.sh.1086/chef_12.10.24-1_amd64.deb
chef-client-02.devopslab.com.br trying curl...
chef-client-02.devopslab.com.br Comparing checksum with sha256sum...
chef-client-02.devopslab.com.br Installing chef 12
chef-client-02.devopslab.com.br installing with dpkg...
chef-client-02.devopslab.com.br Selecting previously unselected package chef.
(Reading database ... 57726 files and directories currently installed.)
chef-client-02.devopslab.com.br Preparing to unpack .../chef_12.10.24-1_amd64.deb ...
chef-client-02.devopslab.com.br Unpacking chef (12.10.24-1) ...
chef-client-02.devopslab.com.br Setting up chef (12.10.24-1) ...
chef-client-02.devopslab.com.br Thank you for installing Chef!
chef-client-02.devopslab.com.br Starting the first Chef Client run...
chef-client-02.devopslab.com.br Starting Chef Client, version 12.10.24
chef-client-02.devopslab.com.br Creating a new client identity for chef-client-02.devopslab.com.br using the validator key.
chef-client-02.devopslab.com.br resolving cookbooks for run list: []
chef-client-02.devopslab.com.br Synchronizing Cookbooks:
chef-client-02.devopslab.com.br Installing Cookbook Gems:
chef-client-02.devopslab.com.br Compiling Cookbooks...
chef-client-02.devopslab.com.br [2016-05-29T09:31:46-03:00] WARN: Node chef-client-02.devopslab.com.br has an empty run list.
chef-client-02.devopslab.com.br Converging 0 resources
chef-client-02.devopslab.com.br 
chef-client-02.devopslab.com.br Running handlers:
chef-client-02.devopslab.com.br Running handlers complete
chef-client-02.devopslab.com.br Chef Client finished, 0/0 resources updated in 03 seconds

Validando:
knife node list
knife client list

root@chef-workstation-01:~/chef-repo# knife node list
chef-client-02.devopslab.com.br

root@chef-workstation-01:~/chef-repo# knife client list
chef-client-02.devopslab.com.br
devopslab-validator

root@chef-workstation-01:~/chef-repo# 

Veja que o Chef detecta automaticamente qual Sistema operacional está sendo utilizado.

chef-client-02.devopslab.com.br ubuntu 14.04 x86_64
chef-client-02.devopslab.com.br Getting information for chef stable 12 for ubuntu...
chef-client-02.devopslab.com.br downloading https://omnitruck-direct.chef.io/stable/chef/metadata?v=12&p=ubuntu&pv=14.04&m=x86_64

6.2. Instalação do Chef-client em um Centos 7 x86_64 – Bootstrap chef client em Centos 7

Vamos fazer a instalação do Chef-client no Centos 7 utilizando um usuário e senha com permissões de sudo.
# root@chef-workstation-01:~# cd chef-repo/
# knife bootstrap chef-client-03.devopslab.com.br -x meu_usuario -P minha_senha –sudo

root@chef-workstation-01:~/chef-repo# knife bootstrap chef-client-03.devopslab.com.br -x meu_usuario -P minha_senha --sudo
Doing old-style registration with the validation key at /root/chef-repo/.chef/orgdevopslab.pem...
Delete your validation key in order to use your user credentials instead

Connecting to chef-client-03.devopslab.com.br
chef-client-03.devopslab.com.br -----> Installing Chef Omnibus (-v 12)
chef-client-03.devopslab.com.br downloading https://omnitruck-direct.chef.io/chef/install.sh
chef-client-03.devopslab.com.br   to file /tmp/install.sh.3048/install.sh
chef-client-03.devopslab.com.br trying wget...
chef-client-03.devopslab.com.br el 7 x86_64
chef-client-03.devopslab.com.br Getting information for chef stable 12 for el...
chef-client-03.devopslab.com.br downloading https://omnitruck-direct.chef.io/stable/chef/metadata?v=12&p=el&pv=7&m=x86_64
chef-client-03.devopslab.com.br   to file /tmp/install.sh.3053/metadata.txt
chef-client-03.devopslab.com.br trying wget...
chef-client-03.devopslab.com.br sha1	4def83368a1349959fdaf0633c4d288d5ae229ce
chef-client-03.devopslab.com.br sha256	6f00c7bdf96a3fb09494e51cd44f4c2e5696accd356fc6dc1175d49ad06fa39f
chef-client-03.devopslab.com.br url	https://packages.chef.io/stable/el/7/chef-12.10.24-1.el7.x86_64.rpm
chef-client-03.devopslab.com.br version	12.10.24
chef-client-03.devopslab.com.br downloaded metadata file looks valid...
chef-client-03.devopslab.com.br downloading https://packages.chef.io/stable/el/7/chef-12.10.24-1.el7.x86_64.rpm
chef-client-03.devopslab.com.br   to file /tmp/install.sh.3053/chef-12.10.24-1.el7.x86_64.rpm
chef-client-03.devopslab.com.br trying wget...
chef-client-03.devopslab.com.br Comparing checksum with sha256sum...
chef-client-03.devopslab.com.br Installing chef 12
chef-client-03.devopslab.com.br installing with rpm...
chef-client-03.devopslab.com.br warning: /tmp/install.sh.3053/chef-12.10.24-1.el7.x86_64.rpm: Header V4 DSA/SHA1 Signature, key ID 83ef826a: NOKEY
chef-client-03.devopslab.com.br Preparing...                          ################################# [100%]
chef-client-03.devopslab.com.br Updating / installing...
chef-client-03.devopslab.com.br    1:chef-12.10.24-1.el7              ################################# [100%]
chef-client-03.devopslab.com.br Thank you for installing Chef!
chef-client-03.devopslab.com.br Starting the first Chef Client run...
chef-client-03.devopslab.com.br Starting Chef Client, version 12.10.24
chef-client-03.devopslab.com.br Creating a new client identity for chef-client-03.devopslab.com.br using the validator key.
chef-client-03.devopslab.com.br resolving cookbooks for run list: []
chef-client-03.devopslab.com.br Synchronizing Cookbooks:
chef-client-03.devopslab.com.br Installing Cookbook Gems:
chef-client-03.devopslab.com.br Compiling Cookbooks...
chef-client-03.devopslab.com.br [2016-05-29T10:37:20-03:00] WARN: Node chef-client-03.devopslab.com.br has an empty run list.
chef-client-03.devopslab.com.br Converging 0 resources
chef-client-03.devopslab.com.br 
chef-client-03.devopslab.com.br Running handlers:
chef-client-03.devopslab.com.br Running handlers complete
chef-client-03.devopslab.com.br Chef Client finished, 0/0 resources updated in 03 seconds

Versão do Sistema Operacional detectada.

chef-client-03.devopslab.com.br el 7 x86_64
chef-client-03.devopslab.com.br Getting information for chef stable 12 for el...
chef-client-03.devopslab.com.br downloading https://omnitruck-direct.chef.io/stable/chef/metadata?v=12&p=el&pv=7&m=x86_64

Verificando.

root@chef-workstation-01:~/chef-repo# knife node list
chef-client-02.devopslab.com.br
chef-client-03.devopslab.com.br

6.3. Instalação do Chef-client em um S.O AmazonAMI – Bootstrap chef client em AmazonAMI

Vou fazer uma instalação na Amazon, em uma instância do tipo AmazonAMI utilizando chaves de autenticação.

A instalação vai falhar pois eu preciso criar uma VPN entre a minha rede interna e a Amazon, para que a instância AmazonAMI se comunique com meu Chef-server.

Porém segue apenas uma demonstração de como seria a instalação na Amazon. Tudo funciona, menos a comunicação com meu Chef-server devido uma falta de VPN, mas se você já tiver a comunicação entre o Chef-Server e a rede da Amazon é um abraço meu amigo =)

A VPN não vou criar agora. Mas quando for fazer, como é minha rede interna, de casa, vou utilizar o OpenVPN mesmo.

Então segue uma demonstração de instalação do Chef-client na Amazon.
A única coisa que muda em relação as instalações anteriores é que ao invés de um usuário e senha, será passado a chave de autenticação na Amazon.

# knife bootstrap ec2-52-67-1-43.sa-east-1.compute.amazonaws.com -x ec2-user -i /root/AMAZON/amazonkey/AMAZON-KEY.pem –sudo

root@chef-workstation-01:~/chef-repo# knife bootstrap ec2-52-67-1-43.sa-east-1.compute.amazonaws.com -x ec2-user -i /root/AMAZON/amazonkey/AMAZON-KEY.pem --sudo
Doing old-style registration with the validation key at /root/chef-repo/.chef/orgdevopslab.pem...
Delete your validation key in order to use your user credentials instead

Connecting to ec2-52-67-1-43.sa-east-1.compute.amazonaws.com
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com -----> Installing Chef Omnibus (-v 12)
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com downloading https://omnitruck-direct.chef.io/chef/install.sh
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com   to file /tmp/install.sh.2672/install.sh
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com trying wget...
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com el 6 x86_64
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com Getting information for chef stable 12 for el...
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com downloading https://omnitruck-direct.chef.io/stable/chef/metadata?v=12&p=el&pv=6&m=x86_64
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com   to file /tmp/install.sh.2687/metadata.txt
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com trying wget...
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com sha1	faec4e0bc2cc236170b400426cd3b51b5657fe90
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com sha256	445b64e38827d8c787267bda57d2cd6be797b6f6f70eb34ec846eceee8f6fae9
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com url	https://packages.chef.io/stable/el/6/chef-12.10.24-1.el6.x86_64.rpm
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com version	12.10.24
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com downloaded metadata file looks valid...
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com downloading https://packages.chef.io/stable/el/6/chef-12.10.24-1.el6.x86_64.rpm
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com   to file /tmp/install.sh.2687/chef-12.10.24-1.el6.x86_64.rpm
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com trying wget...
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com Comparing checksum with sha256sum...
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com Installing chef 12
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com installing with rpm...
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com warning: /tmp/install.sh.2687/chef-12.10.24-1.el6.x86_64.rpm: Header V4 DSA/SHA1 Signature, key ID 83ef826a: NOKEY
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com error: can't create transaction lock on /var/lib/rpm/.rpm.lock (Permission denied)
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com Installation failed
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com Version: 12
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com 
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com Please file a Bug Report at https://github.com/chef/omnitruck/issues/new
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com Alternatively, feel free to open a Support Ticket at https://www.chef.io/support/tickets
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com More Chef support resources can be found at https://www.chef.io/support
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com 
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com Please include as many details about the problem as possible i.e., how to reproduce
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com the problem (if possible), type of the Operating System and its version, etc.,
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com and any other relevant details that might help us with troubleshooting.
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com 
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com mkdir: cannot create directory ‘/etc/chef’: Permission denied
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com sh: line 179: /etc/chef/validation.pem: No such file or directory
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com chmod: cannot access ‘/etc/chef/validation.pem’: No such file or directory
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com sh: line 210: /etc/chef/encrypted_data_bag_secret: No such file or directory
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com chmod: cannot access ‘/etc/chef/encrypted_data_bag_secret’: No such file or directory
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com mkdir: cannot create directory ‘/etc/chef’: Permission denied
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com sh: line 216: /etc/chef/trusted_certs/chef-server-01.crt: No such file or directory
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com sh: line 245: /etc/chef/client.rb: No such file or directory
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com sh: line 255: /etc/chef/first-boot.json: No such file or directory
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com Starting the first Chef Client run...
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com sh: line 262: chef-client: command not found
root@chef-workstation-01:~/chef-repo# knife bootstrap ec2-52-67-1-43.sa-east-1.compute.amazonaws.com -x ec2-user -i /root/AMAZON/amazonkey/AMAZON-KEY.pem --sudo
Doing old-style registration with the validation key at /root/chef-repo/.chef/orgdevopslab.pem...
Delete your validation key in order to use your user credentials instead

Connecting to ec2-52-67-1-43.sa-east-1.compute.amazonaws.com
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com -----> Installing Chef Omnibus (-v 12)
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com downloading https://omnitruck-direct.chef.io/chef/install.sh
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com   to file /tmp/install.sh.2751/install.sh
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com trying wget...
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com el 6 x86_64
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com Getting information for chef stable 12 for el...
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com downloading https://omnitruck-direct.chef.io/stable/chef/metadata?v=12&p=el&pv=6&m=x86_64
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com   to file /tmp/install.sh.2756/metadata.txt
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com trying wget...
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com sha1	faec4e0bc2cc236170b400426cd3b51b5657fe90
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com sha256	445b64e38827d8c787267bda57d2cd6be797b6f6f70eb34ec846eceee8f6fae9
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com url	https://packages.chef.io/stable/el/6/chef-12.10.24-1.el6.x86_64.rpm
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com version	12.10.24
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com downloaded metadata file looks valid...
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com downloading https://packages.chef.io/stable/el/6/chef-12.10.24-1.el6.x86_64.rpm
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com   to file /tmp/install.sh.2756/chef-12.10.24-1.el6.x86_64.rpm
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com trying wget...
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com Comparing checksum with sha256sum...
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com Installing chef 12
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com installing with rpm...
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com warning: /tmp/install.sh.2756/chef-12.10.24-1.el6.x86_64.rpm: Header V4 DSA/SHA1 Signature, key ID 83ef826a: NOKEY
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com Preparing...                          ################################# [100%]
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com Updating / installing...
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com    1:chef-12.10.24-1.el6              ################################# [100%]
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com Thank you for installing Chef!
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com Starting the first Chef Client run...
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com Starting Chef Client, version 12.10.24
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com Creating a new client identity for chefnode-amazonami-01 using the validator key.
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com [2016-05-29T13:58:02+00:00] ERROR: Error connecting to https://chef-server-01/organizations/devopslab/clients, retry 1/5
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com [2016-05-29T13:58:07+00:00] ERROR: Error connecting to https://chef-server-01/organizations/devopslab/clients, retry 2/5
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com [2016-05-29T13:58:12+00:00] ERROR: Error connecting to https://chef-server-01/organizations/devopslab/clients, retry 3/5
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com [2016-05-29T13:58:17+00:00] ERROR: Error connecting to https://chef-server-01/organizations/devopslab/clients, retry 4/5
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com [2016-05-29T13:58:22+00:00] ERROR: Error connecting to https://chef-server-01/organizations/devopslab/clients, retry 5/5
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com 
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com ================================================================================
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com Chef encountered an error attempting to create the client "chefnode-amazonami-01"
ec2-52-67-1-43.sa-east-1.compute.amazonaws.com ================================================================================

6.4. Instalação do Chef-client em um Ubuntu-Server-14.04 – Bootstrap chef client no Ubuntu 14 com Chef + SSH Keys

Vamos fazer a instalação do Chef-client no Ubuntu-Server-14.04 utilizando chave de autenticação SSH.

root@chef-workstation-01:~/chef-repo# knife bootstrap chef-client-01.devopslab.com.br -x leonardo -i ~/.ssh/id_rsa --sudo
Doing old-style registration with the validation key at /root/chef-repo/.chef/orgdevopslab.pem...
Delete your validation key in order to use your user credentials instead

Connecting to chef-client-01.devopslab.com.br
chef-client-01.devopslab.com.br -----> Installing Chef Omnibus (-v 12)
chef-client-01.devopslab.com.br downloading https://omnitruck-direct.chef.io/chef/install.sh
chef-client-01.devopslab.com.br   to file /tmp/install.sh.1086/install.sh
chef-client-01.devopslab.com.br trying wget...
chef-client-01.devopslab.com.br ubuntu 14.04 x86_64
chef-client-01.devopslab.com.br Getting information for chef stable 12 for ubuntu...
chef-client-01.devopslab.com.br downloading https://omnitruck-direct.chef.io/stable/chef/metadata?v=12&p=ubuntu&pv=14.04&m=x86_64
chef-client-01.devopslab.com.br   to file /tmp/install.sh.1090/metadata.txt
chef-client-01.devopslab.com.br trying wget...
chef-client-01.devopslab.com.br sha1	7d30b300f95f00036919ee8bf3b95ab73429e57e
chef-client-01.devopslab.com.br sha256	663d6c42c90bbb9463bc02a7c5d777f7aa6ebd52c071a0c1963bc8c4db76dea2
chef-client-01.devopslab.com.br url	https://packages.chef.io/stable/ubuntu/14.04/chef_12.10.24-1_amd64.deb
chef-client-01.devopslab.com.br version	12.10.24
chef-client-01.devopslab.com.br downloaded metadata file looks valid...
chef-client-01.devopslab.com.br downloading https://packages.chef.io/stable/ubuntu/14.04/chef_12.10.24-1_amd64.deb
chef-client-01.devopslab.com.br   to file /tmp/install.sh.1090/chef_12.10.24-1_amd64.deb
chef-client-01.devopslab.com.br trying wget...
chef-client-01.devopslab.com.br Comparing checksum with sha256sum...
chef-client-01.devopslab.com.br Installing chef 12
chef-client-01.devopslab.com.br installing with dpkg...
chef-client-01.devopslab.com.br Selecting previously unselected package chef.
(Reading database ... 57754 files and directories currently installed.)
chef-client-01.devopslab.com.br Preparing to unpack .../chef_12.10.24-1_amd64.deb ...
chef-client-01.devopslab.com.br Unpacking chef (12.10.24-1) ...
chef-client-01.devopslab.com.br Setting up chef (12.10.24-1) ...
chef-client-01.devopslab.com.br Thank you for installing Chef!
chef-client-01.devopslab.com.br Starting the first Chef Client run...
chef-client-01.devopslab.com.br Starting Chef Client, version 12.10.24
chef-client-01.devopslab.com.br Creating a new client identity for chef-client-01.devopslab.com.br using the validator key.
chef-client-01.devopslab.com.br resolving cookbooks for run list: []
chef-client-01.devopslab.com.br Synchronizing Cookbooks:
chef-client-01.devopslab.com.br Installing Cookbook Gems:
chef-client-01.devopslab.com.br Compiling Cookbooks...
chef-client-01.devopslab.com.br [2016-05-29T11:41:45-03:00] WARN: Node chef-client-01.devopslab.com.br has an empty run list.
chef-client-01.devopslab.com.br Converging 0 resources
chef-client-01.devopslab.com.br 
chef-client-01.devopslab.com.br Running handlers:
chef-client-01.devopslab.com.br Running handlers complete
chef-client-01.devopslab.com.br Chef Client finished, 0/0 resources updated in 03 seconds

Validação:

root@chef-workstation-01:~/chef-repo# knife node list
chef-client-01.devopslab.com.br
chef-client-02.devopslab.com.br
chef-client-03.devopslab.com.br
root@chef-workstation-01:~/chef-repo# knife client list
chef-client-01.devopslab.com.br
chef-client-02.devopslab.com.br
chef-client-03.devopslab.com.br
devopslab-validator

7. Primeiro Cookbook Chef

Agora que você já preparou sua cozinha, chegou a hora de cozinhar, então vamos fazer nossa primeira receita.
Seguinte!!! Vamos fazer um Nhoque com molho bolonhesa. Molho de tomate caseiro, a moda Italiana, vamos amassar o tomate.

Brincadeira… mas você já reparou que no Chef tudo é cozinha, receitas e utensílios, que coisa louca rsrsrs.

Vamos criar um cookbook para instalar um pacote qualquer. Vamos instalar aqui o pacote telnet.

Criação do Cookbook.
# knife cookbook create telnet

~/chef-repo# knife cookbook create telnet
** Creating cookbook telnet in /root/chef-repo/cookbooks
** Creating README for cookbook: telnet
** Creating CHANGELOG for cookbook: telnet
** Creating metadata for cookbook: telnet

O Cookbook fica armazenado dentro da pasta ~/chef-repo/cookbooks

#cd ~/chef-repo/cookbooks/telnet
# ls
attributes  CHANGELOG.md  definitions  files  libraries  metadata.rb  providers  README.md  recipes  resources templates

Veja que dentro da pasta telnet foi criado toda uma estrutura de diretórios. Por hora vamos direto para a pasta “recipes”, que é onde vamos escrever o procedimento de instalação do pacote telnet.

Crie um arquivo .rb com o seguinte conteúdo:
# vi default.rb

package 'telnet' do
  action :install
end

Veja que é bem intuitivo, foi declarado um recurso “package” e uma ação “install”. Fica bem claro que será instado o pacote telnet.

Faça uma verificação nas receitas para procurar por erros.
# knife cookbook test telnet

root@chef-workstation-01:~/chef-repo# knife cookbook test telnet
WARNING: DEPRECATED: Please use ChefSpec or Rubocop to syntax-check cookbooks.
checking telnet
Running syntax check on telnet
Validating ruby files
Validating templates

Sem erros, apenas um Warning informando para você utilizar o ChefSpec ou Rubocop ao invés do knife test, fica a seu critério qual das ferramentas utilizar para a verificação da sintaxe das suas receitas.

Agora faça o upload do cookbook para o Chef-server.

# knife cookbook upload telnet

root@chef-workstation-01:~/chef-repo# knife cookbook upload telnet
Uploading telnet       [0.1.0]
Uploaded 1 cookbook.

Vamos fazer um link entre os nodes e o cookbook. Basicamente vamos dizer quais cookbooks aplicar para determinados nodes.

# knife node run_list add chef-client-01.devopslab.com.br “recipe[telnet]”

root@chef-workstation-01:~/chef-repo# knife node run_list add chef-client-01.devopslab.com.br "recipe[telnet]"
chef-client-01.devopslab.com.br:
  run_list: recipe[telnet]

“recipe[telnet]” é equivalente a “recipe[telnet::default]”, pois a receita é default.rb.
Se a receita tivesse outro nome, por exemplo pacotes, a sintaxe ficaria assim: “recipe[telnet::pacotes]”.

Verificando quais cookbooks estão associados ao node.

root@chef-workstation-01:~/chef-repo# knife node show chef-client-01.devopslab.com.br
Node Name:   chef-client-01.devopslab.com.br
Environment: _default
FQDN:        chef-client-01.devopslab.com.br
IP:          10.0.2.42
Run List:    recipe[telnet]
Roles:       
Recipes:     
Platform:    ubuntu 14.04
Tags: 

Faça o login no node e execute o comando chef-client para baixar a receita de instalação do Chef-server.

root@chef-client-01:~# chef-client 
Starting Chef Client, version 12.10.24
resolving cookbooks for run list: ["telnet"]
Synchronizing Cookbooks:
  - telnet (0.1.0)
Installing Cookbook Gems:
Compiling Cookbooks...
Converging 1 resources
Recipe: telnet::default
  * apt_package[telnet] action install
    - install version 0.17-36build2 of package telnet

Running handlers:
Running handlers complete
Chef Client finished, 1/1 resources updated in 08 seconds
root@chef-client-01:~# 


root@chef-client-01:~# dpkg -l| grep telnet
ii  telnet                             0.17-36build2                    amd64        The telnet client

No comando acima foi executado o chef-client e o comando “dpkg -l”. Veja que o telnet foi instalado conforme o esperado.

Deixa eu testar em um Centos 7 só para ver o comportamento.
Primeiramente associar o cookbook telnet ao node chef-client-03.devopslab.com.br.

root@chef-workstation-01:~/chef-repo# knife node run_list add chef-client-03.devopslab.com.br "recipe[telnet]"
chef-client-03.devopslab.com.br:
  run_list: recipe[telnet]
root@chef-workstation-01:~/chef-repo# 


root@chef-workstation-01:~/chef-repo# knife node show chef-client-03.devopslab.com.br
Node Name:   chef-client-03.devopslab.com.br
Environment: _default
FQDN:        chef-client-03.devopslab.com.br
IP:          10.0.2.44
Run List:    recipe[telnet]
Roles:       
Recipes:     
Platform:    centos 7.2.1511
Tags:   

Agora vou executar o comando chef-client no node chef-client-03.devopslab.com.br (Centos 7).

[root@chef-client-03 ~]# chef-client 
Starting Chef Client, version 12.10.24
resolving cookbooks for run list: ["telnet"]
Synchronizing Cookbooks:
  - telnet (0.1.0)
Installing Cookbook Gems:
Compiling Cookbooks...
Converging 1 resources
Recipe: telnet::default
  * yum_package[telnet] action install
    - install version 0.17-59.el7 of package telnet

Running handlers:
Running handlers complete
Chef Client finished, 1/1 resources updated in 42 seconds
[root@chef-client-03 ~]# 

[root@chef-client-03 ~]# rpm -qa | grep telnet
telnet-0.17-59.el7.x86_64

Repare que tanto no Ubuntu como no Centos foi instalado bonitinho o pacote telnet, e o melhor foi que você não se preocupou se foi utilizado apt-get ou yum, rpm ou dpkg, pois o Chef e sua camada de abstração trata isto para você. O seu trabalho é apenas fazer a receita de instalação.

Referência:
https://docs.chef.io/packages.html
https://docs.chef.io/release/server_12-6/install_server.html#standalone
https://docs.chef.io/release/devkit/install_dk.html
https://docs.chef.io/install_bootstrap.html
https://docs.chef.io/knife_bootstrap.html
https://www.linode.com/docs/applications/chef/creating-your-first-chef-cookbook
https://www.linode.com/docs/applications/chef/deploy-a-chef-server-workstation-and-node-on-ubuntu-14-04/

Faça o que é difícil e a vida será mais fácil. Faça o que é fácil e a vida será mais difícil.

Puppet – Puppet Server, Cliente, orquestração com Mcollective, instalação de Plugins e Tuning

Segue esta série de tutoriais para a criação de uma infraestrutura gerenciada utilizando o Puppet, orquestração via Mcollective, instalação de plugins do Mcollective e por fim tuning do Puppet Server.

Como extra segue um lab para a instalação de agentes de monitoração Zabbix.

1. Puppet – Como instalar e configurar o Puppet Server, Puppet Cliente e Módulos de Configuração
Puppet – Como instalar e configurar o Puppet Server, Puppet Cliente e Módulos de Configuração

2. Puppet – Instalação e configuração do Mcollective, plugins e orquestração de clientes
Puppet – Instalação e configuração do Mcollective, plugins e orquestração de clientes

3. Puppet – Facter – Orquestração via Mcollective – Instalação e utilização do Plugin Facter
Puppet – Facter – Orquestração via Mcollective – Instalação e utilização do Plugin Facter

4. Puppet – Tuning do Puppet Server
Puppet – Tuning do Puppet Server

Extra aula
5. Puppet – Como instalar e configurar o zabbix-agent de forma automática via Puppet
Puppet – Como instalar e configurar o zabbix-agent de forma automática via Puppet

6. Puppet 4.x.x não precisa do Apache/Passenger
Puppet 4.x.x não precisa do Apache/Passenger

Centralização e análise de logs com Graylog, MongoDB e Elasticsearch

“Open source log management that actually works” – www.graylog.org
Neste tutorial vamos instalar e configurar o Graylog para a centralização e análise de logs.

É fundamental ter uma ferramenta para análise de logs na sua infraestrutura, isto te possibilita um debug mais apurado do ambiente, melhora a segurança, ajuda a compartilhar informações com os times, auxilia na monitoração com o uso de triggers, centralização de logs, enfim é uma ferramenta estratégica que oferece vários recursos para uma boa análise da sua infraestrutura.

Graylog é uma excelente alternativa ao Splunk e Kibana+Logstash.

1.Infraestrutura e pré-requisitos

Sistema operacional: Centos 7 x86_64.

Componentes:
Graylog Server – Análise e coleta de logs. Insere os logs no Elasticsearch.
Graylog Web – Interface Web para o Graylog Server.
MongoDB– Armazenamento de configurações e metadados.
Elasticsearch – Armazenamento de logs e ferramenta de busca.
graylog-Diagram

Versões utilizadas neste tutorial:
graylog-web-1.3.4-1.noarch
graylog-server-1.3.4-1.noarch

mongodb-org-server-3.2.4-1.el7.x86_64
mongodb-org-3.2.4-1.el7.x86_64

elasticsearch-1.7.5-1.noarch

Servidores:
Graylog Server e interface Web:
10.0.2.100 graylog-webeserver-01.devopslab.com.br

MongoDB:
10.0.2.101 graylog-mongodb-01.devopslab.com.br

Elasticsearch
10.0.2.102 graylog-elasticsearch-01.devopslab.com.br

2. Instalação do Elasticsearch

Faça o login no servidor do Elasticsearch graylog-elasticsearch-01.devopslab.com.br
Recomendo 1GB de RAM.
Até o presente momento o Graylog funciona apenas com o Elasticsearch 1.7.

Desative o Firewall e Selinux.

# systemctl stop firewalld.service
# systemctl disable firewalld.service
# sed -i s/SELINUX=enforcing/SELINUX=disabled/g /etc/selinux/config
# setenforce 0

Tuning do Sistema Operacional – Aumente a quantidade de Openfiles

# vi /etc/security/limits.conf
*                soft   nofile     64000
*                hard  nofile      64000
# ulimit -n 64000

Verifique o fs.file-max, pois ele tem que ser maior que 64000.

# sysctl -a | grep fs.file-max
fs.file-max = 98929

Instalação do Java
Versões suportadas: OpenJDK ou Java Oracle
Java 8 update 20 ou posterior.
Java 7 update 55 ou posterior.

# yum -y install java-1.8.0-openjdk.x86_64
# java -version
openjdk version "1.8.0_77"

Repositório – Importação da chave pública do repositório

# rpm --import https://packages.elastic.co/GPG-KEY-elasticsearch

Crie o arquivo do repositório do Elasticsearch.
#vi /etc/yum.repos.d/elasticsearch.repo

[elasticsearch-1.7]
name=Elasticsearch repository for 1.7.x packages
baseurl=http://packages.elastic.co/elasticsearch/1.7/centos
gpgcheck=1
gpgkey=http://packages.elastic.co/GPG-KEY-elasticsearch
enabled=1

Instale o Elasticsearch 1.7

# yum -y install elasticsearch

Configuração do Elasticsearch
Todas as configurações serão executadas no arquivo /etc/elasticsearch/elasticsearch.yml
# vi /etc/elasticsearch/elasticsearch.yml

Defina um nome qualquer para o cluster.
cluster.name: graylog-lab

Desabilitando a descoberta automática de nodes Elasticsearch e definindo o servidor do Elasticsearch.
discovery.zen.ping.multicast.enabled: false
discovery.zen.ping.unicast.hosts: [“graylog-elasticsearch-01.devopslab.com.br:9300”]

Desabilitando a execução remota de scripts.
Adicione ao final do arquivo elasticsearch.yml
script.disable_dynamic: true

Arquivo completo elasticsearch.yml.
# cat  /etc/elasticsearch/elasticsearch.yml| grep -v ^#| grep -v ^$
cluster.name: graylog-lab
discovery.zen.ping.multicast.enabled: false
discovery.zen.ping.unicast.hosts: ["graylog-elasticsearch-01.devopslab.com.br:9300"]
script.disable_dynamic: true

Reinicie o Elasticsearch.

# systemctl enable elasticsearch.service
# systemctl restart elasticsearch.service

Verificando a saúde do cluster de Elasticsearch.
Status 200 está ok.

curl -X GET http://localhost:9200
# curl -X GET 'http://localhost:9200'
{
  "status" : 200,
  "name" : "Hydro",
  "cluster_name" : "graylog-lab",
  "version" : {
    "number" : "1.7.5",
    "build_hash" : "00f95f4ffca6de89d68b7ccaf80d148f1f70e4d4",
    "build_timestamp" : "2016-02-02T09:55:30Z",
    "build_snapshot" : false,
    "lucene_version" : "4.10.4"
  },
  "tagline" : "You Know, for Search"
}

Status ‘green’ está ok.

# curl -XGET 'http://localhost:9200/_cluster/health?pretty=true'
# curl -XGET 'http://localhost:9200/_cluster/health?pretty=true'
{
  "cluster_name" : "graylog-lab",
  "status" : "green",
  "timed_out" : false,
  "number_of_nodes" : 1,
  "number_of_data_nodes" : 1,
  "active_primary_shards" : 0,
  "active_shards" : 0,
  "relocating_shards" : 0,
  "initializing_shards" : 0,
  "unassigned_shards" : 0,
  "delayed_unassigned_shards" : 0,
  "number_of_pending_tasks" : 0,
  "number_of_in_flight_fetch" : 0
}

3. Instalação do MongoDB

Servidor graylog-mongodb-01.devopslab.com.br
Recomendo 1GB de RAM.
Desative o Firewall e Selinux.

Tuning do S.O – Aumente a quantidade de Openfiles e Max process

# vi /etc/security/limits.conf
*                soft   nofile      64000
*                hard  nofile      64000
*                soft   nproc      64000
*                hard  nproc      64000
# ulimit -n 64000
# ulimit -u 64000

Verifique o fs.file-max. O valor tem que ser maior que 64000.

# sysctl -a | grep fs.file-max
fs.file-max = 98929

Repositório – Crie o arquivo do repositório do MongoDB

[mongodb-org-3.2]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/3.2/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-3.2.asc

Instale a última versão do MongoDB.

# yum install -y mongodb-org

Comente a linha ‘bindIp: 127.0.0.1’ no arquivo ‘/etc/mongod.conf’ para que o MongoDB escute em todas as interfaces de rede.

# sed -i s/bindIp:/#bindIp:/g /etc/mongod.conf 

Inicie o MongoDB.

# systemctl enable mongod.service
# systemctl start mongod.service

4. Instalação do Graylog Server

Servidor graylog-webeserver-01.devopslab.com.br
Desative o Firewall e Selinux.
Instale o java. Utilize o mesmo passo descrito na instalação do Elasticsearch.

Repositório – Instalação do pacote graylog-1.3-repository-el7_latest.rpm

# rpm -hiv https://packages.graylog2.org/repo/packages/graylog-1.3-repository-el7_latest.rpm

Instalação do Graylog server.

# yum -y install graylog-server

Instale o repositório Epel. Ele é dependencia para a instalação do pacote pwgen.

# yum -y install epel-release.noarch

Configuração do Graylog Server.
# vi /etc/graylog/server/server.conf
Define este node como master.
is_master = true

Gere uma senha de segurança para proteger o armazenamento das senhas dos usuários.

# pwgen -N 1 -s 96
bD9QUDQMjkd0JZ5S205p3mJDtcLAjH61K0jP48wGxcETvcPV8zI7kgRSB5KJwzxpw6CSAelzILFr9zxMXt0wXhOqnKGCkdNA

Configure a senha em password_secret

password_secret =U2UAb7rBEvc0Q1CLRiSaANdaQcEMWYALoN8TuNCph1nCUcII1oyNFtLXZrC4yoBQ3BVWMUSg8WoVRnvo4mURElJjeoC653LQ

Rest API para a conexão do Graylog Web e outros Graylog Server.

rest_listen_uri = http://127.0.0.1:12900/

Crie uma senha para o usuário Administrativo ‘admin’.

# echo -n minha_senha | sha256sum
f9b88ac71caec840be639a8eb18e68728744252316456ce9b3cf6b58d82bb7cd  -
root_password_sha2 = f9b88ac71caec840be639a8eb18e68728744252316456ce9b3cf6b58d82bb7cd

Quantidade de nodes e replicas do Elasticsearch

elasticsearch_shards = 1
elasticsearch_replicas = 0

Nome do Cluster Elasticsearch. É o mesmo definido em no arquivo elasticsearch.yml do servidor do Elasticsearch.

elasticsearch_cluster_name = graylog-lab

Desabilitando a descoberta automática e definindo o servidor do Elasticsearch.

elasticsearch_discovery_zen_ping_multicast_enabled = false
elasticsearch_discovery_zen_ping_unicast_hosts = graylog-elasticsearch-01.devopslab.com.br:9300

Desativando a autenticação e definindo a string de conexão com o banco MongoDB.

mongodb_useauth = false
mongodb_uri = mongodb://graylog-mongodb-01.devopslab.com.br:27017/graylog2

Arquivo server.conf completo.

# cat server.conf | grep -v ^# |grep -v ^$
is_master = true
node_id_file = /etc/graylog/server/node-id
password_secret = bD9QUDQMjkd0JZ5S205p3mJDtcLAjH61K0jP48wGxcETvcPV8zI7kgRSB5KJwzxpw6CSAelzILFr9zxMXt0wXhOqnKGCkdNA
root_password_sha2 = 8b7baf6899f95c2f4723ef35f4cb10ac678221ac2d63ae8901f63151d243881e
plugin_dir = /usr/share/graylog-server/plugin
rest_listen_uri = http://127.0.0.1:12900/
rotation_strategy = count
elasticsearch_max_docs_per_index = 20000000
elasticsearch_max_number_of_indices = 20
retention_strategy = delete
elasticsearch_shards = 1
elasticsearch_replicas = 0
elasticsearch_index_prefix = graylog2
allow_leading_wildcard_searches = false
allow_highlighting = false
elasticsearch_cluster_name = graylog-lab
elasticsearch_discovery_zen_ping_multicast_enabled = false
elasticsearch_discovery_zen_ping_unicast_hosts = graylog-elasticsearch-01.devopslab.com.br:9300
elasticsearch_analyzer = standard
output_batch_size = 500
output_flush_interval = 1
output_fault_count_threshold = 5
output_fault_penalty_seconds = 30
processbuffer_processors = 5
outputbuffer_processors = 3
processor_wait_strategy = blocking
ring_size = 65536
inputbuffer_ring_size = 65536
inputbuffer_processors = 2
inputbuffer_wait_strategy = blocking
message_journal_enabled = true
message_journal_dir = /var/lib/graylog-server/journal
dead_letters_enabled = false
lb_recognition_period_seconds = 3
mongodb_useauth	= false
mongodb_uri = mongodb://graylog-mongodb-01.devopslab.com.br:27017/graylog2
mongodb_max_connections = 100
mongodb_threads_allowed_to_block_multiplier = 5
content_packs_dir = /usr/share/graylog-server/contentpacks
content_packs_auto_load = grok-patterns.json

Inicie o Graylog Server

# systemctl enable graylog-server.service
# systemctl start graylog-server.service

5. Instalação do Graylog Web

O Graylog Web vai ficar no mesmo servidor do Graylog Server, então Java, Firewall e Selinux já estão ok.
Recomendo pelo menos 2GB de RAM.
Servidor graylog-webeserver-01.devopslab.com.br

Instalação do graylog-web.

# yum -y install graylog-web

Configuração do Graylog Web
# vi /etc/graylog/web/web.conf

Gere uma chave para criptografia de funções do graylog com o comando ‘pwgen -N 1 -s 96’ e cole no campo:
application.secret=””

Configure a conexão com a API do Server em graylog2-server.uris=””
graylog2-server.uris=”http://127.0.0.1:12900/”

Veja como ficou a configuração do greylog web.

# cat web.conf| grep -v ^#| grep -v ^$
graylog2-server.uris="http://127.0.0.1:12900/"

application.secret="OGBIrIC2eCOGqc3P621rIXFbGFF0DP6l1FU4A5FN8Zu4RATafF6y2EEdpHIvytkiCG8G2n7C18eUoQxGlJzHd5KHaJE3Sc20"

field_list_limit=100

application.global=lib.Global

Inicie o Graylog Web.

# systemctl enable graylog-web
# systemctl start graylog-web

Faça o login na interface Web (http://ip-webserver:9000):
http://graylog-webeserver-01.devopslab.com.br:9000/

Usuário: admin
Senha: Foi definida na instalação do graylog-server, lembra?.
home-graylog1

6. Configuração dos clientes e envio de Log

O Graylog aceita logs nos formatos RFC-5424 e RFC-3164, que são os utilizados pelo syslog-ng e rsyslog.

Equipamentos e aplicações com logs fora do padrão precisam de plugins, como por exemplo roteadores Cisco e Fortigate ou app Java e Web servers.

Visite o Marketplace para checar todos os plugins disponíveis: https://marketplace.graylog.org/

É possível você desenvolver seu próprio padrão de log com a ferramenta Graylog Extractor ou enviar o log via API.

6.1 – Configuração do Input de logs

Antes de começar a receber logs no Graylog é necessário criar uma configuração de Input, que basicamente diz quais tipos de logs serão aceitos. Os tipos de logs aceitos podem ser estendidos com plugins próprios ou de terceiros (veja o o site graylog markeplace).
Logue na interface Web e vá para:
System/Inputs → Inputs → Launch New Input
Selecione Syslog UDP.
Selecione Syslog TCP.
Clique em Lauch.

Escolha uma porta acima de 1024. Portas <1024 apenas o usuário root pode manipular. Eu escolhi a porta 1030/tcp e 1030/udp para o recebimento de logs do syslog. graylog-input

6.2 – Configuração do Firewall

Eu quero que meus servidores enviem o log para a porta 514/tcp e 514/udp. Simplesmente pois é um padrão, é comum enviar logs para estas portas.
Você também pode enviar direto para a porta definida no Input, no meu caso 1030.

Se você quer usar o padrão, crie uma regra de firewall que redirecione todo o tráfego em vier pela porta 514/tcp e 514/udp para a porta 1030.

# iptables -t nat -A PREROUTING -i enp0s3 -p udp -m udp --dport 514 -j REDIRECT --to-ports 1030
# iptables -t nat -A PREROUTING -i enp0s3 -p tcp -m tcp --dport 514 -j REDIRECT --to-ports 1030

6.3 – Configuração em envio de logs

Vou configurar os próprios servidores do Cluster do Graylog para o envio de log.
Hoje em dia todos os Linux estão utilizando o rsyslog, então vou configurar o rsyslog da seguinte forma.

# vi /etc/rsyslog.conf
*.*	@graylog-webeserver-01.devopslab.com.br:514;RSYSLOG_SyslogProtocol23Format

graylog-webeserver-01.devopslab.com.br:514 – Meu servidor do Graylog ouvindo na porta 514. poderia ser a porta definida no Input 1030tcp/udp.
*.* – Todos os logs e facilidades.
@ – Protocolo UDP.
@@ – Protocolo TCP.

Reinicie o rsyslog para que o logs comecem a ser enviados para o graylog.

# systemctl restart rsyslog

Obs: Este template ‘RSYSLOG_SyslogProtocol23Format’ funciona apenas caso a versão do rsyslog seja maior que 5.

# rsyslogd -version
rsyslogd 7.4.7, compiled with:
	FEATURE_REGEXP:				Yes
	FEATURE_LARGEFILE:			No
	GSSAPI Kerberos 5 support:		Yes
	FEATURE_DEBUG (debug build, slow code):	No
	32bit Atomic operations supported:	Yes
	64bit Atomic operations supported:	Yes
	Runtime Instrumentation (slow code):	No
	uuid support:				Yes
See http://www.rsyslog.com for more information.

Se seu rsyslog for menor 5, utilize apenas a linha:

# vi /etc/rsyslog.conf
*.*	@graylog-webeserver-01.devopslab.com.br:514

7. Verificação dos logs na interface Web

Logue na interface web e entre na abas sources e search que será possível ver os logs e a origem dos logs.

Aba SOURCES.
dashboard-sources

Aba SEARCH.
dashboard-search
Se você chegou até aqui seu Graylog está funcionando e recebendo logs, agora basta você explorar a ferramenta, clicar nas várias opções, integrar com Ldap, criar logins para seus times, criar triggers de monitoramento, criar Dashboards, fazer filtros específicos e etc.

8. Graylog via proxy com o Nginx

Este passo é opcional.
Digitar a url com a porta no navegador não é algo muito legal, então vamos configurar um proxy reverso com Nginx para não ter que digitar http://x.x.x.x:porta/

No servidor Graylog Server e Web instale o Nginx.

# yum -y install nginx

Altere estes campos:

server {
        listen       80 default_server;
        server_name  graylog.devopslab.com.br;
        location / {
	proxy_pass http://localhost:9000;
        }

E reinicie o nginx. Agora você pode simplesmente digitar http://graylog.devopslab.com.br/ sem ter que digitar porta.

Segue todo o arquivo nginx.conf, basta copiar e colar ;). O restante do arquivo está padrão, conforme veio instalado.

# cat nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    include /etc/nginx/conf.d/*.conf;

    server {
        listen       80 default_server;
        server_name  graylog.devopslab.com.br;
        location / {
	proxy_pass http://localhost:9000;
        }

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }
}

Referência:
Graylog
http://docs.graylog.org/en/1.3/

Elasticssearch
https://www.elastic.co/guide/en/elasticsearch/reference/1.7/index.html

MongoDB
https://docs.mongodb.org/manual/

Qualquer dúvida, sugestão e etc, só chamar.

[]’s

Leonardo Macedo Cerqueira

Kubernetes – como instalar e configurar o Kubernetes – K8S – Gerência de containers Docker

Tutorial Kubernetes – como instalar e configurar o Kubernetes, criação de cluster e Pods com Kubernetes.

1. Introdução

Kubernetes é um sistema Open Source desenvolvido pelo Google para o gerenciamento de cluster de containeres tendo como características auto-scaling de serviços e containeres, auto-monitoração de containeres, permite o deploy de containers e serviços, load balancer, orquestração de containers, e orquestração de volumes de armazenamento ‘storages’.

O Kubernetes amigávelmente pode ser chamado de K8S, inventaram isto no Google, eu li em um dos Docs do Kubernetes e seria algo como K[eight-characters]S, o que faz todo sentido.

Mais uma pequena curiosidade, Kubernetes é derivado de uma palavra grega Kuvernetes, que significa timoneiro, aquele cara que pilota o Navio, por isto que o logo do Kuvernetes é um timão de navio.

Minions – São todos os hosts que fazem parte do cluster gerenciado pelo Kubernetes.
Serviços rodando nos Minios: kube-proxy kubelet docker e flannel

Flannel – É uma rede virtual que vai provisionar uma sub-rede para cada host do cluster, esta sub-rede será utilizada para alocar um ip para cada container e fazer a comunicação entre os containers.

Etcd – É um sistema distribuído de armazenamento do tipo key valor ou key=valor, utilizado pelo Kubernetes para armazenar todas informações sobre os Pods, containers, serviços, redes, nós do cluster, localização dos containeres, Cpus, Memória, versões de aplicativos e metados no geral.

Pod – É um grupo de um ou mais containers rodando dentro de um host/minion do cluster.

Replication Controller “RC” – Vai garantir que um determinado número de Pods estejam sempre rodando, ele monitora o cluster e em caso de algum Pod falhar, ficar off-line e etc, o replication controller tratará de subir um novo container ao Pod, mantendo o cluster funcional.

2. Pré-requisitos e Infraestrutura

Pré-requisitos
Sistema Operacional Centos 7 x86_64 instalação mínima.

Hosts – Infraestrutura
Vou utilizar um host para ser o Kubernetes e 3 Minions. Minions podem ser a quantidade que você quiser.

10.0.2.30 kubernetes-master1.devopslab.com.br
10.0.2.31 kubernetes-minion1.devopslab.com.br
10.0.2.32 kubernetes-minion2.devopslab.com.br
10.0.2.33 kubernetes-minion3.devopslab.com.br

3. DNS – Configuração do DNS

Configure o /etc/hosts de todos os nós do cluster “minions” para ter os apontamentos de DNS. Basicamente copie as informações de dns acima para todos os hosts.

4. Configuração do repositório para a instalação de pacotes

Crie o repositório em todos os hosts MASTER e MINIONS.

#vi /etc/yum.repos.d/virt7-docker-common-release.repo

[virt7-docker-common-release]
name=virt7-docker-common-release
baseurl=http://cbs.centos.org/repos/virt7-docker-common-release/x86_64/os/
gpgcheck=0

5. Instalação do Kubernetes e Docker

MASTER
#yum install kubernetes flannel etcd
O pacote kubernetes também vai instalar o Docker entre outras dependências.

#yum install kubernetes flannel etcd
...
Dependencies Resolved

==============================================================================================================================================================================================
 Package                                             Arch                               Version                                                      Repository                          Size
==============================================================================================================================================================================================
Installing:
 etcd                                                x86_64                             2.2.5-1.el7                                                  extras                             5.3 M
 flannel                                             x86_64                             0.5.3-9.el7                                                  extras                             1.7 M
 kubernetes                                          x86_64                             1.2.0-0.9.alpha1.gitb57e8bd.el7                              extras                              34 k
Installing for dependencies:
 audit-libs-python                                   x86_64                             2.4.1-5.el7                                                  base                                69 k
 checkpolicy                                         x86_64                             2.1.12-6.el7                                                 base                               247 k
 docker                                              x86_64                             1.9.1-25.el7.centos                                          extras                              13 M
 docker-forward-journald                             x86_64                             1.9.1-25.el7.centos                                          extras                             824 k
 docker-selinux                                      x86_64                             1.9.1-25.el7.centos                                          extras                              70 k
 kubernetes-client                                   x86_64                             1.2.0-0.9.alpha1.gitb57e8bd.el7                              extras                             9.3 M
 kubernetes-master                                   x86_64                             1.2.0-0.9.alpha1.gitb57e8bd.el7                              extras                              15 M
 kubernetes-node                                     x86_64                             1.2.0-0.9.alpha1.gitb57e8bd.el7                              extras                             9.3 M
 libcgroup                                           x86_64                             0.41-8.el7                                                   base                                64 k
 libsemanage-python                                  x86_64                             2.1.10-18.el7                                                base                                94 k
 policycoreutils-python                              x86_64                             2.2.5-20.el7                                                 base                               435 k
 python-IPy                                          noarch                             0.75-6.el7                                                   base                                32 k
 setools-libs                                        x86_64                             3.3.7-46.el7                                                 base                               485 k
 socat                                               x86_64                             1.7.2.2-5.el7                                                base                               255 k

Transaction Summary
==============================================================================================================================================================================================
Install  3 Packages (+14 Dependent packages)

MINIONS

#yum install kubernetes flannel

6. Configuração do Kubernetes MASTER e os MINIONS

MASTER – Kubernetes Master.
MINIONS – Hosts Minions.

Desative o Firewall e Selinux em todos os hosts MASTER e MINIONS do cluster.

#systemctl stop firewalld.service
#systemctl disable firewalld.service
#sed -i s/SELINUX=enforcing/SELINUX=disabled/g /etc/selinux/config
#setenforce 0

6.1 – Configuração do Kubernetes Master

MASTER – Kubernetes Config

#vi /etc/kubernetes/config
Configure a linha KUBE_MASTER para apontar para o ip MASTER.

# logging to stderr means we get it in the systemd journal
KUBE_LOGTOSTDERR="--logtostderr=true"

# journal message level, 0 is debug
KUBE_LOG_LEVEL="--v=0"

# Should this cluster be allowed to run privileged docker containers
KUBE_ALLOW_PRIV="--allow-privileged=false"

# How the controller-manager, scheduler, and proxy find the apiserver
KUBE_MASTER="--master=http://kubernetes-master1.devopslab.com.br:8080"

MASTER – Apiserserver
Comente a linha KUBE_ADMISSION_CONTROL.
#vi /etc/kubernetes/apiserver

# The address on the local server to listen to.
KUBE_API_ADDRESS="--address=0.0.0.0"

# The port on the local server to listen on.
KUBE_API_PORT="--port=8080"

# Port minions listen on
KUBELET_PORT="--kubelet-port=10250"

# Comma separated list of nodes in the etcd cluster
KUBE_ETCD_SERVERS="--etcd-servers=http://127.0.0.1:2379"

# Address range to use for services
KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=10.254.0.0/16"

# default admission control policies
#KUBE_ADMISSION_CONTROL="--admission-#control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota"

# Add your own!
KUBE_API_ARGS=""

MASTER – ETCD
Verifique se a porta do Etcd é 2379.
Configure o bind para 0.0.0.0:2379.
#vi /etc/etcd/etcd.conf

ETCD_NAME=default
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"
ETCD_ADVERTISE_CLIENT_URLS="http://localhost:2379"

MASTER – Restart dos serviços e habilitação do start no boot.

[root@kubernetes-master1 ~]# for SERVICES in etcd kube-apiserver kube-controller-manager kube-scheduler; do 
        systemctl restart $SERVICES
        systemctl enable $SERVICES
        systemctl status $SERVICES 
done

MASTER – Definição de uma rede FLANNEL
Vamos criar uma rede para que seja alocada para cada novo container do cluster.
Normalmente é uma rede 172.17.0.0/16, porém vou mudar para uma do meu interesse.
Então vamos criar uma chave valor no Etcd.

Crie um arquivo .json em qualquer pasta do servidor Master e defina a rede.

#vi flannel-config.json

{
    "Network": "10.0.10.0/16",
    "SubnetLen": 24,
    "Backend": {
        "Type": "vxlan",
        "VNI": 1
     }
}

Agora faça a criação a Key no Etcd.

#etcdctl set /atomic.io/network/config < flannel-config.json

Verificando se a key foi criada com o comando
#etcdctl get /atomic.io/network/config

#etcdctl get /atomic.io/network/config
{
    "Network": "10.0.10.0/16",
    "SubnetLen": 24,
    "Backend": {
        "Type": "vxlan",
        "VNI": 1
     }
}

6.2 – Configuração dos Minions (Nodes)

Configuração dos hosts Minions.
Cada passo descrito abaixo deve ser feito em todos os hosts Minions da sua rede.

MINIONS – Kubernetes Config
Altere apenas a linha KUBE_MASTER e informe o servidor do Kubernetes.
#vi /etc/kubernetes/config

# logging to stderr means we get it in the systemd journal
KUBE_LOGTOSTDERR="--logtostderr=true"

# journal message level, 0 is debug
KUBE_LOG_LEVEL="--v=0"

# Should this cluster be allowed to run privileged docker containers
KUBE_ALLOW_PRIV="--allow-privileged=false"

# How the controller-manager, scheduler, and proxy find the apiserver
KUBE_MASTER="--master=http://kubernetes-master1.devopslab.com.br:8080"

MINIONS – KUBERLET
Aqui você vai informar qual é o servidor da Api, setar o hostname e bind do kuberlet.
#vi /etc/kubernetes/kubelet

###
# kubernetes kubelet (minion) config

# The address for the info server to serve on (set to 0.0.0.0 or "" for all interfaces)
KUBELET_ADDRESS="--address=0.0.0.0"

# The port for the info server to serve on
# KUBELET_PORT="--port=10250"

# You may leave this blank to use the actual hostname
KUBELET_HOSTNAME="--hostname-override=kubernetes-minion1.devopslab.com.br"

# location of the api-server
KUBELET_API_SERVER="--api-servers=http://kubernetes-master1.devopslab.com.br:8080"

# pod infrastructure container
KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=registry.access.redhat.com/rhel7/pod-infrastructure:latest"

# Add your own!
KUBELET_ARGS=""

MINIONS – rede FLANNEL
Será alterado apenas a linha que informa o ip do ETCD rodando no servidor MASTER.

#vi /etc/sysconfig/flanneld

# etcd url location.  Point this to the server where etcd runs
FLANNEL_ETCD="http://kubernetes-master1.devopslab.com.br:2379"

# etcd config key.  This is the configuration key that flannel queries
# For address range assignment
FLANNEL_ETCD_KEY="/atomic.io/network"

# Any additional options that you want to pass
#FLANNEL_OPTIONS=""

Observe a linha: ‘FLANNEL_ETCD_KEY=”/atomic.io/network”
Esta key “/atomic.io/network” foi criada anteriormente no ETCD do Kubernetes Master.

MINIONS – Restart dos serviços e habilitação do start no boot

[root@kubernetes-minion1 ~]# for SERVICES in kube-proxy kubelet docker flanneld; do 
    systemctl restart $SERVICES
    systemctl enable $SERVICES
    systemctl status $SERVICES 
done

6.3 – Validação do MASTER e MINIONS

MINIONS
Verificação da rede.
Verifique se foram criadas as redes para o docker e flannel.

[root@kubernetes-minion1 ~]# ip -4 a|grep inet
    inet 127.0.0.1/8 scope host lo
    inet 10.0.2.31/24 brd 10.0.2.255 scope global enp0s3
    inet 10.0.10.1/24 scope global docker0
    inet 10.0.10.0/16 scope global flannel.1

Teste de consulta ao Etcd
#curl -s http://kubernetes-master1.devopslab.com.br:2379/v2/keys/atomic.io/network/subnets | python -mjson.tool

[root@kubernetes-minion1 ~]#curl -s http://kubernetes-master1.devopslab.com.br:2379/v2/keys/atomic.io/network/subnets | python -mjson.tool
{
    "action": "get",
    "node": {
        "createdIndex": 32,
        "dir": true,
        "key": "/atomic.io/network/subnets",
        "modifiedIndex": 32,
        "nodes": [
            {
                "createdIndex": 133,
                "expiration": "2016-04-03T01:08:09.060073648Z",
                "key": "/atomic.io/network/subnets/10.0.10.0-24",
                "modifiedIndex": 133,
                "ttl": 84138,
                "value": "{\"PublicIP\":\"10.0.2.31\",\"BackendType\":\"vxlan\",\"BackendData\":{\"VtepMAC\":\"8e:28:15:ca:cd:3b\"}}"
            },
            {
                "createdIndex": 374,
                "expiration": "2016-04-03T01:42:01.861701761Z",
                "key": "/atomic.io/network/subnets/10.0.14.0-24",
                "modifiedIndex": 374,
                "ttl": 86171,
                "value": "{\"PublicIP\":\"10.0.2.32\",\"BackendType\":\"vxlan\",\"BackendData\":{\"VtepMAC\":\"b6:1b:ee:eb:ce:ef\"}}"
            },
            {
                "createdIndex": 434,
                "expiration": "2016-04-03T01:45:36.592848197Z",
                "key": "/atomic.io/network/subnets/10.0.91.0-24",
                "modifiedIndex": 434,
                "ttl": 86385,
                "value": "{\"PublicIP\":\"10.0.2.33\",\"BackendType\":\"vxlan\",\"BackendData\":{\"VtepMAC\":\"4e:84:7d:78:21:00\"}}"
            }
        ]
    }
}

MASTER
No servidor Master faça um “kubectl get nodes” para verificar todos os nós do cluster.

#kubectl get nodes

[root@kubernetes-master1 ~]# kubectl get nodes
NAME                                  LABELS                                                       STATUS    AGE
kubernetes-minion1.devopslab.com.br   kubernetes.io/hostname=kubernetes-minion1.devopslab.com.br   Ready     53m
kubernetes-minion2.devopslab.com.br   kubernetes.io/hostname=kubernetes-minion2.devopslab.com.br   Ready     6m
kubernetes-minion3.devopslab.com.br   kubernetes.io/hostname=kubernetes-minion3.devopslab.com.br   Ready     2m

7. Criação de Pods com o Kubernets

Vamos criar 3 containeres com a imagem nginx e com a porta 80 exposta e um replication controller nomeado como webserver-nginx.

#kubectl run webserver-nginx –image=nginx –replicas=3 –port=80

[root@kubernetes-master1 ~]# kubectl run webserver-nginx --image=nginx --replicas=3 --port=80
replicationcontroller "webserver-nginx" created

Listando os Pods do cluster
#kubectl get pods

[root@kubernetes-master1 ~]# kubectl get pods
NAME                    READY     STATUS    RESTARTS   AGE
webserver-nginx-2th95   0/1       Pending   0          33m
webserver-nginx-v4404   0/1       Pending   0          33m
webserver-nginx-za52c   0/1       Pending   0          33m

Este status pending é normal, pois o Kubernetes está provisionando os Pods, pode demorar alguns minutos dependendo do tamanho da imagem.

No final você terá todos os Pods rodando.
#kubectl get pods

[root@kubernetes-master1 ~]#  kubectl get pods 
NAME                    READY     STATUS    RESTARTS   AGE
webserver-nginx-2th95   1/1       Running   0          54m
webserver-nginx-v4404   1/1       Running   0          54m
webserver-nginx-za52c   1/1       Running   1          54m

Verificando o Replication controller
#kubectl get rc

[root@kubernetes-master1 ~]# kubectl get rc
CONTROLLER        CONTAINER(S)      IMAGE(S)   SELECTOR              REPLICAS   AGE
webserver-nginx   webserver-nginx   nginx      run=webserver-nginx   3          59m

Verificando informações sobre um Pod.
Você criou um Pod pelo Kubernetes mas você não sabe muita coisa sobre ele, como os Ips.
#kubectl describe pod webserver-nginx-2th95

[root@kubernetes-master1 ~]# kubectl describe pod  webserver-nginx-2th95
Name:				webserver-nginx-2th95
Namespace:			default
Image(s):			nginx
Node:				kubernetes-minion2.devopslab.com.br/10.0.2.32
Start Time:			Sat, 02 Apr 2016 00:05:49 -0300
Labels:				run=webserver-nginx
Status:				Running
Reason:				
Message:			
IP:				10.0.14.2
Replication Controllers:	webserver-nginx (3/3 replicas created)
Containers:
  webserver-nginx:
    Container ID:	docker://a08a160b25fb141a8546028b09349c50adf4442b93e19a15e6500fc789ad695b
    Image:		nginx
    Image ID:		docker://6f62f48c4e55d700cf3eb1b5e33fa051802986b77b874cc351cce539e5163707
    QoS Tier:
      cpu:		BestEffort
      memory:		BestEffort
    State:		Running
      Started:		Sat, 02 Apr 2016 00:59:18 -0300
    Ready:		True
    Restart Count:	0
    Environment Variables:
Conditions:
  Type		Status
  Ready 	True 
No volumes.
Events:
  FirstSeen	LastSeen	Count	From						SubobjectPath				Reason	Message
  ─────────	────────	─────	────						─────────────				──────	───────
  38m		38m		1	{kubelet kubernetes-minion2.devopslab.com.br}	implicitly required container POD	Pulled	Successfully pulled image "registry.access.redhat.com/rhel7/pod-infrastructure:latest"
  38m		38m		1	{kubelet kubernetes-minion2.devopslab.com.br}	implicitly required container POD	Created	Created with docker id f7add7ef632a

Consultando os Ips de todos os Pods de um específico Replication Controller.
#kubectl get pods -l run=webserver-nginx -o yaml | grep podIP

[root@kubernetes-master1 ~]# kubectl get pods -l run=webserver-nginx -o yaml | grep podIP
    podIP: 10.0.14.2
    podIP: 10.0.10.2
    podIP: 10.0.91.2

8. Criando um serviço e acessando os serviços dos Pods

Até o momento nós temos o Kubernetes rodando, Pods criados, porta 80 exposta nos containeres, e Nginx instalado, tudo bonito.

Mas como você vai acessar os serviço http do Nginx? Qual é a Url? Qual é o Ip?.
Veja quando nós temos um cluster auto gerenciável como nós criamos aqui, a ideia é que todos os Pods estejam rodando e quando algum deles cair o próprio cluster se encarregará de subir um novo container, e este container com um novo IP.

Então não adianta eu saber os Ips do containers, se um deles morrer, será criado um outro, com um novo Ip, Id e etc.

Aí que entra a ideia de Serviço, vamos criar um serviço que atuará como Loadbalancer do cluster, este serviço vai me disponibilizar um IP do cluster, eu vou acessar meus serviços por este Ip, para mim tanto faz quais são os containeres, Ips, onde estão e etc, eu quero apenas o ip do cluster, e que este responda pelos meus containers.

Vamos ver como isto funciona.
Consultando o RC.
#kubectl get rc

[root@kubernetes-master1 ~]# kubectl get rc
CONTROLLER        CONTAINER(S)      IMAGE(S)   SELECTOR              REPLICAS   AGE
webserver-nginx   webserver-nginx   nginx      run=webserver-nginx   3          1h

Criando um serviço.
#kubectl expose rc webserver-nginx –port=80

[root@kubernetes-master1 ~]# kubectl expose rc webserver-nginx --port=80
service "webserver-nginx" exposed

Consultando o IP do cluster.
#kubectl get service webserver-nginx

[root@kubernetes-master1 ~]# kubectl get service webserver-nginx
NAME              CLUSTER_IP      EXTERNAL_IP   PORT(S)   SELECTOR              AGE
webserver-nginx   10.254.174.71   <none>        80/TCP    run=webserver-nginx   1m

Consultando os Ips dos Pods do Cluster.
kubectl describe service webserver-nginx

[root@kubernetes-master1 ~]# kubectl describe service webserver-nginx
Name:			webserver-nginx
Namespace:		default
Labels:			run=webserver-nginx
Selector:		run=webserver-nginx
Type:			ClusterIP
IP:			10.254.174.71
Port:			<unnamed>	80/TCP
Endpoints:		10.0.10.2:80,10.0.14.2:80,10.0.91.2:80
Session Affinity:	None
No events.

[root@kubernetes-master1 ~]# kubectl get ep webserver-nginx
NAME              ENDPOINTS                                AGE
webserver-nginx   10.0.10.2:80,10.0.14.2:80,10.0.91.2:80   3m

Nosso CLUSTER_IP é 10.254.174.71 e este IP é acessível apenas de dentro da nossa Infraestrutura, ou seja apenas os hosts Minions tem acesso a este ip.

Então a partir de qualquer host Minion você pode fazer um curl para validar se os serviços de Nginx estão respondendo.
#curl 10.254.174.71

[root@kubernetes-minion1 ~]# curl 10.254.174.71
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@kubernetes-minion1 ~]# 

Agora se você quer acessar o cluster externamente, torná-lo público ou disponível para outras redes vamos utilizar algumas das opções como Loadbalancer, EXTERNAL_IP ou NodePort. NodePort é o conhecido expose do Docker, você vai criar um Pod e expor a porta do host Docker/Minion, podendo acessar o serviço do container através do Ip do host Docker/Minion.

Lembrando CLUSTER_IP é acessível apenas dentro da rede dos hosts Minions.

Eu vou criar novos tópicos abordando o acesso público, que na verdade o que vale mesmo é você criar um cluster e poder acessá-lo externamente. Mas veja bem, um cluster interno pode ser muito útil, pode existir serviços que você não queira que seja público como por exemplo um pool de servidores de cache ou algum pool de NoSQL como Cassandra. Nós temos que saber trabalhar com os 2 casos, Cluster Interno e Cluster externo.

Referências.
http://kubernetes.io/docs/getting-started-guides/centos/centos_manual_config/
http://kubernetes.io/docs/getting-started-guides/fedora/fedora_manual_config/
http://kubernetes.io/docs/getting-started-guides/fedora/flannel_multi_node_cluster/#master-setup
http://kubernetes.io/docs/user-guide/simple-nginx/
http://kubernetes.io/docs/user-guide/replication-controller/
http://kubernetes.io/docs/user-guide/deploying-applications/

Obrigado

Leonardo Macedo