From a1ee8bb3bc03e753ba490096870407e1fac0f981 Mon Sep 17 00:00:00 2001 From: abavage Date: Mon, 22 Jun 2026 11:41:38 +1000 Subject: [PATCH 1/5] new: add amazon-cloudwatch-observability chart --- .../.helmignore | 23 + .../Chart.yaml | 8 + .../amazon-cloudwatch-observability/README.md | 192 + ...aws.amazon.com_amazoncloudwatchagents.yaml | 9207 +++++++++++++++++ ...oudwatch.aws.amazon.com_dcgmexporters.yaml | 3263 ++++++ ...watch.aws.amazon.com_instrumentations.yaml | 1765 ++++ ...udwatch.aws.amazon.com_neuronmonitors.yaml | 3274 ++++++ .../images/cw-1.png | Bin 0 -> 246828 bytes .../images/cw-2.png | Bin 0 -> 318543 bytes .../templates/_helpers.tpl | 745 ++ .../operator-webhook-with-cert-manager.yaml | 273 + .../admission-webhooks/operator-webhook.yaml | 291 + .../templates/certmanager.yaml | 176 + .../cloudwatch-agent-clusterrole.yaml | 43 + .../cloudwatch-agent-clusterrolebinding.yaml | 14 + .../templates/cloudwatch-agent-role.yaml | 16 + .../cloudwatch-agent-rolebinding.yaml | 17 + .../cloudwatch-agent-serviceaccount.yaml | 9 + ...tainer-insights-cluster-scraper-config.tpl | 409 + .../linux/_otel-container-insights-config.tpl | 988 ++ .../cloudwatch-agent-custom-resource.yaml | 292 + .../linux/dcgm-exporter-daemonset.yaml | 74 + .../templates/linux/dcgm-exporter-role.yaml | 14 + .../linux/dcgm-exporter-rolebinding.yaml | 17 + .../templates/linux/fluent-bit-configmap.yaml | 22 + .../templates/linux/fluent-bit-daemonset.yaml | 133 + .../linux/kube-state-metrics-clusterrole.yaml | 44 + ...kube-state-metrics-clusterrolebinding.yaml | 16 + .../templates/linux/kube-state-metrics.yaml | 120 + .../linux/neuron-monitor-daemonset.yaml | 99 + .../linux/neuron-monitor-exporter-role.yaml | 14 + .../neuron-monitor-exporter-rolebinding.yaml | 17 + .../linux/node-exporter-daemonset.yaml | 127 + .../templates/linux/node-exporter-role.yaml | 14 + .../linux/node-exporter-rolebinding.yaml | 17 + .../namespace.amazon-cloudwatch.yaml | 10 + .../templates/operator-clusterrole.yaml | 56 + .../operator-clusterrolebinding.yaml | 14 + .../templates/operator-deployment.yaml | 78 + .../templates/operator-service.yaml | 15 + .../templates/operator-serviceaccount.yaml | 7 + .../cloudwatch-agent-scc-clusterrole.yaml | 10 + .../templates/rosa/cloudwatch-agent-scc.yaml | 38 + ...oudwatch-agent-ssc-clusterrolebinding.yaml | 14 + .../target-allocator-clusterrole.yaml | 33 + .../target-allocator-clusterrolebinding.yaml | 21 + ...-windows-container-insights-daemonset.yaml | 49 + .../cloudwatch-agent-windows-daemonset.yaml | 42 + .../windows/fluent-bit-windows-configmap.yaml | 21 + .../windows/fluent-bit-windows-daemonset.yaml | 75 + .../tests/flag_matrix.sh | 190 + .../values.yaml | 1156 +++ 52 files changed, 23562 insertions(+) create mode 100644 charts/amazon-cloudwatch-observability/.helmignore create mode 100644 charts/amazon-cloudwatch-observability/Chart.yaml create mode 100644 charts/amazon-cloudwatch-observability/README.md create mode 100644 charts/amazon-cloudwatch-observability/crds/cloudwatch.aws.amazon.com_amazoncloudwatchagents.yaml create mode 100644 charts/amazon-cloudwatch-observability/crds/cloudwatch.aws.amazon.com_dcgmexporters.yaml create mode 100644 charts/amazon-cloudwatch-observability/crds/cloudwatch.aws.amazon.com_instrumentations.yaml create mode 100644 charts/amazon-cloudwatch-observability/crds/cloudwatch.aws.amazon.com_neuronmonitors.yaml create mode 100644 charts/amazon-cloudwatch-observability/images/cw-1.png create mode 100644 charts/amazon-cloudwatch-observability/images/cw-2.png create mode 100644 charts/amazon-cloudwatch-observability/templates/_helpers.tpl create mode 100644 charts/amazon-cloudwatch-observability/templates/admission-webhooks/operator-webhook-with-cert-manager.yaml create mode 100644 charts/amazon-cloudwatch-observability/templates/admission-webhooks/operator-webhook.yaml create mode 100644 charts/amazon-cloudwatch-observability/templates/certmanager.yaml create mode 100644 charts/amazon-cloudwatch-observability/templates/cloudwatch-agent-clusterrole.yaml create mode 100644 charts/amazon-cloudwatch-observability/templates/cloudwatch-agent-clusterrolebinding.yaml create mode 100644 charts/amazon-cloudwatch-observability/templates/cloudwatch-agent-role.yaml create mode 100644 charts/amazon-cloudwatch-observability/templates/cloudwatch-agent-rolebinding.yaml create mode 100644 charts/amazon-cloudwatch-observability/templates/cloudwatch-agent-serviceaccount.yaml create mode 100644 charts/amazon-cloudwatch-observability/templates/linux/_otel-container-insights-cluster-scraper-config.tpl create mode 100644 charts/amazon-cloudwatch-observability/templates/linux/_otel-container-insights-config.tpl create mode 100644 charts/amazon-cloudwatch-observability/templates/linux/cloudwatch-agent-custom-resource.yaml create mode 100644 charts/amazon-cloudwatch-observability/templates/linux/dcgm-exporter-daemonset.yaml create mode 100644 charts/amazon-cloudwatch-observability/templates/linux/dcgm-exporter-role.yaml create mode 100644 charts/amazon-cloudwatch-observability/templates/linux/dcgm-exporter-rolebinding.yaml create mode 100644 charts/amazon-cloudwatch-observability/templates/linux/fluent-bit-configmap.yaml create mode 100644 charts/amazon-cloudwatch-observability/templates/linux/fluent-bit-daemonset.yaml create mode 100644 charts/amazon-cloudwatch-observability/templates/linux/kube-state-metrics-clusterrole.yaml create mode 100644 charts/amazon-cloudwatch-observability/templates/linux/kube-state-metrics-clusterrolebinding.yaml create mode 100644 charts/amazon-cloudwatch-observability/templates/linux/kube-state-metrics.yaml create mode 100644 charts/amazon-cloudwatch-observability/templates/linux/neuron-monitor-daemonset.yaml create mode 100644 charts/amazon-cloudwatch-observability/templates/linux/neuron-monitor-exporter-role.yaml create mode 100644 charts/amazon-cloudwatch-observability/templates/linux/neuron-monitor-exporter-rolebinding.yaml create mode 100644 charts/amazon-cloudwatch-observability/templates/linux/node-exporter-daemonset.yaml create mode 100644 charts/amazon-cloudwatch-observability/templates/linux/node-exporter-role.yaml create mode 100644 charts/amazon-cloudwatch-observability/templates/linux/node-exporter-rolebinding.yaml create mode 100644 charts/amazon-cloudwatch-observability/templates/namespace.amazon-cloudwatch.yaml create mode 100644 charts/amazon-cloudwatch-observability/templates/operator-clusterrole.yaml create mode 100644 charts/amazon-cloudwatch-observability/templates/operator-clusterrolebinding.yaml create mode 100644 charts/amazon-cloudwatch-observability/templates/operator-deployment.yaml create mode 100644 charts/amazon-cloudwatch-observability/templates/operator-service.yaml create mode 100644 charts/amazon-cloudwatch-observability/templates/operator-serviceaccount.yaml create mode 100644 charts/amazon-cloudwatch-observability/templates/rosa/cloudwatch-agent-scc-clusterrole.yaml create mode 100644 charts/amazon-cloudwatch-observability/templates/rosa/cloudwatch-agent-scc.yaml create mode 100644 charts/amazon-cloudwatch-observability/templates/rosa/cloudwatch-agent-ssc-clusterrolebinding.yaml create mode 100644 charts/amazon-cloudwatch-observability/templates/target-allocator-clusterrole.yaml create mode 100644 charts/amazon-cloudwatch-observability/templates/target-allocator-clusterrolebinding.yaml create mode 100644 charts/amazon-cloudwatch-observability/templates/windows/cloudwatch-agent-windows-container-insights-daemonset.yaml create mode 100644 charts/amazon-cloudwatch-observability/templates/windows/cloudwatch-agent-windows-daemonset.yaml create mode 100644 charts/amazon-cloudwatch-observability/templates/windows/fluent-bit-windows-configmap.yaml create mode 100644 charts/amazon-cloudwatch-observability/templates/windows/fluent-bit-windows-daemonset.yaml create mode 100644 charts/amazon-cloudwatch-observability/tests/flag_matrix.sh create mode 100644 charts/amazon-cloudwatch-observability/values.yaml diff --git a/charts/amazon-cloudwatch-observability/.helmignore b/charts/amazon-cloudwatch-observability/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/charts/amazon-cloudwatch-observability/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/amazon-cloudwatch-observability/Chart.yaml b/charts/amazon-cloudwatch-observability/Chart.yaml new file mode 100644 index 0000000..8f412e2 --- /dev/null +++ b/charts/amazon-cloudwatch-observability/Chart.yaml @@ -0,0 +1,8 @@ +apiVersion: v2 +description: A Helm chart for Amazon CloudWatch Observability +home: https://aws.amazon.com/cloudwatch/ +name: amazon-cloudwatch-observability +sources: +- https://github.com/aws-observability/helm-charts/tree/main/charts/amazon-cloudwatch-observability +type: application +version: 0.0.1 diff --git a/charts/amazon-cloudwatch-observability/README.md b/charts/amazon-cloudwatch-observability/README.md new file mode 100644 index 0000000..97b0e2d --- /dev/null +++ b/charts/amazon-cloudwatch-observability/README.md @@ -0,0 +1,192 @@ +# Amazon CloudWatch Observability + +Helm chart for deploying [Amazon CloudWatch Observability](https://aws.amazon.com/cloudwatch/) on OpenShift (ROSA). It installs the CloudWatch Agent Operator, CloudWatch Agent, Fluent Bit, and supporting components to collect cluster metrics, container logs, and Application Signals telemetry into AWS CloudWatch. + +This chart is a customized fork of the upstream [AWS Helm chart](https://github.com/aws-observability/helm-charts/tree/main/charts/amazon-cloudwatch-observability) (chart version `0.0.4`). + +## Deployment + +The chart is deployed via an Argo CD **multi-source application**. Chart templates live in this repository; cluster-specific values are supplied from the cluster's `infrastructure.yaml` file in the [rosa-helm-config](https://github.com/VG-CTX-StorageUnixServices/awsvicgovprd01-rosa-helm-config/tree/main) repository (for example, `prod/rosaprd01/infrastructure.yaml`). + +Resources are installed into the `amazon-cloudwatch` namespace. + +## AWS IAM Role with Service Account +The following AWS IAM Role (with) Service Account (IRSA) is mandatory for the application to tightly integrate with CloudWatch. + + +### Set the working variables +```bash +export AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) +export OIDC_PROVIDER=$(oc get authentication.config.openshift.io cluster -ojson | jq -r .spec.serviceAccountIssuer | sed 's/https:\/\///') +export CLUSTER_NAME= +``` + +### Create the trustpolicy +```bash +$ cat < ./trust.json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "Federated": "arn:aws:iam::${AWS_ACCOUNT_ID}:oidc-provider/${OIDC_PROVIDER}" + }, + "Action": "sts:AssumeRoleWithWebIdentity", + "Condition": { + "StringEquals": { + "${OIDC_PROVIDER}:sub": [ + "system:serviceaccount:amazon-cloudwatch:cloudwatch-agent" + ] + } + } + } + ] +} +EOF +``` + +### Create the policy +```bash +$ cat < ./policy.json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "allowCloudWatch", + "Effect": "Allow", + "Resource": "arn:aws:logs:*:*:*", + "Action": [ + "logs:CreateLogGroup", + "logs:CreateLogStream", + "logs:DescribeLogGroups", + "logs:DescribeLogStreams", + "logs:PutLogEvents", + "logs:PutRetentionPolicy" + ] + }, + { + "Sid": "allowDescribe", + "Effect": "Allow", + "Resource": "*", + "Action": [ + "ec2:DescribeTags", + "ec2:DescribeVolumes" + ] + } + ] +} +EOF + +$ aws iam create-policy --policy-name amazoncloudwatchobservability --policy-document file://policy.json +``` + +### Create the role, assign the policy and trust policy + +```bash +$ aws iam create-role --role-name "${CLUSTER_NAME}-amazoncloudwatchobservability" --assume-role-policy-document file://trust.json +$ POLICY_ARN=$(aws iam list-policies --query 'Policies[?PolicyName==`amazoncloudwatchobservability`].Arn' --output text) +$ aws iam attach-role-policy --role-name "${CLUSTER_NAME}-amazoncloudwatchobservability" --policy-arn "${POLICY_ARN}" + +``` + +## Required Parameters + +The following values **must** be provided via `infrastructure.yaml`. The chart will fail to render if any are missing or empty. + +| Parameter | Description | Mandatory | +|-----------|-------------|-----------| +| `roleArn` | IAM role ARN assumed by the CloudWatch Agent service account for publishing metrics and logs to CloudWatch | true | +| `clusterName` | Name of the cluster; used as the Container Insights and Application Signals cluster identifier, and in CloudWatch log group paths | true | +| `region` | AWS region where CloudWatch data is sent (for example, `ap-southeast-2`); also selects region-appropriate container images | true | + +### Example `infrastructure.yaml` entry + +```yaml + - chart: amazon-cloudwatch-observability + namespace: amazon-cloudwatch + values: + roleArn: arn:aws:iam::123456789012:role/rosa-cloudwatch-agent + clusterName: rosaprd01 + region: ap-southeast-2 +``` + +### How required parameters are used + +- **`roleArn`** — Annotates the CloudWatch Agent service account with `eks.amazonaws.com/role-arn`, enabling IRSA-style credential federation so the agent can write to CloudWatch without static credentials. +- **`clusterName`** — Populates Container Insights log groups (`/aws/containerinsights//...`), Application Signals `hosted_in`, and OTEL resource attributes. +- **`region`** — Sets the CloudWatch Agent region, Fluent Bit output endpoints, and image registry selection (including GovCloud and China region overrides via `repositoryDomainMap`). + +## Components + +When deployed with default chart values (`k8sMode: ROSA`), the following are installed: + +| Component | Purpose | +|-----------|---------| +| CloudWatch Agent Operator | Manages `AmazonCloudWatchAgent` custom resources and admission webhooks | +| CloudWatch Agent (DaemonSet) | Node-level metrics, Container Insights, and Application Signals collection | +| CloudWatch Agent (Deployment) | Cluster-level metrics scraper (`cloudwatch-agent-cluster-scraper`) | +| Fluent Bit (DaemonSet) | Ships container application, host, and dataplane logs to CloudWatch Logs | +| DCGM Exporter (DaemonSet) | NVIDIA GPU metrics on GPU instance types | +| Neuron Monitor (DaemonSet) | AWS Trainium/Inferentia metrics on supported instance types | + +The following pipelines are enabled by default: + +- **Container Insights** (`containerInsights.enabled: true`) — Legacy Kubernetes metrics via the CloudWatch Agent. +- **Application Signals** (`applicationSignals.enabled: true`) — Application performance monitoring via traces and metrics. +- **Container logs** (`containerLogs.enabled: true`) — Fluent Bit log shipping. + +**OTEL Container Insights** (`otelContainerInsights.enabled: false` by default) is an alternative metrics pipeline using node-exporter and kube-state-metrics. Enable it in `infrastructure.yaml` if required. + +## ROSA-specific configuration + +With `k8sMode: ROSA` (the default), the chart additionally creates: + +- OpenShift Security Context Constraints (SCC) and bindings for the CloudWatch Agent +- ROSA-specific security context and `RUN_IN_ROSA` environment variable on agent pods + +## Optional configuration + +Most settings have sensible defaults in `values.yaml`. Override any of them in `infrastructure.yaml` alongside the required parameters. Common overrides include: + +| Parameter | Default | Description | +|-----------|---------|-------------| +| `k8sMode` | `ROSA` | Platform mode; also supports `EKS` and `K8S` | +| `containerInsights.enabled` | `true` | Legacy Container Insights metrics pipeline | +| `applicationSignals.enabled` | `true` | Application Signals (APM) pipeline | +| `containerLogs.enabled` | `true` | Fluent Bit container log collection | +| `otelContainerInsights.enabled` | `false` | OTEL-based Container Insights pipeline | +| `dcgmExporter.enabled` | `true` | NVIDIA GPU metrics exporter | +| `neuronMonitor.enabled` | `true` | AWS Neuron metrics exporter | + +See `values.yaml` for the full list of configurable values. + +## Verification + +After Argo CD syncs the application, confirm the deployment: + +```bash +# Namespace and operator +oc get pods -n amazon-cloudwatch + +# CloudWatch Agent custom resources +oc get amazoncloudwatchagents -n amazon-cloudwatch + +# Fluent Bit log collection +oc get daemonset -n amazon-cloudwatch -l k8s-app=fluent-bit + +# CloudWatch agent daenonset +oc get daemonset -n amazon-cloudwatch -l app.kubernetes.io/component=amazon-cloudwatch-agent +``` + +In the AWS Console, look for log groups under `/aws/containerinsights//` and metrics in the CloudWatch Container Insights dashboard for the configured region. + +## CloudWatch Sample +![CloudWatch Cluster](images/cw-1.png) +![CloudWatch Pod](images/cw-2.png) + + +## Upstream reference + +- [AWS CloudWatch Observability Helm chart](https://github.com/aws-observability/helm-charts/tree/main/charts/amazon-cloudwatch-observability) +- [Amazon CloudWatch Observability documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/ContainerInsights.html) diff --git a/charts/amazon-cloudwatch-observability/crds/cloudwatch.aws.amazon.com_amazoncloudwatchagents.yaml b/charts/amazon-cloudwatch-observability/crds/cloudwatch.aws.amazon.com_amazoncloudwatchagents.yaml new file mode 100644 index 0000000..9354af6 --- /dev/null +++ b/charts/amazon-cloudwatch-observability/crds/cloudwatch.aws.amazon.com_amazoncloudwatchagents.yaml @@ -0,0 +1,9207 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + argocd.argoproj.io/sync-options: ServerSideApply=true + name: amazoncloudwatchagents.cloudwatch.aws.amazon.com +spec: + group: cloudwatch.aws.amazon.com + names: + kind: AmazonCloudWatchAgent + listKind: AmazonCloudWatchAgentList + plural: amazoncloudwatchagents + shortNames: + - otelcol + - otelcols + singular: amazoncloudwatchagent + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Deployment Mode + jsonPath: .spec.mode + name: Mode + type: string + - description: CloudWatch Agent Version + jsonPath: .status.version + name: Version + type: string + - jsonPath: .status.scale.statusReplicas + name: Ready + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.image + name: Image + type: string + - description: Management State + jsonPath: .spec.managementState + name: Management + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: AmazonCloudWatchAgent is the Schema for the amazoncloudwatchagents + API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: AmazonCloudWatchAgentSpec defines the desired state of AmazonCloudWatchAgent. + properties: + additionalContainers: + description: |- + AdditionalContainers allows injecting additional containers into the Collector's pod definition. + These sidecar containers can be used for authentication proxies, log shipping sidecars, agents for shipping + metrics to their cloud, or in general sidecars that do not support automatic injection. This option only + applies to Deployment, DaemonSet, and StatefulSet deployment modes of the collector. It does not apply to the sidecar + deployment mode. More info about sidecars: + https://kubernetes.io/docs/tasks/configure-pod-container/share-process-namespace/ + + + Container names managed by the operator: + * `otc-container` + + + Overriding containers managed by the operator is outside the scope of what the maintainers will support and by + doing so, you wil accept the risk of it breaking things. + items: + description: A single application container that you want to run + within a pod. + properties: + args: + description: |- + Arguments to the entrypoint. + The container image's CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + command: + description: |- + Entrypoint array. Not executed within a shell. + The container image's ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + env: + description: |- + List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be + a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + description: |- + List of sources to populate environment variables in the container. + The keys defined within a source must be a C_IDENTIFIER. All invalid keys + will be reported as an event when the container is starting. When a key exists in multiple + sources, the value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will take precedence. + Cannot be updated. + items: + description: EnvFromSource represents the source of a set + of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the ConfigMap must be + defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: An optional identifier to prepend to each + key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the Secret must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + image: + description: |- + Container image name. + More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management to default or override + container images in workload controllers like Deployments and StatefulSets. + type: string + imagePullPolicy: + description: |- + Image pull policy. + One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + type: string + lifecycle: + description: |- + Actions that the management system should take in response to container lifecycle events. + Cannot be updated. + properties: + postStart: + description: |- + PostStart is called immediately after a container is created. If the handler fails, + the container is terminated and restarted according to its restart policy. + Other management of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration that the + container should sleep before being terminated. + properties: + seconds: + description: Seconds is the number of seconds to + sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: |- + PreStop is called immediately before a container is terminated due to an + API request or management event such as liveness/startup probe failure, + preemption, resource contention, etc. The handler is not called if the + container crashes or exits. The Pod's termination grace period countdown begins before the + PreStop hook is executed. Regardless of the outcome of the handler, the + container will eventually terminate within the Pod's termination grace + period (unless delayed by finalizers). Other management of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration that the + container should sleep before being terminated. + properties: + seconds: + description: Seconds is the number of seconds to + sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: |- + Periodic probe of container liveness. + Container will be restarted if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP + allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP + port. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + name: + description: |- + Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: |- + List of ports to expose from the container. Not specifying a port here + DOES NOT prevent that port from being exposed. Any port which is + listening on the default "0.0.0.0" address inside a container will be + accessible from the network. + Modifying this array with strategic merge patch may corrupt the data. + For more information See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. + items: + description: ContainerPort represents a network port in a + single container. + properties: + containerPort: + description: |- + Number of port to expose on the pod's IP address. + This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port to. + type: string + hostPort: + description: |- + Number of port to expose on the host. + If specified, this must be a valid port number, 0 < x < 65536. + If HostNetwork is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: |- + If specified, this must be an IANA_SVC_NAME and unique within the pod. Each + named port in a pod must have a unique name. Name for the port that can be + referred to by services. + type: string + protocol: + default: TCP + description: |- + Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: |- + Periodic probe of container service readiness. + Container will be removed from service endpoints if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP + allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP + port. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource resize + policy for the container. + properties: + resourceName: + description: |- + Name of the resource to which this resource resize policy applies. + Supported values: cpu, memory. + type: string + restartPolicy: + description: |- + Restart policy to apply when specified resource is resized. + If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: |- + Compute Resources required by this container. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + RestartPolicy defines the restart behavior of individual containers in a pod. + This field may only be set for init containers, and the only allowed value is "Always". + For non-init containers or when this field is not specified, + the restart behavior is defined by the Pod's restart policy and the container type. + Setting the RestartPolicy as "Always" for the init container will have the following effect: + this init container will be continually restarted on + exit until all regular containers have terminated. Once all regular + containers have completed, all init containers with restartPolicy "Always" + will be shut down. This lifecycle differs from normal init containers and + is often referred to as a "sidecar" container. Although this init + container still starts in the init container sequence, it does not wait + for the container to complete before proceeding to the next init + container. Instead, the next init container starts immediately after this + init container is started, or after any startupProbe has successfully + completed. + type: string + securityContext: + description: |- + SecurityContext defines the security options the container should be run with. + If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: |- + StartupProbe indicates that the Pod has successfully initialized. + If specified, no other probes are executed until this completes successfully. + If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. + This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, + when it might take a long time to load data or warm a cache, than during steady-state operation. + This cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP + allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP + port. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + stdin: + description: |- + Whether this container should allocate a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will always result in EOF. + Default is false. + type: boolean + stdinOnce: + description: |- + Whether the container runtime should close the stdin channel after it has been opened by + a single attach. When stdin is true the stdin stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + first client attaches to stdin, and then remains open and accepts data until the client disconnects, + at which time stdin is closed and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin will never receive an EOF. + Default is false + type: boolean + terminationMessagePath: + description: |- + Optional: Path at which the file to which the container's termination message + will be written is mounted into the container's filesystem. + Message written is intended to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. The total message length across + all containers will be limited to 12kb. + Defaults to /dev/termination-log. + Cannot be updated. + type: string + terminationMessagePolicy: + description: |- + Indicate how the termination message should be populated. File will use the contents of + terminationMessagePath to populate the container status message on both success and failure. + FallbackToLogsOnError will use the last chunk of container log output if the termination + message file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + Defaults to File. + Cannot be updated. + type: string + tty: + description: |- + Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices to be + used by the container. + items: + description: volumeDevice describes a mapping of a raw block + device within a container. + properties: + devicePath: + description: devicePath is the path inside of the container + that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: |- + Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: |- + Container's working directory. + If not specified, the container runtime's default will be used, which + might be configured in the container image. + Cannot be updated. + type: string + required: + - name + type: object + type: array + affinity: + description: If specified, indicates the pod's scheduling constraints + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for the + pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. + items: + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated with the + corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching the corresponding + nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. co-locate + this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules (e.g. + avoid putting this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + args: + additionalProperties: + type: string + description: Args is the set of arguments to pass to the OpenTelemetry + Collector binary + type: object + autoscaler: + description: |- + Autoscaler specifies the pod autoscaling configuration to use + for the AmazonCloudWatchAgent workload. + properties: + behavior: + description: |- + HorizontalPodAutoscalerBehavior configures the scaling behavior of the target + in both Up and Down directions (scaleUp and scaleDown fields respectively). + properties: + scaleDown: + description: |- + scaleDown is scaling policy for scaling Down. + If not set, the default value is to allow to scale down to minReplicas pods, with a + 300 second stabilization window (i.e., the highest recommendation for + the last 300sec is used). + properties: + policies: + description: |- + policies is a list of potential scaling polices which can be used during scaling. + At least one policy must be specified, otherwise the HPAScalingRules will be discarded as invalid + items: + description: HPAScalingPolicy is a single policy which + must hold true for a specified past interval. + properties: + periodSeconds: + description: |- + periodSeconds specifies the window of time for which the policy should hold true. + PeriodSeconds must be greater than zero and less than or equal to 1800 (30 min). + format: int32 + type: integer + type: + description: type is used to specify the scaling + policy. + type: string + value: + description: |- + value contains the amount of change which is permitted by the policy. + It must be greater than zero + format: int32 + type: integer + required: + - periodSeconds + - type + - value + type: object + type: array + x-kubernetes-list-type: atomic + selectPolicy: + description: |- + selectPolicy is used to specify which policy should be used. + If not set, the default value Max is used. + type: string + stabilizationWindowSeconds: + description: |- + stabilizationWindowSeconds is the number of seconds for which past recommendations should be + considered while scaling up or scaling down. + StabilizationWindowSeconds must be greater than or equal to zero and less than or equal to 3600 (one hour). + If not set, use the default values: + - For scale up: 0 (i.e. no stabilization is done). + - For scale down: 300 (i.e. the stabilization window is 300 seconds long). + format: int32 + type: integer + type: object + scaleUp: + description: |- + scaleUp is scaling policy for scaling Up. + If not set, the default value is the higher of: + * increase no more than 4 pods per 60 seconds + * double the number of pods per 60 seconds + No stabilization is used. + properties: + policies: + description: |- + policies is a list of potential scaling polices which can be used during scaling. + At least one policy must be specified, otherwise the HPAScalingRules will be discarded as invalid + items: + description: HPAScalingPolicy is a single policy which + must hold true for a specified past interval. + properties: + periodSeconds: + description: |- + periodSeconds specifies the window of time for which the policy should hold true. + PeriodSeconds must be greater than zero and less than or equal to 1800 (30 min). + format: int32 + type: integer + type: + description: type is used to specify the scaling + policy. + type: string + value: + description: |- + value contains the amount of change which is permitted by the policy. + It must be greater than zero + format: int32 + type: integer + required: + - periodSeconds + - type + - value + type: object + type: array + x-kubernetes-list-type: atomic + selectPolicy: + description: |- + selectPolicy is used to specify which policy should be used. + If not set, the default value Max is used. + type: string + stabilizationWindowSeconds: + description: |- + stabilizationWindowSeconds is the number of seconds for which past recommendations should be + considered while scaling up or scaling down. + StabilizationWindowSeconds must be greater than or equal to zero and less than or equal to 3600 (one hour). + If not set, use the default values: + - For scale up: 0 (i.e. no stabilization is done). + - For scale down: 300 (i.e. the stabilization window is 300 seconds long). + format: int32 + type: integer + type: object + type: object + maxReplicas: + description: MaxReplicas sets an upper bound to the autoscaling + feature. If MaxReplicas is set autoscaling is enabled. + format: int32 + type: integer + metrics: + description: |- + Metrics is meant to provide a customizable way to configure HPA metrics. + currently the only supported custom metrics is type=Pod. + Use TargetCPUUtilization or TargetMemoryUtilization instead if scaling on these common resource metrics. + items: + description: |- + MetricSpec defines a subset of metrics to be defined for the HPA's metric array + more metric type can be supported as needed. + See https://pkg.go.dev/k8s.io/api/autoscaling/v2#MetricSpec for reference. + properties: + pods: + description: |- + PodsMetricSource indicates how to scale on a metric describing each pod in + the current scale target (for example, transactions-processed-per-second). + The values will be averaged together before being compared to the target + value. + properties: + metric: + description: metric identifies the target metric by + name and selector + properties: + name: + description: name is the name of the given metric + type: string + selector: + description: |- + selector is the string-encoded form of a standard kubernetes label selector for the given metric + When set, it is passed as an additional parameter to the metrics server for more specific metrics scoping. + When unset, just the metricName will be used to gather metrics. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - name + type: object + target: + description: target specifies the target value for the + given metric + properties: + averageUtilization: + description: |- + averageUtilization is the target value of the average of the + resource metric across all relevant pods, represented as a percentage of + the requested value of the resource for the pods. + Currently only valid for Resource metric source type + format: int32 + type: integer + averageValue: + anyOf: + - type: integer + - type: string + description: |- + averageValue is the target value of the average of the + metric across all relevant pods (as a quantity) + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: + description: type represents whether the metric + type is Utilization, Value, or AverageValue + type: string + value: + anyOf: + - type: integer + - type: string + description: value is the target value of the metric + (as a quantity). + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + required: + - type + type: object + required: + - metric + - target + type: object + type: + description: MetricSourceType indicates the type of metric. + type: string + required: + - type + type: object + type: array + minReplicas: + description: MinReplicas sets a lower bound to the autoscaling + feature. Set this if your are using autoscaling. It must be + at least 1 + format: int32 + type: integer + targetCPUUtilization: + description: |- + TargetCPUUtilization sets the target average CPU used across all replicas. + If average CPU exceeds this value, the HPA will scale up. Defaults to 90 percent. + format: int32 + type: integer + targetMemoryUtilization: + description: TargetMemoryUtilization sets the target average memory + utilization across all replicas + format: int32 + type: integer + type: object + config: + description: Config is the raw JSON to be used as the collector's + configuration. Refer to the OpenTelemetry Collector documentation + for details. + type: string + configmaps: + description: |- + ConfigMaps is a list of ConfigMaps in the same namespace as the AmazonCloudWatchAgent + object, which shall be mounted into the Collector Pods. + Each ConfigMap will be added to the Collector's Deployments as a volume named `configmap-`. + items: + properties: + mountpath: + type: string + name: + description: Configmap defines name and path where the configMaps + should be mounted. + type: string + required: + - mountpath + - name + type: object + type: array + deploymentUpdateStrategy: + description: |- + UpdateStrategy represents the strategy the operator will take replacing existing Deployment pods with new pods + https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/deployment-v1/#DeploymentSpec + This is only applicable to Deployment mode. + properties: + rollingUpdate: + description: |- + Rolling update config params. Present only if DeploymentStrategyType = + RollingUpdate. + --- + TODO: Update this to follow our convention for oneOf, whatever we decide it + to be. + properties: + maxSurge: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of pods that can be scheduled above the desired number of + pods. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up. + Defaults to 25%. + Example: when this is set to 30%, the new ReplicaSet can be scaled up immediately when + the rolling update starts, such that the total number of old and new pods do not exceed + 130% of desired pods. Once old pods have been killed, + new ReplicaSet can be scaled up further, ensuring that total number of pods running + at any time during the update is at most 130% of desired pods. + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of pods that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + Absolute number is calculated from percentage by rounding down. + This can not be 0 if MaxSurge is 0. + Defaults to 25%. + Example: when this is set to 30%, the old ReplicaSet can be scaled down to 70% of desired pods + immediately when the rolling update starts. Once new pods are ready, old ReplicaSet + can be scaled down further, followed by scaling up the new ReplicaSet, ensuring + that the total number of pods available at all times during the update is at + least 70% of desired pods. + x-kubernetes-int-or-string: true + type: object + type: + description: Type of deployment. Can be "Recreate" or "RollingUpdate". + Default is RollingUpdate. + type: string + type: object + env: + description: |- + ENV vars to set on the OpenTelemetry Collector's Pods. These can then in certain cases be + consumed in the config file for the Collector. + items: + description: EnvVar represents an environment variable present in + a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's value. Cannot + be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath is + written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified + API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed + resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + description: |- + List of sources to populate environment variables on the OpenTelemetry Collector's Pods. + These can then in certain cases be consumed in the config file for the Collector. + items: + description: EnvFromSource represents the source of a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the ConfigMap must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: An optional identifier to prepend to each key in + the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the Secret must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + hostNetwork: + description: HostNetwork indicates if the pod should run in the host + networking namespace. + type: boolean + image: + description: Image indicates the container image to use for the OpenTelemetry + Collector. + type: string + imagePullPolicy: + description: ImagePullPolicy indicates the pull policy to be used + for retrieving the container image (Always, Never, IfNotPresent) + type: string + ingress: + description: |- + Ingress is used to specify how OpenTelemetry Collector is exposed. This + functionality is only available if one of the valid modes is set. + Valid modes are: deployment, daemonset and statefulset. + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations to add to ingress. + e.g. 'cert-manager.io/cluster-issuer: "letsencrypt"' + type: object + hostname: + description: Hostname by which the ingress proxy can be reached. + type: string + ingressClassName: + description: |- + IngressClassName is the name of an IngressClass cluster resource. Ingress + controller implementations use this field to know whether they should be + serving this Ingress resource. + type: string + route: + description: |- + Route is an OpenShift specific section that is only considered when + type "route" is used. + properties: + termination: + description: Termination indicates termination type. By default + "edge" is used. + enum: + - insecure + - edge + - passthrough + - reencrypt + type: string + type: object + ruleType: + description: |- + RuleType defines how Ingress exposes collector receivers. + IngressRuleTypePath ("path") exposes each receiver port on a unique path on single domain defined in Hostname. + IngressRuleTypeSubdomain ("subdomain") exposes each receiver port on a unique subdomain of Hostname. + Default is IngressRuleTypePath ("path"). + enum: + - path + - subdomain + type: string + tls: + description: TLS configuration. + items: + description: IngressTLS describes the transport layer security + associated with an ingress. + properties: + hosts: + description: |- + hosts is a list of hosts included in the TLS certificate. The values in + this list must match the name/s used in the tlsSecret. Defaults to the + wildcard host setting for the loadbalancer controller fulfilling this + Ingress, if left unspecified. + items: + type: string + type: array + x-kubernetes-list-type: atomic + secretName: + description: |- + secretName is the name of the secret used to terminate TLS traffic on + port 443. Field is left optional to allow TLS routing based on SNI + hostname alone. If the SNI host in a listener conflicts with the "Host" + header field used by an IngressRule, the SNI host is used for termination + and value of the "Host" header is used for routing. + type: string + type: object + type: array + type: + description: |- + Type default value is: "" + Supported types are: ingress, route + enum: + - ingress + - route + type: string + type: object + initContainers: + description: |- + InitContainers allows injecting initContainers to the Collector's pod definition. + These init containers can be used to fetch secrets for injection into the + configuration from external sources, run added checks, etc. Any errors during the execution of + an initContainer will lead to a restart of the Pod. More info: + https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ + items: + description: A single application container that you want to run + within a pod. + properties: + args: + description: |- + Arguments to the entrypoint. + The container image's CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + command: + description: |- + Entrypoint array. Not executed within a shell. + The container image's ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot be updated. + More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + items: + type: string + type: array + env: + description: |- + List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be + a C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + description: |- + List of sources to populate environment variables in the container. + The keys defined within a source must be a C_IDENTIFIER. All invalid keys + will be reported as an event when the container is starting. When a key exists in multiple + sources, the value associated with the last source will take precedence. + Values defined by an Env with a duplicate key will take precedence. + Cannot be updated. + items: + description: EnvFromSource represents the source of a set + of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the ConfigMap must be + defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: An optional identifier to prepend to each + key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the Secret must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + image: + description: |- + Container image name. + More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management to default or override + container images in workload controllers like Deployments and StatefulSets. + type: string + imagePullPolicy: + description: |- + Image pull policy. + One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + type: string + lifecycle: + description: |- + Actions that the management system should take in response to container lifecycle events. + Cannot be updated. + properties: + postStart: + description: |- + PostStart is called immediately after a container is created. If the handler fails, + the container is terminated and restarted according to its restart policy. + Other management of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration that the + container should sleep before being terminated. + properties: + seconds: + description: Seconds is the number of seconds to + sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: |- + PreStop is called immediately before a container is terminated due to an + API request or management event such as liveness/startup probe failure, + preemption, resource contention, etc. The handler is not called if the + container crashes or exits. The Pod's termination grace period countdown begins before the + PreStop hook is executed. Regardless of the outcome of the handler, the + container will eventually terminate within the Pod's termination grace + period (unless delayed by finalizers). Other management of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration that the + container should sleep before being terminated. + properties: + seconds: + description: Seconds is the number of seconds to + sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: |- + Periodic probe of container liveness. + Container will be restarted if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP + allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP + port. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + name: + description: |- + Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: |- + List of ports to expose from the container. Not specifying a port here + DOES NOT prevent that port from being exposed. Any port which is + listening on the default "0.0.0.0" address inside a container will be + accessible from the network. + Modifying this array with strategic merge patch may corrupt the data. + For more information See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. + items: + description: ContainerPort represents a network port in a + single container. + properties: + containerPort: + description: |- + Number of port to expose on the pod's IP address. + This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port to. + type: string + hostPort: + description: |- + Number of port to expose on the host. + If specified, this must be a valid port number, 0 < x < 65536. + If HostNetwork is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: |- + If specified, this must be an IANA_SVC_NAME and unique within the pod. Each + named port in a pod must have a unique name. Name for the port that can be + referred to by services. + type: string + protocol: + default: TCP + description: |- + Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: |- + Periodic probe of container service readiness. + Container will be removed from service endpoints if the probe fails. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP + allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP + port. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource resize + policy for the container. + properties: + resourceName: + description: |- + Name of the resource to which this resource resize policy applies. + Supported values: cpu, memory. + type: string + restartPolicy: + description: |- + Restart policy to apply when specified resource is resized. + If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: |- + Compute Resources required by this container. + Cannot be updated. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + restartPolicy: + description: |- + RestartPolicy defines the restart behavior of individual containers in a pod. + This field may only be set for init containers, and the only allowed value is "Always". + For non-init containers or when this field is not specified, + the restart behavior is defined by the Pod's restart policy and the container type. + Setting the RestartPolicy as "Always" for the init container will have the following effect: + this init container will be continually restarted on + exit until all regular containers have terminated. Once all regular + containers have completed, all init containers with restartPolicy "Always" + will be shut down. This lifecycle differs from normal init containers and + is often referred to as a "sidecar" container. Although this init + container still starts in the init container sequence, it does not wait + for the container to complete before proceeding to the next init + container. Instead, the next init container starts immediately after this + init container is started, or after any startupProbe has successfully + completed. + type: string + securityContext: + description: |- + SecurityContext defines the security options the container should be run with. + If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: |- + StartupProbe indicates that the Pod has successfully initialized. + If specified, no other probes are executed until this completes successfully. + If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. + This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, + when it might take a long time to load data or warm a cache, than during steady-state operation. + This cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: |- + Service is the name of the service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + + + If this is not specified, the default behavior is defined by gRPC. + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP + allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP + port. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + stdin: + description: |- + Whether this container should allocate a buffer for stdin in the container runtime. If this + is not set, reads from stdin in the container will always result in EOF. + Default is false. + type: boolean + stdinOnce: + description: |- + Whether the container runtime should close the stdin channel after it has been opened by + a single attach. When stdin is true the stdin stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + first client attaches to stdin, and then remains open and accepts data until the client disconnects, + at which time stdin is closed and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin will never receive an EOF. + Default is false + type: boolean + terminationMessagePath: + description: |- + Optional: Path at which the file to which the container's termination message + will be written is mounted into the container's filesystem. + Message written is intended to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. The total message length across + all containers will be limited to 12kb. + Defaults to /dev/termination-log. + Cannot be updated. + type: string + terminationMessagePolicy: + description: |- + Indicate how the termination message should be populated. File will use the contents of + terminationMessagePath to populate the container status message on both success and failure. + FallbackToLogsOnError will use the last chunk of container log output if the termination + message file is empty and the container exited with an error. + The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + Defaults to File. + Cannot be updated. + type: string + tty: + description: |- + Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices to be + used by the container. + items: + description: volumeDevice describes a mapping of a raw block + device within a container. + properties: + devicePath: + description: devicePath is the path inside of the container + that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: |- + Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: |- + Container's working directory. + If not specified, the container runtime's default will be used, which + might be configured in the container image. + Cannot be updated. + type: string + required: + - name + type: object + type: array + lifecycle: + description: Actions that the management system should take in response + to container lifecycle events. Cannot be updated. + properties: + postStart: + description: |- + PostStart is called immediately after a container is created. If the handler fails, + the container is terminated and restarted according to its restart policy. + Other management of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP + allows repeated headers. + items: + description: HTTPHeader describes a custom header to + be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration that the container + should sleep before being terminated. + properties: + seconds: + description: Seconds is the number of seconds to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: |- + PreStop is called immediately before a container is terminated due to an + API request or management event such as liveness/startup probe failure, + preemption, resource contention, etc. The handler is not called if the + container crashes or exits. The Pod's termination grace period countdown begins before the + PreStop hook is executed. Regardless of the outcome of the handler, the + container will eventually terminate within the Pod's termination grace + period (unless delayed by finalizers). Other management of the container blocks until the hook completes + or until the termination grace period is reached. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: |- + Command is the command line to execute inside the container, the working directory for the + command is root ('/') in the container's filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use + a shell, you need to explicitly call out to that shell. + Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: |- + Host name to connect to, defaults to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP + allows repeated headers. + items: + description: HTTPHeader describes a custom header to + be used in HTTP probes + properties: + name: + description: |- + The header field name. + This will be canonicalized upon output, so case-variant names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Name or number of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: |- + Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + sleep: + description: Sleep represents the duration that the container + should sleep before being terminated. + properties: + seconds: + description: Seconds is the number of seconds to sleep. + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + description: |- + Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept + for the backward compatibility. There are no validation of this field and + lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the container. + Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: |- + Liveness config for the OpenTelemetry Collector except the probe handler which is auto generated from the health extension of the collector. + It is only effective when healthcheckextension is configured in the OpenTelemetry Collector pipeline. + properties: + failureThreshold: + description: |- + Minimum consecutive failures for the probe to be considered failed after having succeeded. + Defaults to 3. Minimum value is 1. + format: int32 + type: integer + initialDelaySeconds: + description: |- + Number of seconds after the container has started before liveness probes are initiated. + Defaults to 0 seconds. Minimum value is 0. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + periodSeconds: + description: |- + How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + Minimum consecutive successes for the probe to be considered successful after having failed. + Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + terminationGracePeriodSeconds: + description: |- + Optional duration in seconds the pod needs to terminate gracefully upon probe failure. + The grace period is the duration in seconds after the processes running in the pod are sent + a termination signal and the time when the processes are forcibly halted with a kill signal. + Set this value longer than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this + value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates stop immediately via + the kill signal (no opportunity to shut down). + This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. + Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: |- + Number of seconds after which the probe times out. + Defaults to 1 second. Minimum value is 1. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + format: int32 + type: integer + type: object + managementState: + default: managed + description: |- + ManagementState defines if the CR should be managed by the operator or not. + Default is managed. + enum: + - managed + - unmanaged + type: string + maxReplicas: + description: |- + MaxReplicas sets an upper bound to the autoscaling feature. If MaxReplicas is set autoscaling is enabled. + Deprecated: use "AmazonCloudWatchAgent.Spec.Autoscaler.MaxReplicas" instead. + format: int32 + type: integer + minReplicas: + description: |- + MinReplicas sets a lower bound to the autoscaling feature. Set this if you are using autoscaling. It must be at least 1 + Deprecated: use "AmazonCloudWatchAgent.Spec.Autoscaler.MinReplicas" instead. + format: int32 + type: integer + mode: + description: Mode represents how the collector should be deployed + (deployment, daemonset, statefulset or sidecar) + enum: + - daemonset + - deployment + - sidecar + - statefulset + type: string + nodeSelector: + additionalProperties: + type: string + description: |- + NodeSelector to schedule OpenTelemetry Collector pods. + This is only relevant to daemonset, statefulset, and deployment mode + type: object + observability: + description: ObservabilitySpec defines how telemetry data gets handled. + properties: + metrics: + description: Metrics defines the metrics configuration for operands. + properties: + enableMetrics: + description: |- + EnableMetrics specifies if ServiceMonitor or PodMonitor(for sidecar mode) should be created for the service managed by the OpenTelemetry Operator. + The operator.observability.prometheus feature gate must be enabled to use this feature. + type: boolean + type: object + type: object + otelConfig: + description: Config is the raw YAML to be used as the collector's + configuration. Refer to the OpenTelemetry Collector documentation + for details. + type: string + podAnnotations: + additionalProperties: + type: string + description: |- + PodAnnotations is the set of annotations that will be attached to + Collector and Target Allocator pods. + type: object + podDisruptionBudget: + description: |- + PodDisruptionBudget specifies the pod disruption budget configuration to use + for the AmazonCloudWatchAgent workload. + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + An eviction is allowed if at most "maxUnavailable" pods selected by + "selector" are unavailable after the eviction, i.e. even in absence of + the evicted pod. For example, one can prevent all voluntary evictions + by specifying 0. This is a mutually exclusive setting with "minAvailable". + x-kubernetes-int-or-string: true + minAvailable: + anyOf: + - type: integer + - type: string + description: |- + An eviction is allowed if at least "minAvailable" pods selected by + "selector" will still be available after the eviction, i.e. even in the + absence of the evicted pod. So for example you can prevent all voluntary + evictions by specifying "100%". + x-kubernetes-int-or-string: true + type: object + podSecurityContext: + description: |- + PodSecurityContext configures the pod security context for the + amazon-cloudwatch-agent pod, when running as a deployment, daemonset, + or statefulset. + + + In sidecar mode, the amazon-cloudwatch-agent-operator will ignore this setting. + properties: + fsGroup: + description: |- + A special supplemental group that applies to all containers in a pod. + Some volume types allow the Kubelet to change the ownership of that volume + to be owned by the pod: + + + 1. The owning GID will be the FSGroup + 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) + 3. The permission bits are OR'd with rw-rw---- + + + If unset, the Kubelet will not modify the ownership and permissions of any volume. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + fsGroupChangePolicy: + description: |- + fsGroupChangePolicy defines behavior of changing ownership and permission of the volume + before being exposed inside Pod. This field will only apply to + volume types which support fsGroup based ownership(and permissions). + It will have no effect on ephemeral volume types such as: secret, configmaps + and emptydir. + Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used. + Note that this field cannot be set when spec.os.name is windows. + type: string + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in SecurityContext. If set in + both SecurityContext and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to + the container. + type: string + role: + description: Role is a SELinux role label that applies to + the container. + type: string + type: + description: Type is a SELinux type label that applies to + the container. + type: string + user: + description: User is a SELinux user label that applies to + the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + supplementalGroups: + description: |- + A list of groups applied to the first process run in each container, in addition + to the container's primary GID, the fsGroup (if specified), and group memberships + defined in the container image for the uid of the container process. If unspecified, + no additional groups are added to any container. Note that group memberships + defined in the container image for the uid of the container process are still effective, + even if they are not included in this list. + Note that this field cannot be set when spec.os.name is windows. + items: + format: int64 + type: integer + type: array + sysctls: + description: |- + Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported + sysctls (by the container runtime) might fail to launch. + Note that this field cannot be set when spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter to be set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options within a container's SecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA + credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + ports: + description: |- + Ports allows a set of ports to be exposed by the underlying v1.Service. By default, the operator + will attempt to infer the required ports by parsing the .Spec.Config property but this property can be + used to open additional ports that can't be inferred by the operator, like for custom receivers. + items: + description: ServicePort contains information on service's port. + properties: + appProtocol: + description: |- + The application protocol for this port. + This is used as a hint for implementations to offer richer behavior for protocols that they understand. + This field follows standard Kubernetes label syntax. + Valid values are either: + + + * Un-prefixed protocol names - reserved for IANA standard service names (as per + RFC-6335 and https://www.iana.org/assignments/service-names). + + + * Kubernetes-defined prefixed names: + * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455 + * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + + + * Other protocols should use implementation-defined prefixed names such as + mycompany.com/my-custom-protocol. + type: string + name: + description: |- + The name of this port within the service. This must be a DNS_LABEL. + All ports within a ServiceSpec must have unique names. When considering + the endpoints for a Service, this must match the 'name' field in the + EndpointPort. + Optional if only one ServicePort is defined on this service. + type: string + nodePort: + description: |- + The port on each node on which this service is exposed when type is + NodePort or LoadBalancer. Usually assigned by the system. If a value is + specified, in-range, and not in use it will be used, otherwise the + operation will fail. If not specified, a port will be allocated if this + Service requires one. If this field is specified when creating a + Service which does not need it, creation will fail. This field will be + wiped when updating a Service to no longer need it (e.g. changing type + from NodePort to ClusterIP). + More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + format: int32 + type: integer + port: + description: The port that will be exposed by this service. + format: int32 + type: integer + protocol: + default: TCP + description: |- + The IP protocol for this port. Supports "TCP", "UDP", and "SCTP". + Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: |- + Number or name of the port to access on the pods targeted by the service. + Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + If this is a string, it will be looked up as a named port in the + target Pod's container ports. If this is not specified, the value + of the 'port' field is used (an identity map). + This field is ignored for services with clusterIP=None, and should be + omitted or set equal to the 'port' field. + More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-type: atomic + priorityClassName: + description: |- + If specified, indicates the pod's priority. + If not specified, the pod priority will be default or zero if there is no + default. + type: string + prometheus: + description: Prometheus is the raw YAML to be used as the collector's + prometheus configuration. + properties: + config: + description: AnyConfig represent parts of the config. + type: object + x-kubernetes-preserve-unknown-fields: true + report_extra_scrape_metrics: + type: boolean + x-kubernetes-preserve-unknown-fields: true + start_time_metric_regex: + type: string + x-kubernetes-preserve-unknown-fields: true + target_allocator: + description: AnyConfig represent parts of the config. + type: object + x-kubernetes-preserve-unknown-fields: true + trim_metric_suffixes: + type: boolean + x-kubernetes-preserve-unknown-fields: true + use_start_time_metric: + type: boolean + x-kubernetes-preserve-unknown-fields: true + type: object + replicas: + description: Replicas is the number of pod instances for the underlying + OpenTelemetry Collector. Set this if your are not using autoscaling + format: int32 + type: integer + resources: + description: Resources to set on the OpenTelemetry Collector pods. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + securityContext: + description: |- + SecurityContext configures the container security context for + the amazon-cloudwatch-agent container. + + + In deployment, daemonset, or statefulset mode, this controls + the security context settings for the primary application + container. + + + In sidecar mode, this controls the security context for the + injected sidecar container. + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default is DefaultProcMount which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to + the container. + type: string + role: + description: Role is a SELinux role label that applies to + the container. + type: string + type: + description: Type is a SELinux type label that applies to + the container. + type: string + user: + description: User is a SELinux user label that applies to + the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA + credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + serviceAccount: + description: |- + ServiceAccount indicates the name of an existing service account to use with this instance. When set, + the operator will not automatically create a ServiceAccount for the collector. + type: string + targetAllocator: + description: TargetAllocator indicates a value which determines whether + to spawn a target allocation resource or not. + properties: + affinity: + description: If specified, indicates the pod's scheduling constraints + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for + the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node matches the corresponding matchExpressions; the + node(s) with the highest sum are the most preferred. + items: + description: |- + An empty preferred scheduling term matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated with + the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching the + corresponding nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: |- + A null or empty node selector term matches no objects. The requirements of + them are ANDed. + The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: |- + A node selector requirement is a selector that contains values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: |- + Represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: |- + An array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. If the operator is Gt or Lt, the values + array must have a single element, which will be interpreted as an integer. + This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. + co-locate this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules + (e.g. avoid putting this pod in the same node, zone, etc. + as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: |- + The scheduler will prefer to schedule pods to nodes that satisfy + the anti-affinity expressions specified by this field, but it may choose + a node that violates one or more of the expressions. The node that is + most preferred is the one with the greatest sum of weights, i.e. + for each node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, etc.), + compute a sum by iterating through the elements of this field and adding + "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: |- + weight associated with matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: |- + If the anti-affinity requirements specified by this field are not met at + scheduling time, the pod will not be scheduled onto the node. + If the anti-affinity requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod label update), the + system may or may not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: |- + Defines a set of pods (namely those matching the labelSelector + relative to the given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node whose value of + the label with key matches that of any node on which + a pod of the set of pods is running + properties: + labelSelector: + description: |- + A label query over a set of resources, in this case pods. + If it's null, this PodAffinityTerm matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key in (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with `LabelSelector` as `key notin (value)` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both MismatchLabelKeys and LabelSelector. + Also, MismatchLabelKeys cannot be set when LabelSelector isn't set. + This is an alpha field and requires enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: |- + A label query over the set of namespaces that the term applies to. + The term is applied to the union of the namespaces selected by this field + and the ones listed in the namespaces field. + null selector and null or empty namespaces list means "this pod's namespace". + An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: |- + namespaces specifies a static list of namespace names that the term applies to. + The term is applied to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. + null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: |- + This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where co-located is defined as running on a node + whose value of the label with key topologyKey matches that of any node on which any of the + selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + allocationStrategy: + description: |- + AllocationStrategy determines which strategy the target allocator should use for allocation. + The current option is consistent-hashing. + enum: + - consistent-hashing + type: string + enabled: + description: Enabled indicates whether to use a target allocation + mechanism for Prometheus targets or not. + type: boolean + env: + description: |- + ENV vars to set on the OpenTelemetry TargetAllocator's Pods. These can then in certain cases be + consumed in the config file for the TargetAllocator. + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: |- + Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in the container and + any service environment variables. If a variable cannot be resolved, + the reference in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether the variable + exists or not. + Defaults to "". + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: |- + Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + filterStrategy: + description: |- + FilterStrategy determines how to filter targets before allocating them among the collectors. + The only current option is relabel-config (drops targets based on prom relabel_config). + Filtering is disabled by default. + type: string + image: + description: Image indicates the container image to use for the + OpenTelemetry TargetAllocator. + type: string + nodeSelector: + additionalProperties: + type: string + description: NodeSelector to schedule OpenTelemetry TargetAllocator + pods. + type: object + prometheusCR: + description: |- + PrometheusCR defines the configuration for the retrieval of PrometheusOperator CRDs ( servicemonitor.monitoring.coreos.com/v1 and podmonitor.monitoring.coreos.com/v1 ) retrieval. + All CR instances which the ServiceAccount has access to will be retrieved. This includes other namespaces. + properties: + enabled: + description: Enabled indicates whether to use a PrometheusOperator + custom resources as targets or not. + type: boolean + podMonitorSelector: + additionalProperties: + type: string + description: |- + PodMonitors to be selected for target discovery. + This is a map of {key,value} pairs. Each {key,value} in the map is going to exactly match a label in a + PodMonitor's meta labels. The requirements are ANDed. + type: object + scrapeInterval: + default: 30s + description: |- + Interval between consecutive scrapes. Equivalent to the same setting on the Prometheus CRD. + + + Default: "30s" + format: duration + type: string + serviceMonitorSelector: + additionalProperties: + type: string + description: |- + ServiceMonitors to be selected for target discovery. + This is a map of {key,value} pairs. Each {key,value} in the map is going to exactly match a label in a + ServiceMonitor's meta labels. The requirements are ANDed. + type: object + type: object + replicas: + description: |- + Replicas is the number of pod instances for the underlying TargetAllocator. This should only be set to a value + other than 1 if a strategy that allows for high availability is chosen. Currently, the only allocation strategy + that can be run in a high availability mode is consistent-hashing. + format: int32 + type: integer + resources: + description: Resources to set on the OpenTelemetryTargetAllocator + containers. + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + securityContext: + description: |- + SecurityContext configures the container security context for + the target-allocator. + properties: + fsGroup: + description: |- + A special supplemental group that applies to all containers in a pod. + Some volume types allow the Kubelet to change the ownership of that volume + to be owned by the pod: + + + 1. The owning GID will be the FSGroup + 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) + 3. The permission bits are OR'd with rw-rw---- + + + If unset, the Kubelet will not modify the ownership and permissions of any volume. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + fsGroupChangePolicy: + description: |- + fsGroupChangePolicy defines behavior of changing ownership and permission of the volume + before being exposed inside Pod. This field will only apply to + volume types which support fsGroup based ownership(and permissions). + It will have no effect on ephemeral volume types such as: secret, configmaps + and emptydir. + Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used. + Note that this field cannot be set when spec.os.name is windows. + type: string + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in SecurityContext. If set in + both SecurityContext and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + supplementalGroups: + description: |- + A list of groups applied to the first process run in each container, in addition + to the container's primary GID, the fsGroup (if specified), and group memberships + defined in the container image for the uid of the container process. If unspecified, + no additional groups are added to any container. Note that group memberships + defined in the container image for the uid of the container process are still effective, + even if they are not included in this list. + Note that this field cannot be set when spec.os.name is windows. + items: + format: int64 + type: integer + type: array + sysctls: + description: |- + Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported + sysctls (by the container runtime) might fail to launch. + Note that this field cannot be set when spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter to be set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options within a container's SecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + serviceAccount: + description: |- + ServiceAccount indicates the name of an existing service account to use with this instance. When set, + the operator will not automatically create a ServiceAccount for the TargetAllocator. + type: string + tolerations: + description: |- + Toleration embedded kubernetes pod configuration option, + controls how pods can be scheduled with matching taints + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + topologySpreadConstraints: + description: |- + TopologySpreadConstraints embedded kubernetes pod configuration option, + controls how pods are spread across your cluster among failure-domains + such as regions, zones, nodes, and other user-defined topology domains + https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ + items: + description: TopologySpreadConstraint specifies how to spread + matching pods among the given topology. + properties: + labelSelector: + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods + in their corresponding topology domain. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + + + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. + format: int32 + type: integer + minDomains: + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + + + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + + + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). + format: int32 + type: integer + nodeAffinityPolicy: + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + + + If this value is nil, the behavior is equivalent to the Honor policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + nodeTaintsPolicy: + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + + + If this value is nil, the behavior is equivalent to the Ignore policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + topologyKey: + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. + type: string + whenUnsatisfiable: + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + type: object + terminationGracePeriodSeconds: + description: Duration in seconds the pod needs to terminate gracefully + upon probe failure. + format: int64 + type: integer + tolerations: + description: |- + Toleration to schedule OpenTelemetry Collector pods. + This is only relevant to daemonset, statefulset, and deployment mode + items: + description: |- + The pod this Toleration is attached to tolerates any taint that matches + the triple using the matching operator . + properties: + effect: + description: |- + Effect indicates the taint effect to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: |- + Key is the taint key that the toleration applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: |- + Operator represents a key's relationship to the value. + Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod can + tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: |- + TolerationSeconds represents the period of time the toleration (which must be + of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint forever (do not evict). Zero and + negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: |- + Value is the taint value the toleration matches to. + If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + topologySpreadConstraints: + description: |- + TopologySpreadConstraints embedded kubernetes pod configuration option, + controls how pods are spread across your cluster among failure-domains + such as regions, zones, nodes, and other user-defined topology domains + https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ + This is only relevant to statefulset, and deployment mode + items: + description: TopologySpreadConstraint specifies how to spread matching + pods among the given topology. + properties: + labelSelector: + description: |- + LabelSelector is used to find matching pods. + Pods that match this label selector are counted to determine the number of pods + in their corresponding topology domain. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select the pods over which + spreading will be calculated. The keys are used to lookup values from the + incoming pod labels, those key-value labels are ANDed with labelSelector + to select the group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. + MatchLabelKeys cannot be set when LabelSelector isn't set. + Keys that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match against labelSelector. + + + This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + description: |- + MaxSkew describes the degree to which pods may be unevenly distributed. + When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference + between the number of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods in an eligible domain + or zero if the number of eligible domains is less than MinDomains. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 2/2/1: + In this case, the global minimum is 1. + | zone1 | zone2 | zone3 | + | P P | P P | P | + - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; + scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). + - if MaxSkew is 2, incoming pod can be scheduled onto any zone. + When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence + to topologies that satisfy it. + It's a required field. Default value is 1 and 0 is not allowed. + format: int32 + type: integer + minDomains: + description: |- + MinDomains indicates a minimum number of eligible domains. + When the number of eligible domains with matching topology keys is less than minDomains, + Pod Topology Spread treats "global minimum" as 0, and then the calculation of Skew is performed. + And when the number of eligible domains with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. + As a result, when the number of eligible domains is less than minDomains, + scheduler won't schedule more than maxSkew Pods to those domains. + If value is nil, the constraint behaves as if MinDomains is equal to 1. + Valid values are integers greater than 0. + When value is not nil, WhenUnsatisfiable must be DoNotSchedule. + + + For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: + | zone1 | zone2 | zone3 | + | P P | P P | P P | + The number of domains is less than 5(MinDomains), so "global minimum" is treated as 0. + In this situation, new pod with the same labelSelector cannot be scheduled, + because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, + it will violate MaxSkew. + + + This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default). + format: int32 + type: integer + nodeAffinityPolicy: + description: |- + NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector + when calculating pod topology spread skew. Options are: + - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. + - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. + + + If this value is nil, the behavior is equivalent to the Honor policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + nodeTaintsPolicy: + description: |- + NodeTaintsPolicy indicates how we will treat node taints when calculating + pod topology spread skew. Options are: + - Honor: nodes without taints, along with tainted nodes for which the incoming pod + has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + + + If this value is nil, the behavior is equivalent to the Ignore policy. + This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. + type: string + topologyKey: + description: |- + TopologyKey is the key of node labels. Nodes that have a label with this key + and identical values are considered to be in the same topology. + We consider each as a "bucket", and try to put balanced number + of pods into each bucket. + We define a domain as a particular instance of a topology. + Also, we define an eligible domain as a domain whose nodes meet the requirements of + nodeAffinityPolicy and nodeTaintsPolicy. + e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. + And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. + It's a required field. + type: string + whenUnsatisfiable: + description: |- + WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy + the spread constraint. + - DoNotSchedule (default) tells the scheduler not to schedule it. + - ScheduleAnyway tells the scheduler to schedule the pod in any location, + but giving higher precedence to topologies that would help reduce the + skew. + A constraint is considered "Unsatisfiable" for an incoming pod + if and only if every possible node assignment for that pod would violate + "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same + labelSelector spread as 3/1/1: + | zone1 | zone2 | zone3 | + | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled + to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies + MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler + won't make it *more* imbalanced. + It's a required field. + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + updateStrategy: + description: |- + UpdateStrategy represents the strategy the operator will take replacing existing DaemonSet pods with new pods + https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/daemon-set-v1/#DaemonSetSpec + This is only applicable to Daemonset mode. + properties: + rollingUpdate: + description: |- + Rolling update config params. Present only if type = "RollingUpdate". + --- + TODO: Update this to follow our convention for oneOf, whatever we decide it + to be. Same as Deployment `strategy.rollingUpdate`. + See https://github.com/kubernetes/kubernetes/issues/35345 + properties: + maxSurge: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of nodes with an existing available DaemonSet pod that + can have an updated DaemonSet pod during during an update. + Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up to a minimum of 1. + Default value is 0. + Example: when this is set to 30%, at most 30% of the total number of nodes + that should be running the daemon pod (i.e. status.desiredNumberScheduled) + can have their a new pod created before the old pod is marked as deleted. + The update starts by launching new pods on 30% of nodes. Once an updated + pod is available (Ready for at least minReadySeconds) the old DaemonSet pod + on that node is marked deleted. If the old pod becomes unavailable for any + reason (Ready transitions to false, is evicted, or is drained) an updated + pod is immediatedly created on that node without considering surge limits. + Allowing surge implies the possibility that the resources consumed by the + daemonset on any given node can double if the readiness check fails, and + so resource intensive daemonsets should take into account that they may + cause evictions during disruption. + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of DaemonSet pods that can be unavailable during the + update. Value can be an absolute number (ex: 5) or a percentage of total + number of DaemonSet pods at the start of the update (ex: 10%). Absolute + number is calculated from percentage by rounding up. + This cannot be 0 if MaxSurge is 0 + Default value is 1. + Example: when this is set to 30%, at most 30% of the total number of nodes + that should be running the daemon pod (i.e. status.desiredNumberScheduled) + can have their pods stopped for an update at any given time. The update + starts by stopping at most 30% of those DaemonSet pods and then brings + up new DaemonSet pods in their place. Once the new pods are available, + it then proceeds onto other DaemonSet pods, thus ensuring that at least + 70% of original number of DaemonSet pods are available at all times during + the update. + x-kubernetes-int-or-string: true + type: object + type: + description: Type of daemon set update. Can be "RollingUpdate" + or "OnDelete". Default is RollingUpdate. + type: string + type: object + upgradeStrategy: + description: UpgradeStrategy represents how the operator will handle + upgrades to the CR when a newer version of the operator is deployed + enum: + - automatic + - none + type: string + volumeClaimTemplates: + description: VolumeClaimTemplates will provide stable storage using + PersistentVolumes. Only available when the mode=statefulset. + items: + description: PersistentVolumeClaim is a user's request for and claim + to a persistent volume + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + spec defines the desired characteristics of a volume requested by a pod author. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over volumes to consider + for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to the + PersistentVolume backing this claim. + type: string + type: object + status: + description: |- + status represents the current information/status of a persistent volume claim. + Read-only. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + accessModes: + description: |- + accessModes contains the actual access modes the volume backing the PVC has. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + allocatedResourceStatuses: + additionalProperties: + description: |- + When a controller receives persistentvolume claim update with ClaimResourceStatus for a resource + that it does not recognizes, then it should ignore that update and let other controllers + handle it. + type: string + description: "allocatedResourceStatuses stores status of + resource being resized for the given PVC.\nKey names follow + standard Kubernetes label syntax. Valid values are either:\n\t* + Un-prefixed keys:\n\t\t- storage - the capacity of the + volume.\n\t* Custom resources must use implementation-defined + prefixed names such as \"example.com/my-custom-resource\"\nApart + from above values - keys that are unprefixed or have kubernetes.io + prefix are considered\nreserved and hence may not be used.\n\n\nClaimResourceStatus + can be in any of following states:\n\t- ControllerResizeInProgress:\n\t\tState + set when resize controller starts resizing the volume + in control-plane.\n\t- ControllerResizeFailed:\n\t\tState + set when resize has failed in resize controller with a + terminal error.\n\t- NodeResizePending:\n\t\tState set + when resize controller has finished resizing the volume + but further resizing of\n\t\tvolume is needed on the node.\n\t- + NodeResizeInProgress:\n\t\tState set when kubelet starts + resizing the volume.\n\t- NodeResizeFailed:\n\t\tState + set when resizing has failed in kubelet with a terminal + error. Transient errors don't set\n\t\tNodeResizeFailed.\nFor + example: if expanding a PVC for more capacity - this field + can be one of the following states:\n\t- pvc.status.allocatedResourceStatus['storage'] + = \"ControllerResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage'] + = \"ControllerResizeFailed\"\n - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizePending\"\n - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizeInProgress\"\n - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizeFailed\"\nWhen this field is not set, it + means that no resize operation is in progress for the + given PVC.\n\n\nA controller that receives PVC update + with previously unknown resourceName or ClaimResourceStatus\nshould + ignore the update for the purpose it was designed. For + example - a controller that\nonly is responsible for resizing + capacity of the volume, should ignore PVC updates that + change other valid\nresources associated with PVC.\n\n\nThis + is an alpha field and requires enabling RecoverVolumeExpansionFailure + feature." + type: object + x-kubernetes-map-type: granular + allocatedResources: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: "allocatedResources tracks the resources allocated + to a PVC including its capacity.\nKey names follow standard + Kubernetes label syntax. Valid values are either:\n\t* + Un-prefixed keys:\n\t\t- storage - the capacity of the + volume.\n\t* Custom resources must use implementation-defined + prefixed names such as \"example.com/my-custom-resource\"\nApart + from above values - keys that are unprefixed or have kubernetes.io + prefix are considered\nreserved and hence may not be used.\n\n\nCapacity + reported here may be larger than the actual capacity when + a volume expansion operation\nis requested.\nFor storage + quota, the larger value from allocatedResources and PVC.spec.resources + is used.\nIf allocatedResources is not set, PVC.spec.resources + alone is used for quota calculation.\nIf a volume expansion + capacity request is lowered, allocatedResources is only\nlowered + if there are no expansion operations in progress and if + the actual volume capacity\nis equal or lower than the + requested capacity.\n\n\nA controller that receives PVC + update with previously unknown resourceName\nshould ignore + the update for the purpose it was designed. For example + - a controller that\nonly is responsible for resizing + capacity of the volume, should ignore PVC updates that + change other valid\nresources associated with PVC.\n\n\nThis + is an alpha field and requires enabling RecoverVolumeExpansionFailure + feature." + type: object + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: capacity represents the actual resources of + the underlying volume. + type: object + conditions: + description: |- + conditions is the current Condition of persistent volume claim. If underlying persistent volume is being + resized then the Condition will be set to 'ResizeStarted'. + items: + description: PersistentVolumeClaimCondition contains details + about state of pvc + properties: + lastProbeTime: + description: lastProbeTime is the time we probed the + condition. + format: date-time + type: string + lastTransitionTime: + description: lastTransitionTime is the time the condition + transitioned from one status to another. + format: date-time + type: string + message: + description: message is the human-readable message + indicating details about last transition. + type: string + reason: + description: |- + reason is a unique, this should be a short, machine understandable string that gives the reason + for condition's last transition. If it reports "ResizeStarted" that means the underlying + persistent volume is being resized. + type: string + status: + type: string + type: + description: PersistentVolumeClaimConditionType is + a valid value of PersistentVolumeClaimCondition.Type + type: string + required: + - status + - type + type: object + type: array + currentVolumeAttributesClassName: + description: |- + currentVolumeAttributesClassName is the current name of the VolumeAttributesClass the PVC is using. + When unset, there is no VolumeAttributeClass applied to this PersistentVolumeClaim + This is an alpha field and requires enabling VolumeAttributesClass feature. + type: string + modifyVolumeStatus: + description: |- + ModifyVolumeStatus represents the status object of ControllerModifyVolume operation. + When this is unset, there is no ModifyVolume operation being attempted. + This is an alpha field and requires enabling VolumeAttributesClass feature. + properties: + status: + description: "status is the status of the ControllerModifyVolume + operation. It can be in any of following states:\n + - Pending\n Pending indicates that the PersistentVolumeClaim + cannot be modified due to unmet requirements, such + as\n the specified VolumeAttributesClass not existing.\n + - InProgress\n InProgress indicates that the volume + is being modified.\n - Infeasible\n Infeasible indicates + that the request has been rejected as invalid by the + CSI driver. To\n\t resolve the error, a valid VolumeAttributesClass + needs to be specified.\nNote: New statuses can be + added in the future. Consumers should check for unknown + statuses and fail appropriately." + type: string + targetVolumeAttributesClassName: + description: targetVolumeAttributesClassName is the + name of the VolumeAttributesClass the PVC currently + being reconciled + type: string + required: + - status + type: object + phase: + description: phase represents the current phase of PersistentVolumeClaim. + type: string + type: object + type: object + type: array + x-kubernetes-list-type: atomic + volumeMounts: + description: VolumeMounts represents the mount points to use in the + underlying collector deployment(s) + items: + description: VolumeMount describes a mounting of a Volume within + a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-type: atomic + volumes: + description: Volumes represents which volumes to use in the underlying + collector deployment(s). + items: + description: Volume represents a named volume in a pod that may + be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: |- + awsElasticBlockStore represents an AWS Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + format: int32 + type: integer + readOnly: + description: |- + readOnly value true will force the readOnly setting in VolumeMounts. + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: boolean + volumeID: + description: |- + volumeID is unique ID of the persistent disk resource in AWS (Amazon EBS volume). + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data Disk mount on + the host and bind mount to the pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching mode: None, + Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data disk in the + blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in the blob + storage + type: string + fsType: + description: |- + fsType is Filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: multiple + blob disks per storage account Dedicated: single blob + disk per storage account Managed: azure managed data + disk (only in managed availability set). defaults to shared' + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File Service mount + on the host and bind mount to the pod. + properties: + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret that contains + Azure Storage Account Name and Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount on the host that + shares a pod's lifetime + properties: + monitors: + description: |- + monitors is Required: Monitors is a collection of Ceph monitors + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + items: + type: string + type: array + path: + description: 'path is Optional: Used as the mounted root, + rather than the full Ceph tree, default is /' + type: string + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: boolean + secretFile: + description: |- + secretFile is Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + secretRef: + description: |- + secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + user: + description: |- + user is optional: User is the rados user name, default is admin + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it + type: string + required: + - monitors + type: object + cinder: + description: |- + cinder represents a cinder volume attached and mounted on kubelets host machine. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: boolean + secretRef: + description: |- + secretRef is optional: points to a secret object containing parameters used to connect + to OpenStack. + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + description: |- + volumeID used to identify the volume in cinder. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that should populate + this volume + properties: + defaultMode: + description: |- + defaultMode is optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: optional specify whether the ConfigMap or its + keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + description: csi (Container Storage Interface) represents ephemeral + storage that is handled by certain external CSI drivers (Beta + feature). + properties: + driver: + description: |- + driver is the name of the CSI driver that handles this volume. + Consult with your admin for the correct name as registered in the cluster. + type: string + fsType: + description: |- + fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the associated CSI driver + which will determine the default filesystem to apply. + type: string + nodePublishSecretRef: + description: |- + nodePublishSecretRef is a reference to the secret object containing + sensitive information to pass to the CSI driver to complete the CSI + NodePublishVolume and NodeUnpublishVolume calls. + This field is optional, and may be empty if no secret is required. If the + secret object contains more than one secret, all secret references are passed. + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + description: |- + readOnly specifies a read-only configuration for the volume. + Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: |- + volumeAttributes stores driver-specific properties that are passed to the CSI + driver. Consult your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about the pod + that should populate this volume + properties: + defaultMode: + description: |- + Optional: mode bits to use on created files by default. Must be a + Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: Items is a list of downward API volume file + items: + description: DownwardAPIVolumeFile represents information + to create the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects a field of the pod: + only annotations, labels, name and namespace are + supported.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the relative path + name of the file to be created. Must not be absolute + or contain the ''..'' path. Must be utf-8 encoded. + The first item of the relative path must not start + with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + description: |- + emptyDir represents a temporary directory that shares a pod's lifetime. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + properties: + medium: + description: |- + medium represents what type of storage medium should back this directory. + The default is "" which means to use the node's default medium. + Must be an empty string (default) or Memory. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: |- + sizeLimit is the total amount of local storage required for this EmptyDir volume. + The size limit is also applicable for memory medium. + The maximum usage on memory medium EmptyDir would be the minimum value between + the SizeLimit specified here and the sum of memory limits of all containers in a pod. + The default is nil which means that the limit is undefined. + More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: |- + ephemeral represents a volume that is handled by a cluster storage driver. + The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, + and deleted when the pod is removed. + + + Use this if: + a) the volume is only needed while the pod runs, + b) features of normal volumes like restoring from snapshot or capacity + tracking are needed, + c) the storage driver is specified through a storage class, and + d) the storage driver supports dynamic volume provisioning through + a PersistentVolumeClaim (see EphemeralVolumeSource for more + information on the connection between this volume type + and PersistentVolumeClaim). + + + Use PersistentVolumeClaim or one of the vendor-specific + APIs for volumes that persist for longer than the lifecycle + of an individual pod. + + + Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to + be used that way - see the documentation of the driver for + more information. + + + A pod can use both types of ephemeral volumes and + persistent volumes at the same time. + properties: + volumeClaimTemplate: + description: |- + Will be used to create a stand-alone PVC to provision the volume. + The pod in which this EphemeralVolumeSource is embedded will be the + owner of the PVC, i.e. the PVC will be deleted together with the + pod. The name of the PVC will be `-` where + `` is the name from the `PodSpec.Volumes` array + entry. Pod validation will reject the pod if the concatenated name + is not valid for a PVC (for example, too long). + + + An existing PVC with that name that is not owned by the pod + will *not* be used for the pod to avoid using an unrelated + volume by mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created PVC is + meant to be used by the pod, the PVC has to updated with an + owner reference to the pod once the pod exists. Normally + this should not be necessary, but it may be useful when + manually reconstructing a broken cluster. + + + This field is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. + + + Required, must not be nil. + properties: + metadata: + description: |- + May contain labels and annotations that will be copied into the PVC + when creating it. No other fields are allowed and will be rejected during + validation. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: |- + The specification for the PersistentVolumeClaim. The entire content is + copied unchanged into the PVC that gets created from this + template. The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: |- + accessModes contains the desired access modes the volume should have. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1 + items: + type: string + type: array + dataSource: + description: |- + dataSource field can be used to specify either: + * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external controller can support the specified data source, + it will create a new volume based on the contents of the specified data source. + When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, + and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. + If the namespace is specified, then dataSourceRef will not be copied to dataSource. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: |- + dataSourceRef specifies the object from which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty API group (non + core object) or a PersistentVolumeClaim object. + When this field is specified, volume binding will only succeed if the type of + the specified object matches some installed volume populator or dynamic + provisioner. + This field will replace the functionality of the dataSource field and as such + if both fields are non-empty, they must have the same value. For backwards + compatibility, when namespace isn't specified in dataSourceRef, + both fields (dataSource and dataSourceRef) will be set to the same + value automatically if one of them is empty and the other is non-empty. + When namespace is specified in dataSourceRef, + dataSource isn't set to the same value and must be empty. + There are three important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping them), dataSourceRef + preserves all values, and generates an error if a disallowed value is + specified. + * While dataSource only allows local objects, dataSourceRef allows objects + in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. + (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + namespace: + description: |- + Namespace is the namespace of resource being referenced + Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. + (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: |- + resources represents the minimum resources the volume should have. + If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements + that are lower than previous value but must still be higher than capacity recorded in the + status field of the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + selector: + description: selector is a label query over volumes + to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: |- + storageClassName is the name of the StorageClass required by the claim. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1 + type: string + volumeAttributesClassName: + description: |- + volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim. + If specified, the CSI driver will create or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName, + it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass + will be applied to the claim but it's not allowed to reset this field to empty string once it is set. + If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller if it exists. + If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be + set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource + exists. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the VolumeAttributesClass feature gate to be enabled. + type: string + volumeMode: + description: |- + volumeMode defines what type of volume is required by the claim. + Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference + to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource that is + attached to a kubelet's host machine and then exposed to the + pod. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: |- + readOnly is Optional: Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target worldwide + names (WWNs)' + items: + type: string + type: array + wwids: + description: |- + wwids Optional: FC volume world wide identifiers (wwids) + Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously. + items: + type: string + type: array + type: object + flexVolume: + description: |- + flexVolume represents a generic volume resource that is + provisioned/attached using an exec based plugin. + properties: + driver: + description: driver is the name of the driver to use for + this volume. + type: string + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field holds extra + command options if any.' + type: object + readOnly: + description: |- + readOnly is Optional: defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef is Optional: secretRef is reference to the secret object containing + sensitive information to pass to the plugin scripts. This may be + empty if no secret object is specified. If the secret object + contains more than one secret, all secrets are passed to the plugin + scripts. + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume attached to + a kubelet's host machine. This depends on the Flocker control + service being running + properties: + datasetName: + description: |- + datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker + should be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. This + is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: |- + gcePersistentDisk represents a GCE Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + properties: + fsType: + description: |- + fsType is filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + partition: + description: |- + partition is the partition in the volume that you want to mount. + If omitted, the default is to mount by volume name. + Examples: For volume /dev/sda1, you specify the partition as "1". + Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + format: int32 + type: integer + pdName: + description: |- + pdName is unique name of the PD resource in GCE. Used to identify the disk in GCE. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + type: boolean + required: + - pdName + type: object + gitRepo: + description: |- + gitRepo represents a git repository at a particular revision. + DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an + EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir + into the Pod's container. + properties: + directory: + description: |- + directory is the target directory name. + Must not contain or start with '..'. If '.' is supplied, the volume directory will be the + git repository. Otherwise, if specified, the volume will contain the git repository in + the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the specified + revision. + type: string + required: + - repository + type: object + glusterfs: + description: |- + glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/glusterfs/README.md + properties: + endpoints: + description: |- + endpoints is the endpoint name that details Glusterfs topology. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + path: + description: |- + path is the Glusterfs volume path. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: string + readOnly: + description: |- + readOnly here will force the Glusterfs volume to be mounted with read-only permissions. + Defaults to false. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: |- + hostPath represents a pre-existing file or directory on the host + machine that is directly exposed to the container. This is generally + used for system agents or other privileged things that are allowed + to see the host machine. Most containers will NOT need this. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- + TODO(jonesdl) We need to restrict who can use host directory mounts and who can/can not + mount host directories as read/write. + properties: + path: + description: |- + path of the directory on the host. + If the path is a symlink, it will follow the link to the real path. + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + type: + description: |- + type for HostPath Volume + Defaults to "" + More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + type: string + required: + - path + type: object + iscsi: + description: |- + iscsi represents an ISCSI Disk resource that is attached to a + kubelet's host machine and then exposed to the pod. + More info: https://examples.k8s.io/volumes/iscsi/README.md + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether support iSCSI + Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support iSCSI + Session CHAP authentication + type: boolean + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + initiatorName: + description: |- + initiatorName is the custom iSCSI Initiator Name. + If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface + : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified Name. + type: string + iscsiInterface: + description: |- + iscsiInterface is the interface Name that uses an iSCSI transport. + Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: |- + portals is the iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for iSCSI target + and initiator authentication + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + description: |- + targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port + is other than default (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: |- + name of the volume. + Must be a DNS_LABEL and unique within the pod. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + nfs: + description: |- + nfs represents an NFS mount on the host that shares a pod's lifetime + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + properties: + path: + description: |- + path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + readOnly: + description: |- + readOnly here will force the NFS export to be mounted with read-only permissions. + Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: boolean + server: + description: |- + server is the hostname or IP address of the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: |- + persistentVolumeClaimVolumeSource represents a reference to a + PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + properties: + claimName: + description: |- + claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims + type: string + readOnly: + description: |- + readOnly Will force the ReadOnly setting in VolumeMounts. + Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets host machine + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon Controller + persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx volume attached + and mounted on kubelets host machine + properties: + fsType: + description: |- + fSType represents the filesystem type to mount + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources secrets, + configmaps, and downward API + properties: + defaultMode: + description: |- + defaultMode are the mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume projections + items: + description: Projection that may be projected along with + other supported volume types + properties: + clusterTrustBundle: + description: |- + ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field + of ClusterTrustBundle objects in an auto-updating file. + + + Alpha, gated by the ClusterTrustBundleProjection feature gate. + + + ClusterTrustBundle objects can either be selected by name, or by the + combination of signer name and a label selector. + + + Kubelet performs aggressive normalization of the PEM contents written + into the pod filesystem. Esoteric PEM features such as inter-block + comments and block headers are stripped. Certificates are deduplicated. + The ordering of certificates within the file is arbitrary, and Kubelet + may change the order over time. + properties: + labelSelector: + description: |- + Select all ClusterTrustBundles that match this label selector. Only has + effect if signerName is set. Mutually-exclusive with name. If unset, + interpreted as "match nothing". If set but empty, interpreted as "match + everything". + properties: + matchExpressions: + description: matchExpressions is a list of + label selector requirements. The requirements + are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + name: + description: |- + Select a single ClusterTrustBundle by object name. Mutually-exclusive + with signerName and labelSelector. + type: string + optional: + description: |- + If true, don't block pod startup if the referenced ClusterTrustBundle(s) + aren't available. If using name, then the named ClusterTrustBundle is + allowed not to exist. If using signerName, then the combination of + signerName and labelSelector is allowed to match zero + ClusterTrustBundles. + type: boolean + path: + description: Relative path from the volume root + to write the bundle. + type: string + signerName: + description: |- + Select all ClusterTrustBundles that match this signer name. + Mutually-exclusive with name. The contents of all selected + ClusterTrustBundles will be unified and deduplicated. + type: string + required: + - path + type: object + configMap: + description: configMap information about the configMap + data to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + ConfigMap will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the ConfigMap, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + description: downwardAPI information about the downwardAPI + data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects a field + of the pod: only annotations, labels, + name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, + defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: |- + Optional: mode bits used to set permissions on this file, must be an octal value + between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must + not be absolute or contain the ''..'' + path. Must be utf-8 encoded. The first + item of the relative path must not start + with ''..''' + type: string + resourceFieldRef: + description: |- + Selects a resource of the container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported. + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults + to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to + select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + description: secret information about the secret data + to project + properties: + items: + description: |- + items if unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + optional: + description: optional field specify whether the + Secret or its key must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + description: serviceAccountToken is information about + the serviceAccountToken data to project + properties: + audience: + description: |- + audience is the intended audience of the token. A recipient of a token + must identify itself with an identifier specified in the audience of the + token, and otherwise should reject the token. The audience defaults to the + identifier of the apiserver. + type: string + expirationSeconds: + description: |- + expirationSeconds is the requested duration of validity of the service + account token. As the token approaches expiration, the kubelet volume + plugin will proactively rotate the service account token. The kubelet will + start trying to rotate the token if the token is older than 80 percent of + its time to live or if the token is older than 24 hours.Defaults to 1 hour + and must be at least 10 minutes. + format: int64 + type: integer + path: + description: |- + path is the path relative to the mount point of the file to project the + token into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: quobyte represents a Quobyte mount on the host + that shares a pod's lifetime + properties: + group: + description: |- + group to map volume access to + Default is no group + type: string + readOnly: + description: |- + readOnly here will force the Quobyte volume to be mounted with read-only permissions. + Defaults to false. + type: boolean + registry: + description: |- + registry represents a single or multiple Quobyte Registry services + specified as a string as host:port pair (multiple entries are separated with commas) + which acts as the central registry for volumes + type: string + tenant: + description: |- + tenant owning the given Quobyte volume in the Backend + Used with dynamically provisioned Quobyte volumes, value is set by the plugin + type: string + user: + description: |- + user to map volume access to + Defaults to serivceaccount user + type: string + volume: + description: volume is a string that references an already + created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: |- + rbd represents a Rados Block Device mount on the host that shares a pod's lifetime. + More info: https://examples.k8s.io/volumes/rbd/README.md + properties: + fsType: + description: |- + fsType is the filesystem type of the volume that you want to mount. + Tip: Ensure that the filesystem type is supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem from compromising the machine + type: string + image: + description: |- + image is the rados image name. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + keyring: + description: |- + keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + monitors: + description: |- + monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + items: + type: string + type: array + pool: + description: |- + pool is the rados pool name. + Default is rbd. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + readOnly: + description: |- + readOnly here will force the ReadOnly setting in VolumeMounts. + Defaults to false. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: boolean + secretRef: + description: |- + secretRef is name of the authentication secret for RBDUser. If provided + overrides keyring. + Default is nil. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + user: + description: |- + user is the rados user name. + Default is admin. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". + Default is "xfs". + type: string + gateway: + description: gateway is the host address of the ScaleIO + API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the ScaleIO + Protection Domain for the configured storage. + type: string + readOnly: + description: |- + readOnly Defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef references to the secret for ScaleIO user and other + sensitive information. If this is not provided, Login operation will fail. + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + description: sslEnabled Flag enable/disable SSL communication + with Gateway, default false + type: boolean + storageMode: + description: |- + storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage Pool associated + with the protection domain. + type: string + system: + description: system is the name of the storage system as + configured in ScaleIO. + type: string + volumeName: + description: |- + volumeName is the name of a volume already created in the ScaleIO system + that is associated with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: |- + secret represents a secret that should populate this volume. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + properties: + defaultMode: + description: |- + defaultMode is Optional: mode bits used to set permissions on created files by default. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values + for mode bits. Defaults to 0644. + Directories within the path are not affected by this setting. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + items: + description: |- + items If unspecified, each key-value pair in the Data field of the referenced + Secret will be projected into the volume as a file whose name is the + key and content is the value. If specified, the listed keys will be + projected into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in the Secret, + the volume setup will error unless it is marked optional. Paths must be + relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: |- + mode is Optional: mode bits used to set permissions on this file. + Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. + If not specified, the volume defaultMode will be used. + This might be in conflict with other options that affect the file + mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + path: + description: |- + path is the relative path of the file to map the key to. + May not be an absolute path. + May not contain the path element '..'. + May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the Secret or + its keys must be defined + type: boolean + secretName: + description: |- + secretName is the name of the secret in the pod's namespace to use. + More info: https://kubernetes.io/docs/concepts/storage/volumes#secret + type: string + type: object + storageos: + description: storageOS represents a StorageOS volume attached + and mounted on Kubernetes nodes. + properties: + fsType: + description: |- + fsType is the filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: |- + readOnly defaults to false (read/write). ReadOnly here will force + the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: |- + secretRef specifies the secret to use for obtaining the StorageOS API + credentials. If not specified, default values will be attempted. + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + description: |- + volumeName is the human-readable name of the StorageOS volume. Volume + names are only unique within a namespace. + type: string + volumeNamespace: + description: |- + volumeNamespace specifies the scope of the volume within StorageOS. If no + namespace is specified then the Pod's namespace will be used. This allows the + Kubernetes name scoping to be mirrored within StorageOS for tighter integration. + Set VolumeName to any name to override the default behaviour. + Set to "default" if you are not using namespaces within StorageOS. + Namespaces that do not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere volume attached + and mounted on kubelets host machine + properties: + fsType: + description: |- + fsType is filesystem type to mount. + Must be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy Based + Management (SPBM) profile ID associated with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage Policy Based + Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies vSphere + volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + x-kubernetes-list-type: atomic + workingDir: + description: |- + WorkingDir represents Container's working directory. If not specified, + the container runtime's default will be used, which might + be configured in the container image. Cannot be updated. + type: string + type: object + status: + description: AmazonCloudWatchAgentStatus defines the observed state of + AmazonCloudWatchAgent. + properties: + image: + description: Image indicates the container image to use for the OpenTelemetry + Collector. + type: string + messages: + description: |- + Messages about actions performed by the operator on this resource. + Deprecated: use Kubernetes events instead. + items: + type: string + type: array + x-kubernetes-list-type: atomic + replicas: + description: |- + Replicas is currently not being set and might be removed in the next version. + Deprecated: use "AmazonCloudWatchAgent.Status.Scale.Replicas" instead. + format: int32 + type: integer + scale: + description: Scale is the AmazonCloudWatchAgent's scale subresource + status. + properties: + replicas: + description: |- + The total number non-terminated pods targeted by this + AmazonCloudWatchAgent's deployment or statefulSet. + format: int32 + type: integer + selector: + description: |- + The selector used to match the AmazonCloudWatchAgent's + deployment or statefulSet pods. + type: string + statusReplicas: + description: |- + StatusReplicas is the number of pods targeted by this AmazonCloudWatchAgent's with a Ready Condition / + Total number of non-terminated pods targeted by this AmazonCloudWatchAgent's (their labels match the selector). + Deployment, Daemonset, StatefulSet. + type: string + type: object + version: + description: Version of the managed OpenTelemetry Collector (operand) + type: string + type: object + type: object + served: true + storage: true + subresources: + scale: + labelSelectorPath: .status.scale.selector + specReplicasPath: .spec.replicas + statusReplicasPath: .status.scale.replicas + status: {} diff --git a/charts/amazon-cloudwatch-observability/crds/cloudwatch.aws.amazon.com_dcgmexporters.yaml b/charts/amazon-cloudwatch-observability/crds/cloudwatch.aws.amazon.com_dcgmexporters.yaml new file mode 100644 index 0000000..7109831 --- /dev/null +++ b/charts/amazon-cloudwatch-observability/crds/cloudwatch.aws.amazon.com_dcgmexporters.yaml @@ -0,0 +1,3263 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.12.0 + name: dcgmexporters.cloudwatch.aws.amazon.com +spec: + group: cloudwatch.aws.amazon.com + names: + kind: DcgmExporter + listKind: DcgmExporterList + plural: dcgmexporters + shortNames: + - dcgmexp + - dcgmexps + singular: dcgmexporter + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: DCGM exporter Version + jsonPath: .status.version + name: Version + type: string + - jsonPath: .status.scale.statusReplicas + name: Ready + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.image + name: Image + type: string + - description: Management State + jsonPath: .spec.managementState + name: Management + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: DcgmExporter is the Schema for the DcgmExporters API. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: DcgmExporterSpec defines the desired state of DcgmExporter. + properties: + securityContext: + description: "SecurityContext configures the container security context + for the amazon-cloudwatch-agent container. \n In deployment, daemonset, + or statefulset mode, this controls the security context settings + for the primary application container. \n In sidecar mode, this + controls the security context for the injected sidecar container." + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a process + can gain more privileges than its parent process. This bool + directly controls if the no_new_privs flag will be set on the + container process. AllowPrivilegeEscalation is true always when + the container is: 1) run as Privileged 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container + runtime. Note that this field cannot be set when spec.os.name + is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in privileged + containers are essentially equivalent to root on the host. Defaults + to false. Note that this field cannot be set when spec.os.name + is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use for + the containers. The default is DefaultProcMount which uses the + container runtime defaults for readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when spec.os.name + is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container process. + Uses runtime default if unset. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence. Note that this + field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail to start + the container if it does. If unset or false, no such validation + will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when spec.os.name + is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence. Note that this + field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to + the container. + type: string + role: + description: Role is a SELinux role label that applies to + the container. + type: string + type: + description: Type is a SELinux type label that applies to + the container. + type: string + user: + description: User is a SELinux user label that applies to + the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. If + seccomp options are provided at both the pod & container level, + the container options override the pod options. Note that this + field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must be + preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must be set if type is "Localhost". Must NOT be + set for any other type. + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a profile + defined in a file on the node should be used. RuntimeDefault + - the container runtime default profile should be used. + Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will + be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named by + the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA + credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. All of a Pod's containers + must have the same effective HostProcess value (it is not + allowed to have a mix of HostProcess containers and non-HostProcess + containers). In addition, if HostProcess is true then HostNetwork + must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in PodSecurityContext. + If set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: string + type: object + type: object + affinity: + description: If specified, indicates the pod's scheduling constraints + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for the + pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the affinity expressions specified by + this field, but it may choose a node that violates one or + more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node matches + the corresponding matchExpressions; the node(s) with the + highest sum are the most preferred. + items: + description: An empty preferred scheduling term matches + all objects with implicit weight 0 (i.e. it's a no-op). + A null preferred scheduling term matches no objects (i.e. + is also a no-op). + properties: + preference: + description: A node selector term, associated with the + corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching the corresponding + nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this + field are not met at scheduling time, the pod will not be + scheduled onto the node. If the affinity requirements specified + by this field cease to be met at some point during pod execution + (e.g. due to an update), the system may or may not try to + eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: A null or empty node selector term matches + no objects. The requirements of them are ANDed. The + TopologySelectorTerm type implements a subset of the + NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. co-locate + this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the affinity expressions specified by + this field, but it may choose a node that violates one or + more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node has + pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: MatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key in (value)` to select + the group of existing pods which pods will be + taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MatchLabelKeys and LabelSelector. Also, + MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key notin (value)` to + select the group of existing pods which pods will + be taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MismatchLabelKeys and LabelSelector. Also, + MismatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding + podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this + field are not met at scheduling time, the pod will not be + scheduled onto the node. If the affinity requirements specified + by this field cease to be met at some point during pod execution + (e.g. due to a pod label update), the system may or may + not try to eventually evict the pod from its node. When + there are multiple elements, the lists of nodes corresponding + to each podAffinityTerm are intersected, i.e. all terms + must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not co-located + (anti-affinity) with, where co-located is defined as running + on a node whose value of the label with key + matches that of any node on which a pod of the set of + pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: MatchLabelKeys is a set of pod label keys + to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged with + `LabelSelector` as `key in (value)` to select the + group of existing pods which pods will be taken into + consideration for the incoming pod's pod (anti) affinity. + Keys that don't exist in the incoming pod labels will + be ignored. The default value is empty. The same key + is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires enabling + MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged with + `LabelSelector` as `key notin (value)` to select the + group of existing pods which pods will be taken into + consideration for the incoming pod's pod (anti) affinity. + Keys that don't exist in the incoming pod labels will + be ignored. The default value is empty. The same key + is forbidden to exist in both MismatchLabelKeys and + LabelSelector. Also, MismatchLabelKeys cannot be set + when LabelSelector isn't set. This is an alpha field + and requires enabling MatchLabelKeysInPodAffinity + feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied to the + union of the namespaces selected by this field and + the ones listed in the namespaces field. null selector + and null or empty namespaces list means "this pod's + namespace". An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list of namespace + names that the term applies to. The term is applied + to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. null or + empty namespaces list and null namespaceSelector means + "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where + co-located is defined as running on a node whose value + of the label with key topologyKey matches that of + any node on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules (e.g. + avoid putting this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the anti-affinity expressions specified + by this field, but it may choose a node that violates one + or more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node has + pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: MatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key in (value)` to select + the group of existing pods which pods will be + taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MatchLabelKeys and LabelSelector. Also, + MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key notin (value)` to + select the group of existing pods which pods will + be taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MismatchLabelKeys and LabelSelector. Also, + MismatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding + podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the anti-affinity requirements + specified by this field cease to be met at some point during + pod execution (e.g. due to a pod label update), the system + may or may not try to eventually evict the pod from its + node. When there are multiple elements, the lists of nodes + corresponding to each podAffinityTerm are intersected, i.e. + all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not co-located + (anti-affinity) with, where co-located is defined as running + on a node whose value of the label with key + matches that of any node on which a pod of the set of + pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: MatchLabelKeys is a set of pod label keys + to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged with + `LabelSelector` as `key in (value)` to select the + group of existing pods which pods will be taken into + consideration for the incoming pod's pod (anti) affinity. + Keys that don't exist in the incoming pod labels will + be ignored. The default value is empty. The same key + is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires enabling + MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged with + `LabelSelector` as `key notin (value)` to select the + group of existing pods which pods will be taken into + consideration for the incoming pod's pod (anti) affinity. + Keys that don't exist in the incoming pod labels will + be ignored. The default value is empty. The same key + is forbidden to exist in both MismatchLabelKeys and + LabelSelector. Also, MismatchLabelKeys cannot be set + when LabelSelector isn't set. This is an alpha field + and requires enabling MatchLabelKeysInPodAffinity + feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied to the + union of the namespaces selected by this field and + the ones listed in the namespaces field. null selector + and null or empty namespaces list means "this pod's + namespace". An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list of namespace + names that the term applies to. The term is applied + to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. null or + empty namespaces list and null namespaceSelector means + "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where + co-located is defined as running on a node whose value + of the label with key topologyKey matches that of + any node on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + args: + additionalProperties: + type: string + description: Args is the set of arguments to pass to the DCGM Exporter + binary + type: object + env: + description: ENV vars to set on the DCGM Exporter Pods. These can + then in certain cases be consumed in the config file for the Collector. + items: + description: EnvVar represents an environment variable present in + a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded using + the previously defined environment variables in the container + and any service environment variables. If a variable cannot + be resolved, the reference in the input string will be unchanged. + Double $$ are reduced to a single $, which allows for escaping + the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the + string literal "$(VAR_NAME)". Escaped references will never + be expanded, regardless of whether the variable exists or + not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. Cannot + be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, `metadata.annotations['''']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, + status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is + written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified + API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed + resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: Image indicates the container image to use for the DCGM + Exporter. + type: string + metricsConfig: + description: MetricsConfig is the raw CSV to be used as metric configuration. + type: string + nodeSelector: + additionalProperties: + type: string + description: NodeSelector to schedule DCGM Exporter pods. This is + only relevant to daemonset, statefulset, and deployment mode + type: object + ports: + description: Ports allows a set of ports to be exposed by the underlying + v1.Service. By default, the operator will attempt to infer the required + ports by parsing the .Spec.Config property but this property can + be used to open additional ports that can't be inferred by the operator, + like for custom receivers. + items: + description: ServicePort contains information on service's port. + properties: + appProtocol: + description: "The application protocol for this port. This is + used as a hint for implementations to offer richer behavior + for protocols that they understand. This field follows standard + Kubernetes label syntax. Valid values are either: \n * Un-prefixed + protocol names - reserved for IANA standard service names + (as per RFC-6335 and https://www.iana.org/assignments/service-names). + \n * Kubernetes-defined prefixed names: * 'kubernetes.io/h2c' + - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described + in https://www.rfc-editor.org/rfc/rfc6455 * 'kubernetes.io/wss' + - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + \n * Other protocols should use implementation-defined prefixed + names such as mycompany.com/my-custom-protocol." + type: string + name: + description: The name of this port within the service. This + must be a DNS_LABEL. All ports within a ServiceSpec must have + unique names. When considering the endpoints for a Service, + this must match the 'name' field in the EndpointPort. Optional + if only one ServicePort is defined on this service. + type: string + nodePort: + description: 'The port on each node on which this service is + exposed when type is NodePort or LoadBalancer. Usually assigned + by the system. If a value is specified, in-range, and not + in use it will be used, otherwise the operation will fail. If + not specified, a port will be allocated if this Service requires + one. If this field is specified when creating a Service which + does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing + type from NodePort to ClusterIP). More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport' + format: int32 + type: integer + port: + description: The port that will be exposed by this service. + format: int32 + type: integer + protocol: + default: TCP + description: The IP protocol for this port. Supports "TCP", + "UDP", and "SCTP". Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: 'Number or name of the port to access on the pods + targeted by the service. Number must be in the range 1 to + 65535. Name must be an IANA_SVC_NAME. If this is a string, + it will be looked up as a named port in the target Pod''s + container ports. If this is not specified, the value of the + ''port'' field is used (an identity map). This field is ignored + for services with clusterIP=None, and should be omitted or + set equal to the ''port'' field. More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service' + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: Resources to set on the DCGM Exporter pods. + properties: + claims: + description: "Claims lists the names of resources, defined in + spec.resourceClaims, that are used by this container. \n This + is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be set + for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims + of the Pod where this field is used. It makes that resource + available inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources + allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + serviceAccount: + description: ServiceAccount indicates the name of an existing service + account to use with this instance. When set, the operator will not + automatically create a ServiceAccount for the collector. + type: string + tlsConfig: + description: TlsConfig is the raw YAML to be used as the exporter + TLS configuration. + type: string + tolerations: + description: Toleration to schedule DCGM Exporter pods. + This is only relevant to daemonset, statefulset, and deployment + mode + items: + description: The pod this Toleration is attached to tolerates any + taint that matches the triple using the matching + operator . + properties: + effect: + description: Effect indicates the taint effect to match. Empty + means match all taint effects. When specified, allowed values + are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match all + values and all keys. + type: string + operator: + description: Operator represents a key's relationship to the + value. Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod + can tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of time + the toleration (which must be of effect NoExecute, otherwise + this field is ignored) tolerates the taint. By default, it + is not set, which means tolerate the taint forever (do not + evict). Zero and negative values will be treated as 0 (evict + immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + volumeMounts: + description: VolumeMounts represents the mount points to use in the + underlying collector deployment(s) + items: + description: VolumeMount describes a mounting of a Volume within + a container. + properties: + mountPath: + description: Path within the container at which the volume should + be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are propagated + from the host to container and the other way around. When + not set, MountPropagationNone is used. This field is beta + in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise + (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's + volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which the + container's volume should be mounted. Behaves similarly to + SubPath but environment variable references $(VAR_NAME) are + expanded using the container's environment. Defaults to "" + (volume's root). SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-type: atomic + volumes: + description: Volumes represents which volumes to use in the underlying + collector deployment(s). + items: + description: Volume represents a named volume in a pod that may + be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: 'awsElasticBlockStore represents an AWS Disk resource + that is attached to a kubelet''s host machine and then exposed + to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + properties: + fsType: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + partition: + description: 'partition is the partition in the volume that + you want to mount. If omitted, the default is to mount + by volume name. Examples: For volume /dev/sda1, you specify + the partition as "1". Similarly, the volume partition + for /dev/sda is "0" (or you can leave the property empty).' + format: int32 + type: integer + readOnly: + description: 'readOnly value true will force the readOnly + setting in VolumeMounts. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: boolean + volumeID: + description: 'volumeID is unique ID of the persistent disk + resource in AWS (Amazon EBS volume). More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data Disk mount on + the host and bind mount to the pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching mode: None, + Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data disk in the + blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in the blob + storage + type: string + fsType: + description: fsType is Filesystem type to mount. Must be + a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. + type: string + kind: + description: 'kind expected values are Shared: multiple + blob disks per storage account Dedicated: single blob + disk per storage account Managed: azure managed data + disk (only in managed availability set). defaults to shared' + type: string + readOnly: + description: readOnly Defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File Service mount + on the host and bind mount to the pod. + properties: + readOnly: + description: readOnly defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret that contains + Azure Storage Account Name and Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount on the host that + shares a pod's lifetime + properties: + monitors: + description: 'monitors is Required: Monitors is a collection + of Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + items: + type: string + type: array + path: + description: 'path is Optional: Used as the mounted root, + rather than the full Ceph tree, default is /' + type: string + readOnly: + description: 'readOnly is Optional: Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: boolean + secretFile: + description: 'secretFile is Optional: SecretFile is the + path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + secretRef: + description: 'secretRef is Optional: SecretRef is reference + to the authentication secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + user: + description: 'user is optional: User is the rados user name, + default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + required: + - monitors + type: object + cinder: + description: 'cinder represents a cinder volume attached and + mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + properties: + fsType: + description: 'fsType is the filesystem type to mount. Must + be a filesystem type supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to + be "ext4" if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + readOnly: + description: 'readOnly defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: boolean + secretRef: + description: 'secretRef is optional: points to a secret + object containing parameters used to connect to OpenStack.' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + description: 'volumeID used to identify the volume in cinder. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that should populate + this volume + properties: + defaultMode: + description: 'defaultMode is optional: mode bits used to + set permissions on created files by default. Must be an + octal value between 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and decimal values, + JSON requires decimal values for mode bits. Defaults to + 0644. Directories within the path are not affected by + this setting. This might be in conflict with other options + that affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + items: + description: items if unspecified, each key-value pair in + the Data field of the referenced ConfigMap will be projected + into the volume as a file whose name is the key and content + is the value. If specified, the listed keys will be projected + into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in + the ConfigMap, the volume setup will error unless it is + marked optional. Paths must be relative and may not contain + the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used to + set permissions on this file. Must be an octal value + between 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and decimal values, + JSON requires decimal values for mode bits. If not + specified, the volume defaultMode will be used. + This might be in conflict with other options that + affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of the file + to map the key to. May not be an absolute path. + May not contain the path element '..'. May not start + with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: optional specify whether the ConfigMap or its + keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + description: csi (Container Storage Interface) represents ephemeral + storage that is handled by certain external CSI drivers (Beta + feature). + properties: + driver: + description: driver is the name of the CSI driver that handles + this volume. Consult with your admin for the correct name + as registered in the cluster. + type: string + fsType: + description: fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the associated + CSI driver which will determine the default filesystem + to apply. + type: string + nodePublishSecretRef: + description: nodePublishSecretRef is a reference to the + secret object containing sensitive information to pass + to the CSI driver to complete the CSI NodePublishVolume + and NodeUnpublishVolume calls. This field is optional, + and may be empty if no secret is required. If the secret + object contains more than one secret, all secret references + are passed. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + description: readOnly specifies a read-only configuration + for the volume. Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: volumeAttributes stores driver-specific properties + that are passed to the CSI driver. Consult your driver's + documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about the pod + that should populate this volume + properties: + defaultMode: + description: 'Optional: mode bits to use on created files + by default. Must be a Optional: mode bits used to set + permissions on created files by default. Must be an octal + value between 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and decimal values, + JSON requires decimal values for mode bits. Defaults to + 0644. Directories within the path are not affected by + this setting. This might be in conflict with other options + that affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + items: + description: Items is a list of downward API volume file + items: + description: DownwardAPIVolumeFile represents information + to create the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects a field of the pod: + only annotations, labels, name and namespace are + supported.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: 'Optional: mode bits used to set permissions + on this file, must be an octal value between 0000 + and 0777 or a decimal value between 0 and 511. YAML + accepts both octal and decimal values, JSON requires + decimal values for mode bits. If not specified, + the volume defaultMode will be used. This might + be in conflict with other options that affect the + file mode, like fsGroup, and the result can be other + mode bits set.' + format: int32 + type: integer + path: + description: 'Required: Path is the relative path + name of the file to be created. Must not be absolute + or contain the ''..'' path. Must be utf-8 encoded. + The first item of the relative path must not start + with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, requests.cpu and requests.memory) + are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + description: 'emptyDir represents a temporary directory that + shares a pod''s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + properties: + medium: + description: 'medium represents what type of storage medium + should back this directory. The default is "" which means + to use the node''s default medium. Must be an empty string + (default) or Memory. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: 'sizeLimit is the total amount of local storage + required for this EmptyDir volume. The size limit is also + applicable for memory medium. The maximum usage on memory + medium EmptyDir would be the minimum value between the + SizeLimit specified here and the sum of memory limits + of all containers in a pod. The default is nil which means + that the limit is undefined. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: "ephemeral represents a volume that is handled + by a cluster storage driver. The volume's lifecycle is tied + to the pod that defines it - it will be created before the + pod starts, and deleted when the pod is removed. \n Use this + if: a) the volume is only needed while the pod runs, b) features + of normal volumes like restoring from snapshot or capacity + tracking are needed, c) the storage driver is specified through + a storage class, and d) the storage driver supports dynamic + volume provisioning through a PersistentVolumeClaim (see EphemeralVolumeSource + for more information on the connection between this volume + type and PersistentVolumeClaim). \n Use PersistentVolumeClaim + or one of the vendor-specific APIs for volumes that persist + for longer than the lifecycle of an individual pod. \n Use + CSI for light-weight local ephemeral volumes if the CSI driver + is meant to be used that way - see the documentation of the + driver for more information. \n A pod can use both types of + ephemeral volumes and persistent volumes at the same time." + properties: + volumeClaimTemplate: + description: "Will be used to create a stand-alone PVC to + provision the volume. The pod in which this EphemeralVolumeSource + is embedded will be the owner of the PVC, i.e. the PVC + will be deleted together with the pod. The name of the + PVC will be `-` where `` is the name from the `PodSpec.Volumes` array entry. + Pod validation will reject the pod if the concatenated + name is not valid for a PVC (for example, too long). \n + An existing PVC with that name that is not owned by the + pod will *not* be used for the pod to avoid using an unrelated + volume by mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created PVC + is meant to be used by the pod, the PVC has to updated + with an owner reference to the pod once the pod exists. + Normally this should not be necessary, but it may be useful + when manually reconstructing a broken cluster. \n This + field is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. \n Required, must + not be nil." + properties: + metadata: + description: May contain labels and annotations that + will be copied into the PVC when creating it. No other + fields are allowed and will be rejected during validation. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: The specification for the PersistentVolumeClaim. + The entire content is copied unchanged into the PVC + that gets created from this template. The same fields + as in a PersistentVolumeClaim are also valid here. + properties: + accessModes: + description: 'accessModes contains the desired access + modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'dataSource field can be used to specify + either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) If the + provisioner or an external controller can support + the specified data source, it will create a new + volume based on the contents of the specified + data source. When the AnyVolumeDataSource feature + gate is enabled, dataSource contents will be copied + to dataSourceRef, and dataSourceRef contents will + be copied to dataSource when dataSourceRef.namespace + is not specified. If the namespace is specified, + then dataSourceRef will not be copied to dataSource.' + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API + group. For any other third-party types, APIGroup + is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: 'dataSourceRef specifies the object + from which to populate the volume with data, if + a non-empty volume is desired. This may be any + object from a non-empty API group (non core object) + or a PersistentVolumeClaim object. When this field + is specified, volume binding will only succeed + if the type of the specified object matches some + installed volume populator or dynamic provisioner. + This field will replace the functionality of the + dataSource field and as such if both fields are + non-empty, they must have the same value. For + backwards compatibility, when namespace isn''t + specified in dataSourceRef, both fields (dataSource + and dataSourceRef) will be set to the same value + automatically if one of them is empty and the + other is non-empty. When namespace is specified + in dataSourceRef, dataSource isn''t set to the + same value and must be empty. There are three + important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types + of objects, dataSourceRef allows any non-core + object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping + them), dataSourceRef preserves all values, and + generates an error if a disallowed value is specified. + * While dataSource only allows local objects, + dataSourceRef allows objects in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource + feature gate to be enabled. (Alpha) Using the + namespace field of dataSourceRef requires the + CrossNamespaceVolumeDataSource feature gate to + be enabled.' + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API + group. For any other third-party types, APIGroup + is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + namespace: + description: Namespace is the namespace of resource + being referenced Note that when a namespace + is specified, a gateway.networking.k8s.io/ReferenceGrant + object is required in the referent namespace + to allow that namespace's owner to accept + the reference. See the ReferenceGrant documentation + for details. (Alpha) This field requires the + CrossNamespaceVolumeDataSource feature gate + to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: 'resources represents the minimum resources + the volume should have. If RecoverVolumeExpansionFailure + feature is enabled users are allowed to specify + resource requirements that are lower than previous + value but must still be higher than capacity recorded + in the status field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount + of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum + amount of compute resources required. If Requests + is omitted for a container, it defaults to + Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests + cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + selector: + description: selector is a label query over volumes + to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: 'storageClassName is the name of the + StorageClass required by the claim. More info: + https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + type: string + volumeAttributesClassName: + description: 'volumeAttributesClassName may be used + to set the VolumeAttributesClass used by this + claim. If specified, the CSI driver will create + or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This + has a different purpose than storageClassName, + it can be changed after the claim is created. + An empty string value means that no VolumeAttributesClass + will be applied to the claim but it''s not allowed + to reset this field to empty string once it is + set. If unspecified and the PersistentVolumeClaim + is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller + if it exists. If the resource referred to by volumeAttributesClass + does not exist, this PersistentVolumeClaim will + be set to a Pending state, as reflected by the + modifyVolumeStatus field, until such as a resource + exists. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the VolumeAttributesClass + feature gate to be enabled.' + type: string + volumeMode: + description: volumeMode defines what type of volume + is required by the claim. Value of Filesystem + is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference + to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource that is + attached to a kubelet's host machine and then exposed to the + pod. + properties: + fsType: + description: 'fsType is the filesystem type to mount. Must + be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. TODO: how do we prevent errors in the + filesystem from compromising the machine' + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: 'readOnly is Optional: Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts.' + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target worldwide + names (WWNs)' + items: + type: string + type: array + wwids: + description: 'wwids Optional: FC volume world wide identifiers + (wwids) Either wwids or combination of targetWWNs and + lun must be set, but not both simultaneously.' + items: + type: string + type: array + type: object + flexVolume: + description: flexVolume represents a generic volume resource + that is provisioned/attached using an exec based plugin. + properties: + driver: + description: driver is the name of the driver to use for + this volume. + type: string + fsType: + description: fsType is the filesystem type to mount. Must + be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". The default filesystem depends + on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field holds extra + command options if any.' + type: object + readOnly: + description: 'readOnly is Optional: defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts.' + type: boolean + secretRef: + description: 'secretRef is Optional: secretRef is reference + to the secret object containing sensitive information + to pass to the plugin scripts. This may be empty if no + secret object is specified. If the secret object contains + more than one secret, all secrets are passed to the plugin + scripts.' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume attached to + a kubelet's host machine. This depends on the Flocker control + service being running + properties: + datasetName: + description: datasetName is Name of the dataset stored as + metadata -> name on the dataset for Flocker should be + considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. This + is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: 'gcePersistentDisk represents a GCE Disk resource + that is attached to a kubelet''s host machine and then exposed + to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + properties: + fsType: + description: 'fsType is filesystem type of the volume that + you want to mount. Tip: Ensure that the filesystem type + is supported by the host operating system. Examples: "ext4", + "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + partition: + description: 'partition is the partition in the volume that + you want to mount. If omitted, the default is to mount + by volume name. Examples: For volume /dev/sda1, you specify + the partition as "1". Similarly, the volume partition + for /dev/sda is "0" (or you can leave the property empty). + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + format: int32 + type: integer + pdName: + description: 'pdName is unique name of the PD resource in + GCE. Used to identify the disk in GCE. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: string + readOnly: + description: 'readOnly here will force the ReadOnly setting + in VolumeMounts. Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: boolean + required: + - pdName + type: object + gitRepo: + description: 'gitRepo represents a git repository at a particular + revision. DEPRECATED: GitRepo is deprecated. To provision + a container with a git repo, mount an EmptyDir into an InitContainer + that clones the repo using git, then mount the EmptyDir into + the Pod''s container.' + properties: + directory: + description: directory is the target directory name. Must + not contain or start with '..'. If '.' is supplied, the + volume directory will be the git repository. Otherwise, + if specified, the volume will contain the git repository + in the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the specified + revision. + type: string + required: + - repository + type: object + glusterfs: + description: 'glusterfs represents a Glusterfs mount on the + host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md' + properties: + endpoints: + description: 'endpoints is the endpoint name that details + Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + path: + description: 'path is the Glusterfs volume path. More info: + https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + readOnly: + description: 'readOnly here will force the Glusterfs volume + to be mounted with read-only permissions. Defaults to + false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: 'hostPath represents a pre-existing file or directory + on the host machine that is directly exposed to the container. + This is generally used for system agents or other privileged + things that are allowed to see the host machine. Most containers + will NOT need this. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- TODO(jonesdl) We need to restrict who can use host directory + mounts and who can/can not mount host directories as read/write.' + properties: + path: + description: 'path of the directory on the host. If the + path is a symlink, it will follow the link to the real + path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + type: + description: 'type for HostPath Volume Defaults to "" More + info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + required: + - path + type: object + iscsi: + description: 'iscsi represents an ISCSI Disk resource that is + attached to a kubelet''s host machine and then exposed to + the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md' + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether support iSCSI + Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support iSCSI + Session CHAP authentication + type: boolean + fsType: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + initiatorName: + description: initiatorName is the custom iSCSI Initiator + Name. If initiatorName is specified with iscsiInterface + simultaneously, new iSCSI interface : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified Name. + type: string + iscsiInterface: + description: iscsiInterface is the interface Name that uses + an iSCSI transport. Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: portals is the iSCSI Target Portal List. The + portal is either an IP or ip_addr:port if the port is + other than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: readOnly here will force the ReadOnly setting + in VolumeMounts. Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for iSCSI target + and initiator authentication + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + description: targetPortal is iSCSI Target Portal. The Portal + is either an IP or ip_addr:port if the port is other than + default (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: 'name of the volume. Must be a DNS_LABEL and unique + within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + nfs: + description: 'nfs represents an NFS mount on the host that shares + a pod''s lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + properties: + path: + description: 'path that is exported by the NFS server. More + info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + readOnly: + description: 'readOnly here will force the NFS export to + be mounted with read-only permissions. Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: boolean + server: + description: 'server is the hostname or IP address of the + NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: 'persistentVolumeClaimVolumeSource represents a + reference to a PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + claimName: + description: 'claimName is the name of a PersistentVolumeClaim + in the same namespace as the pod using this volume. More + info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + type: string + readOnly: + description: readOnly Will force the ReadOnly setting in + VolumeMounts. Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets host machine + properties: + fsType: + description: fsType is the filesystem type to mount. Must + be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon Controller + persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx volume attached + and mounted on kubelets host machine + properties: + fsType: + description: fSType represents the filesystem type to mount + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs". Implicitly inferred to be "ext4" + if unspecified. + type: string + readOnly: + description: readOnly defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources secrets, + configmaps, and downward API + properties: + defaultMode: + description: defaultMode are the mode bits used to set permissions + on created files by default. Must be an octal value between + 0000 and 0777 or a decimal value between 0 and 511. YAML + accepts both octal and decimal values, JSON requires decimal + values for mode bits. Directories within the path are + not affected by this setting. This might be in conflict + with other options that affect the file mode, like fsGroup, + and the result can be other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume projections + items: + description: Projection that may be projected along with + other supported volume types + properties: + clusterTrustBundle: + description: "ClusterTrustBundle allows a pod to access + the `.spec.trustBundle` field of ClusterTrustBundle + objects in an auto-updating file. \n Alpha, gated + by the ClusterTrustBundleProjection feature gate. + \n ClusterTrustBundle objects can either be selected + by name, or by the combination of signer name and + a label selector. \n Kubelet performs aggressive + normalization of the PEM contents written into the + pod filesystem. Esoteric PEM features such as inter-block + comments and block headers are stripped. Certificates + are deduplicated. The ordering of certificates within + the file is arbitrary, and Kubelet may change the + order over time." + properties: + labelSelector: + description: Select all ClusterTrustBundles that + match this label selector. Only has effect + if signerName is set. Mutually-exclusive with + name. If unset, interpreted as "match nothing". If + set but empty, interpreted as "match everything". + properties: + matchExpressions: + description: matchExpressions is a list of + label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, a + key, and an operator that relates the + key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only + "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + name: + description: Select a single ClusterTrustBundle + by object name. Mutually-exclusive with signerName + and labelSelector. + type: string + optional: + description: If true, don't block pod startup + if the referenced ClusterTrustBundle(s) aren't + available. If using name, then the named ClusterTrustBundle + is allowed not to exist. If using signerName, + then the combination of signerName and labelSelector + is allowed to match zero ClusterTrustBundles. + type: boolean + path: + description: Relative path from the volume root + to write the bundle. + type: string + signerName: + description: Select all ClusterTrustBundles that + match this signer name. Mutually-exclusive with + name. The contents of all selected ClusterTrustBundles + will be unified and deduplicated. + type: string + required: + - path + type: object + configMap: + description: configMap information about the configMap + data to project + properties: + items: + description: items if unspecified, each key-value + pair in the Data field of the referenced ConfigMap + will be projected into the volume as a file + whose name is the key and content is the value. + If specified, the listed keys will be projected + into the specified paths, and unlisted keys + will not be present. If a key is specified which + is not present in the ConfigMap, the volume + setup will error unless it is marked optional. + Paths must be relative and may not contain the + '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits + used to set permissions on this file. + Must be an octal value between 0000 and + 0777 or a decimal value between 0 and + 511. YAML accepts both octal and decimal + values, JSON requires decimal values for + mode bits. If not specified, the volume + defaultMode will be used. This might be + in conflict with other options that affect + the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of + the file to map the key to. May not be + an absolute path. May not contain the + path element '..'. May not start with + the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + description: downwardAPI information about the downwardAPI + data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects a field + of the pod: only annotations, labels, + name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, + defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: 'Optional: mode bits used to + set permissions on this file, must be + an octal value between 0000 and 0777 or + a decimal value between 0 and 511. YAML + accepts both octal and decimal values, + JSON requires decimal values for mode + bits. If not specified, the volume defaultMode + will be used. This might be in conflict + with other options that affect the file + mode, like fsGroup, and the result can + be other mode bits set.' + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must + not be absolute or contain the ''..'' + path. Must be utf-8 encoded. The first + item of the relative path must not start + with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of the + container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu + and requests.memory) are currently supported.' + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults + to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to + select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + description: secret information about the secret data + to project + properties: + items: + description: items if unspecified, each key-value + pair in the Data field of the referenced Secret + will be projected into the volume as a file + whose name is the key and content is the value. + If specified, the listed keys will be projected + into the specified paths, and unlisted keys + will not be present. If a key is specified which + is not present in the Secret, the volume setup + will error unless it is marked optional. Paths + must be relative and may not contain the '..' + path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits + used to set permissions on this file. + Must be an octal value between 0000 and + 0777 or a decimal value between 0 and + 511. YAML accepts both octal and decimal + values, JSON requires decimal values for + mode bits. If not specified, the volume + defaultMode will be used. This might be + in conflict with other options that affect + the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of + the file to map the key to. May not be + an absolute path. May not contain the + path element '..'. May not start with + the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: optional field specify whether the + Secret or its key must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + description: serviceAccountToken is information about + the serviceAccountToken data to project + properties: + audience: + description: audience is the intended audience + of the token. A recipient of a token must identify + itself with an identifier specified in the audience + of the token, and otherwise should reject the + token. The audience defaults to the identifier + of the apiserver. + type: string + expirationSeconds: + description: expirationSeconds is the requested + duration of validity of the service account + token. As the token approaches expiration, the + kubelet volume plugin will proactively rotate + the service account token. The kubelet will + start trying to rotate the token if the token + is older than 80 percent of its time to live + or if the token is older than 24 hours.Defaults + to 1 hour and must be at least 10 minutes. + format: int64 + type: integer + path: + description: path is the path relative to the + mount point of the file to project the token + into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: quobyte represents a Quobyte mount on the host + that shares a pod's lifetime + properties: + group: + description: group to map volume access to Default is no + group + type: string + readOnly: + description: readOnly here will force the Quobyte volume + to be mounted with read-only permissions. Defaults to + false. + type: boolean + registry: + description: registry represents a single or multiple Quobyte + Registry services specified as a string as host:port pair + (multiple entries are separated with commas) which acts + as the central registry for volumes + type: string + tenant: + description: tenant owning the given Quobyte volume in the + Backend Used with dynamically provisioned Quobyte volumes, + value is set by the plugin + type: string + user: + description: user to map volume access to Defaults to serivceaccount + user + type: string + volume: + description: volume is a string that references an already + created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: 'rbd represents a Rados Block Device mount on the + host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/rbd/README.md' + properties: + fsType: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + image: + description: 'image is the rados image name. More info: + https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + keyring: + description: 'keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + monitors: + description: 'monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + items: + type: string + type: array + pool: + description: 'pool is the rados pool name. Default is rbd. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + readOnly: + description: 'readOnly here will force the ReadOnly setting + in VolumeMounts. Defaults to false. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: boolean + secretRef: + description: 'secretRef is name of the authentication secret + for RBDUser. If provided overrides keyring. Default is + nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + user: + description: 'user is the rados user name. Default is admin. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: fsType is the filesystem type to mount. Must + be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Default is "xfs". + type: string + gateway: + description: gateway is the host address of the ScaleIO + API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the ScaleIO + Protection Domain for the configured storage. + type: string + readOnly: + description: readOnly Defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: secretRef references to the secret for ScaleIO + user and other sensitive information. If this is not provided, + Login operation will fail. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + description: sslEnabled Flag enable/disable SSL communication + with Gateway, default false + type: boolean + storageMode: + description: storageMode indicates whether the storage for + a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage Pool associated + with the protection domain. + type: string + system: + description: system is the name of the storage system as + configured in ScaleIO. + type: string + volumeName: + description: volumeName is the name of a volume already + created in the ScaleIO system that is associated with + this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: 'secret represents a secret that should populate + this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + properties: + defaultMode: + description: 'defaultMode is Optional: mode bits used to + set permissions on created files by default. Must be an + octal value between 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and decimal values, + JSON requires decimal values for mode bits. Defaults to + 0644. Directories within the path are not affected by + this setting. This might be in conflict with other options + that affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + items: + description: items If unspecified, each key-value pair in + the Data field of the referenced Secret will be projected + into the volume as a file whose name is the key and content + is the value. If specified, the listed keys will be projected + into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in + the Secret, the volume setup will error unless it is marked + optional. Paths must be relative and may not contain the + '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used to + set permissions on this file. Must be an octal value + between 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and decimal values, + JSON requires decimal values for mode bits. If not + specified, the volume defaultMode will be used. + This might be in conflict with other options that + affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of the file + to map the key to. May not be an absolute path. + May not contain the path element '..'. May not start + with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the Secret or + its keys must be defined + type: boolean + secretName: + description: 'secretName is the name of the secret in the + pod''s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + storageos: + description: storageOS represents a StorageOS volume attached + and mounted on Kubernetes nodes. + properties: + fsType: + description: fsType is the filesystem type to mount. Must + be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. + type: string + readOnly: + description: readOnly defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: secretRef specifies the secret to use for obtaining + the StorageOS API credentials. If not specified, default + values will be attempted. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + description: volumeName is the human-readable name of the + StorageOS volume. Volume names are only unique within + a namespace. + type: string + volumeNamespace: + description: volumeNamespace specifies the scope of the + volume within StorageOS. If no namespace is specified + then the Pod's namespace will be used. This allows the + Kubernetes name scoping to be mirrored within StorageOS + for tighter integration. Set VolumeName to any name to + override the default behaviour. Set to "default" if you + are not using namespaces within StorageOS. Namespaces + that do not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere volume attached + and mounted on kubelets host machine + properties: + fsType: + description: fsType is filesystem type to mount. Must be + a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy Based + Management (SPBM) profile ID associated with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage Policy Based + Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies vSphere + volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + x-kubernetes-list-type: atomic + type: object + status: + description: DcgmExporterStatus defines the observed state of DcgmExporter. + properties: + image: + description: Image indicates the container image to use for the DCGM + Exporter. + type: string + messages: + description: 'Messages about actions performed by the operator on + this resource. Deprecated: use Kubernetes events instead.' + items: + type: string + type: array + x-kubernetes-list-type: atomic + replicas: + description: 'Replicas is currently not being set and might be removed + in the next version. Deprecated: use "DcgmExporter.Status.Scale.Replicas" + instead.' + format: int32 + type: integer + scale: + description: Scale is the DcgmExporter's scale subresource status. + properties: + replicas: + description: The total number non-terminated pods targeted by + this AmazonCloudWatchAgent's deployment or statefulSet. + format: int32 + type: integer + selector: + description: The selector used to match the AmazonCloudWatchAgent's + deployment or statefulSet pods. + type: string + statusReplicas: + description: StatusReplicas is the number of pods targeted by + this AmazonCloudWatchAgent's with a Ready Condition / Total + number of non-terminated pods targeted by this AmazonCloudWatchAgent's + (their labels match the selector). Deployment, Daemonset, StatefulSet. + type: string + type: object + version: + description: Version of the managed DCGM Exporter (operand) + type: string + type: object + type: object + served: true + storage: true + subresources: + scale: + labelSelectorPath: .status.scale.selector + specReplicasPath: .spec.replicas + statusReplicasPath: .status.scale.replicas + status: {} diff --git a/charts/amazon-cloudwatch-observability/crds/cloudwatch.aws.amazon.com_instrumentations.yaml b/charts/amazon-cloudwatch-observability/crds/cloudwatch.aws.amazon.com_instrumentations.yaml new file mode 100644 index 0000000..73523f6 --- /dev/null +++ b/charts/amazon-cloudwatch-observability/crds/cloudwatch.aws.amazon.com_instrumentations.yaml @@ -0,0 +1,1765 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.12.0 + labels: + app.kubernetes.io/name: amazon-cloudwatch-agent-operator + name: instrumentations.cloudwatch.aws.amazon.com +spec: + group: cloudwatch.aws.amazon.com + names: + kind: Instrumentation + listKind: InstrumentationList + plural: instrumentations + shortNames: + - otelinst + - otelinsts + singular: instrumentation + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .spec.exporter.endpoint + name: Endpoint + type: string + - jsonPath: .spec.sampler.type + name: Sampler + type: string + - jsonPath: .spec.sampler.argument + name: Sampler Arg + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: Instrumentation is the spec for OpenTelemetry instrumentation. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: InstrumentationSpec defines the desired state of OpenTelemetry + SDK and instrumentation. + properties: + apacheHttpd: + description: ApacheHttpd defines configuration for Apache HTTPD auto-instrumentation. + properties: + attrs: + description: 'Attrs defines Apache HTTPD agent specific attributes. + The precedence is: `agent default attributes` > `instrument + spec attributes` . Attributes are documented at https://github.com/open-telemetry/opentelemetry-cpp-contrib/tree/main/instrumentation/otel-webserver-module' + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + configPath: + description: Location of Apache HTTPD server configuration. Needed + only if different from default "/usr/local/apache2/conf" + type: string + env: + description: 'Env defines Apache HTTPD specific env vars. There + are four layers for env vars'' definitions and the precedence + order is: `original container env vars` > `language specific + env vars` > `common env vars` > `instrument spec configs'' vars`. + If the former var had been defined, then the other vars would + be ignored.' + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: Image is a container image with Apache SDK and auto-instrumentation. + type: string + resourceRequirements: + description: Resources describes the compute resource requirements. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + version: + description: Apache HTTPD server version. One of 2.4 or 2.2. Default + is 2.4 + type: string + volumeLimitSize: + anyOf: + - type: integer + - type: string + description: VolumeSizeLimit defines size limit for volume used + for auto-instrumentation. The default size is 200Mi. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + dotnet: + description: DotNet defines configuration for DotNet auto-instrumentation. + properties: + env: + description: 'Env defines DotNet specific env vars. There are + four layers for env vars'' definitions and the precedence order + is: `original container env vars` > `language specific env vars` + > `common env vars` > `instrument spec configs'' vars`. If the + former var had been defined, then the other vars would be ignored.' + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: Image is a container image with DotNet SDK and auto-instrumentation. + type: string + resourceRequirements: + description: Resources describes the compute resource requirements. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + volumeLimitSize: + anyOf: + - type: integer + - type: string + description: VolumeSizeLimit defines size limit for volume used + for auto-instrumentation. The default size is 200Mi. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + env: + description: 'Env defines common env vars. There are four layers for + env vars'' definitions and the precedence order is: `original container + env vars` > `language specific env vars` > `common env vars` > `instrument + spec configs'' vars`. If the former var had been defined, then the + other vars would be ignored.' + items: + description: EnvVar represents an environment variable present in + a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded using + the previously defined environment variables in the container + and any service environment variables. If a variable cannot + be resolved, the reference in the input string will be unchanged. + Double $$ are reduced to a single $, which allows for escaping + the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the + string literal "$(VAR_NAME)". Escaped references will never + be expanded, regardless of whether the variable exists or + not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. Cannot + be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, `metadata.annotations['''']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, + status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is + written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified + API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed + resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + exporter: + description: Exporter defines exporter configuration. + properties: + endpoint: + description: Endpoint is address of the collector with OTLP endpoint. + type: string + type: object + go: + description: Go defines configuration for Go auto-instrumentation. + When using Go auto-instrumentation you must provide a value for + the OTEL_GO_AUTO_TARGET_EXE env var via the Instrumentation env + vars or via the instrumentation.opentelemetry.io/otel-go-auto-target-exe + pod annotation. Failure to set this value causes instrumentation + injection to abort, leaving the original pod unchanged. + properties: + env: + description: 'Env defines Go specific env vars. There are four + layers for env vars'' definitions and the precedence order is: + `original container env vars` > `language specific env vars` + > `common env vars` > `instrument spec configs'' vars`. If the + former var had been defined, then the other vars would be ignored.' + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: Image is a container image with Go SDK and auto-instrumentation. + type: string + resourceRequirements: + description: Resources describes the compute resource requirements. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + volumeLimitSize: + anyOf: + - type: integer + - type: string + description: VolumeSizeLimit defines size limit for volume used + for auto-instrumentation. The default size is 200Mi. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + java: + description: Java defines configuration for java auto-instrumentation. + properties: + env: + description: 'Env defines java specific env vars. There are four + layers for env vars'' definitions and the precedence order is: + `original container env vars` > `language specific env vars` + > `common env vars` > `instrument spec configs'' vars`. If the + former var had been defined, then the other vars would be ignored.' + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: Image is a container image with javaagent auto-instrumentation + JAR. + type: string + resources: + description: Resources describes the compute resource requirements. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + volumeLimitSize: + anyOf: + - type: integer + - type: string + description: VolumeSizeLimit defines size limit for volume used + for auto-instrumentation. The default size is 200Mi. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + nginx: + description: Nginx defines configuration for Nginx auto-instrumentation. + properties: + attrs: + description: 'Attrs defines Nginx agent specific attributes. The + precedence order is: `agent default attributes` > `instrument + spec attributes` . Attributes are documented at https://github.com/open-telemetry/opentelemetry-cpp-contrib/tree/main/instrumentation/otel-webserver-module' + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + configFile: + description: Location of Nginx configuration file. Needed only + if different from default "/etc/nginx/nginx.conf" + type: string + env: + description: 'Env defines Nginx specific env vars. There are four + layers for env vars'' definitions and the precedence order is: + `original container env vars` > `language specific env vars` + > `common env vars` > `instrument spec configs'' vars`. If the + former var had been defined, then the other vars would be ignored.' + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: Image is a container image with Nginx SDK and auto-instrumentation. + type: string + resourceRequirements: + description: Resources describes the compute resource requirements. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + volumeLimitSize: + anyOf: + - type: integer + - type: string + description: VolumeSizeLimit defines size limit for volume used + for auto-instrumentation. The default size is 200Mi. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + nodejs: + description: NodeJS defines configuration for nodejs auto-instrumentation. + properties: + env: + description: 'Env defines nodejs specific env vars. There are + four layers for env vars'' definitions and the precedence order + is: `original container env vars` > `language specific env vars` + > `common env vars` > `instrument spec configs'' vars`. If the + former var had been defined, then the other vars would be ignored.' + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: Image is a container image with NodeJS SDK and auto-instrumentation. + type: string + resourceRequirements: + description: Resources describes the compute resource requirements. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + volumeLimitSize: + anyOf: + - type: integer + - type: string + description: VolumeSizeLimit defines size limit for volume used + for auto-instrumentation. The default size is 200Mi. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + propagators: + description: Propagators defines inter-process context propagation + configuration. Values in this list will be set in the OTEL_PROPAGATORS + env var. Enum=tracecontext;baggage;b3;b3multi;jaeger;xray;ottrace;none + items: + description: Propagator represents the propagation type. + enum: + - tracecontext + - baggage + - b3 + - b3multi + - jaeger + - xray + - ottrace + - none + type: string + type: array + python: + description: Python defines configuration for python auto-instrumentation. + properties: + env: + description: 'Env defines python specific env vars. There are + four layers for env vars'' definitions and the precedence order + is: `original container env vars` > `language specific env vars` + > `common env vars` > `instrument spec configs'' vars`. If the + former var had been defined, then the other vars would be ignored.' + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be a + C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: Image is a container image with Python SDK and auto-instrumentation. + type: string + resourceRequirements: + description: Resources describes the compute resource requirements. + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be + set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in + pod.spec.resourceClaims of the Pod where this field + is used. It makes that resource available inside a + container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed + Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + volumeLimitSize: + anyOf: + - type: integer + - type: string + description: VolumeSizeLimit defines size limit for volume used + for auto-instrumentation. The default size is 200Mi. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + resource: + description: Resource defines the configuration for the resource attributes, + as defined by the OpenTelemetry specification. + properties: + addK8sUIDAttributes: + description: AddK8sUIDAttributes defines whether K8s UID attributes + should be collected (e.g. k8s.deployment.uid). + type: boolean + resourceAttributes: + additionalProperties: + type: string + description: 'Attributes defines attributes that are added to + the resource. For example environment: dev' + type: object + type: object + sampler: + description: Sampler defines sampling configuration. + properties: + argument: + description: Argument defines sampler argument. The value depends + on the sampler type. For instance for parentbased_traceidratio + sampler type it is a number in range [0..1] e.g. 0.25. The value + will be set in the OTEL_TRACES_SAMPLER_ARG env var. + type: string + type: + description: Type defines sampler type. The value will be set + in the OTEL_TRACES_SAMPLER env var. The value can be for instance + parentbased_always_on, parentbased_always_off, parentbased_traceidratio... + enum: + - always_on + - always_off + - traceidratio + - parentbased_always_on + - parentbased_always_off + - parentbased_traceidratio + - jaeger_remote + - xray + type: string + type: object + type: object + status: + description: InstrumentationStatus defines status of the instrumentation. + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/amazon-cloudwatch-observability/crds/cloudwatch.aws.amazon.com_neuronmonitors.yaml b/charts/amazon-cloudwatch-observability/crds/cloudwatch.aws.amazon.com_neuronmonitors.yaml new file mode 100644 index 0000000..21b8001 --- /dev/null +++ b/charts/amazon-cloudwatch-observability/crds/cloudwatch.aws.amazon.com_neuronmonitors.yaml @@ -0,0 +1,3274 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.12.0 + name: neuronmonitors.cloudwatch.aws.amazon.com +spec: + group: cloudwatch.aws.amazon.com + names: + kind: NeuronMonitor + listKind: NeuronMonitorList + plural: neuronmonitors + shortNames: + - neuronexp + - neuronexps + singular: neuronmonitor + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Neuron Monitor exporter Version + jsonPath: .status.version + name: Version + type: string + - jsonPath: .status.scale.statusReplicas + name: Ready + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.image + name: Image + type: string + - description: Management State + jsonPath: .spec.managementState + name: Management + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: NeuronMonitor is the Schema for the NeuronMonitor API. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: NeuronMonitorSpec defines the desired state of NeuronMonitor. + properties: + affinity: + description: If specified, indicates the pod's scheduling constraints + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for the + pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the affinity expressions specified by + this field, but it may choose a node that violates one or + more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node matches + the corresponding matchExpressions; the node(s) with the + highest sum are the most preferred. + items: + description: An empty preferred scheduling term matches + all objects with implicit weight 0 (i.e. it's a no-op). + A null preferred scheduling term matches no objects (i.e. + is also a no-op). + properties: + preference: + description: A node selector term, associated with the + corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching the corresponding + nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this + field are not met at scheduling time, the pod will not be + scheduled onto the node. If the affinity requirements specified + by this field cease to be met at some point during pod execution + (e.g. due to an update), the system may or may not try to + eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: A null or empty node selector term matches + no objects. The requirements of them are ANDed. The + TopologySelectorTerm type implements a subset of the + NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. co-locate + this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the affinity expressions specified by + this field, but it may choose a node that violates one or + more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node has + pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: MatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key in (value)` to select + the group of existing pods which pods will be + taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MatchLabelKeys and LabelSelector. Also, + MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key notin (value)` to + select the group of existing pods which pods will + be taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MismatchLabelKeys and LabelSelector. Also, + MismatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding + podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this + field are not met at scheduling time, the pod will not be + scheduled onto the node. If the affinity requirements specified + by this field cease to be met at some point during pod execution + (e.g. due to a pod label update), the system may or may + not try to eventually evict the pod from its node. When + there are multiple elements, the lists of nodes corresponding + to each podAffinityTerm are intersected, i.e. all terms + must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not co-located + (anti-affinity) with, where co-located is defined as running + on a node whose value of the label with key + matches that of any node on which a pod of the set of + pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: MatchLabelKeys is a set of pod label keys + to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged with + `LabelSelector` as `key in (value)` to select the + group of existing pods which pods will be taken into + consideration for the incoming pod's pod (anti) affinity. + Keys that don't exist in the incoming pod labels will + be ignored. The default value is empty. The same key + is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires enabling + MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged with + `LabelSelector` as `key notin (value)` to select the + group of existing pods which pods will be taken into + consideration for the incoming pod's pod (anti) affinity. + Keys that don't exist in the incoming pod labels will + be ignored. The default value is empty. The same key + is forbidden to exist in both MismatchLabelKeys and + LabelSelector. Also, MismatchLabelKeys cannot be set + when LabelSelector isn't set. This is an alpha field + and requires enabling MatchLabelKeysInPodAffinity + feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied to the + union of the namespaces selected by this field and + the ones listed in the namespaces field. null selector + and null or empty namespaces list means "this pod's + namespace". An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list of namespace + names that the term applies to. The term is applied + to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. null or + empty namespaces list and null namespaceSelector means + "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where + co-located is defined as running on a node whose value + of the label with key topologyKey matches that of + any node on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules (e.g. + avoid putting this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the anti-affinity expressions specified + by this field, but it may choose a node that violates one + or more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node has + pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: MatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key in (value)` to select + the group of existing pods which pods will be + taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MatchLabelKeys and LabelSelector. Also, + MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged + with `LabelSelector` as `key notin (value)` to + select the group of existing pods which pods will + be taken into consideration for the incoming pod's + pod (anti) affinity. Keys that don't exist in + the incoming pod labels will be ignored. The default + value is empty. The same key is forbidden to exist + in both MismatchLabelKeys and LabelSelector. Also, + MismatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires + enabling MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding + podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the anti-affinity requirements + specified by this field cease to be met at some point during + pod execution (e.g. due to a pod label update), the system + may or may not try to eventually evict the pod from its + node. When there are multiple elements, the lists of nodes + corresponding to each podAffinityTerm are intersected, i.e. + all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not co-located + (anti-affinity) with, where co-located is defined as running + on a node whose value of the label with key + matches that of any node on which a pod of the set of + pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. If it's null, this PodAffinityTerm + matches with no Pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: MatchLabelKeys is a set of pod label keys + to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged with + `LabelSelector` as `key in (value)` to select the + group of existing pods which pods will be taken into + consideration for the incoming pod's pod (anti) affinity. + Keys that don't exist in the incoming pod labels will + be ignored. The default value is empty. The same key + is forbidden to exist in both MatchLabelKeys and LabelSelector. + Also, MatchLabelKeys cannot be set when LabelSelector + isn't set. This is an alpha field and requires enabling + MatchLabelKeysInPodAffinity feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: MismatchLabelKeys is a set of pod label + keys to select which pods will be taken into consideration. + The keys are used to lookup values from the incoming + pod labels, those key-value labels are merged with + `LabelSelector` as `key notin (value)` to select the + group of existing pods which pods will be taken into + consideration for the incoming pod's pod (anti) affinity. + Keys that don't exist in the incoming pod labels will + be ignored. The default value is empty. The same key + is forbidden to exist in both MismatchLabelKeys and + LabelSelector. Also, MismatchLabelKeys cannot be set + when LabelSelector isn't set. This is an alpha field + and requires enabling MatchLabelKeysInPodAffinity + feature gate. + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied to the + union of the namespaces selected by this field and + the ones listed in the namespaces field. null selector + and null or empty namespaces list means "this pod's + namespace". An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list of namespace + names that the term applies to. The term is applied + to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. null or + empty namespaces list and null namespaceSelector means + "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where + co-located is defined as running on a node whose value + of the label with key topologyKey matches that of + any node on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + args: + additionalProperties: + type: string + description: Args is the set of arguments to pass to the Neuron Monitor + Exporter binary + type: object + command: + description: 'Entrypoint array. Not executed within a shell. The container + image''s ENTRYPOINT is used if this is not provided. Variable references + $(VAR_NAME) are expanded using the container''s environment. If + a variable cannot be resolved, the reference in the input string + will be unchanged. Double $$ are reduced to a single $, which allows + for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce + the string literal "$(VAR_NAME)". Escaped references will never + be expanded, regardless of whether the variable exists or not. Cannot + be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + env: + description: ENV vars to set on the Neuron Monitor Exporter Pods. + These can then in certain cases be consumed in the config file for + the Collector. + items: + description: EnvVar represents an environment variable present in + a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded using + the previously defined environment variables in the container + and any service environment variables. If a variable cannot + be resolved, the reference in the input string will be unchanged. + Double $$ are reduced to a single $, which allows for escaping + the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the + string literal "$(VAR_NAME)". Escaped references will never + be expanded, regardless of whether the variable exists or + not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. Cannot + be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, + metadata.namespace, `metadata.labels['''']`, `metadata.annotations['''']`, + spec.nodeName, spec.serviceAccountName, status.hostIP, + status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is + written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified + API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: 'Selects a resource of the container: only + resources limits and requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, requests.memory + and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed + resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + image: + description: Image indicates the container image to use for the Neuron + Monitor Exporter. + type: string + monitorConfig: + description: MonitorConfig is the raw Json to be used as monitor configuration. + type: string + tolerations: + description: Toleration to schedule Neuron Monitor Exporter pods. + This is only relevant to daemonset, statefulset, and deployment + mode + items: + description: The pod this Toleration is attached to tolerates any + taint that matches the triple using the matching + operator . + properties: + effect: + description: Effect indicates the taint effect to match. Empty + means match all taint effects. When specified, allowed values + are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match all + values and all keys. + type: string + operator: + description: Operator represents a key's relationship to the + value. Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod + can tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of time + the toleration (which must be of effect NoExecute, otherwise + this field is ignored) tolerates the taint. By default, it + is not set, which means tolerate the taint forever (do not + evict). Zero and negative values will be treated as 0 (evict + immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + nodeSelector: + additionalProperties: + type: string + description: NodeSelector to schedule Neuron Monitor Exporter pods. + This is only relevant to daemonset, statefulset, and deployment + mode + type: object + ports: + description: Ports allows a set of ports to be exposed by the underlying + v1.Service. By default, the operator will attempt to infer the required + ports by parsing the .Spec.Config property but this property can + be used to open additional ports that can't be inferred by the operator, + like for custom receivers. + items: + description: ServicePort contains information on service's port. + properties: + appProtocol: + description: "The application protocol for this port. This is + used as a hint for implementations to offer richer behavior + for protocols that they understand. This field follows standard + Kubernetes label syntax. Valid values are either: \n * Un-prefixed + protocol names - reserved for IANA standard service names + (as per RFC-6335 and https://www.iana.org/assignments/service-names). + \n * Kubernetes-defined prefixed names: * 'kubernetes.io/h2c' + - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior- + * 'kubernetes.io/ws' - WebSocket over cleartext as described + in https://www.rfc-editor.org/rfc/rfc6455 * 'kubernetes.io/wss' + - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455 + \n * Other protocols should use implementation-defined prefixed + names such as mycompany.com/my-custom-protocol." + type: string + name: + description: The name of this port within the service. This + must be a DNS_LABEL. All ports within a ServiceSpec must have + unique names. When considering the endpoints for a Service, + this must match the 'name' field in the EndpointPort. Optional + if only one ServicePort is defined on this service. + type: string + nodePort: + description: 'The port on each node on which this service is + exposed when type is NodePort or LoadBalancer. Usually assigned + by the system. If a value is specified, in-range, and not + in use it will be used, otherwise the operation will fail. If + not specified, a port will be allocated if this Service requires + one. If this field is specified when creating a Service which + does not need it, creation will fail. This field will be wiped + when updating a Service to no longer need it (e.g. changing + type from NodePort to ClusterIP). More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport' + format: int32 + type: integer + port: + description: The port that will be exposed by this service. + format: int32 + type: integer + protocol: + default: TCP + description: The IP protocol for this port. Supports "TCP", + "UDP", and "SCTP". Default is TCP. + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: 'Number or name of the port to access on the pods + targeted by the service. Number must be in the range 1 to + 65535. Name must be an IANA_SVC_NAME. If this is a string, + it will be looked up as a named port in the target Pod''s + container ports. If this is not specified, the value of the + ''port'' field is used (an identity map). This field is ignored + for services with clusterIP=None, and should be omitted or + set equal to the ''port'' field. More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service' + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: Resources to set on the Neuron Monitor Exporter pods. + properties: + claims: + description: "Claims lists the names of resources, defined in + spec.resourceClaims, that are used by this container. \n This + is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be set + for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims + of the Pod where this field is used. It makes that resource + available inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources + allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: "SecurityContext configures the container security context + for the amazon-cloudwatch-agent container. \n In deployment, daemonset, + or statefulset mode, this controls the security context settings + for the primary application container. \n In sidecar mode, this + controls the security context for the injected sidecar container." + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a process + can gain more privileges than its parent process. This bool + directly controls if the no_new_privs flag will be set on the + container process. AllowPrivilegeEscalation is true always when + the container is: 1) run as Privileged 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container + runtime. Note that this field cannot be set when spec.os.name + is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in privileged + containers are essentially equivalent to root on the host. Defaults + to false. Note that this field cannot be set when spec.os.name + is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use for + the containers. The default is DefaultProcMount which uses the + container runtime defaults for readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when spec.os.name + is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container process. + Uses runtime default if unset. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence. Note that this + field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail to start + the container if it does. If unset or false, no such validation + will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when spec.os.name + is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence. Note that this + field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to + the container. + type: string + role: + description: Role is a SELinux role label that applies to + the container. + type: string + type: + description: Type is a SELinux type label that applies to + the container. + type: string + user: + description: User is a SELinux user label that applies to + the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. If + seccomp options are provided at both the pod & container level, + the container options override the pod options. Note that this + field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must be + preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must be set if type is "Localhost". Must NOT be + set for any other type. + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a profile + defined in a file on the node should be used. RuntimeDefault + - the container runtime default profile should be used. + Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will + be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named by + the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA + credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. All of a Pod's containers + must have the same effective HostProcess value (it is not + allowed to have a mix of HostProcess containers and non-HostProcess + containers). In addition, if HostProcess is true then HostNetwork + must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in PodSecurityContext. + If set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: string + type: object + type: object + serviceAccount: + description: ServiceAccount indicates the name of an existing service + account to use with this instance. When set, the operator will not + automatically create a ServiceAccount for the collector. + type: string + volumeMounts: + description: VolumeMounts represents the mount points to use in the + underlying collector deployment(s) + items: + description: VolumeMount describes a mounting of a Volume within + a container. + properties: + mountPath: + description: Path within the container at which the volume should + be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are propagated + from the host to container and the other way around. When + not set, MountPropagationNone is used. This field is beta + in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise + (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's + volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which the + container's volume should be mounted. Behaves similarly to + SubPath but environment variable references $(VAR_NAME) are + expanded using the container's environment. Defaults to "" + (volume's root). SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-type: atomic + volumes: + description: Volumes represents which volumes to use in the underlying + collector deployment(s). + items: + description: Volume represents a named volume in a pod that may + be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: 'awsElasticBlockStore represents an AWS Disk resource + that is attached to a kubelet''s host machine and then exposed + to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + properties: + fsType: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + partition: + description: 'partition is the partition in the volume that + you want to mount. If omitted, the default is to mount + by volume name. Examples: For volume /dev/sda1, you specify + the partition as "1". Similarly, the volume partition + for /dev/sda is "0" (or you can leave the property empty).' + format: int32 + type: integer + readOnly: + description: 'readOnly value true will force the readOnly + setting in VolumeMounts. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: boolean + volumeID: + description: 'volumeID is unique ID of the persistent disk + resource in AWS (Amazon EBS volume). More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data Disk mount on + the host and bind mount to the pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching mode: None, + Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data disk in the + blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in the blob + storage + type: string + fsType: + description: fsType is Filesystem type to mount. Must be + a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. + type: string + kind: + description: 'kind expected values are Shared: multiple + blob disks per storage account Dedicated: single blob + disk per storage account Managed: azure managed data + disk (only in managed availability set). defaults to shared' + type: string + readOnly: + description: readOnly Defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File Service mount + on the host and bind mount to the pod. + properties: + readOnly: + description: readOnly defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret that contains + Azure Storage Account Name and Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount on the host that + shares a pod's lifetime + properties: + monitors: + description: 'monitors is Required: Monitors is a collection + of Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + items: + type: string + type: array + path: + description: 'path is Optional: Used as the mounted root, + rather than the full Ceph tree, default is /' + type: string + readOnly: + description: 'readOnly is Optional: Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: boolean + secretFile: + description: 'secretFile is Optional: SecretFile is the + path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + secretRef: + description: 'secretRef is Optional: SecretRef is reference + to the authentication secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + user: + description: 'user is optional: User is the rados user name, + default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + required: + - monitors + type: object + cinder: + description: 'cinder represents a cinder volume attached and + mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + properties: + fsType: + description: 'fsType is the filesystem type to mount. Must + be a filesystem type supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to + be "ext4" if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + readOnly: + description: 'readOnly defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: boolean + secretRef: + description: 'secretRef is optional: points to a secret + object containing parameters used to connect to OpenStack.' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + description: 'volumeID used to identify the volume in cinder. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that should populate + this volume + properties: + defaultMode: + description: 'defaultMode is optional: mode bits used to + set permissions on created files by default. Must be an + octal value between 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and decimal values, + JSON requires decimal values for mode bits. Defaults to + 0644. Directories within the path are not affected by + this setting. This might be in conflict with other options + that affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + items: + description: items if unspecified, each key-value pair in + the Data field of the referenced ConfigMap will be projected + into the volume as a file whose name is the key and content + is the value. If specified, the listed keys will be projected + into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in + the ConfigMap, the volume setup will error unless it is + marked optional. Paths must be relative and may not contain + the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used to + set permissions on this file. Must be an octal value + between 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and decimal values, + JSON requires decimal values for mode bits. If not + specified, the volume defaultMode will be used. + This might be in conflict with other options that + affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of the file + to map the key to. May not be an absolute path. + May not contain the path element '..'. May not start + with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: optional specify whether the ConfigMap or its + keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + description: csi (Container Storage Interface) represents ephemeral + storage that is handled by certain external CSI drivers (Beta + feature). + properties: + driver: + description: driver is the name of the CSI driver that handles + this volume. Consult with your admin for the correct name + as registered in the cluster. + type: string + fsType: + description: fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the associated + CSI driver which will determine the default filesystem + to apply. + type: string + nodePublishSecretRef: + description: nodePublishSecretRef is a reference to the + secret object containing sensitive information to pass + to the CSI driver to complete the CSI NodePublishVolume + and NodeUnpublishVolume calls. This field is optional, + and may be empty if no secret is required. If the secret + object contains more than one secret, all secret references + are passed. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + description: readOnly specifies a read-only configuration + for the volume. Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: volumeAttributes stores driver-specific properties + that are passed to the CSI driver. Consult your driver's + documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about the pod + that should populate this volume + properties: + defaultMode: + description: 'Optional: mode bits to use on created files + by default. Must be a Optional: mode bits used to set + permissions on created files by default. Must be an octal + value between 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and decimal values, + JSON requires decimal values for mode bits. Defaults to + 0644. Directories within the path are not affected by + this setting. This might be in conflict with other options + that affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + items: + description: Items is a list of downward API volume file + items: + description: DownwardAPIVolumeFile represents information + to create the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects a field of the pod: + only annotations, labels, name and namespace are + supported.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: 'Optional: mode bits used to set permissions + on this file, must be an octal value between 0000 + and 0777 or a decimal value between 0 and 511. YAML + accepts both octal and decimal values, JSON requires + decimal values for mode bits. If not specified, + the volume defaultMode will be used. This might + be in conflict with other options that affect the + file mode, like fsGroup, and the result can be other + mode bits set.' + format: int32 + type: integer + path: + description: 'Required: Path is the relative path + name of the file to be created. Must not be absolute + or contain the ''..'' path. Must be utf-8 encoded. + The first item of the relative path must not start + with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, requests.cpu and requests.memory) + are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + description: 'emptyDir represents a temporary directory that + shares a pod''s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + properties: + medium: + description: 'medium represents what type of storage medium + should back this directory. The default is "" which means + to use the node''s default medium. Must be an empty string + (default) or Memory. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: 'sizeLimit is the total amount of local storage + required for this EmptyDir volume. The size limit is also + applicable for memory medium. The maximum usage on memory + medium EmptyDir would be the minimum value between the + SizeLimit specified here and the sum of memory limits + of all containers in a pod. The default is nil which means + that the limit is undefined. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: "ephemeral represents a volume that is handled + by a cluster storage driver. The volume's lifecycle is tied + to the pod that defines it - it will be created before the + pod starts, and deleted when the pod is removed. \n Use this + if: a) the volume is only needed while the pod runs, b) features + of normal volumes like restoring from snapshot or capacity + tracking are needed, c) the storage driver is specified through + a storage class, and d) the storage driver supports dynamic + volume provisioning through a PersistentVolumeClaim (see EphemeralVolumeSource + for more information on the connection between this volume + type and PersistentVolumeClaim). \n Use PersistentVolumeClaim + or one of the vendor-specific APIs for volumes that persist + for longer than the lifecycle of an individual pod. \n Use + CSI for light-weight local ephemeral volumes if the CSI driver + is meant to be used that way - see the documentation of the + driver for more information. \n A pod can use both types of + ephemeral volumes and persistent volumes at the same time." + properties: + volumeClaimTemplate: + description: "Will be used to create a stand-alone PVC to + provision the volume. The pod in which this EphemeralVolumeSource + is embedded will be the owner of the PVC, i.e. the PVC + will be deleted together with the pod. The name of the + PVC will be `-` where `` is the name from the `PodSpec.Volumes` array entry. + Pod validation will reject the pod if the concatenated + name is not valid for a PVC (for example, too long). \n + An existing PVC with that name that is not owned by the + pod will *not* be used for the pod to avoid using an unrelated + volume by mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created PVC + is meant to be used by the pod, the PVC has to updated + with an owner reference to the pod once the pod exists. + Normally this should not be necessary, but it may be useful + when manually reconstructing a broken cluster. \n This + field is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. \n Required, must + not be nil." + properties: + metadata: + description: May contain labels and annotations that + will be copied into the PVC when creating it. No other + fields are allowed and will be rejected during validation. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: The specification for the PersistentVolumeClaim. + The entire content is copied unchanged into the PVC + that gets created from this template. The same fields + as in a PersistentVolumeClaim are also valid here. + properties: + accessModes: + description: 'accessModes contains the desired access + modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'dataSource field can be used to specify + either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) If the + provisioner or an external controller can support + the specified data source, it will create a new + volume based on the contents of the specified + data source. When the AnyVolumeDataSource feature + gate is enabled, dataSource contents will be copied + to dataSourceRef, and dataSourceRef contents will + be copied to dataSource when dataSourceRef.namespace + is not specified. If the namespace is specified, + then dataSourceRef will not be copied to dataSource.' + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API + group. For any other third-party types, APIGroup + is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: 'dataSourceRef specifies the object + from which to populate the volume with data, if + a non-empty volume is desired. This may be any + object from a non-empty API group (non core object) + or a PersistentVolumeClaim object. When this field + is specified, volume binding will only succeed + if the type of the specified object matches some + installed volume populator or dynamic provisioner. + This field will replace the functionality of the + dataSource field and as such if both fields are + non-empty, they must have the same value. For + backwards compatibility, when namespace isn''t + specified in dataSourceRef, both fields (dataSource + and dataSourceRef) will be set to the same value + automatically if one of them is empty and the + other is non-empty. When namespace is specified + in dataSourceRef, dataSource isn''t set to the + same value and must be empty. There are three + important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types + of objects, dataSourceRef allows any non-core + object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping + them), dataSourceRef preserves all values, and + generates an error if a disallowed value is specified. + * While dataSource only allows local objects, + dataSourceRef allows objects in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource + feature gate to be enabled. (Alpha) Using the + namespace field of dataSourceRef requires the + CrossNamespaceVolumeDataSource feature gate to + be enabled.' + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API + group. For any other third-party types, APIGroup + is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + namespace: + description: Namespace is the namespace of resource + being referenced Note that when a namespace + is specified, a gateway.networking.k8s.io/ReferenceGrant + object is required in the referent namespace + to allow that namespace's owner to accept + the reference. See the ReferenceGrant documentation + for details. (Alpha) This field requires the + CrossNamespaceVolumeDataSource feature gate + to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: 'resources represents the minimum resources + the volume should have. If RecoverVolumeExpansionFailure + feature is enabled users are allowed to specify + resource requirements that are lower than previous + value but must still be higher than capacity recorded + in the status field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount + of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum + amount of compute resources required. If Requests + is omitted for a container, it defaults to + Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests + cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + selector: + description: selector is a label query over volumes + to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: 'storageClassName is the name of the + StorageClass required by the claim. More info: + https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + type: string + volumeAttributesClassName: + description: 'volumeAttributesClassName may be used + to set the VolumeAttributesClass used by this + claim. If specified, the CSI driver will create + or update the volume with the attributes defined + in the corresponding VolumeAttributesClass. This + has a different purpose than storageClassName, + it can be changed after the claim is created. + An empty string value means that no VolumeAttributesClass + will be applied to the claim but it''s not allowed + to reset this field to empty string once it is + set. If unspecified and the PersistentVolumeClaim + is unbound, the default VolumeAttributesClass + will be set by the persistentvolume controller + if it exists. If the resource referred to by volumeAttributesClass + does not exist, this PersistentVolumeClaim will + be set to a Pending state, as reflected by the + modifyVolumeStatus field, until such as a resource + exists. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#volumeattributesclass + (Alpha) Using this field requires the VolumeAttributesClass + feature gate to be enabled.' + type: string + volumeMode: + description: volumeMode defines what type of volume + is required by the claim. Value of Filesystem + is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference + to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource that is + attached to a kubelet's host machine and then exposed to the + pod. + properties: + fsType: + description: 'fsType is the filesystem type to mount. Must + be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. TODO: how do we prevent errors in the + filesystem from compromising the machine' + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: 'readOnly is Optional: Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts.' + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target worldwide + names (WWNs)' + items: + type: string + type: array + wwids: + description: 'wwids Optional: FC volume world wide identifiers + (wwids) Either wwids or combination of targetWWNs and + lun must be set, but not both simultaneously.' + items: + type: string + type: array + type: object + flexVolume: + description: flexVolume represents a generic volume resource + that is provisioned/attached using an exec based plugin. + properties: + driver: + description: driver is the name of the driver to use for + this volume. + type: string + fsType: + description: fsType is the filesystem type to mount. Must + be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". The default filesystem depends + on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field holds extra + command options if any.' + type: object + readOnly: + description: 'readOnly is Optional: defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts.' + type: boolean + secretRef: + description: 'secretRef is Optional: secretRef is reference + to the secret object containing sensitive information + to pass to the plugin scripts. This may be empty if no + secret object is specified. If the secret object contains + more than one secret, all secrets are passed to the plugin + scripts.' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume attached to + a kubelet's host machine. This depends on the Flocker control + service being running + properties: + datasetName: + description: datasetName is Name of the dataset stored as + metadata -> name on the dataset for Flocker should be + considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. This + is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: 'gcePersistentDisk represents a GCE Disk resource + that is attached to a kubelet''s host machine and then exposed + to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + properties: + fsType: + description: 'fsType is filesystem type of the volume that + you want to mount. Tip: Ensure that the filesystem type + is supported by the host operating system. Examples: "ext4", + "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + partition: + description: 'partition is the partition in the volume that + you want to mount. If omitted, the default is to mount + by volume name. Examples: For volume /dev/sda1, you specify + the partition as "1". Similarly, the volume partition + for /dev/sda is "0" (or you can leave the property empty). + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + format: int32 + type: integer + pdName: + description: 'pdName is unique name of the PD resource in + GCE. Used to identify the disk in GCE. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: string + readOnly: + description: 'readOnly here will force the ReadOnly setting + in VolumeMounts. Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: boolean + required: + - pdName + type: object + gitRepo: + description: 'gitRepo represents a git repository at a particular + revision. DEPRECATED: GitRepo is deprecated. To provision + a container with a git repo, mount an EmptyDir into an InitContainer + that clones the repo using git, then mount the EmptyDir into + the Pod''s container.' + properties: + directory: + description: directory is the target directory name. Must + not contain or start with '..'. If '.' is supplied, the + volume directory will be the git repository. Otherwise, + if specified, the volume will contain the git repository + in the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the specified + revision. + type: string + required: + - repository + type: object + glusterfs: + description: 'glusterfs represents a Glusterfs mount on the + host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md' + properties: + endpoints: + description: 'endpoints is the endpoint name that details + Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + path: + description: 'path is the Glusterfs volume path. More info: + https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + readOnly: + description: 'readOnly here will force the Glusterfs volume + to be mounted with read-only permissions. Defaults to + false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: 'hostPath represents a pre-existing file or directory + on the host machine that is directly exposed to the container. + This is generally used for system agents or other privileged + things that are allowed to see the host machine. Most containers + will NOT need this. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- TODO(jonesdl) We need to restrict who can use host directory + mounts and who can/can not mount host directories as read/write.' + properties: + path: + description: 'path of the directory on the host. If the + path is a symlink, it will follow the link to the real + path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + type: + description: 'type for HostPath Volume Defaults to "" More + info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + required: + - path + type: object + iscsi: + description: 'iscsi represents an ISCSI Disk resource that is + attached to a kubelet''s host machine and then exposed to + the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md' + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether support iSCSI + Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support iSCSI + Session CHAP authentication + type: boolean + fsType: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + initiatorName: + description: initiatorName is the custom iSCSI Initiator + Name. If initiatorName is specified with iscsiInterface + simultaneously, new iSCSI interface : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified Name. + type: string + iscsiInterface: + description: iscsiInterface is the interface Name that uses + an iSCSI transport. Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: portals is the iSCSI Target Portal List. The + portal is either an IP or ip_addr:port if the port is + other than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: readOnly here will force the ReadOnly setting + in VolumeMounts. Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for iSCSI target + and initiator authentication + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + description: targetPortal is iSCSI Target Portal. The Portal + is either an IP or ip_addr:port if the port is other than + default (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: 'name of the volume. Must be a DNS_LABEL and unique + within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + nfs: + description: 'nfs represents an NFS mount on the host that shares + a pod''s lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + properties: + path: + description: 'path that is exported by the NFS server. More + info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + readOnly: + description: 'readOnly here will force the NFS export to + be mounted with read-only permissions. Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: boolean + server: + description: 'server is the hostname or IP address of the + NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: 'persistentVolumeClaimVolumeSource represents a + reference to a PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + claimName: + description: 'claimName is the name of a PersistentVolumeClaim + in the same namespace as the pod using this volume. More + info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + type: string + readOnly: + description: readOnly Will force the ReadOnly setting in + VolumeMounts. Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets host machine + properties: + fsType: + description: fsType is the filesystem type to mount. Must + be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon Controller + persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx volume attached + and mounted on kubelets host machine + properties: + fsType: + description: fSType represents the filesystem type to mount + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs". Implicitly inferred to be "ext4" + if unspecified. + type: string + readOnly: + description: readOnly defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources secrets, + configmaps, and downward API + properties: + defaultMode: + description: defaultMode are the mode bits used to set permissions + on created files by default. Must be an octal value between + 0000 and 0777 or a decimal value between 0 and 511. YAML + accepts both octal and decimal values, JSON requires decimal + values for mode bits. Directories within the path are + not affected by this setting. This might be in conflict + with other options that affect the file mode, like fsGroup, + and the result can be other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume projections + items: + description: Projection that may be projected along with + other supported volume types + properties: + clusterTrustBundle: + description: "ClusterTrustBundle allows a pod to access + the `.spec.trustBundle` field of ClusterTrustBundle + objects in an auto-updating file. \n Alpha, gated + by the ClusterTrustBundleProjection feature gate. + \n ClusterTrustBundle objects can either be selected + by name, or by the combination of signer name and + a label selector. \n Kubelet performs aggressive + normalization of the PEM contents written into the + pod filesystem. Esoteric PEM features such as inter-block + comments and block headers are stripped. Certificates + are deduplicated. The ordering of certificates within + the file is arbitrary, and Kubelet may change the + order over time." + properties: + labelSelector: + description: Select all ClusterTrustBundles that + match this label selector. Only has effect + if signerName is set. Mutually-exclusive with + name. If unset, interpreted as "match nothing". If + set but empty, interpreted as "match everything". + properties: + matchExpressions: + description: matchExpressions is a list of + label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, a + key, and an operator that relates the + key and values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only + "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + name: + description: Select a single ClusterTrustBundle + by object name. Mutually-exclusive with signerName + and labelSelector. + type: string + optional: + description: If true, don't block pod startup + if the referenced ClusterTrustBundle(s) aren't + available. If using name, then the named ClusterTrustBundle + is allowed not to exist. If using signerName, + then the combination of signerName and labelSelector + is allowed to match zero ClusterTrustBundles. + type: boolean + path: + description: Relative path from the volume root + to write the bundle. + type: string + signerName: + description: Select all ClusterTrustBundles that + match this signer name. Mutually-exclusive with + name. The contents of all selected ClusterTrustBundles + will be unified and deduplicated. + type: string + required: + - path + type: object + configMap: + description: configMap information about the configMap + data to project + properties: + items: + description: items if unspecified, each key-value + pair in the Data field of the referenced ConfigMap + will be projected into the volume as a file + whose name is the key and content is the value. + If specified, the listed keys will be projected + into the specified paths, and unlisted keys + will not be present. If a key is specified which + is not present in the ConfigMap, the volume + setup will error unless it is marked optional. + Paths must be relative and may not contain the + '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits + used to set permissions on this file. + Must be an octal value between 0000 and + 0777 or a decimal value between 0 and + 511. YAML accepts both octal and decimal + values, JSON requires decimal values for + mode bits. If not specified, the volume + defaultMode will be used. This might be + in conflict with other options that affect + the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of + the file to map the key to. May not be + an absolute path. May not contain the + path element '..'. May not start with + the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + description: downwardAPI information about the downwardAPI + data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects a field + of the pod: only annotations, labels, + name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, + defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: 'Optional: mode bits used to + set permissions on this file, must be + an octal value between 0000 and 0777 or + a decimal value between 0 and 511. YAML + accepts both octal and decimal values, + JSON requires decimal values for mode + bits. If not specified, the volume defaultMode + will be used. This might be in conflict + with other options that affect the file + mode, like fsGroup, and the result can + be other mode bits set.' + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must + not be absolute or contain the ''..'' + path. Must be utf-8 encoded. The first + item of the relative path must not start + with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of the + container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu + and requests.memory) are currently supported.' + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults + to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to + select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + description: secret information about the secret data + to project + properties: + items: + description: items if unspecified, each key-value + pair in the Data field of the referenced Secret + will be projected into the volume as a file + whose name is the key and content is the value. + If specified, the listed keys will be projected + into the specified paths, and unlisted keys + will not be present. If a key is specified which + is not present in the Secret, the volume setup + will error unless it is marked optional. Paths + must be relative and may not contain the '..' + path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits + used to set permissions on this file. + Must be an octal value between 0000 and + 0777 or a decimal value between 0 and + 511. YAML accepts both octal and decimal + values, JSON requires decimal values for + mode bits. If not specified, the volume + defaultMode will be used. This might be + in conflict with other options that affect + the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of + the file to map the key to. May not be + an absolute path. May not contain the + path element '..'. May not start with + the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: optional field specify whether the + Secret or its key must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + description: serviceAccountToken is information about + the serviceAccountToken data to project + properties: + audience: + description: audience is the intended audience + of the token. A recipient of a token must identify + itself with an identifier specified in the audience + of the token, and otherwise should reject the + token. The audience defaults to the identifier + of the apiserver. + type: string + expirationSeconds: + description: expirationSeconds is the requested + duration of validity of the service account + token. As the token approaches expiration, the + kubelet volume plugin will proactively rotate + the service account token. The kubelet will + start trying to rotate the token if the token + is older than 80 percent of its time to live + or if the token is older than 24 hours.Defaults + to 1 hour and must be at least 10 minutes. + format: int64 + type: integer + path: + description: path is the path relative to the + mount point of the file to project the token + into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: quobyte represents a Quobyte mount on the host + that shares a pod's lifetime + properties: + group: + description: group to map volume access to Default is no + group + type: string + readOnly: + description: readOnly here will force the Quobyte volume + to be mounted with read-only permissions. Defaults to + false. + type: boolean + registry: + description: registry represents a single or multiple Quobyte + Registry services specified as a string as host:port pair + (multiple entries are separated with commas) which acts + as the central registry for volumes + type: string + tenant: + description: tenant owning the given Quobyte volume in the + Backend Used with dynamically provisioned Quobyte volumes, + value is set by the plugin + type: string + user: + description: user to map volume access to Defaults to serivceaccount + user + type: string + volume: + description: volume is a string that references an already + created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: 'rbd represents a Rados Block Device mount on the + host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/rbd/README.md' + properties: + fsType: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + image: + description: 'image is the rados image name. More info: + https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + keyring: + description: 'keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + monitors: + description: 'monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + items: + type: string + type: array + pool: + description: 'pool is the rados pool name. Default is rbd. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + readOnly: + description: 'readOnly here will force the ReadOnly setting + in VolumeMounts. Defaults to false. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: boolean + secretRef: + description: 'secretRef is name of the authentication secret + for RBDUser. If provided overrides keyring. Default is + nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + user: + description: 'user is the rados user name. Default is admin. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: fsType is the filesystem type to mount. Must + be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Default is "xfs". + type: string + gateway: + description: gateway is the host address of the ScaleIO + API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the ScaleIO + Protection Domain for the configured storage. + type: string + readOnly: + description: readOnly Defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: secretRef references to the secret for ScaleIO + user and other sensitive information. If this is not provided, + Login operation will fail. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + description: sslEnabled Flag enable/disable SSL communication + with Gateway, default false + type: boolean + storageMode: + description: storageMode indicates whether the storage for + a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage Pool associated + with the protection domain. + type: string + system: + description: system is the name of the storage system as + configured in ScaleIO. + type: string + volumeName: + description: volumeName is the name of a volume already + created in the ScaleIO system that is associated with + this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: 'secret represents a secret that should populate + this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + properties: + defaultMode: + description: 'defaultMode is Optional: mode bits used to + set permissions on created files by default. Must be an + octal value between 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and decimal values, + JSON requires decimal values for mode bits. Defaults to + 0644. Directories within the path are not affected by + this setting. This might be in conflict with other options + that affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + items: + description: items If unspecified, each key-value pair in + the Data field of the referenced Secret will be projected + into the volume as a file whose name is the key and content + is the value. If specified, the listed keys will be projected + into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in + the Secret, the volume setup will error unless it is marked + optional. Paths must be relative and may not contain the + '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used to + set permissions on this file. Must be an octal value + between 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and decimal values, + JSON requires decimal values for mode bits. If not + specified, the volume defaultMode will be used. + This might be in conflict with other options that + affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of the file + to map the key to. May not be an absolute path. + May not contain the path element '..'. May not start + with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the Secret or + its keys must be defined + type: boolean + secretName: + description: 'secretName is the name of the secret in the + pod''s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + storageos: + description: storageOS represents a StorageOS volume attached + and mounted on Kubernetes nodes. + properties: + fsType: + description: fsType is the filesystem type to mount. Must + be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. + type: string + readOnly: + description: readOnly defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: secretRef specifies the secret to use for obtaining + the StorageOS API credentials. If not specified, default + values will be attempted. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + description: volumeName is the human-readable name of the + StorageOS volume. Volume names are only unique within + a namespace. + type: string + volumeNamespace: + description: volumeNamespace specifies the scope of the + volume within StorageOS. If no namespace is specified + then the Pod's namespace will be used. This allows the + Kubernetes name scoping to be mirrored within StorageOS + for tighter integration. Set VolumeName to any name to + override the default behaviour. Set to "default" if you + are not using namespaces within StorageOS. Namespaces + that do not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere volume attached + and mounted on kubelets host machine + properties: + fsType: + description: fsType is filesystem type to mount. Must be + a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy Based + Management (SPBM) profile ID associated with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage Policy Based + Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies vSphere + volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + x-kubernetes-list-type: atomic + type: object + status: + description: NeuronMonitorStatus defines the observed state of NeuronMonitor. + properties: + image: + description: Image indicates the container image to use for the Neuron + Monitor Exporter. + type: string + messages: + description: 'Messages about actions performed by the operator on + this resource. Deprecated: use Kubernetes events instead.' + items: + type: string + type: array + x-kubernetes-list-type: atomic + replicas: + description: 'Replicas is currently not being set and might be removed + in the next version. Deprecated: use "NeuronMonitor.Status.Scale.Replicas" + instead.' + format: int32 + type: integer + scale: + description: Scale is the NeuronMonitor's scale subresource status. + properties: + replicas: + description: The total number non-terminated pods targeted by + this AmazonCloudWatchAgent's deployment or statefulSet. + format: int32 + type: integer + selector: + description: The selector used to match the AmazonCloudWatchAgent's + deployment or statefulSet pods. + type: string + statusReplicas: + description: StatusReplicas is the number of pods targeted by + this AmazonCloudWatchAgent's with a Ready Condition / Total + number of non-terminated pods targeted by this AmazonCloudWatchAgent's + (their labels match the selector). Deployment, Daemonset, StatefulSet. + type: string + type: object + version: + description: Version of the managed Neuron Monitor Exporter (operand) + type: string + type: object + type: object + served: true + storage: true + subresources: + scale: + labelSelectorPath: .status.scale.selector + specReplicasPath: .spec.replicas + statusReplicasPath: .status.scale.replicas + status: {} diff --git a/charts/amazon-cloudwatch-observability/images/cw-1.png b/charts/amazon-cloudwatch-observability/images/cw-1.png new file mode 100644 index 0000000000000000000000000000000000000000..371e74f72781a1a883ee3ad8c62e1e5c2e84cdee GIT binary patch literal 246828 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

)Oe@}H@v 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

iLS|9dKiU(c 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�<~RU%ujfc4o} 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

v5Fl};HnW!*I$wQwEpfu;O#_0f;Yw8kW+ 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 snPKt+7iH>jY_ye}_CK*nwH@aY"}} when no feature targets the agent +*/}} +{{- define "cloudwatch-agent.build-default-config" -}} +{{- $agentName := .agentName -}} +{{- $ctx := .context -}} +{{- $region := $ctx.Values.region | required ".Values.region is required." -}} +{{- $config := dict "agent" (dict "region" $region) -}} +{{- $needsLogs := false -}} +{{- $metricsCollected := dict -}} +{{/* Application Signals: add logs.metrics_collected.application_signals + traces.traces_collected.application_signals */}} +{{- if and $ctx.Values.applicationSignals.enabled (eq $ctx.Values.applicationSignals.targetAgent $agentName) -}} + {{- $needsLogs = true -}} + {{- $_ := set $metricsCollected "application_signals" dict -}} + {{- $_ := set $config "traces" (dict "traces_collected" (dict "application_signals" dict)) -}} +{{- end -}} +{{/* Container Insights: add logs.metrics_collected.kubernetes */}} +{{- if and $ctx.Values.containerInsights.enabled (eq $ctx.Values.containerInsights.targetAgent $agentName) -}} + {{- $needsLogs = true -}} + {{- $_ := set $metricsCollected "kubernetes" (dict "enhanced_container_insights" true) -}} +{{- end -}} +{{- if $needsLogs -}} + {{- $_ := set $config "logs" (dict "metrics_collected" $metricsCollected) -}} +{{- end -}} +{{- $config | toJson -}} +{{- end -}} + +{{/* +Build the default OTEL YAML config for a given agent based on which feature flags target it. +Accepts a dict with "agentName" (string) and "context" (root context $). +Returns OTEL YAML string. + +Logic: + - When otelContainerInsights.enabled is false, return empty config ({}) + - When otelContainerInsights.targetAgent matches agentName, return node-level OTEL CI config + - When otelContainerInsights.clusterScraperAgent matches agentName, return cluster-level OTEL CI config + - Default: return empty config ({}) +*/}} +{{- define "cloudwatch-agent.validate-flags" -}} +{{- /* + Flag validation and type checking for the CI flag state matrix. + Four flags control CI behavior: + - containerInsights.enabled (ECI) — legacy Container Insights metrics + - containerLogs.enabled (FB) — FluentBit log pipeline + - otelContainerInsights.enabled — OTEL Container Insights (metrics) + - otelContainerInsights.logs.enabled — OTEL log pipelines + + All flag combinations are valid. Notable behaviors: + - otelCI.logs.enabled=true without otelCI.enabled=true is a no-op + (logs config is only rendered when the parent OTEL CI pipeline is active) + - otelCI.enabled=true + containerLogs.enabled=true = dual-publish + (both OTEL and FluentBit log pipelines run simultaneously) +*/ -}} +{{- if not (kindIs "bool" .Values.containerInsights.enabled) }} +{{- fail "containerInsights.enabled must be a boolean (true/false)" }} +{{- end }} +{{- if not (kindIs "bool" .Values.containerLogs.enabled) }} +{{- fail "containerLogs.enabled must be a boolean (true/false)" }} +{{- end }} +{{- if not (kindIs "bool" .Values.otelContainerInsights.enabled) }} +{{- fail "otelContainerInsights.enabled must be a boolean (true/false)" }} +{{- end }} +{{- if not (kindIs "bool" .Values.otelContainerInsights.logs.enabled) }} +{{- fail "otelContainerInsights.logs.enabled must be a boolean (true/false)" }} +{{- end }} +{{- end -}} + +{{- define "cloudwatch-agent.build-default-otel-config" -}} +{{- $agentName := .agentName -}} +{{- $ctx := .context -}} +{{- include "cloudwatch-agent.validate-flags" $ctx -}} +{{- if not $ctx.Values.otelContainerInsights.enabled -}} +{} +{{- else if eq $ctx.Values.otelContainerInsights.targetAgent $agentName -}} +{{- include "otel-container-insights.config" $ctx -}} +{{- else if eq $ctx.Values.otelContainerInsights.clusterScraperAgent $agentName -}} +{{- include "otel-container-insights-cluster-scraper.config" $ctx -}} +{{- else -}} +{} +{{- end -}} +{{- end -}} + +{{/* +Helper function to modify cloudwatch-agent config +*/}} +{{- define "cloudwatch-agent.config-modifier" -}} +{{- $configCopy := deepCopy .Config }} + +{{- $agent := pluck "agent" $configCopy | first }} +{{- if or (empty $agent) (empty $agent.region) }} +{{- $agentRegion := dict "region" .Values.region }} +{{- $agent := set $configCopy "agent" $agentRegion }} +{{- end }} + +{{- if .Values.useDualstackEndpoint }} +{{- if not (hasKey $configCopy "agent") }} +{{- $_ := set $configCopy "agent" dict }} +{{- end }} +{{- $_ := set $configCopy.agent "use_dualstack_endpoint" true }} +{{- end }} + +{{- if and (hasKey $configCopy "logs") (hasKey $configCopy.logs "metrics_collected") }} +{{- $appSignals := pluck "application_signals" $configCopy.logs.metrics_collected | first }} +{{- if and (hasKey $configCopy.logs.metrics_collected "application_signals") (empty $appSignals.hosted_in) }} +{{- $clusterName := .Values.clusterName | toString | required ".Values.clusterName is required." -}} +{{- $appSignals := set $appSignals "hosted_in" $clusterName }} +{{- end }} + +{{- $containerInsights := pluck "kubernetes" $configCopy.logs.metrics_collected | first }} +{{- if and (hasKey $configCopy.logs.metrics_collected "kubernetes") (empty $containerInsights.cluster_name) }} +{{- $clusterName := .Values.clusterName | toString | required ".Values.clusterName is required." -}} +{{- $containerInsights := set $containerInsights "cluster_name" $clusterName }} +{{- end }} +{{- end }} + +{{- default "" $configCopy | toJson | quote }} +{{- end }} + +{{/* +Helper function to modify customer supplied agent config if ContainerInsights or ApplicationSignals is enabled +*/}} +{{- define "cloudwatch-agent.modify-config" -}} +{{- if and (hasKey .Config "logs") (or (and (hasKey .Config.logs "metrics_collected") (hasKey .Config.logs.metrics_collected "application_signals")) (and (hasKey .Config.logs "metrics_collected") (hasKey .Config.logs.metrics_collected "kubernetes"))) }} +{{- include "cloudwatch-agent.config-modifier" . }} +{{- else }} +{{- default "" .Config | toJson | quote }} +{{- end }} +{{- end }} + +{{/* +Helper function to modify cloudwatch-agent YAML config +*/}} +{{- define "cloudwatch-agent.modify-otel-config" -}} +{{- $configCopy := deepCopy .OtelConfig }} +{{- if kindIs "string" $configCopy }} + {{- $configCopy = fromYaml $configCopy }} + {{- if hasKey $configCopy "Error" }} + {{- fail (printf "Failed to parse otelConfig: %s" (index $configCopy "Error")) }} + {{- end }} +{{- end }} + +{{- range $name, $component := $configCopy }} +{{- if and $component (kindIs "map" $component) }} + {{- range $key, $value := $component }} + {{- if eq $value nil }} + {{- $_ := set $component $key dict }} + {{- end -}} + {{- end }} +{{- end }} +{{- end }} + +{{- $configCopy | toYaml | quote }} +{{- end }} + +{{/* +Compute scrape_timeout: use metricResolution if it's less than 10s, otherwise 10s. +Validates metricResolution is in "s" format. +*/}} +{{- define "otel-container-insights.scrapeTimeout" -}} +{{- $raw := .Values.otelContainerInsights.metricResolution -}} +{{- if not (hasSuffix "s" $raw) -}} + {{- fail (printf "otelContainerInsights.metricResolution must be in \"s\" format (e.g. \"30s\"), got: %s" $raw) -}} +{{- end -}} +{{- $seconds := trimSuffix "s" $raw -}} +{{- if not (regexMatch "^[0-9]+$" $seconds) -}} + {{- fail (printf "otelContainerInsights.metricResolution must be in \"s\" format (e.g. \"30s\"), got: %s" $raw) -}} +{{- end -}} +{{- if lt ($seconds | int) 10 -}} +{{- $raw }} +{{- else -}} +10s +{{- end -}} +{{- end -}} + +{{- define "cloudwatch-agent.rolloutStrategyMaxUnavailable" -}} +{{- if eq .mode "daemonset" -}} +1 +{{- else -}} +25% +{{- end -}} +{{- end -}} + +{{- define "cloudwatch-agent.updateStrategy" -}} +{{- if eq .mode "deployment" -}} +deploymentUpdateStrategy +{{- else -}} +updateStrategy +{{- end -}} +{{- end -}} + +{{- define "cloudwatch-agent.rolloutStrategyMaxSurge" -}} +{{- if eq .mode "daemonset" -}} +0 +{{- else -}} +25% +{{- end -}} +{{- end -}} + +{{/* +Name for cloudwatch-agent +*/}} +{{- define "cloudwatch-agent.name" -}} +{{- default "cloudwatch-agent" .Values.agent.name }} +{{- end }} + +{{/* +Name for dcgm-exporter +*/}} +{{- define "dcgm-exporter.name" -}} +{{- default "dcgm-exporter" .Values.dcgmExporter.name }} +{{- end }} + +{{/* +Name for neuron-monitor +*/}} +{{- define "neuron-monitor.name" -}} +{{- default "neuron-monitor" .Values.neuronMonitor.name }} +{{- end }} + +{{/* +Get the current recommended cloudwatch agent image for a region +*/}} +{{- define "cloudwatch-agent.image" -}} +{{- $imageDomain := "" -}} +{{- $imageDomain = index .repositoryDomainMap .region -}} +{{- if not $imageDomain -}} +{{- $imageDomain = .repositoryDomainMap.public -}} +{{- end -}} +{{- printf "%s/%s:%s" $imageDomain .repository .tag -}} +{{- end -}} + +{{/* +Get the current recommended cloudwatch agent operator image for a region +*/}} +{{- define "cloudwatch-agent-operator.image" -}} +{{- $region := .Values.region | required ".Values.region is required." -}} +{{- $imageDomain := "" -}} +{{- $imageDomain = index .Values.manager.image.repositoryDomainMap .Values.region -}} +{{- if not $imageDomain -}} +{{- $imageDomain = .Values.manager.image.repositoryDomainMap.public -}} +{{- end -}} +{{- printf "%s/%s:%s" $imageDomain .Values.manager.image.repository .Values.manager.image.tag -}} +{{- end -}} + +{{/* +Get the current recommended target allocator image for a region +*/}} +{{- define "target-allocator.image" -}} +{{- $imageDomain := "" -}} +{{- $imageDomain = index .repositoryDomainMap .region -}} +{{- if not $imageDomain -}} +{{- $imageDomain = .repositoryDomainMap.public -}} +{{- end -}} +{{- printf "%s/%s:%s" $imageDomain .repository .tag -}} +{{- end -}} + +{{/* +Get the current recommended fluent-bit image for a region +*/}} +{{- define "fluent-bit.image" -}} +{{- $region := .Values.region | required ".Values.region is required." -}} +{{- $imageDomain := "" -}} +{{- $imageDomain = index .Values.containerLogs.fluentBit.image.repositoryDomainMap .Values.region -}} +{{- if not $imageDomain -}} +{{- $imageDomain = .Values.containerLogs.fluentBit.image.repositoryDomainMap.public -}} +{{- end -}} +{{- printf "%s/%s:%s" $imageDomain .Values.containerLogs.fluentBit.image.repository .Values.containerLogs.fluentBit.image.tag -}} +{{- end -}} + +{{/* +Helper function to add dualstack endpoints to fluent-bit OUTPUT sections +Uses regex to handle variable whitespace in the region line +*/}} +{{- define "fluent-bit.add-dualstack-endpoints" -}} +{{- $config := .config -}} +{{- if and .Values.useDualstackEndpoint (not (contains "endpoint" $config)) -}} +{{- $config = mustRegexReplaceAll "(region\\s+\\$\\{AWS_REGION\\})" $config "$1\n endpoint logs.$${AWS_REGION}.api.aws\n sts_endpoint sts.$${AWS_REGION}.api.aws" -}} +{{- end -}} +{{- $config -}} +{{- end -}} + +{{/* +Helper function to add IPv6 preference to fluent-bit SERVICE section +Inserts net.dns.prefer_ipv6 right after [SERVICE] or [ SERVICE ] header +*/}} +{{- define "fluent-bit.add-ipv6-preference" -}} +{{- $config := .config -}} +{{- $indent := .indent | default " " -}} +{{- if and .useDualstackEndpoint (not (contains "net.dns.prefer_ipv6" $config)) -}} +{{- $config = mustRegexReplaceAll "(\\[\\s*SERVICE\\s*\\])" $config (printf "$1\n%snet.dns.prefer_ipv6 true" $indent) -}} +{{- end -}} +{{- $config -}} +{{- end -}} + +{{/* +Get the current recommended fluent-bit Windows image for a region +*/}} +{{- define "fluent-bit-windows.image" -}} +{{- $region := .Values.region | required ".Values.region is required." -}} +{{- $imageDomain := "" -}} +{{- $imageDomain = index .Values.containerLogs.fluentBit.image.repositoryDomainMap .Values.region -}} +{{- if not $imageDomain -}} +{{- $imageDomain = .Values.containerLogs.fluentBit.image.repositoryDomainMap.public -}} +{{- end -}} +{{- printf "%s/%s:%s" $imageDomain .Values.containerLogs.fluentBit.image.repository .Values.containerLogs.fluentBit.image.tagWindows -}} +{{- end -}} + +{{/* +Get the current recommended dcgm-exporter image for a region +*/}} +{{- define "dcgm-exporter.image" -}} +{{- $region := .Values.region | required ".Values.region is required." -}} +{{- $imageDomain := "" -}} +{{- $imageDomain = index .Values.dcgmExporter.image.repositoryDomainMap .Values.region -}} +{{- if not $imageDomain -}} +{{- $imageDomain = .Values.dcgmExporter.image.repositoryDomainMap.public -}} +{{- end -}} +{{- printf "%s/%s:%s" $imageDomain .Values.dcgmExporter.image.repository .Values.dcgmExporter.image.tag -}} +{{- end -}} + +{{/* +Get the current recommended neuron-monitor image for a region +*/}} +{{- define "neuron-monitor.image" -}} +{{- $imageDomain := "" -}} +{{- $imageDomain = index .Values.neuronMonitor.image.repositoryDomainMap .Values.region -}} +{{- if not $imageDomain -}} +{{- $imageDomain = .Values.neuronMonitor.image.repositoryDomainMap.public -}} +{{- end -}} +{{- printf "%s/%s:%s" $imageDomain .Values.neuronMonitor.image.repository .Values.neuronMonitor.image.tag -}} +{{- end -}} + +{{/* +Set DCGM_EXPORTER_INTERVAL environment variable for dcgmExporter if accelerated_compute_gpu_metrics_collection_interval is set and less than 60 +*/}} +{{- define "dcgm-exporter.env" -}} +{{- $intervalFound := false -}} +{{- $intervalValue := 0 -}} +{{- range .Values.agents -}} + {{- $agent := mergeOverwrite (deepCopy $.Values.agent) . -}} + {{- $agentConfig := $agent.config -}} + {{- if or (not $agentConfig) (eq ($agentConfig | toString) "default") -}} + {{- $agentConfig = dict -}} + {{- end -}} + {{- if and (hasKey $agentConfig "logs") (hasKey $agentConfig.logs "metrics_collected") (hasKey $agentConfig.logs.metrics_collected "kubernetes") (hasKey $agentConfig.logs.metrics_collected.kubernetes "accelerated_compute_gpu_metrics_collection_interval") -}} + {{- $intervalFound = true -}} + {{- $intervalValue = $agentConfig.logs.metrics_collected.kubernetes.accelerated_compute_gpu_metrics_collection_interval -}} + {{- end -}} +{{- end -}} +{{- if and $intervalFound (lt ($intervalValue | int) 60) -}} +- name: DCGM_EXPORTER_INTERVAL + value: "1000" +{{- end -}} +{{- end -}} + +{{/* +Get the current recommended auto instrumentation java image +*/}} +{{- define "auto-instrumentation-java.image" -}} +{{- printf "%s/%s:%s" .Values.manager.autoInstrumentationImage.java.repositoryDomain .Values.manager.autoInstrumentationImage.java.repository .Values.manager.autoInstrumentationImage.java.tag -}} +{{- end -}} + +{{/* +Get the current recommended auto instrumentation python image +*/}} +{{- define "auto-instrumentation-python.image" -}} +{{- printf "%s/%s:%s" .Values.manager.autoInstrumentationImage.python.repositoryDomain .Values.manager.autoInstrumentationImage.python.repository .Values.manager.autoInstrumentationImage.python.tag -}} +{{- end -}} + +{{/* +Get the current recommended auto instrumentation dotnet image +*/}} +{{- define "auto-instrumentation-dotnet.image" -}} +{{- printf "%s/%s:%s" .Values.manager.autoInstrumentationImage.dotnet.repositoryDomain .Values.manager.autoInstrumentationImage.dotnet.repository .Values.manager.autoInstrumentationImage.dotnet.tag -}} +{{- end -}} + +{{/* +Get the current recommended auto instrumentation nodejs image +*/}} +{{- define "auto-instrumentation-nodejs.image" -}} +{{- printf "%s/%s:%s" .Values.manager.autoInstrumentationImage.nodejs.repositoryDomain .Values.manager.autoInstrumentationImage.nodejs.repository .Values.manager.autoInstrumentationImage.nodejs.tag -}} +{{- end -}} + +{{/* +Common labels +*/}} +{{- define "amazon-cloudwatch-observability.labels" -}} +{{ include "amazon-cloudwatch-observability.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: "amazon-cloudwatch-agent-operator" +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "amazon-cloudwatch-observability.selectorLabels" -}} +app.kubernetes.io/name: {{ include "amazon-cloudwatch-observability.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "amazon-cloudwatch-observability.managerServiceAccountName" -}} +{{- if .Values.manager.serviceAccount.create }} +{{- default (printf "%s-controller-manager" (include "amazon-cloudwatch-observability.name" .)) .Values.manager.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.manager.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "cloudwatch-agent.serviceAccountName" -}} +{{- if .Values.agent.enabled }} +{{- default (include "cloudwatch-agent.name" .) .Values.agent.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.agent.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Create the name of the service account to use for dcgm exporter +*/}} +{{- define "dcgm-exporter.serviceAccountName" -}} +{{- default "dcgm-exporter-service-acct" .Values.dcgmExporter.serviceAccount.name }} +{{- end }} + +{{/* +Create the name of the service account to use for neuron monitor +*/}} +{{- define "neuron-monitor.serviceAccountName" -}} +{{- default "neuron-monitor-service-acct" .Values.neuronMonitor.serviceAccount.name }} +{{- end }} + +{{- define "amazon-cloudwatch-observability.podAnnotations" -}} +{{- if .Values.manager.podAnnotations }} +{{- .Values.manager.podAnnotations | toYaml }} +{{- end }} +{{- end }} + +{{- define "amazon-cloudwatch-observability.podLabels" -}} +{{- if .Values.manager.podLabels }} +{{- .Values.manager.podLabels | toYaml }} +{{- end }} +{{- end }} + +{{/* +Define the default certificate secret name +*/}} +{{- define "amazon-cloudwatch-observability.certificateSecretName" -}} +{{- default (printf "%s-controller-manager-service-cert" (include "amazon-cloudwatch-observability.name" .)) .Values.admissionWebhooks.secretName }} +{{- end -}} + +{{/* +Define the default service name +*/}} +{{- define "amazon-cloudwatch-observability.webhookServiceName" -}} +{{- default (printf "%s-webhook-service" (include "amazon-cloudwatch-observability.name" .)) .Values.manager.service.name }} +{{- end -}} + +{{/* +Check if a specific admission webhook is enabled +*/}} +{{- define "amazon-cloudwatch-observability.isWebhookEnabled" -}} +{{- $ctx := index . 0 -}} +{{- $webhook := index . 1 -}} +{{- $webhookConfig := index $ctx.Values.admissionWebhooks $webhook -}} +{{- if hasKey $webhookConfig "create" -}} +{{- if $webhookConfig.create }}true{{- end -}} +{{- else -}} +{{- if $ctx.Values.admissionWebhooks.create }}true{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Check if any admission webhook is enabled +*/}} +{{- define "amazon-cloudwatch-observability.webhookEnabled" -}} +{{- $webhooks := list "agents" "instrumentations" "pods" "workloads" "namespaces" -}} +{{- range $webhook := $webhooks -}} +{{- if include "amazon-cloudwatch-observability.isWebhookEnabled" (list $ $webhook) -}} +true +{{- break -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Get namespaceSelector value for admission webhooks +*/}} +{{- define "amazon-cloudwatch-observability.namespaceSelector" -}} +{{- $ctx := index . 0 -}} +{{- $webhook := index . 1 -}} +{{- $webhookConfig := index $ctx.Values.admissionWebhooks $webhook -}} +{{- if and (hasKey $webhookConfig "namespaceSelector") (ne $webhookConfig.namespaceSelector nil) -}} +{{- $selector := $webhookConfig.namespaceSelector -}} +{{- if $selector -}} +{{- toYaml $selector | nindent 4 -}} +{{- else -}} +{} +{{- end -}} +{{- else -}} +{{- $selector := $ctx.Values.admissionWebhooks.namespaceSelector -}} +{{- if $selector -}} +{{- toYaml $selector | nindent 4 -}} +{{- else -}} +{} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Returns auto-generated certificate and CA for admission webhooks. +*/}} +{{- define "amazon-cloudwatch-observability.webhookCert" -}} +{{- $tlsCrt := "" }} +{{- $tlsKey := "" }} +{{- $caCrt := "" }} +{{- if .Values.admissionWebhooks.autoGenerateCert.enabled }} +{{- $existingCert := ( lookup "v1" "Secret" .Release.Namespace (include "amazon-cloudwatch-observability.certificateSecretName" .) ) }} +{{- if and (not .Values.admissionWebhooks.autoGenerateCert.recreate) $existingCert }} +{{- $tlsCrt = index $existingCert "data" "tls.crt" }} +{{- $tlsKey = index $existingCert "data" "tls.key" }} +{{- $caCrt = index $existingCert "data" "ca.crt" }} +{{- if not $caCrt }} +{{- $existingWebhook := ( lookup "admissionregistration.k8s.io/v1" "MutatingWebhookConfiguration" "" (printf "%s-mutating-webhook-configuration" (include "amazon-cloudwatch-observability.name" .)) ) }} +{{- $caCrt = (first $existingWebhook.webhooks).clientConfig.caBundle }} +{{- end }} +{{- else }} +{{- $altNames := list ( printf "%s-webhook-service.%s" (include "amazon-cloudwatch-observability.name" .) .Release.Namespace ) ( printf "%s-webhook-service.%s.svc" (include "amazon-cloudwatch-observability.name" .) .Release.Namespace ) ( printf "%s-webhook-service.%s.svc.cluster.local" (include "amazon-cloudwatch-observability.name" .) .Release.Namespace ) -}} +{{- $ca := genCA ( printf "%s-ca" (include "amazon-cloudwatch-observability.name" .) ) ( .Values.admissionWebhooks.autoGenerateCert.expiryDays | int ) -}} +{{- $cert := genSignedCert (include "amazon-cloudwatch-observability.name" .) nil $altNames ( .Values.admissionWebhooks.autoGenerateCert.expiryDays | int ) $ca -}} +{{- $tlsCrt = b64enc $cert.Cert }} +{{- $tlsKey = b64enc $cert.Key }} +{{- $caCrt = b64enc $ca.Cert }} +{{- end }} +{{- $result := dict "Cert" $tlsCrt "Key" $tlsKey "Ca" $caCrt }} +{{- $result | toYaml }} +{{- end }} +{{- end }} + +{{/* +Name for node-exporter +*/}} +{{- define "node-exporter.name" -}} +{{- default "node-exporter" .Values.nodeExporter.name }} +{{- end }} + +{{/* +Create the name of the service account to use for node exporter +*/}} +{{- define "node-exporter.serviceAccountName" -}} +{{- default "node-exporter-service-acct" .Values.nodeExporter.serviceAccount.name }} +{{- end }} + +{{/* +Get the node-exporter scope version (image tag) for the configured region. +Uses restrictedTag for regions with a repositoryDomainMap entry, public tag otherwise. +*/}} +{{- define "node-exporter.scopeVersion" -}} +{{- if and (hasKey .Values.nodeExporter.image.repositoryDomainMap .Values.region) (index .Values.nodeExporter.image.repositoryDomainMap .Values.region) -}} +{{- .Values.nodeExporter.image.restrictedTag -}} +{{- else -}} +{{- .Values.nodeExporter.image.tag -}} +{{- end -}} +{{- end -}} + +{{/* +Get the node-exporter image for the configured region using repositoryDomainMap +*/}} +{{- define "node-exporter.image" -}} +{{- if and (hasKey .Values.nodeExporter.image.repositoryDomainMap .Values.region) (index .Values.nodeExporter.image.repositoryDomainMap .Values.region) -}} +{{- $imageDomain := index .Values.nodeExporter.image.repositoryDomainMap .Values.region -}} +{{- printf "%s/%s:%s" $imageDomain .Values.nodeExporter.image.restrictedRepository .Values.nodeExporter.image.restrictedTag -}} +{{- else -}} +{{- $imageDomain := .Values.nodeExporter.image.repositoryDomainMap.public -}} +{{- printf "%s/%s:%s" $imageDomain .Values.nodeExporter.image.repository .Values.nodeExporter.image.tag -}} +{{- end -}} +{{- end -}} + +{{/* +Name for kube-state-metrics +*/}} +{{- define "kube-state-metrics.name" -}} +{{- default "kube-state-metrics" .Values.kubeStateMetrics.name }} +{{- end }} + +{{/* +Create the name of the service account to use for kube-state-metrics +*/}} +{{- define "kube-state-metrics.serviceAccountName" -}} +{{- default "kube-state-metrics-service-acct" .Values.kubeStateMetrics.serviceAccount.name }} +{{- end }} + +{{/* +Get the kube-state-metrics scope version (image tag) for the configured region. +Uses restrictedTag for regions with a repositoryDomainMap entry, public tag otherwise. +*/}} +{{- define "kube-state-metrics.scopeVersion" -}} +{{- if and (hasKey .Values.kubeStateMetrics.image.repositoryDomainMap .Values.region) (index .Values.kubeStateMetrics.image.repositoryDomainMap .Values.region) -}} +{{- .Values.kubeStateMetrics.image.restrictedTag -}} +{{- else -}} +{{- .Values.kubeStateMetrics.image.tag -}} +{{- end -}} +{{- end -}} + +{{/* +Get the kube-state-metrics image for the configured region using repositoryDomainMap +*/}} +{{- define "kube-state-metrics.image" -}} +{{- if and (hasKey .Values.kubeStateMetrics.image.repositoryDomainMap .Values.region) (index .Values.kubeStateMetrics.image.repositoryDomainMap .Values.region) -}} +{{- $imageDomain := index .Values.kubeStateMetrics.image.repositoryDomainMap .Values.region -}} +{{- printf "%s/%s:%s" $imageDomain .Values.kubeStateMetrics.image.restrictedRepository .Values.kubeStateMetrics.image.restrictedTag -}} +{{- else -}} +{{- $imageDomain := .Values.kubeStateMetrics.image.repositoryDomainMap.public -}} +{{- printf "%s/%s:%s" $imageDomain .Values.kubeStateMetrics.image.repository .Values.kubeStateMetrics.image.tag -}} +{{- end -}} +{{- end -}} + +{{/* +Merge two OTEL configs. The generated OTLP CI config (Base) takes precedence over the +user-supplied otelConfig (User) on name collision. For map sections (extensions, receivers, +processors, exporters) both sets of entries are combined, with generated entries winning on +key collision. For service.extensions (a list) both lists are concatenated and deduped. +For service.pipelines (a map) both pipeline maps are combined, with generated pipelines +winning on key collision. +*/}} +{{- define "cloudwatch-agent.merge-otel-configs" -}} +{{- $base := .Base -}} +{{- $user := .User -}} +{{- if kindIs "string" $base }} + {{- $base = fromYaml $base }} + {{- if hasKey $base "Error" }} + {{- fail (printf "Failed to parse generated otelConfig: %s" (index $base "Error")) }} + {{- end }} +{{- end }} +{{- if kindIs "string" $user }} + {{- $user = fromYaml $user }} + {{- if hasKey $user "Error" }} + {{- fail (printf "Failed to parse user-supplied otelConfig: %s" (index $user "Error")) }} + {{- end }} +{{- end }} +{{/* Merge top-level map sections: extensions, receivers, processors, exporters */}} +{{- $merged := deepCopy $base -}} +{{- range $section := list "extensions" "receivers" "processors" "exporters" -}} + {{- if and (hasKey $user $section) (hasKey $merged $section) -}} + {{- $_ := set $merged $section (mustMergeOverwrite (index $user $section) (index $merged $section)) -}} + {{- else if hasKey $user $section -}} + {{- $_ := set $merged $section (index $user $section) -}} + {{- end -}} +{{- end -}} +{{/* Merge service section */}} +{{- if and (hasKey $user "service") (hasKey $merged "service") -}} + {{/* Concatenate service.extensions lists */}} + {{- if and (hasKey $user.service "extensions") (hasKey $merged.service "extensions") -}} + {{- $mergedExts := concat $merged.service.extensions $user.service.extensions | uniq -}} + {{- $_ := set $merged.service "extensions" $mergedExts -}} + {{- else if hasKey $user.service "extensions" -}} + {{- $_ := set $merged.service "extensions" $user.service.extensions -}} + {{- end -}} + {{/* Merge service.pipelines maps */}} + {{- if and (hasKey $user.service "pipelines") (hasKey $merged.service "pipelines") -}} + {{- $_ := set $merged.service "pipelines" (mustMergeOverwrite $user.service.pipelines $merged.service.pipelines) -}} + {{- else if hasKey $user.service "pipelines" -}} + {{- $_ := set $merged.service "pipelines" $user.service.pipelines -}} + {{- end -}} +{{- else if hasKey $user "service" -}} + {{- $_ := set $merged "service" $user.service -}} +{{- end -}} +{{- $merged | toYaml -}} +{{- end -}} diff --git a/charts/amazon-cloudwatch-observability/templates/admission-webhooks/operator-webhook-with-cert-manager.yaml b/charts/amazon-cloudwatch-observability/templates/admission-webhooks/operator-webhook-with-cert-manager.yaml new file mode 100644 index 0000000..3709495 --- /dev/null +++ b/charts/amazon-cloudwatch-observability/templates/admission-webhooks/operator-webhook-with-cert-manager.yaml @@ -0,0 +1,273 @@ +{{- if and (.Values.admissionWebhooks.certManager.enabled) (include "amazon-cloudwatch-observability.webhookEnabled" .) }} +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + annotations: + cert-manager.io/inject-ca-from: {{ printf "%s/%s-serving-cert" .Release.Namespace (include "amazon-cloudwatch-observability.name" .) }} + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4}} + name: {{ template "amazon-cloudwatch-observability.name" . }}-mutating-webhook-configuration +webhooks: +{{- if include "amazon-cloudwatch-observability.isWebhookEnabled" (list . "instrumentations") }} +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: {{ template "amazon-cloudwatch-observability.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /mutate-cloudwatch-aws-amazon-com-v1alpha1-instrumentation + failurePolicy: {{ .Values.admissionWebhooks.instrumentations.failurePolicy | default .Values.admissionWebhooks.failurePolicy }} + name: minstrumentation.kb.io + namespaceSelector: {{ include "amazon-cloudwatch-observability.namespaceSelector" (list . "instrumentations") }} + {{- if .Values.admissionWebhooks.objectSelector }} + objectSelector: + {{- toYaml .Values.admissionWebhooks.objectSelector | nindent 6 }} + {{- end }} + rules: + - apiGroups: + - cloudwatch.aws.amazon.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - instrumentations + sideEffects: None + timeoutSeconds: {{ .Values.admissionWebhooks.timeoutSeconds }} +{{- end }} +{{- if include "amazon-cloudwatch-observability.isWebhookEnabled" (list . "agents") }} +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: {{ template "amazon-cloudwatch-observability.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /mutate-cloudwatch-aws-amazon-com-v1alpha1-amazoncloudwatchagent + failurePolicy: {{ .Values.admissionWebhooks.agents.failurePolicy | default .Values.admissionWebhooks.failurePolicy }} + name: mamazoncloudwatchagent.kb.io + namespaceSelector: {{ include "amazon-cloudwatch-observability.namespaceSelector" (list . "agents") }} + {{- if .Values.admissionWebhooks.objectSelector }} + objectSelector: + {{- toYaml .Values.admissionWebhooks.objectSelector | nindent 6 }} + {{- end }} + rules: + - apiGroups: + - cloudwatch.aws.amazon.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - amazoncloudwatchagents + sideEffects: None + timeoutSeconds: {{ .Values.admissionWebhooks.timeoutSeconds }} +{{- end }} +{{- if include "amazon-cloudwatch-observability.isWebhookEnabled" (list . "pods") }} +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: {{ template "amazon-cloudwatch-observability.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /mutate-v1-pod + failurePolicy: {{ .Values.admissionWebhooks.pods.failurePolicy | default .Values.admissionWebhooks.failurePolicy }} + name: mpod.kb.io + namespaceSelector: {{ include "amazon-cloudwatch-observability.namespaceSelector" (list . "pods") }} + {{- if .Values.admissionWebhooks.objectSelector }} + objectSelector: + {{- toYaml .Values.admissionWebhooks.objectSelector | nindent 6 }} + {{- end }} + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - pods + sideEffects: None + timeoutSeconds: {{ .Values.admissionWebhooks.timeoutSeconds }} +{{- end }} +{{- if include "amazon-cloudwatch-observability.isWebhookEnabled" (list . "namespaces") }} +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: {{ template "amazon-cloudwatch-observability.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /mutate-v1-namespace + failurePolicy: {{ .Values.admissionWebhooks.namespaces.failurePolicy | default .Values.admissionWebhooks.pods.failurePolicy | default .Values.admissionWebhooks.failurePolicy }} + name: mnamespace.kb.io + namespaceSelector: {{ include "amazon-cloudwatch-observability.namespaceSelector" (list . "namespaces") }} + {{- if .Values.admissionWebhooks.objectSelector }} + objectSelector: + {{- toYaml .Values.admissionWebhooks.objectSelector | nindent 6 }} + {{- end }} + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - namespaces + sideEffects: None + timeoutSeconds: {{ .Values.admissionWebhooks.timeoutSeconds }} +{{- end }} +{{- if include "amazon-cloudwatch-observability.isWebhookEnabled" (list . "workloads") }} +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: {{ template "amazon-cloudwatch-observability.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /mutate-v1-workload + failurePolicy: {{ .Values.admissionWebhooks.workloads.failurePolicy | default .Values.admissionWebhooks.pods.failurePolicy | default .Values.admissionWebhooks.failurePolicy }} + name: mworkload.kb.io + namespaceSelector: {{ include "amazon-cloudwatch-observability.namespaceSelector" (list . "workloads") }} + {{- if .Values.admissionWebhooks.objectSelector }} + objectSelector: + {{- toYaml .Values.admissionWebhooks.objectSelector | nindent 6 }} + {{- end }} + rules: + - apiGroups: + - apps + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - daemonsets + - deployments + - statefulsets + sideEffects: None + timeoutSeconds: {{ .Values.admissionWebhooks.timeoutSeconds }} +{{- end }} +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + annotations: + cert-manager.io/inject-ca-from: {{ printf "%s/%s-serving-cert" .Release.Namespace (include "amazon-cloudwatch-observability.name" .) }} + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4}} + name: {{ template "amazon-cloudwatch-observability.name" . }}-validating-webhook-configuration +webhooks: +{{- if include "amazon-cloudwatch-observability.isWebhookEnabled" (list . "instrumentations") }} +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: {{ template "amazon-cloudwatch-observability.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-cloudwatch-aws-amazon-com-v1alpha1-instrumentation + failurePolicy: {{ .Values.admissionWebhooks.instrumentations.failurePolicy | default .Values.admissionWebhooks.failurePolicy }} + name: vinstrumentationcreateupdate.kb.io + namespaceSelector: {{ include "amazon-cloudwatch-observability.namespaceSelector" (list . "instrumentations") }} + {{- if .Values.admissionWebhooks.objectSelector }} + objectSelector: + {{- toYaml .Values.admissionWebhooks.objectSelector | nindent 6 }} + {{- end }} + rules: + - apiGroups: + - cloudwatch.aws.amazon.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - instrumentations + sideEffects: None + timeoutSeconds: {{ .Values.admissionWebhooks.timeoutSeconds }} +{{- end }} +{{- if include "amazon-cloudwatch-observability.isWebhookEnabled" (list . "instrumentations") }} +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: {{ template "amazon-cloudwatch-observability.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-cloudwatch-aws-amazon-com-v1alpha1-instrumentation + failurePolicy: Ignore + name: vinstrumentationdelete.kb.io + namespaceSelector: {{ include "amazon-cloudwatch-observability.namespaceSelector" (list . "instrumentations") }} + {{- if .Values.admissionWebhooks.objectSelector }} + objectSelector: + {{- toYaml .Values.admissionWebhooks.objectSelector | nindent 6 }} + {{- end }} + rules: + - apiGroups: + - cloudwatch.aws.amazon.com + apiVersions: + - v1alpha1 + operations: + - DELETE + resources: + - instrumentations + sideEffects: None + timeoutSeconds: {{ .Values.admissionWebhooks.timeoutSeconds }} +{{- end }} +{{- if include "amazon-cloudwatch-observability.isWebhookEnabled" (list . "agents") }} +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: {{ template "amazon-cloudwatch-observability.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-cloudwatch-aws-amazon-com-v1alpha1-amazoncloudwatchagent + failurePolicy: {{ .Values.admissionWebhooks.agents.failurePolicy | default .Values.admissionWebhooks.failurePolicy }} + name: vamazoncloudwatchagentcreateupdate.kb.io + namespaceSelector: {{ include "amazon-cloudwatch-observability.namespaceSelector" (list . "agents") }} + {{- if .Values.admissionWebhooks.objectSelector }} + objectSelector: + {{- toYaml .Values.admissionWebhooks.objectSelector | nindent 6 }} + {{- end }} + rules: + - apiGroups: + - cloudwatch.aws.amazon.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - amazoncloudwatchagents + sideEffects: None + timeoutSeconds: {{ .Values.admissionWebhooks.timeoutSeconds }} +{{- end }} +{{- if include "amazon-cloudwatch-observability.isWebhookEnabled" (list . "agents") }} +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: {{ template "amazon-cloudwatch-observability.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-cloudwatch-aws-amazon-com-v1alpha1-amazoncloudwatchagent + failurePolicy: Ignore + name: vamazoncloudwatchagentdelete.kb.io + namespaceSelector: {{ include "amazon-cloudwatch-observability.namespaceSelector" (list . "agents") }} + {{- if .Values.admissionWebhooks.objectSelector }} + objectSelector: + {{- toYaml .Values.admissionWebhooks.objectSelector | nindent 6 }} + {{- end }} + rules: + - apiGroups: + - cloudwatch.aws.amazon.com + apiVersions: + - v1alpha1 + operations: + - DELETE + resources: + - amazoncloudwatchagents + sideEffects: None + timeoutSeconds: {{ .Values.admissionWebhooks.timeoutSeconds }} +{{- end }} +{{- end }} diff --git a/charts/amazon-cloudwatch-observability/templates/admission-webhooks/operator-webhook.yaml b/charts/amazon-cloudwatch-observability/templates/admission-webhooks/operator-webhook.yaml new file mode 100644 index 0000000..d34897a --- /dev/null +++ b/charts/amazon-cloudwatch-observability/templates/admission-webhooks/operator-webhook.yaml @@ -0,0 +1,291 @@ +{{- if and (.Values.admissionWebhooks.autoGenerateCert.enabled) (not .Values.admissionWebhooks.certManager.enabled) (include "amazon-cloudwatch-observability.webhookEnabled" .) }} +{{- $cert := fromYaml (include "amazon-cloudwatch-observability.webhookCert" .) }} +apiVersion: v1 +kind: Secret +type: kubernetes.io/tls +metadata: + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4}} + name: {{ template "amazon-cloudwatch-observability.certificateSecretName" . }} + namespace: {{ .Release.Namespace }} +data: + tls.crt: {{ $cert.Cert }} + tls.key: {{ $cert.Key }} +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4}} + name: {{ template "amazon-cloudwatch-observability.name" . }}-mutating-webhook-configuration +webhooks: +{{- if include "amazon-cloudwatch-observability.isWebhookEnabled" (list . "instrumentations") }} +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: {{ template "amazon-cloudwatch-observability.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /mutate-cloudwatch-aws-amazon-com-v1alpha1-instrumentation + caBundle: {{ $cert.Ca }} + failurePolicy: {{ .Values.admissionWebhooks.instrumentations.failurePolicy | default .Values.admissionWebhooks.failurePolicy }} + name: minstrumentation.kb.io + namespaceSelector: {{ include "amazon-cloudwatch-observability.namespaceSelector" (list . "instrumentations") }} + {{- if .Values.admissionWebhooks.objectSelector }} + objectSelector: + {{- toYaml .Values.admissionWebhooks.objectSelector | nindent 6 }} + {{- end }} + rules: + - apiGroups: + - cloudwatch.aws.amazon.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - instrumentations + sideEffects: None + timeoutSeconds: {{ .Values.admissionWebhooks.timeoutSeconds }} +{{- end }} +{{- if include "amazon-cloudwatch-observability.isWebhookEnabled" (list . "agents") }} +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: {{ template "amazon-cloudwatch-observability.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /mutate-cloudwatch-aws-amazon-com-v1alpha1-amazoncloudwatchagent + caBundle: {{ $cert.Ca }} + failurePolicy: {{ .Values.admissionWebhooks.agents.failurePolicy | default .Values.admissionWebhooks.failurePolicy }} + name: mamazoncloudwatchagent.kb.io + namespaceSelector: {{ include "amazon-cloudwatch-observability.namespaceSelector" (list . "agents") }} + {{- if .Values.admissionWebhooks.objectSelector }} + objectSelector: + {{- toYaml .Values.admissionWebhooks.objectSelector | nindent 6 }} + {{- end }} + rules: + - apiGroups: + - cloudwatch.aws.amazon.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - amazoncloudwatchagents + sideEffects: None + timeoutSeconds: {{ .Values.admissionWebhooks.timeoutSeconds }} +{{- end }} +{{- if include "amazon-cloudwatch-observability.isWebhookEnabled" (list . "pods") }} +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: {{ template "amazon-cloudwatch-observability.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /mutate-v1-pod + caBundle: {{ $cert.Ca }} + failurePolicy: {{ .Values.admissionWebhooks.pods.failurePolicy | default .Values.admissionWebhooks.failurePolicy }} + name: mpod.kb.io + namespaceSelector: {{ include "amazon-cloudwatch-observability.namespaceSelector" (list . "pods") }} + {{- if .Values.admissionWebhooks.objectSelector }} + objectSelector: + {{- toYaml .Values.admissionWebhooks.objectSelector | nindent 6 }} + {{- end }} + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - pods + sideEffects: None + timeoutSeconds: {{ .Values.admissionWebhooks.timeoutSeconds }} +{{- end }} +{{- if include "amazon-cloudwatch-observability.isWebhookEnabled" (list . "namespaces") }} +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: {{ template "amazon-cloudwatch-observability.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /mutate-v1-namespace + caBundle: {{ $cert.Ca }} + failurePolicy: {{ .Values.admissionWebhooks.namespaces.failurePolicy | default .Values.admissionWebhooks.pods.failurePolicy | default .Values.admissionWebhooks.failurePolicy }} + name: mnamespace.kb.io + namespaceSelector: {{ include "amazon-cloudwatch-observability.namespaceSelector" (list . "namespaces") }} + {{- if .Values.admissionWebhooks.objectSelector }} + objectSelector: + {{- toYaml .Values.admissionWebhooks.objectSelector | nindent 6 }} + {{- end }} + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - namespaces + sideEffects: None + timeoutSeconds: {{ .Values.admissionWebhooks.timeoutSeconds }} +{{- end }} +{{- if include "amazon-cloudwatch-observability.isWebhookEnabled" (list . "workloads") }} +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: {{ template "amazon-cloudwatch-observability.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /mutate-v1-workload + caBundle: {{ $cert.Ca }} + failurePolicy: {{ .Values.admissionWebhooks.workloads.failurePolicy | default .Values.admissionWebhooks.pods.failurePolicy | default .Values.admissionWebhooks.failurePolicy }} + name: mworkload.kb.io + namespaceSelector: {{ include "amazon-cloudwatch-observability.namespaceSelector" (list . "workloads") }} + {{- if .Values.admissionWebhooks.objectSelector }} + objectSelector: + {{- toYaml .Values.admissionWebhooks.objectSelector | nindent 6 }} + {{- end }} + rules: + - apiGroups: + - apps + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - daemonsets + - deployments + - statefulsets + sideEffects: None + timeoutSeconds: {{ .Values.admissionWebhooks.timeoutSeconds }} +{{- end }} +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4}} + name: {{ template "amazon-cloudwatch-observability.name" . }}-validating-webhook-configuration +webhooks: +{{- if include "amazon-cloudwatch-observability.isWebhookEnabled" (list . "instrumentations") }} +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: {{ template "amazon-cloudwatch-observability.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-cloudwatch-aws-amazon-com-v1alpha1-instrumentation + caBundle: {{ $cert.Ca }} + failurePolicy: {{ .Values.admissionWebhooks.instrumentations.failurePolicy | default .Values.admissionWebhooks.failurePolicy }} + name: vinstrumentationcreateupdate.kb.io + namespaceSelector: {{ include "amazon-cloudwatch-observability.namespaceSelector" (list . "instrumentations") }} + {{- if .Values.admissionWebhooks.objectSelector }} + objectSelector: + {{- toYaml .Values.admissionWebhooks.objectSelector | nindent 6 }} + {{- end }} + rules: + - apiGroups: + - cloudwatch.aws.amazon.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - instrumentations + sideEffects: None + timeoutSeconds: {{ .Values.admissionWebhooks.timeoutSeconds }} +{{- end }} +{{- if include "amazon-cloudwatch-observability.isWebhookEnabled" (list . "instrumentations") }} +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: {{ template "amazon-cloudwatch-observability.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-cloudwatch-aws-amazon-com-v1alpha1-instrumentation + caBundle: {{ $cert.Ca }} + failurePolicy: Ignore + name: vinstrumentationdelete.kb.io + namespaceSelector: {{ include "amazon-cloudwatch-observability.namespaceSelector" (list . "instrumentations") }} + {{- if .Values.admissionWebhooks.objectSelector }} + objectSelector: + {{- toYaml .Values.admissionWebhooks.objectSelector | nindent 6 }} + {{- end }} + rules: + - apiGroups: + - cloudwatch.aws.amazon.com + apiVersions: + - v1alpha1 + operations: + - DELETE + resources: + - instrumentations + sideEffects: None + timeoutSeconds: {{ .Values.admissionWebhooks.timeoutSeconds }} +{{- end }} +{{- if include "amazon-cloudwatch-observability.isWebhookEnabled" (list . "agents") }} +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: {{ template "amazon-cloudwatch-observability.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-cloudwatch-aws-amazon-com-v1alpha1-amazoncloudwatchagent + caBundle: {{ $cert.Ca }} + failurePolicy: {{ .Values.admissionWebhooks.agents.failurePolicy | default .Values.admissionWebhooks.failurePolicy }} + name: vamazoncloudwatchagentcreateupdate.kb.io + namespaceSelector: {{ include "amazon-cloudwatch-observability.namespaceSelector" (list . "agents") }} + {{- if .Values.admissionWebhooks.objectSelector }} + objectSelector: + {{- toYaml .Values.admissionWebhooks.objectSelector | nindent 6 }} + {{- end }} + rules: + - apiGroups: + - cloudwatch.aws.amazon.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - amazoncloudwatchagents + sideEffects: None + timeoutSeconds: {{ .Values.admissionWebhooks.timeoutSeconds }} +{{- end }} +{{- if include "amazon-cloudwatch-observability.isWebhookEnabled" (list . "agents") }} +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: {{ template "amazon-cloudwatch-observability.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-cloudwatch-aws-amazon-com-v1alpha1-amazoncloudwatchagent + caBundle: {{ $cert.Ca }} + failurePolicy: Ignore + name: vamazoncloudwatchagentdelete.kb.io + namespaceSelector: {{ include "amazon-cloudwatch-observability.namespaceSelector" (list . "agents") }} + {{- if .Values.admissionWebhooks.objectSelector }} + objectSelector: + {{- toYaml .Values.admissionWebhooks.objectSelector | nindent 6 }} + {{- end }} + rules: + - apiGroups: + - cloudwatch.aws.amazon.com + apiVersions: + - v1alpha1 + operations: + - DELETE + resources: + - amazoncloudwatchagents + sideEffects: None + timeoutSeconds: {{ .Values.admissionWebhooks.timeoutSeconds }} +{{- end }} +{{- end }} diff --git a/charts/amazon-cloudwatch-observability/templates/certmanager.yaml b/charts/amazon-cloudwatch-observability/templates/certmanager.yaml new file mode 100644 index 0000000..e8f1612 --- /dev/null +++ b/charts/amazon-cloudwatch-observability/templates/certmanager.yaml @@ -0,0 +1,176 @@ +{{- if and .Values.admissionWebhooks.create .Values.admissionWebhooks.certManager.enabled }} +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + {{- if .Values.admissionWebhooks.certManager.certificateAnnotations }} + annotations: + {{- toYaml .Values.admissionWebhooks.certManager.certificateAnnotations | nindent 4 }} + {{- end }} + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4 }} + name: {{ template "amazon-cloudwatch-observability.name" . }}-serving-cert + namespace: {{ .Release.Namespace }} +spec: + dnsNames: + - {{ template "amazon-cloudwatch-observability.name" .}}-webhook-service.{{ .Release.Namespace }} + - {{ template "amazon-cloudwatch-observability.name" .}}-webhook-service.{{ .Release.Namespace }}.svc + - {{ template "amazon-cloudwatch-observability.name" .}}-webhook-service.{{ .Release.Namespace }}.svc.cluster.local + issuerRef: + {{- if .Values.admissionWebhooks.certManager.issuerRef }} + {{- toYaml .Values.admissionWebhooks.certManager.issuerRef | nindent 4 }} + {{- else }} + kind: Issuer + name: {{ template "amazon-cloudwatch-observability.name" . }}-selfsigned-issuer + {{- end }} + secretName: {{ template "amazon-cloudwatch-observability.certificateSecretName" . }} + subject: + organizationalUnits: + - {{ template "amazon-cloudwatch-observability.name" . }} +{{- if not .Values.admissionWebhooks.certManager.issuerRef }} +--- +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + {{- if .Values.admissionWebhooks.certManager.issuerAnnotations }} + annotations: + {{- toYaml .Values.admissionWebhooks.certManager.issuerAnnotations | nindent 4 }} + {{- end }} + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4 }} + name: {{ template "amazon-cloudwatch-observability.name" . }}-selfsigned-issuer + namespace: {{ .Release.Namespace }} +spec: + selfSigned: { } +{{- end }} +{{- end }} + +{{- if ( .Values.agent.certManager.enabled) }} +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4 }} + name: "amazon-cloudwatch-observability-agent-cert" + namespace: {{ .Release.Namespace }} +spec: + dnsNames: + {{- range $i, $customAgent := .Values.agents }} + - {{( printf "%s-target-allocator-service" $customAgent.name )}} + {{- end }} + - "dcgm-exporter-service" + - "dcgm-exporter-service.{{ .Release.Namespace }}.svc" + - "neuron-monitor-service" + - "neuron-monitor-service.amazon-cloudwatch.svc" + - "node-exporter-service" + - "node-exporter-service.amazon-cloudwatch.svc" + issuerRef: + kind: Issuer + name: "agent-ca" + secretName: "amazon-cloudwatch-observability-agent-cert" +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4 }} + name: "amazon-cloudwatch-observability-agent-server-cert" + namespace: {{ .Release.Namespace }} +spec: + commonName: "agent-server" + dnsNames: + - "cloudwatch-agent" + - "cloudwatch-agent.{{ .Release.Namespace }}.svc" + issuerRef: + kind: Issuer + name: "agent-ca" + secretName: "amazon-cloudwatch-observability-agent-server-cert" + usages: + - digital signature + - key encipherment + - cert sign +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4 }} + name: "amazon-cloudwatch-observability-agent-client-cert" + namespace: {{ .Release.Namespace }} +spec: + commonName: "agent-client" + issuerRef: + kind: Issuer + name: "agent-ca" + secretName: "amazon-cloudwatch-observability-agent-client-cert" + usages: + - digital signature + - key encipherment + - cert sign +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4 }} + name: "amazon-cloudwatch-observability-agent-ta-client-cert" + namespace: {{ .Release.Namespace }} +spec: + commonName: "agent-ta-client" + issuerRef: + kind: Issuer + name: "agent-ca" + secretName: "amazon-cloudwatch-observability-agent-ta-client-cert" + usages: + - digital signature + - key encipherment + - cert sign +{{- if not .Values.agent.certManager.issuerRef }} +--- +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + {{- if .Values.agent.certManager.issuerAnnotations }} + annotations: + {{- toYaml .Values.agent.certManager.issuerAnnotations | nindent 4 }} + {{- end }} + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4 }} + name: "agent-ca" + namespace: {{ .Release.Namespace }} +spec: + selfSigned: { } +{{- end }} +--- +apiVersion: v1 +kind: Secret +metadata: + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4 }} + name: "amazon-cloudwatch-observability-agent-cert" + namespace: {{ .Release.Namespace }} +--- +apiVersion: v1 +kind: Secret +metadata: + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4 }} + name: "amazon-cloudwatch-observability-agent-server-cert" + namespace: {{ .Release.Namespace }} +--- +apiVersion: v1 +kind: Secret +metadata: + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4 }} + name: "amazon-cloudwatch-observability-agent-client-cert" + namespace: {{ .Release.Namespace }} +--- +apiVersion: v1 +kind: Secret +metadata: + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4 }} + name: "amazon-cloudwatch-observability-agent-ta-client-cert" + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/charts/amazon-cloudwatch-observability/templates/cloudwatch-agent-clusterrole.yaml b/charts/amazon-cloudwatch-observability/templates/cloudwatch-agent-clusterrole.yaml new file mode 100644 index 0000000..b4b80d9 --- /dev/null +++ b/charts/amazon-cloudwatch-observability/templates/cloudwatch-agent-clusterrole.yaml @@ -0,0 +1,43 @@ +{{ if .Values.agent.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4}} + name: {{ template "cloudwatch-agent.name" . }}-role +rules: +- apiGroups: [ "" ] + resources: [ "pods", "pods/logs", "nodes", "nodes/proxy", "namespaces", "endpoints" ] + verbs: [ "list", "watch", "get" ] +- apiGroups: ["discovery.k8s.io"] + resources: ["endpointslices"] + verbs: ["list", "watch", "get"] +- apiGroups: [ "" ] + resources: [ "services" ] + verbs: [ "get", "list", "watch" ] +- apiGroups: [ "apps" ] + resources: [ "replicasets", "daemonsets", "deployments", "statefulsets" ] + verbs: [ "list", "watch", "get" ] +- apiGroups: [ "batch" ] + resources: [ "jobs" ] + verbs: [ "list", "watch" ] +- apiGroups: [ "networking.k8s.io" ] + resources: [ "ingresses" ] + verbs: [ "list", "watch", "get" ] +- apiGroups: [ "" ] + resources: [ "nodes/stats", "events" ] + verbs: [ "create", "get" ] +{{- if .Values.otelContainerInsights.enabled }} +- apiGroups: [ "" ] + resources: [ "nodes/metrics" ] + verbs: [ "get" ] +{{- end }} +- apiGroups: [ "" ] + resources: [ "configmaps" ] + verbs: [ "get" ] +- apiGroups: [ "" ] + resources: [ "persistentvolumeclaims", "persistentvolumes" ] + verbs: [ "get", "list", "watch" ] +- nonResourceURLs: [ "/metrics" ] + verbs: [ "get", "list", "watch" ] +{{- end }} diff --git a/charts/amazon-cloudwatch-observability/templates/cloudwatch-agent-clusterrolebinding.yaml b/charts/amazon-cloudwatch-observability/templates/cloudwatch-agent-clusterrolebinding.yaml new file mode 100644 index 0000000..bcd290d --- /dev/null +++ b/charts/amazon-cloudwatch-observability/templates/cloudwatch-agent-clusterrolebinding.yaml @@ -0,0 +1,14 @@ +{{ if .Values.agent.enabled }} +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "cloudwatch-agent.name" . }}-role-binding +roleRef: + kind: ClusterRole + name: {{ template "cloudwatch-agent.name" . }}-role + apiGroup: rbac.authorization.k8s.io +subjects: +- kind: ServiceAccount + name: {{ template "cloudwatch-agent.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/charts/amazon-cloudwatch-observability/templates/cloudwatch-agent-role.yaml b/charts/amazon-cloudwatch-observability/templates/cloudwatch-agent-role.yaml new file mode 100644 index 0000000..e9862b0 --- /dev/null +++ b/charts/amazon-cloudwatch-observability/templates/cloudwatch-agent-role.yaml @@ -0,0 +1,16 @@ +{{- if .Values.agent.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "cloudwatch-agent.name" . }}-role + namespace: {{ .Release.Namespace }} + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4}} +rules: +- apiGroups: [""] + resources: ["configmaps"] + verbs: ["create", "update"] +- apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "list", "watch", "create", "update", "delete"] +{{- end }} diff --git a/charts/amazon-cloudwatch-observability/templates/cloudwatch-agent-rolebinding.yaml b/charts/amazon-cloudwatch-observability/templates/cloudwatch-agent-rolebinding.yaml new file mode 100644 index 0000000..118ba20 --- /dev/null +++ b/charts/amazon-cloudwatch-observability/templates/cloudwatch-agent-rolebinding.yaml @@ -0,0 +1,17 @@ +{{- if .Values.agent.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + namespace: {{ .Release.Namespace }} + name: {{ template "cloudwatch-agent.name" . }}-role-binding + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4}} +roleRef: + kind: Role + name: {{ template "cloudwatch-agent.name" . }}-role + apiGroup: rbac.authorization.k8s.io +subjects: +- kind: ServiceAccount + name: {{ template "cloudwatch-agent.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/charts/amazon-cloudwatch-observability/templates/cloudwatch-agent-serviceaccount.yaml b/charts/amazon-cloudwatch-observability/templates/cloudwatch-agent-serviceaccount.yaml new file mode 100644 index 0000000..56c4c33 --- /dev/null +++ b/charts/amazon-cloudwatch-observability/templates/cloudwatch-agent-serviceaccount.yaml @@ -0,0 +1,9 @@ +{{- if .Values.agent.enabled }} +apiVersion: v1 +kind: ServiceAccount +metadata: + annotations: + eks.amazonaws.com/role-arn: {{ .Values.roleArn }} + name: {{ template "cloudwatch-agent.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/charts/amazon-cloudwatch-observability/templates/linux/_otel-container-insights-cluster-scraper-config.tpl b/charts/amazon-cloudwatch-observability/templates/linux/_otel-container-insights-cluster-scraper-config.tpl new file mode 100644 index 0000000..e91df8d --- /dev/null +++ b/charts/amazon-cloudwatch-observability/templates/linux/_otel-container-insights-cluster-scraper-config.tpl @@ -0,0 +1,409 @@ +{{- define "otel-container-insights-cluster-scraper.config" -}} +extensions: + sigv4auth/cw_k8s_ci_v0_cwotel: + region: {{ .Values.region }} + service: monitoring + nodemetadatacache/cw_k8s_ci_v0: + namespace: {{ .Release.Namespace }} + +receivers: + prometheus/cw_k8s_ci_v0_apiserver: + config: + scrape_configs: + - job_name: kubernetes-apiserver + scrape_interval: {{ .Values.otelContainerInsights.metricResolution }} + scrape_timeout: {{ include "otel-container-insights.scrapeTimeout" . }} + scheme: https + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + insecure_skip_verify: false + bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + kubernetes_sd_configs: + - role: endpoints + namespaces: + names: + - default + relabel_configs: + - source_labels: [__meta_kubernetes_service_name] + action: keep + regex: kubernetes + - source_labels: [__meta_kubernetes_endpoint_port_name] + action: keep + regex: https + - target_label: __metrics_path__ + replacement: /metrics + +{{- if .Values.kubeStateMetrics.enabled }} + prometheus/cw_k8s_ci_v0_kube_state_metrics: + config: + scrape_configs: + - job_name: kube-state-metrics + scrape_interval: {{ .Values.otelContainerInsights.metricResolution }} + scrape_timeout: {{ include "otel-container-insights.scrapeTimeout" . }} + scheme: https + tls_config: + ca_file: /etc/amazon-cloudwatch-observability-agent-cert/tls-ca.crt + static_configs: + - targets: + - {{ include "kube-state-metrics.name" . }}.{{ .Release.Namespace }}.svc:{{ .Values.kubeStateMetrics.service.port }} +{{- end }} + +processors: + filter/cw_k8s_ci_v0_scrape_metadata: + error_mode: ignore + metrics: + metric: + - IsMatch(name, "^(up|scrape_duration_seconds|scrape_samples_scraped|scrape_samples_post_metric_relabeling|scrape_series_added)$") + + transform/cw_k8s_ci_v0_set_unit: + error_mode: ignore + metric_statements: + - context: metric + statements: + # ── Suffix-based ── + # Time + - set(unit, "s") where IsMatch(name, ".*_seconds(_total)?$") + - set(unit, "ms") where IsMatch(name, ".*_milliseconds(_total)?$") + - set(unit, "us") where IsMatch(name, ".*_microseconds(_total)?$") + - set(unit, "ns") where IsMatch(name, ".*_nanoseconds(_total)?$") + # Bytes + - set(unit, "By") where IsMatch(name, ".*_bytes(_total)?$") + - set(unit, "KBy") where IsMatch(name, ".*_kilobytes(_total)?$") + - set(unit, "MBy") where IsMatch(name, ".*_megabytes(_total)?$") + - set(unit, "GBy") where IsMatch(name, ".*_gigabytes(_total)?$") + - set(unit, "KiBy") where IsMatch(name, ".*_kibibytes(_total)?$") + - set(unit, "MiBy") where IsMatch(name, ".*_mebibytes(_total)?$") + - set(unit, "GiBy") where IsMatch(name, ".*_gibibytes(_total)?$") + # Other + - set(unit, "Cel") where IsMatch(name, ".*_celsius$") + - set(unit, "Hz") where IsMatch(name, ".*_hertz$") + - set(unit, "1") where IsMatch(name, ".*_ratio$") + - set(unit, "%") where IsMatch(name, ".*_percent$") + - set(unit, "V") where IsMatch(name, ".*_volts$") + - set(unit, "W") where IsMatch(name, ".*_watts$") + - set(unit, "J") where IsMatch(name, ".*_joules$") + - set(unit, "A") where IsMatch(name, ".*_amperes$") + - set(unit, "m") where IsMatch(name, ".*_meters(_total)?$") + # ── Counters with only _total suffix (dimensionless count) ── + - set(unit, "1") where unit == "" and IsMatch(name, ".*_total$") + + metricstarttime/cw_k8s_ci_v0: + + transform/cw_k8s_ci_v0_apiserver_extract_version: + error_mode: ignore + metric_statements: + - context: datapoint + statements: + - set(resource.attributes["k8s.apiserver.version"], attributes["git_version"]) where attributes["git_version"] != nil and attributes["git_version"] != "" + + filter/cw_k8s_ci_v0_apiserver_build_info: + error_mode: ignore + metrics: + metric: + - name == "kubernetes_build_info" + + transform/cw_k8s_ci_v0_set_scope_apiserver: + error_mode: ignore + metric_statements: + - context: scope + statements: + - set(scope.version, resource.attributes["k8s.apiserver.version"]) where resource.attributes["k8s.apiserver.version"] != nil + - set(scope.schema_url, "") + - set(attributes["cloudwatch.source"], "cloudwatch-agent") + - set(attributes["cloudwatch.solution"], "k8s-otel-container-insights") + - set(attributes["cloudwatch.pipeline"], "apiserver") + + transform/cw_k8s_ci_v0_apiserver_cleanup_version: + error_mode: ignore + metric_statements: + - context: resource + statements: + - delete_key(attributes, "k8s.apiserver.version") where attributes["k8s.apiserver.version"] != nil + +{{- if .Values.kubeStateMetrics.enabled }} + transform/cw_k8s_ci_v0_set_scope_kube_state_metrics: + error_mode: ignore + metric_statements: + - context: scope + statements: + - set(scope.name, "github.com/kubernetes/kube-state-metrics") + - set(scope.version, "{{ include "kube-state-metrics.scopeVersion" . }}") + - set(scope.schema_url, "") + - set(attributes["cloudwatch.source"], "cloudwatch-agent") + - set(attributes["cloudwatch.solution"], "k8s-otel-container-insights") + - set(attributes["cloudwatch.pipeline"], "kube-state-metrics") +{{- end }} + + transform/cw_k8s_ci_v0_set_cluster_name: + error_mode: ignore + metric_statements: + - context: datapoint + statements: + - set(resource.attributes["k8s.cluster.name"], "{{ .Values.clusterName }}") + +{{- if .Values.kubeStateMetrics.enabled }} + transform/cw_k8s_ci_v0_ksm_clean_resource: + error_mode: ignore + metric_statements: + - context: resource + statements: + # Remove scraper pod's own K8s identity so only KSM-promoted values remain. + - delete_key(attributes, "k8s.pod.name") + - delete_key(attributes, "k8s.pod.uid") + - delete_key(attributes, "k8s.namespace.name") + - delete_key(attributes, "k8s.node.name") + - delete_key(attributes, "k8s.container.name") + - delete_key(attributes, "k8s.deployment.name") + - delete_key(attributes, "k8s.replicaset.name") + - delete_key(attributes, "k8s.workload.name") + - delete_key(attributes, "k8s.workload.type") + + # Split the single Prometheus scrape resource into per-pod resources. + # groupbyattrs moves datapoint labels to resource scope, creating one resource + # per unique (pod, namespace, uid, node) combination. + groupbyattrs/cw_k8s_ci_v0_ksm: + keys: + - pod + - namespace + - uid + - node + - container + - owner_name + - owner_kind + - deployment + - daemonset + - statefulset + - replicaset + - job_name + - cronjob + + # Rename raw Prometheus label names (now in resource scope from groupbyattrs) + # to OTel semantic convention names. Raw labels stay at resource scope and are + # copied back to datapoint scope for dashboard compatibility. + transform/cw_k8s_ci_v0_ksm_promote: + error_mode: ignore + metric_statements: + - context: resource + statements: + - set(attributes["k8s.pod.name"], attributes["pod"]) where attributes["pod"] != nil + - set(attributes["k8s.namespace.name"], attributes["namespace"]) where attributes["namespace"] != nil + - set(attributes["k8s.node.name"], attributes["node"]) where attributes["node"] != nil + - set(attributes["k8s.pod.uid"], attributes["uid"]) where attributes["uid"] != nil + - set(attributes["k8s.container.name"], attributes["container"]) where attributes["container"] != nil + # Workload identity from owner references (kube_pod_owner metric) + - set(attributes["k8s.workload.name"], attributes["owner_name"]) where attributes["owner_name"] != nil + - set(attributes["k8s.workload.type"], attributes["owner_kind"]) where attributes["owner_kind"] != nil + # K8s object names from object-level metrics (deployment, daemonset, etc.) + - set(attributes["k8s.deployment.name"], attributes["deployment"]) where attributes["deployment"] != nil + - set(attributes["k8s.daemonset.name"], attributes["daemonset"]) where attributes["daemonset"] != nil + - set(attributes["k8s.statefulset.name"], attributes["statefulset"]) where attributes["statefulset"] != nil + - set(attributes["k8s.job.name"], attributes["job_name"]) where attributes["job_name"] != nil + - set(attributes["k8s.cronjob.name"], attributes["cronjob"]) where attributes["cronjob"] != nil + - set(attributes["k8s.replicaset.name"], attributes["replicaset"]) where attributes["replicaset"] != nil + - context: datapoint + statements: + # Restore raw Prometheus names to datapoint scope (groupbyattrs removed them). + - set(attributes["pod"], resource.attributes["pod"]) where resource.attributes["pod"] != nil + - set(attributes["namespace"], resource.attributes["namespace"]) where resource.attributes["namespace"] != nil + - set(attributes["node"], resource.attributes["node"]) where resource.attributes["node"] != nil + - set(attributes["uid"], resource.attributes["uid"]) where resource.attributes["uid"] != nil + - set(attributes["container"], resource.attributes["container"]) where resource.attributes["container"] != nil + - set(attributes["deployment"], resource.attributes["deployment"]) where resource.attributes["deployment"] != nil + - set(attributes["daemonset"], resource.attributes["daemonset"]) where resource.attributes["daemonset"] != nil + - set(attributes["statefulset"], resource.attributes["statefulset"]) where resource.attributes["statefulset"] != nil + - set(attributes["replicaset"], resource.attributes["replicaset"]) where resource.attributes["replicaset"] != nil + - set(attributes["job_name"], resource.attributes["job_name"]) where resource.attributes["job_name"] != nil + - set(attributes["cronjob"], resource.attributes["cronjob"]) where resource.attributes["cronjob"] != nil + - set(attributes["owner_name"], resource.attributes["owner_name"]) where resource.attributes["owner_name"] != nil + - set(attributes["owner_kind"], resource.attributes["owner_kind"]) where resource.attributes["owner_kind"] != nil + + k8sattributes/cw_k8s_ci_v0_pod: + auth_type: serviceAccount + passthrough: false + extract: + metadata: + - k8s.pod.uid + - k8s.node.name + - k8s.deployment.name + - k8s.statefulset.name + - k8s.daemonset.name + - k8s.replicaset.name + - k8s.job.name + - k8s.cronjob.name + labels: + # $$$1 is Helm escaping: $$$ → $$ (Helm) → $ (OTel env resolver) → literal $1 backreference + - tag_name: "k8s.pod.label.$$$1" + key_regex: "(.*)" + from: pod + pod_association: + - sources: + - from: resource_attribute + name: k8s.pod.name + - from: resource_attribute + name: k8s.namespace.name + + transform/cw_k8s_ci_v0_set_workload: + error_mode: ignore + metric_statements: + - context: datapoint + statements: + - set(resource.attributes["k8s.workload.name"], resource.attributes["k8s.deployment.name"]) where resource.attributes["k8s.workload.name"] == nil and resource.attributes["k8s.deployment.name"] != nil + - set(resource.attributes["k8s.workload.type"], "Deployment") where resource.attributes["k8s.workload.type"] == nil and resource.attributes["k8s.deployment.name"] != nil + - set(resource.attributes["k8s.workload.name"], resource.attributes["k8s.statefulset.name"]) where resource.attributes["k8s.workload.name"] == nil and resource.attributes["k8s.statefulset.name"] != nil + - set(resource.attributes["k8s.workload.type"], "StatefulSet") where resource.attributes["k8s.workload.type"] == nil and resource.attributes["k8s.statefulset.name"] != nil + - set(resource.attributes["k8s.workload.name"], resource.attributes["k8s.daemonset.name"]) where resource.attributes["k8s.workload.name"] == nil and resource.attributes["k8s.daemonset.name"] != nil + - set(resource.attributes["k8s.workload.type"], "DaemonSet") where resource.attributes["k8s.workload.type"] == nil and resource.attributes["k8s.daemonset.name"] != nil + - set(resource.attributes["k8s.workload.name"], resource.attributes["k8s.job.name"]) where resource.attributes["k8s.workload.name"] == nil and resource.attributes["k8s.job.name"] != nil + - set(resource.attributes["k8s.workload.type"], "Job") where resource.attributes["k8s.workload.type"] == nil and resource.attributes["k8s.job.name"] != nil + - set(resource.attributes["k8s.workload.name"], resource.attributes["k8s.cronjob.name"]) where resource.attributes["k8s.workload.name"] == nil and resource.attributes["k8s.cronjob.name"] != nil + - set(resource.attributes["k8s.workload.type"], "CronJob") where resource.attributes["k8s.workload.type"] == nil and resource.attributes["k8s.cronjob.name"] != nil + - set(resource.attributes["k8s.workload.name"], resource.attributes["k8s.replicaset.name"]) where resource.attributes["k8s.workload.name"] == nil and resource.attributes["k8s.replicaset.name"] != nil + - set(resource.attributes["k8s.workload.type"], "ReplicaSet") where resource.attributes["k8s.workload.type"] == nil and resource.attributes["k8s.replicaset.name"] != nil + + k8sattributes/cw_k8s_ci_v0_node: + auth_type: serviceAccount + passthrough: false + extract: + metadata: + - k8s.node.name + labels: + - tag_name: "k8s.node.label.$$$1" + key_regex: "(.*)" + from: node + pod_association: + - sources: + - from: resource_attribute + name: k8s.node.name +{{- end }} + + transform/cw_k8s_ci_v0_set_component: + error_mode: ignore + metric_statements: + - context: datapoint + statements: + - set(attributes["component"], "apiserver") + + transform/cw_k8s_ci_v0_promote_component: + error_mode: ignore + metric_statements: + - context: datapoint + statements: + - set(resource.attributes["k8s.component.name"], attributes["component"]) + + resourcedetection/cw_k8s_ci_v0: + detectors: [eks, ec2] + ec2: + resource_attributes: + host.id: { enabled: false } + host.type: { enabled: false } + host.name: { enabled: false } + host.image.id: { enabled: false } + cloud.provider: { enabled: true } + cloud.platform: { enabled: true } + cloud.region: { enabled: true } + cloud.availability_zone: { enabled: true } + cloud.account.id: { enabled: true } + + nodemetadataenricher/cw_k8s_ci_v0: {} + + transform/cw_k8s_ci_v0_clear_schema_url: + error_mode: ignore + metric_statements: + - context: resource + statements: + - set(resource.schema_url, "") + + awsattributelimit/cw_k8s_ci_v0: + max_total_attributes: 150 + unconditional_removal_prefixes: + - "k8s.node.label.feature.node.kubernetes.io/" + - "k8s.node.label.beta.kubernetes.io/" + - "k8s.node.label.failure-domain.beta.kubernetes.io/" + - "k8s.node.label.alpha.eksctl.io/" + unconditional_removal_keys: + - "k8s.node.label.topology.kubernetes.io/region" + - "k8s.node.label.topology.kubernetes.io/zone" + - "k8s.node.label.topology.ebs.csi.aws.com/zone" + - "k8s.node.label.node.kubernetes.io/instance-type" + - "k8s.node.label.kubernetes.io/hostname" + - "k8s.node.label.helm.sh/chart" + - "k8s.node.label.release" + - "k8s.node.label.eks.amazonaws.com/nodegroup-image" + - "k8s.node.label.k8s.io/cloud-provider-aws" + - "k8s.node.label.eks.amazonaws.com/sourceLaunchTemplateId" + - "k8s.node.label.eks.amazonaws.com/sourceLaunchTemplateVersion" + - "k8s.pod.label.pod-template-hash" + - "k8s.pod.label.controller-revision-hash" + + transform/cw_k8s_ci_v0_set_cloud_resource_id: + error_mode: ignore + metric_statements: + - context: resource + statements: + - set(resource.attributes["cloud.resource_id"], Concat(["arn:aws:eks:", resource.attributes["cloud.region"], ":", resource.attributes["cloud.account.id"], ":cluster/", resource.attributes["k8s.cluster.name"]], "")) + where resource.attributes["cloud.region"] != nil and resource.attributes["cloud.account.id"] != nil and resource.attributes["k8s.cluster.name"] != nil + + batch/cw_k8s_ci_v0_cwotel: + send_batch_size: 500 + send_batch_max_size: 500 + timeout: 10s + +exporters: + otlphttp/cw_k8s_ci_v0_cwotel: + endpoint: {{ if .Values.otelContainerInsights.cloudwatchMetricsEndpoint }}{{ .Values.otelContainerInsights.cloudwatchMetricsEndpoint | quote }}{{ else }}"https://monitoring.{{ .Values.region }}.amazonaws.com:443"{{ end }} + tls: + insecure: false + auth: + authenticator: sigv4auth/cw_k8s_ci_v0_cwotel + +service: + extensions: + - sigv4auth/cw_k8s_ci_v0_cwotel + - nodemetadatacache/cw_k8s_ci_v0 + pipelines: + metrics/cw_k8s_ci_v0_apiserver: + receivers: [prometheus/cw_k8s_ci_v0_apiserver] + processors: + - filter/cw_k8s_ci_v0_scrape_metadata + - transform/cw_k8s_ci_v0_set_unit + - metricstarttime/cw_k8s_ci_v0 + - transform/cw_k8s_ci_v0_apiserver_extract_version + - filter/cw_k8s_ci_v0_apiserver_build_info + - transform/cw_k8s_ci_v0_set_scope_apiserver + - transform/cw_k8s_ci_v0_apiserver_cleanup_version + - transform/cw_k8s_ci_v0_set_cluster_name + - transform/cw_k8s_ci_v0_set_component + - transform/cw_k8s_ci_v0_promote_component + - resourcedetection/cw_k8s_ci_v0 + - transform/cw_k8s_ci_v0_clear_schema_url + - transform/cw_k8s_ci_v0_set_cloud_resource_id + - awsattributelimit/cw_k8s_ci_v0 + - batch/cw_k8s_ci_v0_cwotel + exporters: + - otlphttp/cw_k8s_ci_v0_cwotel +{{- if .Values.kubeStateMetrics.enabled }} + metrics/cw_k8s_ci_v0_kube_state_metrics: + receivers: [prometheus/cw_k8s_ci_v0_kube_state_metrics] + processors: + - filter/cw_k8s_ci_v0_scrape_metadata + - transform/cw_k8s_ci_v0_set_unit + - metricstarttime/cw_k8s_ci_v0 + - transform/cw_k8s_ci_v0_set_scope_kube_state_metrics + - transform/cw_k8s_ci_v0_set_cluster_name + - transform/cw_k8s_ci_v0_ksm_clean_resource + - groupbyattrs/cw_k8s_ci_v0_ksm + - transform/cw_k8s_ci_v0_ksm_promote + - k8sattributes/cw_k8s_ci_v0_pod + - k8sattributes/cw_k8s_ci_v0_node + - transform/cw_k8s_ci_v0_set_workload + - resourcedetection/cw_k8s_ci_v0 + - nodemetadataenricher/cw_k8s_ci_v0 + - transform/cw_k8s_ci_v0_clear_schema_url + - transform/cw_k8s_ci_v0_set_cloud_resource_id + - awsattributelimit/cw_k8s_ci_v0 + - batch/cw_k8s_ci_v0_cwotel + exporters: + - otlphttp/cw_k8s_ci_v0_cwotel +{{- end }} +{{- end -}} + diff --git a/charts/amazon-cloudwatch-observability/templates/linux/_otel-container-insights-config.tpl b/charts/amazon-cloudwatch-observability/templates/linux/_otel-container-insights-config.tpl new file mode 100644 index 0000000..3d9a295 --- /dev/null +++ b/charts/amazon-cloudwatch-observability/templates/linux/_otel-container-insights-config.tpl @@ -0,0 +1,988 @@ +{{- define "otel-container-insights.config" -}} +extensions: + sigv4auth/cw_k8s_ci_v0_metrics_dest: + region: {{ .Values.region }} + service: monitoring +{{- if .Values.otelContainerInsights.logs.enabled }} + sigv4auth/cw_k8s_ci_v0_logs_dest: + region: {{ .Values.region }} + service: logs + awscloudwatchlogsprovisioner/cw_k8s_ci_v0_logs: + region: {{ .Values.region }} + additional_auth: sigv4auth/cw_k8s_ci_v0_logs_dest +{{- end }} + +receivers: +{{- if .Values.nodeExporter.enabled }} + prometheus/cw_k8s_ci_v0_node_exporter: + config: + scrape_configs: + - job_name: node-exporter + scrape_interval: {{ .Values.otelContainerInsights.metricResolution }} + scrape_timeout: {{ include "otel-container-insights.scrapeTimeout" . }} + scheme: https + tls_config: + ca_file: /etc/amazon-cloudwatch-observability-agent-client-cert/tls-ca.crt + static_configs: + - targets: + - {{ include "node-exporter.name" . }}-service:9487 +{{- end }} + + prometheus/cw_k8s_ci_v0_cadvisor: + config: + scrape_configs: + - job_name: cadvisor + scrape_interval: {{ .Values.otelContainerInsights.metricResolution }} + scrape_timeout: {{ include "otel-container-insights.scrapeTimeout" . }} + scheme: https + tls_config: + insecure_skip_verify: true + bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + metrics_path: /metrics/cadvisor + static_configs: + - targets: + - ${env:HOST_IP}:10250 + + {{- if .Values.dcgmExporter.enabled }} + prometheus/cw_k8s_ci_v0_dcgm: + config: + scrape_configs: + - job_name: dcgm-exporter + scrape_interval: {{ .Values.otelContainerInsights.metricResolution }} + scrape_timeout: {{ include "otel-container-insights.scrapeTimeout" . }} + scheme: https + tls_config: + ca_file: /etc/amazon-cloudwatch-observability-agent-client-cert/tls-ca.crt + static_configs: + - targets: + - dcgm-exporter-service:9400 + {{- end }} + + {{- if .Values.neuronMonitor.enabled }} + prometheus/cw_k8s_ci_v0_neuron: + config: + scrape_configs: + - job_name: neuron-monitor + scrape_interval: {{ .Values.otelContainerInsights.metricResolution }} + scrape_timeout: {{ include "otel-container-insights.scrapeTimeout" . }} + scheme: https + tls_config: + ca_file: /etc/amazon-cloudwatch-observability-agent-client-cert/tls-ca.crt + static_configs: + - targets: + - neuron-monitor-service:8000 + {{- end }} + + awsefareceiver/cw_k8s_ci_v0: + collection_interval: {{ .Values.otelContainerInsights.metricResolution }} + + prometheus/cw_k8s_ci_v0_ebs_csi_node: + config: + scrape_configs: + - job_name: ebs-csi-node + scrape_interval: {{ .Values.otelContainerInsights.metricResolution }} + scrape_timeout: {{ include "otel-container-insights.scrapeTimeout" . }} + kubernetes_sd_configs: + - role: pod + namespaces: + names: + - kube-system + relabel_configs: + - source_labels: [__meta_kubernetes_pod_label_app] + regex: ebs-csi-node + action: keep + - source_labels: [__meta_kubernetes_pod_node_name] + regex: ${env:K8S_NODE_NAME} + action: keep + - source_labels: [__meta_kubernetes_pod_container_port_name] + regex: metrics + action: keep + + prometheus/cw_k8s_ci_v0_lis_csi_node: + config: + scrape_configs: + - job_name: lis-csi-node + scrape_interval: {{ .Values.otelContainerInsights.metricResolution }} + scrape_timeout: {{ include "otel-container-insights.scrapeTimeout" . }} + kubernetes_sd_configs: + - role: pod + namespaces: + names: + - kube-system + relabel_configs: + - source_labels: [__meta_kubernetes_pod_label_app] + regex: ec2-instance-store-plugin + action: keep + - source_labels: [__meta_kubernetes_pod_node_name] + regex: ${env:K8S_NODE_NAME} + action: keep + - source_labels: [__meta_kubernetes_pod_container_port_name] + regex: metrics + action: keep + + kubeletstats/cw_k8s_ci_v0: + auth_type: serviceAccount + collection_interval: {{ .Values.otelContainerInsights.metricResolution }} + endpoint: "https://${env:HOST_IP}:10250" + insecure_skip_verify: true + metric_groups: + - pod + - container + - node + metrics: + k8s.pod.cpu_limit_utilization: + enabled: true + k8s.pod.cpu_request_utilization: + enabled: true + k8s.pod.memory_limit_utilization: + enabled: true + k8s.pod.memory_request_utilization: + enabled: true + k8s.container.cpu_limit_utilization: + enabled: true + k8s.container.cpu_request_utilization: + enabled: true + k8s.container.memory_limit_utilization: + enabled: true + k8s.container.memory_request_utilization: + enabled: true + k8s.pod.cpu.usage: + enabled: true + container.cpu.usage: + enabled: true + k8s.node.cpu.usage: + enabled: true + k8s.pod.uptime: + enabled: true + container.uptime: + enabled: true + k8s.node.uptime: + enabled: true + +{{- if .Values.otelContainerInsights.logs.enabled }} + # ── CI Logs receivers ── + filelog/cw_k8s_ci_v0_app: + include: + - /var/log/containers/*.log + exclude: + - /var/log/containers/cloudwatch-agent* + - /var/log/containers/fluent-bit* + # aws-node and kube-proxy are dataplane components — excluded to match + # FluentBit's existing Exclude_Path behavior. + - /var/log/containers/aws-node* + - /var/log/containers/kube-proxy* + # No checkpoint persistence — logs during agent downtime are lost. + # Filestorage support is tracked in a follow-up PR. + start_at: end + include_file_path: true + include_file_name: false + max_concurrent_files: 100 + operators: + - type: regex_parser + id: extract_metadata_from_filepath + regex: '^.*\/(?P[^_]+)_(?P[^_]+)_(?P.+)-[a-f0-9]{64}\.log$' + parse_from: attributes["log.file.path"] + parse_to: resource + - type: move + from: resource.pod + to: resource["k8s.pod.name"] + - type: move + from: resource.namespace + to: resource["k8s.namespace.name"] + - type: move + from: resource.container + to: resource["k8s.container.name"] + - id: parse_container_log + type: container_log_parser + + filelog/cw_k8s_ci_v0_node: + include: + - /var/log/messages + - /var/log/dmesg + - /var/log/secure + # No checkpoint persistence — logs during agent downtime are lost. + # Filestorage support is tracked in a follow-up PR. + start_at: end + include_file_path: true + include_file_name: false + max_concurrent_files: 100 + +{{- end }} + +processors: + filter/cw_k8s_ci_v0_scrape_metadata: + error_mode: ignore + metrics: + metric: + - IsMatch(name, "^(up|scrape_duration_seconds|scrape_samples_scraped|scrape_samples_post_metric_relabeling|scrape_series_added)$") + + transform/cw_k8s_ci_v0_set_unit: + error_mode: ignore + metric_statements: + - context: metric + statements: + # Time + - set(unit, "s") where IsMatch(name, ".*_seconds(_total)?$") + - set(unit, "ms") where IsMatch(name, ".*_milliseconds(_total)?$") + - set(unit, "us") where IsMatch(name, ".*_microseconds(_total)?$") + - set(unit, "ns") where IsMatch(name, ".*_nanoseconds(_total)?$") + # Bytes + - set(unit, "By") where IsMatch(name, ".*_bytes(_total)?$") + - set(unit, "KBy") where IsMatch(name, ".*_kilobytes(_total)?$") + - set(unit, "MBy") where IsMatch(name, ".*_megabytes(_total)?$") + - set(unit, "GBy") where IsMatch(name, ".*_gigabytes(_total)?$") + - set(unit, "KiBy") where IsMatch(name, ".*_kibibytes(_total)?$") + - set(unit, "MiBy") where IsMatch(name, ".*_mebibytes(_total)?$") + - set(unit, "GiBy") where IsMatch(name, ".*_gibibytes(_total)?$") + # Other + - set(unit, "Cel") where IsMatch(name, ".*_celsius$") + - set(unit, "Hz") where IsMatch(name, ".*_hertz$") + - set(unit, "1") where IsMatch(name, ".*_ratio$") + - set(unit, "%") where IsMatch(name, ".*_percent$") + - set(unit, "V") where IsMatch(name, ".*_volts$") + - set(unit, "W") where IsMatch(name, ".*_watts$") + - set(unit, "J") where IsMatch(name, ".*_joules$") + - set(unit, "A") where IsMatch(name, ".*_amperes$") + - set(unit, "m") where IsMatch(name, ".*_meters(_total)?$") + # Counters with only _total suffix (dimensionless count) + - set(unit, "1") where unit == "" and IsMatch(name, ".*_total$") + # DCGM explicit mappings (no suffix convention) + - set(unit, "%") where name == "DCGM_FI_DEV_GPU_UTIL" + - set(unit, "%") where name == "DCGM_FI_DEV_MEM_COPY_UTIL" + - set(unit, "%") where name == "DCGM_FI_PROF_PIPE_TENSOR_ACTIVE" + - set(unit, "MiBy") where name == "DCGM_FI_DEV_FB_USED" + - set(unit, "MiBy") where name == "DCGM_FI_DEV_FB_FREE" + - set(unit, "MiBy") where name == "DCGM_FI_DEV_FB_TOTAL" + - set(unit, "Cel") where name == "DCGM_FI_DEV_GPU_TEMP" + - set(unit, "W") where name == "DCGM_FI_DEV_POWER_USAGE" + - set(unit, "MHz") where name == "DCGM_FI_DEV_SM_CLOCK" + # Neuron explicit mappings + - set(unit, "By") where IsMatch(name, "^neuroncore_memory_usage_.*") + + transform/cw_k8s_ci_v0_set_cluster_name: + error_mode: ignore + metric_statements: + - context: datapoint + statements: + - set(resource.attributes["k8s.cluster.name"], "{{ .Values.clusterName }}") + +{{- if .Values.nodeExporter.enabled }} + transform/cw_k8s_ci_v0_set_scope_node_exporter: + error_mode: ignore + metric_statements: + - context: scope + statements: + - set(scope.name, "github.com/prometheus/node_exporter") + - set(scope.version, "{{ include "node-exporter.scopeVersion" . }}") + - set(scope.schema_url, "") + - set(attributes["cloudwatch.source"], "cloudwatch-agent") + - set(attributes["cloudwatch.solution"], "k8s-otel-container-insights") + - set(attributes["cloudwatch.pipeline"], "node-exporter") +{{- end }} + + transform/cw_k8s_ci_v0_set_scope_cadvisor: + error_mode: ignore + metric_statements: + - context: scope + statements: + - set(scope.name, "github.com/google/cadvisor") + - set(scope.schema_url, "") + - set(attributes["cloudwatch.source"], "cloudwatch-agent") + - set(attributes["cloudwatch.solution"], "k8s-otel-container-insights") + - set(attributes["cloudwatch.pipeline"], "cadvisor") + + {{- if .Values.dcgmExporter.enabled }} + transform/cw_k8s_ci_v0_set_scope_dcgm: + error_mode: ignore + metric_statements: + - context: scope + statements: + - set(scope.name, "github.com/NVIDIA/dcgm-exporter") + - set(scope.version, "{{ .Values.dcgmExporter.image.tag }}") + - set(scope.schema_url, "") + - set(attributes["cloudwatch.source"], "cloudwatch-agent") + - set(attributes["cloudwatch.solution"], "k8s-otel-container-insights") + - set(attributes["cloudwatch.pipeline"], "dcgm") + {{- end }} + + {{- if .Values.neuronMonitor.enabled }} + transform/cw_k8s_ci_v0_set_scope_neuron_monitor: + error_mode: ignore + metric_statements: + - context: scope + statements: + - set(scope.name, "awsneuron") + - set(scope.version, "{{ .Values.neuronMonitor.image.tag }}") + - set(scope.schema_url, "") + - set(attributes["cloudwatch.source"], "cloudwatch-agent") + - set(attributes["cloudwatch.solution"], "k8s-otel-container-insights") + - set(attributes["cloudwatch.pipeline"], "neuron-monitor") + {{- end }} + + transform/cw_k8s_ci_v0_set_scope_efa: + error_mode: ignore + metric_statements: + - context: scope + statements: + - set(scope.schema_url, "") + - set(attributes["cloudwatch.source"], "cloudwatch-agent") + - set(attributes["cloudwatch.solution"], "k8s-otel-container-insights") + - set(attributes["cloudwatch.pipeline"], "efa") + + transform/cw_k8s_ci_v0_set_scope_ebs_csi: + error_mode: ignore + metric_statements: + - context: scope + statements: + - set(scope.schema_url, "") + - set(attributes["cloudwatch.source"], "cloudwatch-agent") + - set(attributes["cloudwatch.solution"], "k8s-otel-container-insights") + - set(attributes["cloudwatch.pipeline"], "ebs-csi") + + transform/cw_k8s_ci_v0_set_scope_lis_csi: + error_mode: ignore + metric_statements: + - context: scope + statements: + - set(scope.schema_url, "") + - set(attributes["cloudwatch.source"], "cloudwatch-agent") + - set(attributes["cloudwatch.solution"], "k8s-otel-container-insights") + - set(attributes["cloudwatch.pipeline"], "lis-csi") + + transform/cw_k8s_ci_v0_set_scope_kubeletstats: + error_mode: ignore + metric_statements: + - context: scope + statements: + - set(scope.schema_url, "") + - set(attributes["cloudwatch.source"], "cloudwatch-agent") + - set(attributes["cloudwatch.solution"], "k8s-otel-container-insights") + - set(attributes["cloudwatch.pipeline"], "kubeletstats") + + transform/cw_k8s_ci_v0_set_node_name: + error_mode: ignore + metric_statements: + - context: datapoint + statements: + - set(attributes["node_name"], "${env:K8S_NODE_NAME}") + + transform/cw_k8s_ci_v0_promote_node_name: + error_mode: ignore + metric_statements: + - context: datapoint + statements: + - set(resource.attributes["k8s.node.name"], attributes["node_name"]) where attributes["node_name"] != nil + + resourcedetection/cw_k8s_ci_v0: + detectors: [eks, ec2] + ec2: + resource_attributes: + host.id: { enabled: true } + host.type: { enabled: true } + host.name: { enabled: true } + host.image.id: { enabled: true } + cloud.provider: { enabled: true } + cloud.platform: { enabled: true } + cloud.region: { enabled: true } + cloud.availability_zone: { enabled: true } + cloud.account.id: { enabled: true } + + transform/cw_k8s_ci_v0_clear_schema_url: + error_mode: ignore + metric_statements: + - context: resource + statements: + - set(resource.schema_url, "") + + k8sattributes/cw_k8s_ci_v0_node: + auth_type: serviceAccount + passthrough: false + filter: + node_from_env_var: K8S_NODE_NAME + extract: + metadata: + - k8s.node.name + labels: + - tag_name: "k8s.node.label.$$$1" + key_regex: "(.*)" + from: node + pod_association: + - sources: + - from: resource_attribute + name: k8s.node.name + + k8sattributes/cw_k8s_ci_v0_pod: + auth_type: serviceAccount + passthrough: false + filter: + node_from_env_var: K8S_NODE_NAME + extract: + metadata: + - k8s.pod.uid + - k8s.node.name + - k8s.deployment.name + - k8s.statefulset.name + - k8s.daemonset.name + - k8s.replicaset.name + - k8s.job.name + - k8s.cronjob.name + labels: + - tag_name: "k8s.pod.label.$$$1" + key_regex: "(.*)" + from: pod + pod_association: + - sources: + - from: resource_attribute + name: k8s.pod.name + - from: resource_attribute + name: k8s.namespace.name + + awsattributelimit/cw_k8s_ci_v0: + max_total_attributes: 150 + unconditional_removal_prefixes: + - "k8s.node.label.feature.node.kubernetes.io/" + - "k8s.node.label.beta.kubernetes.io/" + - "k8s.node.label.failure-domain.beta.kubernetes.io/" + - "k8s.node.label.alpha.eksctl.io/" + unconditional_removal_keys: + - "k8s.node.label.topology.kubernetes.io/region" + - "k8s.node.label.topology.kubernetes.io/zone" + - "k8s.node.label.topology.ebs.csi.aws.com/zone" + - "k8s.node.label.node.kubernetes.io/instance-type" + - "k8s.node.label.kubernetes.io/hostname" + - "k8s.node.label.helm.sh/chart" + - "k8s.node.label.release" + - "k8s.node.label.eks.amazonaws.com/nodegroup-image" + - "k8s.node.label.k8s.io/cloud-provider-aws" + - "k8s.node.label.eks.amazonaws.com/sourceLaunchTemplateId" + - "k8s.node.label.eks.amazonaws.com/sourceLaunchTemplateVersion" + - "k8s.pod.label.pod-template-hash" + - "k8s.pod.label.controller-revision-hash" + + transform/cw_k8s_ci_v0_set_cloud_resource_id: + error_mode: ignore + metric_statements: + - context: resource + statements: + - set(resource.attributes["cloud.resource_id"], Concat(["arn:aws:eks:", resource.attributes["cloud.region"], ":", resource.attributes["cloud.account.id"], ":cluster/", resource.attributes["k8s.cluster.name"]], "")) + where resource.attributes["cloud.region"] != nil and resource.attributes["cloud.account.id"] != nil and resource.attributes["k8s.cluster.name"] != nil + + metricstarttime/cw_k8s_ci_v0: + + transform/cw_k8s_ci_v0_set_workload: + error_mode: ignore + metric_statements: + - context: datapoint + statements: + - set(resource.attributes["k8s.workload.name"], resource.attributes["k8s.deployment.name"]) where resource.attributes["k8s.deployment.name"] != nil + - set(resource.attributes["k8s.workload.type"], "Deployment") where resource.attributes["k8s.deployment.name"] != nil + - set(resource.attributes["k8s.workload.name"], resource.attributes["k8s.statefulset.name"]) where resource.attributes["k8s.workload.name"] == nil and resource.attributes["k8s.statefulset.name"] != nil + - set(resource.attributes["k8s.workload.type"], "StatefulSet") where resource.attributes["k8s.statefulset.name"] != nil and resource.attributes["k8s.workload.type"] == nil + - set(resource.attributes["k8s.workload.name"], resource.attributes["k8s.daemonset.name"]) where resource.attributes["k8s.workload.name"] == nil and resource.attributes["k8s.daemonset.name"] != nil + - set(resource.attributes["k8s.workload.type"], "DaemonSet") where resource.attributes["k8s.daemonset.name"] != nil and resource.attributes["k8s.workload.type"] == nil + - set(resource.attributes["k8s.workload.name"], resource.attributes["k8s.job.name"]) where resource.attributes["k8s.workload.name"] == nil and resource.attributes["k8s.job.name"] != nil + - set(resource.attributes["k8s.workload.type"], "Job") where resource.attributes["k8s.job.name"] != nil and resource.attributes["k8s.workload.type"] == nil + - set(resource.attributes["k8s.workload.name"], resource.attributes["k8s.cronjob.name"]) where resource.attributes["k8s.workload.name"] == nil and resource.attributes["k8s.cronjob.name"] != nil + - set(resource.attributes["k8s.workload.type"], "CronJob") where resource.attributes["k8s.cronjob.name"] != nil and resource.attributes["k8s.workload.type"] == nil + - set(resource.attributes["k8s.workload.name"], resource.attributes["k8s.replicaset.name"]) where resource.attributes["k8s.workload.name"] == nil and resource.attributes["k8s.replicaset.name"] != nil + - set(resource.attributes["k8s.workload.type"], "ReplicaSet") where resource.attributes["k8s.replicaset.name"] != nil and resource.attributes["k8s.workload.type"] == nil + + batch/cw_k8s_ci_v0_metrics_dest: + send_batch_size: 500 + send_batch_max_size: 500 + timeout: 10s + + filter/cw_k8s_ci_v0_cadvisor_empty: + error_mode: ignore + metrics: + datapoint: + - attributes["container"] == "" and attributes["pod"] == "" + - attributes["container"] == "" and attributes["pod"] == nil + - attributes["container"] == nil and attributes["pod"] == "" + - attributes["container"] == nil and attributes["pod"] == nil + + filter/cw_k8s_ci_v0_cadvisor_pod: + error_mode: ignore + metrics: + datapoint: + - attributes["container"] == "POD" + + groupbyattrs/cw_k8s_ci_v0_cadvisor: + keys: + - container + - pod + - namespace + + transform/cw_k8s_ci_v0_cadvisor_promote: + error_mode: ignore + metric_statements: + - context: resource + statements: + - set(attributes["k8s.container.name"], attributes["container"]) where attributes["container"] != nil and attributes["container"] != "" + - set(attributes["k8s.pod.name"], attributes["pod"]) where attributes["pod"] != nil + - set(attributes["k8s.namespace.name"], attributes["namespace"]) where attributes["namespace"] != nil + - context: datapoint + statements: + # Restore raw Prometheus names to datapoint scope (groupbyattrs removed them). + - set(attributes["container"], resource.attributes["container"]) where resource.attributes["container"] != nil + - set(attributes["pod"], resource.attributes["pod"]) where resource.attributes["pod"] != nil + - set(attributes["namespace"], resource.attributes["namespace"]) where resource.attributes["namespace"] != nil + + {{- if .Values.dcgmExporter.enabled }} + groupbyattrs/cw_k8s_ci_v0_dcgm: + keys: + - pod + - namespace + - container + + transform/cw_k8s_ci_v0_dcgm_promote: + error_mode: ignore + metric_statements: + - context: resource + statements: + - set(attributes["k8s.pod.name"], attributes["pod"]) where attributes["pod"] != nil + - set(attributes["k8s.namespace.name"], attributes["namespace"]) where attributes["namespace"] != nil + - set(attributes["k8s.container.name"], attributes["container"]) where attributes["container"] != nil + - context: datapoint + statements: + # Restore raw Prometheus names to datapoint scope (groupbyattrs removed them). + # Raw labels are still at resource scope (not deleted), so copy them back down. + - set(attributes["pod"], resource.attributes["pod"]) where resource.attributes["pod"] != nil + - set(attributes["namespace"], resource.attributes["namespace"]) where resource.attributes["namespace"] != nil + - set(attributes["container"], resource.attributes["container"]) where resource.attributes["container"] != nil + # Clean up leftover datapoint attributes not needed downstream. + - delete_key(attributes, "Hostname") where attributes["Hostname"] != nil + - delete_key(attributes, "pci_bus_id") where attributes["pci_bus_id"] != nil + {{- end }} + + {{- if .Values.neuronMonitor.enabled }} + filter/cw_k8s_ci_v0_neuron: + error_mode: ignore + metrics: + metric: + - IsMatch(name, "^(neuron|execution_|hardware_ecc_)") != true + + awsneuron/cw_k8s_ci_v0: + + groupbyattrs/cw_k8s_ci_v0_neuron: + keys: + - k8s.pod.name + - k8s.namespace.name + - k8s.container.name + + transform/cw_k8s_ci_v0_neuron_promote: + error_mode: ignore + metric_statements: + - context: datapoint + statements: + - set(resource.attributes["k8s.pod.name"], attributes["k8s.pod.name"]) where attributes["k8s.pod.name"] != nil + - set(resource.attributes["k8s.namespace.name"], attributes["k8s.namespace.name"]) where attributes["k8s.namespace.name"] != nil + - set(resource.attributes["k8s.container.name"], attributes["k8s.container.name"]) where attributes["k8s.container.name"] != nil + - set(resource.attributes["aws.neuron.runtime.tag"], attributes["runtime_tag"]) where attributes["runtime_tag"] != nil + - delete_key(attributes, "k8s.pod.name") where attributes["k8s.pod.name"] != nil + - delete_key(attributes, "k8s.namespace.name") where attributes["k8s.namespace.name"] != nil + - delete_key(attributes, "k8s.container.name") where attributes["k8s.container.name"] != nil + - delete_key(attributes, "runtime_tag") where attributes["runtime_tag"] != nil + + transform/cw_k8s_ci_v0_neuron_hw_attrs: + error_mode: ignore + metric_statements: + - context: datapoint + statements: + - set(attributes["aws.neuron.device"], attributes["neurondevice"]) where attributes["neurondevice"] != nil + - set(attributes["aws.neuron.core"], attributes["neuroncore"]) where attributes["neuroncore"] != nil + - delete_key(attributes, "neuroncore") where attributes["neuroncore"] != nil + - delete_key(attributes, "neurondevice") where attributes["neurondevice"] != nil + - delete_key(attributes, "instance_type") where attributes["instance_type"] != nil + {{- end }} + + awsdevicepodcorrelation/cw_k8s_ci_v0: + device_types: + - name: neuron-by-core + device_id_attribute: neuroncore + resource_names: + - aws.amazon.com/neuroncore + - name: neuron-by-device + device_id_attribute: neurondevice + resource_names: + - aws.amazon.com/neurondevice + - aws.amazon.com/neuron + - name: efa + device_id_attribute: aws.efa.device + resource_names: + - vpc.amazonaws.com/efa + + transform/cw_k8s_ci_v0_efa_promote: + error_mode: ignore + metric_statements: + - context: datapoint + statements: + - set(resource.attributes["k8s.pod.name"], attributes["k8s.pod.name"]) where attributes["k8s.pod.name"] != nil + - set(resource.attributes["k8s.namespace.name"], attributes["k8s.namespace.name"]) where attributes["k8s.namespace.name"] != nil + - set(resource.attributes["k8s.container.name"], attributes["k8s.container.name"]) where attributes["k8s.container.name"] != nil + - delete_key(attributes, "k8s.pod.name") where attributes["k8s.pod.name"] != nil + - delete_key(attributes, "k8s.namespace.name") where attributes["k8s.namespace.name"] != nil + - delete_key(attributes, "k8s.container.name") where attributes["k8s.container.name"] != nil + + transform/cw_k8s_ci_v0_ebs_csi_promote: + error_mode: ignore + metric_statements: + - context: datapoint + statements: + - set(resource.attributes["instance_id"], attributes["instance_id"]) where attributes["instance_id"] != nil + - set(resource.attributes["volume_id"], attributes["volume_id"]) where attributes["volume_id"] != nil + - delete_key(attributes, "instance_id") where attributes["instance_id"] != nil + - delete_key(attributes, "volume_id") where attributes["volume_id"] != nil + + transform/cw_k8s_ci_v0_lis_csi_promote: + error_mode: ignore + metric_statements: + - context: datapoint + statements: + - set(resource.attributes["instance_id"], attributes["instance_id"]) where attributes["instance_id"] != nil + - set(resource.attributes["volume_id"], attributes["volume_id"]) where attributes["volume_id"] != nil + - delete_key(attributes, "instance_id") where attributes["instance_id"] != nil + - delete_key(attributes, "volume_id") where attributes["volume_id"] != nil + +{{- if .Values.otelContainerInsights.logs.enabled }} + # ── CI Logs processors ── + transform/cw_k8s_ci_v0_logs_set_workload: + error_mode: ignore + log_statements: + - context: resource + statements: + # Derive k8s.workload.name and k8s.workload.type — matches metrics' + # transform/cw_k8s_ci_v0_set_workload exactly so metrics and logs use + # the same workload identity for the same pod. + - set(attributes["k8s.workload.name"], attributes["k8s.deployment.name"]) where attributes["k8s.deployment.name"] != nil + - set(attributes["k8s.workload.type"], "Deployment") where attributes["k8s.deployment.name"] != nil + - set(attributes["k8s.workload.name"], attributes["k8s.statefulset.name"]) where attributes["k8s.workload.name"] == nil and attributes["k8s.statefulset.name"] != nil + - set(attributes["k8s.workload.type"], "StatefulSet") where attributes["k8s.statefulset.name"] != nil and attributes["k8s.workload.type"] == nil + - set(attributes["k8s.workload.name"], attributes["k8s.daemonset.name"]) where attributes["k8s.workload.name"] == nil and attributes["k8s.daemonset.name"] != nil + - set(attributes["k8s.workload.type"], "DaemonSet") where attributes["k8s.daemonset.name"] != nil and attributes["k8s.workload.type"] == nil + - set(attributes["k8s.workload.name"], attributes["k8s.job.name"]) where attributes["k8s.workload.name"] == nil and attributes["k8s.job.name"] != nil + - set(attributes["k8s.workload.type"], "Job") where attributes["k8s.job.name"] != nil and attributes["k8s.workload.type"] == nil + - set(attributes["k8s.workload.name"], attributes["k8s.cronjob.name"]) where attributes["k8s.workload.name"] == nil and attributes["k8s.cronjob.name"] != nil + - set(attributes["k8s.workload.type"], "CronJob") where attributes["k8s.cronjob.name"] != nil and attributes["k8s.workload.type"] == nil + - set(attributes["k8s.workload.name"], attributes["k8s.replicaset.name"]) where attributes["k8s.workload.name"] == nil and attributes["k8s.replicaset.name"] != nil + - set(attributes["k8s.workload.type"], "ReplicaSet") where attributes["k8s.replicaset.name"] != nil and attributes["k8s.workload.type"] == nil + # Derive service.name from k8s.workload.name (OTEL logs semconv). + # Logs need service.name; metrics use k8s.workload.name directly. + - set(attributes["service.name"], attributes["k8s.workload.name"]) where attributes["service.name"] == nil and attributes["k8s.workload.name"] != nil + + transform/cw_k8s_ci_v0_logs_set_cluster_and_node: + error_mode: ignore + log_statements: + - context: resource + statements: + - set(attributes["k8s.cluster.name"], "{{ .Values.clusterName }}") + - set(attributes["k8s.node.name"], "${env:K8S_NODE_NAME}") + + transform/cw_k8s_ci_v0_logs_set_cloud_resource_id: + error_mode: ignore + log_statements: + - context: resource + statements: + - set(attributes["cloud.resource_id"], Concat(["arn:aws:eks:", attributes["cloud.region"], ":", attributes["cloud.account.id"], ":cluster/", attributes["k8s.cluster.name"]], "")) + where attributes["cloud.region"] != nil and attributes["cloud.account.id"] != nil and attributes["k8s.cluster.name"] != nil + + transform/cw_k8s_ci_v0_logs_clear_schema_url: + error_mode: ignore + log_statements: + - context: resource + statements: + - set(resource.schema_url, "") + + # Scope transforms — tag each logs pipeline with cloudwatch.source/solution/pipeline + # for backend attribution. Matches the metrics pipeline's transform/set_scope_* + # processors so logs are attributed identically to metrics. + # scope.name is intentionally not set — the metrics pipeline sets it only for + # pipelines with a well-known source library (e.g., github.com/google/cadvisor). + # filelog receivers don't have an equivalent upstream library, so scope.name is + # omitted (matches metrics' set_scope_efa / set_scope_ebs_csi / + # set_scope_kubeletstats which also omit scope.name). + transform/cw_k8s_ci_v0_logs_set_scope_app: + error_mode: ignore + log_statements: + - context: scope + statements: + - set(scope.schema_url, "") + - set(attributes["cloudwatch.source"], "cloudwatch-agent") + - set(attributes["cloudwatch.solution"], "k8s-otel-container-insights") + - set(attributes["cloudwatch.pipeline"], "application-logs") + + transform/cw_k8s_ci_v0_logs_set_scope_host: + error_mode: ignore + log_statements: + - context: scope + statements: + - set(scope.schema_url, "") + - set(attributes["cloudwatch.source"], "cloudwatch-agent") + - set(attributes["cloudwatch.solution"], "k8s-otel-container-insights") + - set(attributes["cloudwatch.pipeline"], "host-logs") + + batch/cw_k8s_ci_v0_logs_dest: + send_batch_size: 500 + send_batch_max_size: 500 + timeout: 5s +{{- end }} + +exporters: + otlphttp/cw_k8s_ci_v0_metrics_dest: + endpoint: {{ if .Values.otelContainerInsights.cloudwatchMetricsEndpoint }}{{ .Values.otelContainerInsights.cloudwatchMetricsEndpoint | quote }}{{ else }}"https://monitoring.{{ .Values.region }}.amazonaws.com:443"{{ end }} + tls: + insecure: false + auth: + authenticator: sigv4auth/cw_k8s_ci_v0_metrics_dest + +{{- if .Values.otelContainerInsights.logs.enabled }} + otlphttp/cw_k8s_ci_v0_app_logs_dest: + endpoint: {{ if .Values.otelContainerInsights.cloudwatchLogsEndpoint }}{{ .Values.otelContainerInsights.cloudwatchLogsEndpoint | quote }}{{ else if hasKey .Values.adcEndpointOverrides .Values.region }}"https://logs.{{ .Values.region }}.{{ index .Values.adcEndpointOverrides .Values.region }}:443"{{ else }}"https://logs.{{ .Values.region }}.amazonaws.com:443"{{ end }} + # compression: none matches FluentBit's current behavior (the aws-for-fluent-bit + # cloudwatch_logs plugin does not compress by default), so customers migrating + # from FluentBit see no bandwidth bill change. Enabling compression: gzip is + # available as an opt-in bandwidth optimization (~5–10× reduction for typical + # container logs) at the cost of +25% agent CPU — customers who raise the CPU + # limit accordingly can improve on FluentBit's bandwidth cost. See OTELify CI + # Logs Pipeline Optimizations doc for details. + compression: none + headers: + x-aws-log-group: "/aws/otel/containerinsights/{{ .Values.clusterName }}/application" + x-aws-log-stream: "${env:K8S_NODE_NAME}-application" + sending_queue: + queue_size: 500 + num_consumers: 10 + tls: + insecure: false + auth: + authenticator: awscloudwatchlogsprovisioner/cw_k8s_ci_v0_logs + + otlphttp/cw_k8s_ci_v0_node_logs_dest: + endpoint: {{ if .Values.otelContainerInsights.cloudwatchLogsEndpoint }}{{ .Values.otelContainerInsights.cloudwatchLogsEndpoint | quote }}{{ else if hasKey .Values.adcEndpointOverrides .Values.region }}"https://logs.{{ .Values.region }}.{{ index .Values.adcEndpointOverrides .Values.region }}:443"{{ else }}"https://logs.{{ .Values.region }}.amazonaws.com:443"{{ end }} + # See app_logs_dest comment for compression tradeoff rationale. + compression: none + headers: + x-aws-log-group: "/aws/otel/containerinsights/{{ .Values.clusterName }}/host" + x-aws-log-stream: "${env:K8S_NODE_NAME}-host" + sending_queue: + queue_size: 500 + num_consumers: 10 + tls: + insecure: false + auth: + authenticator: awscloudwatchlogsprovisioner/cw_k8s_ci_v0_logs + +{{- end }} + +service: + extensions: + - sigv4auth/cw_k8s_ci_v0_metrics_dest +{{- if .Values.otelContainerInsights.logs.enabled }} + - sigv4auth/cw_k8s_ci_v0_logs_dest + - awscloudwatchlogsprovisioner/cw_k8s_ci_v0_logs +{{- end }} + pipelines: +{{- if .Values.nodeExporter.enabled }} + metrics/cw_k8s_ci_v0_node_exporter: + receivers: [prometheus/cw_k8s_ci_v0_node_exporter] + processors: + - filter/cw_k8s_ci_v0_scrape_metadata + - transform/cw_k8s_ci_v0_set_unit + - metricstarttime/cw_k8s_ci_v0 + - transform/cw_k8s_ci_v0_set_cluster_name + - transform/cw_k8s_ci_v0_set_node_name + - transform/cw_k8s_ci_v0_promote_node_name + - resourcedetection/cw_k8s_ci_v0 + - transform/cw_k8s_ci_v0_set_cloud_resource_id + - k8sattributes/cw_k8s_ci_v0_node + - transform/cw_k8s_ci_v0_set_scope_node_exporter + - transform/cw_k8s_ci_v0_clear_schema_url + - transform/cw_k8s_ci_v0_set_workload + - awsattributelimit/cw_k8s_ci_v0 + - batch/cw_k8s_ci_v0_metrics_dest + exporters: + - otlphttp/cw_k8s_ci_v0_metrics_dest +{{- end }} + + metrics/cw_k8s_ci_v0_cadvisor: + receivers: [prometheus/cw_k8s_ci_v0_cadvisor] + processors: + - filter/cw_k8s_ci_v0_scrape_metadata + - transform/cw_k8s_ci_v0_set_unit + - metricstarttime/cw_k8s_ci_v0 + - transform/cw_k8s_ci_v0_set_cluster_name + - filter/cw_k8s_ci_v0_cadvisor_empty + - filter/cw_k8s_ci_v0_cadvisor_pod + - groupbyattrs/cw_k8s_ci_v0_cadvisor + - transform/cw_k8s_ci_v0_cadvisor_promote + - transform/cw_k8s_ci_v0_set_node_name + - transform/cw_k8s_ci_v0_promote_node_name + - resourcedetection/cw_k8s_ci_v0 + - transform/cw_k8s_ci_v0_set_cloud_resource_id + - k8sattributes/cw_k8s_ci_v0_node + - k8sattributes/cw_k8s_ci_v0_pod + - transform/cw_k8s_ci_v0_set_scope_cadvisor + - transform/cw_k8s_ci_v0_clear_schema_url + - transform/cw_k8s_ci_v0_set_workload + - awsattributelimit/cw_k8s_ci_v0 + - batch/cw_k8s_ci_v0_metrics_dest + exporters: + - otlphttp/cw_k8s_ci_v0_metrics_dest + + {{- if .Values.dcgmExporter.enabled }} + metrics/cw_k8s_ci_v0_dcgm: + receivers: [prometheus/cw_k8s_ci_v0_dcgm] + processors: [filter/cw_k8s_ci_v0_scrape_metadata, transform/cw_k8s_ci_v0_set_unit, metricstarttime/cw_k8s_ci_v0, transform/cw_k8s_ci_v0_set_cluster_name, groupbyattrs/cw_k8s_ci_v0_dcgm, transform/cw_k8s_ci_v0_dcgm_promote, k8sattributes/cw_k8s_ci_v0_pod, transform/cw_k8s_ci_v0_set_node_name, transform/cw_k8s_ci_v0_promote_node_name, k8sattributes/cw_k8s_ci_v0_node, resourcedetection/cw_k8s_ci_v0, transform/cw_k8s_ci_v0_set_scope_dcgm, transform/cw_k8s_ci_v0_clear_schema_url, transform/cw_k8s_ci_v0_set_cloud_resource_id, transform/cw_k8s_ci_v0_set_workload, awsattributelimit/cw_k8s_ci_v0, batch/cw_k8s_ci_v0_metrics_dest] + exporters: + - otlphttp/cw_k8s_ci_v0_metrics_dest + {{- end }} + + {{- if .Values.neuronMonitor.enabled }} + metrics/cw_k8s_ci_v0_neuron: + receivers: [prometheus/cw_k8s_ci_v0_neuron] + processors: + - filter/cw_k8s_ci_v0_scrape_metadata + - metricstarttime/cw_k8s_ci_v0 + - transform/cw_k8s_ci_v0_set_cluster_name + - filter/cw_k8s_ci_v0_neuron + - awsneuron/cw_k8s_ci_v0 + - transform/cw_k8s_ci_v0_set_unit + - awsdevicepodcorrelation/cw_k8s_ci_v0 + - groupbyattrs/cw_k8s_ci_v0_neuron + - transform/cw_k8s_ci_v0_neuron_promote + - transform/cw_k8s_ci_v0_neuron_hw_attrs + - k8sattributes/cw_k8s_ci_v0_pod + - transform/cw_k8s_ci_v0_set_node_name + - transform/cw_k8s_ci_v0_promote_node_name + - resourcedetection/cw_k8s_ci_v0 + - transform/cw_k8s_ci_v0_set_cloud_resource_id + - k8sattributes/cw_k8s_ci_v0_node + - transform/cw_k8s_ci_v0_set_scope_neuron_monitor + - transform/cw_k8s_ci_v0_clear_schema_url + - transform/cw_k8s_ci_v0_set_workload + - awsattributelimit/cw_k8s_ci_v0 + - batch/cw_k8s_ci_v0_metrics_dest + exporters: + - otlphttp/cw_k8s_ci_v0_metrics_dest + {{- end }} + + metrics/cw_k8s_ci_v0_efa: + receivers: [awsefareceiver/cw_k8s_ci_v0] + processors: + - transform/cw_k8s_ci_v0_set_unit + - metricstarttime/cw_k8s_ci_v0 + - transform/cw_k8s_ci_v0_set_scope_efa + - transform/cw_k8s_ci_v0_set_cluster_name + - awsdevicepodcorrelation/cw_k8s_ci_v0 + - transform/cw_k8s_ci_v0_efa_promote + - transform/cw_k8s_ci_v0_set_node_name + - transform/cw_k8s_ci_v0_promote_node_name + - k8sattributes/cw_k8s_ci_v0_pod + - k8sattributes/cw_k8s_ci_v0_node + - resourcedetection/cw_k8s_ci_v0 + - transform/cw_k8s_ci_v0_clear_schema_url + - transform/cw_k8s_ci_v0_set_cloud_resource_id + - transform/cw_k8s_ci_v0_set_workload + - awsattributelimit/cw_k8s_ci_v0 + - batch/cw_k8s_ci_v0_metrics_dest + exporters: + - otlphttp/cw_k8s_ci_v0_metrics_dest + + metrics/cw_k8s_ci_v0_ebs_csi_node: + receivers: [prometheus/cw_k8s_ci_v0_ebs_csi_node] + processors: + - filter/cw_k8s_ci_v0_scrape_metadata + - transform/cw_k8s_ci_v0_set_unit + - metricstarttime/cw_k8s_ci_v0 + - transform/cw_k8s_ci_v0_set_cluster_name + - transform/cw_k8s_ci_v0_ebs_csi_promote + - transform/cw_k8s_ci_v0_set_node_name + - transform/cw_k8s_ci_v0_promote_node_name + - resourcedetection/cw_k8s_ci_v0 + - transform/cw_k8s_ci_v0_set_cloud_resource_id + - k8sattributes/cw_k8s_ci_v0_node + - transform/cw_k8s_ci_v0_set_scope_ebs_csi + - transform/cw_k8s_ci_v0_clear_schema_url + - transform/cw_k8s_ci_v0_set_workload + - awsattributelimit/cw_k8s_ci_v0 + - batch/cw_k8s_ci_v0_metrics_dest + exporters: + - otlphttp/cw_k8s_ci_v0_metrics_dest + + metrics/cw_k8s_ci_v0_lis_csi_node: + receivers: [prometheus/cw_k8s_ci_v0_lis_csi_node] + processors: + - filter/cw_k8s_ci_v0_scrape_metadata + - transform/cw_k8s_ci_v0_set_unit + - metricstarttime/cw_k8s_ci_v0 + - transform/cw_k8s_ci_v0_set_cluster_name + - transform/cw_k8s_ci_v0_lis_csi_promote + - transform/cw_k8s_ci_v0_set_node_name + - transform/cw_k8s_ci_v0_promote_node_name + - resourcedetection/cw_k8s_ci_v0 + - transform/cw_k8s_ci_v0_set_cloud_resource_id + - k8sattributes/cw_k8s_ci_v0_node + - transform/cw_k8s_ci_v0_set_scope_lis_csi + - transform/cw_k8s_ci_v0_clear_schema_url + - transform/cw_k8s_ci_v0_set_workload + - awsattributelimit/cw_k8s_ci_v0 + - batch/cw_k8s_ci_v0_metrics_dest + exporters: + - otlphttp/cw_k8s_ci_v0_metrics_dest + + metrics/cw_k8s_ci_v0_kubeletstats: + receivers: [kubeletstats/cw_k8s_ci_v0] + processors: + - metricstarttime/cw_k8s_ci_v0 + - transform/cw_k8s_ci_v0_set_scope_kubeletstats + - transform/cw_k8s_ci_v0_set_cluster_name + - resourcedetection/cw_k8s_ci_v0 + - transform/cw_k8s_ci_v0_set_cloud_resource_id + - k8sattributes/cw_k8s_ci_v0_pod + - k8sattributes/cw_k8s_ci_v0_node + - transform/cw_k8s_ci_v0_clear_schema_url + - transform/cw_k8s_ci_v0_set_workload + - awsattributelimit/cw_k8s_ci_v0 + - batch/cw_k8s_ci_v0_metrics_dest + exporters: + - otlphttp/cw_k8s_ci_v0_metrics_dest + +{{- if .Values.otelContainerInsights.logs.enabled }} + # ── CI Logs pipelines ── + logs/cw_k8s_ci_v0_app: + receivers: [filelog/cw_k8s_ci_v0_app] + processors: + - transform/cw_k8s_ci_v0_logs_set_cluster_and_node + - resourcedetection/cw_k8s_ci_v0 + - transform/cw_k8s_ci_v0_logs_set_cloud_resource_id + - k8sattributes/cw_k8s_ci_v0_node + - k8sattributes/cw_k8s_ci_v0_pod + - transform/cw_k8s_ci_v0_logs_set_scope_app + - transform/cw_k8s_ci_v0_logs_clear_schema_url + - transform/cw_k8s_ci_v0_logs_set_workload + - batch/cw_k8s_ci_v0_logs_dest + exporters: + - otlphttp/cw_k8s_ci_v0_app_logs_dest + + # ── CI Logs: Host pipeline ── + # Intentionally omits k8sattributes/pod and set_workload — host logs + # (/var/log/messages, /var/log/dmesg, /var/log/secure) come from the node OS + # and have no pod/workload context to enrich from. k8sattributes/node adds + # node-level labels; cluster + cloud attributes apply as with other pipelines. + # service.name is intentionally not set — host logs are node-level, not + # service-level. Customers query host logs by k8s.node.name + log group. + logs/cw_k8s_ci_v0_node: + receivers: [filelog/cw_k8s_ci_v0_node] + processors: + - transform/cw_k8s_ci_v0_logs_set_cluster_and_node + - resourcedetection/cw_k8s_ci_v0 + - transform/cw_k8s_ci_v0_logs_set_cloud_resource_id + - k8sattributes/cw_k8s_ci_v0_node + - transform/cw_k8s_ci_v0_logs_set_scope_host + - transform/cw_k8s_ci_v0_logs_clear_schema_url + - batch/cw_k8s_ci_v0_logs_dest + exporters: + - otlphttp/cw_k8s_ci_v0_node_logs_dest +{{- end }} + +{{- end -}} diff --git a/charts/amazon-cloudwatch-observability/templates/linux/cloudwatch-agent-custom-resource.yaml b/charts/amazon-cloudwatch-observability/templates/linux/cloudwatch-agent-custom-resource.yaml new file mode 100644 index 0000000..6db99cf --- /dev/null +++ b/charts/amazon-cloudwatch-observability/templates/linux/cloudwatch-agent-custom-resource.yaml @@ -0,0 +1,292 @@ +{{- if .Values.agent.enabled }} +{{- if and (.Values.agent.autoGenerateCert.enabled) (not .Values.agent.certManager.enabled) -}} +{{- $altNames := list ( printf "%s-service" (include "dcgm-exporter.name" .) ) ( printf "%s-service" (include "neuron-monitor.name" .) ) ( printf "%s-service.%s.svc" (include "dcgm-exporter.name" .) .Release.Namespace ) ( printf "%s-service.%s.svc" (include "neuron-monitor.name" .) .Release.Namespace ) ( printf "%s-service" (include "node-exporter.name" .) ) ( printf "%s-service.%s.svc" (include "node-exporter.name" .) .Release.Namespace ) ( include "kube-state-metrics.name" . ) ( printf "%s.%s.svc" (include "kube-state-metrics.name" .) .Release.Namespace ) -}} +{{- range $i, $customAgent := .Values.agents }} +{{ $altNames = append $altNames ( printf "%s-target-allocator-service" $customAgent.name )}} +{{- end }} +{{- $agentAltNames := list ( printf "%s" (include "cloudwatch-agent.name" .) ) ( printf "%s.%s.svc" (include "cloudwatch-agent.name" .) .Release.Namespace ) -}} +{{- $ca := genCA ("agent-ca") ( .Values.agent.autoGenerateCert.expiryDays | int ) -}} +{{- $cert := genSignedCert ("agent") nil $altNames ( .Values.agent.autoGenerateCert.expiryDays | int ) $ca -}} +{{- $serverCert := genSignedCert ("agent-server") nil $agentAltNames ( .Values.agent.autoGenerateCert.expiryDays | int ) $ca -}} +{{- $clientCert := genSignedCert ("agent-client") nil nil ( .Values.agent.autoGenerateCert.expiryDays | int ) $ca -}} +{{- $agentTAClientCert := genSignedCert ("agent-ta-client") nil nil ( .Values.agent.autoGenerateCert.expiryDays | int ) $ca -}} +apiVersion: v1 +kind: Secret +metadata: + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4}} + name: "amazon-cloudwatch-observability-agent-cert" + namespace: {{ .Release.Namespace }} +data: + ca.crt: {{ $ca.Cert | b64enc }} + tls.crt: {{ $cert.Cert | b64enc }} + tls.key: {{ $cert.Key | b64enc }} +--- +apiVersion: v1 +kind: Secret +metadata: + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4}} + name: "amazon-cloudwatch-observability-agent-server-cert" + namespace: {{ .Release.Namespace }} +data: + ca.crt: {{ $ca.Cert | b64enc }} + tls.crt: {{ $serverCert.Cert | b64enc }} + tls.key: {{ $serverCert.Key | b64enc }} +--- +apiVersion: v1 +kind: Secret +metadata: + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4}} + name: "amazon-cloudwatch-observability-agent-client-cert" + namespace: {{ .Release.Namespace }} +data: + ca.crt: {{ $ca.Cert | b64enc }} + tls.crt: {{ $clientCert.Cert | b64enc }} + tls.key: {{ $clientCert.Key | b64enc }} +--- +apiVersion: v1 +kind: Secret +metadata: + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4}} + name: "amazon-cloudwatch-observability-agent-ta-client-cert" + namespace: {{ .Release.Namespace }} +data: + ca.crt: {{ $ca.Cert | b64enc }} + tls.crt: {{ $agentTAClientCert.Cert | b64enc }} + tls.key: {{ $agentTAClientCert.Key | b64enc }} +--- +{{- end -}} + +{{- $clusterName := .Values.clusterName | required ".Values.clusterName is required." -}} +{{- $region := .Values.region | required ".Values.region is required." -}} +{{- $isROSA := eq $.Values.k8sMode "ROSA" -}} +{{- range .Values.agents }} +{{- $agent := mergeOverwrite (deepCopy $.Values.agent) . }} +{{/* Skip cluster-scraper agent when otelContainerInsights is disabled */}} +{{- if or $.Values.otelContainerInsights.enabled (ne $agent.name $.Values.otelContainerInsights.clusterScraperAgent) }} +apiVersion: cloudwatch.aws.amazon.com/v1alpha1 +kind: AmazonCloudWatchAgent +metadata: + name: {{ $agent.name | default (include "cloudwatch-agent.name" $) }} + namespace: {{ $.Release.Namespace }} +spec: + {{ template "cloudwatch-agent.updateStrategy" (dict "mode" $agent.mode) }}: + type: {{ $agent.updateStrategy.type }} + {{- if eq $agent.updateStrategy.type "RollingUpdate" }} + rollingUpdate: + maxUnavailable: {{ $agent.updateStrategy.rollingUpdate.maxUnavailable | default (include "cloudwatch-agent.rolloutStrategyMaxUnavailable" (dict "mode" $agent.mode)) }} + maxSurge: {{ $agent.updateStrategy.rollingUpdate.maxSurge | default (include "cloudwatch-agent.rolloutStrategyMaxSurge" (dict "mode" $agent.mode)) }} + {{- end }} + image: {{ template "cloudwatch-agent.image" (merge $agent.image (dict "region" $.Values.region)) }} + mode: {{ $agent.mode }} + replicas: {{ $agent.replicas }} + {{- with $agent.nodeSelector }} + nodeSelector: {{- toYaml . | nindent 4 }} + {{- end }} + serviceAccount: {{ $agent.serviceAccount.name | default (include "cloudwatch-agent.serviceAccountName" $) }} + {{ if $isROSA }} + securityContext: + runAsNonRoot: false + capabilities: + add: + - SYS_ADMIN + {{ end }} + priorityClassName: {{ $agent.priorityClassName | default $.Values.agent.priorityClassName }} + {{- with $agent.affinity }} + affinity: {{- toYaml . | nindent 4 }} + {{- end }} + hostNetwork: {{ $agent.hostNetwork }} + {{- if and $agent.config (ne ($agent.config | toString) "default") }} + config: {{ include "cloudwatch-agent.modify-config" (merge (dict "Config" $agent.config) $ ) }} + {{- else }} + config: {{ include "cloudwatch-agent.modify-config" (merge (dict "Config" (include "cloudwatch-agent.build-default-config" (dict "agentName" $agent.name "context" $) | fromJson)) $ ) }} + {{- end }} + {{- $generatedOtelConfig := include "cloudwatch-agent.build-default-otel-config" (dict "agentName" $agent.name "context" $) -}} + {{- if $agent.otelConfig }} + otelConfig: {{ include "cloudwatch-agent.modify-otel-config" (merge (dict "OtelConfig" (include "cloudwatch-agent.merge-otel-configs" (dict "Base" $generatedOtelConfig "User" $agent.otelConfig))) $) }} + {{- else if ne (trimAll " \n\t" $generatedOtelConfig) "{}" }} + otelConfig: {{ include "cloudwatch-agent.modify-otel-config" (merge (dict "OtelConfig" $generatedOtelConfig) $) }} + {{- end }} + {{- if $agent.prometheus.config }} + prometheus: + {{- with $agent.prometheus.config }} + config: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- end }} + {{- if $agent.prometheus.targetAllocator.enabled }} + targetAllocator: + enabled: {{ $agent.prometheus.targetAllocator.enabled | default false }} + image: {{ template "target-allocator.image" (merge $agent.prometheus.targetAllocator.image (dict "region" $.Values.region)) }} + allocationStrategy: "consistent-hashing" + {{- if $agent.prometheus.targetAllocator.prometheusCR.enabled }} + prometheusCR: + enabled: {{ $agent.prometheus.targetAllocator.prometheusCR.enabled | default false }} + {{- end }} + {{- end }} + {{- with $agent.resources }} + resources: {{- toYaml . | nindent 4}} + {{- end }} + volumeMounts: + - mountPath: /rootfs + name: rootfs + readOnly: true + - mountPath: /var/run/docker.sock + name: dockersock + readOnly: true + - mountPath: /run/containerd/containerd.sock + name: containerdsock + - mountPath: /var/run/crio/crio.sock + name: criosock + readOnly: true + - mountPath: /var/lib/containers + name: criocontainer + readOnly: true + - mountPath: /var/log/pods + name: criologs + readOnly: true + {{- if and $.Values.otelContainerInsights.enabled $.Values.otelContainerInsights.logs.enabled (eq $agent.name $.Values.otelContainerInsights.targetAgent) }} + # /var/log covers the paths the OTEL log pipelines need: /var/log/containers/*.log + # (app container logs), /var/log/messages, /var/log/dmesg, /var/log/secure + # (host logs). The existing criologs mount on /var/log/pods is retained for + # the existing metrics pipelines. + - mountPath: /var/log + name: varlog + readOnly: true + {{- end }} + - mountPath: /var/lib/docker + name: varlibdocker + readOnly: true + - mountPath: /sys + name: sys + readOnly: true + - mountPath: /dev/disk + name: devdisk + readOnly: true + - mountPath: /etc/amazon-cloudwatch-observability-agent-cert + name: agenttls + readOnly: true + - mountPath: /etc/amazon-cloudwatch-observability-agent-client-cert + name: agentclienttls + readOnly: true + - mountPath: /etc/amazon-cloudwatch-observability-agent-server-cert + name: agentservertls + readOnly: true + - mountPath: /etc/amazon-cloudwatch-observability-agent-ta-client-cert + name: agenttaclienttls + readOnly: true + - mountPath: /var/lib/kubelet/pod-resources + name: kubelet-podresources + {{ if $isROSA }} + - mountPath: /etc/kubernetes/kubelet-ca.crt + name: kubelet-ca + readOnly: true + {{ end }} + volumes: + - name: kubelet-podresources + hostPath: + path: /var/lib/kubelet/pod-resources + type: Directory + - name: rootfs + hostPath: + path: / + - hostPath: + path: /var/run/docker.sock + name: dockersock + - hostPath: + path: /var/lib/docker + name: varlibdocker + - hostPath: + path: /run/containerd/containerd.sock + name: containerdsock + - hostPath: + path: /var/run/crio/crio.sock + name: criosock + - hostPath: + path: /var/lib/containers + name: criocontainer + - hostPath: + path: /var/log/pods + name: criologs + {{- if and $.Values.otelContainerInsights.enabled $.Values.otelContainerInsights.logs.enabled (eq $agent.name $.Values.otelContainerInsights.targetAgent) }} + - hostPath: + path: /var/log + name: varlog + {{- end }} + - hostPath: + path: /sys + name: sys + - hostPath: + path: /dev/disk/ + name: devdisk + - name: agenttls + secret: + secretName: amazon-cloudwatch-observability-agent-cert + items: + - key: ca.crt + path: tls-ca.crt + - name: agentclienttls + secret: + secretName: amazon-cloudwatch-observability-agent-client-cert + items: + - key: ca.crt + path: tls-ca.crt + - name: agentservertls + secret: + secretName: amazon-cloudwatch-observability-agent-server-cert + items: + - key: tls.crt + path: server.crt + - key: tls.key + path: server.key + - name: agenttaclienttls + secret: + secretName: amazon-cloudwatch-observability-agent-ta-client-cert + items: + - key: tls.crt + path: client.crt + - key: tls.key + path: client.key + {{ if $isROSA }} + - name: kubelet-ca + hostPath: + path: /etc/kubernetes/kubelet-ca.crt + {{end }} + env: + - name: K8S_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: HOST_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: K8S_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{ if $isROSA }} + - name: RUN_IN_ROSA + value: "True" + {{ end }} + - name: K8S_CLUSTER_NAME + value: {{ $.Values.clusterName | quote }} + {{- if $.Values.otelContainerInsights.enabled }} + - name: OTEL_CI_VERSION + value: "1.0.0" + {{- end }} + {{- with $agent.env }} + {{- . | toYaml | nindent 2 }} + {{- end }} + {{- dict "component" $agent "context" $ | include "amazon-cloudwatch-observability.common.tolerations" | nindent 2 }} +--- +{{- end }}{{/* end: render unless cluster-scraper with OTLP disabled */}} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/amazon-cloudwatch-observability/templates/linux/dcgm-exporter-daemonset.yaml b/charts/amazon-cloudwatch-observability/templates/linux/dcgm-exporter-daemonset.yaml new file mode 100644 index 0000000..47c7b23 --- /dev/null +++ b/charts/amazon-cloudwatch-observability/templates/linux/dcgm-exporter-daemonset.yaml @@ -0,0 +1,74 @@ +{{- if .Values.dcgmExporter.enabled }} +apiVersion: cloudwatch.aws.amazon.com/v1alpha1 +kind: DcgmExporter +metadata: + name: {{ include "dcgm-exporter.name" . }} + namespace: {{ .Release.Namespace }} + labels: + k8s-app: {{ include "dcgm-exporter.name" . }} + version: v1 +spec: + image: {{ template "dcgm-exporter.image" . }} + {{- with .Values.dcgmExporter.nodeSelector }} + nodeSelector: {{- toYaml . | nindent 4 }} + {{- end }} + serviceAccount: {{ template "dcgm-exporter.serviceAccountName" . }} + {{- with .Values.dcgmExporter.affinity }} + affinity: {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.dcgmExporter.resources }} + resources: {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.dcgmExporter.securityContext }} + securityContext: {{- toYaml . | nindent 4 }} + {{- end }} + env: + - name: "DCGM_EXPORTER_KUBERNETES" + value: "true" + - name: "DCGM_EXPORTER_LISTEN" + value: "{{ .Values.dcgmExporter.service.address }}" + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + {{- include "dcgm-exporter.env" . | nindent 2 }} + ports: + - name: "metrics" + port: {{ .Values.dcgmExporter.service.port }} + volumeMounts: + - name: "pod-gpu-resources" + readOnly: true + mountPath: "/var/lib/kubelet/pod-resources" + - mountPath: /etc/amazon-cloudwatch-observability-dcgm-cert + name: dcgmtls + readOnly: true + volumes: + - name: dcgmtls + secret: + secretName: amazon-cloudwatch-observability-agent-cert + items: + - key: tls.crt + path: server.crt + - key: tls.key + path: server.key + - name: "pod-gpu-resources" + hostPath: + path: /var/lib/kubelet/pod-resources + metricsConfig: | + DCGM_FI_DEV_GPU_UTIL, gauge, GPU utilization (in %). + DCGM_FI_DEV_MEM_COPY_UTIL, gauge, Memory utilization (in %). + DCGM_FI_DEV_FB_FREE, gauge, Framebuffer memory free (in MiB). + DCGM_FI_DEV_FB_USED, gauge, Framebuffer memory used (in MiB). + DCGM_FI_DEV_FB_TOTAL, gauge, Framebuffer memory used (in MiB). + DCGM_FI_DEV_FB_USED_PERCENT, gauge, Percentage used of Frame Buffer: Used/(Total - Reserved). + DCGM_FI_DEV_MEMORY_TEMP, gauge, Memory temperature (in C). + DCGM_FI_DEV_GPU_TEMP, gauge, GPU temperature (in C). + DCGM_FI_DEV_POWER_USAGE, gauge, Power draw (in W). + DCGM_FI_PROF_PIPE_TENSOR_ACTIVE, gauge, Tensor Core utilization (in %). + DCGM_FI_DRIVER_VERSION, label, Driver Version. + tlsConfig: | + tls_server_config: + cert_file: /etc/amazon-cloudwatch-observability-dcgm-cert/server.crt + key_file: /etc/amazon-cloudwatch-observability-dcgm-cert/server.key + {{- dict "component" .Values.dcgmExporter "context" . | include "amazon-cloudwatch-observability.common.tolerations" | nindent 2 }} +{{- end }} diff --git a/charts/amazon-cloudwatch-observability/templates/linux/dcgm-exporter-role.yaml b/charts/amazon-cloudwatch-observability/templates/linux/dcgm-exporter-role.yaml new file mode 100644 index 0000000..21986c1 --- /dev/null +++ b/charts/amazon-cloudwatch-observability/templates/linux/dcgm-exporter-role.yaml @@ -0,0 +1,14 @@ +{{- if .Values.dcgmExporter.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: "{{ template "dcgm-exporter.name" . }}-role" + namespace: {{ .Release.Namespace }} + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4}} +rules: +- apiGroups: [""] + resources: ["configmaps"] + resourceNames: ["{{ .Values.dcgmExporter.configmap }}"] + verbs: ["get"] +{{- end }} \ No newline at end of file diff --git a/charts/amazon-cloudwatch-observability/templates/linux/dcgm-exporter-rolebinding.yaml b/charts/amazon-cloudwatch-observability/templates/linux/dcgm-exporter-rolebinding.yaml new file mode 100644 index 0000000..aaebf75 --- /dev/null +++ b/charts/amazon-cloudwatch-observability/templates/linux/dcgm-exporter-rolebinding.yaml @@ -0,0 +1,17 @@ +{{- if .Values.dcgmExporter.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + namespace: {{ .Release.Namespace }} + name: {{ template "dcgm-exporter.name" . }}-role-binding + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4}} +roleRef: + kind: Role + name: "{{ template "dcgm-exporter.name" . }}-role" + apiGroup: rbac.authorization.k8s.io +subjects: +- kind: ServiceAccount + name: {{ template "dcgm-exporter.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} \ No newline at end of file diff --git a/charts/amazon-cloudwatch-observability/templates/linux/fluent-bit-configmap.yaml b/charts/amazon-cloudwatch-observability/templates/linux/fluent-bit-configmap.yaml new file mode 100644 index 0000000..8d7abf8 --- /dev/null +++ b/charts/amazon-cloudwatch-observability/templates/linux/fluent-bit-configmap.yaml @@ -0,0 +1,22 @@ +{{- if .Values.containerLogs.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: fluent-bit-config + namespace: {{ .Release.Namespace }} + labels: + k8s-app: fluent-bit +data: + fluent-bit.conf: | + {{- include "fluent-bit.add-ipv6-preference" (dict "config" .Values.containerLogs.fluentBit.config.service "useDualstackEndpoint" .Values.useDualstackEndpoint "indent" " ") | nindent 4 }} + {{- range $key, $val := .Values.containerLogs.fluentBit.config.extraFiles }} + @INCLUDE {{ $key }} + {{- end }} + parsers.conf: | + {{- .Values.containerLogs.fluentBit.config.customParsers | nindent 4 }} +{{- range $key, $val := .Values.containerLogs.fluentBit.config.extraFiles }} + {{ $key }}: | + {{- $config := tpl $val $ }} + {{- include "fluent-bit.add-dualstack-endpoints" (dict "Values" $.Values "config" $config) | nindent 4 }} +{{- end -}} +{{- end -}} diff --git a/charts/amazon-cloudwatch-observability/templates/linux/fluent-bit-daemonset.yaml b/charts/amazon-cloudwatch-observability/templates/linux/fluent-bit-daemonset.yaml new file mode 100644 index 0000000..1baa9b0 --- /dev/null +++ b/charts/amazon-cloudwatch-observability/templates/linux/fluent-bit-daemonset.yaml @@ -0,0 +1,133 @@ +{{- if .Values.containerLogs.enabled }} +{{- $clusterName := .Values.clusterName | required ".Values.clusterName is required." -}} +{{- $region := .Values.region | required ".Values.region is required." -}} +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: fluent-bit + namespace: {{ .Release.Namespace }} + labels: + k8s-app: fluent-bit + version: v1 + kubernetes.io/cluster-service: "true" +spec: + selector: + matchLabels: + k8s-app: fluent-bit + updateStrategy: + type: {{ .Values.containerLogs.fluentBit.updateStrategy.type }} + {{- if eq .Values.containerLogs.fluentBit.updateStrategy.type "RollingUpdate" }} + rollingUpdate: + maxUnavailable: {{ .Values.containerLogs.fluentBit.updateStrategy.rollingUpdate.maxUnavailable }} + maxSurge: {{ .Values.containerLogs.fluentBit.updateStrategy.rollingUpdate.maxSurge }} + {{- end }} + template: + metadata: + annotations: + checksum/config: {{ include (print $.Template.BasePath "/linux/fluent-bit-configmap.yaml") . | sha256sum }} + labels: + k8s-app: fluent-bit + version: v1 + kubernetes.io/cluster-service: "true" + spec: + containers: + - name: fluent-bit + image: {{ template "fluent-bit.image" . }} + imagePullPolicy: Always + env: + - name: AWS_REGION + value: {{ .Values.region }} + - name: CLUSTER_NAME + value: {{ .Values.clusterName | quote }} + - name: READ_FROM_HEAD + value: "Off" + - name: READ_FROM_TAIL + value: "On" + - name: HOST_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: HOSTNAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: CI_VERSION + value: "k8s/1.3.17" + {{- with .Values.containerLogs.fluentBit.resources }} + resources: {{- toYaml . | nindent 10}} + {{- end }} + {{- with .Values.containerLogs.fluentBit.securityContext }} + securityContext: + {{- toYaml . | nindent 10}} + {{- end }} + volumeMounts: + # Please don't change below read-only permissions + - name: fluentbitstate + mountPath: /var/fluent-bit/state + - name: varlog + mountPath: /var/log + readOnly: true + - name: varlibdockercontainers + mountPath: /var/lib/docker/containers + readOnly: true + - name: fluent-bit-config + mountPath: /fluent-bit/etc/ + - name: runlogjournal + mountPath: /run/log/journal + readOnly: true + - name: dmesg + mountPath: /var/log/dmesg + readOnly: true + - mountPath: /etc/amazon-cloudwatch-observability-agent-client-cert + name: agentclienttls + readOnly: true + - mountPath: /etc/amazon-cloudwatch-observability-agent-server-cert + name: agentservertls + readOnly: true + terminationGracePeriodSeconds: 10 + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet + priorityClassName: {{ .Values.containerLogs.fluentBit.priorityClassName }} + volumes: + - name: fluentbitstate + hostPath: + path: /var/fluent-bit/state + - name: varlog + hostPath: + path: /var/log + - name: varlibdockercontainers + hostPath: + path: /var/lib/docker/containers + - name: fluent-bit-config + configMap: + name: fluent-bit-config + - name: runlogjournal + hostPath: + path: /run/log/journal + - name: dmesg + hostPath: + path: /var/log/dmesg + - name: agentclienttls + secret: + secretName: amazon-cloudwatch-observability-agent-client-cert + items: + - key: tls.crt + path: client.crt + - key: tls.key + path: client.key + - name: agentservertls + secret: + secretName: amazon-cloudwatch-observability-agent-server-cert + items: + - key: ca.crt + path: tls-ca.crt + serviceAccountName: {{ template "cloudwatch-agent.serviceAccountName" . }} + {{- with .Values.containerLogs.fluentBit.affinity }} + affinity: {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.containerLogs.fluentBit.nodeSelector }} + nodeSelector: {{- toYaml . | nindent 8 }} + {{- end }} + {{- dict "component" .Values.containerLogs.fluentBit "context" . | include "amazon-cloudwatch-observability.common.tolerations" | nindent 6 }} +{{- end }} diff --git a/charts/amazon-cloudwatch-observability/templates/linux/kube-state-metrics-clusterrole.yaml b/charts/amazon-cloudwatch-observability/templates/linux/kube-state-metrics-clusterrole.yaml new file mode 100644 index 0000000..be36596 --- /dev/null +++ b/charts/amazon-cloudwatch-observability/templates/linux/kube-state-metrics-clusterrole.yaml @@ -0,0 +1,44 @@ +{{- if and .Values.kubeStateMetrics.enabled .Values.otelContainerInsights.enabled }} +# ClusterRole is cluster-scoped — prefixed with component name to avoid +# collision with a customer's own kube-state-metrics ClusterRole. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "kube-state-metrics.name" . }}-cluster-role + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4 }} +rules: + - apiGroups: [""] + resources: [configmaps, secrets, nodes, pods, services, serviceaccounts, resourcequotas, replicationcontrollers, limitranges, persistentvolumeclaims, persistentvolumes, namespaces, endpoints] + verbs: [list, watch] + - apiGroups: [apps] + resources: [statefulsets, daemonsets, deployments, replicasets] + verbs: [list, watch] + - apiGroups: [batch] + resources: [cronjobs, jobs] + verbs: [list, watch] + - apiGroups: [autoscaling] + resources: [horizontalpodautoscalers] + verbs: [list, watch] + - apiGroups: [policy] + resources: [poddisruptionbudgets] + verbs: [list, watch] + - apiGroups: [storage.k8s.io] + resources: [storageclasses, volumeattachments] + verbs: [list, watch] + - apiGroups: [networking.k8s.io] + resources: [networkpolicies, ingresses] + verbs: [list, watch] + - apiGroups: [discovery.k8s.io] + resources: [endpointslices] + verbs: [list, watch] + - apiGroups: [admissionregistration.k8s.io] + resources: [mutatingwebhookconfigurations, validatingwebhookconfigurations] + verbs: [list, watch] + - apiGroups: [certificates.k8s.io] + resources: [certificatesigningrequests] + verbs: [list, watch] + - apiGroups: [coordination.k8s.io] + resources: [leases] + verbs: [list, watch] +{{- end }} diff --git a/charts/amazon-cloudwatch-observability/templates/linux/kube-state-metrics-clusterrolebinding.yaml b/charts/amazon-cloudwatch-observability/templates/linux/kube-state-metrics-clusterrolebinding.yaml new file mode 100644 index 0000000..0d6098f --- /dev/null +++ b/charts/amazon-cloudwatch-observability/templates/linux/kube-state-metrics-clusterrolebinding.yaml @@ -0,0 +1,16 @@ +{{- if and .Values.kubeStateMetrics.enabled .Values.otelContainerInsights.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "kube-state-metrics.name" . }}-cluster-role-binding + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "kube-state-metrics.name" . }}-cluster-role +subjects: + - kind: ServiceAccount + name: {{ template "kube-state-metrics.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/charts/amazon-cloudwatch-observability/templates/linux/kube-state-metrics.yaml b/charts/amazon-cloudwatch-observability/templates/linux/kube-state-metrics.yaml new file mode 100644 index 0000000..da1e6c0 --- /dev/null +++ b/charts/amazon-cloudwatch-observability/templates/linux/kube-state-metrics.yaml @@ -0,0 +1,120 @@ +{{- if and .Values.kubeStateMetrics.enabled .Values.otelContainerInsights.enabled }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "kube-state-metrics.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4 }} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "kube-state-metrics.name" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4 }} + app.kubernetes.io/component: {{ include "kube-state-metrics.name" . }} +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/component: {{ include "kube-state-metrics.name" . }} + template: + metadata: + labels: + app.kubernetes.io/component: {{ include "kube-state-metrics.name" . }} + spec: + serviceAccountName: {{ template "kube-state-metrics.serviceAccountName" . }} + {{- with .Values.kubeStateMetrics.nodeSelector }} + nodeSelector: {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.kubeStateMetrics.affinity }} + affinity: {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.kubeStateMetrics.securityContext }} + securityContext: {{- toYaml . | nindent 8 }} + {{- end }} + {{- dict "component" .Values.kubeStateMetrics "context" . | include "amazon-cloudwatch-observability.common.tolerations" | nindent 6 }} + containers: + - name: kube-state-metrics + image: {{ template "kube-state-metrics.image" . }} + args: + - --port=8443 + - --tls-config=/etc/ksm-web-config/web.yml + ports: + - name: https-metrics + containerPort: 8443 + protocol: TCP + - name: telemetry + containerPort: 8081 + protocol: TCP + readinessProbe: + httpGet: + path: /healthz + port: 8443 + scheme: HTTPS + initialDelaySeconds: 5 + timeoutSeconds: 5 + livenessProbe: + httpGet: + path: /healthz + port: 8443 + scheme: HTTPS + initialDelaySeconds: 5 + timeoutSeconds: 5 + resources: + {{- toYaml .Values.kubeStateMetrics.resources | nindent 12 }} + volumeMounts: + - name: ksm-tls + mountPath: /etc/ksm-cert + readOnly: true + - name: ksm-web-config + mountPath: /etc/ksm-web-config + readOnly: true + volumes: + - name: ksm-tls + secret: + secretName: amazon-cloudwatch-observability-agent-cert + items: + - key: tls.crt + path: server.crt + - key: tls.key + path: server.key + - name: ksm-web-config + configMap: + name: {{ include "kube-state-metrics.name" . }}-web-config +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "kube-state-metrics.name" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4 }} + app.kubernetes.io/component: {{ include "kube-state-metrics.name" . }} + # Exposes the KSM metrics endpoint (8443/HTTPS) for the cluster-scraper's static_configs. + # No prometheus scrape annotations — the cluster-scraper uses explicit service DNS targets, not annotation-based discovery. +spec: + type: {{ .Values.kubeStateMetrics.service.type | default "ClusterIP" }} + ports: + - name: https-metrics + port: {{ .Values.kubeStateMetrics.service.port | default 8443 }} + targetPort: https-metrics + protocol: TCP + selector: + app.kubernetes.io/component: {{ include "kube-state-metrics.name" . }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "kube-state-metrics.name" . }}-web-config + namespace: {{ .Release.Namespace }} + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4 }} +data: + web.yml: | + tls_server_config: + cert_file: /etc/ksm-cert/server.crt + key_file: /etc/ksm-cert/server.key +{{- end }} diff --git a/charts/amazon-cloudwatch-observability/templates/linux/neuron-monitor-daemonset.yaml b/charts/amazon-cloudwatch-observability/templates/linux/neuron-monitor-daemonset.yaml new file mode 100644 index 0000000..d48adcd --- /dev/null +++ b/charts/amazon-cloudwatch-observability/templates/linux/neuron-monitor-daemonset.yaml @@ -0,0 +1,99 @@ +{{- if .Values.neuronMonitor.enabled }} +apiVersion: cloudwatch.aws.amazon.com/v1alpha1 +kind: NeuronMonitor +metadata: + name: {{ include "neuron-monitor.name" . }} + namespace: {{ .Release.Namespace }} + labels: + k8s-app: {{ include "neuron-monitor.name" . }} + version: v1 +spec: + image: {{ template "neuron-monitor.image" . }} + serviceAccount: {{ template "neuron-monitor.serviceAccountName" . }} + {{- with .Values.neuronMonitor.nodeSelector }} + nodeSelector: {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.neuronMonitor.affinity }} + affinity: {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.neuronMonitor.resources }} + resources: {{- toYaml . | nindent 4}} + {{- end }} + env: + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: PATH + value: /usr/local/bin:/usr/bin:/bin:/opt/aws/neuron/bin + - name: GOMEMLIMIT + value: 320MiB + ports: + - name: "metrics" + port: {{ .Values.neuronMonitor.service.port }} + command: + - "/opt/bin/entrypoint.sh" + - "--cert-file" + - "/etc/amazon-cloudwatch-observability-neuron-cert/server.crt" + - "--key-file" + - "/etc/amazon-cloudwatch-observability-neuron-cert/server.key" + - "--port" + - "{{ .Values.neuronMonitor.service.port }}" + - "--neuron-monitor-config" + - "/etc/neuron-monitor-config/monitor.json" + securityContext: + privileged: true + volumeMounts: + - mountPath: /etc/amazon-cloudwatch-observability-neuron-cert/ + name: neurontls + readOnly: true + - mountPath: /opt-aws + name: "aws-config" + readOnly: true + - mountPath: /neuron-monitor-blocker + name: neuron-monitor-blocker + readOnly: true + volumes: + - name: neurontls + secret: + secretName: amazon-cloudwatch-observability-agent-cert + items: + - key: tls.crt + path: server.crt + - key: tls.key + path: server.key + - name: "aws-config" + hostPath: + path: /opt/aws + - name: neuron-monitor-blocker + hostPath: + path: /var/neuron-monitor-blocker + type: "" + monitorConfig: | + { + "period": "5s", + "neuron_runtimes": [ + { + "tag_filter": ".*", + "metrics": [ + { + "type": "neuroncore_counters" + }, + { + "type": "memory_used" + }, + { + "type": "execution_stats" + } + ] + } + ], + "system_metrics": [ + { + "period": "5s", + "type": "neuron_hw_counters" + } + ] + } + {{- dict "component" .Values.neuronMonitor "context" . | include "amazon-cloudwatch-observability.common.tolerations" | nindent 2 }} +{{- end }} diff --git a/charts/amazon-cloudwatch-observability/templates/linux/neuron-monitor-exporter-role.yaml b/charts/amazon-cloudwatch-observability/templates/linux/neuron-monitor-exporter-role.yaml new file mode 100644 index 0000000..869521a --- /dev/null +++ b/charts/amazon-cloudwatch-observability/templates/linux/neuron-monitor-exporter-role.yaml @@ -0,0 +1,14 @@ +{{- if .Values.neuronMonitor.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: "{{ include "neuron-monitor.name" . }}-role" + namespace: {{ .Release.Namespace }} + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4}} +rules: +- apiGroups: [""] + resources: ["configmaps"] + resourceNames: ["{{ .Values.neuronMonitor.configmap }}"] + verbs: ["get"] +{{- end }} \ No newline at end of file diff --git a/charts/amazon-cloudwatch-observability/templates/linux/neuron-monitor-exporter-rolebinding.yaml b/charts/amazon-cloudwatch-observability/templates/linux/neuron-monitor-exporter-rolebinding.yaml new file mode 100644 index 0000000..06be0e2 --- /dev/null +++ b/charts/amazon-cloudwatch-observability/templates/linux/neuron-monitor-exporter-rolebinding.yaml @@ -0,0 +1,17 @@ +{{- if .Values.neuronMonitor.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + namespace: {{ .Release.Namespace }} + name: {{ include "neuron-monitor.name" . }}-role-binding + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4}} +roleRef: + kind: Role + name: "{{ include "neuron-monitor.name" . }}-role" + apiGroup: rbac.authorization.k8s.io +subjects: +- kind: ServiceAccount + name: {{ include "neuron-monitor.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} \ No newline at end of file diff --git a/charts/amazon-cloudwatch-observability/templates/linux/node-exporter-daemonset.yaml b/charts/amazon-cloudwatch-observability/templates/linux/node-exporter-daemonset.yaml new file mode 100644 index 0000000..dff0760 --- /dev/null +++ b/charts/amazon-cloudwatch-observability/templates/linux/node-exporter-daemonset.yaml @@ -0,0 +1,127 @@ +{{- if and .Values.nodeExporter.enabled .Values.otelContainerInsights.enabled }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "node-exporter.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4 }} +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ include "node-exporter.name" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4 }} + k8s-app: {{ include "node-exporter.name" . }} +spec: + selector: + matchLabels: + k8s-app: {{ include "node-exporter.name" . }} + template: + metadata: + labels: + k8s-app: {{ include "node-exporter.name" . }} + spec: + serviceAccountName: {{ template "node-exporter.serviceAccountName" . }} + {{- with .Values.nodeExporter.nodeSelector }} + nodeSelector: {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeExporter.affinity }} + affinity: {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeExporter.securityContext }} + securityContext: {{- toYaml . | nindent 8 }} + {{- end }} + {{- dict "component" .Values.nodeExporter "context" . | include "amazon-cloudwatch-observability.common.tolerations" | nindent 6 }} + containers: + - name: node-exporter + image: {{ template "node-exporter.image" . }} + args: + - --path.rootfs=/host/root + - --path.sysfs=/host/sys + - --path.procfs=/host/proc + - --web.listen-address=:9487 + # TLS configuration: node-exporter loads TLS settings from the web config file below, + # which references the node-exporter-web-config ConfigMap mounted at /etc/node-exporter. + # The ConfigMap contains tls_server_config pointing to certs from the agent-cert Secret. + - --web.config.file=/etc/node-exporter/web.yml + ports: + - name: metrics + containerPort: 9487 + hostPort: 9487 + protocol: TCP + resources: + {{- toYaml .Values.nodeExporter.resources | nindent 12 }} + volumeMounts: + - name: rootfs + mountPath: /host/root + readOnly: true + mountPropagation: HostToContainer + - name: sys + mountPath: /host/sys + readOnly: true + - name: proc + mountPath: /host/proc + readOnly: true + - name: nodeexportertls + mountPath: /etc/node-exporter-cert + readOnly: true + - name: web-config + mountPath: /etc/node-exporter + readOnly: true + volumes: + - name: rootfs + hostPath: + path: / + - name: sys + hostPath: + path: /sys + - name: proc + hostPath: + path: /proc + - name: nodeexportertls + secret: + secretName: amazon-cloudwatch-observability-agent-cert + items: + - key: tls.crt + path: server.crt + - key: tls.key + path: server.key + - name: web-config + configMap: + name: {{ include "node-exporter.name" . }}-web-config +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "node-exporter.name" . }}-service + namespace: {{ .Release.Namespace }} + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4 }} + app.kubernetes.io/component: {{ include "node-exporter.name" . }} +spec: + type: ClusterIP + internalTrafficPolicy: Local + ports: + - name: metrics + port: 9487 + targetPort: metrics + protocol: TCP + selector: + k8s-app: {{ include "node-exporter.name" . }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "node-exporter.name" . }}-web-config + namespace: {{ .Release.Namespace }} + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4 }} +data: + web.yml: | + tls_server_config: + cert_file: /etc/node-exporter-cert/server.crt + key_file: /etc/node-exporter-cert/server.key +{{- end }} diff --git a/charts/amazon-cloudwatch-observability/templates/linux/node-exporter-role.yaml b/charts/amazon-cloudwatch-observability/templates/linux/node-exporter-role.yaml new file mode 100644 index 0000000..06e2925 --- /dev/null +++ b/charts/amazon-cloudwatch-observability/templates/linux/node-exporter-role.yaml @@ -0,0 +1,14 @@ +{{- if and .Values.nodeExporter.enabled .Values.otelContainerInsights.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: "{{ template "node-exporter.name" . }}-role" + namespace: {{ .Release.Namespace }} + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4}} +rules: +- apiGroups: [""] + resources: ["configmaps"] + resourceNames: ["{{ include "node-exporter.name" . }}-web-config"] + verbs: ["get"] +{{- end }} diff --git a/charts/amazon-cloudwatch-observability/templates/linux/node-exporter-rolebinding.yaml b/charts/amazon-cloudwatch-observability/templates/linux/node-exporter-rolebinding.yaml new file mode 100644 index 0000000..f32e460 --- /dev/null +++ b/charts/amazon-cloudwatch-observability/templates/linux/node-exporter-rolebinding.yaml @@ -0,0 +1,17 @@ +{{- if and .Values.nodeExporter.enabled .Values.otelContainerInsights.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + namespace: {{ .Release.Namespace }} + name: {{ template "node-exporter.name" . }}-role-binding + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4}} +roleRef: + kind: Role + name: "{{ template "node-exporter.name" . }}-role" + apiGroup: rbac.authorization.k8s.io +subjects: +- kind: ServiceAccount + name: {{ template "node-exporter.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/charts/amazon-cloudwatch-observability/templates/namespace.amazon-cloudwatch.yaml b/charts/amazon-cloudwatch-observability/templates/namespace.amazon-cloudwatch.yaml new file mode 100644 index 0000000..217122b --- /dev/null +++ b/charts/amazon-cloudwatch-observability/templates/namespace.amazon-cloudwatch.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Namespace +metadata: + annotations: + argocd.argoproj.io/sync-wave: "0" + openshift.io/description: "" + openshift.io/display-name: "amazon-cloudwatch" + labels: + kubernetes.io/metadata.name: amazon-cloudwatch + name: amazon-cloudwatch diff --git a/charts/amazon-cloudwatch-observability/templates/operator-clusterrole.yaml b/charts/amazon-cloudwatch-observability/templates/operator-clusterrole.yaml new file mode 100644 index 0000000..7eaa6d9 --- /dev/null +++ b/charts/amazon-cloudwatch-observability/templates/operator-clusterrole.yaml @@ -0,0 +1,56 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "amazon-cloudwatch-observability.name" . }}-manager-role +rules: +- apiGroups: [ "" ] + resources: [ "configmaps" ] + verbs: [ "create", "delete", "get", "list", "patch", "update", "watch" ] +- apiGroups: [ "" ] + resources: [ "events" ] + verbs: [ "create", "patch" ] +- apiGroups: [ "" ] + resources: [ "namespaces" ] + verbs: [ "get","list","patch","update","watch" ] +- apiGroups: [ "" ] + resources: [ "serviceaccounts" ] + verbs: [ "create","delete","get","list","patch","update","watch" ] +- apiGroups: [ "" ] + resources: [ "services" ] + verbs: [ "create","delete","get","list","patch","update","watch" ] +- apiGroups: [ "apps" ] + resources: [ "daemonsets" ] + verbs: [ "create","delete","get","list","patch","update","watch" ] +- apiGroups: [ "apps" ] + resources: [ "deployments" ] + verbs: [ "create","delete","get","list","patch","update","watch" ] +- apiGroups: [ "apps" ] + resources: [ "statefulsets" ] + verbs: [ "create","delete","get","list","patch","update","watch" ] +- apiGroups: [ "apps" ] + resources: [ "replicasets" ] + verbs: [ "get","list","watch" ] +- apiGroups: [ "cloudwatch.aws.amazon.com" ] + resources: [ "amazoncloudwatchagents", "dcgmexporters", "neuronmonitors" ] + verbs: [ "get","list","patch","update","watch" ] +- apiGroups: [ "cloudwatch.aws.amazon.com" ] + resources: [ "amazoncloudwatchagents/finalizers", "dcgmexporters/finalizers", "neuronmonitors/finalizers" ] + verbs: [ "get","patch","update" ] +- apiGroups: [ "cloudwatch.aws.amazon.com" ] + resources: [ "amazoncloudwatchagents/status", "dcgmexporters/status", "neuronmonitors/status" ] + verbs: [ "get","patch","update" ] +- apiGroups: [ "cloudwatch.aws.amazon.com" ] + resources: [ "instrumentations" ] + verbs: [ "get","list","patch","update","watch" ] +- apiGroups: [ "coordination.k8s.io" ] + resources: [ "leases" ] + verbs: [ "create","get","list","update" ] +- apiGroups: [ "networking.k8s.io" ] + resources: [ "ingresses" ] + verbs: [ "create","delete","get","list","patch","update","watch" ] +- apiGroups: [ "route.openshift.io" ] + resources: [ "routes", "routes/custom-host" ] + verbs: [ "create","delete","get","list","patch","update","watch" ] +- apiGroups: [ "policy" ] + resources: [ "poddisruptionbudgets" ] + verbs: [ "create","delete","get","list","patch","update","watch" ] diff --git a/charts/amazon-cloudwatch-observability/templates/operator-clusterrolebinding.yaml b/charts/amazon-cloudwatch-observability/templates/operator-clusterrolebinding.yaml new file mode 100644 index 0000000..b979f07 --- /dev/null +++ b/charts/amazon-cloudwatch-observability/templates/operator-clusterrolebinding.yaml @@ -0,0 +1,14 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4 }} + name: {{ template "amazon-cloudwatch-observability.name" . }}-manager-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "amazon-cloudwatch-observability.name" . }}-manager-role +subjects: +- kind: ServiceAccount + name: {{ template "amazon-cloudwatch-observability.managerServiceAccountName" . }} + namespace: {{ .Release.Namespace }} diff --git a/charts/amazon-cloudwatch-observability/templates/operator-deployment.yaml b/charts/amazon-cloudwatch-observability/templates/operator-deployment.yaml new file mode 100644 index 0000000..2df8a46 --- /dev/null +++ b/charts/amazon-cloudwatch-observability/templates/operator-deployment.yaml @@ -0,0 +1,78 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4 }} + control-plane: controller-manager + name: {{ template "amazon-cloudwatch-observability.name" . }}-controller-manager + namespace: {{ .Release.Namespace }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + app.kubernetes.io/name: {{ template "amazon-cloudwatch-observability.name" . }} + control-plane: controller-manager + template: + metadata: + annotations: + {{- if .Values.manager.podAnnotations }} + {{- include "amazon-cloudwatch-observability.podAnnotations" . | nindent 8 }} + {{- end }} + {{- if .Values.manager.rolling }} + rollme: {{ randAlphaNum 5 | quote }} + {{- end }} + labels: + app.kubernetes.io/name: {{ template "amazon-cloudwatch-observability.name" . }} + control-plane: controller-manager + {{- include "amazon-cloudwatch-observability.podLabels" . | nindent 8 }} + spec: + containers: + - image: {{ template "cloudwatch-agent-operator.image" . }} + args: + - {{ printf "--auto-instrumentation-config=%s" (dict "java" (merge .Values.manager.autoInstrumentationResources.java .Values.manager.autoInstrumentationConfiguration.java) "python" (merge .Values.manager.autoInstrumentationResources.python .Values.manager.autoInstrumentationConfiguration.python) "dotnet" (merge .Values.manager.autoInstrumentationResources.dotnet .Values.manager.autoInstrumentationConfiguration.dotnet) "nodejs" (.Values.manager.autoInstrumentationResources.nodejs) | toJson) | quote }} + - {{ printf "--auto-annotation-config=%s" (.Values.manager.autoAnnotateAutoInstrumentation | toJson) | quote }} + - {{ printf "--auto-monitor-config=%s" (include "manager.modify-auto-monitor-config" .) | quote }} + - "--auto-instrumentation-java-image={{ template "auto-instrumentation-java.image" . }}" + - "--auto-instrumentation-python-image={{ template "auto-instrumentation-python.image" . }}" + - "--auto-instrumentation-dotnet-image={{ template "auto-instrumentation-dotnet.image" . }}" + - "--auto-instrumentation-nodejs-image={{ template "auto-instrumentation-nodejs.image" . }}" + - "--target-allocator-image={{ template "target-allocator.image" (merge .Values.agent.prometheus.targetAllocator.image (dict "region" $.Values.region)) }}" + - "--feature-gates=operator.autoinstrumentation.multi-instrumentation,operator.autoinstrumentation.multi-instrumentation.skip-container-validation" + command: + - /manager + name: manager + ports: + - containerPort: {{ .Values.manager.ports.containerPort }} + name: webhook-server + protocol: TCP + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + resources: {{ toYaml .Values.manager.resources | nindent 10 }} + volumeMounts: + - mountPath: /tmp/k8s-webhook-server/serving-certs + name: cert + readOnly: true + {{- with .Values.manager.affinity }} + affinity: {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ template "amazon-cloudwatch-observability.managerServiceAccountName" . }} + terminationGracePeriodSeconds: 10 + volumes: + - name: cert + secret: + defaultMode: 420 + secretName: {{ template "amazon-cloudwatch-observability.certificateSecretName" . }} + {{- with .Values.manager.nodeSelector }} + nodeSelector: {{- toYaml . | nindent 8 }} + {{- end }} + {{- dict "component" .Values.manager "context" . | include "amazon-cloudwatch-observability.common.tolerations" | nindent 6 }} diff --git a/charts/amazon-cloudwatch-observability/templates/operator-service.yaml b/charts/amazon-cloudwatch-observability/templates/operator-service.yaml new file mode 100644 index 0000000..03638e3 --- /dev/null +++ b/charts/amazon-cloudwatch-observability/templates/operator-service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4}} + name: {{ template "amazon-cloudwatch-observability.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} +spec: + ports: + - port: 443 + protocol: TCP + targetPort: {{ .Values.manager.ports.containerPort }} + selector: + app.kubernetes.io/name: {{ template "amazon-cloudwatch-observability.name" . }} + control-plane: controller-manager diff --git a/charts/amazon-cloudwatch-observability/templates/operator-serviceaccount.yaml b/charts/amazon-cloudwatch-observability/templates/operator-serviceaccount.yaml new file mode 100644 index 0000000..6c81353 --- /dev/null +++ b/charts/amazon-cloudwatch-observability/templates/operator-serviceaccount.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + {{- include "amazon-cloudwatch-observability.labels" . | nindent 4}} + name: {{ template "amazon-cloudwatch-observability.managerServiceAccountName" . }} + namespace: {{ .Release.Namespace }} diff --git a/charts/amazon-cloudwatch-observability/templates/rosa/cloudwatch-agent-scc-clusterrole.yaml b/charts/amazon-cloudwatch-observability/templates/rosa/cloudwatch-agent-scc-clusterrole.yaml new file mode 100644 index 0000000..1dad2e4 --- /dev/null +++ b/charts/amazon-cloudwatch-observability/templates/rosa/cloudwatch-agent-scc-clusterrole.yaml @@ -0,0 +1,10 @@ +{{ if and .Values.agent.enabled (eq .Values.k8sMode "ROSA") }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: system:openshift:scc:cloudwatch-agent-scc +rules: + - apiGroups: [""] + resources: ["securitycontextconstraints"] + verbs: ["use"] +{{- end }} \ No newline at end of file diff --git a/charts/amazon-cloudwatch-observability/templates/rosa/cloudwatch-agent-scc.yaml b/charts/amazon-cloudwatch-observability/templates/rosa/cloudwatch-agent-scc.yaml new file mode 100644 index 0000000..121e49a --- /dev/null +++ b/charts/amazon-cloudwatch-observability/templates/rosa/cloudwatch-agent-scc.yaml @@ -0,0 +1,38 @@ +{{ if and .Values.agent.enabled (eq .Values.k8sMode "ROSA") }} +apiVersion: security.openshift.io/v1 +kind: SecurityContextConstraints +metadata: + name: cloudwatch-agent-scc +allowHostDirVolumePlugin: true +allowHostIPC: false +allowHostNetwork: true +allowHostPID: false +allowHostPorts: true +allowPrivilegeEscalation: true +allowPrivilegedContainer: true +allowedCapabilities: null +readOnlyRootFilesystem: false +runAsUser: + type: RunAsAny +seLinuxContext: + type: RunAsAny +supplementalGroups: + type: RunAsAny +defaultAddCapabilities: +- SYS_ADMIN +fsGroup: + type: RunAsAny +groups: [] +requiredDropCapabilities: + - ALL +volumes: + - configMap + - emptyDir + - hostPath + - projected + - secret +users: + - system:serviceaccount:{{ .Release.Namespace }}:{{ template "cloudwatch-agent.serviceAccountName" . }} + + +{{ end }} diff --git a/charts/amazon-cloudwatch-observability/templates/rosa/cloudwatch-agent-ssc-clusterrolebinding.yaml b/charts/amazon-cloudwatch-observability/templates/rosa/cloudwatch-agent-ssc-clusterrolebinding.yaml new file mode 100644 index 0000000..0866220 --- /dev/null +++ b/charts/amazon-cloudwatch-observability/templates/rosa/cloudwatch-agent-ssc-clusterrolebinding.yaml @@ -0,0 +1,14 @@ +{{ if and .Values.agent.enabled (eq .Values.k8sMode "ROSA") }} +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "cloudwatch-agent.name" . }}-scc-role-binding +roleRef: + kind: ClusterRole + name: system:openshift:scc:cloudwatch-agent-scc + apiGroup: rbac.authorization.k8s.io +subjects: +- kind: ServiceAccount + name: {{ template "cloudwatch-agent.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} \ No newline at end of file diff --git a/charts/amazon-cloudwatch-observability/templates/target-allocator-clusterrole.yaml b/charts/amazon-cloudwatch-observability/templates/target-allocator-clusterrole.yaml new file mode 100644 index 0000000..951e6e4 --- /dev/null +++ b/charts/amazon-cloudwatch-observability/templates/target-allocator-clusterrole.yaml @@ -0,0 +1,33 @@ +{{- if .Values.agent.enabled }} +{{- range $i, $customAgent := .Values.agents }} +{{- if and (and (hasKey ($customAgent.prometheus) "targetAllocator") (hasKey ($customAgent.prometheus.targetAllocator) "enabled")) $customAgent.prometheus.targetAllocator.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "amazon-cloudwatch-observability.labels" $ | nindent 4}} + name: "cloudwatch-agent-target-allocator-role" +rules: + - apiGroups: [ "" ] + resources: [ "pods", "nodes", "nodes/metrics", "services", "endpoints" ] + verbs: [ "list", "watch", "get" ] + - apiGroups: [ "" ] + resources: [ "configmaps" ] + verbs: [ "get" ] + - apiGroups: ["discovery.k8s.io"] + resources: ["endpointslices"] + verbs: ["get", "list", "watch"] + - apiGroups: [ "networking.k8s.io"] + resources: ["ingresses"] + verbs: ["get", "list", "watch"] + - nonResourceURLs: ["/metrics"] + verbs: ["get"] + {{- if and (hasKey ($customAgent.prometheus.targetAllocator) "prometheusCR") $customAgent.prometheus.targetAllocator.prometheusCR.enabled }} + - apiGroups: [ "monitoring.coreos.com"] + resources: ["podmonitors", "servicemonitors"] + verbs: ["get", "list", "watch"] + {{- end }} +{{- end }} +--- +{{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/amazon-cloudwatch-observability/templates/target-allocator-clusterrolebinding.yaml b/charts/amazon-cloudwatch-observability/templates/target-allocator-clusterrolebinding.yaml new file mode 100644 index 0000000..1356b7a --- /dev/null +++ b/charts/amazon-cloudwatch-observability/templates/target-allocator-clusterrolebinding.yaml @@ -0,0 +1,21 @@ +{{- if .Values.agent.enabled }} +{{- range $i, $customAgent := .Values.agents }} +{{- if and (and (hasKey ($customAgent.prometheus) "targetAllocator") (hasKey ($customAgent.prometheus.targetAllocator) "enabled")) $customAgent.prometheus.targetAllocator.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + {{- include "amazon-cloudwatch-observability.labels" $ | nindent 4 }} + name: "cloudwatch-agent-target-allocator-rolebinding" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: "cloudwatch-agent-target-allocator-role" +subjects: +- kind: ServiceAccount + name: "target-allocator-service-acct" + namespace: {{ $.Release.Namespace }} +{{- end }} +--- +{{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/amazon-cloudwatch-observability/templates/windows/cloudwatch-agent-windows-container-insights-daemonset.yaml b/charts/amazon-cloudwatch-observability/templates/windows/cloudwatch-agent-windows-container-insights-daemonset.yaml new file mode 100644 index 0000000..a578d50 --- /dev/null +++ b/charts/amazon-cloudwatch-observability/templates/windows/cloudwatch-agent-windows-container-insights-daemonset.yaml @@ -0,0 +1,49 @@ +{{- if .Values.agent.enabled }} +{{- $clusterName := .Values.clusterName | required ".Values.clusterName is required." -}} +{{- $region := .Values.region | required ".Values.region is required." -}} +{{- $config := `{"logs":{"metrics_collected":{"kubernetes":{"enhanced_container_insights":true}}}}` | fromJson -}} + +apiVersion: cloudwatch.aws.amazon.com/v1alpha1 +kind: AmazonCloudWatchAgent +metadata: + name: {{ template "cloudwatch-agent.name" . }}-windows-container-insights + namespace: {{ .Release.Namespace }} +spec: + podSecurityContext: + windowsOptions: + hostProcess: true + runAsUserName: "NT AUTHORITY\\System" + hostNetwork: true + image: {{ template "cloudwatch-agent.image" (merge .Values.agent.image (dict "region" .Values.region)) }} + workingDir: "%CONTAINER_SANDBOX_MOUNT_POINT%\\Program Files\\Amazon\\AmazonCloudWatchAgent" + mode: daemonset + serviceAccount: {{ template "cloudwatch-agent.serviceAccountName" . }} + nodeSelector: + kubernetes.io/os: windows + config: {{ include "cloudwatch-agent.modify-config" (merge (dict "Config" $config) .) }} + {{- with .Values.agent.resources }} + resources: {{- toYaml . | nindent 4}} + {{- end }} + env: + - name: K8S_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: HOST_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: K8S_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: RUN_IN_CONTAINER + value: "True" + - name: RUN_AS_HOST_PROCESS_CONTAINER + value: "True" + {{- dict "component" .Values.agent "context" . | include "amazon-cloudwatch-observability.common.tolerations" | nindent 2 }} +{{- end }} \ No newline at end of file diff --git a/charts/amazon-cloudwatch-observability/templates/windows/cloudwatch-agent-windows-daemonset.yaml b/charts/amazon-cloudwatch-observability/templates/windows/cloudwatch-agent-windows-daemonset.yaml new file mode 100644 index 0000000..fd5d1d7 --- /dev/null +++ b/charts/amazon-cloudwatch-observability/templates/windows/cloudwatch-agent-windows-daemonset.yaml @@ -0,0 +1,42 @@ +{{- if .Values.agent.enabled }} +{{- $clusterName := .Values.clusterName | required ".Values.clusterName is required." -}} +{{- $region := .Values.region | required ".Values.region is required." -}} +{{- $config := `{"logs":{"metrics_collected":{"application_signals":{}}},"traces":{"traces_collected":{"application_signals":{}}}}` | fromJson -}} +apiVersion: cloudwatch.aws.amazon.com/v1alpha1 +kind: AmazonCloudWatchAgent +metadata: + name: {{ template "cloudwatch-agent.name" . }}-windows + namespace: {{ .Release.Namespace }} +spec: + podSecurityContext: + windowsOptions: + runAsUserName: "NT AUTHORITY\\System" + image: {{ template "cloudwatch-agent.image" (merge .Values.agent.image (dict "region" .Values.region)) }} + mode: daemonset + serviceAccount: {{ template "cloudwatch-agent.serviceAccountName" . }} + priorityClassName: {{ .Values.agent.priorityClassName }} + nodeSelector: + kubernetes.io/os: windows + config: {{ include "cloudwatch-agent.modify-config" (merge (dict "Config" $config) .) }} + {{- with .Values.agent.resources }} + resources: {{- toYaml . | nindent 4}} + {{- end }} + env: + - name: K8S_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: HOST_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: K8S_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- dict "component" .Values.agent "context" . | include "amazon-cloudwatch-observability.common.tolerations" | nindent 2 }} +{{- end }} \ No newline at end of file diff --git a/charts/amazon-cloudwatch-observability/templates/windows/fluent-bit-windows-configmap.yaml b/charts/amazon-cloudwatch-observability/templates/windows/fluent-bit-windows-configmap.yaml new file mode 100644 index 0000000..40b22f9 --- /dev/null +++ b/charts/amazon-cloudwatch-observability/templates/windows/fluent-bit-windows-configmap.yaml @@ -0,0 +1,21 @@ +{{- if .Values.containerLogs.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: fluent-bit-windows-config + namespace: {{ .Release.Namespace }} + labels: + k8s-app: fluent-bit +data: + fluent-bit.conf: | + {{- .Values.containerLogs.fluentBit.configWindows.service | nindent 4 }} + {{- range $key, $val := .Values.containerLogs.fluentBit.configWindows.extraFiles }} + @INCLUDE {{ $key }} + {{- end }} + parsers.conf: | + {{- .Values.containerLogs.fluentBit.configWindows.customParsers | nindent 4 }} + {{- range $key, $val := .Values.containerLogs.fluentBit.configWindows.extraFiles }} + {{ $key }}: | + {{- (tpl $val $) | nindent 4 }} + {{- end -}} +{{- end -}} \ No newline at end of file diff --git a/charts/amazon-cloudwatch-observability/templates/windows/fluent-bit-windows-daemonset.yaml b/charts/amazon-cloudwatch-observability/templates/windows/fluent-bit-windows-daemonset.yaml new file mode 100644 index 0000000..aa97c65 --- /dev/null +++ b/charts/amazon-cloudwatch-observability/templates/windows/fluent-bit-windows-daemonset.yaml @@ -0,0 +1,75 @@ +{{- if .Values.containerLogs.enabled }} +{{- $clusterName := .Values.clusterName | required ".Values.clusterName is required." -}} +{{- $region := .Values.region | required ".Values.region is required." -}} +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: fluent-bit-windows + namespace: {{ .Release.Namespace }} + labels: + k8s-app: fluent-bit + version: v1 + kubernetes.io/cluster-service: "true" +spec: + selector: + matchLabels: + k8s-app: fluent-bit + template: + metadata: + annotations: + checksum/config: {{ include (print $.Template.BasePath "/windows/fluent-bit-windows-configmap.yaml") . | sha256sum }} + labels: + k8s-app: fluent-bit + version: v1 + kubernetes.io/cluster-service: "true" + spec: + securityContext: + windowsOptions: + hostProcess: true + runAsUserName: "NT AUTHORITY\\System" + hostNetwork: true + priorityClassName: {{ .Values.containerLogs.fluentBit.priorityClassName }} + nodeSelector: + kubernetes.io/os: windows + containers: + - name: fluent-bit + image: {{ template "fluent-bit-windows.image" . }} + imagePullPolicy: Always + command: ["powershell.exe", "-Command", "New-Item -ItemType Directory -Path C:\\var\\fluent-bit\\state -Force;", "%CONTAINER_SANDBOX_MOUNT_POINT%/fluent-bit/bin/fluent-bit.exe", "-e", "%CONTAINER_SANDBOX_MOUNT_POINT%/fluent-bit/kinesis.dll", "-e", "%CONTAINER_SANDBOX_MOUNT_POINT%/fluent-bit/firehose.dll", "-e", "%CONTAINER_SANDBOX_MOUNT_POINT%/fluent-bit/cloudwatch.dll", "-c", "%CONTAINER_SANDBOX_MOUNT_POINT%/fluent-bit/configuration/fluent-bit.conf"] + env: + - name: AWS_REGION + value: {{ .Values.region }} + - name: CLUSTER_NAME + value: {{ .Values.clusterName | quote }} + - name: READ_FROM_HEAD + value: "Off" + - name: HOST_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: HOSTNAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: CI_VERSION + value: "k8s/1.3.17" + {{- with .Values.containerLogs.fluentBit.resources }} + resources: {{- toYaml . | nindent 10}} + {{- end }} + {{- with .Values.containerLogs.fluentBit.securityContext }} + securityContext: + {{- toYaml . | nindent 10}} + {{- end }} + volumeMounts: + - name: fluent-bit-config + mountPath: fluent-bit\configuration\ + volumes: + - name: fluent-bit-config + configMap: + name: fluent-bit-windows-config + terminationGracePeriodSeconds: 10 + dnsPolicy: ClusterFirstWithHostNet + serviceAccountName: {{ template "cloudwatch-agent.serviceAccountName" . }} + {{- dict "component" .Values.containerLogs.fluentBit "context" . | include "amazon-cloudwatch-observability.common.tolerations" | nindent 6 }} +{{- end }} \ No newline at end of file diff --git a/charts/amazon-cloudwatch-observability/tests/flag_matrix.sh b/charts/amazon-cloudwatch-observability/tests/flag_matrix.sh new file mode 100644 index 0000000..cadf174 --- /dev/null +++ b/charts/amazon-cloudwatch-observability/tests/flag_matrix.sh @@ -0,0 +1,190 @@ +#!/usr/bin/env bash +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: MIT +# +# Validates the 3-flag OTEL CI gating matrix by exhaustively rendering +# `helm template` across all 8 combinations of: +# +# otelContainerInsights.enabled +# otelContainerInsights.logs.enabled +# containerLogs.enabled +# +# This is a template-level test — it does not deploy anything to a real cluster. +# Minikube integration tests cover deployment; this script fills the gap for: +# (a) testing all 8 combinations quickly without minikube +# (b) asserting correct fragment presence/absence for each state +# +# Run from the repo root: +# bash charts/amazon-cloudwatch-observability/tests/flag_matrix.sh + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +CHART_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)" + +# Colors for readable output. +R='\033[0;31m' +G='\033[0;32m' +Y='\033[1;33m' +N='\033[0m' + +pass_count=0 +fail_count=0 + +# ────────────────────────────────────────────────────────────────────────── +# run_case — render helm with the given flags and verify expected behavior. +# +# Arguments: +# $1 case number (for output) +# $2 otelContainerInsights.enabled (true|false) +# $3 otelContainerInsights.logs.enabled (true|false) +# $4 containerLogs.enabled (true|false) +# $5 expected outcome: "ok" (renders successfully) +# $6 description shown in output +# Optional args (only checked when $5 == "ok"): +# $7 comma-separated list of fragments that MUST be present in output +# $8 comma-separated list of fragments that MUST NOT be present in output +# ────────────────────────────────────────────────────────────────────────── +run_case() { + local num="$1" enabled="$2" logs="$3" fb="$4" expected="$5" desc="$6" + local must_have="${7:-}" must_not="${8:-}" + + printf "\n${Y}[State #%s]${N} enabled=%s logs=%s containerLogs=%s — %s\n" \ + "$num" "$enabled" "$logs" "$fb" "$desc" + + local output exit_code + output=$(helm template "$CHART_DIR" \ + --set region=us-west-2 \ + --set clusterName=test-cluster \ + --set "otelContainerInsights.enabled=$enabled" \ + --set "otelContainerInsights.logs.enabled=$logs" \ + --set "containerLogs.enabled=$fb" 2>&1) && exit_code=0 || exit_code=$? + + if [[ "$expected" == "fail" ]]; then + if [[ $exit_code -eq 0 ]]; then + echo -e " ${R}FAIL${N}: expected helm template to fail, but it succeeded" + fail_count=$((fail_count + 1)) + return + fi + echo -e " ${G}PASS${N}: helm template failed as expected" + pass_count=$((pass_count + 1)) + return + fi + + # Expected success path. + if [[ $exit_code -ne 0 ]]; then + echo -e " ${R}FAIL${N}: helm template failed unexpectedly" + echo "$output" | tail -5 | sed 's/^/ /' + fail_count=$((fail_count + 1)) + return + fi + + local local_fail=0 + + if [[ -n "$must_have" ]]; then + IFS=',' read -ra fragments <<< "$must_have" + for f in "${fragments[@]}"; do + if ! grep -q "$f" <<< "$output"; then + echo -e " ${R}FAIL${N}: missing required fragment: $f" + local_fail=1 + fi + done + fi + + if [[ -n "$must_not" ]]; then + IFS=',' read -ra fragments <<< "$must_not" + for f in "${fragments[@]}"; do + if grep -q "$f" <<< "$output"; then + echo -e " ${R}FAIL${N}: forbidden fragment present: $f" + local_fail=1 + fi + done + fi + + if [[ $local_fail -eq 0 ]]; then + echo -e " ${G}PASS${N}" + pass_count=$((pass_count + 1)) + else + fail_count=$((fail_count + 1)) + fi +} + +# Fragment shortcuts used across states. +METRICS_EXPORTER="otlphttp/cw_k8s_ci_v0_metrics_dest" +METRICS_SIGV4="sigv4auth/cw_k8s_ci_v0_metrics_dest" +LOG_EXPORTER_APP="otlphttp/cw_k8s_ci_v0_app_logs_dest" +LOG_EXPORTER_NODE="otlphttp/cw_k8s_ci_v0_node_logs_dest" +LOG_SIGV4="sigv4auth/cw_k8s_ci_v0_logs_dest" +LOG_PIPELINE_APP="logs/cw_k8s_ci_v0_app" +FILELOG_APP="filelog/cw_k8s_ci_v0_app" +# aws-for-fluent-bit is the container image string — unique to the FluentBit +# DaemonSet. Using this instead of bare "fluent-bit" avoids false matches in +# OTEL config paths like /var/log/containers/fluent-bit* (which exist in the +# filelog exclude list regardless of the FB DaemonSet flag). +FLUENT_BIT_IMAGE="aws-for-fluent-bit" + +# All OTEL log pipeline fragments (app + host). +ALL_LOG_FRAGMENTS="$LOG_EXPORTER_APP,$LOG_EXPORTER_NODE,$LOG_SIGV4,$LOG_PIPELINE_APP,$FILELOG_APP" + +# ────────────────────────────────────────────────────────────────────────── +# Run all 8 combinations. +# ────────────────────────────────────────────────────────────────────────── + +echo "=== OTEL CI flag gating matrix ===" +echo "Chart: $CHART_DIR" + +# State #1: all false — no monitoring. +run_case 1 false false false "ok" \ + "No monitoring — all flags off" \ + "" "$METRICS_EXPORTER,$FLUENT_BIT_IMAGE" + +# State #2: FluentBit only (pure v1 legacy). +run_case 2 false false true "ok" \ + "FluentBit legacy only" \ + "$FLUENT_BIT_IMAGE" "$METRICS_EXPORTER,$ALL_LOG_FRAGMENTS" + +# State #3: logs=true without enabled — silently ignored. +run_case 3 false true false "ok" \ + "logs=true without enabled — no OTEL output" \ + "" "$METRICS_EXPORTER,$ALL_LOG_FRAGMENTS,$FLUENT_BIT_IMAGE" + +# State #4: same as #3 with FluentBit. +run_case 4 false true true "ok" \ + "logs=true without enabled + FluentBit — only FluentBit" \ + "$FLUENT_BIT_IMAGE" "$METRICS_EXPORTER,$ALL_LOG_FRAGMENTS" + +# State #5: OTEL metrics only. +run_case 5 true false false "ok" \ + "OTEL metrics only, no logs" \ + "$METRICS_EXPORTER,$METRICS_SIGV4" "$ALL_LOG_FRAGMENTS,$FLUENT_BIT_IMAGE" + +# State #6: hybrid — OTEL metrics + FluentBit logs. +run_case 6 true false true "ok" \ + "Hybrid — OTEL metrics + FluentBit logs" \ + "$METRICS_EXPORTER,$METRICS_SIGV4,$FLUENT_BIT_IMAGE" "$ALL_LOG_FRAGMENTS" + +# State #7: full OTEL (metrics + logs, no FluentBit). +run_case 7 true true false "ok" \ + "Full OTEL (metrics + logs)" \ + "$METRICS_EXPORTER,$METRICS_SIGV4,$LOG_EXPORTER_APP,$LOG_EXPORTER_NODE,$LOG_SIGV4,$FILELOG_APP" \ + "$FLUENT_BIT_IMAGE" + +# State #8: dual-publish (migration window — OTEL logs + FluentBit both active). +run_case 8 true true true "ok" \ + "Dual-publish — OTEL logs + FluentBit both active" \ + "$METRICS_EXPORTER,$LOG_EXPORTER_APP,$LOG_EXPORTER_NODE,$FILELOG_APP,$FLUENT_BIT_IMAGE" \ + "" + +# ────────────────────────────────────────────────────────────────────────── +# Summary. +# ────────────────────────────────────────────────────────────────────────── +total=$((pass_count + fail_count)) +echo "" +echo "=== Summary ===" +if [[ $fail_count -eq 0 ]]; then + echo -e "${G}All $total cases passed.${N}" + exit 0 +else + echo -e "${R}$fail_count of $total cases failed.${N}" + exit 1 +fi diff --git a/charts/amazon-cloudwatch-observability/values.yaml b/charts/amazon-cloudwatch-observability/values.yaml new file mode 100644 index 0000000..fa44b4d --- /dev/null +++ b/charts/amazon-cloudwatch-observability/values.yaml @@ -0,0 +1,1156 @@ +# Default values for amazon-cloudwatch-observability. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + + +## Passed in via the infrastructure.yaml file as required parameters +roleArn: "" +clusterName: "" +region: "" + +replicaCount: 1 +## Provide a name in place of cloudwatchagent-operator. +## +nameOverride: "" +## Provide the ClusterName (this is a required parameter) +#clusterName: +# Endpoint overrides for isolated regions (commercial regions defaults to empty) the front will have logs.${REGION} +adcEndpointOverrides: + us-iso-east-1: c2s.ic.gov + us-iso-west-1: c2s.ic.gov + us-isob-east-1: sc2s.sgov.gov + us-isof-south-1: csp.hci.ic.gov + eu-isoe-west-1: cloud.adc-e.uk + eusc-de-east-1: amazonaws.eu +k8sMode: ROSA # can be EKS | ROSA | K8S +## Enable dualstack endpoints for IPv6 support (default: false) +useDualstackEndpoint: false +## Provide default tolerations +tolerations: + - operator: Exists +containerLogs: + enabled: true + fluentBit: + image: + repository: aws-for-fluent-bit + tag: 3.4.0 + tagWindows: 2.31.12-windowsservercore + repositoryDomainMap: + public: public.ecr.aws/aws-observability + cn-north-1: 128054284489.dkr.ecr.cn-north-1.amazonaws.com.cn + cn-northwest-1: 128054284489.dkr.ecr.cn-northwest-1.amazonaws.com.cn + us-gov-east-1: 161423150738.dkr.ecr.us-gov-east-1.amazonaws.com + us-gov-west-1: 161423150738.dkr.ecr.us-gov-west-1.amazonaws.com + securityContext: {} + resources: + limits: + cpu: 500m + memory: 250Mi + requests: + cpu: 50m + memory: 25Mi + ## Override root tolerations + # tolerations: [] + priorityClassName: system-node-critical + updateStrategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 1 + maxSurge: 0 + config: + service: | + [SERVICE] + Flush 5 + Grace 30 + Log_Level error + Daemon off + Parsers_File parsers.conf + storage.path /var/fluent-bit/state/flb-storage/ + storage.sync normal + storage.checksum off + storage.backlog.mem_limit 5M + customParsers: | + [PARSER] + Name syslog + Format regex + Regex ^(?