透過 SOAP API 管理 Citrix 負載平衡器,可以實作自動化監控和管理,提高效率並減少人工干預。本文首先介紹了登入機制,說明如何使用 Cookie 維護 Session。接著,文章詳細說明瞭如何使用 statsystemstatprotocolhttp 方法取得系統的 CPU、記憶體使用率以及 HTTP 請求速率等關鍵效能指標。此外,文章也示範瞭如何使用 statlbvserverstatservice 方法查詢虛擬伺服器和服務的狀態,以及如何透過 getlbvserver 方法取得虛擬伺服器上的服務列表。最後,文章提供 Python 程式碼範例,展示如何封裝這些 SOAP API,簡化管理任務,例如取得虛擬伺服器列表、服務詳細資訊以及健康狀態檢查等。

使用SOAP API管理裝置

登入後的Session維護機制

成功登入網頁服務後,您可能會好奇後續的請求是如何被授權的。有些網頁服務會傳回一個特殊的token,這個token是在伺服器上生成的,並與使用API的帳戶相關聯。如果是這樣的話,我們就需要將這個token包含在每次傳送給網頁服務的請求中。

然而,Netscaler負載平衡器的處理方式更為簡單。在我們傳送登入請求後,如果認證資訊正確,負載平衡器會回應一個簡單的「OK」訊息。同時,它也會在HTTP標頭中回應一個特殊的cookie,這個cookie就扮演著token的角色。我們不需要將token的詳細資訊包含在每個SOAP請求中,只需要確保在傳送後續請求時,HTTP標頭中設定了這個cookie即可。

HTTP封裝的SOAP登入請求與回應訊息範例

POST /soap/ HTTP/1.1
Host: 192.168.1.1
Accept-Encoding: identity
Content-Length: 540
Content-Type: text/xml; charset=utf-8
SOAPAction: "urn:NSConfigAction"

<SOAP-ENV:Envelope xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" 
                   xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
                   xmlns:ZSI="http://www.zolera.com/schemas/ZSI/" 
                   xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                   SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <SOAP-ENV:Header></SOAP-ENV:Header>
    <SOAP-ENV:Body xmlns:ns1="urn:NSConfig">
        <ns1:login>
            <username>nstest</username>
            <password>nstest</password>
        </ns1:login>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

HTTP/1.1 200 OK
Date: Mon, 29 Jun 2009 11:13:08 GMT
Server: Apache
Last-Modified: Mon, 29 Jun 2009 11:13:08 GMT
Status: 200 OK
Content-Length: 622
Connection: close
Set-Cookie: NSAPI=##F0F402A6574084DB4956184C6443FEE54DD5FC1E1953E3730A5A307BBEC3; Domain=192.168.1.1; Path=/soap
Content-Type: text/xml; charset=utf-8

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
                   xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" 
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                   xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
                   xmlns:ns="urn:NSConfig">
    <SOAP-ENV:Header></SOAP-ENV:Header>
    <SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" id="_0">
        <ns:loginResponse>
            <return xsi:type="ns:simpleResult">
                <rc xsi:type="xsd:unsignedInt">0</rc>
                <message xsi:type="xsd:string">Done</message>
            </return>
        </ns:loginResponse>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

內容解密:

這個範例展示了登入請求和回應的詳細過程。初始請求中,我們發送了一個包含認證資訊的SOAP訊息。回應中,SOAP訊息本身只包含了兩個資料:一個數字回傳碼(rc)和一個文字訊息(message)。當一切正常時,rc被設為0,message被設為「Done」。更重要的是,HTTP標頭中設定了一個cookie(NSAPI),這個cookie的值與我們的帳戶相關聯,確保後續請求的安全性。

蒐集效能統計資料

我們已經確定了統計資料蒐集和監控工具的需求:

  • CPU和記憶體使用率
  • 系統概覽:請求速率、資料速率、已建立的連線數
  • 所有虛擬伺服器的概覽:上線/下線狀態以及每個虛擬伺服器中哪些服務是下線的

這些需求可以分為兩組:

  • 系統狀態(CPU、記憶體和請求速率讀數)
  • 虛擬伺服器狀態(虛擬伺服器狀態)

用於讀取統計資料的SOAP方法及其回傳值

方法回傳變數描述
statsystem_internaltemp系統內部溫度(攝氏)
_rescpuusage綜合CPU使用率(百分比)
_memusagepcnt記憶體使用率(百分比)
statprotocolhttp_httprequestsrate總HTTP(S)請求速率(每秒)
statlbvserver_primaryipaddress虛擬伺服器的IP地址
_primaryport虛擬伺服器的埠號
_state虛擬伺服器的狀態:UP(運作中)、DOWN(所有服務失敗)、OUT OF SERVICE(已停用)
_vslbhealth虛擬伺服器的健康狀態,以UP狀態的服務百分比表示
_requestsrate虛擬伺服器接收的每秒請求速率
statservice_primaryipaddress虛擬伺服器的IP地址
_primaryport虛擬伺服器的埠號
_state虛擬伺服器的狀態:UP(運作中)、DOWN(未運作)、OUT OF SERVICE(已停用)
_requestsrate服務接收的每秒請求速率

內容解密:

這個表格列出了用於統計資料蒐集工具的SOAP方法及其回傳值。這些方法可以用來查詢系統和虛擬伺服器的各種統計資料。開發者可以根據需要修改程式碼,加入更多的查詢專案。同時,也可以參考Netscaler API檔案,瞭解更多特定專案的詳細資訊。

管理裝置使用 SOAP API

讀取系統健康資料

讀取系統狀態資料相對簡單;我們只需要呼叫兩個方法:一個用於檢索有關硬體和記憶體狀態的讀數,另一個用於檢查負載平衡器所服務的總 HTTP 和 HTTPS 請求。

從表 2-1 中我們可以看到,我們將呼叫 statsystemstatprotocolhttp 方法。這兩個方法都不需要任何輸入引數。清單 2-19 顯示了我們的 NSStatApi 類別中統計資訊收集方法的簡化版本。

清單 2-19. 取得系統健康資料

def system_health_check(self):
    results = {}
    [...]
    req = self.module.statsystem()
    res = self.soap.statsystem(req)._return
    results['temp'] = res._List[0]._internaltemp
    results['cpu'] = res._List[0]._rescpuusage
    results['mem'] = res._List[0]._memusagepcnt
    [...]
    req = self.module.statprotocolhttp()
    res = self.soap.statprotocolhttp(req)._return
    results['http_req_rate'] = res._List[0]._httprequestsrate
    [...]
    return results

這與我們之前執行的登入請求類別似;然而,有一個重要的區別需要注意。這次我們需要使用 _List 變數來存取我們感興趣的詳細資訊。原因是所有的回應 _return 物件都包含兩個必需和一個可選變數:_rc_message_List。我們已經知道 _rc_message 包含請求傳回程式碼和提供更多有關請求狀態的詳細資訊的訊息。

然而,_List 是可選的,是一個陣列,可能包含一個或多個 Return 物件的例項。即使該方法總是傳回單一例項,它仍然包含在陣列中。這是提供標準通訊方式的方法之一:每個請求總是傳回相同的變數集,因此如果需要,我們可以編寫標準的 SOAP 請求分派器/回應處理器。

內容解密:

  1. statsystem 方法用於取得系統的健康狀態,包括內部溫度、CPU 使用率和記憶體使用率等。
  2. statprotocolhttp 方法用於取得 HTTP 請求的統計資訊,包括 HTTP 請求率。
  3. _List 變數是一個陣列,用於儲存傳回的資料,即使只有一個例項。

如何找到傳回的 Structure 物件

要找出列表中傳回的 Structure 物件,我們需要檢視 NSStat_services_types.py 模組中包含的所有 SOAP 通訊中使用的資料型別。在我們的例子中,我們正在搜尋 statsystemResult_Def 類別。

一旦找到它,我們就需要尋找類別似於以下的 Type 定義:

TClist = [ZSI.TCnumbers.IunsignedInt(pname="rc", aname="_rc", minOccurs=1, maxOccurs=1, nillable=False, typed=False, encoded=kw.get("encoded")),
          ZSI.TC.String(pname="message", aname="_message", minOccurs=1, maxOccurs=1, nillable=False, typed=False, encoded=kw.get("encoded")),
          GTD("urn:NSConfig","systemstatsList",lazy=False)(pname="List", aname="_List", minOccurs=0, maxOccurs=1, nillable=False, typed=False, encoded=kw.get("encoded"))]

內容解密:

  1. TClist 定義了傳回物件的結構,包括 _rc_message_List
  2. _List 的型別是 systemstatsList,這是一個複雜型別。

讀取服務狀態資料

檢索有關服務的資訊非常相似;它只是涉及更多的步驟:

  1. 我們需要檢索 Netscaler 上所有虛擬伺服器的列表。這可以透過 statlbvserver 方法實作,該方法接受一個可選的名稱引數。如果指定了該名稱,則只會傳回有關該虛擬伺服器的資訊。如果未指定名稱或為空白,則會傳回有關所有虛擬伺服器的資訊。
  2. 對於列表中的每個虛擬伺服器,我們建立一個附加到它的服務列表。這實際上需要使用不同的 SOAP 服務——Netscaler 組態 SOAP。統計 API 不提供查詢組態實體之間的依賴關係的功能,因此我們將使用組態 API 中的 getlbvserver 方法。
  3. 我們檢查虛擬伺服器的健康評分是否不是 100%。如果伺服器不在忽略列表中,我們列出附加到它的不健康服務。我們使用 statservice 方法檢索有關每個服務的統計資訊,如果服務不在 UP 狀態,則指示該情況。

內容解密:

  1. statlbvserver 方法用於取得虛擬伺服器的列表。
  2. getlbvserver 方法用於取得虛擬伺服器上的服務列表。
  3. statservice 方法用於取得每個服務的統計資訊,並檢查其健康狀態。

管理裝置使用 SOAP API

健康狀態與服務統計收集

在 Citrix 負載平衡器中,虛擬伺服器的健康狀態是根據其服務池中活躍服務的百分比來計算的。如果一個虛擬伺服器有十個服務,其中兩個沒有回應健康檢查,那麼該虛擬伺服器的健康狀態分數就是 80%。

統計 API 包裝類別實作

class NSStatApi(NSSoapApi):
    def get_vservers_list(self, name=''):
        result = {}
        req = self.module.statlbvserver()
        req._name = name
        res = self.soap.statlbvserver(req)._return
        for e in res._List:
            result[e._name.strip('"')] = {
                'ip': e._primaryipaddress,
                'port': e._primaryport,
                'status': e._state,
                'health': e._vslbhealth,
                'requestsrate': e._requestsrate,
            }
        return result

    def get_service_details(self, service):
        result = {}
        req = self.module.statservice()
        req._name = service
        res = self.soap.statservice(req)._return
        result = {
            'ip': res._List[0]._primaryipaddress,
            'port': res._List[0]._primaryport,
            'status': res._List[0]._state,
            'requestsrate': res._List[0]._requestsrate,
        }
        return result

內容解密:

  1. NSStatApi 類別繼承自 NSSoapApi,並實作了兩個方法:get_vservers_listget_service_details
  2. get_vservers_list 方法呼叫 statlbvserver SOAP 方法,並傳遞一個可選的名稱引數。如果名稱字串為空,則傳回所有虛擬伺服器的列表。
  3. 傳回的列表經過處理,形成一個字典,包含虛擬伺服器的名稱、IP、埠、狀態、健康狀態和請求率等資訊。
  4. get_service_details 方法呼叫 statservice SOAP 方法,並傳遞服務名稱作為引數,傳回該服務的詳細資訊。

組態 API 包裝類別實作

class NSConfigApi(NSSoapApi):
    def get_services_list(self, vserver):
        req = self.module.getlbvserver()
        req._name = vserver
        res = self.soap.getlbvserver(req)._return
        result = [e.strip('"') for e in res._List[0]._servicename]
        return result

內容解密:

  1. NSConfigApi 類別繼承自 NSSoapApi,並實作了 get_services_list 方法。
  2. 該方法呼叫 getlbvserver SOAP 方法,並傳遞虛擬伺服器名稱作為引數。
  3. 傳回與該虛擬伺服器繫結的服務列表。

檢索服務狀態資料

ns = NSStatApi([...])
ns_c = NSConfigApi([...])
for (vs, data) in ns.get_vservers_list(name=OPTS.vserver_query).iteritems():
    if (data['status'] != 'UP' or data['health'] != 100) and vs not in config.netscalers['primary']['vserver_ignore_list'] or OPTS.verbose:
        print("SERVICE: %s (%s:%s)" % (vs, data['ip'], data['port']))
        print("LOAD: %s req/s" % data['requestsrate'])
        print("HEALTH: %s%%" % data['health'])
        for srv in sorted(ns_c.get_services_list(vs)):
            service = ns.get_service_details(srv)
            if service['status'] != 'UP' or OPTS.vserver_query or OPTS.verbose:
                print(' * %s (%s:%s) - %s (%s req/sec)' % (srv, service['ip'], service['port'], service['status'], service['requestsrate']))

內容解密:

  1. 初始化 NSStatApiNSConfigApi 例項。
  2. 檢索所有虛擬伺服器的列表,並遍歷它們。
  3. 如果虛擬伺服器的健康狀態不是 100%,則取得與其繫結的服務列表。
  4. 列印出不健康的服務及其詳細資訊。

自動化管理任務

裝置組態 SOAP 方法

組態 API 提供了超過 2,500 種不同的方法來更改負載平衡器的組態。組態負載平衡器通常是一項複雜的任務,遠遠超出了本文的範圍。在本文中,將展示如何取得服務列表以及如何啟用和停用它們。