Cách thực hiện theo dõi phân tán với Jaeger trên Kubernetes
Kubernetes và các kiến trúc microservice mà nó cho phép có thể tạo ra các hệ thống rất hiệu quả và có thể mở rộng. Nhưng vấn đề nảy sinh khi một trong những dịch vụ nhỏ này phát triển các vấn đề về hiệu suất. Thông thường, trước tiên, ta nhận thấy rằng thời gian phản hồi từ các dịch vụ dành cho khách hàng của ta ngày càng dài hơn. Vấn đề có thể là với một trong các dịch vụ backend , hoặc có thể là một database vượt quá khả năng tối ưu của nó. Để phát hiện ra root rễ của vấn đề, ta cần triển khai theo dõi phân tán .Jaeger là một giải pháp theo dõi phân tán và đã tốt nghiệp Dự án ươm tạo của Tổ chức Máy tính Bản địa Đám mây . Nó có giao diện user dễ chịu để hiển thị các dấu vết, các thanh trợ giúp Jaeger để thu thập dấu vết và một số thành phần khác. Các hệ thống theo dõi phân tán như Jaeger cho phép ta theo dõi vòng đời của từng sự kiện do khách hàng tạo và xem từng dịch vụ xử lý sự kiện đó như thế nào.
Trong hướng dẫn này, ta sẽ triển khai một ứng dụng phân tán rất nhỏ đến một cụm Kubernetes và mô phỏng độ trễ hiệu suất bằng cách sử dụng hàm ngủ trong mã của ta . Để tìm ra nguyên nhân root rễ của vấn đề này và theo dõi từng sự kiện, ta sẽ sử dụng Jaeger . Khi đã bật tính năng theo dõi, ta sẽ thấy hiệu quả của việc quan sát hành vi của Dịch vụ và xác định các vấn đề.
Yêu cầu
Trước khi bắt đầu, bạn cần các công cụ và account sau:
-  Một cụm Kubernetes 1.15+ với cấu hình kết nối của bạn được đặt làm mặc định kubectl. Để tạo một cụm Kubernetes trên DigitalOcean, hãy đọc Phần khởi động nhanh Kubernetes của ta . Để kết nối với cụm, hãy đọc Cách kết nối với một cụm DigitalOcean Kubernetes .
- Docker đã được cài đặt. Làm theo hướng dẫn của ta vềCách cài đặt và sử dụng Docker để được hướng dẫn. Trang web của Docker cung cấp hướng dẫn cài đặt cho các hệ điều hành khác như macOS và Windows.
- Một account tại Docker Hub để lưu trữ Docker image của bạn.
-  Công cụ dòng lệnh kubectlđược cài đặt trên máy local của bạn và được cấu hình để kết nối với cụm của bạn. Bạn có thể đọc thêm về cách cài đặtkubectltrong tài liệu chính thức hoặc làm theo hướng dẫn này để bắt đầu với Kubernetes: AkubectlCheat Sheet .
-  Tiện ích dòng lệnh curlđược cài đặt trên máy local của bạn. Bạn có thể cài đặtcurlbằng trình quản lý gói được tích hợp trong hệ điều hành của bạn .
Bước 1 - Xây dựng ứng dụng mẫu
 Để kiểm tra khả năng truy tìm của Jaeger,  ta  sẽ xây dựng và triển khai một ứng dụng mẫu, sammy-jaeger , sử dụng hai dịch vụ: một cho frontend và một cho backend.  Ta  sẽ xây dựng cả bằng Python và vi khung Flask .
 Ứng dụng của  ta  sẽ là một bộ đếm lượt truy cập có giá trị tăng lên mỗi khi  ta  gọi giao diện  user . Để mô phỏng các vấn đề về hiệu suất,  ta  sẽ viết mã một hàm sleep ngẫu nhiên thực thi  khi  nào giao diện  user  gửi yêu cầu GET tới phần  backend . Ở bước này,  ta  sẽ xây dựng và triển khai ứng dụng đó. Trong các bước sau,  ta  sẽ triển khai ứng dụng tới Kubernetes, cài đặt Jaeger và sau đó sử dụng nó để theo dõi sự cố dịch vụ của  ta .
Đầu tiên, hãy tạo cấu trúc folder dự án và chuyển bên trong:
- mkdir -p ./sammy-jaeger/frontend ./sammy-jaeger/backend && cd ./sammy-jaeger 
Bây giờ  ta  có một folder  root , sammy-jaeger và hai folder  con:
output. ├── backend └── frontend  Ta  cũng đã thay đổi thành folder  root , /sammy-jaeger .  Ta  sẽ chạy tất cả các lệnh còn lại từ đây.
Hãy bắt đầu xây dựng ứng dụng giao diện user .
Xây dựng ứng dụng giao diện user
 Sử dụng editor   bạn muốn , tạo và mở một file  mới có tên frontend.py trong ./frontend :
nano ./frontend/frontend.py Thêm mã sau. Thao tác này sẽ nhập Flask, xây dựng các chức năng bộ đếm của ta và xác định một tuyến cho các yêu cầu HTTP:
import os import requests from flask import Flask app = Flask(__name__)  def get_counter(counter_endpoint):     counter_response = requests.get(counter_endpoint)     return counter_response.text  def increase_counter(counter_endpoint):     counter_response = requests.post(counter_endpoint)     return counter_response.text  @app.route('/') def hello_world():     counter_service = os.environ.get('COUNTER_ENDPOINT', default="https://localhost:5000")     counter_endpoint = f'{counter_service}/api/counter'     counter = get_counter(counter_endpoint)      increase_counter(counter_endpoint)      return f"""Hello, World!  You're visitor number {counter} in here!\n\n"""  Ta  đang nhập ba module . Mô-đun os sẽ giao tiếp với hệ điều hành của  ta . Mô-đun requests là một thư viện để gửi các yêu cầu HTTP. Flask là một microframework sẽ lưu trữ ứng dụng của  ta .
 Sau đó  ta  được xác định của  ta  get_counter() và increase_counter() chức năng, mà cả hai chấp nhận các tham số counter_endpoint . get_counter() sẽ gọi chương trình  backend  bằng phương thức GET để tìm trạng thái bộ đếm hiện tại. increase_counter() sẽ gọi chương trình  backend  với phương thức POST để tăng bộ đếm.
 Sau đó,  ta  xác định tuyến đường của  ta  / , nó sẽ gọi một hàm khác có tên hello_world() . Hàm này sẽ truy xuất một URL và một cổng cho  group   backend  của  ta , gán nó cho một biến, sau đó chuyển biến đó cho hai hàm đầu tiên của  ta , get_counter() và get_counter() increase_counter() , sẽ gửi các yêu cầu GET và POST đến phần  backend  . Sau đó, chương trình  backend  sẽ tạm dừng trong một khoảng thời gian ngẫu nhiên (độ trễ mô phỏng của  ta ) trước khi tăng số bộ đếm hiện tại và sau đó trả lại số đó. Cuối cùng, hello_world() sẽ lấy giá trị này và in ra "Hello World!" chuỗi vào console  của  ta  bao gồm số lượng khách truy cập mới của  ta .
 Bạn có thể nhận thấy rằng  ta  không tạo môi trường Python, cũng như không cài đặt pip trên máy local   của bạn .  Ta  sẽ hoàn thành các bước này khi  ta  chứa ứng dụng  của bạn  bằng Docker.
 Lưu và đóng frontend.py .
Bây giờ ta sẽ xây dựng một Dockerfile cho ứng dụng frontend. Dockerfile này sẽ bao gồm tất cả các lệnh cần thiết để xây dựng môi trường được chứa trong containers của ta .
 Tạo và mở một Dockerfile mới trong ./frontend :
- nano ./frontend/Dockerfile 
Thêm nội dung sau:
FROM alpine:3.8  RUN apk add --no-cache py3-pip python3 && \     pip3 install flask requests  COPY . /usr/src/frontend  ENV FLASK_APP frontend.py  WORKDIR /usr/src/frontend  CMD flask run --host=0.0.0.0 --port=8000 Trong Dockerfile này,  ta  hướng dẫn hình ảnh của  ta  xây dựng từ hình ảnh cơ sở của Alpine Linux . Sau đó,  ta  cài đặt Python3, pip và một số phụ thuộc bổ sung. Tiếp theo,  ta  sao chép mã nguồn ứng dụng, đặt một biến môi trường trỏ đến mã ứng dụng chính, đặt folder  làm việc và viết lệnh chạy Flask  khi  nào  ta  tạo containers  từ hình ảnh.
Lưu và đóng file .
Bây giờ, hãy xây dựng Docker image cho ứng dụng giao diện user của ta và đẩy nó vào repository trong Docker Hub.
Trước tiên, hãy kiểm tra xem bạn đã đăng nhập vào Docker Hub chưa:
- docker login --username=your_username --password=your_password 
Xây dựng hình ảnh:
- docker build -t your_username/do-visit-counter-frontend:v1 ./frontend 
Bây giờ đẩy hình ảnh vào Docker Hub:
- docker push your_username/do-visit-counter-frontend:v1 
Ứng dụng giao diện user của ta hiện đã được xây dựng và có sẵn trong Docker Hub. Tuy nhiên, trước khi ta triển khai nó cho Kubernetes, hãy viết mã và xây dựng ứng dụng backend của ta .
Xây dựng ứng dụng backend
Ứng dụng backend yêu cầu các bước tương tự như giao diện user .
 Đầu tiên, tạo và mở một file  có tên backend.py trong ./backend :
- nano ./backend/backend.py 
Thêm nội dung sau, sẽ xác định hai chức năng và một tuyến đường khác:
from random import randint from time import sleep  from flask import request from flask import Flask app = Flask(__name__)  counter_value = 1  def get_counter():     return str(counter_value)  def increase_counter():     global counter_value     int(counter_value)     sleep(randint(1,10))     counter_value += 1     return str(counter_value)  @app.route('/api/counter', methods=['GET', 'POST']) def counter():     if request.method == 'GET':         return get_counter()     elif request.method == 'POST':         return increase_counter()  Ta  đang nhập một số module , bao gồm random và sleep . Sau đó,  ta  đang đặt giá trị bộ đếm của  ta  thành 1 và xác định hai chức năng. Đầu tiên, get_counter , trả về giá trị bộ đếm hiện tại, được lưu trữ dưới dạng counter_value . Hàm thứ hai, increase_counter , thực hiện hai hành động. Nó tăng giá trị bộ đếm của  ta  lên 1 và nó sử dụng module  sleep để trì hoãn việc hoàn thành chức năng trong một khoảng thời gian ngẫu nhiên.
 Phần  backend  cũng có một tuyến đường ( /api/counter ) chấp nhận hai phương thức: POST và GET .
 Khi  ta  gọi tuyến này bằng phương thức GET , nó gọi get_counter() và trả về giá trị bộ đếm của  ta . Khi  ta  gọi tuyến này bằng phương thức POST , nó sẽ gọi hàm increase_counter() và tăng giá trị của bộ đếm trong khi chờ một khoảng thời gian ngẫu nhiên.
Lưu và đóng file .
 Ứng dụng  backend  của  ta  cũng sẽ yêu cầu Dockerfile của riêng nó, Dockerfile này gần giống với version  của giao diện  user .
 Tạo và mở Dockerfile thứ hai trong ./backend :
- nano ./backend/Dockerfile 
Thêm nội dung sau. Một điểm khác biệt chính ở đây, ngoài đường dẫn file , sẽ là cổng:
FROM alpine:3.8  RUN apk add --no-cache py3-pip python3 && \     pip3 install flask  COPY . /usr/src/backend  ENV FLASK_APP backend.py  WORKDIR /usr/src/backend  CMD flask run --host=0.0.0.0 --port=5000 Lưu và đóng file .
Bây giờ xây dựng hình ảnh:
- docker build -t your_username/do-visit-counter-backend:v1 ./backend 
Đẩy nó vào Docker Hub:
- docker push your_username/do-visit-counter-backend:v1 
Với ứng dụng của ta có sẵn trên Docker Hub, ta hiện đã sẵn sàng triển khai ứng dụng đó cho cụm của ta và kiểm tra nó trong bước tiếp theo.
Bước 2 - Triển khai và Kiểm tra Ứng dụng
Viết mã và xuất bản containers là bước quan trọng đầu tiên của ta . Bây giờ ta cần triển khai tới Kubernetes và thử nghiệm ứng dụng cơ bản. Sau đó, ta có thể thêm Jaeger và khám phá tiềm năng của truy tìm phân tán.
Hãy bắt đầu với việc triển khai và thử nghiệm.
Đến đây, cây folder của ta trông giống như sau:
. ├── backend │   ├── Dockerfile │   └── backend.py └── frontend     ├── Dockerfile     └── frontend.py Để triển khai ứng dụng này cho cụm của ta , ta cũng cần hai tệp kê khai Kubernetes ; một cho mỗi nửa ứng dụng.
 Tạo và mở file  kê khai mới trong ./frontend :
- nano ./frontend/deploy_frontend.yaml 
Thêm nội dung sau. Tệp kê khai này sẽ chỉ định cách Kubernetes xây dựng Triển khai của ta (hãy nhớ thay thế phần được đánh dấu bằng tên user Docker Hub của bạn):
apiVersion: apps/v1 kind: Deployment metadata:   name: do-visit-counter-frontend   labels:     name: do-visit-counter-frontend spec:   replicas: 1   selector:     matchLabels:       app: do-visit-counter-frontend   template:     metadata:       labels:         app: do-visit-counter-frontend     spec:       containers:         - name: do-visit-counter-frontend           image: your_dockerhub_username/do-visit-counter-frontend:v1           imagePullPolicy: Always           env:             - name: COUNTER_ENDPOINT               value: "http://do-visit-counter-backend.default.svc.cluster.local:5000"           ports:             - name: frontend-port               containerPort: 8000               protocol: TCP   Ta  đã chỉ định Kubernetes xây dựng một Triển khai, đặt tên cho nó là do-visit-counter-frontend và triển khai một bản sao bằng hình ảnh giao diện  user  của  ta  trên Docker Hub.  Ta  cũng đã  cấu hình  một biến môi trường có tên COUNTER_ENDPOINT để liên kết hai nửa ứng dụng của  ta .
Lưu và đóng file .
 Bây giờ, hãy tạo file  kê khai cho ứng dụng  backend  của  ta  trong ./backend :
- nano ./backend/deploy_backend.yaml 
Thêm nội dung sau, thay thế phần được đánh dấu bằng tên user Docker Hub của bạn:
apiVersion: apps/v1 kind: Deployment metadata:   name: do-visit-counter-backend   labels:     name: do-visit-counter-backend spec:   replicas: 1   selector:     matchLabels:       app: do-visit-counter-backend   template:     metadata:       labels:         app: do-visit-counter-backend     spec:       containers:         - name: do-visit-counter-backend           image: your_dockerhub_username/do-visit-counter-backend:v1           imagePullPolicy: Always           ports:             - name: backend-port               containerPort: 5000               protocol: TCP --- apiVersion: v1 kind: Service metadata:     name: do-visit-counter-backend spec:     selector:         app: do-visit-counter-backend     ports:         - protocol: TCP           port: 5000           targetPort: 5000 Trong file  kê khai này, bạn đang xác định Triển khai và Dịch vụ cho chương trình  backend  của  ta . Triển khai mô tả cách thức và những gì containers  sẽ chạy.  Lưu ý  cổng của  ta  đã thay đổi từ 8000 trên giao diện  user  thành 5000 trên  backend . Dịch vụ cho phép các kết nối liên cụm từ giao diện  user  đến  backend .
Lưu và đóng file .
 Bây giờ hãy triển khai bộ đếm của  ta  đến cụm bằng cách sử dụng kubectl . Bắt đầu với giao diện  user :
- kubectl apply -f ./frontend/deploy_frontend.yaml 
Và sau đó triển khai phần backend :
- kubectl apply -f ./backend/deploy_backend.yaml 
Để  xác minh  mọi thứ đang hoạt động, hãy gọi kubectl get pods :
- kubectl get pods 
Bạn sẽ thấy một kết quả như thế này:
OutputNAME                                         READY   STATUS    RESTARTS   AGE do-visit-counter-backend-79f6964-prqpb       1/1     Running   0          3m do-visit-counter-frontend-6985bdc8fd-92clz   1/1     Running   0          3m  Ta  muốn tất cả các  group  ở trạng thái READY . Nếu chúng vẫn chưa sẵn sàng, hãy đợi một vài phút và chạy lại lệnh trước đó.
 Cuối cùng,  ta  muốn sử dụng ứng dụng  của bạn . Để làm điều đó,  ta  sẽ chuyển tiếp các cổng từ cụm và sau đó giao tiếp với giao diện  user  bằng lệnh curl . Đảm bảo mở cửa sổ  terminal  thứ hai vì các cổng chuyển tiếp sẽ chặn một cửa sổ.
 Sử dụng kubectl để chuyển tiếp cổng:
- kubectl port-forward $(kubectl get pods -l=app="do-visit-counter-frontend" -o name) 8000:8000 
Bây giờ, trong cửa sổ terminal thứ hai, hãy gửi ba yêu cầu đến ứng dụng giao diện user của bạn:
for i in 1 2 3; do curl localhost:8000; done Mỗi cuộc gọi curl sẽ tăng số lượt truy cập. Bạn sẽ thấy một  kết quả  như thế này:
OutputHello, World!  You're visitor number 1 in here!  Hello, World!  You're visitor number 2 in here!  Hello, World!  You're visitor number 3 in here! Bộ đếm khách truy cập của ta đang hoạt động bình thường, nhưng bạn có thể nhận thấy sự chậm trễ giữa mỗi phản hồi. Đây là kết quả của chức năng ngủ, mô phỏng độ trễ hiệu suất.
Với ứng dụng phân tán của ta đã sẵn sàng, đã đến lúc cài đặt Jaeger và theo dõi các sự kiện này.
Bước 3 - Triển khai Jaeger
Thu thập dấu vết và hình dung chúng là chuyên môn của Jaeger. Trong bước này, ta sẽ triển khai Jaeger vào cụm của ta để nó có thể tìm thấy độ trễ hiệu suất của ta .
Tài liệu chính thức của Jaeger bao gồm các lệnh để cài đặt Jaeger Operator . Nó cũng bao gồm bốn file kê khai bổ sung mà bạn phải triển khai để công cụ hoạt động. Hãy làm điều đó ngay bây giờ:
Đầu tiên, tạo Định nghĩa tài nguyên tùy chỉnh được yêu cầu bởi Nhà điều hành Jaeger. Ta sẽ sử dụng các mẫu được đề xuất có sẵn trong tài liệu chính thức của Jaeger :
- kubectl create -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/crds/jaegertracing.io_jaegers_crd.yaml 
Tiếp theo, tạo Tài khoản dịch vụ , role và ràng buộc role cho Kiểm soát truy cập dựa trên role :
- kubectl create -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/service_account.yaml 
- kubectl create -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/role.yaml 
- kubectl create -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/role_binding.yaml 
Cuối cùng, triển khai Jaeger Operator:
- kubectl create -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/operator.yaml 
Bản thân Nhà điều hành không nghĩa là ta có Jaeger làm việc. Đây là lúc các Định nghĩa tài nguyên tùy chỉnh phát huy tác dụng. Ta cần tạo một tài nguyên mô tả cá thể Jaeger mà ta muốn Người vận hành quản lý. , ta sẽ làm theo các bước được liệt kê trong tài liệu chính thức của Jaeger:
Sử dụng heredoc để tạo tài nguyên này từ dòng lệnh:
- kubectl apply -f - <<EOF 
- apiVersion: jaegertracing.io/v1 
- kind: Jaeger 
- metadata: 
-   name: simplest 
- EOF 
Nhấn ENTER để tạo tài nguyên.
Bây giờ hãy kiểm tra lại các triển khai của bạn:
- kubectl get pods 
Bạn sẽ thấy  kết quả  với toán tử Jaeger  của bạn  và triển khai simplest :
OutputNAME                                                   READY   STATUS    RESTARTS   AGE do-visit-counter-backend-79f6964-prqpb                 1/1     Running   0          3m do-visit-counter-frontend-6985bdc8fd-92clz             1/1     Running   0          3m jaeger-operator-547567dddb-rxsd2                       1/1     Running   0          73s simplest-759cb7d586-q6x28                              1/1     Running   0          42s Để xác thực rằng Jaeger đang hoạt động chính xác, hãy chuyển tiếp cổng của nó và xem liệu ta có thể truy cập vào giao diện user hay không:
- kubectl port-forward $(kubectl get pods -l=app="jaeger" -o name) 16686:16686 
Mở trình duyệt và  chuyển  đến http://localhost:16686 . Giao diện  user  Jaeger sẽ tải. 
Cả ứng dụng của ta và Jaeger đều đang hoạt động. Trong bước tiếp theo, ta sẽ thêm thiết bị đo để cho phép Jaeger thu thập dữ liệu và tìm ra độ trễ hiệu suất của ta .
Bước 4 - Thêm thiết bị
Mặc dù Jaeger tự động hóa nhiều tác vụ khi được sử dụng với Kubernetes, ta vẫn cần thêm thiết bị đo đạc theo cách thủ công vào ứng dụng của bạn . May mắn là ta có mô-đun Flask-OpenTracing để xử lý tác vụ đó.
OpenTracing là một trong những tiêu chuẩn của truy tìm phân tán . Nó đã được đề xuất bởi các tác giả của Jaeger với mục đích cũng hỗ trợ các công cụ truy tìm khác. Nó trung lập với nhà cung cấp và hỗ trợ nhiều ngôn ngữ lập trình khác nhau và các khuôn khổ phổ biến.
Như trường hợp của tất cả các triển khai OpenTracing, ta cần phải sửa đổi các ứng dụng ban đầu của bạn bằng cách thêm cấu hình Jaeger và nối các trình trang trí theo dõi vào các điểm cuối mà ta muốn theo dõi.
Hãy thêm Flask-OpenTracing vào mã giao diện user của ta .
 Mở lại .frontend.py :
- nano ./frontend/frontend.py 
Bây giờ hãy thêm mã được đánh dấu sau, mã này sẽ nhúng OpenTracing:
import os import requests from flask import Flask from jaeger_client import Config from flask_opentracing import FlaskTracing  app = Flask(__name__) config = Config(     config={         'sampler':         {'type': 'const',          'param': 1},                         'logging': True,                         'reporter_batch_size': 1,},                          service_name="service") jaeger_tracer = config.initialize_tracer() tracing = FlaskTracing(jaeger_tracer, True, app)  def get_counter(counter_endpoint):     counter_response = requests.get(counter_endpoint)     return counter_response.text  def increase_counter(counter_endpoint):     counter_response = requests.post(counter_endpoint)     return counter_response.text  @app.route('/') def hello_world():     counter_service = os.environ.get('COUNTER_ENDPOINT', default="https://localhost:5000")     counter_endpoint = f'{counter_service}/api/counter'     counter = get_counter(counter_endpoint)      increase_counter(counter_endpoint)      return f"""Hello, World!  You're visitor number {counter} in here!\n\n""" Lưu và đóng file . Bạn có thể tìm hiểu thêm về cấu hình Flask OpenTracing trên trang GitHub của họ .
Bây giờ hãy mở mã ứng dụng backend của bạn:
- nano ./backend/backend.py 
Thêm mã được đánh dấu. Đây là cùng một mã mà  ta  đã đặt trong frontend.py :
from random import randint from time import sleep  from flask import Flask from flask import request from jaeger_client import Config from flask_opentracing import FlaskTracing   app = Flask(__name__) config = Config(     config={         'sampler':         {'type': 'const',          'param': 1},                         'logging': True,                         'reporter_batch_size': 1,},                          service_name="service") jaeger_tracer = config.initialize_tracer() tracing = FlaskTracing(jaeger_tracer, True, app)  counter_value = 1  def get_counter():     return str(counter_value)  def increase_counter():     global counter_value     int(counter_value)     sleep(randint(1,10))     counter_value += 1     return str(counter_value)  @app.route('/api/counter', methods=['GET', 'POST']) def counter():     if request.method == 'GET':         return get_counter()     elif request.method == 'POST':         return increase_counter()  Lưu và đóng file .
 Vì  ta  đang thêm các thư viện bổ sung,  ta  cũng phải sửa đổi Dockerfiles của Dockerfiles cho cả hai dịch vụ.
 Mở Dockerfile cho giao diện  user :
nano ./frontend/Dockerfile Thêm mã được đánh dấu:
FROM alpine:3.8  RUN apk add --no-cache py3-pip python3 && \     pip3 install flask requests Flask-Opentracing jaeger-client  COPY . /usr/src/frontend  ENV FLASK_APP frontend.py  WORKDIR /usr/src/frontend  CMD flask run --host=0.0.0.0 --port=8000 Lưu và đóng file .
 Bây giờ hãy mở Dockerfile của  backend :
- nano ./backend/Dockerfile 
Thêm mã được đánh dấu:
FROM alpine:3.8  RUN apk add --no-cache py3-pip python3 && \     pip3 install flask Flask-Opentracing jaeger-client  COPY . /usr/src/backend  ENV FLASK_APP backend.py  WORKDIR /usr/src/backend  CMD flask run --host=0.0.0.0 --port=5000 Với những thay đổi này, ta muốn xây dựng lại và đẩy các version mới của containers của bạn .
 Xây dựng và đẩy ứng dụng giao diện  user . Lưu ý thẻ v2 ở cuối:
- docker build -t your_username/do-visit-counter-frontend:v2 ./frontend 
- docker push your_username/do-visit-counter-frontend:v2 
Bây giờ xây dựng và đẩy ứng dụng backend :
- docker build -t your_username/do-visit-counter-backend:v2 ./backend 
- docker push your_username/do-visit-counter-backend:v2 
Hệ thống theo dõi phân tán của ta yêu cầu một phần cuối cùng: Ta muốn đưa các sidecar Jaeger vào các group ứng dụng của bạn để lắng nghe các dấu vết từ group và chuyển tiếp chúng đến server Jaeger. Để làm được điều đó, ta cần thêm chú thích vào file kê khai của bạn .
Mở file kê khai cho giao diện user :
- nano ./frontend/deploy_frontend.yaml 
Thêm mã được đánh dấu.  Lưu ý   ta  cũng đang thay thế hình ảnh  của bạn  bằng version  v2 . Đảm bảo sửa đổi dòng đó và thêm tên  user  Docker Hub của bạn:
apiVersion: apps/v1 kind: Deployment metadata:   name: do-visit-counter-frontend   labels:     name: do-visit-counter-frontend   annotations:     "sidecar.jaegertracing.io/inject": "true" spec:   replicas: 1   selector:     matchLabels:       app: do-visit-counter-frontend   template:     metadata:       labels:         app: do-visit-counter-frontend     spec:       containers:         - name: do-visit-counter-frontend              image: your_dockerhub_username/do-visit-counter-frontend:v2           imagePullPolicy: Always           env:             - name: COUNTER_ENDPOINT               value: "http://do-visit-counter-backend.default.svc.cluster.local:5000"           ports:             - name: frontend-port               containerPort: 8000               protocol: TCP Chú thích này sẽ đưa một Jaeger sidecar vào group của ta .
Lưu và đóng file .
Bây giờ hãy mở file kê khai cho phần backend :
- nano ./backend/deploy_backend.yaml 
Lặp lại quy trình, thêm các dòng được đánh dấu để đưa vào Jaeger sidecar và cập nhật thẻ hình ảnh của bạn:
apiVersion: apps/v1 kind: Deployment metadata:   name: do-visit-counter-backend   labels:     name: do-visit-counter-backend   annotations:     "sidecar.jaegertracing.io/inject": "true" spec:   replicas: 1   selector:     matchLabels:       app: do-visit-counter-backend   template:     metadata:       labels:         app: do-visit-counter-backend     spec:       containers:         - name: do-visit-counter-backend              image: your_dockerhub_username/do-visit-counter-backend:v2           imagePullPolicy: Always           ports:             - name: backend-port               containerPort: 5000               protocol: TCP --- apiVersion: v1 kind: Service metadata:     name: do-visit-counter-backend spec:     selector:         app: do-visit-counter-backend     ports:         - protocol: TCP           port: 5000           targetPort: 5000 Với các file  kê khai mới của  ta  đã có sẵn,  ta  cần áp dụng chúng vào cụm và chờ các  group 
 để tạo.
Hãy xóa tài nguyên cũ của ta :
- kubectl delete -f ./frontend/deploy_frontend.yaml 
- kubectl delete -f ./backend/deploy_backend.yaml 
Và sau đó thay thế chúng:
- kubectl apply -f ./frontend/deploy_frontend.yaml 
- kubectl apply -f ./backend/deploy_backend.yaml 
Lần này, các group cho các ứng dụng của ta sẽ bao gồm hai containers : một cho ứng dụng và một vùng thứ hai cho Jaeger sidecar.
 Sử dụng kubectl để kiểm tra điều này:
- kubectl get pods 
 Group  ứng dụng của  ta  hiện xuất hiện với 2/2 trong cột READY :
OutputNAME                                                   READY   STATUS    RESTARTS   AGE jaeger-operator-547567dddb-rxsd2                       1/1     Running   0          23m simplest-759cb7d586-q6x28                              1/1     Running   0          22m do-visit-counter-backend-694c7db576-jcsmv              2/2     Running   0          73s do-visit-counter-frontend-6d7d47f955-lwdnf             2/2     Running   0          42s Với các thiết bị trợ giúp và thiết bị đo đạc của ta tại chỗ, bây giờ ta có thể chạy lại chương trình của bạn và điều tra các dấu vết trong giao diện user Jaeger.
Bước 5 - Điều tra dấu vết trong Jaeger
Bây giờ ta có thể gặt hái những lợi ích của việc truy tìm. Mục tiêu ở đây là để xem cuộc gọi nào có thể là một vấn đề về hiệu suất bằng cách xem giao diện user Jaeger. Tất nhiên, nếu ta muốn xem một số dấu vết trong giao diện user , trước tiên ta phải tạo một số dữ liệu bằng cách sử dụng ứng dụng của bạn .
 Hãy  cài đặt  điều này bằng cách mở cửa sổ  terminal  thứ hai và thứ ba.  Ta  sẽ sử dụng hai cửa sổ để chuyển tiếp Jaeger và ứng dụng của  ta  và cửa sổ thứ ba để gửi các yêu cầu HTTP đến giao diện  user  từ máy của  ta  thông qua curl .
Trong cửa sổ đầu tiên, chuyển tiếp cổng cho dịch vụ giao diện user :
- kubectl port-forward $(kubectl get pods -l=app="do-visit-counter-frontend" -o name) 8000:8000 
Trong cửa sổ thứ hai, chuyển tiếp cổng cho Jaeger:
- kubectl port-forward $(kubectl get pods -l=app="jaeger" -o name) 16686:16686 
Trong cửa sổ thứ ba, sử dụng curl in a loop để tạo 10 yêu cầu HTTP:
for i in 0 1 2 3 4 5 6 7 8 9; do curl localhost:8000; done Bạn sẽ nhận được một kết quả như trước đây:
OutputHello, World!  You're visitor number 1 in here!  Hello, World!  You're visitor number 2 in here!  . . .  Hello, World!  You're visitor number 10 in here! Điều này sẽ cung cấp cho ta đủ các điểm dữ liệu khác nhau để so sánh chúng trong trực quan.
 Mở trình duyệt và  chuyển  đến http://localhost:16686 . Đặt menu thả xuống Dịch vụ thành dịch vụ và thay đổi kết quả giới hạn thành 30 . Nhấn Tìm dấu vết .
Các dấu vết từ ứng dụng của ta sẽ xuất hiện trong biểu đồ:
 Ở đây,  ta  thấy rằng các lệnh gọi khác nhau đến dịch vụ có thời gian thực hiện khác nhau. Jaeger đã theo dõi các ứng dụng của  ta  mất bao lâu để xử lý thông tin và chức năng nào đóng góp nhiều thời gian nhất.  Lưu ý , do hàm sleep của  ta , nên thời gian để hàm hello_world() hoàn thành là rất thay đổi. Điều này rất đáng ngờ và nó cho  ta  một nơi để tập trung điều tra. Jaeger đã trực quan hóa hiệu quả rò rỉ hiệu suất bên trong ứng dụng phân tán của  ta .
Bằng cách triển khai theo dõi và sử dụng Jaeger UI, ta có thể tìm ra nguyên nhân gây ra thời gian phản hồi không đều của ta .
Kết luận
Trong bài viết này, ta cài đặt hệ thống theo dõi phân tán bằng Jaeger và thêm thiết bị đo vào một ứng dụng nhỏ. Như vậy, ta có thể triển khai các dung lượng công việc khác vào cụm, đưa các sidecar Jaeger vào và xem các dịch vụ khác nhau của ta tương tác như thế nào và thao tác nào đang chiếm nhiều thời gian nhất.
Tìm kiếm tắc nghẽn hiệu suất trong các ứng dụng sử dụng nhiều dịch vụ nhanh hơn nhiều với tính năng theo dõi phân tán. Tuy nhiên, ví dụ này chỉ thể hiện một phần nhỏ tiềm năng của Jaeger. Trong một môi trường production phức tạp hơn, bạn có thể sử dụng Jaeger để so sánh các dấu vết khác nhau và thực sự đi sâu vào các rò rỉ hiệu suất. Những hình dung phức tạp mà Jaeger có thể tạo ra khá ấn tượng và rất hữu ích . Để tìm hiểu thêm về cách Jaeger có thể giúp bạn theo dõi và giải quyết các vấn đề về hiệu suất trong cụm của bạn, hãy truy cập tài liệu chính thức của họ .
Các tin liên quan
 

