Chapter 3. Configuring metering
3.1. About configuring metering
A CustomResource
called your MeteringConfig
specifies all the configuration details for your metering installation. When you first install the metering stack, a default MeteringConfig
is generated. Use the examples in the documentation to modify this default file. Keep in mind the following key points:
- At a minimum, you need to configure persistent storage and configure the Hive metastore.
- Most default configuration settings work, but larger deployments or highly customized deployments should review all configuration options carefully.
- Some configuration options can not be modifed after installation.
For configuration options that can be modified after installation, make the changes in your MeteringConfig
and reapply the file.
3.2. Common configuration options
3.2.1. Resource requests and limits
You can adjust the CPU, memory, or storage resource requests and/or limits for pods and volumes. The default-resource-limits.yaml
below provides an example of setting resource request and limits for each component.
apiVersion: metering.openshift.io/v1 kind: MeteringConfig metadata: name: "operator-metering" spec: reporting-operator: spec: resources: limits: cpu: 1 memory: 500Mi requests: cpu: 500m memory: 100Mi presto: spec: coordinator: resources: limits: cpu: 4 memory: 4Gi requests: cpu: 2 memory: 2Gi worker: replicas: 0 resources: limits: cpu: 8 memory: 8Gi requests: cpu: 4 memory: 2Gi hive: spec: metastore: resources: limits: cpu: 4 memory: 2Gi requests: cpu: 500m memory: 650Mi storage: class: null create: true size: 5Gi server: resources: limits: cpu: 1 memory: 1Gi requests: cpu: 500m memory: 500Mi
3.2.2. Node selectors
If you want to run the metering components on specific sets of nodes, then you can set nodeSelectors
on each component to control where each component of metering is scheduled. The node-selectors.yaml
file below provides an example of setting node selectors for each component.
apiVersion: metering.openshift.io/v1 kind: MeteringConfig metadata: name: "operator-metering" spec: reporting-operator: spec: nodeSelector: "node-role.kubernetes.io/infra": "true" presto: spec: coordinator: nodeSelector: "node-role.kubernetes.io/infra": "true" worker: nodeSelector: "node-role.kubernetes.io/infra": "true" hive: spec: metastore: nodeSelector: "node-role.kubernetes.io/infra": "true" server: nodeSelector: "node-role.kubernetes.io/infra": "true"
3.3. Configuring persistent storage
Metering requires persistent storage to persist data collected by the metering-operator
and to store the results of reports. A number of different storage providers and storage formats are supported. Select your storage provider and modify the example configuration files to configure persistent storage for your metering installation.
3.3.1. Storing data in Amazon S3
Metering can use an existing Amazon S3 bucket or create a bucket for storage.
Metering does not manage or delete any S3 bucket data. When uninstalling metering, any S3 buckets used to store metering data must be manually cleaned up.
To use Amazon S3 for storage, edit the spec.storage
section in the example s3-storage.yaml
file below.
apiVersion: metering.openshift.io/v1 kind: MeteringConfig metadata: name: "operator-metering" spec: storage: type: "hive" hive: type: "s3" s3: bucket: "bucketname/path/" 1 region: "us-west-1" 2 secretName: "my-aws-secret" 3 # Set to false if you want to provide an existing bucket, instead of # having metering create the bucket on your behalf. createBucket: true 4
- 1
- Specify the name of the bucket where you would like to store your data. You may optionally specify the path within the bucket.
- 2
- Specify the region of your bucket.
- 3
- The name of a secret in the metering namespace containing the AWS credentials in the
data.aws-access-key-id
anddata.aws-secret-access-key
fields. See the examples that follow for more details. - 4
- Set this field to
false
if you want to provide an existing S3 bucket, or if you do not want to provide IAM credentials that haveCreateBucket
permissions.
Use the example secret below as a template.
The values of the aws-access-key-id
and aws-secret-access-key
must be base64 encoded.
apiVersion: v1 kind: Secret metadata: name: your-aws-secret data: aws-access-key-id: "dGVzdAo=" aws-secret-access-key: "c2VjcmV0Cg=="
You can use the following command to create the secret.
This command automatically base64 encodes your aws-access-key-id
and aws-secret-access-key
values.
oc create secret -n openshift-metering generic your-aws-secret --from-literal=aws-access-key-id=your-access-key --from-literal=aws-secret-access-key=your-secret-key
The aws-access-key-id
and aws-secret-access-key
credentials must have read and write access to the bucket. For an example of an IAM policy granting the required permissions, see the aws/read-write.json
file below.
{ "Version": "2012-10-17", "Statement": [ { "Sid": "1", "Effect": "Allow", "Action": [ "s3:AbortMultipartUpload", "s3:DeleteObject", "s3:GetObject", "s3:HeadBucket", "s3:ListBucket", "s3:ListMultipartUploadParts", "s3:PutObject" ], "Resource": [ "arn:aws:s3:::operator-metering-data/*", "arn:aws:s3:::operator-metering-data" ] } ] }
If you left spec.storage.hive.s3.createBucket
set to true
, or unset, then you should use the aws/read-write-create.json
file below, which contains permissions for creating and deleting buckets.
{ "Version": "2012-10-17", "Statement": [ { "Sid": "1", "Effect": "Allow", "Action": [ "s3:AbortMultipartUpload", "s3:DeleteObject", "s3:GetObject", "s3:HeadBucket", "s3:ListBucket", "s3:CreateBucket", "s3:DeleteBucket", "s3:ListMultipartUploadParts", "s3:PutObject" ], "Resource": [ "arn:aws:s3:::operator-metering-data/*", "arn:aws:s3:::operator-metering-data" ] } ] }
3.3.2. Storing data in S3-compatible storage
To use S3-compatible storage such as Noobaa, edit the spec.storage
section in the example s3-compatible-storage.yaml
file below.
apiVersion: metering.openshift.io/v1 kind: MeteringConfig metadata: name: "operator-metering" spec: storage: type: "hive" hive: type: "s3Compatible" s3Compatible: bucket: "bucketname" 1 endpoint: "http://example:port-number" 2 secretName: "my-aws-secret" 3
Use the example secret below as a template.
apiVersion: v1 kind: Secret metadata: name: your-aws-secret data: aws-access-key-id: "dGVzdAo=" aws-secret-access-key: "c2VjcmV0Cg=="
3.3.3. Storing data in Microsoft Azure
To store data in Azure blob storage you must use an existing container. Edit the spec.storage
section in the example azure-blob-storage.yaml
file below.
apiVersion: metering.openshift.io/v1 kind: MeteringConfig metadata: name: "operator-metering" spec: storage: type: "hive" hive: type: "azure" azure: container: "bucket1" 1 secretName: "my-azure-secret" 2 rootDirectory: "/testDir" 3
Use the example secret below as a template.
apiVersion: v1 kind: Secret metadata: name: your-azure-secret data: azure-storage-account-name: "dGVzdAo=" azure-secret-access-key: "c2VjcmV0Cg=="
You can use the following command to create the secret.
oc create secret -n openshift-metering generic your-azure-secret --from-literal=azure-storage-account-name=your-storage-account-name --from-literal=azure-secret-access-key-your-secret-key
3.3.4. Storing data in Google Cloud Storage
To store your data in Google Cloud Storage you must use an existing bucket. Edit the spec.storage
section in the example gcs-storage.yaml
file below.
apiVersion: metering.openshift.io/v1 kind: MeteringConfig metadata: name: "operator-metering" spec: storage: type: "hive" hive: type: "gcs" gcs: bucket: "metering-gcs/test1" 1 secretName: "my-gcs-secret" 2
Use the example secret below as a template:
apiVersion: v1 kind: Secret metadata: name: your-gcs-secret data: gcs-service-account.json: "c2VjcmV0Cg=="
You can use the following command to create the secret.
oc create secret -n openshift-metering generic your-gcs-secret --from-file gcs-service-account.json=/path/to/your/service-account-key.json
3.4. Configuring the Hive metastore
Hive metastore is responsible for storing all the metadata about the database tables created in Presto and Hive. By default, the metastore stores this information in a local embedded Derby database in a PersistentVolume
attached to the pod.
Generally, the default configuration of the Hive metastore works for small clusters, but users may wish to improve performance or move storage requirements out of cluster by using a dedicated SQL database for storing the Hive metastore data.
3.4.1. Configuring PersistentVolumes
By default, Hive requires one PersistentVolume to operate.
hive-metastore-db-data
is the main PersistentVolumeClaim (PVC) required by default. This PVC is used by the Hive metastore to store metadata about tables, such as table name, columns, and location. Hive metastore is used by Presto and the Hive server to look up table metadata when processing queries. You remove this requirement by using MySQL or PostgreSQL for the Hive metastore database.
To install, Hive metastore requires that dynamic volume provisioning be enabled via a StorageClass, a persistent volume of the correct size must be manually pre-created, or that you use a pre-existing MySQL or PostgreSQL database.
3.4.1.1. Configuring the storage class for Hive metastore
To configure and specify a StorageClass for the hive-metastore-db-data
PVC, specify the StorageClass in your MeteringConfig. An example StorageClass section is included in metastore-storage.yaml
file below.
apiVersion: metering.openshift.io/v1
kind: MeteringConfig
metadata:
name: "operator-metering"
spec:
hive:
spec:
metastore:
storage:
# Default is null, which means using the default storage class if it exists.
# If you wish to use a different storage class, specify it here
# class: "null" 1
size: "5Gi"
- 1
- Uncomment this line and replace
null
with the name of the StorageClass to use. Leaving the valuenull
will cause metering to use the default StorageClass for the cluster.
3.4.1.2. Configuring the volume sizes for the Hive Metastore
Use the metastore-storage.yaml
file below as a template.
apiVersion: metering.openshift.io/v1
kind: MeteringConfig
metadata:
name: "operator-metering"
spec:
hive:
spec:
metastore:
storage:
# Default is null, which means using the default storage class if it exists.
# If you wish to use a different storage class, specify it here
# class: "null"
size: "5Gi" 1
- 1
- Replace the value for
size
with your desired capacity. The example file shows "5Gi".
3.4.2. Use MySQL or PostgreSQL for the Hive metastore
The default installation of metering configures Hive to use an embedded Java database called Derby. This is unsuited for larger environments and can be replaced with either a MySQL or PostgreSQL database. Use the following example configuration files if your deployment requires a MySQL or PostgreSQL database for Hive.
There are 4 configuration options you can use to control the database used by Hive metastore: url, driver, username, and password.
Use the example configuration file below to use a MySQL database for Hive:
spec: hive: spec: metastore: storage: create: false config: db: url: "jdbc:mysql://mysql.example.com:3306/hive_metastore" driver: "com.mysql.jdbc.Driver" username: "REPLACEME" password: "REPLACEME"
You can pass additional JDBC parameters using the spec.hive.config.url
. For more details see the MySQL Connector/J documentation.
Use the example configuration file below to use a PostgreSQL database for Hive:
spec: hive: spec: metastore: storage: create: false config: db: url: "jdbc:postgresql://postgresql.example.com:5432/hive_metastore" driver: "org.postgresql.Driver" username: "REPLACEME" password: "REPLACEME"
You can pass additional JDBC parameters using the URL. For more details see the PostgreSQL JDBC driver documentation.
3.5. Configuring the reporting-operator
The reporting-operator
is responsible for collecting data from Prometheus, storing the metrics in Presto, running report queries against Presto, and exposing their results via an HTTP API. Configuring the Operator is primarily done through your MeteringConfig
file.
3.5.1. Prometheus connection
When you install metering on OpenShift Container Platform, Prometheus is available at https://prometheus-k8s.openshift-monitoring.svc:9091/.
To secure the connection to Prometheus, the default metering installation uses the OpenShift Container Platform certificate authority. If your Prometheus instance uses a different CA, the CA can be injected through a ConfigMap. See the following example.
spec: reporting-operator: spec: config: prometheus: certificateAuthority: useServiceAccountCA: false configMap: enabled: true create: true name: reporting-operator-certificate-authority-config filename: "internal-ca.crt" value: | -----BEGIN CERTIFICATE----- (snip) -----END CERTIFICATE-----
Alternatively, to use the system certificate authorities for publicly valid certificates, set both useServiceAccountCA
and configMap.enabled
to false
.
The reporting-operator
can also be configured to use a specified bearer token to auth with Prometheus. See the following example.
spec: reporting-operator: spec: config: prometheus: metricsImporter: auth: useServiceAccountToken: false tokenSecret: enabled: true create: true value: "abc-123"
3.5.2. Exposing the reporting API
On OpenShift Container Platform the default metering installation automatically exposes a Route, making the reporting API available. This provides the following features:
- Automatic DNS
- Automatic TLS based on the cluster CA
Also, the default installation makes it possible to use the OpenShift service for serving certificates to protect the reporting API with TLS. The OpenShift OAuth proxy is deployed as a side-car container for reporting-operator
, which protects the reporting API with authentication.
3.5.2.1. Using OpenShift Authentication
By default, the reporting API is secured with TLS and authentication. This is done by configuring the reporting-operator
to deploy a pod containing both the reporting-operator’s
container, and a sidecar container running OpenShift auth-proxy.
In order to access the reporting API, the metering operator exposes a route. Once that route has been installed, you can run the following command to get the route’s hostname.
METERING_ROUTE_HOSTNAME=$(oc -n openshift-metering get routes metering -o json | jq -r '.status.ingress[].host')
Next, set up authentication using either a service account token or basic authentication with a username/password.
3.5.2.1.1. Authenticate using a service account token
With this method, you use the token in the reporting Operator’s service account, and pass that bearer token to the Authorization header in the following command:
TOKEN=$(oc -n openshift-metering serviceaccounts get-token reporting-operator) curl -H "Authorization: Bearer $TOKEN" -k "https://$METERING_ROUTE_HOSTNAME/api/v1/reports/get?name=[Report Name]&namespace=openshift-metering&format=[Format]"
Be sure to replace the name=[Report Name]
and format=[Format]
parameters in the URL above. The format
parameter can be json, csv, or tabular.
3.5.2.1.2. Authenticate using a username and password
We are able to do basic authentication using a username and password combination, which is specified in the contents of a htpasswd file. By default, we create a secret containing an empty htpasswd data. You can, however, configure the reporting-operator.spec.authProxy.htpasswd.data
and reporting-operator.spec.authProxy.htpasswd.createSecret
keys to use this method.
Once you have specified the above in your MeteringConfig, you can run the following command:
curl -u testuser:password123 -k "https://$METERING_ROUTE_HOSTNAME/api/v1/reports/get?name=[Report Name]&namespace=openshift-metering&format=[Format]"
Be sure to replace testuser:password123
with a valid username and password combination.
3.5.2.2. Manually Configuring Authentication
In order to manually configure, or disable OAuth in the reporting-operator
, you must set spec.tls.enabled: false
in your MeteringConfig.
This also disables all TLS/authentication between the reporting-operator
, presto, and hive. You would need to manually configure these resources yourself.
Authentication can be enabled by configuring the following options. Enabling authentication configures the reporting-operator
pod to run the OpenShift auth-proxy as a sidecar container in the pod. This adjusts the ports so that the reporting-operator
API isn’t exposed directly, but instead is proxied to via the auth-proxy sidecar container.
- reporting-operator.spec.authProxy.enabled
- reporting-operator.spec.authProxy.cookie.createSecret
- reporting-operator.spec.authProxy.cookie.seed
You need to set reporting-operator.spec.authProxy.enabled
and reporting-operator.spec.authProxy.cookie.createSecret
to true
and reporting-operator.spec.authProxy.cookie.seed
to a 32-character random string.
You can generate a 32-character random string using the following command.
$ openssl rand -base64 32 | head -c32; echo.
3.5.2.2.1. Token authentication
When the following options are set to true
, authentication using a bearer token is enabled for the reporting REST API. Bearer tokens can come from serviceAccounts or users.
- reporting-operator.spec.authProxy.subjectAccessReview.enabled
- reporting-operator.spec.authProxy.delegateURLs.enabled
When authentication is enabled, the Bearer token used to query the reporting API of the user or serviceAccount
must be granted access using one of the following roles:
- report-exporter
- reporting-admin
- reporting-viewer
- metering-admin
- metering-viewer
The metering-operator
is capable of creating RoleBindings for you, granting these permissions by specifying a list of subjects in the spec.permissions
section. For an example, see the following advanced-auth.yaml
example configuration.
apiVersion: metering.openshift.io/v1 kind: MeteringConfig metadata: name: "operator-metering" spec: permissions: # anyone in the "metering-admins" group can create, update, delete, etc any # metering.openshift.io resources in the namespace. # This also grants permissions to get query report results from the reporting REST API. meteringAdmins: - kind: Group name: metering-admins # Same as above except read only access and for the metering-viewers group. meteringViewers: - kind: Group name: metering-viewers # the default serviceaccount in the namespace "my-custom-ns" can: # create, update, delete, etc reports. # This also gives permissions query the results from the reporting REST API. reportingAdmins: - kind: ServiceAccount name: default namespace: my-custom-ns # anyone in the group reporting-readers can get, list, watch reports, and # query report results from the reporting REST API. reportingViewers: - kind: Group name: reporting-readers # anyone in the group cluster-admins can query report results # from the reporting REST API. So can the user bob-from-accounting. reportExporters: - kind: Group name: cluster-admins - kind: User name: bob-from-accounting reporting-operator: spec: authProxy: # htpasswd.data can contain htpasswd file contents for allowing auth # using a static list of usernames and their password hashes. # # username is 'testuser' password is 'password123' # generated htpasswdData using: `htpasswd -nb -s testuser password123` # htpasswd: # data: | # testuser:{SHA}y/2sYAj5yrQIN4TL0YdPdmGNKpc= # # change REPLACEME to the output of your htpasswd command htpasswd: data: | REPLACEME
Alternatively, you can use any role which has rules granting get
permissions to reports/export
. This means get
access to the export
sub-resource of the Report resources in the namespace of the reporting-operator
. For example: admin
and cluster-admin
.
By default, the reporting-operator
and metering-operator
serviceAccounts
both have these permissions, and their tokens can be used for authentication.
3.5.2.2.2. Basic authentication (username/password)
For basic authentication you can supply a username and password in reporting-operator.spec.authProxy.htpasswd.data
. The username and password must be the same format as those found in an htpasswd file. When set, you can use HTTP basic authentication to provide your username and password that has a corresponding entry in the htpasswdData
contents.
3.6. Configure AWS billing correlation
Metering can correlate cluster usage information with AWS detailed billing information, attaching a dollar amount to resource usage. For clusters running in EC2, you can enable this by modifying the example aws-billing.yaml
file below.
apiVersion: metering.openshift.io/v1 kind: MeteringConfig metadata: name: "operator-metering" spec: openshift-reporting: spec: awsBillingReportDataSource: enabled: true # Replace these with where your AWS billing reports are # stored in S3. bucket: "<your-aws-cost-report-bucket>" 1 prefix: "<path/to/report>" region: "<your-buckets-region>" reporting-operator: spec: config: aws: secretName: "<your-aws-secret>" 2 presto: spec: config: aws: secretName: "<your-aws-secret>" 3 hive: spec: config: aws: secretName: "<your-aws-secret>" 4
To enable AWS billing correlation, first ensure the AWS Cost and Usage Reports are enabled. For more information, see Turning on the AWS Cost and Usage Report in the AWS documentation.
- 1
- Update the bucket, prefix, and region to the location of your AWS Detailed billing report.
- 2 3 4
- All
secretName
fields should be set to the name of a secret in the metering namespace containing AWS credentials in thedata.aws-access-key-id
anddata.aws-secret-access-key
fields. See the example secret file below for more details.
apiVersion: v1 kind: Secret metadata: name: <your-aws-secret> data: aws-access-key-id: "dGVzdAo=" aws-secret-access-key: "c2VjcmV0Cg=="
To store data in S3, the aws-access-key-id
and aws-secret-access-key
credentials must have read and write access to the bucket. For an example of an IAM policy granting the required permissions, see the aws/read-write.json
file below.
{ "Version": "2012-10-17", "Statement": [ { "Sid": "1", "Effect": "Allow", "Action": [ "s3:AbortMultipartUpload", "s3:DeleteObject", "s3:GetObject", "s3:HeadBucket", "s3:ListBucket", "s3:ListMultipartUploadParts", "s3:PutObject" ], "Resource": [ "arn:aws:s3:::operator-metering-data/*", 1 "arn:aws:s3:::operator-metering-data" 2 ] } ] } { "Version": "2012-10-17", "Statement": [ { "Sid": "1", "Effect": "Allow", "Action": [ "s3:AbortMultipartUpload", "s3:DeleteObject", "s3:GetObject", "s3:HeadBucket", "s3:ListBucket", "s3:ListMultipartUploadParts", "s3:PutObject" ], "Resource": [ "arn:aws:s3:::operator-metering-data/*", 3 "arn:aws:s3:::operator-metering-data" 4 ] } ] }
This can be done either pre-installation or post-installation. Disabling it post-installation can cause errors in the reporting-operator
.