Olá. Aqui é a Komiya.
A primeira metade deste ano acabou antes que eu percebesse. Parece que o Uji Kintoki se tornou uma temporada deliciosa.
Enfim, esta é uma continuação do artigo anterior. Desta vez, vou escrever sobre a definição do ambiente antes de escrever a receita Chef-Solo.
Acho que é mais rápido dar uma olhada no Chef, que explica a terminologia do Chef de forma leve, ou assistir ao clássico Chef Solo introdutório.
A infraestrutura automatizada está no cardápio também em inglês, mas é fácil de entender.
As coisas que quero fazer são as seguintes.
Escreva um arquivo vagrant para criar uma instância virtual
Crie um repositório de chefs
Faça um livro de receitas de chef
Defina nó
Defina o papel
Defina dados_bags\
★ É isso ★ por agora
Escreva uma receita
Aplicando uma receita a um nó
Escrevendo testes de especificação do servidor
Executar testes em um ambiente real
Configuração do Teste:
Chef-Solo ADMserver Original: 10.0.0.93
Servidor web cliente da aplicação Knife-Solo: 10.0.0.240
Cliente de aplicação Knife-Solo DBserver: 10.0.0.241
Todos são CentOS 5.8.
- Definir variáveis do ambiente AWS
Como está na VPC da AWS, é definido de acordo
[shell]# cd # vi .ec2 exportar AWS_ACCESS_KEY_ID=*** exportar AWS_SECRET_ACCESS_KEY=***\* exportar AWS_KEYPAIR_NAME=xxx-key exportar AWS_PRIVATE_KEY_PATH=/root/.ssh/xxx-key # source .ec2[/shell]
・Escreva um VagrantFile
Se você rodar vagrant init, pode criar um vagrantfile, então edite e
Escreva as configurações para iniciar a instância virtual na VPC.
Nota
Configurações de Provisão (Chef Solo)
*Como o método de escrita de arquivos de configuração pode ser diferente do Vagrant 1.1, você precisa consultar o manual da v2.
Como fazer um script shell rodar
[shell]# vagrant init # cp -p Vagrantfile{,.org} # vi Vagrantfile ----------------------- Vagrant.configure("2") do |config| # Configuração comum config.vm.box = "dummy"
#---- Crie um servidor web a partir daqui config.vm.define :web do |web| web.vm.box = "dummy" web.vm.provider :aws do |aws| aws.access_key_id = ENV['AWS_ACCESS_KEY_ID'] aws.secret_access_key = ENV['AWS_SECRET_ACCESS_KEY'] aws.keypair_name = ENV['AWS_KEYPAIR_NAME'] aws.ssh_private_key_path = ENV['AWS_PRIVATE_KEY_PATH']
#---- Configuração específica de VPC ----# aws.private_ip_address = "10.0.0.240" aws.subnet_id = "subnet-80bxxxx9" aws.security_groups = ["SG-6EBXXXX", "SG-FA81xxxx"] #---- Configuração específica de VPC até agora ----#
aws.ssh_username = "raiz" aws.ssh_private_key_path = "~/.." ssh/komi-test.pem" aws.instance_type = "t1.micro" aws.tags = ["xxx-web03"] aws.region = "ap-northeast-1" aws.ami = "ami-d7bxxxx6" fim ## Configurar provisionamento #web.vm.provision :chef_solo do |chef| # chef.cookbooks_path = ["receitas", "site-cookbooks"] # chef.roles_path = "roles" # chef.add_role("servidor web") # chef.data_bags_path = "data_bags" # chef.node_name = "xxx-web03" # chef.log_level = "debugar" #end fim
#---- Crie um servidor de banco de banco a partir daqui config.vm.define :d b do |db| db.vm.provider :aws do |aws| aws.access_key_id = ENV['AWS_ACCESS_KEY_ID'] aws.secret_access_key = ENV['AWS_SECRET_ACCESS_KEY'] aws.keypair_name = ENV['AWS_KEYPAIR_NAME'] aws.ssh_username = '"root' #aws.ssh_private_key_path = ENV['AWS_PRIVATE_KEY_PATH']
#---- configurações específicas de VPC ----# aws.private_ip_address = "10.0.0.241" aws.subnet_id = "subnet-80bxxxx9" aws.security_groups = ["SG-6EBDXXXx", "SG-FA81xxxx"] #---- Configurações específicas de VPC até agora ----#
aws.ssh_username = "root" aws.ssh_private_key_path = "/.ssh/komi-test.pem" #aws.ssh_private_key_path = "/.ssh/id_dsa" aws.instance_type = "t1.micro" aws.tags = ["xxx-db03"] aws.region = "ap-northeast-1" aws.ami = "ami-d7bxxxx6" fim ## Configurar provisioning #db.vm.provision :chef_solo do |chef| # chef.receitas_path = ["livros de receitas", "site-receitas"] # chef.roles_path = "roles" # chef.add_role("dbserver") # chef.data_bags_path = "data_bags" # chef.json = { # "mysqld" => { # "server_id" => "103" # } # # # # chef.node_name = "xxx-db03" # chef.log_level = "debug" #end fim -----------------------[/shell] As configurações de provisionamento foram comentadas por conveniência (*)
(*Dados _bags conveniência da chave, etc., não funciona bem a menos que seja um comando de faca, etc.)
O seguinte erro ocorre quando o SecurityGroup não é escrito como um ID, mas com um nome ou uma sub-rede diferente na VPC.
[shell][web] -- Grupos de Segurança: ["default,nat-test-grp"] Houve um erro falando com a AWS. A mensagem de erro está mostrada abaixo:
InvalidParameterCombination => O parâmetro groupName não pode ser usado com a sub-rede de parâmetros
[web] -- Grupos de Segurança: ["sg-6815xxxx", "sg-6ebdxxxx"] Houve um erro falando com a AWS. A mensagem de erro está mostrada abaixo:
InvalidParameter => grupo de segurança sg-6815xxxx e sub-net sub-net 80bfxxxx pertencem a redes diferentes.[/shell]
・Configurações mínimas antes da conversão AMI
Depois de iniciado, ele para no meio, então vou realizar as seguintes configurações e pegar o AMI e especificá-lo novamente.
[shell]# ssh 10.0.0.240 # cd /root/.ssh # vi autorizado_keys[/shell] Registrar a chave raiz para o vagrant
Configurações de permissões do Sudo via SSH após o login [shell]# Visudo #Defaults requisito[/shell]
Por causa do ambiente VPC durante o período de transição, não pude sair, o curl falhou, o preparo solo com faca não funcionou e o chef não instalou.
Defina a fonte chef-solo equivalente a stg para a instância NAT e aponte o gateway padrão do cliente knife solo para NAT
[shell]# vi /etc/sysconfig/network GATEWAY=10.0.0.93[/shell]
Crie uma AMI para um nó a partir do AWS Management Console e lance a instância com o vagrant novamente
- Iniciar uma instância com vagrant
[shell]# vagrant up --provider=aws omitido [db] Esperando a instância ficar "pronta"... [db] Esperando SSH ficar disponível... [db] Máquina ligada e pronta para uso! [db] Pasta de rsync: /root/ => /vagrant[/shell]
Até agora, parece que várias instâncias de VPC foram bem lançadas, então
Em seguida, criamos um repositório, definimos um ambiente como role, escrevemos uma receita e provisionamos. Provision é aplicar uma receita a uma instância.
- Criar um novo repositório Chef
[shell]# knife solo init chef-repo # tree -L 1 chef-repo chef-repo |-- livros de receitas #サードパーティレシピ置き場 |-- dados_bags #ユーザ等データ管理機能使用時に使う |-- armazenamento de arquivos JSON para nós #各サーバ (nó) |-- papéis #Roleを使うとき用ディレクトリ |-- site-cookbooks #自作レシピ置き場 '-- solo.rb #cookbookのパスなどを設定[/shell]
Mova o arquivo vagrantfile diretamente para baixo do repositório do chef (para que o caminho do livro de receitas passe)
[shell]# mv Vagrantfile chef-repo/[/shell]
・Crie o livro de receitas necessário
Você pode criá-lo com o livro de receitas da faca criar nome-livro de receitas -o criar diretório-caminho.
[shell]# CD chef-repo # para i em base_setting login-users httpd mysqld munin zabbix ; do knife cookbook criar $i -o site-cookbooks; feito # árvore -L 1 site-cookbooks/munin site-cookbooks/munin site-cookbooks/munin |-- CHANGELOG.md |-- README.md |-- atributos #Attributesはtemplateで指定した変数のデフォルト値置き場 |-- definições |-- arquivos #定数のみの設定ファイルやパッケージファイル置き場 |-- bibliotecas |-- metadata.rb |-- fornecedores |-- receitas #レシピ置き場 |-- recursos '-- templates #変数を用いる設定ファイル置き場[/shell]
- Criar um papel
Ao definir um papel, ao aplicá-lo a cada servidor (ao editar um arquivo json para o nó),
Você não precisa listar nomes de receitas ou atributos toda vez, pode definir apenas o nome do Papel
Parece que você definiu um papel como servidor web ou dbserver, e enumera as receitas de acordo com o papel no papel. Defina um papel para o nó.
Template e Atributo também podem ser definidos em função ou nó.
Template e coloque um arquivo de configuração com variáveis no diretório de templates,
Coloque uma receita com o valor padrão no diretório de atributos e substitua o valor único com um papel ou nó.
*Se você quiser usar as informações coletadas pelo Ohai, não precisa definir um valor padrão no diretório de atributos nem não ter um valor de nó ou papel.
Defina as receitas que pretende escrever para cada rolo
[shell]# CD chef-repo/roles # vi webserver.json { "name":"webserver", "chef_type": "role", "json_class":"Chef::Role", "default_attributes":{ "base_setting": { "swappiness": "30", "tcp_tw_reuse": "0", "tcp_tw_recycle": "0", "tcp_fin_timeout": "60", "tcp_max_syn_backlog": "4096", "somaxconn": "4096", "somaxconn": "4096" } }, "override_attributes":{}, "description":"webserver's role", "run_list": [ "receita[base_setting:::" bkup_dir]", "receita[login_users]", "receita[base_setting::hosts]", "receita[base_setting::sysctl]", "receita[base_setting::d isable]", "receita[base_setting::ntpdate]", "receita[base_setting::mail-client]", "receita[base_setting::logrotate]", "receita[httpd::httpd-server]", "receita[httpd::basic_auth]", "receita[httpd::wordpress]", "receita[httpd::s3mount]", "receita[munin::munin-node]", "receita[munin::munin-node-web]", "receita[zabbix::zabbix-agent]" ] }
# vi dbserver.json { "name":"dbserver", "json_class":"Chef::Role", "chef_type": "role", "description":", "default_attributes":{ "base_setting": { "swappiness": "0", "tcp_tw_reuse": "1", "tcp_tw_recycle": "1", "tcp_fin_timeout": "10", "tcp_max_syn_backlog": "8192", "somaxconn": "8192" } }, "override_attributes":{}, "run_list": [ "receita[base_setting:::" bkup_dir]", "Receita[login_users]", "Receita[base_setting::hosts]", "Receita[base_setting::sysCTL]", "Receita[base_setting::d isable]", "Receita[base_setting::NTPdate]", "Receita[base_setting::Mail-client]", "Receita[base_setting::logrotate]", "Receita[mysqld::mysqld-server]", "Receita[mysqld::MySQL-users]", "Receita[munin::munin-node]", "receita[munin::munin-node-db]", "receita[zabbix::zabbix-agente]" ] }
# vi admserver.json { "name":"admserver", "json_class":"Chef::Role", "description":", "chef_type": "role", "default_attributes":{ "base_setting": { "swappiness": "0", "tcp_tw_reuse": "0", "tcp_tw_recycle": "0", "tcp_fin_timeout": "60", "tcp_max_syn_backlog": "8192", "somaxconn": "8192" } }, "override_attributes": {}, "run_list": [ "receita[base_setting::bkup_dir]", "receita[login_users]", "receita[base_setting::hosts]", "receita[base_setting::sysctl]", "receita[base_setting::d isable]", "receita[base_setting::ntpd]", "receita[base_setting::ntpdate]", "receita[base_setting:::mail-postfix]", "receita[base_setting::mail-dovecot]", "receita[base_setting::logrotate]", "receita[httpd::httpd-servidor]", "receita[httpd::wordpress]", "receita[mysqld::mysqld-server]", "receita[mysqld::mysql-users]", "receita[munin::munin-node]", "receita[munin::munin-node-web]", "receita[munin::munin-node-db]", "receita[munin::munin-server]", "receita[zabbix::zabbix-agent]", "receita[zabbix::zabbix-proxy]" ] }[/shell]
*De acordo com o anti-padrão iniciante do Chef, o papel não pode ser versionado.
Parece que a lista de runs não deveria ser gerenciada por função (sujeita a refatoração)
*Eu queria que o sysctl.conf tivesse um valor diferente para cada função, então decidi sobrepor isso incorporando uma variável no template e usando um atributo.
Vou explicar o modelo e o atributo em detalhes na próxima vez, mas entendo o atributo [[chef]. (http://tech.blog.piyo.org/2012/05/23/chef-attribute%E3%81%AE%E7%90%86%E8%A7%A3/) foi fácil de entender.
Sinto muito que essa seja uma história que não tem nada a ver com o chef, mas como está escrito aqui,
Você deveria (em alguns casos) parar de ativar "net.ipv4.tcp_tw_recycle".
Usando a mesma linha de um ambiente LAN sem fio pública com smartphone, etc.
A comunicação pode não ser possível ao acessar de vários terminais diferentes ao mesmo tempo.
Em outras palavras, 0 é o valor recomendado para o front WEB e o servidor MTA.
Se for um banco de dados backend que está sempre conectado de um IP diferente, não deve haver problema com o 1. Talvez.
・Criar um arquivo JSON para o nó
[shell]# CD chef-repo/nodes # vi localhost.json { "run_list":[ "role[admserver]" ] }
# vi 10.0.0.240.json { "run_list":[ "role[webserver]" ] }
# vi 10.0.0.241.json { "mysqld" : { "server_id" : 103 }, "run_list":[ "role[dbserver]" ] }[/shell]
*Papel e receita podem ser escritos juntos.
*Se você não usa o role, precisa escrever tudo no node, então se você tem 30 servidores web, é bem complicado.
*Especifica o atributo do parâmetro servidor_id do MySQL que precisa ser separado para cada nó.
*Se você quiser provisionar com o vagrant, pode ser que não precise de muito do arquivo JSON do nó.
・Prepare o gerenciamento de usuários com dados_bags
data_bags é algo que pode ser gerenciado, como busca de dados com funções semelhantes a LDAP.
Se você usar chef-server, pode se comunicar com o servidor para recuperar dados e refleti-los.
Como este é o Chef-solo, vamos preparar os dados em um arquivo local e refleti-los.
Referência:
Se você tem um grande número de usuários e frequentemente adiciona e troca de contas, seria uma boa ideia usar dados_bags para gerenciar a habilitação e desativação, conforme mostrado no link abaixo.
Como usar chef-data-bag
[shell]# CD ; CD chef-repo/data_bags # usuários de mkdir; usuários de cd # vi xxx-op.json // xxx-op.json { "id" : "xxx-op", "groups": [ "xxx-op", "wheel" ], "uid": 1000, "nome de usuário" : "xxx-op", "home" : "/home/xxx-op", "shell" : "/bin/bash", "senha" : "$1$Ka.Mw69U$TT5HRfSe7xxxxx" }
# vi yyy-op.json // yyy-op.json { "id" : "yyy-op", "groups": [ "yyy-op","wheel" ], "uid": 500, "username" : "yyy-op", "home" : "/home/yyy-op", "shell" : "/bin/bash", "password" : "$1$Ka.Mw69U$TT5HRfSe78Pxxxxx" }
# vi dev.json // dev.json { "id" : "dev", "groups": [ "dev","wheel" ], "uid": 501, "username" : "dev", "home" : "\/home\/dev", "shell" : "\/bin\/bash", "password" : "$1$S/q25RbR$o7pCoAjBWxxxxx" }[/shell]
Crie uma senha com o seguinte comando
[shell]# OPENSSL passwd -1[/shell]
[shell]# knife solo data bag show users[/shell] Certifique-se de que os dados estejam exibidos
- Criptografar a definição de usuário no MySQL
*Definir senhas em texto simples em arquivos JSON para nós e funções não é seguro, e não é inteligente registrá-las para cada nó.
Então vamos usar databags que podem ser criptografados usando chaves
Parece que a criptografia não pode ser usada apenas com knife-solo, mas se você _bag instalar o gem deck-solo_data\, poderá usá-la.
[shell]# openssl rand -base64 512 | tr -d '\r\n' > /etc/chef/encrypted_data_bag_secret # chmod 400 encrypted_data_bag_secret # cd /root/chef-repo # knife solo data bag criar mysqlusers root --secret-file ./encrypted_data_bag_secret o editor vai abrir, digitar o seguinte { "id": "root", "user": "root", "pass": "xxxxxxx", "host": "localhost", "privileges": "all" }
# knife solo data bag criar mysqlusers repl --secret-file ./encrypted_data_bag_secret O editor abrirá, inserirá o seguinte { "id": "repl", "user": "repl", "pass":"xxxxxxx", "host":"10.0.0.%", "privileges": ["\:replication slave", "\\:replication client"] }
# knife solo data bag criar mysqlusers xxx_admin --secret-file ./encrypted_data_bag_secret O editor abrirá, inserirá o seguinte { "id": "xxx_admin", "user": "xxx_admin", "pass": "xxxxxxx", "host":"10.0.0.%" "privileges": "all" }
# knife solo data bag criar mysqlusers zabbix --secret-file ./encrypted_data_bag_secret O editor abrirá, inserirá o seguinte { "id": "zabbix", "user": "zabbix", "pass": "xxxxxxx", "host": "localhost", "privileges": "all" }
Verifique # knife solo data bag mostrar mysqlusers # knife solo data bag mostrar mysqlusers repl --secret-file ./encrypted_data_bag_secret # knife solo data bag mostrar mysqlusers root --file-secreto ./encrypted_data_bag_secret # knife solo data bag mostrar mysqlusers xxx_admin --secret-file ./encrypted_data_bag_secret # knife solo data bag mostrar mysqlusers zabbix --secret-file ./encrypted_data_bag_secret[/shell] Certifique-se de que os dados estejam exibidos
Outros comandos podem ser encontrados abaixo.
[shell]# knife solo data bag --socorro[/shell]
Parece que é possível passar a chave para databags para o host cliente em um arquivo bootstrap com chef-server,
Talvez por causa do knife-solo_data_bag, parecia que não havia necessidade de especificar o arquivo bootstrap ao usar o nome de host do knife solo.
Eu realmente não sei como fazer isso do lado dos vagabundos.
Vou postar uma receita sobre como chamar a receita a partir da receita depois, mas o seguinte será útil.
Referência:
Registros do uso de DataBags para criptografar dados JSON que você não quer publicar no Chef Gerenciando senhas MySQL no Chef
Parece que o Chef-Server consegue separar o ambiente de produção e o ambiente de teste por ambiente, mas é um pouco decepcionante que essa função não esteja incluída no Chef-Solo.
No caso de um ambiente um pouco maior (mais de 20 unidades), o Chef-Server parece ser melhor, então se existir essa história, talvez eu a use、、、
Eu imaginei, mas depois que procurei, parece que pode ser usado a partir da 11.6. Ah, estou feliz. Vou tentar salvar depois.
É isso por agora. Obrigado por assistirem.
O próximo passo é sobre a receita.