diff --git a/README.md b/README.md index d423e9a..c62970f 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,12 @@ Then, apply the Kubernetes manifests directly from this repo: kubectl kustomize https://github.com/GoogleCloudPlatform/otlp-k8s-ingest/k8s/base | envsubst | kubectl apply -f - ``` +If the prefer way is DaemonSet instead of Deployment, apply the following mainfests + +```console +kubectl kustomize https://github.com/GoogleCloudPlatform/otlp-k8s-ingest/k8s/daemonset | envsubst | kubectl apply -f - +``` + (Remember to set the `GOOGLE_CLOUD_PROJECT` environment variable.) ### [Optional] Run the OpenTelemetry demo application alongside the collector diff --git a/k8s/base/3_service.yaml b/k8s/base/3_service.yaml index db5b668..b60993d 100644 --- a/k8s/base/3_service.yaml +++ b/k8s/base/3_service.yaml @@ -24,6 +24,7 @@ spec: selector: app: opentelemetry-collector internalTrafficPolicy: Cluster + trafficDistribution: PreferClose ports: - name: otel-grpc protocol: TCP diff --git a/k8s/base/4_deployment.yaml b/k8s/base/4_deployment.yaml index 01a3866..6cc0e3e 100644 --- a/k8s/base/4_deployment.yaml +++ b/k8s/base/4_deployment.yaml @@ -20,7 +20,7 @@ metadata: labels: app: opentelemetry-collector spec: - replicas: 2 + replicas: 1 selector: matchLabels: app: opentelemetry-collector @@ -32,6 +32,13 @@ spec: serviceAccountName: opentelemetry-collector securityContext: {} + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: DoNotSchedule + labelSelector: + matchLabels: + app: opentelemetry-collector containers: - name: opentelemetry-collector imagePullPolicy: Always diff --git a/k8s/daemonset/0_namespace.yaml b/k8s/daemonset/0_namespace.yaml new file mode 100644 index 0000000..43f7f78 --- /dev/null +++ b/k8s/daemonset/0_namespace.yaml @@ -0,0 +1,18 @@ +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: v1 +kind: Namespace +metadata: + name: opentelemetry diff --git a/k8s/daemonset/1_configmap.yaml b/k8s/daemonset/1_configmap.yaml new file mode 100644 index 0000000..c8758ce --- /dev/null +++ b/k8s/daemonset/1_configmap.yaml @@ -0,0 +1,234 @@ +apiVersion: v1 +data: + collector.yaml: | + # Copyright 2024 Google LLC + # + # Licensed under the Apache License, Version 2.0 (the "License"); + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + + exporters: + googlecloud: + log: + default_log_name: opentelemetry-collector + user_agent: Google-Cloud-OTLP manifests:0.5.0 OpenTelemetry Collector Built By Google/0.131.0 (linux/amd64) + googlemanagedprometheus: + user_agent: Google-Cloud-OTLP manifests:0.5.0 OpenTelemetry Collector Built By Google/0.131.0 (linux/amd64) + # The otlphttp exporter is used to send traces to Google Cloud Trace using OTLP http/proto + # The otlp exporter could also be used to send them using OTLP grpc + otlphttp: + encoding: proto + endpoint: https://telemetry.googleapis.com + # Use the googleclientauth extension to authenticate with Google credentials + auth: + authenticator: googleclientauth + + + extensions: + health_check: + endpoint: ${env:MY_POD_IP}:13133 + googleclientauth: + + + processors: + filter/self-metrics: + metrics: + include: + match_type: strict + metric_names: + - otelcol_process_uptime + - otelcol_process_memory_rss + - otelcol_grpc_io_client_completed_rpcs + - otelcol_googlecloudmonitoring_point_count + batch: + send_batch_max_size: 200 + send_batch_size: 200 + timeout: 5s + + k8sattributes: + filter: + node_from_env_var: KUBE_NODE_NAME + extract: + metadata: + - k8s.namespace.name + - k8s.deployment.name + - k8s.statefulset.name + - k8s.daemonset.name + - k8s.cronjob.name + - k8s.job.name + - k8s.replicaset.name + - k8s.node.name + - k8s.pod.name + - k8s.pod.uid + - k8s.pod.start_time + passthrough: false + pod_association: + - sources: + - from: resource_attribute + name: k8s.pod.ip + - sources: + - from: resource_attribute + name: k8s.pod.uid + - sources: + - from: connection + + memory_limiter: + check_interval: 1s + limit_percentage: 65 + spike_limit_percentage: 20 + + metricstransform/self-metrics: + transforms: + - action: update + include: otelcol_process_uptime + operations: + - action: add_label + new_label: version + new_value: Google-Cloud-OTLP manifests:0.5.0 OpenTelemetry Collector Built By Google/0.131.0 (linux/amd64) + + resourcedetection: + detectors: [gcp] + timeout: 10s + + transform/collision: + metric_statements: + - context: datapoint + statements: + - set(attributes["exported_location"], attributes["location"]) + - delete_key(attributes, "location") + - set(attributes["exported_cluster"], attributes["cluster"]) + - delete_key(attributes, "cluster") + - set(attributes["exported_namespace"], attributes["namespace"]) + - delete_key(attributes, "namespace") + - set(attributes["exported_job"], attributes["job"]) + - delete_key(attributes, "job") + - set(attributes["exported_instance"], attributes["instance"]) + - delete_key(attributes, "instance") + - set(attributes["exported_project_id"], attributes["project_id"]) + - delete_key(attributes, "project_id") + + # The relative ordering of statements between ReplicaSet & Deployment and Job & CronJob are important. + # The ordering of these controllers is decided based on the k8s controller documentation available at + # https://kubernetes.io/docs/concepts/workloads/controllers. + # The relative ordering of the other controllers in this list is inconsequential since they directly + # create pods. + transform/aco-gke: + metric_statements: + - context: datapoint + statements: + - set(attributes["top_level_controller_type"], "ReplicaSet") where resource.attributes["k8s.replicaset.name"] != nil + - set(attributes["top_level_controller_name"], resource.attributes["k8s.replicaset.name"]) where resource.attributes["k8s.replicaset.name"] != nil + - set(attributes["top_level_controller_type"], "Deployment") where resource.attributes["k8s.deployment.name"] != nil + - set(attributes["top_level_controller_name"], resource.attributes["k8s.deployment.name"]) where resource.attributes["k8s.deployment.name"] != nil + - set(attributes["top_level_controller_type"], "DaemonSet") where resource.attributes["k8s.daemonset.name"] != nil + - set(attributes["top_level_controller_name"], resource.attributes["k8s.daemonset.name"]) where resource.attributes["k8s.daemonset.name"] != nil + - set(attributes["top_level_controller_type"], "StatefulSet") where resource.attributes["k8s.statefulset.name"] != nil + - set(attributes["top_level_controller_name"], resource.attributes["k8s.statefulset.name"]) where resource.attributes["k8s.statefulset.name"] != nil + - set(attributes["top_level_controller_type"], "Job") where resource.attributes["k8s.job.name"] != nil + - set(attributes["top_level_controller_name"], resource.attributes["k8s.job.name"]) where resource.attributes["k8s.job.name"] != nil + - set(attributes["top_level_controller_type"], "CronJob") where resource.attributes["k8s.cronjob.name"] != nil + - set(attributes["top_level_controller_name"], resource.attributes["k8s.cronjob.name"]) where resource.attributes["k8s.cronjob.name"] != nil + + # When sending telemetry to the GCP OTLP endpoint, the gcp.project_id resource attribute is required to be set to your project ID. + resource/gcp_project_id: + attributes: + - key: gcp.project_id + # MAKE SURE YOU REPLACE THIS WITH YOUR PROJECT ID + value: ${GOOGLE_CLOUD_PROJECT} + action: insert + # The metricstarttime processor is important to include if you are using the prometheus receiver to ensure the start time is set properly. + # It is a no-op otherwise. + metricstarttime: + strategy: subtract_initial_point + + receivers: + # This collector is configured to accept OTLP metrics, logs, and traces, and is designed to receive OTLP from workloads running in the cluster. + otlp: + protocols: + grpc: + endpoint: ${env:MY_POD_IP}:4317 + http: + cors: + allowed_origins: + - http://* + - https://* + endpoint: ${env:MY_POD_IP}:4318 + otlp/self-metrics: + protocols: + grpc: + endpoint: ${env:MY_POD_IP}:14317 + + service: + extensions: + - health_check + - googleclientauth + pipelines: + logs: + exporters: + - googlecloud + processors: + - k8sattributes + - resourcedetection + - memory_limiter + - batch + receivers: + - otlp + metrics/otlp: + exporters: + - googlemanagedprometheus + processors: + - k8sattributes + - memory_limiter + - metricstarttime + - resourcedetection + - transform/collision + - transform/aco-gke + - batch + receivers: + - otlp + metrics/self-metrics: + exporters: + - googlemanagedprometheus + processors: + - filter/self-metrics + - metricstransform/self-metrics + - k8sattributes + - memory_limiter + - resourcedetection + - batch + receivers: + - otlp/self-metrics + traces: + exporters: + - otlphttp + processors: + - k8sattributes + - memory_limiter + - resource/gcp_project_id + - resourcedetection + - batch + receivers: + - otlp + telemetry: + logs: + encoding: json + metrics: + readers: + - periodic: + exporter: + otlp: + protocol: grpc + endpoint: ${env:MY_POD_IP}:14317 +kind: ConfigMap +metadata: + creationTimestamp: null + name: collector-config + namespace: opentelemetry diff --git a/k8s/daemonset/2_rbac.yaml b/k8s/daemonset/2_rbac.yaml new file mode 100644 index 0000000..5d451da --- /dev/null +++ b/k8s/daemonset/2_rbac.yaml @@ -0,0 +1,57 @@ +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: v1 +kind: ServiceAccount +metadata: + name: opentelemetry-collector + namespace: opentelemetry + labels: + app.kubernetes.io/name: google-built-opentelemetry-collector + app.kubernetes.io/version: "0.131.0" +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: opentelemetry-collector + namespace: opentelemetry + labels: + app.kubernetes.io/name: google-built-opentelemetry-collector + app.kubernetes.io/version: "0.131.0" +rules: + - apiGroups: [""] + resources: ["pods", "namespaces", "nodes"] + verbs: ["get", "watch", "list"] + - apiGroups: ["apps"] + resources: ["replicasets"] + verbs: ["get", "list", "watch"] + - apiGroups: ["extensions"] + resources: ["replicasets"] + verbs: ["get", "list", "watch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: opentelemetry-collector + labels: + app.kubernetes.io/name: google-built-opentelemetry-collector + app.kubernetes.io/version: "0.131.0" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: opentelemetry-collector +subjects: + - kind: ServiceAccount + name: opentelemetry-collector + namespace: opentelemetry diff --git a/k8s/daemonset/3_service.yaml b/k8s/daemonset/3_service.yaml new file mode 100644 index 0000000..a158053 --- /dev/null +++ b/k8s/daemonset/3_service.yaml @@ -0,0 +1,36 @@ +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: v1 +kind: Service +metadata: + name: opentelemetry-collector + namespace: opentelemetry + labels: + app: opentelemetry-collector +spec: + type: ClusterIP + selector: + app: opentelemetry-collector + internalTrafficPolicy: Cluster + trafficDistribution: PreferClose + ports: + - name: otel-grpc + protocol: TCP + port: 4317 + targetPort: 4317 + - name: otlp-http + port: 4318 + targetPort: 4318 + protocol: TCP diff --git a/k8s/daemonset/4_daemonset.yaml b/k8s/daemonset/4_daemonset.yaml new file mode 100644 index 0000000..f161104 --- /dev/null +++ b/k8s/daemonset/4_daemonset.yaml @@ -0,0 +1,78 @@ +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: opentelemetry-collector + namespace: opentelemetry + labels: + app: opentelemetry-collector +spec: + selector: + matchLabels: + app: opentelemetry-collector + template: + metadata: + labels: + app: opentelemetry-collector + spec: + serviceAccountName: opentelemetry-collector + securityContext: + {} + containers: + - name: opentelemetry-collector + imagePullPolicy: Always + image: us-docker.pkg.dev/cloud-ops-agents-artifacts/google-cloud-opentelemetry-collector/otelcol-google:0.131.0 + args: + - "--config=/conf/collector.yaml" + - "--feature-gates=exporter.googlemanagedprometheus.intToDouble,receiver.prometheusreceiver.RemoveStartTimeAdjustment" + ports: + - name: otlp-grpc + containerPort: 4317 + protocol: TCP + - name: otlp-http + containerPort: 4318 + protocol: TCP + env: + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + - name: MY_POD_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP + resources: + requests: + memory: "200Mi" + cpu: "200m" + limits: + memory: "400Mi" + volumeMounts: + - name: collector-config + mountPath: /conf + readinessProbe: + httpGet: + path: / + port: 13133 + volumes: + - name: collector-config + configMap: + name: collector-config + items: + - key: collector.yaml + path: collector.yaml diff --git a/k8s/daemonset/kustomization.yml b/k8s/daemonset/kustomization.yml new file mode 100644 index 0000000..598671b --- /dev/null +++ b/k8s/daemonset/kustomization.yml @@ -0,0 +1,23 @@ +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - 0_namespace.yaml + - 1_configmap.yaml + - 2_rbac.yaml + - 3_service.yaml + - 4_daemonset.yaml + diff --git a/k8s/overlays/high-availability/configmap-patch.yaml b/k8s/overlays/high-availability/configmap-patch.yaml new file mode 100644 index 0000000..f123e69 --- /dev/null +++ b/k8s/overlays/high-availability/configmap-patch.yaml @@ -0,0 +1,237 @@ +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: v1 +kind: ConfigMap +metadata: + name: collector-config + namespace: opentelemetry +data: + collector.yaml: | + # Copyright 2024 Google LLC + # + # Licensed under the Apache License, Version 2.0 (the "License"); + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + + exporters: + googlecloud: + log: + default_log_name: opentelemetry-collector + user_agent: Google-Cloud-OTLP manifests:0.5.0 OpenTelemetry Collector Built By Google/0.131.0 (linux/amd64) + googlemanagedprometheus: + user_agent: Google-Cloud-OTLP manifests:0.5.0 OpenTelemetry Collector Built By Google/0.131.0 (linux/amd64) + # The otlphttp exporter is used to send traces to Google Cloud Trace using OTLP http/proto + # The otlp exporter could also be used to send them using OTLP grpc + otlphttp: + encoding: proto + endpoint: https://telemetry.googleapis.com + # Use the googleclientauth extension to authenticate with Google credentials + auth: + authenticator: googleclientauth + + + extensions: + health_check: + endpoint: ${env:MY_POD_IP}:13133 + googleclientauth: + + + processors: + filter/self-metrics: + metrics: + include: + match_type: strict + metric_names: + - otelcol_process_uptime + - otelcol_process_memory_rss + - otelcol_grpc_io_client_completed_rpcs + - otelcol_googlecloudmonitoring_point_count + batch: + send_batch_max_size: 200 + send_batch_size: 200 + timeout: 5s + + k8sattributes: + extract: + metadata: + - k8s.namespace.name + - k8s.deployment.name + - k8s.statefulset.name + - k8s.daemonset.name + - k8s.cronjob.name + - k8s.job.name + - k8s.replicaset.name + - k8s.node.name + - k8s.pod.name + - k8s.pod.uid + - k8s.pod.start_time + filter: + node_from_env_var: KUBE_NODE_NAME + passthrough: false + pod_association: + - sources: + - from: resource_attribute + name: k8s.pod.ip + - sources: + - from: resource_attribute + name: k8s.pod.uid + - sources: + - from: connection + + memory_limiter: + check_interval: 1s + limit_percentage: 65 + spike_limit_percentage: 20 + + metricstransform/self-metrics: + transforms: + - action: update + include: otelcol_process_uptime + operations: + - action: add_label + new_label: version + new_value: Google-Cloud-OTLP manifests:0.5.0 OpenTelemetry Collector Built By Google/0.131.0 (linux/amd64) + + resourcedetection: + detectors: [gcp] + timeout: 10s + + transform/collision: + metric_statements: + - context: datapoint + statements: + - set(attributes["exported_location"], attributes["location"]) + - delete_key(attributes, "location") + - set(attributes["exported_cluster"], attributes["cluster"]) + - delete_key(attributes, "cluster") + - set(attributes["exported_namespace"], attributes["namespace"]) + - delete_key(attributes, "namespace") + - set(attributes["exported_job"], attributes["job"]) + - delete_key(attributes, "job") + - set(attributes["exported_instance"], attributes["instance"]) + - delete_key(attributes, "instance") + - set(attributes["exported_project_id"], attributes["project_id"]) + - delete_key(attributes, "project_id") + + # The relative ordering of statements between ReplicaSet & Deployment and Job & CronJob are important. + # The ordering of these controllers is decided based on the k8s controller documentation available at + # https://kubernetes.io/docs/concepts/workloads/controllers. + # The relative ordering of the other controllers in this list is inconsequential since they directly + # create pods. + transform/aco-gke: + metric_statements: + - context: datapoint + statements: + - set(attributes["top_level_controller_type"], "ReplicaSet") where resource.attributes["k8s.replicaset.name"] != nil + - set(attributes["top_level_controller_name"], resource.attributes["k8s.replicaset.name"]) where resource.attributes["k8s.replicaset.name"] != nil + - set(attributes["top_level_controller_type"], "Deployment") where resource.attributes["k8s.deployment.name"] != nil + - set(attributes["top_level_controller_name"], resource.attributes["k8s.deployment.name"]) where resource.attributes["k8s.deployment.name"] != nil + - set(attributes["top_level_controller_type"], "DaemonSet") where resource.attributes["k8s.daemonset.name"] != nil + - set(attributes["top_level_controller_name"], resource.attributes["k8s.daemonset.name"]) where resource.attributes["k8s.daemonset.name"] != nil + - set(attributes["top_level_controller_type"], "StatefulSet") where resource.attributes["k8s.statefulset.name"] != nil + - set(attributes["top_level_controller_name"], resource.attributes["k8s.statefulset.name"]) where resource.attributes["k8s.statefulset.name"] != nil + - set(attributes["top_level_controller_type"], "Job") where resource.attributes["k8s.job.name"] != nil + - set(attributes["top_level_controller_name"], resource.attributes["k8s.job.name"]) where resource.attributes["k8s.job.name"] != nil + - set(attributes["top_level_controller_type"], "CronJob") where resource.attributes["k8s.cronjob.name"] != nil + - set(attributes["top_level_controller_name"], resource.attributes["k8s.cronjob.name"]) where resource.attributes["k8s.cronjob.name"] != nil + + # When sending telemetry to the GCP OTLP endpoint, the gcp.project_id resource attribute is required to be set to your project ID. + resource/gcp_project_id: + attributes: + - key: gcp.project_id + # MAKE SURE YOU REPLACE THIS WITH YOUR PROJECT ID + value: ${GOOGLE_CLOUD_PROJECT} + action: insert + # The metricstarttime processor is important to include if you are using the prometheus receiver to ensure the start time is set properly. + # It is a no-op otherwise. + metricstarttime: + strategy: subtract_initial_point + + receivers: + # This collector is configured to accept OTLP metrics, logs, and traces, and is designed to receive OTLP from workloads running in the cluster. + otlp: + protocols: + grpc: + endpoint: ${env:MY_POD_IP}:4317 + http: + cors: + allowed_origins: + - http://* + - https://* + endpoint: ${env:MY_POD_IP}:4318 + otlp/self-metrics: + protocols: + grpc: + endpoint: ${env:MY_POD_IP}:14317 + + service: + extensions: + - health_check + - googleclientauth + pipelines: + metrics/otlp: + exporters: + - googlemanagedprometheus + processors: + - k8sattributes + - memory_limiter + - metricstarttime + - resourcedetection + - transform/collision + - transform/aco-gke + - batch + receivers: + - otlp + metrics/self-metrics: + exporters: + - googlemanagedprometheus + processors: + - filter/self-metrics + - metricstransform/self-metrics + - k8sattributes + - memory_limiter + - resourcedetection + - batch + receivers: + - otlp/self-metrics + traces: + exporters: + - otlphttp + processors: + - k8sattributes + - memory_limiter + - resource/gcp_project_id + - resourcedetection + - batch + receivers: + - otlp + telemetry: + logs: + encoding: json + metrics: + readers: + - periodic: + exporter: + otlp: + protocol: grpc + endpoint: ${env:MY_POD_IP}:14317 \ No newline at end of file diff --git a/k8s/overlays/high-availability/deployment-patch.yaml b/k8s/overlays/high-availability/deployment-patch.yaml new file mode 100644 index 0000000..e6a85eb --- /dev/null +++ b/k8s/overlays/high-availability/deployment-patch.yaml @@ -0,0 +1,68 @@ +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: opentelemetry-collector + namespace: opentelemetry +spec: + replicas: 2 + template: + metadata: + labels: + app: opentelemetry-collector + topology.kubernetes.io/zone-aware-routing: "enabled" + spec: + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: DoNotSchedule + labelSelector: + matchLabels: + app: opentelemetry-collector + - maxSkew: 1 + topologyKey: kubernetes.io/hostname + whenUnsatisfiable: ScheduleAnyway + labelSelector: + matchLabels: + app: opentelemetry-collector + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchLabels: + app: opentelemetry-collector + topologyKey: topology.kubernetes.io/zone + - weight: 50 + podAffinityTerm: + labelSelector: + matchLabels: + app: opentelemetry-collector + topologyKey: kubernetes.io/hostname + containers: + - name: opentelemetry-collector + env: + - name: MY_POD_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName \ No newline at end of file diff --git a/k8s/overlays/high-availability/hpa-patch.yaml b/k8s/overlays/high-availability/hpa-patch.yaml new file mode 100644 index 0000000..4522e06 --- /dev/null +++ b/k8s/overlays/high-availability/hpa-patch.yaml @@ -0,0 +1,53 @@ +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: opentelemetry-collector + namespace: opentelemetry +spec: + minReplicas: 2 + maxReplicas: 10 + metrics: + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: 80 + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 80 + behavior: + scaleDown: + policies: + - type: Pods + value: 1 + periodSeconds: 60 + stabilizationWindowSeconds: 300 + selectPolicy: Min + scaleUp: + policies: + - type: Percent + value: 100 + periodSeconds: 15 + - type: Pods + value: 2 + periodSeconds: 15 + selectPolicy: Max + stabilizationWindowSeconds: 0 \ No newline at end of file diff --git a/k8s/overlays/high-availability/kustomization.yaml b/k8s/overlays/high-availability/kustomization.yaml new file mode 100644 index 0000000..375f7f6 --- /dev/null +++ b/k8s/overlays/high-availability/kustomization.yaml @@ -0,0 +1,33 @@ +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +# High-availability overlay with: +# - 2 replicas minimum +# - Node name tracking via KUBE_NODE_NAME env var +# - Zone-aware pod distribution with topology spread constraints +# - Zone-aware traffic routing (prefer same zone) +# - Pod anti-affinity for better distribution + +resources: + - ../../base + +patches: + - path: deployment-patch.yaml + - path: hpa-patch.yaml + - path: configmap-patch.yaml + +