Slide 1

Slide 1 text

ฏ࿨ͳ Consul cluster ӡ༻ Consul Casual Talks #1@fujiwara

Slide 2

Slide 2 text

౻ݪ ढ़Ұ࿠ @fujiwara github.com/fujiwara sfujiwara.hatenablog.com ٕज़෦

Slide 3

Slide 3 text

Game & Community

Slide 4

Slide 4 text

Agenda Consulͷ׆༻ࣄྫ ฏ࿨ʹӡ༻͢ΔͨΊͷϙΠϯτ

Slide 5

Slide 5 text

Consulͷ׆༻ࣄྫ 1. Internal DNS (node, service) 2. maintͰϝϯςφϯε 3. StretcherʹΑΔσϓϩΠɺChef࣮ߦ 4. consul-templateʹΑΔnginxͷઃఆߋ৽ 5. 1୆͔͠ಈ͔ͨ͘͠ͳ͍daemonͷഉଞىಈ

Slide 6

Slide 6 text

Internal DNS

Slide 7

Slide 7 text

Internal DNS (node, service) node໊ (ྫ kayac-web-i-1234567...) service໊(ྫ) • log-aggregator : Fluentdͷू໿αʔό • log-analyzer : Norikra • internal-proxy : ֎ʹग़ͯߦͨ͘ΊͷSquid • internal-mta : ֎ʹग़ͯߦͨ͘ΊͷPostfix

Slide 8

Slide 8 text

Internal DNS (node, service) dnsmasqΛશ୆Ͱىಈ .consul υϝΠϯͷ໊લղܾ͸consul agent΁ 127.0.0.1:53 Λdnsmasq͕Listen͢Δ # dnsmasq.conf server=/consul/127.0.0.1#8600 bind-interfaces listen-address=127.0.0.1

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

Internal DNS (node, service) resolv.conf Ͱ (node|service).consul ΛݕࡧυϝΠϯʹࢦఆ → node໊ɺservice໊͚ͩͰ઀ଓͰ͖Δ # /etc/resolv.conf search node.consul service.consul nameserver 127.0.0.1 # dnsmasq nameserver 172.16.0.2 # VPC resolver nameserver 172.16.0.254 # Unbound on EC2

Slide 11

Slide 11 text

bash-completionͰsshͷϗετ໊ิ׬ ~/.bash_profile _known_hosts_real() { local members=$(consul members -status=alive | awk '!/Node/{printf("%s ", $1)}') COMPREPLY=( $( \ compgen -W "$members" \ ${COMP_WORDS[COMP_CWORD]} \ ) ) return 0 } ੜ͖͍ͯΔϗετͷΈิ׬ީิʹͳΔ http://qiita.com/sfujiwara/items/f4fa907ead53ed104e1a

Slide 12

Slide 12 text

Fluentdͷू໿αʔό΁ૹΔઃఆ ConsulͰఏڙ͢ΔDNS໊΁ϥ΢ϯυϩϏϯͰૹ৴ type forward expire_dns_cache 15 dns_round_robin true heartbeat_type tcp host log-aggregator.service.consul ૹ৴ઌͷྻڍෆཁɺࣗಈ੾Γ཭͠

Slide 13

Slide 13 text

maintͰϝϯςφϯε

Slide 14

Slide 14 text

consul maint consul maint -enable [-reason "..."] ͋ΔnodeΛϝϯςφϯεϞʔυʹ͢Δ → serviceͷ໊લղܾ͔Β͸֎ΕΔ → nodeͷ໊લղܾ͸Ͱ͖Δ (sshͱ͔)

Slide 15

Slide 15 text

consul maint࢖༻ྫ Fluentdू໿αʔόΛϝϯςφϯε͍ͨ͠৔߹ʹmaint → DNS͔Β֎ΕΔͷͰૹ৴͕ࢭ·Δ (expire_dns_cache ͷઃఆ͕ඞཁ) NorikraͷΠϯελϯεΛऔΓସ͍͑ͨͱ͖ʹ • ৽͍͠ϗετΛ maint -enable ͰηοτΞοϓ • چͰ maint -enable, ৽Ͱ maint -disable • DNSͰೖΕସΘΔͷͰૹ৴ઌ͕੾ΓସΘΔ

Slide 16

Slide 16 text

PackerͰ AMI ࡞੒࣌ʹ maint 1. consul cluster ʹ join 2. maint -enable (ߏஙதʹ૊Έࠐ·Εͳ͍Α͏ʹ) 3. ChefͰߏங 4. maintঢ়ଶͷ·· AMI ࡞੒ 5. AMI͔Βىಈͨ͠Πϯελϯε΋maintͷ·· 6. ىಈޙͷॾʑ͕ऴΘͬͨΒ maint -disable → αʔϏεΠϯ

Slide 17

Slide 17 text

maintͳΒىಈ͠ͳ͍ daemontools ͷ run script #!/bin/bash maint=$(consul maint) if [[ $maint != "" ]]; then echo "$maint" sleep 10 exit 1 fi exec ... ϝϯς࣌ʹىಈͯ͠ཉ͘͠ͳ͍daemonΛ੍ޚ (maint -enableʹͳͬͯ΋stopͨ͠Γ͸͠ͳ͍)

Slide 18

Slide 18 text

StretcherʹΑΔσϓϩΠ

Slide 19

Slide 19 text

StretcherʹΑΔσϓϩΠ github.com/fujiwara/stretcher Consul / Serf ͱ࿈ܞͯ͠ಈ͘σϓϩΠπʔϧ

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

StretcherͰChef࣮ߦ Chef-Server → Stretcher + Chef-Solo • Chef-Serverr͕ SPOF / ϘτϧωοΫʹͳΒͳ͍ • શ୆ʹಉ͡tar, eventΛ഑෍ˠద༻͢ΔjsonΛ֤ϊʔυͰܾఆ # /etc/sysconfig/hostname-prefix HOSTNAME_PREFIX="xxx-app" → nodes/xxx-app.json Λద༻

Slide 22

Slide 22 text

ChefͷroleݕࡧΛserviceఆٛͰ /etc/consul.d/role.json { "service": { "name": "role", "tags": [ "batch-server", "db-client", ... ] } } Serviceͱͯ͠ఆٛͯ͠ݕࡧՄೳʹ http://localhost:8500/v1/catalog/service/role? tag=db-client

Slide 23

Slide 23 text

http://localhost:8500/v1/catalog/service/role? tag=internal-proxy [ { "Node": "xxx-i-10bf0fe2", "Address": "10.0.0.123", "ServiceID": "role", "ServiceName": "role", ... }, { "Node": "xxx-i-3c1b72b3", "Address": "10.0.1.234", "ServiceID": "role", "ServiceName": "role", ... } ]

Slide 24

Slide 24 text

Daemontools؅ཧԼͷdaemon΋serviceఆٛ { "service": { "name": "daemontools", "tags": [ "app", stretcher", "gunfish", ... ] } }

Slide 25

Slide 25 text

͋Δdaemontools؅ཧϓϩηεΛ࠶ىಈ͍ͨ͠ curl http://localhost:8500/v1/catalog/service/ daemontools?tag=gunfish | jq -r ".[].Node" xxx-admin-i-0391d6162be552655 xxx-app-i-01a7ff42f4796be4f xxx-app-i-05bd652734828b522 xxx-batch-i-0095ac858fe87d8e5 Regexp::TrieͰ࠷దͳਖ਼نදݱʹͯ͠ consul exec consul exec -node '(?:xxx\-(?:a(?:dmin|pp)|batch))' "svc -h /service/gunfish"

Slide 26

Slide 26 text

consul-templateʹΑΔnginxͷઃఆߋ৽

Slide 27

Slide 27 text

consul-template https://github.com/hashicorp/consul-template • Consul KVͷ஋ɺServiceͷղܾ݁ՌͳͲΛτϦΨʹ • ςϯϓϨʔτߋ৽ɺ೚ҙscript kick͕Ͱ͖Δ

Slide 28

Slide 28 text

nginxͷઃఆߋ৽ # config.hcl template { source = "/etc/nginx/spam.ip.conf.ctmpl" destination = "/etc/nginx/spam.ip.conf" command = "service nginx reload" perms = 0644 backup = true } # spam.ip.conf.ctmpl {{key "spam_ips"}} localhost:8500/v1/kv/spam_ips ʹPUT͢Δ͚ͩͰઃఆߋ৽

Slide 29

Slide 29 text

1୆͔͠ಈ͔ͨ͘͠ͳ͍daemonͷഉଞىಈ

Slide 30

Slide 30 text

1୆͔͠ಈ͔ͨ͘͠ͳ͍daemonͷഉଞىಈ WebSocketड৴Ͱಈ͘Slack bot→ 2୆Ҏ্Ͱಈ͘ͱ෼਎͢Δ Ͱ΋Մ༻ੑΛ͍࣋ͨͤͨ…

Slide 31

Slide 31 text

1୆͔͠ಈ͔ͨ͘͠ͳ͍daemonͷഉଞىಈ consul lock Λ࢖͏ ϩοΫΛऔಘͰ͖ͨΒࢦఆͨ͠ίϚϯυ͕࣮ߦ͞ΕΔwrapper consul lock -n 1 nuko "/path/to/run-nuko.sh" Consul leader͕ೖΕସΘΔͱϩοΫ͕ղ์͞ΕΔͷͰ஫ҙ

Slide 32

Slide 32 text

ฏ࿨ʹӡ༻͢ΔͨΊͷϙΠϯτ

Slide 33

Slide 33 text

ฏ࿨ʹӡ༻͢ΔͨΊͷϙΠϯτ RaftΛ(େ·͔ʹͰ΋͍͍ͷͰ)஌͓ͬͯ͘ http://thesecretlivesofdata.com/raft/ ෼ࢄ؀ڥͰͷ߹ҙܗ੒ΞϧΰϦζϜ • Ϧʔμʔબग़ʹʮա൒਺ʯͷ߹ҙ͕ඞཁ • 2୆ = 1୆མͪΔͱա൒਺(=2)͕औΕͳ͍ • 3୆ = 1୆མͪͯ΋ա൒਺(=2)͕औΕΔ • 4୆ = 2୆མͪΔͱա൒਺(=3)͕औΕͳ͍

Slide 34

Slide 34 text

Deployment Table ຊ൪Ͱ͸࠷௿3୆, 3 or 5͕ਪ঑ consul.io/docs/internals/consensus.html

Slide 35

Slide 35 text

ServerʹඞཁͳϦιʔε • CPU: 2CPUͰे෼ • Memory: 20MBʙ • Disk: 2MBʙ Memory, Disk͸KVͷར༻ঢ়گ࣍ୈ KV dump JSON 10MB, data_dir/raft 120MB → consul agent RSS 250MB

Slide 36

Slide 36 text

Serverʹ͸ઐ༻ϗετ͕ඞཁʁ consul agentࣗମ͸ͦΕ΄ͲϦιʔεΛ࢖༻͠ͳ͍ Disk IO͕ߴෛՙͳ৔߹ʹRaftͷHeartbeat͕ࣦഊ͠΍͍͢ • Timeout 500ms • Heartbeatʹࣦഊ͢ΔͱLeaderબग़͕ߦΘΕΔ • ௨ৗ2,3ඵͰબग़͸׬ྃ͢Δ • Consul server ͸ tmpfs Λอଘઌʹͯ͠Disk IOͷӨڹճආ

Slide 37

Slide 37 text

ߴՄ༻ੑͷͨΊʹ Server୆਺ʹΑΓಉ࣌ʹো֐Λىͯ͜͠ ΋໰୊ͳ͍node਺͕มΘΔ • 3 node → 1 • 5 node → 2 3 nodeߏ੒࣌ɺ2୆མͪͯ࢒Γ1୆ʹͳ ͬͯ͠·͏ͱLeader͕બग़Ͱ͖ͳ͍ ௕࣌ؒ੾Γ཭͢ϝϯςφϯε࣌ʹ͸Ұ࣌ తʹServer nodeΛ૿΍͢ख΋

Slide 38

Slide 38 text

ߴՄ༻ੑͷͨΊʹ Server nodeͷfailover͸ࣗಈ ! Ϣʔβ͸ৗʹlocalhostͷagent͚ͩΛΈ͍ͯΕ͹Α͍

Slide 39

Slide 39 text

nodeো֐࣌ͷӨڹ ! LeaderͰ͸ͳ͍ → " ଞnodeʹ͸Өڹͳ͠ ! Leader → " Leader࠶બग़ σϑΥϧτͰ͸͢΂ͯͷಡΈॻ͖ΛLeader͕ॲཧ (ڧҰ؏ੑ) Leader͕ܾ·Δ·ͰΞΫηεෆೳ (DNS, HTTP)

Slide 40

Slide 40 text

Stale mode (DNS) Leader࠶બग़͸௨ৗ2ʙ3ඵͰ׬ྃ ͦͷؒ΋DNSͰNode, Service໊ղܾΛ͍ͨ͠ʁ → Stale mode : Leaderະબग़Ͱ΋Ԡ౴Մೳ "dns_config":{ "allow_stale": true, // default false "max_stale": "10s" // default 5s } ݁Ռ͸ݹ͍Մೳੑ͕͋Δ(݁Ռ੔߹ੑ)

Slide 41

Slide 41 text

DNS TTL default͸TTL 0 → cache͞Εͳ͍ node, serviceผʹTTLΛઃఆՄೳ DNS cache(ͨͱ͑͹dnsmasq)Λલஈʹ഑ஔͯ͠cacheͰ͖Δ "dns_config":{ "node_ttl": "60s", "service_ttl": { "*": "15s" } }

Slide 42

Slide 42 text

Stale mode (HTTP API) HTTP APIͰstale modeʹ͢Δ৔߹͸Ҿ਺ stale $ curl "http://127.0.0.1:8500/v1/kv/web/key1?stale" staleҾ਺ͳ͠ͰLeaderબग़தʹΞΫηε → 500 Internal Server Error

Slide 43

Slide 43 text

ӡ༻தͷUpgrade consul.io/docs/upgrading.html consul.io/docs/upgrade-specific.html όʔδϣϯผʹ஫ҙ఺͕͋ΔͷͰυΩϡϝϯτΛ ॱ൪ʹAgentΛೖΕସ͑Δ͜ͱͰ Rolling upgradeՄೳ (Leader nodeೖΕସ͑Ͱ࠶બग़͸ى͖Δ)

Slide 44

Slide 44 text

҆ఆੑ v0.2࣌୅͔Β2೥Ҏ্ӡ༻ Agentϓϩηε͕མͪͨ͜ͱ͸1ճ͚ͩ(0.4.1࣌୅) EBS(gp2)ͷΫϨδοτރׇ → IO waitେྔ → panic: Timeout starting MDB transaction ΦϖϛεͰServerΛམͱ͗͢͠Δͱճ෮ෆೳ

Slide 45

Slide 45 text

KVͷόοΫΞοϓ ͋Δ֊૚ͷԼͷ஋Λ࠶ؼతʹऔΓ͍ͨ৔߹͸ recurse $ curl -s "http://127.0.0.1:8500/v1/kv/?recurse" [ {"CreateIndex":112,"ModifyIndex":115,"LockIndex":0, "Key":"key1","Flags":123,"Value":"dGVzdA=="}, {"CreateIndex":122,"ModifyIndex":122,"LockIndex":0, "Key":"key2","Flags":0,"Value":"dGVzdDI="}, {"CreateIndex":124,"ModifyIndex":124,"LockIndex":0, "Key":"test/1","Flags":0,"Value":"dGVzdDM="} ] Key, Flags, ValueΛPUT͠ͳ͓͠ͰϨετΞͰ͖Δ

Slide 46

Slide 46 text

࣮ࡍʹLeader͕ೖΕସΘͬͨͱ͖ͷϩά 2016/07/30 10:07:28 [WARN] raft: Heartbeat timeout reached, starting election 2016/07/30 10:07:28 [INFO] raft: Node at 10.0.2.132:8300 [Candidate] entering Candidate state 2016/07/30 10:07:30 [WARN] raft: Election timeout reached, restarting election 2016/07/30 10:07:30 [INFO] raft: Node at 10.0.2.132:8300 [Candidate] entering Candidate state 2016/07/30 10:07:30 [INFO] raft: Election won. Tally: 3 2016/07/30 10:07:30 [INFO] raft: Node at 10.0.2.132:8300 [Leader] entering Leader state 2016/07/30 10:07:30 [INFO] consul: cluster leadership acquired 2016/07/30 10:07:30 [INFO] consul: New leader elected: xxx-consul-i-ff26ca5a 2ඵఔ౓Ͱճ෮ DNSͷcache / stale mode ͰαʔϏεӨڹͳ͠ stale໌ࣔ͠ͳ͍HTTP API͸500ʹͳΔˠৗ࣌ୟ͖·͘Δͷ͸…?

Slide 47

Slide 47 text

࣮ࡍʹ͋ͬͨා͍࿩

Slide 48

Slide 48 text

consul exec Ͱେྔ݁Ռऔಘ consul exec "cat /var/log/foo.log" | grep ... ֤ϗετͷϩάΛconsul execͰऔಘ͠Α͏ͱͨ͠ → consul exec ͸KVʹҰ୴อଘ͢ΔͷͰϝϞϦ/DBංେԽ serverΛ1୆ͣͭ࠶ىಈͯ͠ճ෮

Slide 49

Slide 49 text

ΦϖϛεͰΫϥελ่յ upgrade͔ͨͬͨ͠ 3୆ߏ੒ͷserverͷ1୆Λམͱͯ͠ɺ৽͍͠όΠφϦͰىಈͨ͠ (ͭ΋Γͩͬͨ) ͪΌΜͱىಈ͍ͯ͠ͳ͍ͷʹ2୆໨ͷαʔόΛམͱͨ͠ → ่յ

Slide 50

Slide 50 text

่յͨ͠ΒͲ͏͢Ε͹ 1. མͪண͘ 2. serverΛશ෦ࢭΊΔ 3. σʔλ(data_dir)΋શ෦ফ͢ 4. serverΛ -bootstrap-expect N Ͱىಈ • start_join ·ͨ͸ खಈͰ join 5. (ඞཁͳΒ) KVΛόοΫΞοϓ͔Β໭͢