diff --git a/apm-dist/src/main/assembly/binary.xml b/apm-dist/src/main/assembly/binary.xml index 4eed1b7efa..27a9499bba 100644 --- a/apm-dist/src/main/assembly/binary.xml +++ b/apm-dist/src/main/assembly/binary.xml @@ -72,6 +72,7 @@ lal/* log-mal-rules/** telegraf-rules/* + cilium-rules/* config diff --git a/docs/en/concepts-and-designs/service-hierarchy-configuration.md b/docs/en/concepts-and-designs/service-hierarchy-configuration.md index c09c8c1d1e..6aa0d40d56 100644 --- a/docs/en/concepts-and-designs/service-hierarchy-configuration.md +++ b/docs/en/concepts-and-designs/service-hierarchy-configuration.md @@ -53,6 +53,7 @@ layer-levels: MYSQL: 2 POSTGRESQL: 2 MESH_DP: 1 + CILIUM_SERVICE: 1 K8S_SERVICE: 0 ``` diff --git a/docs/en/setup/backend/backend-k8s-monitoring-cilium.md b/docs/en/setup/backend/backend-k8s-monitoring-cilium.md index 4dcfd76341..7ec68f89e6 100644 --- a/docs/en/setup/backend/backend-k8s-monitoring-cilium.md +++ b/docs/en/setup/backend/backend-k8s-monitoring-cilium.md @@ -34,6 +34,26 @@ cilium-fetcher: 3. `sslPrivateKeyFile`: the path of the private key file. 4. `sslCertChainFile`: the path of the certificate chain file. 5. `sslCaFile`: the path of the CA file. +3. Configure the cilium rules please configure the following configuration: + 1. `cilium-rules/exclude.yaml`: Configure the which endpoint should be excluded from the monitoring, Please read [exclude rules selection](#exclude-rules) for more detail. + 2. `cilium-rules/metadata-service-mapping.yaml`: Configure the service name and endpoint mapping. + +### Exclude Rules + +The exclude configuration in Cilium rules is used to specify which Cilium Endpoints would be excluded from being added to the topology map or from the generation of metrics and other data. + +```yaml +namespaces: # define with traffic from which namespace should be excluded + - kube-system + +labels: # define with traffic from which endpoint labels should be excluded, if matches any labels, the traffic would be excluded. + - k8s:io.cilium.k8s.namespace.labels.istio-injection: "enabled" # Each labels is a key-value pair, the key is the label key, the value is the label value. + k8s:security.istio.io/tlsMode: istio +``` + +By default, all the traffic from `kube-system` and traffic management by istio mesh would be excluded. + +NOTE: Only the endpoint in both source and destination matches the exclude rules would be excluded. Otherwise, the traffic would be still included. ## Generated Entities diff --git a/oap-server/server-fetcher-plugin/cilium-fetcher-plugin/src/main/java/org/apache/skywalking/oap/server/fetcher/cilium/CiliumFetcherProvider.java b/oap-server/server-fetcher-plugin/cilium-fetcher-plugin/src/main/java/org/apache/skywalking/oap/server/fetcher/cilium/CiliumFetcherProvider.java index 98ef2f9e82..f7c130ac1c 100644 --- a/oap-server/server-fetcher-plugin/cilium-fetcher-plugin/src/main/java/org/apache/skywalking/oap/server/fetcher/cilium/CiliumFetcherProvider.java +++ b/oap-server/server-fetcher-plugin/cilium-fetcher-plugin/src/main/java/org/apache/skywalking/oap/server/fetcher/cilium/CiliumFetcherProvider.java @@ -32,11 +32,14 @@ import org.apache.skywalking.oap.server.library.module.ModuleStartException; import org.apache.skywalking.oap.server.library.module.ServiceNotProvidedException; import org.apache.skywalking.oap.server.library.util.FieldsHelper; +import java.io.IOException; + @Slf4j public class CiliumFetcherProvider extends ModuleProvider { private CiliumFetcherConfig config; - protected String fieldMappingFile = "metadata-service-mapping.yaml"; + protected String excludeRulesFile = "cilium-rules/exclude.yaml"; + protected String fieldMappingFile = "cilium-rules/metadata-service-mapping.yaml"; @Override public String name() { @@ -79,9 +82,15 @@ public class CiliumFetcherProvider extends ModuleProvider { } catch (Exception e) { throw new ModuleStartException(e.getMessage(), e); } + ExcludeRules excludeRules; + try { + excludeRules = ExcludeRules.loadRules(excludeRulesFile); + } catch (IOException e) { + throw new ModuleStartException("loading exclude rules error", e); + } final CiliumNodeManager ciliumNodeManager = new CiliumNodeManager(getManager(), new GrpcStubBuilder(config), config); - ciliumNodeManager.addListener(new CiliumFlowListener(getManager(), config)); + ciliumNodeManager.addListener(new CiliumFlowListener(getManager(), config, excludeRules)); ciliumNodeManager.start(); } diff --git a/oap-server/server-fetcher-plugin/cilium-fetcher-plugin/src/main/java/org/apache/skywalking/oap/server/fetcher/cilium/ExcludeRules.java b/oap-server/server-fetcher-plugin/cilium-fetcher-plugin/src/main/java/org/apache/skywalking/oap/server/fetcher/cilium/ExcludeRules.java new file mode 100644 index 0000000000..ddc481bb53 --- /dev/null +++ b/oap-server/server-fetcher-plugin/cilium-fetcher-plugin/src/main/java/org/apache/skywalking/oap/server/fetcher/cilium/ExcludeRules.java @@ -0,0 +1,105 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + * + */ + +package org.apache.skywalking.oap.server.fetcher.cilium; + +import io.cilium.api.flow.Endpoint; +import lombok.Data; +import org.apache.commons.lang3.StringUtils; +import org.apache.skywalking.oap.server.library.util.ResourceUtils; +import org.yaml.snakeyaml.Yaml; + +import java.io.FileReader; +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +public class ExcludeRules { + + private final Set namespaces; + private final List labels; + + public static ExcludeRules loadRules(final String path) throws IOException { + try (FileReader r = new FileReader(ResourceUtils.getPath(path).toFile())) { + final RuleYaml yaml = new Yaml().loadAs(r, RuleYaml.class); + return new ExcludeRules(yaml); + } + } + + /** + * check if the endpoint should be excluded + */ + public boolean shouldExclude(Endpoint endpoint) { + // if the namespace is in the exclude list, return true + if (namespaces.contains(endpoint.getNamespace())) { + return true; + } + // if the endpoint has no labels, return false + if (endpoint.getLabelsCount() == 0) { + return false; + } + return labels.stream().anyMatch(label -> label.isMatch(endpoint)); + } + + private ExcludeRules(RuleYaml yaml) { + this.namespaces = Set.copyOf(yaml.getNamespaces()); + this.labels = yaml.getLabels().stream().map(Labels::new).collect(Collectors.toList()); + } + + private static class Labels { + private Map labelMap; + + public Labels(Map labelMap) { + this.labelMap = labelMap; + } + + /** + * validate if the endpoint matches all the labels + */ + public boolean isMatch(Endpoint endpoint) { + int matchCount = 0; + for (Map.Entry entry : labelMap.entrySet()) { + for (String endpointLabel : endpoint.getLabelsList()) { + // ignore when the key is not match + if (endpointLabel.indexOf(entry.getKey()) != 0) { + continue; + } + // ignore when the value is not match + if (!StringUtils.substring(endpointLabel, entry.getKey().length() + 1).equals(entry.getValue())) { + return false; + } + matchCount++; + + // check the match count(full matched) to avoid unnecessary iteration + if (matchCount == labelMap.size()) { + return true; + } + } + } + return false; + } + } + + @Data + public static class RuleYaml { + private List namespaces; + private List> labels; + } +} diff --git a/oap-server/server-fetcher-plugin/cilium-fetcher-plugin/src/main/java/org/apache/skywalking/oap/server/fetcher/cilium/handler/CiliumFlowListener.java b/oap-server/server-fetcher-plugin/cilium-fetcher-plugin/src/main/java/org/apache/skywalking/oap/server/fetcher/cilium/handler/CiliumFlowListener.java index c5d9b2f2b3..51b76d6d70 100644 --- a/oap-server/server-fetcher-plugin/cilium-fetcher-plugin/src/main/java/org/apache/skywalking/oap/server/fetcher/cilium/handler/CiliumFlowListener.java +++ b/oap-server/server-fetcher-plugin/cilium-fetcher-plugin/src/main/java/org/apache/skywalking/oap/server/fetcher/cilium/handler/CiliumFlowListener.java @@ -44,6 +44,7 @@ import org.apache.skywalking.oap.server.core.source.CiliumService; import org.apache.skywalking.oap.server.core.source.CiliumServiceRelation; import org.apache.skywalking.oap.server.core.source.SourceReceiver; import org.apache.skywalking.oap.server.fetcher.cilium.CiliumFetcherConfig; +import org.apache.skywalking.oap.server.fetcher.cilium.ExcludeRules; import org.apache.skywalking.oap.server.fetcher.cilium.nodes.CiliumNode; import org.apache.skywalking.oap.server.fetcher.cilium.nodes.CiliumNodeUpdateListener; import org.apache.skywalking.oap.server.library.module.ModuleManager; @@ -66,13 +67,15 @@ public class CiliumFlowListener implements CiliumNodeUpdateListener { private final SourceReceiver sourceReceiver; private final Integer retrySecond; private final boolean convertClientAsServerTraffic; + private final ExcludeRules excludeRules; public static final Layer SERVICE_LAYER = Layer.CILIUM_SERVICE; - public CiliumFlowListener(ModuleManager moduleManager, CiliumFetcherConfig config) { + public CiliumFlowListener(ModuleManager moduleManager, CiliumFetcherConfig config, ExcludeRules excludeRules) { this.sourceReceiver = moduleManager.find(CoreModule.NAME).provider().getService(SourceReceiver.class); this.retrySecond = config.getFetchFailureRetrySecond(); this.convertClientAsServerTraffic = config.isConvertClientAsServerTraffic(); + this.excludeRules = excludeRules; } @Override @@ -357,6 +360,10 @@ public class CiliumFlowListener implements CiliumNodeUpdateListener { if (this.convertClientAsServerTraffic && DetectPoint.SERVER.equals(parseDetectPoint(flow))) { return true; } + // ignore the flow when the source and dest endpoint should exclude both + if (excludeRules.shouldExclude(flow.getSource()) && excludeRules.shouldExclude(flow.getDestination())) { + return true; + } return false; } diff --git a/oap-server/server-starter/pom.xml b/oap-server/server-starter/pom.xml index 7e07a73f45..a1de0b2b46 100644 --- a/oap-server/server-starter/pom.xml +++ b/oap-server/server-starter/pom.xml @@ -320,6 +320,7 @@ lal/ log-mal-rules/ telegraf-rules/ + cilium-rules/ diff --git a/oap-server/server-starter/src/main/resources/cilium-rules/exclude.yaml b/oap-server/server-starter/src/main/resources/cilium-rules/exclude.yaml new file mode 100644 index 0000000000..28b4df6dd2 --- /dev/null +++ b/oap-server/server-starter/src/main/resources/cilium-rules/exclude.yaml @@ -0,0 +1,22 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. + +namespaces: + - kube-system + +labels: + - k8s:io.cilium.k8s.namespace.labels.istio-injection: enabled + k8s:security.istio.io/tlsMode: istio diff --git a/oap-server/server-starter/src/main/resources/cilium-rules/metadata-service-mapping.yaml b/oap-server/server-starter/src/main/resources/cilium-rules/metadata-service-mapping.yaml new file mode 100644 index 0000000000..6246e987fc --- /dev/null +++ b/oap-server/server-starter/src/main/resources/cilium-rules/metadata-service-mapping.yaml @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You 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. + +serviceName: ${LABELS."service.istio.io/canonical-name",LABELS."app.kubernetes.io/name",LABELS.component,LABELS.app,LABELS.k8s-app}.${NAMESPACE} +serviceInstanceName: ${NAME} diff --git a/oap-server/server-starter/src/main/resources/hierarchy-definition.yml b/oap-server/server-starter/src/main/resources/hierarchy-definition.yml index 428f80e105..c64a933d6b 100644 --- a/oap-server/server-starter/src/main/resources/hierarchy-definition.yml +++ b/oap-server/server-starter/src/main/resources/hierarchy-definition.yml @@ -74,6 +74,9 @@ hierarchy: KAFKA: lower-short-name-with-fqdn PULSAR: lower-short-name-with-fqdn + CILIUM_SERVICE: + K8S_SERVICE: short-name + # Use Groovy script to define the matching rules, the input parameters are the upper service(u) and the lower service(l) and the return value is a boolean, # which are used to match the relation between the upper service(u) and the lower service(l) on the different layers. auto-matching-rules: @@ -109,6 +112,7 @@ layer-levels: ACTIVEMQ: 2 MESH_DP: 1 + CILIUM_SERVICE: 1 K8S_SERVICE: 0 diff --git a/oap-server/server-starter/src/main/resources/ui-initialized-templates/cilium_service/cilium-service.json b/oap-server/server-starter/src/main/resources/ui-initialized-templates/cilium_service/cilium-service.json index 330751d945..e59d749d3d 100644 --- a/oap-server/server-starter/src/main/resources/ui-initialized-templates/cilium_service/cilium-service.json +++ b/oap-server/server-starter/src/main/resources/ui-initialized-templates/cilium_service/cilium-service.json @@ -554,7 +554,37 @@ "layer": "CILIUM_SERVICE", "entity": "Service", "name": "Cilium-Service", - "isRoot": false + "isRoot": false, + "isDefault": true, + "expressions": [ + "avg(cilium_service_l4_read_pkg_cpm)", + "avg(cilium_service_l4_write_pkg_cpm)", + "avg(cilium_service_protocol_cpm)", + "avg(cilium_service_protocol_call_duration/cilium_service_protocol_cpm)/1000000", + "avg(cilium_service_protocol_call_success_count/cilium_service_protocol_cpm*100)" + ], + "expressionsConfig": [ + { + "unit": "package / min", + "label": "Read" + }, + { + "label": "Write", + "unit": "package / min" + }, + { + "label": "Load", + "unit": "calls / min" + }, + { + "label": "Latency", + "unit": "ms" + }, + { + "label": "Success Rate", + "unit": "%" + } + ] } } ] \ No newline at end of file diff --git a/skywalking-ui b/skywalking-ui index f664e786ac..fe6e853c57 160000 --- a/skywalking-ui +++ b/skywalking-ui @@ -1 +1 @@ -Subproject commit f664e786acead0bb1884d12f91635b2a1cb0fc47 +Subproject commit fe6e853c57ffe690f799620be4b7393a4d2f7041