使用可觀測(cè)鏈路OpenTelemetry版實(shí)現(xiàn)網(wǎng)格內(nèi)外應(yīng)用的一體化追蹤
ASM可以便捷地為部署在網(wǎng)格內(nèi)的應(yīng)用提供鏈路追蹤能力,但要實(shí)現(xiàn)網(wǎng)格內(nèi)和網(wǎng)格外應(yīng)用的一體化追蹤,需要使用可觀測(cè)鏈路OpenTelemetry版以形成調(diào)用鏈。本文介紹如何通過(guò)阿里云可觀測(cè)鏈路OpenTelemetry版,使網(wǎng)格外部應(yīng)用調(diào)用網(wǎng)格內(nèi)部應(yīng)用并形成一個(gè)完整的鏈路追蹤信息。
前提條件
已創(chuàng)建一個(gè)ASM實(shí)例,并已將ACK集群添加到ASM實(shí)例中。具體操作,請(qǐng)參見(jiàn)創(chuàng)建ASM實(shí)例和添加集群到ASM實(shí)例。
ASM實(shí)例已部署入口網(wǎng)關(guān),便于訪問(wèn)網(wǎng)格內(nèi)應(yīng)用。具體操作,請(qǐng)參見(jiàn)創(chuàng)建入口網(wǎng)關(guān)。
已準(zhǔn)備一個(gè)用于運(yùn)行網(wǎng)格外示例應(yīng)用的環(huán)境,并安裝Python 2.7。
已啟用阿里云可觀測(cè)鏈路OpenTelemetry版。具體操作,請(qǐng)參見(jiàn)將鏈路追蹤數(shù)據(jù)采集到阿里云可觀測(cè)鏈路OpenTelemetry版。
使用說(shuō)明
本示例將部署一個(gè)用Python編寫(xiě)的應(yīng)用ExternalProxy。該應(yīng)用會(huì)啟用一個(gè)HTTP Server,當(dāng)ExternalProxy的根路徑被訪問(wèn)時(shí),會(huì)調(diào)用網(wǎng)格內(nèi)應(yīng)用BookInfo的Productpage應(yīng)用。
本示例將使用XTrace為追蹤系統(tǒng)進(jìn)行演示。若您使用自行部署的Zipkin兼容的追蹤系統(tǒng),可以將該系統(tǒng)上報(bào)地址暴露于網(wǎng)格外應(yīng)用可以訪問(wèn)的地址,可以跳過(guò)步驟二:獲取可觀測(cè)鏈路OpenTelemetry版的接入點(diǎn)地址,直接參照步驟三:部署網(wǎng)格外應(yīng)用ExternalProxy使用該地址作為上報(bào)地址即可。
步驟一:部署網(wǎng)格內(nèi)應(yīng)用BookInfo
執(zhí)行以下命令,將Bookinfo應(yīng)用部署到ASM實(shí)例的集群中。
BookInfo應(yīng)用的YAML文件,請(qǐng)從GitHub下載。
kubectl --kubeconfig=${DATA_PLANE_KUBECONFIG} apply -f bookinfo.yaml
執(zhí)行以下命令,部署B(yǎng)ookinfo應(yīng)用的VirtualService。
VirtualService的YAML文件,請(qǐng)從GitHub下載。
kubectl --kubeconfig=${ASM_KUBECONFIG} apply -f virtual-service-all-v1.yaml
執(zhí)行以下命令,部署B(yǎng)ookinfo應(yīng)用的DestinationRule。
DestinationRule的YAML文件,請(qǐng)從Github下載。
kubectl --kubeconfig=${ASM_KUBECONFIG} apply -f destination-rule-all.yaml
執(zhí)行以下命令,部署B(yǎng)ookinfo應(yīng)用的Gateway。
Gateway的YAML文件,請(qǐng)從GitHub下載。
kubectl --kubeconfig=${ASM_KUBECONFIG} apply -f bookinfo-gateway.yaml
步驟二:獲取可觀測(cè)鏈路OpenTelemetry版的接入點(diǎn)地址
登錄可觀測(cè)鏈路OpenTelemetry版,在左側(cè)導(dǎo)航欄,單擊概覽。
在概覽頁(yè)面,單擊接入流程頁(yè)簽,然后單擊查看接入點(diǎn)信息。
查看接入點(diǎn)地址。
在頁(yè)面上方,選擇目標(biāo)地域。
請(qǐng)選擇BookInfo應(yīng)用部署的ACK集群所在地域來(lái)上報(bào)數(shù)據(jù),否則追蹤信息無(wú)法關(guān)聯(lián)。
在接入點(diǎn)信息頁(yè)簽,打開(kāi)顯示Token開(kāi)關(guān),并根據(jù)您的ExternalProxy部署位置決定選擇公網(wǎng)或私網(wǎng)接入點(diǎn)地址。
因?yàn)镋xternalProxy通過(guò)Zipkin V1 API進(jìn)行數(shù)據(jù)上報(bào),因此選用V1版本的接入點(diǎn)地址。
步驟三:部署網(wǎng)格外應(yīng)用ExternalProxy
Sidecar代理會(huì)將接收到的請(qǐng)求中的所有內(nèi)容(包括HTTP頭部、請(qǐng)求體等)轉(zhuǎn)發(fā)給上游服務(wù),因此鏈路追蹤相關(guān)的Header也會(huì)被轉(zhuǎn)發(fā)至上游。
為了完成鏈路追蹤信息的透?jìng)鳎瑧?yīng)用需要按照社區(qū)規(guī)范將鏈路追蹤相關(guān)的請(qǐng)求Header透?jìng)髦辽嫌蔚恼?qǐng)求。
將下面的代碼保存至網(wǎng)格外應(yīng)用運(yùn)行環(huán)境,命名為ExternalProxy.py。
將
{XTRACE_ZIPKIN_V1_ENDPOINT}
替換為上一步獲取到的接入點(diǎn)地址。如果您希望上報(bào)于自行部署的追蹤系統(tǒng),這里請(qǐng)?zhí)鎿Q為其上報(bào)地址。將
{INGRESS_GATE_WAY_IP}
替換為ACK集群Ingress Gateway的地址。import requests from flask import Flask from py_zipkin.zipkin import zipkin_span,create_http_headers_for_new_span from py_zipkin.util import generate_random_64bit_string from py_zipkin.util import ZipkinAttrs import time app = Flask(__name__) def do_stuff(trace_id, span_id, parent_span_id): time.sleep(2) headers = create_http_headers_for_new_span() headers["X-B3-TraceId"] = trace_id headers["X-B3-SpanId"] = span_id headers["X-B3-ParentSpanId"] = parent_span_id print "SEND TO INGRESS HEADERS : {0}".format(headers) r = requests.get('http://${INGRESS_GATE_WAY_IP}/productpage', headers=headers) return 'OK' def http_transport(encoded_span): # encoding prefix explained in https://github.com/Yelp/py_zipkin#transport body=encoded_span zipkin_url="${XTRACE_ZIPKIN_V1_ENDPOINT}" headers = {"Content-Type": "application/x-thrift"} # You'd probably want to wrap this in a try/except in case POSTing fails r=requests.post(zipkin_url, data=body, headers=headers) print(body) @app.route('/') def index(): with zipkin_span( service_name='external-proxy', span_name='external-proxy/inbound', transport_handler=http_transport, port=5000, sample_rate=100, ) as inbound_span: do_stuff(inbound_span.zipkin_attrs.trace_id, inbound_span.zipkin_attrs.span_id, inbound_span.zipkin_attrs.parent_span_id) return 'OK', 200 if __name__=='__main__': app.run(host="0.0.0.0",port=5000,debug=True)
執(zhí)行下面的命令,啟動(dòng)ExternalProxy。
python ExternalProxy.py
* Serving Flask app "main" (lazy loading) * Environment: production WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Debug mode: on * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit) * Restarting with stat * Debugger is active! * Debugger PIN: 317-792-686
執(zhí)行以下命令,調(diào)用ExternalProxy。
curl localhost:5000
預(yù)期輸出:
OK
步驟四:查看鏈路追蹤信息
在左側(cè)導(dǎo)航欄,單擊應(yīng)用列表,然后在上方選擇地域,單擊下方列表中的ExternalProxy。
在左側(cè)導(dǎo)航欄,單擊應(yīng)用詳情,單擊調(diào)用鏈路頁(yè)簽,單擊相應(yīng)的traceId查看鏈路追蹤信息。
可以看到,網(wǎng)格外部應(yīng)用ExternalProxy與內(nèi)部應(yīng)用BookInfo之間已形成完整的調(diào)用鏈路。