From 31b9533eb163442af8a25c200315dc880cf0ba71 Mon Sep 17 00:00:00 2001 From: Evgenii Gordymov Date: Tue, 25 Oct 2022 20:42:25 +0400 Subject: .........T [ZBX-21588] optimized template k8s nodes by http --- ChangeLog.d/feature/ZBX-21588 | 1 + .../kubernetes_nodes_http/README.md | 80 +++++---- .../template_kubernetes_nodes.yaml | 199 ++++++++++++++------- 3 files changed, 172 insertions(+), 108 deletions(-) create mode 100644 ChangeLog.d/feature/ZBX-21588 diff --git a/ChangeLog.d/feature/ZBX-21588 b/ChangeLog.d/feature/ZBX-21588 new file mode 100644 index 00000000000..f0f2aa394d9 --- /dev/null +++ b/ChangeLog.d/feature/ZBX-21588 @@ -0,0 +1 @@ +.........T [ZBX-21588] optimized template k8s nodes by http (egordymov) diff --git a/templates/app/kubernetes_http/kubernetes_nodes_http/README.md b/templates/app/kubernetes_http/kubernetes_nodes_http/README.md index 76f85c4ef2e..7060c5c1acc 100644 --- a/templates/app/kubernetes_http/kubernetes_nodes_http/README.md +++ b/templates/app/kubernetes_http/kubernetes_nodes_http/README.md @@ -3,10 +3,10 @@ ## Overview -For Zabbix version: 6.4 and higher +For Zabbix version: 6.4 and higher. The template to monitor Kubernetes nodes that work without any external scripts. It works without external scripts and uses the script item to make HTTP requests to the Kubernetes API. -Install the Zabbix Helm Chart (https://git.zabbix.com/projects/ZT/repos/kubernetes-helm/browse?at=refs%2Fheads%2Frelease%2F6.0) in your Kubernetes cluster. +Install the Zabbix Helm Chart (https://git.zabbix.com/projects/ZT/repos/kubernetes-helm/browse) in your Kubernetes cluster. Set the `{$KUBE.API.ENDPOINT.URL}` such as `://:/api`. @@ -27,7 +27,7 @@ This template was tested on: > See [Zabbix template operation](https://www.zabbix.com/documentation/6.4/manual/config/templates_out_of_the_box/http) for basic instructions. -Install the [Zabbix Helm Chart](https://git.zabbix.com/projects/ZT/repos/kubernetes-helm/browse?at=refs%2Fheads%2Fmaster) in your Kubernetes cluster. +Install the [Zabbix Helm Chart](https://git.zabbix.com/projects/ZT/repos/kubernetes-helm/browse) in your Kubernetes cluster. Set the `{$KUBE.API.ENDPOINT.URL}` such as `://:/api`. @@ -118,40 +118,42 @@ There are no template links in this template. |Kubernetes |Kubernetes: Get nodes |

Collecting and processing cluster nodes data via Kubernetes API.

|SCRIPT |kube.nodes

**Expression**:

`The text is too long. Please see the template.` | |Kubernetes |Get nodes check |

Data collection check.

|DEPENDENT |kube.nodes.check

**Preprocessing**:

- JSONPATH: `$.error`

⛔️ON_FAIL: `CUSTOM_VALUE -> `

- DISCARD_UNCHANGED_HEARTBEAT: `3h`

| |Kubernetes |Node LLD |

Generation of data for node discovery rules.

|DEPENDENT |kube.nodes.lld

**Preprocessing**:

- JAVASCRIPT: `function parseFilters(filter) { var pairs = {}; filter.split(/\s*,\s*/).forEach(function (kv) { if (/([\w\.-]+\/[\w\.-]+):\s*.+/.test(kv)) { var pair = kv.split(/\s*:\s*/); pairs[pair[0]] = pair[1]; } }); return pairs; } function filter(name, data, filters) { var filtered = true; if (typeof data === 'object') { Object.keys(filters).some(function (filter) { var exclude = filter.match(/^!(.+)/); if (filter in data || (exclude && exclude[1] in data)) { if ((exclude && new RegExp(filters[filter]).test(data[exclude[1]])) || (!exclude && !(new RegExp(filters[filter]).test(data[filter])))) { Zabbix.log(4, '[ Kubernetes discovery ] Discarded "' + name + '" by filter "' + filter + ': ' + filters[filter] + '"'); filtered = false; return true; } }; }); } return filtered; } try { var input = JSON.parse(value), output = []; api_url = '{$KUBE.API.ENDPOINT.URL}', hostname = api_url.match(/\/\/(.+):/); if (typeof hostname[1] === 'undefined') { Zabbix.log(4, '[ Kubernetes ] Received incorrect Kubernetes API url: ' + api_url + '. Expected format: ://:'); throw 'Cannot get hostname from Kubernetes API url. Check debug log for more information.'; }; if (typeof input !== 'object' || typeof input.items === 'undefined') { Zabbix.log(4, '[ Kubernetes ] Received incorrect JSON: ' + input); throw 'Incorrect JSON. Check debug log for more information.'; } var filterLabels = parseFilters('{$KUBE.NODE.FILTER.LABELS}'), filterAnnotations = parseFilters('{$KUBE.NODE.FILTER.ANNOTATIONS}'); input.items.forEach(function (node) { if (filter(node.metadata.name, node.metadata.labels, filterLabels) && filter(node.metadata.name, node.metadata.annotations, filterAnnotations)) { Zabbix.log(4, '[ Kubernetes discovery ] Filtered node "' + node.metadata.name + '"'); var internalIPs = node.status.addresses.filter(function (addr) { return addr.type === 'InternalIP'; }); var internalIP = internalIPs.length && internalIPs[0].address; if (internalIP in input.endpointIPs) { output.push({ '{#NAME}': node.metadata.name, '{#IP}': internalIP, '{#ROLES}': node.status.roles, '{#ARCH}': node.metadata.labels['kubernetes.io/arch'] || '', '{#OS}': node.metadata.labels['kubernetes.io/os'] || '', '{#CLUSTER_HOSTNAME}': hostname[1] }); } else { Zabbix.log(4, '[ Kubernetes discovery ] Node "' + node.metadata.name + '" is not included in the list of endpoint IPs'); } } }); return JSON.stringify(output); } catch (error) { error += (String(error).endsWith('.')) ? '' : '.'; Zabbix.log(3, '[ Kubernetes discovery ] ERROR: ' + error); throw 'Discovery error: ' + error; } `

- DISCARD_UNCHANGED_HEARTBEAT: `3h`

| -|Kubernetes |Node [{#NAME}] Addresses: External IP |

Typically the IP address of the node that is externally routable (available from outside the cluster).

|DEPENDENT |kube.node.addresses.external_ip[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.items[?(@.metadata.name == "{#NAME}")].status.addresses[?(@.type == "ExternalIP")].address.first()`

⛔️ON_FAIL: `DISCARD_VALUE -> `

- DISCARD_UNCHANGED_HEARTBEAT: `3h`

| -|Kubernetes |Node [{#NAME}] Addresses: Internal IP |

Typically the IP address of the node that is routable only within the cluster.

|DEPENDENT |kube.node.addresses.internal_ip[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.items[?(@.metadata.name == "{#NAME}")].status.addresses[?(@.type == "InternalIP")].address.first()`

⛔️ON_FAIL: `DISCARD_VALUE -> `

- DISCARD_UNCHANGED_HEARTBEAT: `3h`

| -|Kubernetes |Node [{#NAME}] Allocatable: CPU |

Allocatable CPU.

'Allocatable' on a Kubernetes node is defined as the amount of compute resources that are available for pods. The scheduler does not over-subscribe 'Allocatable'. 'CPU', 'memory' and 'ephemeral-storage' are supported as of now.

|DEPENDENT |kube.node.allocatable.cpu[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.items[?(@.metadata.name == "{#NAME}")].status.allocatable.cpu.first()`

| -|Kubernetes |Node [{#NAME}] Allocatable: Memory |

Allocatable Memory.

'Allocatable' on a Kubernetes node is defined as the amount of compute resources that are available for pods. The scheduler does not over-subscribe 'Allocatable'. 'CPU', 'memory' and 'ephemeral-storage' are supported as of now.

|DEPENDENT |kube.node.allocatable.memory[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.items[?(@.metadata.name == "{#NAME}")].status.allocatable.memory.first()`

| -|Kubernetes |Node [{#NAME}] Allocatable: Pods |

https://kubernetes.io/docs/tasks/administer-cluster/reserve-compute-resources/

|DEPENDENT |kube.node.allocatable.pods[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.items[?(@.metadata.name == "{#NAME}")].status.allocatable.pods.first()`

| -|Kubernetes |Node [{#NAME}] Capacity: CPU |

CPU resource capacity.

https://kubernetes.io/docs/concepts/architecture/nodes/#capacity

|DEPENDENT |kube.node.capacity.cpu[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.items[?(@.metadata.name == "{#NAME}")].status.capacity.cpu.first()`

| -|Kubernetes |Node [{#NAME}] Capacity: Memory |

Memory resource capacity.

https://kubernetes.io/docs/concepts/architecture/nodes/#capacity

|DEPENDENT |kube.node.capacity.memory[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.items[?(@.metadata.name == "{#NAME}")].status.capacity.memory.first()`

| -|Kubernetes |Node [{#NAME}] Capacity: Pods |

https://kubernetes.io/docs/tasks/administer-cluster/reserve-compute-resources/

|DEPENDENT |kube.node.capacity.pods[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.items[?(@.metadata.name == "{#NAME}")].status.capacity.pods.first()`

| -|Kubernetes |Node [{#NAME}] Conditions: Disk pressure |

True if pressure exists on the disk size - that is, if the disk capacity is low; otherwise False.

|DEPENDENT |kube.node.conditions.diskpressure[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.items[?(@.metadata.name == "{#NAME}")].status.conditions[?(@.type == "DiskPressure")].status.first()`

⛔️ON_FAIL: `DISCARD_VALUE -> `

- JAVASCRIPT: `return ['True', 'False', 'Unknown'].indexOf(value) + 1 || 'Problem with status processing in JS'; `

| -|Kubernetes |Node [{#NAME}] Conditions: Memory pressure |

True if pressure exists on the node memory - that is, if the node memory is low; otherwise False.

|DEPENDENT |kube.node.conditions.memorypressure[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.items[?(@.metadata.name == "{#NAME}")].status.conditions[?(@.type == "MemoryPressure")].status.first()`

⛔️ON_FAIL: `DISCARD_VALUE -> `

- JAVASCRIPT: `return ['True', 'False', 'Unknown'].indexOf(value) + 1 || 'Problem with status processing in JS'; `

| -|Kubernetes |Node [{#NAME}] Conditions: Network unavailable |

True if the network for the node is not correctly configured, otherwise False.

|DEPENDENT |kube.node.conditions.networkunavailable[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.items[?(@.metadata.name == "{#NAME}")].status.conditions[?(@.type == "NetworkUnavailable")].status.first()`

⛔️ON_FAIL: `DISCARD_VALUE -> `

- JAVASCRIPT: `return ['True', 'False', 'Unknown'].indexOf(value) + 1 || 'Problem with status processing in JS'; `

| -|Kubernetes |Node [{#NAME}] Conditions: PID pressure |

True if pressure exists on the processes - that is, if there are too many processes on the node; otherwise False.

|DEPENDENT |kube.node.conditions.pidpressure[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.items[?(@.metadata.name == "{#NAME}")].status.conditions[?(@.type == "PIDPressure")].status.first()`

⛔️ON_FAIL: `DISCARD_VALUE -> `

- JAVASCRIPT: `return ['True', 'False', 'Unknown'].indexOf(value) + 1 || 'Problem with status processing in JS'; `

| -|Kubernetes |Node [{#NAME}] Conditions: Ready |

True if the node is healthy and ready to accept pods, False if the node is not healthy and is not accepting pods, and Unknown if the node controller has not heard from the node in the last node-monitor-grace-period (default is 40 seconds).

|DEPENDENT |kube.node.conditions.ready[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.items[?(@.metadata.name == "{#NAME}")].status.conditions[?(@.type == "Ready")].status.first()`

⛔️ON_FAIL: `DISCARD_VALUE -> `

- JAVASCRIPT: `return ['True', 'False', 'Unknown'].indexOf(value) + 1 || 'Problem with status processing in JS'; `

| -|Kubernetes |Node [{#NAME}] Info: Architecture |

Node architecture.

|DEPENDENT |kube.node.info.architecture[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.items[?(@.metadata.name == "{#NAME}")].status.nodeInfo.architecture.first()`

- DISCARD_UNCHANGED_HEARTBEAT: `3h`

| -|Kubernetes |Node [{#NAME}] Info: Container runtime |

Container runtime.

https://kubernetes.io/docs/setup/production-environment/container-runtimes/

|DEPENDENT |kube.node.info.containerruntime[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.items[?(@.metadata.name == "{#NAME}")].status.nodeInfo.containerRuntimeVersion.first()`

- DISCARD_UNCHANGED_HEARTBEAT: `3h`

| -|Kubernetes |Node [{#NAME}] Info: Kernel version |

Node kernel version.

|DEPENDENT |kube.node.info.kernelversion[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.items[?(@.metadata.name == "{#NAME}")].status.nodeInfo.kernelVersion.first()`

- DISCARD_UNCHANGED_HEARTBEAT: `3h`

| -|Kubernetes |Node [{#NAME}] Info: Kubelet version |

Version of Kubelet.

|DEPENDENT |kube.node.info.kubeletversion[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.items[?(@.metadata.name == "{#NAME}")].status.nodeInfo.kubeletVersion.first()`

- DISCARD_UNCHANGED_HEARTBEAT: `3h`

| -|Kubernetes |Node [{#NAME}] Info: KubeProxy version |

Version of KubeProxy.

|DEPENDENT |kube.node.info.kubeproxyversion[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.items[?(@.metadata.name == "{#NAME}")].status.nodeInfo.kubeProxyVersion.first()`

- DISCARD_UNCHANGED_HEARTBEAT: `3h`

| -|Kubernetes |Node [{#NAME}] Info: Operating system |

Node operating system.

|DEPENDENT |kube.node.info.operatingsystem[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.items[?(@.metadata.name == "{#NAME}")].status.nodeInfo.operatingSystem.first()`

- DISCARD_UNCHANGED_HEARTBEAT: `3h`

| -|Kubernetes |Node [{#NAME}] Info: OS image |

Node OS image.

|DEPENDENT |kube.node.info.osversion[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.items[?(@.metadata.name == "{#NAME}")].status.nodeInfo.kernelVersion.first()`

- DISCARD_UNCHANGED_HEARTBEAT: `3h`

| -|Kubernetes |Node [{#NAME}] Info: Roles |

Node roles.

|DEPENDENT |kube.node.info.roles[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.items[?(@.metadata.name == "{#NAME}")].status.roles.first()`

- DISCARD_UNCHANGED_HEARTBEAT: `3h`

| -|Kubernetes |Node [{#NAME}] Limits: CPU |

Node CPU limits.

https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

|DEPENDENT |kube.node.limits.cpu[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.items[?(@.metadata.name == "{#NAME}")].pods[*].containers.limits.cpu.sum()`

| -|Kubernetes |Node [{#NAME}] Limits: Memory |

Node Memory limits.

https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

|DEPENDENT |kube.node.limits.memory[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.items[?(@.metadata.name == "{#NAME}")].pods[*].containers.limits.memory.sum()`

| -|Kubernetes |Node [{#NAME}] Requests: CPU |

Node CPU requests.

https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

|DEPENDENT |kube.node.requests.cpu[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.items[?(@.metadata.name == "{#NAME}")].pods[*].containers.requests.cpu.sum()`

| -|Kubernetes |Node [{#NAME}] Requests: Memory |

Node Memory requests.

https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

|DEPENDENT |kube.node.requests.memory[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.items[?(@.metadata.name == "{#NAME}")].pods[*].containers.requests.memory.sum()`

| -|Kubernetes |Node [{#NAME}] Uptime |

Node uptime.

|DEPENDENT |kube.node.uptime[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.items[?(@.metadata.name == "{#NAME}")].metadata.creationTimestamp.first()`

⛔️ON_FAIL: `DISCARD_VALUE -> `

- JAVASCRIPT: `return Math.floor((Date.now() - new Date(value)) / 1000);`

| -|Kubernetes |Node [{#NAME}] Used: Pods |

Current number of pods on the node.

|DEPENDENT |kube.node.used.pods[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.items[?(@.metadata.name == "{#NAME}")].status.podsCount.first()`

| -|Kubernetes |Node [{#NODE}] Pod [{#POD}] Conditions: Containers ready |

All containers in the Pod are ready.

https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-conditions

|DEPENDENT |kube.pod.conditions.containers_ready[{#POD}]

**Preprocessing**:

- JSONPATH: `$.items[?(@.metadata.name == "{#NODE}")].pods[?(@.name == "{#POD}")].conditions[?(@.type == "ContainersReady")].status.first()`

⛔️ON_FAIL: `DISCARD_VALUE -> `

- JAVASCRIPT: `return ['True', 'False', 'Unknown'].indexOf(value) + 1 || 'Problem with status processing in JS'; `

| -|Kubernetes |Node [{#NODE}] Pod [{#POD}] Conditions: Initialized |

All init containers have started successfully.

https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-conditions

|DEPENDENT |kube.pod.conditions.initialized[{#POD}]

**Preprocessing**:

- JSONPATH: `$.items[?(@.metadata.name == "{#NODE}")].pods[?(@.name == "{#POD}")].conditions[?(@.type == "Initialized")].status.first()`

⛔️ON_FAIL: `DISCARD_VALUE -> `

- JAVASCRIPT: `return ['True', 'False', 'Unknown'].indexOf(value) + 1 || 'Problem with status processing in JS'; `

| -|Kubernetes |Node [{#NODE}] Pod [{#POD}] Conditions: Ready |

The Pod is able to serve requests and should be added to the load balancing pools of all matching Services.

https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-conditions

|DEPENDENT |kube.pod.conditions.ready[{#POD}]

**Preprocessing**:

- JSONPATH: `$.items[?(@.metadata.name == "{#NODE}")].pods[?(@.name == "{#POD}")].conditions[?(@.type == "Ready")].status.first()`

⛔️ON_FAIL: `DISCARD_VALUE -> `

- JAVASCRIPT: `return ['True', 'False', 'Unknown'].indexOf(value) + 1 || 'Problem with status processing in JS'; `

| -|Kubernetes |Node [{#NODE}] Pod [{#POD}] Conditions: Scheduled |

The Pod has been scheduled to a node.

https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-conditions

|DEPENDENT |kube.pod.conditions.scheduled[{#POD}]

**Preprocessing**:

- JSONPATH: `$.items[?(@.metadata.name == "{#NODE}")].pods[?(@.name == "{#POD}")].conditions[?(@.type == "PodScheduled")].status.first()`

⛔️ON_FAIL: `DISCARD_VALUE -> `

- JAVASCRIPT: `return ['True', 'False', 'Unknown'].indexOf(value) + 1 || 'Problem with status processing in JS'; `

| -|Kubernetes |Node [{#NODE}] Pod [{#POD}] Containers: Restarts |

The number of times the container has been restarted, currently based on the number of dead containers that have not yet been removed. Note that this is calculated from dead containers. But those containers are subject to garbage collection.

|DEPENDENT |kube.pod.containers.restartcount[{#POD}]

**Preprocessing**:

- JSONPATH: `$.items[?(@.metadata.name == "{#NODE}")].pods[?(@.name == "{#POD}")].containers.restartCount.first()`

⛔️ON_FAIL: `DISCARD_VALUE -> `

| -|Kubernetes |Node [{#NODE}] Pod [{#POD}] Status: Phase |

The phase of a Pod is a simple, high-level summary of where the Pod is in its lifecycle.

https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-phase

|DEPENDENT |kube.pod.status.phase[{#POD}]

**Preprocessing**:

- JSONPATH: `$.items[?(@.metadata.name == "{#NODE}")].pods[?(@.name == "{#POD}")].phase.first()`

⛔️ON_FAIL: `DISCARD_VALUE -> `

- JAVASCRIPT: `return ['Pending', 'Running', 'Succeeded', 'Failed', 'Unknown'].indexOf(value) + 1 || 'Problem with status processing in JS'; `

| -|Kubernetes |Node [{#NODE}] Pod [{#POD}] Uptime |

Pod uptime.

|DEPENDENT |kube.pod.uptime[{#POD}]

**Preprocessing**:

- JSONPATH: `$.items[?(@.metadata.name == "{#NODE}")].pods[?(@.name == "{#POD}")].startTime.first()`

⛔️ON_FAIL: `DISCARD_VALUE -> `

- JAVASCRIPT: `return Math.floor((Date.now() - new Date(value)) / 1000);`

| +|Kubernetes |Node [{#NAME}]: Get data |

Collecting and processing cluster by node [{#NAME}] data via Kubernetes API.

|DEPENDENT |kube.node.get[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.items[?(@.metadata.name == "{#NAME}")].first()`

⛔️ON_FAIL: `DISCARD_VALUE -> `

- DISCARD_UNCHANGED_HEARTBEAT: `3h`

| +|Kubernetes |Node [{#NAME}] Addresses: External IP |

Typically the IP address of the node that is externally routable (available from outside the cluster).

|DEPENDENT |kube.node.addresses.external_ip[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.status.addresses[?(@.type == "ExternalIP")].address.first()`

⛔️ON_FAIL: `DISCARD_VALUE -> `

- DISCARD_UNCHANGED_HEARTBEAT: `3h`

| +|Kubernetes |Node [{#NAME}] Addresses: Internal IP |

Typically the IP address of the node that is routable only within the cluster.

|DEPENDENT |kube.node.addresses.internal_ip[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.status.addresses[?(@.type == "InternalIP")].address.first()`

⛔️ON_FAIL: `DISCARD_VALUE -> `

- DISCARD_UNCHANGED_HEARTBEAT: `3h`

| +|Kubernetes |Node [{#NAME}] Allocatable: CPU |

Allocatable CPU.

'Allocatable' on a Kubernetes node is defined as the amount of compute resources that are available for pods. The scheduler does not over-subscribe 'Allocatable'. 'CPU', 'memory' and 'ephemeral-storage' are supported as of now.

|DEPENDENT |kube.node.allocatable.cpu[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.status.allocatable.cpu`

| +|Kubernetes |Node [{#NAME}] Allocatable: Memory |

Allocatable Memory.

'Allocatable' on a Kubernetes node is defined as the amount of compute resources that are available for pods. The scheduler does not over-subscribe 'Allocatable'. 'CPU', 'memory' and 'ephemeral-storage' are supported as of now.

|DEPENDENT |kube.node.allocatable.memory[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.status.allocatable.memory`

| +|Kubernetes |Node [{#NAME}] Allocatable: Pods |

https://kubernetes.io/docs/tasks/administer-cluster/reserve-compute-resources/

|DEPENDENT |kube.node.allocatable.pods[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.status.allocatable.pods`

| +|Kubernetes |Node [{#NAME}] Capacity: CPU |

CPU resource capacity.

https://kubernetes.io/docs/concepts/architecture/nodes/#capacity

|DEPENDENT |kube.node.capacity.cpu[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.status.capacity.cpu`

| +|Kubernetes |Node [{#NAME}] Capacity: Memory |

Memory resource capacity.

https://kubernetes.io/docs/concepts/architecture/nodes/#capacity

|DEPENDENT |kube.node.capacity.memory[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.status.capacity.memory`

| +|Kubernetes |Node [{#NAME}] Capacity: Pods |

https://kubernetes.io/docs/tasks/administer-cluster/reserve-compute-resources/

|DEPENDENT |kube.node.capacity.pods[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.status.capacity.pods`

| +|Kubernetes |Node [{#NAME}] Conditions: Disk pressure |

True if pressure exists on the disk size - that is, if the disk capacity is low; otherwise False.

|DEPENDENT |kube.node.conditions.diskpressure[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.status.conditions[?(@.type == "DiskPressure")].status.first()`

⛔️ON_FAIL: `DISCARD_VALUE -> `

- JAVASCRIPT: `return ['True', 'False', 'Unknown'].indexOf(value) + 1 || 'Problem with status processing in JS'; `

| +|Kubernetes |Node [{#NAME}] Conditions: Memory pressure |

True if pressure exists on the node memory - that is, if the node memory is low; otherwise False.

|DEPENDENT |kube.node.conditions.memorypressure[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.status.conditions[?(@.type == "MemoryPressure")].status.first()`

⛔️ON_FAIL: `DISCARD_VALUE -> `

- JAVASCRIPT: `return ['True', 'False', 'Unknown'].indexOf(value) + 1 || 'Problem with status processing in JS'; `

| +|Kubernetes |Node [{#NAME}] Conditions: Network unavailable |

True if the network for the node is not correctly configured, otherwise False.

|DEPENDENT |kube.node.conditions.networkunavailable[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.status.conditions[?(@.type == "NetworkUnavailable")].status.first()`

⛔️ON_FAIL: `DISCARD_VALUE -> `

- JAVASCRIPT: `return ['True', 'False', 'Unknown'].indexOf(value) + 1 || 'Problem with status processing in JS'; `

| +|Kubernetes |Node [{#NAME}] Conditions: PID pressure |

True if pressure exists on the processes - that is, if there are too many processes on the node; otherwise False.

|DEPENDENT |kube.node.conditions.pidpressure[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.status.conditions[?(@.type == "PIDPressure")].status.first()`

⛔️ON_FAIL: `DISCARD_VALUE -> `

- JAVASCRIPT: `return ['True', 'False', 'Unknown'].indexOf(value) + 1 || 'Problem with status processing in JS'; `

| +|Kubernetes |Node [{#NAME}] Conditions: Ready |

True if the node is healthy and ready to accept pods, False if the node is not healthy and is not accepting pods, and Unknown if the node controller has not heard from the node in the last node-monitor-grace-period (default is 40 seconds).

|DEPENDENT |kube.node.conditions.ready[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.status.conditions[?(@.type == "Ready")].status.first()`

⛔️ON_FAIL: `DISCARD_VALUE -> `

- JAVASCRIPT: `return ['True', 'False', 'Unknown'].indexOf(value) + 1 || 'Problem with status processing in JS'; `

| +|Kubernetes |Node [{#NAME}] Info: Architecture |

Node architecture.

|DEPENDENT |kube.node.info.architecture[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.status.nodeInfo.architecture`

- DISCARD_UNCHANGED_HEARTBEAT: `3h`

| +|Kubernetes |Node [{#NAME}] Info: Container runtime |

Container runtime.

https://kubernetes.io/docs/setup/production-environment/container-runtimes/

|DEPENDENT |kube.node.info.containerruntime[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.status.nodeInfo.containerRuntimeVersion`

- DISCARD_UNCHANGED_HEARTBEAT: `3h`

| +|Kubernetes |Node [{#NAME}] Info: Kernel version |

Node kernel version.

|DEPENDENT |kube.node.info.kernelversion[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.status.nodeInfo.kernelVersion`

- DISCARD_UNCHANGED_HEARTBEAT: `3h`

| +|Kubernetes |Node [{#NAME}] Info: Kubelet version |

Version of Kubelet.

|DEPENDENT |kube.node.info.kubeletversion[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.status.nodeInfo.kubeletVersion`

- DISCARD_UNCHANGED_HEARTBEAT: `3h`

| +|Kubernetes |Node [{#NAME}] Info: KubeProxy version |

Version of KubeProxy.

|DEPENDENT |kube.node.info.kubeproxyversion[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.status.nodeInfo.kubeProxyVersion`

- DISCARD_UNCHANGED_HEARTBEAT: `3h`

| +|Kubernetes |Node [{#NAME}] Info: Operating system |

Node operating system.

|DEPENDENT |kube.node.info.operatingsystem[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.status.nodeInfo.operatingSystem`

- DISCARD_UNCHANGED_HEARTBEAT: `3h`

| +|Kubernetes |Node [{#NAME}] Info: OS image |

Node OS image.

|DEPENDENT |kube.node.info.osversion[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.status.nodeInfo.kernelVersion`

- DISCARD_UNCHANGED_HEARTBEAT: `3h`

| +|Kubernetes |Node [{#NAME}] Info: Roles |

Node roles.

|DEPENDENT |kube.node.info.roles[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.status.roles`

- DISCARD_UNCHANGED_HEARTBEAT: `3h`

| +|Kubernetes |Node [{#NAME}] Limits: CPU |

Node CPU limits.

https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

|DEPENDENT |kube.node.limits.cpu[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.pods[*].containers.limits.cpu.sum()`

| +|Kubernetes |Node [{#NAME}] Limits: Memory |

Node Memory limits.

https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

|DEPENDENT |kube.node.limits.memory[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.pods[*].containers.limits.memory.sum()`

| +|Kubernetes |Node [{#NAME}] Requests: CPU |

Node CPU requests.

https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

|DEPENDENT |kube.node.requests.cpu[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.pods[*].containers.requests.cpu.sum()`

| +|Kubernetes |Node [{#NAME}] Requests: Memory |

Node Memory requests.

https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

|DEPENDENT |kube.node.requests.memory[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.pods[*].containers.requests.memory.sum()`

| +|Kubernetes |Node [{#NAME}] Uptime |

Node uptime.

|DEPENDENT |kube.node.uptime[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.metadata.creationTimestamp`

⛔️ON_FAIL: `DISCARD_VALUE -> `

- JAVASCRIPT: `return Math.floor((Date.now() - new Date(value)) / 1000);`

| +|Kubernetes |Node [{#NAME}] Used: Pods |

Current number of pods on the node.

|DEPENDENT |kube.node.used.pods[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.status.podsCount`

| +|Kubernetes |Node [{#NODE}] Pod [{#POD}]: Get data |

Collecting and processing cluster by node [{#NODE}] data via Kubernetes API.

|DEPENDENT |kube.pod.get[{#POD}]

**Preprocessing**:

- JSONPATH: `$.items[?(@.metadata.name == "{#NODE}")].pods[?(@.name == "{#POD}")].first()`

⛔️ON_FAIL: `DISCARD_VALUE -> `

- DISCARD_UNCHANGED_HEARTBEAT: `3h`

| +|Kubernetes |Node [{#NODE}] Pod [{#POD}] Conditions: Containers ready |

All containers in the Pod are ready.

https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-conditions

|DEPENDENT |kube.pod.conditions.containers_ready[{#POD}]

**Preprocessing**:

- JSONPATH: `$.conditions[?(@.type == "ContainersReady")].status.first()`

⛔️ON_FAIL: `DISCARD_VALUE -> `

- JAVASCRIPT: `return ['True', 'False', 'Unknown'].indexOf(value) + 1 || 'Problem with status processing in JS'; `

| +|Kubernetes |Node [{#NODE}] Pod [{#POD}] Conditions: Initialized |

All init containers have started successfully.

https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-conditions

|DEPENDENT |kube.pod.conditions.initialized[{#POD}]

**Preprocessing**:

- JSONPATH: `$.conditions[?(@.type == "Initialized")].status.first()`

⛔️ON_FAIL: `DISCARD_VALUE -> `

- JAVASCRIPT: `return ['True', 'False', 'Unknown'].indexOf(value) + 1 || 'Problem with status processing in JS'; `

| +|Kubernetes |Node [{#NODE}] Pod [{#POD}] Conditions: Ready |

The Pod is able to serve requests and should be added to the load balancing pools of all matching Services.

https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-conditions

|DEPENDENT |kube.pod.conditions.ready[{#POD}]

**Preprocessing**:

- JSONPATH: `$.conditions[?(@.type == "Ready")].status.first()`

⛔️ON_FAIL: `DISCARD_VALUE -> `

- JAVASCRIPT: `return ['True', 'False', 'Unknown'].indexOf(value) + 1 || 'Problem with status processing in JS'; `

| +|Kubernetes |Node [{#NODE}] Pod [{#POD}] Conditions: Scheduled |

The Pod has been scheduled to a node.

https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-conditions

|DEPENDENT |kube.pod.conditions.scheduled[{#POD}]

**Preprocessing**:

- JSONPATH: `$.conditions[?(@.type == "PodScheduled")].status.first()`

⛔️ON_FAIL: `DISCARD_VALUE -> `

- JAVASCRIPT: `return ['True', 'False', 'Unknown'].indexOf(value) + 1 || 'Problem with status processing in JS'; `

| +|Kubernetes |Node [{#NODE}] Pod [{#POD}] Containers: Restarts |

The number of times the container has been restarted, currently based on the number of dead containers that have not yet been removed. Note that this is calculated from dead containers. But those containers are subject to garbage collection.

|DEPENDENT |kube.pod.containers.restartcount[{#POD}]

**Preprocessing**:

- JSONPATH: `$.containers.restartCount`

⛔️ON_FAIL: `DISCARD_VALUE -> `

| +|Kubernetes |Node [{#NODE}] Pod [{#POD}] Status: Phase |

The phase of a Pod is a simple, high-level summary of where the Pod is in its lifecycle.

https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-phase

|DEPENDENT |kube.pod.status.phase[{#POD}]

**Preprocessing**:

- JSONPATH: `$.phase`

⛔️ON_FAIL: `DISCARD_VALUE -> `

- JAVASCRIPT: `return ['Pending', 'Running', 'Succeeded', 'Failed', 'Unknown'].indexOf(value) + 1 || 'Problem with status processing in JS'; `

| +|Kubernetes |Node [{#NODE}] Pod [{#POD}] Uptime |

Pod uptime.

|DEPENDENT |kube.pod.uptime[{#POD}]

**Preprocessing**:

- JSONPATH: `$.startTime`

⛔️ON_FAIL: `DISCARD_VALUE -> `

- JAVASCRIPT: `return Math.floor((Date.now() - new Date(value)) / 1000);`

| ## Triggers @@ -178,7 +180,7 @@ There are no template links in this template. ## Feedback -Please report any issues with the template at https://support.zabbix.com +Please report any issues with the template at https://support.zabbix.com. -You can also provide feedback, discuss the template or ask for help with it at [ZABBIX forums](https://www.zabbix.com/forum/zabbix-suggestions-and-feedback). +You can also provide feedback, discuss the template, or ask for help at [ZABBIX forums](https://www.zabbix.com/forum/zabbix-suggestions-and-feedback). diff --git a/templates/app/kubernetes_http/kubernetes_nodes_http/template_kubernetes_nodes.yaml b/templates/app/kubernetes_http/kubernetes_nodes_http/template_kubernetes_nodes.yaml index 7b9ee2583a4..43d7819de76 100644 --- a/templates/app/kubernetes_http/kubernetes_nodes_http/template_kubernetes_nodes.yaml +++ b/templates/app/kubernetes_http/kubernetes_nodes_http/template_kubernetes_nodes.yaml @@ -1,6 +1,6 @@ zabbix_export: version: '6.4' - date: '2022-07-07T11:07:51Z' + date: '2022-10-25T13:31:13Z' template_groups: - uuid: a571c0d144b14fd4a87a9d9b2aa9fcd6 @@ -485,14 +485,14 @@ zabbix_export: - type: JSONPATH parameters: - - '$.items[?(@.metadata.name == "{#NAME}")].status.addresses[?(@.type == "ExternalIP")].address.first()' + - '$.status.addresses[?(@.type == "ExternalIP")].address.first()' error_handler: DISCARD_VALUE - type: DISCARD_UNCHANGED_HEARTBEAT parameters: - 3h master_item: - key: kube.nodes + key: 'kube.node.get[{#NAME}]' tags: - tag: component @@ -514,14 +514,14 @@ zabbix_export: - type: JSONPATH parameters: - - '$.items[?(@.metadata.name == "{#NAME}")].status.addresses[?(@.type == "InternalIP")].address.first()' + - '$.status.addresses[?(@.type == "InternalIP")].address.first()' error_handler: DISCARD_VALUE - type: DISCARD_UNCHANGED_HEARTBEAT parameters: - 3h master_item: - key: kube.nodes + key: 'kube.node.get[{#NAME}]' tags: - tag: component @@ -545,9 +545,9 @@ zabbix_export: - type: JSONPATH parameters: - - '$.items[?(@.metadata.name == "{#NAME}")].status.allocatable.cpu.first()' + - $.status.allocatable.cpu master_item: - key: kube.nodes + key: 'kube.node.get[{#NAME}]' tags: - tag: component @@ -571,9 +571,9 @@ zabbix_export: - type: JSONPATH parameters: - - '$.items[?(@.metadata.name == "{#NAME}")].status.allocatable.memory.first()' + - $.status.allocatable.memory master_item: - key: kube.nodes + key: 'kube.node.get[{#NAME}]' tags: - tag: component @@ -593,9 +593,9 @@ zabbix_export: - type: JSONPATH parameters: - - '$.items[?(@.metadata.name == "{#NAME}")].status.allocatable.pods.first()' + - $.status.allocatable.pods master_item: - key: kube.nodes + key: 'kube.node.get[{#NAME}]' tags: - tag: component @@ -619,9 +619,9 @@ zabbix_export: - type: JSONPATH parameters: - - '$.items[?(@.metadata.name == "{#NAME}")].status.capacity.cpu.first()' + - $.status.capacity.cpu master_item: - key: kube.nodes + key: 'kube.node.get[{#NAME}]' tags: - tag: component @@ -645,9 +645,9 @@ zabbix_export: - type: JSONPATH parameters: - - '$.items[?(@.metadata.name == "{#NAME}")].status.capacity.memory.first()' + - $.status.capacity.memory master_item: - key: kube.nodes + key: 'kube.node.get[{#NAME}]' tags: - tag: component @@ -667,9 +667,9 @@ zabbix_export: - type: JSONPATH parameters: - - '$.items[?(@.metadata.name == "{#NAME}")].status.capacity.pods.first()' + - $.status.capacity.pods master_item: - key: kube.nodes + key: 'kube.node.get[{#NAME}]' tags: - tag: component @@ -691,14 +691,14 @@ zabbix_export: - type: JSONPATH parameters: - - '$.items[?(@.metadata.name == "{#NAME}")].status.conditions[?(@.type == "DiskPressure")].status.first()' + - '$.status.conditions[?(@.type == "DiskPressure")].status.first()' error_handler: DISCARD_VALUE - type: JAVASCRIPT parameters: - 'return [''True'', ''False'', ''Unknown''].indexOf(value) + 1 || ''Problem with status processing in JS'';' master_item: - key: kube.nodes + key: 'kube.node.get[{#NAME}]' tags: - tag: component @@ -732,14 +732,14 @@ zabbix_export: - type: JSONPATH parameters: - - '$.items[?(@.metadata.name == "{#NAME}")].status.conditions[?(@.type == "MemoryPressure")].status.first()' + - '$.status.conditions[?(@.type == "MemoryPressure")].status.first()' error_handler: DISCARD_VALUE - type: JAVASCRIPT parameters: - 'return [''True'', ''False'', ''Unknown''].indexOf(value) + 1 || ''Problem with status processing in JS'';' master_item: - key: kube.nodes + key: 'kube.node.get[{#NAME}]' tags: - tag: component @@ -773,14 +773,14 @@ zabbix_export: - type: JSONPATH parameters: - - '$.items[?(@.metadata.name == "{#NAME}")].status.conditions[?(@.type == "NetworkUnavailable")].status.first()' + - '$.status.conditions[?(@.type == "NetworkUnavailable")].status.first()' error_handler: DISCARD_VALUE - type: JAVASCRIPT parameters: - 'return [''True'', ''False'', ''Unknown''].indexOf(value) + 1 || ''Problem with status processing in JS'';' master_item: - key: kube.nodes + key: 'kube.node.get[{#NAME}]' tags: - tag: component @@ -814,14 +814,14 @@ zabbix_export: - type: JSONPATH parameters: - - '$.items[?(@.metadata.name == "{#NAME}")].status.conditions[?(@.type == "PIDPressure")].status.first()' + - '$.status.conditions[?(@.type == "PIDPressure")].status.first()' error_handler: DISCARD_VALUE - type: JAVASCRIPT parameters: - 'return [''True'', ''False'', ''Unknown''].indexOf(value) + 1 || ''Problem with status processing in JS'';' master_item: - key: kube.nodes + key: 'kube.node.get[{#NAME}]' tags: - tag: component @@ -855,14 +855,14 @@ zabbix_export: - type: JSONPATH parameters: - - '$.items[?(@.metadata.name == "{#NAME}")].status.conditions[?(@.type == "Ready")].status.first()' + - '$.status.conditions[?(@.type == "Ready")].status.first()' error_handler: DISCARD_VALUE - type: JAVASCRIPT parameters: - 'return [''True'', ''False'', ''Unknown''].indexOf(value) + 1 || ''Problem with status processing in JS'';' master_item: - key: kube.nodes + key: 'kube.node.get[{#NAME}]' tags: - tag: component @@ -884,6 +884,35 @@ zabbix_export: - tag: scope value: availability + - + uuid: 3d8536659ac44347b36e61f60873fa61 + name: 'Node [{#NAME}]: Get data' + type: DEPENDENT + key: 'kube.node.get[{#NAME}]' + delay: '0' + history: '0' + trends: '0' + value_type: CHAR + description: 'Collecting and processing cluster by node [{#NAME}] data via Kubernetes API.' + preprocessing: + - + type: JSONPATH + parameters: + - '$.items[?(@.metadata.name == "{#NAME}")].first()' + error_handler: DISCARD_VALUE + - + type: DISCARD_UNCHANGED_HEARTBEAT + parameters: + - 3h + master_item: + key: kube.nodes + tags: + - + tag: component + value: raw + - + tag: node + value: '{#NAME}' - uuid: 8f9152074e2041d7b5cd2c6215e06832 name: 'Node [{#NAME}] Info: Architecture' @@ -898,13 +927,13 @@ zabbix_export: - type: JSONPATH parameters: - - '$.items[?(@.metadata.name == "{#NAME}")].status.nodeInfo.architecture.first()' + - $.status.nodeInfo.architecture - type: DISCARD_UNCHANGED_HEARTBEAT parameters: - 3h master_item: - key: kube.nodes + key: 'kube.node.get[{#NAME}]' tags: - tag: component @@ -929,13 +958,13 @@ zabbix_export: - type: JSONPATH parameters: - - '$.items[?(@.metadata.name == "{#NAME}")].status.nodeInfo.containerRuntimeVersion.first()' + - $.status.nodeInfo.containerRuntimeVersion - type: DISCARD_UNCHANGED_HEARTBEAT parameters: - 3h master_item: - key: kube.nodes + key: 'kube.node.get[{#NAME}]' tags: - tag: component @@ -957,13 +986,13 @@ zabbix_export: - type: JSONPATH parameters: - - '$.items[?(@.metadata.name == "{#NAME}")].status.nodeInfo.kernelVersion.first()' + - $.status.nodeInfo.kernelVersion - type: DISCARD_UNCHANGED_HEARTBEAT parameters: - 3h master_item: - key: kube.nodes + key: 'kube.node.get[{#NAME}]' tags: - tag: component @@ -985,13 +1014,13 @@ zabbix_export: - type: JSONPATH parameters: - - '$.items[?(@.metadata.name == "{#NAME}")].status.nodeInfo.kubeletVersion.first()' + - $.status.nodeInfo.kubeletVersion - type: DISCARD_UNCHANGED_HEARTBEAT parameters: - 3h master_item: - key: kube.nodes + key: 'kube.node.get[{#NAME}]' tags: - tag: component @@ -1013,13 +1042,13 @@ zabbix_export: - type: JSONPATH parameters: - - '$.items[?(@.metadata.name == "{#NAME}")].status.nodeInfo.kubeProxyVersion.first()' + - $.status.nodeInfo.kubeProxyVersion - type: DISCARD_UNCHANGED_HEARTBEAT parameters: - 3h master_item: - key: kube.nodes + key: 'kube.node.get[{#NAME}]' tags: - tag: component @@ -1041,13 +1070,13 @@ zabbix_export: - type: JSONPATH parameters: - - '$.items[?(@.metadata.name == "{#NAME}")].status.nodeInfo.operatingSystem.first()' + - $.status.nodeInfo.operatingSystem - type: DISCARD_UNCHANGED_HEARTBEAT parameters: - 3h master_item: - key: kube.nodes + key: 'kube.node.get[{#NAME}]' tags: - tag: component @@ -1069,13 +1098,13 @@ zabbix_export: - type: JSONPATH parameters: - - '$.items[?(@.metadata.name == "{#NAME}")].status.nodeInfo.kernelVersion.first()' + - $.status.nodeInfo.kernelVersion - type: DISCARD_UNCHANGED_HEARTBEAT parameters: - 3h master_item: - key: kube.nodes + key: 'kube.node.get[{#NAME}]' tags: - tag: component @@ -1097,13 +1126,13 @@ zabbix_export: - type: JSONPATH parameters: - - '$.items[?(@.metadata.name == "{#NAME}")].status.roles.first()' + - $.status.roles - type: DISCARD_UNCHANGED_HEARTBEAT parameters: - 3h master_item: - key: kube.nodes + key: 'kube.node.get[{#NAME}]' tags: - tag: component @@ -1127,9 +1156,9 @@ zabbix_export: - type: JSONPATH parameters: - - '$.items[?(@.metadata.name == "{#NAME}")].pods[*].containers.limits.cpu.sum()' + - '$.pods[*].containers.limits.cpu.sum()' master_item: - key: kube.nodes + key: 'kube.node.get[{#NAME}]' tags: - tag: component @@ -1153,9 +1182,9 @@ zabbix_export: - type: JSONPATH parameters: - - '$.items[?(@.metadata.name == "{#NAME}")].pods[*].containers.limits.memory.sum()' + - '$.pods[*].containers.limits.memory.sum()' master_item: - key: kube.nodes + key: 'kube.node.get[{#NAME}]' tags: - tag: component @@ -1179,9 +1208,9 @@ zabbix_export: - type: JSONPATH parameters: - - '$.items[?(@.metadata.name == "{#NAME}")].pods[*].containers.requests.cpu.sum()' + - '$.pods[*].containers.requests.cpu.sum()' master_item: - key: kube.nodes + key: 'kube.node.get[{#NAME}]' tags: - tag: component @@ -1205,9 +1234,9 @@ zabbix_export: - type: JSONPATH parameters: - - '$.items[?(@.metadata.name == "{#NAME}")].pods[*].containers.requests.memory.sum()' + - '$.pods[*].containers.requests.memory.sum()' master_item: - key: kube.nodes + key: 'kube.node.get[{#NAME}]' tags: - tag: component @@ -1228,14 +1257,14 @@ zabbix_export: - type: JSONPATH parameters: - - '$.items[?(@.metadata.name == "{#NAME}")].metadata.creationTimestamp.first()' + - $.metadata.creationTimestamp error_handler: DISCARD_VALUE - type: JAVASCRIPT parameters: - 'return Math.floor((Date.now() - new Date(value)) / 1000);' master_item: - key: kube.nodes + key: 'kube.node.get[{#NAME}]' tags: - tag: component @@ -1267,9 +1296,9 @@ zabbix_export: - type: JSONPATH parameters: - - '$.items[?(@.metadata.name == "{#NAME}")].status.podsCount.first()' + - $.status.podsCount master_item: - key: kube.nodes + key: 'kube.node.get[{#NAME}]' tags: - tag: component @@ -1538,14 +1567,14 @@ zabbix_export: - type: JSONPATH parameters: - - '$.items[?(@.metadata.name == "{#NODE}")].pods[?(@.name == "{#POD}")].conditions[?(@.type == "ContainersReady")].status.first()' + - '$.conditions[?(@.type == "ContainersReady")].status.first()' error_handler: DISCARD_VALUE - type: JAVASCRIPT parameters: - 'return [''True'', ''False'', ''Unknown''].indexOf(value) + 1 || ''Problem with status processing in JS'';' master_item: - key: kube.nodes + key: 'kube.pod.get[{#POD}]' tags: - tag: component @@ -1576,14 +1605,14 @@ zabbix_export: - type: JSONPATH parameters: - - '$.items[?(@.metadata.name == "{#NODE}")].pods[?(@.name == "{#POD}")].conditions[?(@.type == "Initialized")].status.first()' + - '$.conditions[?(@.type == "Initialized")].status.first()' error_handler: DISCARD_VALUE - type: JAVASCRIPT parameters: - 'return [''True'', ''False'', ''Unknown''].indexOf(value) + 1 || ''Problem with status processing in JS'';' master_item: - key: kube.nodes + key: 'kube.pod.get[{#POD}]' tags: - tag: component @@ -1614,14 +1643,14 @@ zabbix_export: - type: JSONPATH parameters: - - '$.items[?(@.metadata.name == "{#NODE}")].pods[?(@.name == "{#POD}")].conditions[?(@.type == "Ready")].status.first()' + - '$.conditions[?(@.type == "Ready")].status.first()' error_handler: DISCARD_VALUE - type: JAVASCRIPT parameters: - 'return [''True'', ''False'', ''Unknown''].indexOf(value) + 1 || ''Problem with status processing in JS'';' master_item: - key: kube.nodes + key: 'kube.pod.get[{#POD}]' tags: - tag: component @@ -1652,14 +1681,14 @@ zabbix_export: - type: JSONPATH parameters: - - '$.items[?(@.metadata.name == "{#NODE}")].pods[?(@.name == "{#POD}")].conditions[?(@.type == "PodScheduled")].status.first()' + - '$.conditions[?(@.type == "PodScheduled")].status.first()' error_handler: DISCARD_VALUE - type: JAVASCRIPT parameters: - 'return [''True'', ''False'', ''Unknown''].indexOf(value) + 1 || ''Problem with status processing in JS'';' master_item: - key: kube.nodes + key: 'kube.pod.get[{#POD}]' tags: - tag: component @@ -1685,10 +1714,10 @@ zabbix_export: - type: JSONPATH parameters: - - '$.items[?(@.metadata.name == "{#NODE}")].pods[?(@.name == "{#POD}")].containers.restartCount.first()' + - $.containers.restartCount error_handler: DISCARD_VALUE master_item: - key: kube.nodes + key: 'kube.pod.get[{#POD}]' tags: - tag: component @@ -1713,6 +1742,38 @@ zabbix_export: - tag: scope value: availability + - + uuid: 34a542538cf449f287a99052870988be + name: 'Node [{#NODE}] Pod [{#POD}]: Get data' + type: DEPENDENT + key: 'kube.pod.get[{#POD}]' + delay: '0' + history: '0' + trends: '0' + value_type: CHAR + description: 'Collecting and processing cluster by node [{#NODE}] data via Kubernetes API.' + preprocessing: + - + type: JSONPATH + parameters: + - '$.items[?(@.metadata.name == "{#NODE}")].pods[?(@.name == "{#POD}")].first()' + error_handler: DISCARD_VALUE + - + type: DISCARD_UNCHANGED_HEARTBEAT + parameters: + - 3h + master_item: + key: kube.nodes + tags: + - + tag: component + value: raw + - + tag: node + value: '{#NODE}' + - + tag: pod + value: '{#POD}' - uuid: 6862be81e52b4abcb319a8847b022634 name: 'Node [{#NODE}] Pod [{#POD}] Status: Phase' @@ -1730,14 +1791,14 @@ zabbix_export: - type: JSONPATH parameters: - - '$.items[?(@.metadata.name == "{#NODE}")].pods[?(@.name == "{#POD}")].phase.first()' + - $.phase error_handler: DISCARD_VALUE - type: JAVASCRIPT parameters: - 'return [''Pending'', ''Running'', ''Succeeded'', ''Failed'', ''Unknown''].indexOf(value) + 1 || ''Problem with status processing in JS'';' master_item: - key: kube.nodes + key: 'kube.pod.get[{#POD}]' tags: - tag: component @@ -1775,14 +1836,14 @@ zabbix_export: - type: JSONPATH parameters: - - '$.items[?(@.metadata.name == "{#NODE}")].pods[?(@.name == "{#POD}")].startTime.first()' + - $.startTime error_handler: DISCARD_VALUE - type: JAVASCRIPT parameters: - 'return Math.floor((Date.now() - new Date(value)) / 1000);' master_item: - key: kube.nodes + key: 'kube.pod.get[{#POD}]' tags: - tag: component -- cgit v1.2.3 From 4b6ebd965669b9269bca2e0c968c118bd77b0941 Mon Sep 17 00:00:00 2001 From: Evgenii Gordymov Date: Fri, 28 Oct 2022 18:32:17 +0400 Subject: .........T [ZBX-21588] optimized template k8s nodes by http --- templates/app/kubernetes_http/kubernetes_nodes_http/README.md | 3 ++- .../kubernetes_nodes_http/template_kubernetes_nodes.yaml | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/templates/app/kubernetes_http/kubernetes_nodes_http/README.md b/templates/app/kubernetes_http/kubernetes_nodes_http/README.md index 7060c5c1acc..60a250ec7f8 100644 --- a/templates/app/kubernetes_http/kubernetes_nodes_http/README.md +++ b/templates/app/kubernetes_http/kubernetes_nodes_http/README.md @@ -16,6 +16,7 @@ Get the generated service account token using the command Then set it to the macro `{$KUBE.API.TOKEN}`. +Set `{$KUBE.NODES.ENDPOINT.NAME}` with Zabbix agent's endpoint name. See `kubectl -n monitoring get ep`. Default: `zabbix-zabbix-helm-chrt-agent`. Set up the macros to filter the metrics of discovered nodes @@ -117,7 +118,7 @@ There are no template links in this template. |-----|----|-----------|----|---------------------| |Kubernetes |Kubernetes: Get nodes |

Collecting and processing cluster nodes data via Kubernetes API.

|SCRIPT |kube.nodes

**Expression**:

`The text is too long. Please see the template.` | |Kubernetes |Get nodes check |

Data collection check.

|DEPENDENT |kube.nodes.check

**Preprocessing**:

- JSONPATH: `$.error`

⛔️ON_FAIL: `CUSTOM_VALUE -> `

- DISCARD_UNCHANGED_HEARTBEAT: `3h`

| -|Kubernetes |Node LLD |

Generation of data for node discovery rules.

|DEPENDENT |kube.nodes.lld

**Preprocessing**:

- JAVASCRIPT: `function parseFilters(filter) { var pairs = {}; filter.split(/\s*,\s*/).forEach(function (kv) { if (/([\w\.-]+\/[\w\.-]+):\s*.+/.test(kv)) { var pair = kv.split(/\s*:\s*/); pairs[pair[0]] = pair[1]; } }); return pairs; } function filter(name, data, filters) { var filtered = true; if (typeof data === 'object') { Object.keys(filters).some(function (filter) { var exclude = filter.match(/^!(.+)/); if (filter in data || (exclude && exclude[1] in data)) { if ((exclude && new RegExp(filters[filter]).test(data[exclude[1]])) || (!exclude && !(new RegExp(filters[filter]).test(data[filter])))) { Zabbix.log(4, '[ Kubernetes discovery ] Discarded "' + name + '" by filter "' + filter + ': ' + filters[filter] + '"'); filtered = false; return true; } }; }); } return filtered; } try { var input = JSON.parse(value), output = []; api_url = '{$KUBE.API.ENDPOINT.URL}', hostname = api_url.match(/\/\/(.+):/); if (typeof hostname[1] === 'undefined') { Zabbix.log(4, '[ Kubernetes ] Received incorrect Kubernetes API url: ' + api_url + '. Expected format: ://:'); throw 'Cannot get hostname from Kubernetes API url. Check debug log for more information.'; }; if (typeof input !== 'object' || typeof input.items === 'undefined') { Zabbix.log(4, '[ Kubernetes ] Received incorrect JSON: ' + input); throw 'Incorrect JSON. Check debug log for more information.'; } var filterLabels = parseFilters('{$KUBE.NODE.FILTER.LABELS}'), filterAnnotations = parseFilters('{$KUBE.NODE.FILTER.ANNOTATIONS}'); input.items.forEach(function (node) { if (filter(node.metadata.name, node.metadata.labels, filterLabels) && filter(node.metadata.name, node.metadata.annotations, filterAnnotations)) { Zabbix.log(4, '[ Kubernetes discovery ] Filtered node "' + node.metadata.name + '"'); var internalIPs = node.status.addresses.filter(function (addr) { return addr.type === 'InternalIP'; }); var internalIP = internalIPs.length && internalIPs[0].address; if (internalIP in input.endpointIPs) { output.push({ '{#NAME}': node.metadata.name, '{#IP}': internalIP, '{#ROLES}': node.status.roles, '{#ARCH}': node.metadata.labels['kubernetes.io/arch'] || '', '{#OS}': node.metadata.labels['kubernetes.io/os'] || '', '{#CLUSTER_HOSTNAME}': hostname[1] }); } else { Zabbix.log(4, '[ Kubernetes discovery ] Node "' + node.metadata.name + '" is not included in the list of endpoint IPs'); } } }); return JSON.stringify(output); } catch (error) { error += (String(error).endsWith('.')) ? '' : '.'; Zabbix.log(3, '[ Kubernetes discovery ] ERROR: ' + error); throw 'Discovery error: ' + error; } `

- DISCARD_UNCHANGED_HEARTBEAT: `3h`

| +|Kubernetes |Node LLD |

Generation of data for node discovery rules.

|DEPENDENT |kube.nodes.lld

**Preprocessing**:

- JAVASCRIPT: `function parseFilters(filter) { var pairs = {}; filter.split(/\s*,\s*/).forEach(function (kv) { if (/([\w\.-]+\/[\w\.-]+):\s*.+/.test(kv)) { var pair = kv.split(/\s*:\s*/); pairs[pair[0]] = pair[1]; } }); return pairs; } function filter(name, data, filters) { var filtered = true; if (typeof data === 'object') { Object.keys(filters).some(function (filter) { var exclude = filter.match(/^!(.+)/); if (filter in data || (exclude && exclude[1] in data)) { if ((exclude && new RegExp(filters[filter]).test(data[exclude[1]])) || (!exclude && !(new RegExp(filters[filter]).test(data[filter])))) { Zabbix.log(4, '[ Kubernetes discovery ] Discarded "' + name + '" by filter "' + filter + ': ' + filters[filter] + '"'); filtered = false; return true; } }; }); } return filtered; } try { var input = JSON.parse(value), output = []; api_url = '{$KUBE.API.ENDPOINT.URL}', hostname = api_url.match(/\/\/(.+):/); if (typeof hostname[1] === 'undefined') { Zabbix.log(4, '[ Kubernetes ] Received incorrect Kubernetes API url: ' + api_url + '. Expected format: ://:'); throw 'Cannot get hostname from Kubernetes API url. Check debug log for more information.'; }; if (typeof input !== 'object' || typeof input.items === 'undefined') { Zabbix.log(4, '[ Kubernetes ] Received incorrect JSON: ' + value); throw 'Incorrect JSON. Check debug log for more information.'; } var filterLabels = parseFilters('{$KUBE.NODE.FILTER.LABELS}'), filterAnnotations = parseFilters('{$KUBE.NODE.FILTER.ANNOTATIONS}'); input.items.forEach(function (node) { if (filter(node.metadata.name, node.metadata.labels, filterLabels) && filter(node.metadata.name, node.metadata.annotations, filterAnnotations)) { Zabbix.log(4, '[ Kubernetes discovery ] Filtered node "' + node.metadata.name + '"'); var internalIPs = node.status.addresses.filter(function (addr) { return addr.type === 'InternalIP'; }); var internalIP = internalIPs.length && internalIPs[0].address; if (internalIP in input.endpointIPs) { output.push({ '{#NAME}': node.metadata.name, '{#IP}': internalIP, '{#ROLES}': node.status.roles, '{#ARCH}': node.metadata.labels['kubernetes.io/arch'] || '', '{#OS}': node.metadata.labels['kubernetes.io/os'] || '', '{#CLUSTER_HOSTNAME}': hostname[1] }); } else { Zabbix.log(4, '[ Kubernetes discovery ] Node "' + node.metadata.name + '" is not included in the list of endpoint IPs'); } } }); return JSON.stringify(output); } catch (error) { error += (String(error).endsWith('.')) ? '' : '.'; Zabbix.log(3, '[ Kubernetes discovery ] ERROR: ' + error); throw 'Discovery error: ' + error; } `

- DISCARD_UNCHANGED_HEARTBEAT: `3h`

| |Kubernetes |Node [{#NAME}]: Get data |

Collecting and processing cluster by node [{#NAME}] data via Kubernetes API.

|DEPENDENT |kube.node.get[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.items[?(@.metadata.name == "{#NAME}")].first()`

⛔️ON_FAIL: `DISCARD_VALUE -> `

- DISCARD_UNCHANGED_HEARTBEAT: `3h`

| |Kubernetes |Node [{#NAME}] Addresses: External IP |

Typically the IP address of the node that is externally routable (available from outside the cluster).

|DEPENDENT |kube.node.addresses.external_ip[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.status.addresses[?(@.type == "ExternalIP")].address.first()`

⛔️ON_FAIL: `DISCARD_VALUE -> `

- DISCARD_UNCHANGED_HEARTBEAT: `3h`

| |Kubernetes |Node [{#NAME}] Addresses: Internal IP |

Typically the IP address of the node that is routable only within the cluster.

|DEPENDENT |kube.node.addresses.internal_ip[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.status.addresses[?(@.type == "InternalIP")].address.first()`

⛔️ON_FAIL: `DISCARD_VALUE -> `

- DISCARD_UNCHANGED_HEARTBEAT: `3h`

| diff --git a/templates/app/kubernetes_http/kubernetes_nodes_http/template_kubernetes_nodes.yaml b/templates/app/kubernetes_http/kubernetes_nodes_http/template_kubernetes_nodes.yaml index 43d7819de76..83a235ee487 100644 --- a/templates/app/kubernetes_http/kubernetes_nodes_http/template_kubernetes_nodes.yaml +++ b/templates/app/kubernetes_http/kubernetes_nodes_http/template_kubernetes_nodes.yaml @@ -1,6 +1,6 @@ zabbix_export: version: '6.4' - date: '2022-10-25T13:31:13Z' + date: '2022-10-28T14:15:00Z' template_groups: - uuid: a571c0d144b14fd4a87a9d9b2aa9fcd6 @@ -391,7 +391,7 @@ zabbix_export: }; if (typeof input !== 'object' || typeof input.items === 'undefined') { - Zabbix.log(4, '[ Kubernetes ] Received incorrect JSON: ' + input); + Zabbix.log(4, '[ Kubernetes ] Received incorrect JSON: ' + value); throw 'Incorrect JSON. Check debug log for more information.'; } @@ -1903,7 +1903,7 @@ zabbix_export: output = []; if (typeof input !== 'object' || typeof input.items === 'undefined') { - Zabbix.log(4, '[ Kubernetes ] Received incorrect JSON: ' + input); + Zabbix.log(4, '[ Kubernetes ] Received incorrect JSON: ' + value); throw 'Incorrect JSON. Check debug log for more information.'; } -- cgit v1.2.3 From 4ec0a9db826dd6083f28f05988def407a001fd1c Mon Sep 17 00:00:00 2001 From: Evgenii Gordymov Date: Fri, 28 Oct 2022 18:34:46 +0400 Subject: .........T [ZBX-21588] optimized template k8s nodes by http --- templates/app/kubernetes_http/kubernetes_nodes_http/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/app/kubernetes_http/kubernetes_nodes_http/README.md b/templates/app/kubernetes_http/kubernetes_nodes_http/README.md index 60a250ec7f8..582b34e5a0c 100644 --- a/templates/app/kubernetes_http/kubernetes_nodes_http/README.md +++ b/templates/app/kubernetes_http/kubernetes_nodes_http/README.md @@ -6,7 +6,7 @@ For Zabbix version: 6.4 and higher. The template to monitor Kubernetes nodes that work without any external scripts. It works without external scripts and uses the script item to make HTTP requests to the Kubernetes API. -Install the Zabbix Helm Chart (https://git.zabbix.com/projects/ZT/repos/kubernetes-helm/browse) in your Kubernetes cluster. +Install the Zabbix Helm Chart (https://git.zabbix.com/projects/ZT/repos/kubernetes-helm/browse?at=refs%2Fheads%2Fmaster) in your Kubernetes cluster. Set the `{$KUBE.API.ENDPOINT.URL}` such as `://:/api`. @@ -28,7 +28,7 @@ This template was tested on: > See [Zabbix template operation](https://www.zabbix.com/documentation/6.4/manual/config/templates_out_of_the_box/http) for basic instructions. -Install the [Zabbix Helm Chart](https://git.zabbix.com/projects/ZT/repos/kubernetes-helm/browse) in your Kubernetes cluster. +Install the [Zabbix Helm Chart](https://git.zabbix.com/projects/ZT/repos/kubernetes-helm/browse?at=refs%2Fheads%2Fmaster) in your Kubernetes cluster. Set the `{$KUBE.API.ENDPOINT.URL}` such as `://:/api`. -- cgit v1.2.3 From 34495a3c0dd27ed8dbce87068a258dfb9099da43 Mon Sep 17 00:00:00 2001 From: Evgenii Gordymov Date: Thu, 10 Nov 2022 14:31:16 +0400 Subject: .........T [ZBX-21588] optimized template k8s nodes by http --- .../app/kubernetes_http/kubernetes_nodes_http/README.md | 4 ++-- .../kubernetes_nodes_http/template_kubernetes_nodes.yaml | 12 +----------- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/templates/app/kubernetes_http/kubernetes_nodes_http/README.md b/templates/app/kubernetes_http/kubernetes_nodes_http/README.md index 582b34e5a0c..f1f83f25f09 100644 --- a/templates/app/kubernetes_http/kubernetes_nodes_http/README.md +++ b/templates/app/kubernetes_http/kubernetes_nodes_http/README.md @@ -119,7 +119,7 @@ There are no template links in this template. |Kubernetes |Kubernetes: Get nodes |

Collecting and processing cluster nodes data via Kubernetes API.

|SCRIPT |kube.nodes

**Expression**:

`The text is too long. Please see the template.` | |Kubernetes |Get nodes check |

Data collection check.

|DEPENDENT |kube.nodes.check

**Preprocessing**:

- JSONPATH: `$.error`

⛔️ON_FAIL: `CUSTOM_VALUE -> `

- DISCARD_UNCHANGED_HEARTBEAT: `3h`

| |Kubernetes |Node LLD |

Generation of data for node discovery rules.

|DEPENDENT |kube.nodes.lld

**Preprocessing**:

- JAVASCRIPT: `function parseFilters(filter) { var pairs = {}; filter.split(/\s*,\s*/).forEach(function (kv) { if (/([\w\.-]+\/[\w\.-]+):\s*.+/.test(kv)) { var pair = kv.split(/\s*:\s*/); pairs[pair[0]] = pair[1]; } }); return pairs; } function filter(name, data, filters) { var filtered = true; if (typeof data === 'object') { Object.keys(filters).some(function (filter) { var exclude = filter.match(/^!(.+)/); if (filter in data || (exclude && exclude[1] in data)) { if ((exclude && new RegExp(filters[filter]).test(data[exclude[1]])) || (!exclude && !(new RegExp(filters[filter]).test(data[filter])))) { Zabbix.log(4, '[ Kubernetes discovery ] Discarded "' + name + '" by filter "' + filter + ': ' + filters[filter] + '"'); filtered = false; return true; } }; }); } return filtered; } try { var input = JSON.parse(value), output = []; api_url = '{$KUBE.API.ENDPOINT.URL}', hostname = api_url.match(/\/\/(.+):/); if (typeof hostname[1] === 'undefined') { Zabbix.log(4, '[ Kubernetes ] Received incorrect Kubernetes API url: ' + api_url + '. Expected format: ://:'); throw 'Cannot get hostname from Kubernetes API url. Check debug log for more information.'; }; if (typeof input !== 'object' || typeof input.items === 'undefined') { Zabbix.log(4, '[ Kubernetes ] Received incorrect JSON: ' + value); throw 'Incorrect JSON. Check debug log for more information.'; } var filterLabels = parseFilters('{$KUBE.NODE.FILTER.LABELS}'), filterAnnotations = parseFilters('{$KUBE.NODE.FILTER.ANNOTATIONS}'); input.items.forEach(function (node) { if (filter(node.metadata.name, node.metadata.labels, filterLabels) && filter(node.metadata.name, node.metadata.annotations, filterAnnotations)) { Zabbix.log(4, '[ Kubernetes discovery ] Filtered node "' + node.metadata.name + '"'); var internalIPs = node.status.addresses.filter(function (addr) { return addr.type === 'InternalIP'; }); var internalIP = internalIPs.length && internalIPs[0].address; if (internalIP in input.endpointIPs) { output.push({ '{#NAME}': node.metadata.name, '{#IP}': internalIP, '{#ROLES}': node.status.roles, '{#ARCH}': node.metadata.labels['kubernetes.io/arch'] || '', '{#OS}': node.metadata.labels['kubernetes.io/os'] || '', '{#CLUSTER_HOSTNAME}': hostname[1] }); } else { Zabbix.log(4, '[ Kubernetes discovery ] Node "' + node.metadata.name + '" is not included in the list of endpoint IPs'); } } }); return JSON.stringify(output); } catch (error) { error += (String(error).endsWith('.')) ? '' : '.'; Zabbix.log(3, '[ Kubernetes discovery ] ERROR: ' + error); throw 'Discovery error: ' + error; } `

- DISCARD_UNCHANGED_HEARTBEAT: `3h`

| -|Kubernetes |Node [{#NAME}]: Get data |

Collecting and processing cluster by node [{#NAME}] data via Kubernetes API.

|DEPENDENT |kube.node.get[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.items[?(@.metadata.name == "{#NAME}")].first()`

⛔️ON_FAIL: `DISCARD_VALUE -> `

- DISCARD_UNCHANGED_HEARTBEAT: `3h`

| +|Kubernetes |Node [{#NAME}]: Get data |

Collecting and processing cluster by node [{#NAME}] data via Kubernetes API.

|DEPENDENT |kube.node.get[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.items[?(@.metadata.name == "{#NAME}")].first()`

| |Kubernetes |Node [{#NAME}] Addresses: External IP |

Typically the IP address of the node that is externally routable (available from outside the cluster).

|DEPENDENT |kube.node.addresses.external_ip[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.status.addresses[?(@.type == "ExternalIP")].address.first()`

⛔️ON_FAIL: `DISCARD_VALUE -> `

- DISCARD_UNCHANGED_HEARTBEAT: `3h`

| |Kubernetes |Node [{#NAME}] Addresses: Internal IP |

Typically the IP address of the node that is routable only within the cluster.

|DEPENDENT |kube.node.addresses.internal_ip[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.status.addresses[?(@.type == "InternalIP")].address.first()`

⛔️ON_FAIL: `DISCARD_VALUE -> `

- DISCARD_UNCHANGED_HEARTBEAT: `3h`

| |Kubernetes |Node [{#NAME}] Allocatable: CPU |

Allocatable CPU.

'Allocatable' on a Kubernetes node is defined as the amount of compute resources that are available for pods. The scheduler does not over-subscribe 'Allocatable'. 'CPU', 'memory' and 'ephemeral-storage' are supported as of now.

|DEPENDENT |kube.node.allocatable.cpu[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.status.allocatable.cpu`

| @@ -147,7 +147,7 @@ There are no template links in this template. |Kubernetes |Node [{#NAME}] Requests: Memory |

Node Memory requests.

https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

|DEPENDENT |kube.node.requests.memory[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.pods[*].containers.requests.memory.sum()`

| |Kubernetes |Node [{#NAME}] Uptime |

Node uptime.

|DEPENDENT |kube.node.uptime[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.metadata.creationTimestamp`

⛔️ON_FAIL: `DISCARD_VALUE -> `

- JAVASCRIPT: `return Math.floor((Date.now() - new Date(value)) / 1000);`

| |Kubernetes |Node [{#NAME}] Used: Pods |

Current number of pods on the node.

|DEPENDENT |kube.node.used.pods[{#NAME}]

**Preprocessing**:

- JSONPATH: `$.status.podsCount`

| -|Kubernetes |Node [{#NODE}] Pod [{#POD}]: Get data |

Collecting and processing cluster by node [{#NODE}] data via Kubernetes API.

|DEPENDENT |kube.pod.get[{#POD}]

**Preprocessing**:

- JSONPATH: `$.items[?(@.metadata.name == "{#NODE}")].pods[?(@.name == "{#POD}")].first()`

⛔️ON_FAIL: `DISCARD_VALUE -> `

- DISCARD_UNCHANGED_HEARTBEAT: `3h`

| +|Kubernetes |Node [{#NODE}] Pod [{#POD}]: Get data |

Collecting and processing cluster by node [{#NODE}] data via Kubernetes API.

|DEPENDENT |kube.pod.get[{#POD}]

**Preprocessing**:

- JSONPATH: `$.items[?(@.metadata.name == "{#NODE}")].pods[?(@.name == "{#POD}")].first()`

| |Kubernetes |Node [{#NODE}] Pod [{#POD}] Conditions: Containers ready |

All containers in the Pod are ready.

https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-conditions

|DEPENDENT |kube.pod.conditions.containers_ready[{#POD}]

**Preprocessing**:

- JSONPATH: `$.conditions[?(@.type == "ContainersReady")].status.first()`

⛔️ON_FAIL: `DISCARD_VALUE -> `

- JAVASCRIPT: `return ['True', 'False', 'Unknown'].indexOf(value) + 1 || 'Problem with status processing in JS'; `

| |Kubernetes |Node [{#NODE}] Pod [{#POD}] Conditions: Initialized |

All init containers have started successfully.

https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-conditions

|DEPENDENT |kube.pod.conditions.initialized[{#POD}]

**Preprocessing**:

- JSONPATH: `$.conditions[?(@.type == "Initialized")].status.first()`

⛔️ON_FAIL: `DISCARD_VALUE -> `

- JAVASCRIPT: `return ['True', 'False', 'Unknown'].indexOf(value) + 1 || 'Problem with status processing in JS'; `

| |Kubernetes |Node [{#NODE}] Pod [{#POD}] Conditions: Ready |

The Pod is able to serve requests and should be added to the load balancing pools of all matching Services.

https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-conditions

|DEPENDENT |kube.pod.conditions.ready[{#POD}]

**Preprocessing**:

- JSONPATH: `$.conditions[?(@.type == "Ready")].status.first()`

⛔️ON_FAIL: `DISCARD_VALUE -> `

- JAVASCRIPT: `return ['True', 'False', 'Unknown'].indexOf(value) + 1 || 'Problem with status processing in JS'; `

| diff --git a/templates/app/kubernetes_http/kubernetes_nodes_http/template_kubernetes_nodes.yaml b/templates/app/kubernetes_http/kubernetes_nodes_http/template_kubernetes_nodes.yaml index 83a235ee487..7957c135b04 100644 --- a/templates/app/kubernetes_http/kubernetes_nodes_http/template_kubernetes_nodes.yaml +++ b/templates/app/kubernetes_http/kubernetes_nodes_http/template_kubernetes_nodes.yaml @@ -1,6 +1,6 @@ zabbix_export: version: '6.4' - date: '2022-10-28T14:15:00Z' + date: '2022-11-10T10:19:26Z' template_groups: - uuid: a571c0d144b14fd4a87a9d9b2aa9fcd6 @@ -899,11 +899,6 @@ zabbix_export: type: JSONPATH parameters: - '$.items[?(@.metadata.name == "{#NAME}")].first()' - error_handler: DISCARD_VALUE - - - type: DISCARD_UNCHANGED_HEARTBEAT - parameters: - - 3h master_item: key: kube.nodes tags: @@ -1757,11 +1752,6 @@ zabbix_export: type: JSONPATH parameters: - '$.items[?(@.metadata.name == "{#NODE}")].pods[?(@.name == "{#POD}")].first()' - error_handler: DISCARD_VALUE - - - type: DISCARD_UNCHANGED_HEARTBEAT - parameters: - - 3h master_item: key: kube.nodes tags: -- cgit v1.2.3