Service Mesh-Istio Practical Chapter (Part 2)

First article:


Collect metrics and monitor applications

In observability, indicators are the most able to reflect the operating conditions of the system from many aspects. Because there are various indicators, we can measure and monitor each dimension of the system through multi-dimensional data analysis.

By default, Istio uses its own Promethuse and Grafana components to complete the collection and display of indicators, but basic tools such as monitoring systems are usually necessary in each company’s production environment, so if you use Istio’s own components Just repeat.

Therefore, integrating the existing monitoring system with Istio is the best solution. So this section will demonstrate the integration of indicator collection with the existing monitoring system and Istio.

Istio's indicator interface

First, we need to understand how Istio exposes its indicators. It mainly provides the following two indicator interfaces:

  • /metrics:Provide indicator information of Istio's own operating status
  • /stats/prometheus: Interface provided by Envoy to obtain network traffic-related indicators
    Service Mesh-Istio Practical Chapter (Part 2)

We can request /stats/prometheusinterface to see the metrics it provides:

$ kubectl exec -it -n demo ${sleep_pod_name} -c sleep -- curl http://httpbin.demo:15090/stats/prometheus

istiod service /metricsinterface exposes some of the indicators of the control plane, we can get through the following ways:

$ kubectl exec -it -n demo ${sleep_pod_name} -c sleep -- curl http://istiod.istio-system:15014/metrics

Prometheus configuration method

Service Mesh-Istio Practical Chapter (Part 2)

  • Static configuration has relatively large limitations and cannot adapt to changes well, so dynamic configuration is generally used

The foundation supporting dynamic configuration is Prometheus's service discovery mechanism:

  • The service discovery mechanism can ensure that Prometheus can find the interfaces provided by these corresponding indicators through the interfaces exposed by the service
  • kubernetes_sd_config.role Configuration items define which targets are collected for metrics
    • node: cluster node
    • service: service, often used for black box monitoring
    • pod: target the container in the pod
    • endpoints: endpoints
    • ingress: ingress gateway
  • relabel_configs The configuration item defines the filtering mechanism to filter the exposed interfaces

Actual combat

Let's build a monitoring system first, and then integrate with Istio. First deploy Prometheus, the specific configuration list is as follows:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: prometheus
  namespace: monitoring
  labels:
    app: prometheus
spec:
  selector:
    matchLabels:
      app: prometheus
  template:
    metadata:
      labels:
        app: prometheus
    spec:
      serviceAccount: appmesh-prometheus
      serviceAccountName: appmesh-prometheus
      containers:
      - image: prom/prometheus:latest
        name: prometheus
        command:
        - "/bin/prometheus"
        args:
        - "--config.file=/etc/prometheus/prometheus.yml"
        - "--storage.tsdb.path=/prometheus"
        - "--storage.tsdb.retention=24h"
        - "--web.enable-admin-api"  
        - "--web.enable-lifecycle"  
        ports:
        - containerPort: 9090
          protocol: TCP
          name: http
        volumeMounts:
        - mountPath: /etc/prometheus
          name: config-volume
        - mountPath: /prometheus/data
          name: data-volume
        resources:
          requests:
            cpu: 100m
            memory: 512Mi
          limits:
            cpu: 100m
            memory: 512Mi
      securityContext:
        runAsUser: 0
      volumes:
      - configMap:
          name: prometheus-config
        name: config-volume
      - emptyDir: {}
        name: data-volume
---
apiVersion: v1
kind: Service
metadata:
  name: prometheus
  namespace: monitoring
  labels:
    app: prometheus
spec:
  selector:
    app: prometheus
  type: NodePort
  ports:
    - name: web
      port: 9090
      targetPort: http
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: appmesh-prometheus
  namespace: monitoring
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  namespace: monitoring
  name: appmesh-prometheus
rules:
  - apiGroups:
      - ""
    resources:
      - nodes
      - nodes/proxy
      - nodes/metrics
      - services
      - endpoints
      - pods
      - ingresses
      - configmaps
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - "extensions"
      - "networking.k8s.io"
    resources:
      - ingresses/status
      - ingresses
    verbs:
      - get
      - list
      - watch
  - nonResourceURLs:
      - "/metrics"
    verbs:
      - get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: appmesh-prometheus
subjects:
  - kind: ServiceAccount
    name: appmesh-prometheus
    namespace: monitoring
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: appmesh-prometheus

Create a Prometheus ConfigMap:

apiVersion: v1
kind: ConfigMap
metadata:
  name: prometheus-config
  namespace: monitoring
data:
  prometheus.yml: |
    global:
      scrape_interval: 15s
      scrape_timeout: 15s
    scrape_configs:
    - job_name: 'prometheus'
      static_configs:
      - targets: ['localhost:9090']

Then deploy Grafana, the configuration list is as follows:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: grafana
  name: grafana
  namespace: monitoring
spec:
  replicas: 1
  selector:
    matchLabels:
      app: grafana
  template:
    metadata:
      labels:
        app: grafana
    spec:
      containers:
      - name: grafana
        image: grafana/grafana:latest
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 3000
          name: grafana
        env:
        - name: GRAFANA_PORT
          value: "3000"
        - name: GF_AUTH_BASIC_ENABLED
          value: "false"
        - name: GF_AUTH_ANONYMOUS_ENABLED
          value: "true"
        - name: GF_AUTH_ANONYMOUS_ORG_ROLE
          value: Admin
        resources:
          limits:
            cpu: 100m
            memory: 256Mi
          requests:
            cpu: 100m
            memory: 256Mi
        volumeMounts:
          - mountPath: /var/lib/grafana
            name: grafana-storage
      volumes:
        - name: grafana-storage
          emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
  name: grafana
  namespace: monitoring
  labels:
    app: grafana
spec:
  selector:
    app: grafana
  type: NodePort
  ports:
    - name: http
      port: 3000
      targetPort: 3000
      nodePort: 32000
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: grafana
  namespace: monitoring

Confirm that all started normally:

[root@m1 ~]# kubectl get all -n monitoring 
NAME                             READY   STATUS    RESTARTS   AGE
pod/grafana-86f5dc96d-6hsmz      1/1     Running   0          20m
pod/prometheus-9dd6bd8bb-wcdrw   1/1     Running   0          2m30s

NAME                 TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
service/grafana      NodePort   10.101.215.111   <none>        3000:32000/TCP   20m
service/prometheus   NodePort   10.101.113.122   <none>        9090:31053/TCP   13m

NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/grafana      1/1     1            1           20m
deployment.apps/prometheus   1/1     1            1           13m

NAME                                   DESIRED   CURRENT   READY   AGE
replicaset.apps/grafana-86f5dc96d      1         1         1       20m
replicaset.apps/prometheus-9dd6bd8bb   1         1         1       13m
[root@m1 ~]# 

Check which work node prometheus and grafana are scheduled on:

[root@m1 ~]# kubectl get po -l app=grafana -n monitoring -o jsonpath='{.items[0].status.hostIP}'
192.168.243.139
[root@m1 ~]# kubectl get po -l app=prometheus -n monitoring -o jsonpath='{.items[0].status.hostIP}'
192.168.243.139

Use a browser to visit prometheus, and check whether its configuration content meets expectations, that is, whether it can correspond to the content of the ConfigMap:
Service Mesh-Istio Practical Chapter (Part 2)

From the figure above, we can see that currently prometheus is statically configured. Next, we need to change it to dynamic configuration and modify its ConfigMap content as follows:

apiVersion: v1
kind: ConfigMap
metadata:
  name: prometheus-config
  namespace: monitoring
data:
  prometheus.yml: |-
    global:
      scrape_interval: 15s
      scrape_timeout: 15s
    scrape_configs:
    - job_name: 'prometheus'
      static_configs:
      - targets: ['localhost:9090']

    # 以下是整合Istio的配置
    - job_name: envoy-stats
      honor_timestamps: true
      metrics_path: /stats/prometheus
      scheme: http
      kubernetes_sd_configs:
      - role: pod
      relabel_configs:
      - source_labels: [__meta_kubernetes_pod_container_port_name]
        separator: ;
        regex: .*-envoy-prom
        replacement: $1
        action: keep
      - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
        separator: ;
        regex: ([^:]+)(?::\d+)?;(\d+)
        target_label: __address__
        replacement: $1:15090
        action: replace
      - separator: ;
        regex: __meta_kubernetes_pod_label_(.+)
        replacement: $1
        action: labeldrop
      - source_labels: [__meta_kubernetes_namespace]
        separator: ;
        regex: (.*)
        target_label: namespace
        replacement: $1
        action: replace
      - source_labels: [__meta_kubernetes_pod_name]
        separator: ;
        regex: (.*)
        target_label: pod_name
        replacement: $1
        action: replace  
  • Tips: The ConfigMap configuration content here is copied from the Prometheus configuration file officially provided by Istio, and the configuration may be different for each version. The path is:$ISTIO_HOME/samples/addons/prometheus.yaml

Then rebuild prometheus through the patch command:

[root@m1 ~]# kubectl patch deployment prometheus -n monitoring -p "{\"spec\":{\"template\":{\"metadata\":{\"labels\":{\"date\":\"`date +'%s'`\"}}}}}"
deployment.apps/prometheus patched
[root@m1 ~]# 

Check whether the configuration has taken effect:
Service Mesh-Istio Practical Chapter (Part 2)

At this point, Istio's metrics can be queried on prometheus:
Service Mesh-Istio Practical Chapter (Part 2)

For Grafana, you only need to export the built-in Dashboard of Istio and then import it to another Grafana. It's relatively simple and won't demonstrate.


Integrated ELK Stack log suite

In a distributed system, the logs generated by the application will be distributed on each node, which is very unfavorable for viewing and management. Therefore, a centralized log architecture is generally used to aggregate log data into a log platform for unified management, and the most widely known log platform is the ELK Stack.

Centralized log architecture

Service Mesh-Istio Practical Chapter (Part 2)

The main function:

  • collect
  • deal with
  • Show off

ELK Stack log architecture

Service Mesh-Istio Practical Chapter (Part 2)

  • ElasticSearch: responsible for data storage and search
  • Logstash: Responsible for the data collection pipeline, providing filtering and preprocessing functions
  • Kibana: used for charting data
  • LibBeats: Lightweight data collector

ELK deployment form

Service Mesh-Istio Practical Chapter (Part 2)

Actual combat

Next we install the ELK suite to collect Istio Envoy log data. First create a namespace in the cluster:

[root@m1 ~]# kubectl create ns elk
namespace/elk created
[root@m1 ~]# 

Then use the following configuration checklist to deploy Elastic Search and Kibana:

kind: List
apiVersion: v1
items:
- apiVersion: apps/v1
  kind: Deployment
  metadata:
    name: kibana
  spec:
    selector:
      matchLabels:
        app: kibana
    replicas: 1
    template:
      metadata:
        name: kibana
        labels:
          app: kibana
      spec:
        containers:
        - image: docker.elastic.co/kibana/kibana:6.4.0
          name: kibana
          env:
          - name: ELASTICSEARCH_URL
            value: "http://elasticsearch:9200"
          ports:
          - name: http
            containerPort: 5601
- apiVersion: v1
  kind: Service
  metadata:
    name: kibana
  spec:
    type: NodePort
    ports:
    - name: http
      port: 5601
      targetPort: 5601 
      nodePort: 32001
    selector:
      app: kibana            
- apiVersion: apps/v1
  kind: Deployment
  metadata:
    name: elasticsearch
  spec:
    selector:
      matchLabels:
        app: elasticsearch
    replicas: 1
    template:
      metadata:
        name: elasticsearch
        labels:
          app: elasticsearch
      spec:
        initContainers:
        - name: init-sysctl
          image: busybox
          command:
          - sysctl
          - -w
          - vm.max_map_count=262144
          securityContext:
            privileged: true
        containers:
        - image: docker.elastic.co/elasticsearch/elasticsearch:6.4.0
          name: elasticsearch
          env:
          - name: network.host
            value: "_site_"
          - name: node.name
            value: "${HOSTNAME}"
          - name: discovery.zen.ping.unicast.hosts
            value: "${ELASTICSEARCH_NODEPORT_SERVICE_HOST}"
          - name: cluster.name
            value: "test-single"
          - name: ES_JAVA_OPTS
            value: "-Xms128m -Xmx128m"
          volumeMounts:
          - name: es-data
            mountPath: /usr/share/elasticsearch/data
        volumes:
          - name: es-data
            emptyDir: {}
- apiVersion: v1
  kind: Service
  metadata: 
    name: elasticsearch-nodeport
  spec:
    type: NodePort
    ports:
    - name: http
      port: 9200
      targetPort: 9200
      nodePort: 32002
    - name: tcp
      port: 9300
      targetPort: 9300
      nodePort: 32003
    selector:
      app: elasticsearch
- apiVersion: v1
  kind: Service
  metadata:
    name: elasticsearch
  spec:
    clusterIP: None
    ports:
    - name: http
      port: 9200
    - name: tcp
      port: 9300
    selector:
      app: elasticsearch

Specify the namespace for deployment:

[root@m1 ~]# kubectl apply -f elk/deploy.yaml -n elk 
deployment.apps/kibana created
service/kibana created
deployment.apps/elasticsearch created
service/elasticsearch-nodeport created
service/elasticsearch created
[root@m1 ~]# 

The above only deploys elasticsearch and kibana, but if we want to collect Envoy logs, we also need to deploy Logstash or FileBeats. Here, FileBeats is used as an example. The configuration list is as follows:

kind: List
apiVersion: v1
items:
- apiVersion: v1
  kind: ConfigMap
  metadata:
    name: filebeat-config
    labels:
      k8s-app: filebeat
      kubernetes.io/cluster-service: "true"
      app: filebeat-config
  data:
    filebeat.yml: |
      processors:
        - add_cloud_metadata:
      filebeat.modules:
      - module: system
      filebeat.inputs:
      - type: log
        paths:
          - /var/log/containers/*.log
        symlinks: true
      output.elasticsearch:
        hosts: ['elasticsearch:9200']
      logging.level: info        
- apiVersion: apps/v1
  kind: Deployment 
  metadata:
    name: filebeat
    labels:
      k8s-app: filebeat
      kubernetes.io/cluster-service: "true"
  spec:
    selector:
      matchLabels:
        app: filebeat
    replicas: 1
    template:
      metadata:
        name: filebeat
        labels:
          app: filebeat
          k8s-app: filebeat
          kubernetes.io/cluster-service: "true"
      spec:
        containers:
        - image: docker.elastic.co/beats/filebeat:6.4.0
          name: filebeat
          args: [
            "-c", "/home/filebeat-config/filebeat.yml",
            "-e",
          ]
          securityContext:
            runAsUser: 0
          volumeMounts:
          - name: filebeat-storage
            mountPath: /var/log/containers
          - name: varlogpods
            mountPath: /var/log/pods
          - name: varlibdockercontainers
            mountPath: /var/lib/docker/containers
          - name: "filebeat-volume"
            mountPath: "/home/filebeat-config"
        volumes:
          - name: filebeat-storage
            hostPath:
              path: /var/log/containers
          - name: varlogpods
            hostPath:
              path: /var/log/pods
          - name: varlibdockercontainers
            hostPath:
              path: /var/lib/docker/containers
          - name: filebeat-volume
            configMap:
              name: filebeat-config
- apiVersion: rbac.authorization.k8s.io/v1
  kind: ClusterRoleBinding
  metadata:
    name: filebeat
  subjects:
  - kind: ServiceAccount
    name: filebeat
    namespace: elk
  roleRef:
    kind: ClusterRole
    name: filebeat
    apiGroup: rbac.authorization.k8s.io
- apiVersion: rbac.authorization.k8s.io/v1
  kind: ClusterRole
  metadata:
    name: filebeat
    labels:
      k8s-app: filebeat
  rules:
  - apiGroups: [""] # "" indicates the core API group
    resources:
    - namespaces
    - pods
    verbs:
    - get
    - watch
    - list
- apiVersion: v1
  kind: ServiceAccount
  metadata:
    name: filebeat
    namespace: elk
    labels:
      k8s-app: filebeat

Confirm that all components have been successfully deployed:

[root@m1 ~]# kubectl get all -n elk 
NAME                                 READY   STATUS    RESTARTS   AGE
pod/elasticsearch-697c88cd76-xvn4j   1/1     Running   0          4m53s
pod/filebeat-8646b847b7-f58zg        1/1     Running   0          32s
pod/kibana-fc98677d7-9z5dl           1/1     Running   0          8m14s

NAME                             TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                         AGE
service/elasticsearch            ClusterIP   None            <none>        9200/TCP,9300/TCP               8m14s
service/elasticsearch-nodeport   NodePort    10.96.106.229   <none>        9200:32002/TCP,9300:32003/TCP   8m14s
service/kibana                   NodePort    10.105.91.140   <none>        5601:32001/TCP                  8m14s

NAME                            READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/elasticsearch   1/1     1            1           8m14s
deployment.apps/filebeat        1/1     1            1           32s
deployment.apps/kibana          1/1     1            1           8m14s

NAME                                       DESIRED   CURRENT   READY   AGE
replicaset.apps/elasticsearch-697c88cd76   1         1         1       4m53s
replicaset.apps/filebeat-8646b847b7        1         1         1       32s
replicaset.apps/kibana-fc98677d7           1         1         1       8m14s
[root@m1 ~]# 

Go to Kibana to create a simple Index Pattern:
Service Mesh-Istio Practical Chapter (Part 2)

Created:
Service Mesh-Istio Practical Chapter (Part 2)

Then you can view the log data collected by FileBeat and stored in Elastic Search on the Discover page:
Service Mesh-Istio Practical Chapter (Part 2)


Integrated distributed tracing tools

Istio's distributed tracking

  • Istio's distributed tracing is implemented based on Envoy
  • The application is responsible for transmitting the trace header information (b3 trace header), so it is not completely transparent to the application, and the application needs to pass the header by itself
  • b3 This information header was first proposed by openzipkin: https://github.com/openzipkin/b3-propagation
  • Support sampling rate

The process of distributed tracing based on Envoy is as follows:
Service Mesh-Istio Practical Chapter (Part 2)

  • First, generate RequestId for requests flowing through Envoy proxy, and TraceHeader, which is the information header
  • Generate the corresponding TraceSpan based on the metadata of the request and response, and then send the Span to the Trace backend
  • Finally, the Trace header is forwarded to the application node of the agent

Deploy Jaeger

Next, we use Operator to install Jaeger to demonstrate how Istio can be integrated with the existing distributed tracking system. Let’s take a brief look at Operator:

  • Toolkit for deploying and managing Kubernetes applications
  • Deploy in a cluster, use Kubernetes API to manage applications
  • Operator Framework
    • Operator SDK
    • Operator Lifecycle Manager
      Service Mesh-Istio Practical Chapter (Part 2)

First clone the jaeger-operator repository:

[root@m1 ~]# cd /usr/local/src
[root@m1 /usr/local/src]# git clone https://github.com/jaegertracing/jaeger-operator.git

Modify the configuration file, WATCH_NAMESPACEis valueset to null, so that it could track the request in all namespaces:

[root@m1 /usr/local/src]# vim jaeger-operator/deploy/operator.yaml
...
        env:
        - name: WATCH_NAMESPACE
          value:
...

Create jaeger's crd:

[root@m1 /usr/local/src]# kubectl apply -f jaeger-operator/deploy/crds/jaegertracing.io_jaegers_crd.yaml 
customresourcedefinition.apiextensions.k8s.io/jaegers.jaegertracing.io created
[root@m1 /usr/local/src]# 

Then create a namespace and create other jaeger resources under this namespace:

$ kubectl create ns observability
$ kubectl apply -f jaeger-operator/deploy/role.yaml -n observability 
$ kubectl apply -f jaeger-operator/deploy/role_binding.yaml -n observability 
$ kubectl apply -f jaeger-operator/deploy/service_account.yaml -n observability 
$ kubectl apply -f jaeger-operator/deploy/cluster_role.yaml -n observability
$ kubectl apply -f jaeger-operator/deploy/cluster_role_binding.yaml -n observability
$ kubectl apply -f jaeger-operator/deploy/operator.yaml -n observability 

Confirm that the operator has started normally:

[root@m1 /usr/local/src]# kubectl get all -n observability 
NAME                                   READY   STATUS    RESTARTS   AGE
pod/jaeger-operator-7f76698d98-x9wkh   1/1     Running   0          105s

NAME                              TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)             AGE
service/jaeger-operator-metrics   ClusterIP   10.100.189.227   <none>        8383/TCP,8686/TCP   11s

NAME                              READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/jaeger-operator   1/1     1            1           105s

NAME                                         DESIRED   CURRENT   READY   AGE
replicaset.apps/jaeger-operator-7f76698d98   1         1         1       105s
[root@m1 /usr/local/src]# 

Install jaegers, a custom resource, and the operator will automatically deploy jaeger for us through the custom resource:

[root@m1 /usr/local/src]# kubectl apply -f jaeger-operator/examples/simplest.yaml -n observability 
jaeger.jaegertracing.io/simplest created
[root@m1 /usr/local/src]# kubectl get jaegers -n observability 
NAME       STATUS    VERSION   STRATEGY   STORAGE   AGE
simplest   Running   1.21.0    allinone   memory    3m8s
[root@m1 /usr/local/src]# 

Jaeger integrates Istio

After Jaeger is deployed, the next step is to integrate it with Istio. Integration is very simple, only need istioctlto set some configuration variables tools, command is as follows:

[root@m1 ~]# istioctl install --set profile=demo -y \
--set values.global.tracer.zipkin.address=simplest-collector.observability:9411 \
--set values.pilot.traceSampling=100
  • Tips: Theprofile value needs to be set to the value set when Istio is installed, otherwise Istio will be reinstalled according to the default value

After Jaeger integrates Istio, there is the last step left. We need to inject Jaeger's agent into our application by injection. Jaeger Operator supports automatic injection, we only need to add an injection flag in Annotation.

We also mentioned that Istio's tracing is not completely transparent to the application. We need to process the trace header in the application ourselves. So for the convenience of testing, we will use the official Bookinfo application as a demonstration. Deploy Bookinfo:

[root@m1 ~]# kubectl apply -f /usr/local/istio-1.8.1/samples/bookinfo/platform/kube/bookinfo.yaml
[root@m1 ~]# kubectl apply -f /usr/local/istio-1.8.1/samples/bookinfo/networking/bookinfo-gateway.yaml

Jaeger supports namespaces for injection or Deployment, Deployment to product this example, we only need to add a line in his Annotation sidecar.jaegertracing.io/inject: "true"to:

[root@m1 ~]# kubectl edit deployments.apps/productpage-v1
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    sidecar.jaegertracing.io/inject: "true"

    ...

Then use the patch command to rebuild the productpage:

[root@m1 ~]# kubectl patch deployment productpage-v1 -p "{\"spec\":{\"template\":{\"metadata\":{\"labels\":{\"date\":\"`date +'%s'`\"}}}}}"
deployment.apps/productpage-v1 patched
[root@m1 ~]# 

At this point, you can see that the number of containers in the productpage Pod has increased to three, indicating that Jaeger has injected the agent into it:

[root@m1 ~]# kubectl get pods
NAME                              READY   STATUS    RESTARTS   AGE
productpage-v1-5c75dcd69f-g9sjh   3/3     Running   0          96s
...

Use the following command to open Jaeger's Web UI access port:

[root@m1 ~]# kubectl port-forward svc/simplest-query -n observability 16686:16686 --address 192.168.243.138
Forwarding from 192.168.243.138:16686 -> 16686

You can see on the page that Jaeger can detect the productpage service:
Service Mesh-Istio Practical Chapter (Part 2)


Debugging tools and methods: What are the tools and methods for debugging grids?

Istio's common debugging methods mainly include the following:

  • istioctl command line
  • Self-check tool for controlZ control plane
  • Envoy admin interface
  • Pilot debug interface

istioctl command line

We can use the --helpparameters to see istioctlcommand help information:

$ istioctl --help

Installation and deployment related

  • istioctl verify-install: Can be used to verify whether the current k8s cluster environment can deploy Istio
  • istioctl install [flags]: Used to install the Istio environment in the current cluster
  • istioctl profile [list / diff / dump]: Operating Istio's profile
  • istioctl kube-inject: Used to inject Envoy sidecar into Pod
  • istioctl dashboard [command]: Start the specified Istio Dashboard Web UI
    • controlz / envoy / Grafana / jaeger / kiali / Prometheus / zipkin

Grid configuration status check

  • istioctl ps &lt;pod-name&gt;: View the synchronization status of the grid configuration. There are several states:
    • SYNCED: Configuration is synchronized
    • NOT SENT: The configuration is not issued
    • STALE: The configuration was delivered, but the Pod did not respond to act
  • istioctl pc [cluster/route/…] &lt;pod-name.namespace&gt;: Get the grid configuration details of the specified resource

View Pod-related grid configuration information

istioctl x( experimental )describe pod &lt;pod-name&gt;

  • Verify that it is inside the grid
  • Verify VirtualService
  • Verify DestinationRule
  • Verify routing

Example:

[root@m1 ~]# istioctl x describe pod productpage-v1-65576bb7bf-4bwwr
Pod: productpage-v1-65576bb7bf-4bwwr
   Pod Ports: 9080 (productpage), 15090 (istio-proxy)
--------------------
Service: productpage
   Port: http 9080/HTTP targets pod port 9080

Exposed on Ingress Gateway http://192.168.243.140
VirtualService: bookinfo
   /productpage, /static*, /login, /logout, /api/v1/products*
[root@m1 ~]# 

Grid configuration diagnosis

  • istioctl analyze [–n &lt;namespace&gt; / --all-namespaces]: Check the grid configuration under the specified namespace, if there is a problem, a corresponding warning or error message will be prompted
  • istioctl analyze a.yaml b.yaml my-app-config/: Check for a single configuration file or all configuration files in a directory
  • istioctl analyze --use-kube=false a.yaml: Check the specified configuration file by ignoring the deployment platform

controlZ visual self-check tool

controlZ is a visual self-checking tool for the control plane. Its main functions are as follows:

  • Adjust the log output level
  • View memory usage
  • View environment variables
  • View process information

The usage is as follows:

istioctl d controlz <istiod-podname> -n istio-system

Service Mesh-Istio Practical Chapter (Part 2)

Envoy admin API interface

Envoy admin API can view and operate the data plane. Its main functions are as follows:

  • Log level adjustment
  • Performance data analysis
  • Configuration and other information
  • Indicator View

Use the following command to open the Envoy admin API of the specified Pod:

istioctl d envoy <pod-name>.[namespace] --address ${ip}

Or open its port by:

kubectl port-forward <pod-name> 15000:15000 ${ip}

Its page is as follows:
Service Mesh-Istio Practical Chapter (Part 2)

Pilot debug interface

The main functions of the Pilot debug interface are as follows:

  • xDS and configuration information
  • Performance problem analysis
  • Configure synchronization

Use the following command to open its port:

kubectl port-forward service/istiod -n istio-system 15014:15014 --address ${ip}

Its page is as follows:
Service Mesh-Istio Practical Chapter (Part 2)

Guess you like

Origin blog.51cto.com/zero01/2572828