fuel部完高可用環境後vip__public無法啓動從而導致創建虛機時無法創建virtualInterface.

查看fuel日誌:

# less /var/log/docker-logs/remote/node-1.domain.tld/puppet-apply.log

2015-12-25T17:26:22.134118+00:00 debug:  Waiting 600 seconds for service ‘vip__public‘ to start

 

等待“vip__public”啓動超過600秒。“vip__public”是集羣的VIP資源:

# crm configure show

primitive vip__public ocf:fuel:ns_IPaddr2 \
    op stop timeout=30 interval=0 \
    op monitor timeout=30 interval=3 \
    op start timeout=30 interval=0 \
    params ns_iptables_start_rules=false ip=168.1.22.80 ns_iptables_stop_rules=false iptables_stop_rules=false bridge=br-ex ns=haproxy nic=br-ex iptables_start_rules=false other_networks=false gateway=168.1.22.1 base_veth=br-ex-hapr gateway_metric=10 ns_veth=hapr-p iflabel=ka iptables_comment=false cidr_netmask=24 \
    meta migration-threshold=3 failure-timeout=60 resource-stickiness=1 target-role=Started

某種原因造成“vip__public”資源無法啓動:

# crm resource status vip__public

resource vip__public is NOT running

 

# ping 168.1.22.80

PING 168.1.22.80 (168.1.22.80) 56(84) bytes of data.
From 168.1.22.82 icmp_seq=2 Destination Host Unreachable
From 168.1.22.82 icmp_seq=3 Destination Host Unreachable

 

嘗試手動啓動資源仍失敗:

# crm resource start vip__public

# crm resource status vip__public

resource vip__public is NOT running

 

由於/var/log/corosync.log中沒有資源無法啓動的錯誤日誌,需另想辦法排查。

 

由於vip__public的資源類型是ocf:fuel:ns_IPaddr2,可知創建VIP時,調用了資源代理腳本:

/usr/lib/ocf/resource.d/fuel/ns_IPaddr2

創建OCF測試配置文件/usr/share/resource-agents/ocft/configs/ns_IPaddr2_start,內容如下:

--------------------------------------------------------------------------

# ns_IPaddr2

CONFIG
        Agent ns_IPaddr2
        AgentRoot /usr/lib/ocf/resource.d/fuel
        HangTimeout 20

CASE-BLOCK set_ocf_reskey_env
        Env OCF_RESKEY_iptables_start_rules=false
        Env OCF_RESKEY_iptables_stop_rules=false
        Env OCF_RESKEY_gateway_metric=10
        Env OCF_RESKEY_ns_veth=hapr-p
        Env OCF_RESKEY_base_veth=br-ex-hapr
        Env OCF_RESKEY_gateway=168.1.22.1
        Env OCF_RESKEY_bridge=br-ex
        Env OCF_RESKEY_ip=168.1.22.80
        Env OCF_RESKEY_iflabel=ka
        Env OCF_RESKEY_other_networks=false
        Env OCF_RESKEY_other_cidr_netmask=24
        Env OCF_RESKEY_ns=haproxy
        Env OCF_RESKEY_ns_iptables_start_rules=false
        Env OCF_RESKEY_iptables_comment=false
        Env OCF_RESKEY_nic=br-ex
        Env OCF_RESKEY_ns_iptables_stop_rules=false

CASE "::::begin test start::::"
        Include set_ocf_reskey_env
        AgentRun start OCF_SUCCESS

-----------------------------------------------------------------

編譯測試腳本:

# ocft make ns_IPaddr2_start

執行測試腳本:

# ocft test ns_IPaddr2_start

執行測試腳本並沒有報錯,且成功創建了VIP:

# ping 168.1.22.80

PING 168.1.22.80 (168.1.22.80) 56(84) bytes of data.
64 bytes from 168.1.22.80: icmp_seq=1 ttl=64 time=0.046 ms
64 bytes from 168.1.22.80: icmp_seq=2 ttl=64 time=0.059 ms

 

懷疑vip__public由於某些原因未調用此腳本。故編輯資源代理腳本:

# cp -a /usr/lib/ocf/resource.d/fuel/ns_IPaddr2 /usr/lib/ocf/resource.d/fuel/ns_IPaddr2.bak

# vi /usr/lib/ocf/resource.d/fuel/ns_IPaddr2

在669行添加:

    668 ## main
    669 echo $__OCF_ACTION>>/root/ns_IPaddr2.log
    670 rc=$OCF_SUCCESS
    671 case $__OCF_ACTION in

經此修改,一旦有調用資源代理腳本發生,就會輸出被調用的方法。

 

嘗試手動啓動資源並查看資源代理腳本是否被調用:

# crm resource start vip__public

# less /root/ns_IPaddr2.log

發現日誌中內容爲空,說明資源代理腳本果然沒被調用。

爲進一步驗證,我們嘗試操作其它正常的資源:

# crm resource restart vip__management

# less /root/ns_IPaddr2.log

發現日誌中有內容,說明正常的資源是有調用資源代理腳本的。

 

corosync.log中沒有日誌,ns_IPaddr2資源代理腳本沒有被調用,最有可能是vip__public的資源定義有邏輯錯誤。

集羣中的資源定義等相關數據,以xml文件的形式存儲在每個節點的/var/lib/pacemaker/cib/cib.xml,其中,對於每個定義的資源,同時可以定義其約束。約束的作用是設置一定條件,若滿足或不滿足條件,資源可啓動或不可啓動。

最有可能是約束定義錯誤。由於當時對cib.xml沒有任何瞭解,無法從中看出任何邏輯錯誤。

 

這種情況下,需要知道fuel在推送時,在什麼時候出現問題,且出現問題時,puppet做到哪一步。由於是VIP資源出問題,出問題的現象是ping 168.1.22.80不能通,且168.1.22.80並不是安裝初期就通不了,利用此特性,如果能夠知道168.1.22.80從通到不通的具體時間,就能知道這個時間puppet做了什麼動作,導致問題的發生。

 

在168.1.22.0/24網段的linux服務器,編寫一個帶時間的ping腳本,內容如下:

----------------------------------------------------

#!/bin/sh
ping 168.1.22.80| while read pong; do echo "$(date +%Y-%m-%d\ %H:%M:%S) $pong"; done>>/root/ping.log

----------------------------------------------------

重新在fuel推送,且在該服務器在後臺執行該腳本:

# nohup /root/ping.sh &

 

根據日誌發現vip__public失效的時間約是23:12:00

2015-12-25 23:11:58 64 bytes from 168.1.22.80: icmp_seq=2844 ttl=64 time=6.70 ms
2015-12-25 23:11:59 64 bytes from 168.1.22.80: icmp_seq=2845 ttl=64 time=1.15 ms
2015-12-25 23:12:00 64 bytes from 168.1.22.80: icmp_seq=2846 ttl=64 time=0.892 ms
2015-12-25 23:12:30 From 168.1.22.205 icmp_seq=2873 Destination Host Unreachable
2015-12-25 23:12:30 From 168.1.22.205 icmp_seq=2874 Destination Host Unreachable
2015-12-25 23:12:30 From 168.1.22.205 icmp_seq=2875 Destination Host Unreachable

 

在puppet的日誌中查看23:12:00發生的事情:

2015-12-25T23:12:00.766102+00:00 debug:  (Cs_rsc_location[loc_ping_vip__public](provider=crm)) {}
2015-12-25T23:12:00.768631+00:00 notice:  (/Stage[main]/Main/Cluster::Virtual_ip_ping[vip__public]/Cs_rsc_location[loc_ping_vip__public]/ensure) created
2015-12-25T23:12:00.775187+00:00 debug:  Executing ‘/usr/sbin/pcs property show dc-version‘
2015-12-25T23:12:03.157766+00:00 debug:  (Cs_rsc_location[loc_ping_vip__public](provider=crm)) Evaluating {:cib=>"ping_vip__public", :node_score=>nil, :primitive=>"vip__public", :name=>"loc_ping_vip__public", :rules=>[{:expressions=>[{:value=>"or", :operation=>"pingd", :attribute=>"not_defined"}, {:value=>"0", :operation=>"lte", :attribute=>"pingd"}], :boolean=>"", :score=>"-inf"}], :node_name=>nil, :ensure=>:present}
2015-12-25T23:12:03.157951+00:00 debug:  (Cs_rsc_location[loc_ping_vip__public](provider=crm)) creating location with command
2015-12-25T23:12:03.157951+00:00 debug:  (Cs_rsc_location[loc_ping_vip__public](provider=crm))  location loc_ping_vip__public vip__public rule -inf: not_defined pingd or pingd lte 0  
2015-12-25T23:12:03.157951+00:00 debug:  (Cs_rsc_location[loc_ping_vip__public](provider=crm)) trying to delete old shadow if exists
2015-12-25T23:12:03.157951+00:00 debug:  Executing ‘/usr/sbin/crm_shadow -b -f -D location_loc_ping_vip__public‘
2015-12-25T23:12:03.206974+00:00 debug:  (Cs_rsc_location[loc_ping_vip__public](provider=crm)) delete failed but proceeding anyway
2015-12-25T23:12:03.207226+00:00 debug:  Executing ‘/usr/sbin/crm_shadow -b -c location_loc_ping_vip__public‘
2015-12-25T23:12:04.355222+00:00 debug:  (Cs_rsc_location[loc_ping_vip__public](provider=crm)) no difference - nothing to apply
2015-12-25T23:12:04.355979+00:00 debug:  (/Stage[main]/Main/Cluster::Virtual_ip_ping[vip__public]/Cs_rsc_location[loc_ping_vip__public]) The container Cluster::Virtual_ip_ping[vip__public] will propagate my refresh event
2015-12-25T23:12:04.356660+00:00 info:  (/Stage[main]/Main/Cluster::Virtual_ip_ping[vip__public]/Cs_rsc_location[loc_ping_vip__public]) Evaluated in 6.21 seconds
2015-12-25T23:12:04.357718+00:00 info:  (/Stage[main]/Main/Cluster::Virtual_ip_ping[vip__public]/Service[ping_vip__public]) Starting to evaluate the resource
2015-12-25T23:12:04.358951+00:00 debug:  Waiting 600 seconds for Pacemaker to become online

 

由於當時對crm不是很瞭解,看不懂日誌到底做什麼了,只大概看懂了puppet對cib進行了一定的操作,看來需要繼續跟蹤cib的變化。

重新用fuel推送,在controller1,添加腳本不斷地導出cib.xml的內容:

------------------------------------------------------------------------

#!/bin/sh

STR_TIME=‘‘
STR_PATH=‘‘
STR_MD5_C=‘‘
STR_MD5=‘‘

mkdir -p /root/cib
while :
do
  STR_TIME=$(date +%Y%m%d%H%M%S)
  STR_PATH=/root/cib/cib_$STR_TIME.xml
  cibadmin --query>$STR_PATH
  STR_MD5_C=$(md5sum $STR_PATH|awk ‘{print $1}‘)
  if [ "$STR_MD5" != "$STR_MD5_C" ]; then
    STR_MD5=$STR_MD5_C
    mv $STR_PATH /root/cib/cib_$STR_TIME.${STR_MD5:0-4}
  else
    rm -f $STR_PATH
  fi
  sleep 1s
done

--------------------------------------------------------------------------

在controller1後臺執行該腳本:

# nohup /root/cib.sh &

 

從ping 168.1.22.80的腳本看出,出現問題的時間點大概是23:12:00,查看controller1的/root/cib目錄:

cib_20151225231150.1fbc
cib_20151225231201.b4f1
cib_20151225231203.09b2

 

cib_20151225231150.1fbc:
<cib crm_feature_set="3.0.9" validate-with="pacemaker-2.0" epoch="119" num_updates="3" admin_epoch="0" cib-last-written="Fri Dec 25 23:11:48 2015" have-quorum="1" dc-uuid="11">
 
cib_20151225231201.b4f1:
<cib crm_feature_set="3.0.9" validate-with="pacemaker-2.0" epoch="120" num_updates="0" admin_epoch="0" cib-last-written="Fri Dec 25 23:12:00 2015" have-quorum="1" dc-uuid="11">
 
 
兩個文件用Beybond Compare比較,發現第二個文件只多了:
    399       <rsc_location id="loc_ping_vip__public" rsc="vip__public">
    400         <rule score="-INFINITY" id="loc_ping_vip__public-rule" boolean-op="or">
    401           <expression operation="not_defined" id="loc_ping_vip__public-rule-expression" attribute="pingd"/>
    402           <expression value="0" operation="lte" id="loc_ping_vip__public-rule-expression-0" attribute="pingd"/>
    403         </rule>
    404       </rsc_location>

 

loc_ping_vip__public是cib.xml中約束部分(constraints)的內容,與我的猜想吻合。

導出錯誤發生後的約束部分內容:

# cibadmin --query --scope=constraints>/root/constraints.xml

 

編輯constraints.xml,刪除loc_ping_vip__public的定義,並保存到自己的電腦。

重新用fuel推送,在controller1,添加腳本等待cib.xml的內容中出現“loc_ping_vip__public”:

---------------------------------------------------------------------------

#!/bin/sh
r=1
while [ "$r" = 1 ]; do
  cibadmin --query --scope=constraints>/root/t.xml
  grep loc_ping_vip__public /root/t.xml
  r=$?
  sleep 1s
done
sleep 29s
cibadmin --replace --scope=constraints --xml-file /root/constraints.xml

---------------------------------------------------------------------------

推送成功。

 

推送成功,是相當於手動修改了puppet推出的內容,在網絡上沒有找到別人有相同的問題,且通過修改puppet的方法解決這個問題,這問題應該不是一個bug。需要理解loc_ping_vip__public定義的內容到底是什麼意思。

經過下列連接的學習:

http://clusterlabs.org/doc/en-US/Pacemaker/1.1/html-single/Pacemaker_Explained/#_scores

http://clusterlabs.org/doc/en-US/Pacemaker/1.1/html-single/Pacemaker_Explained/#_rule_properties

http://clusterlabs.org/doc/en-US/Pacemaker/1.1/html/Pacemaker_Explained/_moving_resources_due_to_connectivity_changes.html

http://clusterlabs.org/doc/en-US/Pacemaker/1.1/html/Pacemaker_Explained/_tell_pacemaker_how_to_interpret_the_connectivity_data.html

明白了loc_ping_vip__public定義的內容到底是什麼意思:

    399       <rsc_location id="loc_ping_vip__public" rsc="vip__public">
    400         <rule score="-INFINITY" id="loc_ping_vip__public-rule" boolean-op="or">
    401           <expression operation="not_defined" id="loc_ping_vip__public-rule-expression" attribute="pingd"/>
    402           <expression value="0" operation="lte" id="loc_ping_vip__public-rule-expression-0" attribute="pingd"/>
    403         </rule>
    404       </rsc_location>

rsc="vip__public"指約束的對象是vip__public資源;

boolean-op="or"指每條表達式(<expression... />)的布爾值進行“或”運算;

rule score="-INFINITY"指最終結果如果是“True”(此處則爲或運算的結果),則被約束的對象不能啓動;

表達式 1:<expression ... not_defined ... />,此條表達式檢查資源中是否缺少定義了屬性爲“pingd”的資源,結果爲假,因爲是屬性爲“pingd”的資源:

      <clone id="clone_ping_vip__public">
        <primitive class="ocf" type="ping" id="ping_vip__public" provider="pacemaker">
          <operations>
            <op timeout="30" name="monitor" interval="20" id="ping_vip__public-monitor-20"/>
          </operations>
          <instance_attributes id="ping_vip__public-instance_attributes">
            <nvpair value="3s" name="timeout" id="ping_vip__public-instance_attributes-timeout"/>
            <nvpair value="30s" name="dampen" id="ping_vip__public-instance_attributes-dampen"/>
            <nvpair value="1000" name="multiplier" id="ping_vip__public-instance_attributes-multiplier"/>
            <nvpair value="168.1.22.1" name="host_list" id="ping_vip__public-instance_attributes-host_list"/>
          </instance_attributes>
        </primitive>
      </clone>

表達式2:<expression ... value="0" operation="lte" ... />,此條表達式檢查屬性爲“pingd”的資源。屬性爲“pingd”的資源是用來檢查某個IP能不能ping通的,能ping通返回0。這裏lte 0表示返回值不爲0時,表達式返回真。從ping_vip__public的資源定義看出,它ping的是168.1.22.1,是我環境中的網關,我環境中其實是沒有網關的,所以ping不通,所以此條表達式的最終結果是真,或運算後是真,則被約束對象不能啓動。

綜上,約束定義loc_ping_vip__public是用來測試網關能不能通的,只有網關能通的節點才能啓動vip__public,難怪刪除loc_ping_vip__public後推送是成功的,也難怪網絡上沒人遇到我這個問題,因爲他們的網絡環境網關是能通的!

在網絡上找到了相同問題:

http://irclog.perlgeek.de/fuel-dev/2015-01-28

 

PS:再解釋一下什麼是“屬性爲pingd的資源”,就是類型是“ocf:pacemaker:ping”的資源,請用命令“crm configure show”查看,一般集羣中至少要有一個這種類型的資源。

 

用fuel重推了好幾次才排查出問題,且最後排查出的問題竟然是網關ping不通。。。

發佈了91 篇原創文章 · 獲贊 37 · 訪問量 43萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章