DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Good Data, Bad Metric: A Mutation Testing Pattern for Analytics Engineering
  • Evaluating SOC Effectiveness Using Detection Coverage and Response Metrics
  • Governing Identity Under Uncertainty: Experimentation and Incrementality in Modern Programmatic Advertising
  • Infrastructure as Code Is Not Enough

Trending

  • The Missing `bandit` for AI Agents: How I Built a Static Analyzer for Prompt Injection
  • Identity in Action
  • Building AI-Powered Java Applications With Jakarta EE and LangChain4j
  • Building Threat Intelligence Pipelines Using Python, APIs, and Elasticsearch
  1. DZone
  2. Testing, Deployment, and Maintenance
  3. Deployment
  4. Utilize OpenShift to Manage External Services Metrics

Utilize OpenShift to Manage External Services Metrics

Openshift 4 has great metrics monitor suites used to monitor and create dashboards for infra and application layer services; we can leverage that to manage external services and infra as well.

By 
Ryan ZhangCheng user avatar
Ryan ZhangCheng
·
Apr. 22, 21 · Tutorial
Likes (2)
Comment
Save
Tweet
Share
7.1K Views

Join the DZone community and get the full member experience.

Join For Free

Why

Openshift 4 provided great metrics monitor suites, we can use them to monitor and create dashboards for both infra and application layer services; What's more, we can leverage that to manage external services and infra as well.

The benefits why I want to address this issue are:

  1. Establish and maintaining a sophisticated monitoring solution can be very hard and time-consuming.
  2. The monitoring components are almost coming free with embedded in Openshift. They are managed by the Openshift Cluster Monitoring operator which is stable, self-healing, and well-structured.
  3. Manage and scale infra configuration like monitoring components in OpenShift is easier than doing it in VM because of its declarative nature and we can even manage them by GitOps.
  4. Of course, if you have both the OpenShift Platform to manage the container world and the VM world to manage other businesses, you don't have to manage two complicated Monitoring solutions for time and cost-saving.

What

In this article I'm going to cover the following topic in order to demonstrate how to monitor external services on OpenShift Monitoring Component:

  1. Exporting Quarkus applications via MicroProfile metrics.
  2. Configuring OpenShift to enable user-defined monitoring components.
  3. Proxy external service in Openshift via Kubernetes service.
  4. Create My Grafana Instance to host application dashboard for external service metrics.
  5. (Optional) Utilize node exporter to monitor external infra metrics.

Although the issue I am addressing is targeted to external services, you can surely apply the same steps for your applications hosted in OpenShift.

How

Exporting Quarkus Applications by Micro Profile Metrics

In this lab I'm going to use the Quarkus framework to demonstrate the application metric monitoring, the application example is a quarkus-todo-application in my GitHub repo.

Quarkus application supports 2 ways to export metrics:

  1. MicroProfile metrics.
  2. Micrometer metrics.

I'm using the MicroProfile metric.

The key part of exporting metrics in a quarkus application are:

Markdown
 




xxxxxxxxxx
1
32


 
1
## Quarkus MicroPofile metrics How to
2
1. Add smallrye dependencies
3
```xml
4
       <dependency>
5
            <groupId>io.quarkus</groupId>
6
            <artifactId>quarkus-smallrye-metrics</artifactId>
7
        </dependency>
8
```
9
2. Add metric for your rest api method
10
```java
11
   @GET
12
    @Path("/{id}")
13
    @Counted(name= "getOneTask", description = "How many get method being triggered.")
14
    @Timed(name = "getOneTaskTimer", description = "How long get one task perform", unit = MetricUnits.MILLISECONDS)
15
    public Todo getOne(@PathParam("id") Long id) {  ...  }
16
 
17
    @GET
18
    @Path("/{number}")
19
    @Produces(MediaType.TEXT_PLAIN)
20
    @Counted(name = "performedChecks", description = "How many primality checks have been performed.")
21
    @Timed(name = "checksTimer", description = "A measure of how long it takes to perform the primality test.", unit = MetricUnits.MILLISECONDS)
22
    public String checkIfPrime(@PathParam("number") long number) {...}
23
```
24
3. Configure quarkus to export metrics to /metrics
25

          
26
By default MicroProfile would export metrics at /q/metrics instead of **/metrics**.
27
Since prometheus is expecting endpint /metrics, we must explicit configure quarkus to change the metric rest path
28

          
29
```properties
30
#application.properties
31
quarkus.smallrye-metrics.path=/metrics
32
```



Build and Deploy

If you are familiar with build and dev concepts, you can directly get a binary image in my quay.io repo.

Here are the steps to deploy the Todo service on a virtual machine.

My target VM IP is

192.168.2.10 OS: rhel7

#Execute on my laptop
mvn quarkus:dev
#Test my metrics is actual exporting
curl http://localhost:8080/metrics|grep Prime
application_io_quarkus_sample_PrimeNumberChecker_checksTimer_rate_per_second gauge
application_io_quarkus_sample_PrimeNumberChecker_checksTimer_rate_per_second 9...
#Build container images and push into a remote repo, you need to change to your accessible repo
podman build -f src/main/docker/Dockerfile.ubi . -t quay.io/rzhang/quarkus:todo-app-jvm-11-nodb
# log into my target virtual machine 192.168.2.10
ssh 192.168.2.10
podman run -d --name todo-app -p 8080:8080 quay.io/rzhang/quarkus:todo-app-jvm-11-nodb
curl http://192.168.2.10:8080/metrics|grep Prime
application_io_quarkus_sample_PrimeNumberChecker_checksTimer_rate_per_second gauge
application_io_quarkus_sample_PrimeNumberChecker_checksTimer_rate_per_second 9...


OK, the application is deployed in a VM and metrics have been exported to: http://192.168.2.10:8080/metrics

Let's see how to configure OpenShift to collect these metrics.

Configuring OpenShift to Enable User-defined Monitoring Components

First, let's have a briefing on how Monitoring components are organized in OpenShift.

Monitoring Component Organization

User-Defined Project's metric would be managed by the right part of Monitoring components (i.e., openshift-user-workload-monitoring).

On the left side, all OpenShift Infra-related metrics would be managed by openshift-monitoring namespaces, so they are well separated and have different storage and components for Platform and User-defined.

There are few components that are shared between Platform and User-Defined monitoring components.

Thanos Querier  —  Aggregates both Platform metrics and User-Defined and provide a unique query interface for searching metrics; In the next part of Grafana configuration, we would use the Thanos Querier URL to display the metrics;

AlertManager  —  Receiving alert from both sides of Prometheus and sending alert to the external system;

Cluster Monitoring Operator - Provides easy install and maintenance of monitoring components;

The left part is installed out of the box if you installed OpenShift 4.

However, the right part would not be installed by default. We would utilize the User-defined monitoring components to manage the external services metrics. And the steps are the same if you want to manage your own application metrics which run in OpenShift instead of outside.

To enable user-workload-monitoring:

oc apply -f cluster-monitoring-config.yaml


cluster-monitoring-config.yaml

Markdown
 




xxxxxxxxxx
1
11


 
1
```yaml
2
apiVersion: v1
3
kind: ConfigMap
4
metadata:
5
  name: cluster-monitoring-config
6
  namespace: openshift-monitoring
7
data:
8
  config.yaml: |
9
    enableUserWorkload: true
10

          
11
```



After enabling this, you can see that a new namespace and related monitoring component would be created in these new namespaces:

>oc projects|grep monitoring
openshift-monitoring
openshift-user-workload-monitoring
>oc get po -n openshift-user-workload-monitoring
NAME READY STATUS RESTARTS AGE
prometheus-operator-6bf7fbbbdd-m8fsl 2/2 Running 0 9d
prometheus-user-workload-0 5/5 Running 0 23d
prometheus-user-workload-1 5/5 Running 0 23d
thanos-ruler-user-workload-0 3/3 Running 1 23d
thanos-ruler-user-workload-1 3/3 Running 1 23d

OK, now Openshift User-Defined Monitoring components have been ready.

Let's move on and create a new namespace to host a proxy to external services metrics.

Proxy External Service in OpenShift via Kubernetes Service

For readers who are familiar with the following concepts, you can just check my lab code at https://github.com/ryanzhang/openshift-monitor-external-service.

1. Create a new project to host my proxy and metrics collecting configuration for external metrics and configuration.

>oc new-project external-service


2. Create a Kubernetes service to integrate external service which points to external metric rest endpoints.

Markdown
 




xxxxxxxxxx
1
70


 
1
### a. Create Proxy service pointing external service
2
```bash
3
oc apply -f external-service-proxy.yaml
4
```
5
```yaml
6
apiVersion: v1
7
kind: Service
8
metadata:
9
  labels:
10
    external-service-monitor: "true"
11
  name: external-service-monitor <- *It would match the followed endpoints names*
12
  namespace: external-service
13
spec:
14
  ports:
15
  - name: web
16
    port: 8080
17
    protocol: TCP
18
    targetPort: 8080
19
    nodeport: 0
20
  selector: {} <-*It needs to none*
21
  sessionAffinity: None
22
  type: ClusterIP
23
---
24
kind: "Endpoints"
25
apiVersion: "v1"
26
metadata:
27
  name: "external-service-monitor" 
28
subsets:  <-**Use this to specify an external service through IP**
29
  - addresses:
30
    - ip: "192.168.2.10" 
31
    ports:
32
      - port: 8080  <- *Point to our todo-app service port*
33
        name: "web"
34
```
35
### b. Tell OpenShift User Workload monitor where to look for collecting metrics
36
```
37
oc apply -f todo-app-metric-service-monitor.yaml
38
```
39
```yaml
40
apiVersion: monitoring.coreos.com/v1
41
kind: ServiceMonitor
42
metadata:
43
  name: app-prometheus-external-service
44
  namespace: external-service
45
spec:
46
  endpoints:
47
  - interval: 30s <- Set interval to every 30 seconds to collect the metrics from external service endpoints
48
    port: web
49
    scheme: http
50
  selector:
51
    matchLabels:
52
      external-app-monitor: "true" <-Select svc by match this label, we already mark this label in above service
53
```
54

          
55
## c. Check the service pointingto external endpoints
56
```
57
 oc describe svc ext-app-metric-todo-app
58
Name:              ext-app-metric-todo-app
59
Namespace:         external-service
60
Labels:            app.kubernetes.io/managed-by=Helm
61
                   external-app-monitor=true <-User-Defined Monitoring would use this label to collect this service metrics 
62
Selector:          <none>
63
Type:              ClusterIP
64
IP:                10.217.5.220
65
Port:              web  8080/TCP
66
TargetPort:        8080/TCP
67
Endpoints:         192.168.2.10:8080 <- Correct!
68
Session Affinity:  None
69
Events:            <none>
70
```



Now you can monitor the external metric in the embedded dashboard:

First trigger some load via ab test tools:

Trigger some load via ab test tools

Search metrics in OpenShift integrated UI:

Search metrics in OpenShift integrated UI

Create Grafana Instance to Display External Service Metrics

Wouldn't it be great if we can view our user-defined metric in Grafana?

Although OpenShift has installed Grafana out of the box, they are not supposed to be used by user-defined workloads. Currently, there is no way to edit and add a user-defined dashboard or create more user accounts for the default Grafana instance.

So let me show you how to install a user-defined Grafana to integrate our own metrics.

Install the Grafana Operator Into my-grafana Namespaces

1. oc new-project my-grafana

Install grafana operator into my-grafana namespace

2. Create a my-grafana instance to host my metrics dashboards:

Markdown
 




xxxxxxxxxx
1
69


 
1
##  create  my-grafana Customer Resources
2

          
3
```yaml
4
apiVersion: integreatly.org/v1alpha1
5
kind: Grafana
6
metadata:
7
  name: my-grafana
8
  namespace: my-grafana
9
spec:
10
  config:
11
    auth:
12
      disable_signout_menu: false
13
    auth.anonymous:
14
      enabled: true
15
    log:
16
      level: warn
17
      mode: console
18
    security:
19
      admin_password: admin <-1. this is your frist time login password
20
      admin_user: admin
21
  dashboardLabelSelector:
22
  - matchExpressions:
23
    - key: app
24
      operator: In
25
      values:
26
      - grafana
27
  dataStorage:
28
    labels: # Additional labels for the PVC
29
      app: grafana
30
    annotations: # Additional annotations for the PVC
31
      app: grafana
32
    accessModes: # An array of access modes, e.g. `ReadWriteOnce`
33
    - ReadWriteMany
34
    size: '10Gi'        # Requested size, e.g. `10Gi`
35
    class: "" <-2. you can input StorageClass Name if there is available 
36
  ingress:
37
    enabled: true
38
    hostname: my-grafana.apps-crc.testing <- 3. You need to input your own subdomain here.
39

          
40
```
41
```
42
oc apply -f my-grafana-cr.yaml
43
oc get po
44
NAME                                  READY   STATUS    RESTARTS   AGE
45
grafana-deployment-789d66454d-xkdwk   1/1     Running   0          23d
46
grafana-operator-5bddbfb9f9-x72jv     1/1     Running   0          24d
47

          
48
oc get route
49
NAME            HOST/PORT                     PATH   SERVICES          PORT   TERMINATION   WILDCARD
50
grafana-route   my-grafana.apps-crc.testing          grafana-service   3000   edge          None
51
```
52
## Configure the cluster-monitor-view-rolebinding
53
```yaml
54
apiVersion: rbac.authorization.k8s.io/v1
55
kind: ClusterRoleBinding
56
metadata:
57
  name: cluster-monitoring-view
58
roleRef:
59
  apiGroup: rbac.authorization.k8s.io
60
  kind: ClusterRole
61
  name: cluster-monitoring-view
62
subjects:
63
- kind: ServiceAccount
64
  name: grafana-serviceaccount <- Bind the grafana-serviceaccount to cluster role: cluster-monitoring-view
65
  namespace: my-grafana
66
```
67
```bash
68
oc apply -f cluster-monitoring-view-clusterrolebinding.yaml
69
```



Now you can access my-grafana instance via: https://my-grafana.apps-crc.testing/

Login in with admin/admin.

Add my todo-app quarkus MicroProfile Metrics dashboard.

To find more information on how to generate MicroProfile Metrics for your application, I recommend you to check this: https://github.com/jamesfalkner/microprofile-grafana

Here we go:

MicroProfile Metrics

(I also trigger a load test at the backend for monitoring the metrics.)

What's more, you could monitor external infra metrics by utilizing the node_exporter process.

(Optional) Utilize Node Exporter to Monitor External Infra Metrics

Please follow Prometheus official documentation to install node_exporter to your VM or bare metal, then you would have the metrics available at, for example in my case:

http://192.168.2.10:9100

Repeat the above steps, or take a look at the YAML resource in my GitHub repo:

You would get the external infra metrics managed in user-defined monitoring components.

Here is the node_exporter dashboard I used in the following graph.

node_exporter Dashboard

OpenShift monitoring components are easy to install and operate. I hope it's useful to show you that we can not only integrate the container-based workload's metrics inside OpenShift but also external services and infra metrics outside OpenShift.

Metric (unit) OpenShift

Opinions expressed by DZone contributors are their own.

Related

  • Good Data, Bad Metric: A Mutation Testing Pattern for Analytics Engineering
  • Evaluating SOC Effectiveness Using Detection Coverage and Response Metrics
  • Governing Identity Under Uncertainty: Experimentation and Incrementality in Modern Programmatic Advertising
  • Infrastructure as Code Is Not Enough

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook