Series of navigation

  • Istio Mixer Adapter development (I) K8S environment construction
  • (2) Istio environment construction
  • (3) Customized Mixer Grpc Adapter deployment

An overview of the

For the development of Istio Mixer Adapter, there will be articles devoted to the source code analysis and development and debugging process. Here, I only use the K8S+Istio environment described in the previous two articles to deploy the Istio Mixer Grpc Adapter I have developed and configure K8S to make it effective

Gatewaymetric profile

Gatewaymetric is the Istio Mixer Grpc Adapter developed by the author with reference to Istio official website. Its main function is to process THE HTTP access logs reported by Mixer. Collect access logs of north-to-south traffic (that is, from outside the cluster to the cluster through istio-ingressGateway). By invoking promethues official Go program library, metrics are generated in memory and promethues is exposed to its exporter port for data collection. Its functionality is far from perfect, but it is sufficient as a learning guide

This article mainly refers to the official website Wiki for development, which also talked about part of the principle

Github.com/istio/istio…

Here is the code structure

➜ gatewaymetric git: v1.0.5 ✗ tree. ├ ─ ─ CMD │ └ ─ ─ main. Go ├ ─ ─ the config │ ├ ─ ─ adapter. Gatewaymetric. Config. Pb. HTML │ ├ ─ ─ Config. Pb. Go │ ├ ─ ─ config. The proto │ ├ ─ ─ config. Proto_descriptor │ └ ─ ─ gatewaymetric. Yaml ├ ─ ─ gatewaymetric. Go ├ ─ ─ ├─ Ample_operator_cfg. ├─ Ample_operator_cfg. ├─ Ample_operator_├ ─ Ample_operator_cfg template.yamlCopy the code

In the above file, CMD /main.go is the program entrance, which exposes two ports: 1) HTTP :9145 is the data capture port of Promethues; 2) GRPC :41543 is the communication port of GrpcAdapter, that is, the port to establish connection with Mixer, which will be used later. The display should be registered with the Mixer so that the Mixer senses it

Build a custom Mixer Grpc Adapter (GatewayMetric)

The first step is to package the Adapter, make it into a Docker image and publish it to the Docker Hub

✗ ➜ CMD git: (v1.0.5)cd/ home/ubuntu/go/SRC/istio. IO/istio/mixer/adapter/gatewaymetric/CMD ➜ CMD git: (master) CGO_ENABLED = 0 GOOS = Linux GOARCH=amd64 go build-a-installsuffix cgo -o gatewaymetric ➜ CMD git:(v1.0.5) go onto university CGO_ENABLE➜ CMD git:(v1.0.5) go onto university./gatewaymetric adapter listening on"[...] : 41543"
promethues listening on ": 9145"
D=0 GOOS=linux GOARCH=amd64 go build -a -installsuffix cgo -o gatewaymetric
Copy the code

Through the above command, we built a customized GrpcAdapter based on the source code and successfully started it. If the reader cannot execute the end go build command normally, it may be the go environment configuration problem, you can bypass here and directly use the gatewaymetric file under the source code CMD. Now that I’ve built the binaries, let’s write the Dockerfile

➜ CMD git:(v1.0.5) qualify vim Dockerfile ➜ CMD git:(v1.0.5) qualify vim Dockerfile FROM scratch ADD gatewaymetric/ENTRYPOINT ["/gatewaymetric"]
Copy the code

The Dockerfile uses the Scratch base image and adds the GatewayMetric (as we will later call our custom Mixer Grpc Adapter) to the image, starting with a “/ gatewayMetric “entry to start building

➜ CMD git:(v1.0.5) qualify sudo docker build-fDockerfile. Sending build context to Docker daemon 17.87MB Step 3: FROM scratch --> Step 2/3: ADD gatewaymetric / ---> 82ca9cdf54ab Step 3/3 : ENTRYPOINT ["/gatewaymetric"]
 ---> Running in2630beb8DA5d Removing Intermediate Container 2630beb8DA5D --> 3747Dfc14d90 Successfully built 3747dfc14d90 ➜ CMD Git :(v1.0.5) Qualify Sudo Docker Run -P 9145:9145-P 41543:41543 3747DFC14D90 adapter listening on"[...] : 41543"
promethues listening on ": 9145"
Copy the code

Through the simulation program test (here is the use of the Wiki described in the previous local simulation test method), it shows that there is no problem with the Docker image, if the reader does not understand the knowledge of this, ignore here can, the later article will describe in detail how to develop and debug Adapter locally

Next, we submit the image to Docker Hub (here describes the process of developing, building and pushing the image, readers can skip this step and directly use the image that the author has built and published to Docker Hub).

➜ CMD git: v1.0.5 ✗ sudo docker tag 3747 dfc14d90 zrbcool/gatewaymetric: v1.0 ➜ CMD git: v1.0.5 ✗ sudo docker push Zrbcool/gatewaymetric: v1.0 The push refers to The repository docker. IO/zrbcool/gatewaymetric 115 a048ee88f: Pushed v1.0: digest: sha256:616fc9e1d91ad963a5ace4b5210caecbde21aca8ea5f2bfe8f98ac20e33a6cfa size: 528
Copy the code

Deploy the Adapter to the K8S + Istio cluster

Deploy the image on the VM in the K8S + Istio cluster

➜ gatewaymetric cat deployment.yaml apiVersion: Extensions /v1beta1 kind: deployment metadata: name: gatewaymetric namespace: istio-system labels: app: gatewaymetric spec: replicas: 1 selector: matchLabels: app: gatewaymetric template: metadata: labels: app: gatewaymetric spec: containers: - name: gatewaymetric image:"Zrbcool/gatewaymetric: v1.0"
        imagePullPolicy: "IfNotPresent"
        ports:
        - containerPort: 9145
        - containerPort: 41543
Copy the code

And then create the Service

➜  gatewaymetric cat service.yaml 
apiVersion: v1
kind: Service
metadata:
  labels:
    app: gatewaymetric
  name: gatewaymetric
  namespace: istio-system
spec:
  selector:
    app: gatewaymetric
  ports:
  type: ClusterIP
  ports:
  - name: promethues
    port: 9145
    targetPort: 9145
  - name: grpc
    port: 41543
    targetPort: 41543
Copy the code

Simple authentication: The port is connected, and metrics of Promethues can be obtained

➜ gatewaymetric kubectl get svc-n istio-system NAME TYPE cluster-ip external-ip PORT(S) gatewaymetric ClusterIP 10.104.182.140 < None > 9145/TCP,41543/TCP ➜ gatewaymetric Telnet 10.104.182.140 41543 Trying 10.104.182.140... Connected to 10.104.182.140. Escape character is'^]'. ➜ gatewaymetric curl 10.104.182.140:9145 / metrics# HELP go_gc_duration_seconds A summary of the GC invocation durations.
# TYPE go_gc_duration_seconds summary
go_gc_duration_seconds{quantile="0"} 0
go_gc_duration_seconds{quantile="0.25"} 0...Copy the code

Now that our Mixer Grpc Adapter has been deployed to our K8S cluster, we need to configure CRD so that Mixer can sense the contents of our Grpc Adapter deployment file, which contains the runtime instance handler of the custom Adapter, Template-> logentity, a run-time instance of instance, and the Mixer’s matching rule specify that the handler handle instance Report data. The purpose is to separate Mixer Adapter developers from operators and to make Mixer Adapter development more flexible. Later sections will elaborate on the significance of each model. If you want to know more about it in advance, please refer to the following links:

Istio. IO/docs/concep…

# handler for adapter gatewaymetric
apiVersion: "config.istio.io/v1alpha2"
kind: handler
metadata:
 name: h1
 namespace: istio-system
spec:
 adapter: gatewaymetric
 connection:
   address: "gatewaymetric.istio-system.svc.cluster.local:41543" #replaces at runtime by the test
 params:
   file_path: "out.txt"
---

# instance for template metric
apiVersion: "config.istio.io/v1alpha2"
kind: instance
metadata:
  name: i1metric
  namespace: istio-system
spec:
  template: logentry
  params:
    severity: '"warning"'
    timestamp: request.time
    variables:
      host: request.host
      method: request.method | ""
      url: request.path | ""
      responseCode: response.code | 0
      responseBodySize: response.size | 0
      responseTotalSize: response.total_size | 0
      latency: response.duration | "0ms"
    monitored_resource_type: '"UNSPECIFIED"'
---

# rule to dispatch to handler h1
apiVersion: "config.istio.io/v1alpha2"
kind: rule
metadata:
  name: r1
  namespace: istio-system
spec:
  actions:
    - handler: h1.istio-system
      instances:
        - i1metric
---
Copy the code

Deploy them in Kubernetes

➜  gatewaymetric kubectl apply -f attributes.yaml 
attributemanifest.config.istio.io/istio-proxy created
attributemanifest.config.istio.io/kubernetes configured
➜  gatewaymetric kubectl apply -fThe template. The yaml template. Config. Istio. IO/logentry created ➜ gatewaymetric kubectl apply-fGatewaymetric. Yaml adapter. Config. Istio. IO/gatewaymetric created ➜ gatewaymetric kubectl apply-f operator_cfg.yaml 
handler.config.istio.io/h1 created
instance.config.istio.io/i1metric created
rule.config.istio.io/r1 created
Copy the code

Use the browser to http://192.168.101.6:31380/productpage, and view the log, Mixer

{"level":"info"."time":"The 2019-02-21 T03:05:40. 292749 z"."instance":"accesslog.logentry.istio-system"."apiClaims":""."apiKey":""."clientTraceId":""."connection_security_policy":"unknown"."destinationApp":""."destinationIp":"10.32.0.34"."destinationName":""."destinationNamespace":""."destinationOwner":""."destinationPrincipal":""."destinationServiceHost":"productpage.default.svc.cluster.local"."destinationWorkload":""."httpAuthority":"192.168.101.6:31380"."latency":"25.101758 ms"."method":"GET"."protocol":"http"."receivedBytes": 488,"referer":""."reporter":"source"."requestId":"405ed7ca-c988-4cfa-8e6a-e808e2cbeab8"."requestSize": 0."requestedServerName":""."responseCode": 200,"responseSize": 5719,"responseTimestamp":"The 2019-02-21 T03:05:40. 317790 z"."sentBytes": 5858,"sourceApp":""."sourceIp":"0.0.0.0"."sourceName":""."sourceNamespace":"istio-system"."sourceOwner":""."sourcePrincipal":""."sourceWorkload":""."url":"/productpage"."userAgent":"Mozilla / 5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.81 Safari/537.36"."xForwardedFor":"10.32.0.1"}
Copy the code

View our custom Grpc Adapter log and see

2019-02-21T03:05:41.002442z info Received request {[&InstanceMsg{Variables:map[string]*istio_policy_v1beta11.Value{host: & Value {Value: & Value_StringValue {StringValue: 192.168.101.6:31380,},}, latency: & Value {Value: & Value_DurationValue {DurationValue: & Duration {Value: 34.547407 ms,},},}, method: &Value{Value:&Value_StringValue{StringValue:GET,},},responseBodySize: &Value{Value:&Value_Int64Value{Int64Value:5719,},},responseCode: &Value{Value:&Value_Int64Value{Int64Value:200,},},responseTotalSize: &Value{Value:&Value_Int64Value{Int64Value:5858,},},url: &Value{Value:&Value_StringValue{StringValue:/productpage,},},},Timestamp:&istio_policy_v1beta11.TimeStamp{Value:2019-02- 21 t03:05:39. 955797905 z,}, Severity: warning, MonitoredResourceType: UNSPECIFIED, MonitoredResourceDimensions: map [string] * isti o_policy_v1beta11.Value{},Name:i1metric.instance.istio-system,} &InstanceMsg{Variables:map[string]*istio_policy_v1beta11.Value{host: & Value {Value: & Value_StringValue {StringValue: 192.168.101.6:31380,},}, latency: & Value {Value: & Value_DurationValue {DurationValue: & Duration {Value: 39.579628 ms,},},}, method: &Value{Value:&Value_StringValue{StringValue:GET,},},responseBodySize: &Value{Value:&Value_Int64Value{Int64Value:5723,},},responseCode: &Value{Value:&Value_Int64Value{Int64Value:200,},},responseTotalSize: &Value{Value:&Value_Int64Value{Int64Value:5862,},},url: &Value{Value:&Value_StringValue{StringValue:/productpage,},},},Timestamp:&istio_policy_v1beta11.TimeStamp{Value:2019-02- 21 t03:05:40. 126271976 z,}, Severity: warning, MonitoredResourceType: UNSPECIFIED, MonitoredResourceDimensions: map [string] * isti o_policy_v1beta11.Value{},Name:i1metric.instance.istio-system,} &InstanceMsg{Variables:map[string]*istio_policy_v1beta11.Value{host: & Value {Value: & Value_StringValue {StringValue: 192.168.101.6:31380,},}, latency: & Value {Value: & Value_DurationValue {DurationValue: & Duration {Value: 24.084598 ms,},},}, method: &Value{Value:&Value_StringValue{StringValue:GET,},},responseBodySize: &Value{Value:&Value_Int64Value{Int64Value:5719,},},responseCode: &Value{Value:&Value_Int64Value{Int64Value:200,},},responseTotalSize: &Value{Value:&Value_Int64Value{Int64Value:5858,},},url: &Value{Value:&Value_StringValue{StringValue:/productpage,},},},Timestamp:&istio_policy_v1beta11.TimeStamp{Value:2019-02- 21 t03:05:40. 293294914 z,}, Severity: warning, MonitoredResourceType: UNSPECIFIED, MonitoredResourceDimensions: map [string] * isti o_policy_v1beta11.Value{},Name:i1metric.instance.istio-system,} &InstanceMsg{Variables:map[string]*istio_policy_v1beta11.Value{host: & Value {Value: & Value_StringValue {StringValue: 192.168.101.6:31380,},}, latency: & Value {Value: & Value_DurationValue {DurationValue: & Duration {Value: 30.813597 ms,},},}, method: &Value{Value:&Value_StringValue{StringValue:GET,},},responseBodySize: &Value{Value:&Value_Int64Value{Int64Value:4415,},},responseCode: &Value{Value:&Value_Int64Value{Int64Value:200,},},responseTotalSize: &Value{Value:&Value_Int64Value{Int64Value:4554,},},url: &Value{Value:&Value_StringValue{StringValue:/productpage,},},},Timestamp:&istio_policy_v1beta11.TimeStamp{Value:2019-02- 21 t03:05:40. 55426223 z,}, Severity: warning, MonitoredResourceType: UNSPECIFIED, MonitoredResourceDimensions: map [string] * istio _policy_v1beta11.Value{},Name:i1metric.instance.istio-system,}] &Any{TypeUrl:type.googleapis.com/adapter.gatewaymetric.config.Params,Value:[10 7 111 117 116 46 116 120 116],} 7051031778836507932} 2019-02-21t03:05:41.002468z info host: %! (EXTRA String =192.168.101.6:31380) 2019-02-21T03:05:41.002473z info URL: %! 2019-02-21T03:05:41.002475z info method: %! (EXTRA String =/ productPage) 2019-02-21T03:05:41.002475z info Method: %! (EXTRA string=GET) 2019-02-21t03:05:41.002477z info responseCode: %! ResponseBodySize: %! (EXTRA String =200) 2019-02-21t03:05:41.002479z info responseBodySize: %! ResponseTotalSize: %! (EXTRA int64= 579) 2019-02-21T03:05:41.002483z info responseTotalSize: %! (EXTRA int64=5858) 2019-02-21T03:05:41.00247z info Latency: %! (EXTRAfloat64=0.034547407) 2019-02-21T03:05:41.002500z info host: %! (EXTRA String =192.168.101.6:31380) 2019-02-21T03:05:41.002506z info URL: %! 2019-02-21T03:05:41.002508z info Method: %! (EXTRA String =/ productPage) 2019-02-21T03:05:41.002508z info Method: %! (EXTRA string=GET) 2019-02-21T03:05:41.002510z info responseCode: %! ResponseBodySize: %! (EXTRA String =200) 2019-02-21t03:05:41.002512z info responseBodySize: %! ResponseTotalSize: %! (EXTRA int64=5723) 2019-02-21t03:05:41.002514z info responseTotalSize: %! (EXTRA int64=5862) 2019-02-21T03:05:41.00216z info Latency: %! (EXTRAfloat64=0.039579628) 2019-02-21t03:05:41.002520z info host: %! (EXTRA String =192.168.101.6:31380) 2019-02-21T03:05:41.002522z info URL: %! 2019-02-21T03:05:41.002524z info Method: %! (EXTRA String =/ productPage) 2019-02-21T03:05:41.002524z info Method: %! (EXTRA string=GET) 2019-02-21T03:05:41.002526z info responseCode: %! ResponseBodySize: %! (EXTRA String =200) 2019-02-21t03:05:41.002528z info responseBodySize: %! ResponseTotalSize: %! (EXTRA int64=5719) 2019-02-21t03:05:41.002530z info responseTotalSize: %! (EXTRA int64=5858) 2019-02-21T03:05:41.00264z info Latency: %! (EXTRAfloat64=0.024084598) 2019-02-21T03:05:41.002535z info host: %! (EXTRA String =192.168.101.6:31380) 2019-02-21T03:05:41.002537z info URL: %! 2019-02-21T03:05:41.002538z info Method: %! (EXTRA String =/ productPage) 2019-02-21T03:05:41.002538z info Method: %! (EXTRA string=GET) 2019-02-21t03:05:41.002540z info responseCode: %! ResponseBodySize: %! (EXTRA String =200) 2019-02-21t03:05:41.00254z info responseBodySize: %! ResponseTotalSize: %! (EXTRA int64=4554) 2019-02-21T03:05:41.002547z info Latency: %! (EXTRAfloat64 = 0.030813597)Copy the code

Let’s see if there is data on port 9145 exposed by Promethues

➜ gatewaymetric curl 10.104.182.140:9145 / metrics... http_request_seconds_histogram_bucket{endpoint="/test",fullurl="/productpage",host="192.168.101.6:31380",method="GET",status="200",le="0.00099"} 0
http_request_seconds_histogram_bucket{endpoint="/test",fullurl="/productpage",host="192.168.101.6:31380",method="GET",status="200",le="0.00089"} 0
http_request_seconds_histogram_bucket{endpoint="/test",fullurl="/productpage",host="192.168.101.6:31380",method="GET",status="200",le="0.0007899999999999999"} 0
http_request_seconds_histogram_bucket{endpoint="/test",fullurl="/productpage",host="192.168.101.6:31380",method="GET",status="200",le="0.0006899999999999999"} 0
http_request_seconds_histogram_bucket{endpoint="/test",fullurl="/productpage",host="192.168.101.6:31380",method="GET",status="200",le="0.0005899999999999998"} 0
http_request_seconds_histogram_bucket{endpoint="/test",fullurl="/productpage",host="192.168.101.6:31380",method="GET",status="200",le="0.0004899999999999998"} 0
http_request_seconds_histogram_bucket{endpoint="/test",fullurl="/productpage",host="192.168.101.6:31380",method="GET",status="200",le="0.0003899999999999998"} 0
http_request_seconds_histogram_bucket{endpoint="/test",fullurl="/productpage",host="192.168.101.6:31380",method="GET",status="200",le="0.0002899999999999998"} 0
http_request_seconds_histogram_bucket{endpoint="/test",fullurl="/productpage",host="192.168.101.6:31380",method="GET",status="200",le="0.0001899999999999998"} 0
http_request_seconds_histogram_bucket{endpoint="/test",fullurl="/productpage",host="192.168.101.6:31380",method="GET",status="200",le="-8.999999999999979e-05"} 0
http_request_seconds_histogram_bucket{endpoint="/test",fullurl="/productpage",host="192.168.101.6:31380",method="GET",status="200",le="1.0000000000000216 e-05"} 0
http_request_seconds_histogram_bucket{endpoint="/test",fullurl="/productpage",host="192.168.101.6:31380",method="GET",status="200",le="0.00011000000000000022"} 0
http_request_seconds_histogram_bucket{endpoint="/test",fullurl="/productpage",host="192.168.101.6:31380",method="GET",status="200",le="0.00021000000000000023"} 0
http_request_seconds_histogram_bucket{endpoint="/test",fullurl="/productpage",host="192.168.101.6:31380",method="GET",status="200",le="0.0003100000000000002"} 0
http_request_seconds_histogram_bucket{endpoint="/test",fullurl="/productpage",host="192.168.101.6:31380",method="GET",status="200",le="0.0004100000000000002"} 0
http_request_seconds_histogram_bucket{endpoint="/test",fullurl="/productpage",host="192.168.101.6:31380",method="GET",status="200",le="0.0005100000000000003"} 0
http_request_seconds_histogram_bucket{endpoint="/test",fullurl="/productpage",host="192.168.101.6:31380",method="GET",status="200",le="0.0006100000000000003"} 0
http_request_seconds_histogram_bucket{endpoint="/test",fullurl="/productpage",host="192.168.101.6:31380",method="GET",status="200",le="0.0007100000000000003"} 0
http_request_seconds_histogram_bucket{endpoint="/test",fullurl="/productpage",host="192.168.101.6:31380",method="GET",status="200",le="0.0008100000000000004"} 0
http_request_seconds_histogram_bucket{endpoint="/test",fullurl="/productpage",host="192.168.101.6:31380",method="GET",status="200",le="0.0009100000000000004"} 0
http_request_seconds_histogram_bucket{endpoint="/test",fullurl="/productpage",host="192.168.101.6:31380",method="GET",status="200",le="+Inf"} 34
http_request_seconds_histogram_sum{endpoint="/test",fullurl="/productpage",host="192.168.101.6:31380",method="GET",status="200"1.1806039740000003 http_request_seconds_histogram_count} {the endpoint ="/test",fullurl="/productpage",host="192.168.101.6:31380",method="GET",status="200"} 34
http_request_seconds_histogram_bucket{endpoint="/test",fullurl="/ratings/0",host="ratings:9080",method="GET",status="200",le="0.00099"} 0
http_request_seconds_histogram_bucket{endpoint="/test",fullurl="/ratings/0",host="ratings:9080",method="GET",status="200",le="0.00089"} 0
http_request_seconds_histogram_bucket{endpoint="/test",fullurl="/ratings/0",host="ratings:9080",method="GET",status="200",le="0.0007899999999999999"} 0
http_request_seconds_histogram_bucket{endpoint="/test",fullurl="/ratings/0",host="ratings:9080",method="GET",status="200",le="0.0006899999999999999"} 0
http_request_seconds_histogram_bucket{endpoint="/test",fullurl="/ratings/0",host="ratings:9080",method="GET",status="200",le="0.0005899999999999998"} 0
http_request_seconds_histogram_bucket{endpoint="/test",fullurl="/ratings/0",host="ratings:9080",method="GET",status="200",le="0.0004899999999999998"} 0
http_request_seconds_histogram_bucket{endpoint="/test",fullurl="/ratings/0",host="ratings:9080",method="GET",status="200",le="0.0003899999999999998"} 0
http_request_seconds_histogram_bucket{endpoint="/test",fullurl="/ratings/0",host="ratings:9080",method="GET",status="200",le="0.0002899999999999998"} 0...Copy the code

It means everything is working, have fun!