åé·åããããã¹ããã¹ã±ã¼ã«ã¢ã¦ãããããã¹ããªã©ã®åããµã¼ãæ§æããã¤ãã¹ãã°ã«ã¼ããããããµã¼ãã¹ã«æå±ãããã¹ãå ¨ã¦ã«åæã«sshãã¦åæã«æä½ããããã¨ãããã è¤æ°ã®ãã¹ãã«åæãã°ã¤ã³ãããã¼ã«ã¨ã㦠cssh ããããã©ãæ¯åè¤æ°ã®ãã¹ãåãããããå ¥åããããããã«å¤ããªããã¹ãä¸è¦§ãã¡ã¤ã«ãæå ã«æã¡ãããªããImmutable Infrastructure æ代ã«ã¯ããããªããImmutable Infrastructure æ代ã«ã¯ãã¹ãåãªãã¦æ¯æ¥å¤åããã誰ãè¦ãã¦ãªãããµã¼ã管çãã¼ã«ä¸ã®ã°ã«ã¼ãåã使ã£ã¦ã°ã«ã¼ãé ä¸ã®ãã¹ãã«åæã«sshãããã ãã¨ãcssh ã¯å人çã«æåããªããå¾®å¦ãªã®ã§ã代ããã« tmux 㨠ssh ãçµã¿åããã¦ããã cssh ã¯ãã¹ã¿ã¨ãã¹ã¬ã¼ãã¨ãæ°æã¡ã¯ããããã©ãè¤æ°ã¦ã£ã³ãã¦æä½ã¯ä½¿ãæ £ããã¿ã¼ããã«ãã«ããã¬ã¯ãµã使ãããã
ãã1å°1å°ä¸å¯§ã« ssh ããããæ¯åè¤æ°ã®ãã¹ãåãããããæå®ã㦠cssh ããæ代ã¯çµãã£ãã ï¼ã¿ã¤ãã«ã« Mackerel ã¨æ¸ãã¦ããã©ãåå以ä¸ã¯ Mackerel ã«ä¾åããªã話ã§ããï¼
ãã¢
tssh
tmux ã使ã£ã¦ãè¤æ°ãã¹ãã«åæ ssh ãã°ã¤ã³ãã¦åæã«ãªãã¬ã¼ã·ã§ã³ã§ããã
GitHub - dennishafemann/tmux-cssh: TMUX with a "ClusterSSH"-like behaviour. ã使ã£ã¦ãããããä¸è¨ã®ãããªã¹ã¯ãªããã使ã£ã¦ãããã æåã¯ã»ã¼åãã§ãtmux ã使ãã¨30è¡è¶³ããã§å®ç¾ã§ããããããã
https://github.com/y-uuki/opstools/blob/master/tssh
#!/bin/bash hosts=("$@") session_name="tmux-ssh-$$" tmux start-server is_first="true" for host in ${hosts[@]}; do cmd="ssh $SSH_OPTION $USER@$host" if [ "${is_first}" == "true" ]; then tmux new-session -d -s $session_name "$cmd" is_first="false" else tmux split-window -t $session_name "$cmd" tmux select-layout -t $session_name tiled 1>/dev/null fi done tmux set-window-option -t $session_name synchronize-panes on tmux select-pane -t 0 tmux attach-session -t $session_name
Usage
$ tssh blogapp001.domain blogapp002.domain blogapp003.domain ... $ tssh blogapp00{1,2,3}.domain # ditto
ãã®ãã¨ãã ããã top å©ãã ãã°ãã¡ã¤ã«ã tail ãããããã
ãã¾ãã¨ãã¦ãç¹å®ã®ãã¹ãã®ã¿ãæä½ãããã¨ã㯠tmux ã® synchronize-panes 㨠ãã¤ã³ç§»åã使ãã
~/.tmux.conf ã«ä¸è¨ã®è¨å®ãæ¸ãã¦ããã¦ã
bind-key g setw synchronize-panes
tssh ã ãã§ãåå便å©ã ããMackerel ã® RESTful API ã使ããã¨ã§ããã¹ãåã¾ã㯠IP ã¢ãã¬ã¹ã«ä¾åããªããªãã¬ã¼ã·ã§ã³ãã§ãããã
Mackerel
Mackerel: A Revolutionary New Kind of Application Performance Management
ãµã¼ã管çãã¼ã« Mackerel ã§ã¯ããã¹ãããã¼ã«ã§ç®¡çããã å ·ä½çã«ã¯ããµã¼ãã¹åã¨ãã¼ã«åã®çµã§ãSaba-Blog::proxy ã Saba-Blog::appãSaba-Blog::db ã¿ãããªæãã
Mackerel ã¯ã¢ãã¿ãªã³ã°ã ãã§ãªããRESTful API ã使ã£ããµã¼ã管çã®èªååãä¿é²ãããã¨ãã¦ããã
Mackerel API ドキュメント(v0) - Mackerel API ドキュメント (v0)
ä»åã¯ããã¼ã«ã«æå±ãããã¹ãä¸è¦§ãåãããã®ã§ä¸è¨ã®ãã㪠curl 㨠jq ãçµã¿åãããã¯ã³ã©ã¤ãã¼ã使ãã ãããããã®ç¨éãªã API ã¯ã©ã¤ã¢ã³ãã使ãã¾ã§ããªãã
$ curl -s -H "X-Api-Key:<apikey>" -X GET 'https://mackerel.io/api/v0/hosts.js?service=Saba-Blog&role=app' | jq -a -M -r ".hosts[].name blogapp001.domain blogapp002.domain blogapp003.domain
æ¯åã¯ã³ã©ã¤ãã¼ãå©ãã®ãã ããã®ã§ã¹ã¯ãªããã«ããã~/bin/role
ã«ä»¥ä¸ã®ãããªã¹ã¯ãªãããç½®ãã¦ãã
#!/bin/bash if [[ $1 == '' ]]; then echo "requried service name" exit 1 fi if [[ $2 == '' ]]; then echo "requried role name" exit 1 fi curl -s -H "X-Api-Key:<apikey>" -X GET "https://mackerel.io/api/v0/hosts.json?service=$1&role=$2" | jq -a -M -r ".hosts[].name
ä¸è¨ role ã³ãã³ãã«ãµã¼ãã¹åã¨ãã¼ã«åãæå®ãã¦ããã°ç°¡åã«ãã¹ãä¸è¦§ãåå¾ã§ããã
$ role Saba-Blog app blogapp001.domain blogapp002.domain blogapp003.domain
role ã³ãã³ãã®ä»ã« service ã³ãã³ããç½®ãã¦ãããã£ãã¨ã»ã¨ãã©åãã
#!/bin/bash if [[ $1 == '' ]]; then echo "requried service name" exit 1 fi curl -s -H "X-Api-Key:<apikey>" -X GET 'https://mackerel.io/api/v0/hosts.js?service=$1' | jq -a -M -r ".hosts[].name
service Saba-Blog blogproxy001.domain blogproxy002.domain blogproxy003.domain blogapp001.domain blogapp002.domain blogapp003.domain ...
tssh + Mackerel
$ tssh `role Saba-Blog app`
ããã§ãªãã§ãã§ããã Zabbix ã Datadog ãªã©ä»ã®ãµã¼ã管çãã¼ã«/ãµã¼ãã¹ã使ã£ã¦ãããã¡ããåããã¨ã¯ã§ããã ãããã©ãMackerel ã¯ãã¹ãã®ã°ã«ã¼ãã³ã°ã®æéãå®ã¾ã£ã¦ããã®ã§ãã°ã«ã¼ãã³ã°æ¹éã«è¿·ããã¨ãå°ãªãã¨æãã
社å ã§ãã®æã®é£æºã¯æãããã£ã¦ã¦ãã¨ã«ãã便å©ã§æ¯æ¥ä½¿ã£ã¦ãã