rcbops / chef-cookbooks
自己紹介
名前 : 平井伴和(ひらいともかず) ID 名 : jedipunkz ブログ : http://jedipunkz.github.io 所属 : 日本 OpenStack ユーザ会 仕事 : R&D, インフラインジニア 職場 : KDDI ウェブコミュニケーションズ FF14: ‘jedi master’ キャラ on Alexander今日話すこと
•
osops-utils の概要 ( Chef は複数台構成を扱える)
•
rcbops-cookbooks で複数台 Havana を構成してみる
前提
* Chef の知識は前提とさせていただきます。
* Chef サーバ・ワークステーションの構築方法 は割愛させていただきます。
とは言っても
Chef とは?
Chef-Server WorkStation Node (1) (2) (3)(1) : cookbooks, roles, data_bag, environments 等をアップロード (2) : node に対して ‘bootstrap’ 行いデプロイ開始
(3) : cookbooks, roles 等をダウンロードし chef-client 実行, その後も定期的に実行
rcbops/chef-cookbooks とは?#1
rackspace 社の ‘Private Cloud’ サービスで用いられている OpenCenter が内部で Chef を使っている。
特徴 :
* ブラウザベースでデプロイ * 複数台構成, HA 構成等
rcbops/chef-cookbooks とは?#2
OpenCenter 内部で用いられている Chef Cookbooks
まず疑問
「
Chef で複数台構成を扱うのは厳しい」という
話をちょくちょく聞くのですが本当か?
Chef で複数台構成を扱うのは
簡単です!
osops-utils の概要 #1
* 複数台構成を扱う となる Cookbooks * 単体では動かない
* rcbops-cookbooks の各 Cookbooks が include
https://github.com/rcbops-cookbooks/osops-utils
特徴
osops-utils の概要 #2
… snip … ! "override_attributes": { "package_component": "havana", "osops_networks": { "management": "10.200.10.0/24", "public": "10.200.17.0/24", "nova": "10.200.10.0/24" }, ! … snip … Attributes の上書きを Environments で行う 1 Environment で OpenStack 1 クラスタosops-utils の概要 #3
hosts = search(:node, “chef_environment:#{node.chef_environment}")
!
… snip …
hosts.each do |host|
Chef::Log.info("osops-utils/autoetchosts: checking (#{host})") begin
ip = ::Chef::Recipe::IPManagement.get_ip_for_net("management", host) stra = String.new("#{ip} #{host["fqdn"]} #{host["hostname"]}\n")
hfile << stra rescue
Chef::Log.info(
"osops-utils/autoetchosts: skipping node (#{ip}) because" + " it doesn't have a network assigned yet")
end end
Recipe の中を覗いてみる
自らと同じ environment のノードを検索
osops-utils の概要 #4
Chef::Recipe::IPManagement クラス get_ip_for_net メソッドを覗く
# network number associated with this network
net = IPAddr.new(node[“osops_networks"][network])
! !
# loop thru node's interfaces and look at addresses
node["network"]["interfaces"].each do |interface| # ohai で interfaces を取得
! !
Chef::Log.debug("#{ourname} examining interface #{interface[0]}") if interface[1].has_key?("addresses") then
# loop thru each address on this interface interface[1]["addresses"].each do |k, v|
if v["family"] == "inet6" or (v["family"] == "inet" and v["prefixlen"] != "32") then
!
addr=IPAddr.new(k) if net.include?(addr)
Chef::Log.debug(ourname + " ===> using #{addr}") return k # found it
else
Chef::Log.debug(ourname + " - ignoring #{addr}") end
environment で指定したネットワークアドレス
chef サーバに node の全 NW I/F 情報を取得しに
osops-utils の概要 #4
ohai コマンドの結果抜粋 "network": { "interfaces": { "lo": { "mtu": "16436", "flags": [ "LOOPBACK", "UP", "LOWER_UP" ], … snip … "eth0": { "type": "eth", …. snip … "10.200.9.100": { "family": "inet", "prefixlen": "24", "netmask": "255.255.255.0", "broadcast": "10.200.9.255", "scope": "Global" }, … snip …osops-utils の概要 #5
query = "#{query_type}s:#{search_string} AND chef_environment:#{current_node.chef_environment}" debug("osops_search query: #{query}")
result, _, _ = Chef::Search::Query.new.search(:node, query)
* 下記の条件で検索すると目的のノードを知ることが可能 ‘role, recipe 名 + 自ノードと同じ environmnet’
osops_search というノード検索のためのメソッドの抜粋
* その後 get_ip_for_net メソッドにて目的のノードの IP を 知ることが可能
osops-utils の概要 #6
* 自ノードと同じ environment 且つ目的の Roles/Recipe のノードを Chef サーバで検索することが可能 * 目的のノードの IP アドレスを get_ip_for_net メソッド で検索することが可能 おぷ☆すたの複数台構成を Chef で構成出来る! まとめ 用途にあったノードの I/F アドレスが取得し合えるrcbops-cookbooks で
Havana
rcbops-cookbooks で Havana
controller network network compute compute workstationexternal public management guest * 4つの物理ネットワークを前提 * public ネットワーク : 外部 API 用ネットワーク * external ネットワーク : インスタンス外部接続用ネットワーク * guest ネットワーク : インスタンス内部用ネットワーク * management ネットワーク : 各コンポーネント接続用ネットワーク * public, external のみグローバルネットワーク
* controller : 2 nics, network : 4 nics, compute : 3nics の構成 * controller はシングル構成
* network ノードは台数拡張可能, agent 単位でノード間移動可能 * compute ノードも台数拡張可能
* workstation は chef-repo の所在地, management ネットワークに所属 特徴
rcbops-cookbooks で Havana #2
% git clone https://github.com/rcbops/chef-cookbooks.git % cd chef-cookbooks
% git checkout -b v4.2.0 refs/tags/v4.2.0
% # .chef 配下の準備割愛。各 Chef サーバ環境に合わせる % git submodule init
% git submodule sync % git submodule update
% knife cookbook upload -o cookbooks -a % knife role from file roles/*.rb
rcbops-cookbooks で Havana #3
{ "name": "havana-neutron", "description": "", "cookbook_versions": { }, "json_class": "Chef::Environment", "chef_type": "environment", "default_attributes": { }, "override_attributes": { "package_component": "havana", "osops_networks": { "management": "10.200.10.0/24", "public": "10.200.9.0/24", "nova": "10.200.10.0/24" }, … snip … * 詳しくはブログで。 http://jedipunkz.github.io/blog/2013/11/17/openstack-havana-chef-deploy/rcbops-cookbooks で Havana #4
% knife environment from file \
rcbops-cookbooks で Havana #5
controller ノードのデプロイ。!
% knife bootstrap <controller_ipaddr> -N <controller_name> \ -r 'role[single-controller]','role[cinder-volume]' \
-E havana-neutron -x <username> —sudo
!
network ノードのデプロイ。台数分デプロイしてください。
!
% knife bootstrap <network_ipaddr> -N <network_name> \
-r 'role[single-network-node]','recipe[nova-network::neutron-l3-agent]' \ -E neutron-havana -x <username> —sudo
!
compute ノードのデプロイ。台数分デプロイしてください。
!
% knife bootstrap <compute_ipaddr> -N <compute_name> \ -r 'role[single-compute]' \
rcbops-cookbooks で Havana #6
% sudo ovs-vsctl add-port br-eth1 eth1% sudo ovs-vsctl add-port br-ex eth3
% sudo ovs-vsctl add-port br-eth1 eth1 ネットワークノードにて
rcbops-cookbooks で Swift #1
構成swift-storage01 swift-storage02 swift-storage03 swift-account01 swift-account02 swift-account03 chef server chef workstation swift-manage swift-proxy01 swift-proxy02
load balancer
proxy network
storage network
* swift-storage, account には予め /dev/sdb を接続 * swift-mange 上で git サーバ稼働 <- Rings 管理
rcbops-cookbooks で Swift #2
% git clone https://github.com/rcbops/chef-cookbooks.git % cd chef-cookbooks
% git checkout -b v4.1.2 refs/tags/v4.1.2 % git submodule init
% git submodule sync % git submodule update
% knife cookbook upload -o cookbook -a % knife role from file role/*.rb
rcbops-cookbooks で Swift #3
{ "name": "swift", "description": "", "cookbook_versions": { }, "json_class": "Chef::Environment", "chef_type": "environment", "default_attributes": { }, "override_attributes": { "package_component": "grizzly", "osops_networks": { "management": "10.200.9.0/24", "public": "10.200.9.0/24", "nova": "10.200.9.0/24", "swift": "10.200.9.0/24" }, Environment の json ファイルを生成rcbops-cookbooks で Swift #4
% knife environment from file environments/swift.json Environment の json ファイルをアップロード
rcbops-cookbooks で Swift #6
swift-manage のブートストラップ
% knife bootstrap <manage_ip_addr> -N swift-manage -r \
’role[base]','role[mysql-master]','role[keystone]','role[swift-management-server]' -E swift --sudo -x thirai swift-proxyNN のブートストラップ
% knife bootstrap <proxy01_ip_addr> -N swift-proxy01 -r \
”role[base]","role[swift-proxy-server]",'role[swift-setup]','role[openstack-ha]' -E swift --sudo -x thirai % knife bootstrap <proxy02_ip_addr> -N swift-proxy02 -r \
”role[base]","role[swift-proxy-server]",'role[openstack-ha]' -E swift --sudo -x thirai swift-storageNN のブートストラップ
% knife bootstrap <storage01_ip_addr> -N swift-storage01 -r \ role[base]’,'role[swift-object-server]' -E swift --sudo -x thirai % knife bootstrap <storage02_ip_addr> -N swift-storage02 -r \ ’role[base]','role[swift-object-server]' -E swift --sudo -x thirai % knife bootstrap <storage03_ip_addr> -N swift-storage03 -r \ ’role[base]','role[swift-object-server]' -E swift --sudo -x thirai swift-accountNN のブートストラップ
% knife bootstrap <account01_ip_addr> -N swift-account01 -r \
’role[base]','role[swift-account-server]','role[swift-container-server]' -E swift --sudo -x thirai % knife bootstrap <account02_ip_addr> -N swift-account02 -r \
’role[base]','role[swift-account-server]','role[swift-container-server]' -E swift --sudo -x thirai % knife bootstrap <account03_ip_addr> -N swift-account03 -r \
’role[base]','role[swift-account-server]','role[swift-container-server]' -E swift --sudo -x thirai
rcbops-cookbooks で Swift #7
% knife bootstrap <ip_swift-proxy01> -N swift-proxy01 -r 'role[ha-swift-controller1]' -E swift-ha --sudo -x jedipunkz
% knife bootstrap <ip_swift-proxy02> -N swift-proxy02 -r 'role[ha-swift-controller2]' -E swift-ha --sudo -x jedipunkz
おまけ 下記のように Roles を割り当てると HA 構成の Swift を構成することも可能 特徴 * haproxy でロードバランス * keepalived で VRRP * MySQL HA
rcbops-cookbooks で Swift #8
% knife exec -E "nodes.find(:name => 'swift-storage01') {|n| n.set['swift']['zone'] = '1'; n.save }" % knife exec -E "nodes.find(:name => 'swift-account01') {|n| n.set['swift']['zone'] = '1'; n.save }" % knife exec -E "nodes.find(:name => 'swift-storage02') {|n| n.set['swift']['zone'] = '2'; n.save }" % knife exec -E "nodes.find(:name => 'swift-account02') {|n| n.set['swift']['zone'] = '2'; n.save }" % knife exec -E "nodes.find(:name => 'swift-storage03') {|n| n.set['swift']['zone'] = '3'; n.save }" % knife exec -E "nodes.find(:name => 'swift-account03') {|n| n.set['swift']['zone'] = '3'; n.save }"
rcbops-cookbooks で Swift #9
% knife exec -E \ 'search(:node,"role:swift-object-server OR \ role:swift-account-server \ OR role:swift-container-server") \ { |n| puts "#{n.name}"; \ begin; n[:swift][:state][:devs].each do |d| \ puts "\tdevice #{d[1]["device"]}"; \end; rescue; puts \
"no candidate drives found"; end; }' swift-storage02 device sdb1 swift-storage03 device sdb1 swift-account01 device sdb1 swift-account02 device sdb1 swift-account03 device sdb1 swift-storage01 device sdb1 disk が検知出来るかを確認
rcbops-cookbooks で Swift #10
swift-manage% sudo chef-client
swift-manage% sudo ${EDITOR} /etc/swift/ring-workspace/generage-rings.sh swift-manage% sudo /etc/swift/ring-workspace/generate-rings.sh
swift-manage# cd /etc/swift/ring-workspace/rings
swift-manage# git add account.builder container.builder object.builder swift-manage# git add account.ring.gz container.ring.gz object.ring.gz swift-manage# git commit -m "initial commit"
swift-manage# git push
rings ファイル達の git サーバでの管理 chef-client 実行と rings ファイル達の生成