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
We can request /stats/prometheus
interface 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 /metrics
interface 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
- 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:
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:
At this point, Istio's metrics can be queried on prometheus:
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
The main function:
- collect
- deal with
- Show off
ELK Stack log architecture
- 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
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:
Created:
Then you can view the log data collected by FileBeat and stored in Elastic Search on the Discover page:
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:
- 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
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_NAMESPACE
is value
set 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 istioctl
to 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: The
profile
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:
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 --help
parameters to see istioctl
command help information:
$ istioctl --help
Installation and deployment related
istioctl verify-install
: Can be used to verify whether the current k8s cluster environment can deploy Istioistioctl install [flags]
: Used to install the Istio environment in the current clusteristioctl profile [list / diff / dump]
: Operating Istio's profileistioctl kube-inject
: Used to inject Envoy sidecar into Podistioctl dashboard [command]
: Start the specified Istio Dashboard Web UIcontrolz / envoy / Grafana / jaeger / kiali / Prometheus / zipkin
Grid configuration status check
istioctl ps <pod-name>
: 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/…] <pod-name.namespace>
: Get the grid configuration details of the specified resource
View Pod-related grid configuration information
istioctl x( experimental )describe pod <pod-name>
:
- 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 <namespace> / --all-namespaces]
: Check the grid configuration under the specified namespace, if there is a problem, a corresponding warning or error message will be promptedistioctl analyze a.yaml b.yaml my-app-config/
: Check for a single configuration file or all configuration files in a directoryistioctl 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
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:
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: