Dataway Sink¶
Version-1.14.0 This version of Datakit enables the use of the Sinker feature described here.
Introduction to Dataway Sinker Functionality¶
During routine data collection processes, due to the existence of multiple different workspaces, we may need to direct different data to different workspaces. For example, in a shared Kubernetes cluster, the collected data might involve different teams or business departments. In such cases, we can route data with specific attributes to various distinct workspaces to achieve fine-grained collection under a shared infrastructure scenario.
The basic network topology is as follows:
flowchart TD
dw(Dataway);
dk(Datakit);
etcd[(etcd)];
sinker(分流);
wksp1(Workspace 1);
wksp2(Workspace 2);
wksp3(Specific Workspace);
wkspx(Fallback Workspace);
rules(Diversion Rules);
as_default{Fallback rule exists?};
drop(Discard Data/Request);
subgraph "Datakit Cluster"
dk
end
dk -.-> |"HTTP: X-Global-Tags + Secret-Token"|dw
dk -..-> |"Non-diverted request (specific workspace Token)"|dw
subgraph "Dataway Cluster(Nginx)"
%%direction LR
rules --> dw ---> |Diverted Request|sinker
dw ---> |Non-diverted request|wksp3
sinker --> |Rule 1 Match|wksp1;
sinker --> |Rule 2 Match|wksp2;
sinker --> |No Rule Match|as_default -->|No|drop;
as_default -->|Yes|wkspx;
end
subgraph "Workspace Changes"
direction BT
etcd -.-> |Key Change Notification|rules
end
Dataway 1.8.0 supports receiving both Sinker and non-Sinker types of requests, so deploying only one Dataway instance is sufficient.
Cascaded Mode for Dataway¶
For SaaS users, a Dataway can be deployed locally (on k8s Cluster) specifically for diversion, and then forward the data to Openway:
Warning
In cascaded mode, the Dataway within the cluster needs to enable the cascaded option. Refer to the environment variable description in the installation documentation.
flowchart LR;
dk1(Datakit-A);
dk2(Datakit-B);
dk3(Datakit-C);
sink_dw(Dataway);
openway(Openway);
etcd(etcd);
%%
subgraph "K8s Cluster"
dk1 ---> sink_dw
dk2 ---> sink_dw
dk3 ---> sink_dw
etcd-.-> |Diversion Rules|sink_dw
end
subgraph "SaaS"
sink_dw --> |Divert|openway;
sink_dw --> |Divert|openway;
end
Impact of cascading:
- Some API behaviors will differ. Due to historical reasons, there are differences between the request URLs from Datakit and those on Kodo, and Dataway plays a role in API translation. In cascaded situations, the API translation function is disabled.
- The cascaded Dataway will not send heartbeat requests to the center. Because the next-level Dataway does not process this request (so it results in a 404).
- For requests received by the cascaded Dataway, when they are forwarded to the next Dataway, no API signature will be applied.
Dataway Installation¶
Refer to here
Dataway Configuration¶
In addition to regular Dataway settings, several additional configurations need to set (located at /usr/local/cloudcare/dataflux/dataway/dataway.yaml):
# Set the address where Dataway uploads data; usually Kodo, but it could also be another Dataway
remote_host: https://kodo.guance.com
# If the upload address is Dataway, this should be set to true, indicating Dataway cascading
cascaded: false
# This token is an arbitrary segment set on Dataway; it needs to be filled into the
# Datakit's datakit.conf configuration. It should maintain a certain length and format.
secret_token: tkn_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# Sinker rules setting
sinker:
etcd: # Supports etcd
urls:
- http://localhost:2379
dial_timeout: 30s
key_space: /dw_sinker
username: "dataway"
password: "<PASSWORD>"
#file: # Also supports local file method, commonly used for debugging
# path: /path/to/sinker.json
Warning
If secret_token
is not set, any request sent by Datakit will pass, which will not cause data issues. However, if Dataway is deployed on the public internet, it is still recommended to set the secret_token
.
Sinker Rules Configuration¶
Dataway Sinker rules are a set of JSON-formatted configurations, where the matching rule syntax is consistent with the blacklist writing style. Refer to here.
Currently, two sources of configuration are supported:
- Specify a local JSON file, mainly used for debugging Sinker rules. In this case, after updating the Sinker rules in the JSON file, Dataway needs to be restarted for the changes to take effect.
- etcd: Store debugged rules in etcd, and update them directly in etcd when making minor adjustments, without needing to restart Dataway.
Actually, the JSON content stored in etcd is the same as the local file's JSON content. Below, only the etcd management method is introduced.
etcd Configuration¶
All commands below are executed on Linux.
As an etcd client, Dataway can configure the following username and roles in etcd (etcd 3.5+), refer to here
Create the dataway
account and corresponding role:
# Add username, it will prompt for password input
$ etcdctl user add dataway
# Add the sinker role
$ etcdctl role add sinker
# Add dataway to the role
$ etcdctl user grant-role dataway sinker
# Restrict role's key permissions (the keys /dw_sinker and /ping are used by default)
$ etcdctl role grant-permission sinker readwrite /dw_sinker
$ etcdctl role grant-permission sinker readwrite /ping # Used for connectivity checks
Why create roles?
Roles control permissions for specific users on certain keys. Here, we may be using an existing etcd service, so it is necessary to restrict the data permissions for the Dataway user.
Warning
If etcd has enabled authentication mode, when executing etcdctl
commands, the corresponding username and password must be provided:
Writing Sinker Rules¶
New versions (1.3.6) of Dataway support managing etcd Sinker rules via the
dataway
command.
Assume that the sinker.json rule definition is as follows:
{
"strict":true,
"rules": [
{
"rules": [
"{ host = 'my-host'}"
],
"url": "https://kodo.guance.com?token=tkn_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
},
{
"rules": [
"{ host = 'my-host' OR cluster = 'cluster-A' }"
],
"url": "https://kodo.guance.com?token=tkn_yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"
}
]
}
The following command writes the Sinker rule configuration:
Identifying Workspace Information
Since sinker.json does not support comments, we can add an info
field in the JSON to serve as a memo, achieving the effect of commenting:
Default Rule¶
By adding the as_default
identifier in a specific rule entry, you can set that rule as the default fallback rule. A fallback rule does not require any match conditions (no rules
field configured); simultaneously, it should not participate in regular rule matching. A recommended fallback rule is as follows:
{
"as_default": true,
"info": "This is the default fallback workspace",
"url": "https://kodo.guance.com?token=tkn_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
Note: Only one fallback rule should be set. If multiple fallback rules exist in the Sinker configuration, the last one takes precedence.
Token Rules¶
Since Datakit will check the tokens on Dataway, the token
(including secret_token
) set here must meet the following conditions:
Start with
token_
ortkn_
, followed by 32 characters.
For tokens that do not meet these conditions, Datakit installation will fail.
Datakit End Configuration¶
In Datakit, we need to make a few settings so that it can tag the collected data with specific labels for grouping.
- Configure the Global Custom Key List
Datakit will search for fields with these Keys in its collected data (only string type fields are searched) and extract them as the basis for grouped sending.
- Configure "Global Host Tag" and "Global Election Tag"
All Datakit uploaded data will carry the configured global tags (including tag key and tag value) as the basis for grouped sending.
Datakit End Customer Key Configuration¶
If you want the data collected by a specific Datakit to meet the requirements for diversion, ensure the following points:
- Datakit has enabled the Sinker feature
- Datakit has configured an effective Global Customer Key
These configurations are as follows:
# /usr/local/datakit/conf.d/datakit.conf
[dataway]
# Specify a group of customer keys
global_customer_keys = [
# Example: Add category and class two keys
# Not too many keys should be configured here, generally 2 ~ 3 keys are sufficient
"category",
"class",
]
# Enable sinker functionality
enable_sinker = true
Besides testing data and regular data classifications, it also supports Session Replay and Profiling binary file data. Therefore, all field names can be selected here, but note that non-string type fields should not be configured, normal Keys generally come from Tags (all Tag values are string types). Datakit will not use non-string type fields as diversion criteria.
Influence of Global Tags¶
Besides global_customer_keys
, the global Tags configured on Datakit (including global election Tags and global host Tags) also affect the diversion marking. That is, if the data point contains fields that appear in the global Tags (these field values must be string types), they will also be included in the diversion. Assume the global election Tags are as follows:
For the following data point:
Since the global election Tags contain cluster
(regardless of the value configured for the Tag), the point itself also has the cluster
Tag. In the final X-Global-Tags
, cluster=cluster_A
will be appended:
If global_customer_keys
also configures app
as a key, the final diversion Header will be (the order of the key-value pairs is not important):
Note
In this example, the value of cluster
configured in datakit.conf is intentionally set differently from the cluster
field value in the data point, mainly to emphasize the influence of the Tag Key. You can understand that once a qualified global Tag Key appears in the data point, its effect is equivalent to adding this global Tag Key to global_customer_keys
.
Dataway Sink Command¶
Starting from version Version-1.3.6, Dataway supports managing sinker
configurations via the command line. Specific usage is as follows:
$ ./dataway sink --help
Usage of sink:
-add string
single rule json file
-cfg-file string
configure file (default "/usr/local/cloudcare/dataflux/dataway/dataway.yaml")
-file string
file path of the rule json, only used for command put and get
-get
get the rule json
-list
list rules
-log string
log file path (default "/dev/null")
-put
save the rule json
-token string
rules filtered by token, eg: xx,yy
Specifying Configuration File
By default, the command loads the configuration file /usr/local/cloudcare/dataflux/dataway/dataway.yaml
. If you need to load other configurations, specify it through --cfg-file
.
Command Log Settings
By default, command output logs are disabled. To view them, set the --log
parameter.
# Output log to stdout
$ ./dataway sink --list --log stdout
# Output log to file
$ ./dataway sink --list --log /tmp/log
Viewing Rule List
# List all rules
$ ./dataway sink --list
# List all rules filtered by token
$ ./dataway sink --list --token=token1,token2
CreateRevision: 2
ModRevision: 41
Version: 40
Rules:
[
{
"rules": [
"{ workspace = 'zhengb-test'}"
],
"url": "https://openway.guance.com?token=token1"
}
]
Adding Rules
Create a rule file rule.json
, reference content as follows:
[
{
"rules": [
"{ host = 'HOST1'}"
],
"url": "https://openway.guance.com?token=tkn_xxxxxxxxxxxxx"
},
{
"rules": [
"{ host = 'HOST2'}"
],
"url": "https://openway.guance.com?token=tkn_yyyyyyyyyyyyy"
}
]
Add rules
Exporting Configuration
Exporting configuration allows exporting the sinker
configuration to a local file.
Writing Configuration
Writing rules synchronizes the local rule file to sinker
.
Create a rule file sink-put.json
, reference content as follows:
{
"rules": [
{
"rules": [
"{ workspace = 'test'}"
],
"url": "https://openway.guance.com?token=tkn_xxxxxxxxxxxxxx"
}
],
"strict": true
}
Write configuration
Configuration Examples¶
Example of dataway.yaml in Kubernetes (expand to view)
Directly specify sinker JSON in yaml:
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: deployment-utils-dataway
name: dataway
namespace: utils
spec:
replicas: 1
selector:
matchLabels:
app: deployment-utils-dataway
template:
metadata:
labels:
app: deployment-utils-dataway
annotations:
datakit/logs: |
[{"disable": true}]
datakit/prom.instances: |
[[inputs.prom]]
url = "http://$IP:9090/metrics" # Port (default 9090) depends on circumstances
source = "dataway"
measurement_name = "dw" # Fixed as this Measurement
interval = "10s"
[inputs.prom.tags]
namespace = "$NAMESPACE"
pod_name = "$PODNAME"
node_name = "$NODENAME"
spec:
affinity:
podAffinity: {}
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- deployment-utils-dataway
topologyKey: kubernetes.io/hostname
containers:
- image: registry.jiagouyun.com/dataway/dataway:1.3.6 # Select an appropriate version number
#imagePullPolicy: IfNotPresent
imagePullPolicy: Always
name: dataway
env:
- name: DW_REMOTE_HOST
value: "http://kodo.forethought-kodo:9527" # Fill in the real Kodo address or the next Dataway address
- name: DW_BIND
value: "0.0.0.0:9528"
- name: DW_UUID
value: "agnt_xxxxx" # Fill in the real Dataway UUID
- name: DW_TOKEN
value: "tkn_oooooooooooooooooooooooooooooooo" # Fill in the real Dataway token, generally the system workspace token
- name: DW_PROM_LISTEN
value: "0.0.0.0:9090"
- name: DW_SECRET_TOKEN
value: "tkn_zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
- name: DW_SINKER_FILE_PATH
value: "/usr/local/cloudcare/dataflux/dataway/sinker.json"
ports:
- containerPort: 9528
name: 9528tcp01
protocol: TCP
volumeMounts:
- mountPath: /usr/local/cloudcare/dataflux/dataway/cache
name: dataway-cache
- mountPath: /usr/local/cloudcare/dataflux/dataway/sinker.json
name: sinker
subPath: sinker.json
resources:
limits:
cpu: '4'
memory: 4Gi
requests:
cpu: 100m
memory: 512Mi
# nodeSelector:
# key: string
imagePullSecrets:
- name: registry-key
restartPolicy: Always
volumes:
- hostPath:
path: /root/dataway_cache
name: dataway-cache
- configMap:
name: sinker
name: sinker
---
apiVersion: v1
kind: Service
metadata:
name: dataway
namespace: utils
spec:
ports:
- name: 9528tcp02
port: 9528
protocol: TCP
targetPort: 9528
nodePort: 30928
selector:
app: deployment-utils-dataway
type: NodePort
---
apiVersion: v1
kind: ConfigMap
metadata:
name: sinker
namespace: utils
data:
sinker.json: |
{
"strict":true,
"rules": [
{
"rules": [
"{ project = 'xxxxx'}"
],
"url": "http://kodo.forethought-kodo:9527?token=tkn_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
},
{
"rules": [
"{ project = 'xxxxx'}"
],
"url": "http://kodo.forethought-kodo:9527?token=tkn_yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"
}
]
}
Ingress Configuration Example (Expand to View)
FAQ¶
Viewing Details of Dropped Requests¶
When a request does not meet the Sinker rules, Dataway will drop the request and increase a discard count in the metrics. During the debugging phase, we need to know the specific situation of a dropped request, especially the X-Global-Tags
information carried in the request Header.
We can search the Dataway logs using the following command:
In the output, we can see similar outputs like the following:
Troubleshooting Datakit Requests Being Dropped¶
When a Datakit request is discarded by Dataway, Dataway returns the corresponding HTTP error, and in the Datakit logs, there will be similar errors like the following:
post 3641 to http://dataway-ip:9528/v1/write/metric failed(HTTP: 406 Not Acceptable):
{"error_code":"dataway.sinkRulesNotMatched","message":"X-Global-Tags: `host=my-host',
URL: `/v1/write/metric'"}, data dropped
This error indicates that the request /v1/write/metric
was discarded because its X-Global-Tags did not satisfy any of the Dataway rules.
At the same time, in the Datakit monitor (datakit monitor -V
), in the lower-right DataWay APIs
panel, the column Status
will show Not Acceptable
, indicating that the corresponding Dataway API request was discarded.
Checking the Datakit internal metrics also reveals the corresponding metric:
$ curl -s http://localhost:9529/metrics | grep datakit_io_dataway_api_latency_seconds_count
datakit_io_dataway_api_latency_seconds_count{api="/v1/datakit/pull",status="Not Acceptable"} 50
datakit_io_dataway_api_latency_seconds_count{api="/v1/write/metric",status="Not Acceptable"} 301
Datakit Error 403¶
If the Sinker configuration on Dataway is incorrect, causing all Datakit requests to use secret_token
, and this token is not recognized by the center (Kodo), hence reporting a 403 error kodo.tokenNotFound
.
This issue might occur due to incorrect etcd username/password, causing Dataway to fail to obtain the Sinker configuration, leading Dataway to consider the current Sinker invalid and all data being directly transmitted to the center.
etcd Permission Configuration Issues¶
If the Dataway logs contain the following error, it suggests there might be permission issues:
If the permission configuration is inappropriate, all existing Dataway-based permissions can be deleted and reconfigured. Refer to here
Key Overriding Relationship on the Datakit End¶
When configuring the "Global Custom Key List", if the "Global Host Tag" and "Global Election Tag" also have keys with the same name, the corresponding Key-Value pair in the collected data is used.
For example, if the "Global Custom Key List" includes key1,key2,key3
, and the "Global Host Tag" or "Global Election Tag" also configures these keys with corresponding values, such as key1=value-1
, and in some data collection, there is also a field key1=value-from-data
, then the final grouping basis uses the key1=value-from-data
from the data, ignoring the corresponding Key Value configured in the "Global Host Tag" and "Global Election Tag".
If there are keys with the same name between the "Global Host Tag" and the "Global Election Tag", the "Global Election Tag" key takes priority. In summary, the priority of Key value sources (decreasing) is as follows:
- Collected data
- Global Election Tag
- Global Host Tag
Built-in "Global Custom Keys"¶
Datakit includes several available custom Keys by default, which generally do not appear in the collected data, but Datakit can use these Keys to group data. If there is a need for diversion in these Key dimensions, they can be added to the "Global Custom Key" list (these Keys are not configured by default). We can use the following built-in custom Keys to achieve data diversion.
Warning
Adding "Global Custom Keys" causes data to be sent in separate packages. If the granularity is too fine, it significantly reduces the efficiency of Datakit uploads. Generally, "Global Custom Keys" should not exceed three.
class
Targets object data, enabling it will divert based on object classification. For example, the object classification for Pod iskubelet_pod
, so rules can be made for Pods accordingly:
{
"strict": true,
"rules": [
{
"rules": [
"{ class = 'kubelet_pod' AND other_conditon = 'some-value' }",
],
"url": "https://kodo.guance.com?token=<YOUR-TOKEN>"
},
{
... # other rules
}
]
}
measurement
Targets metric data, we can direct specific Measurements to specific workspaces. For example, if the name of the disk Measurement isdisk
, we can write the rule as follows:
{
"strict": true,
"rules": [
{
"rules": [
"{ measurement = 'disk' AND other_conditon = 'some-value' }",
],
"url": "https://kodo.guance.com?token=<YOUR-TOKEN>"
},
{
... # other rules
}
]
}
source
Targets logs (L), eBPF network metrics (N), events (E), and RUM dataservice
Targets Tracing, Scheck, and Profilingcategory
Targets all standard data categories, whose values correspond to the "name" column of each data category (e.g., time series ismetric
, objects areobject
). Taking logs as an example, we can create diversion rules specifically for logs as follows:
{
"strict": true,
"rules": [
{
"rules": [
"{ category = 'logging' AND other_conditon = 'some-value' }",
],
"url": "https://kodo.guance.com?token=<YOUR-TOKEN>"
},
{
... # other rules
}
]
}
Special Diversion Behavior¶
Some requests initiated by Datakit aim to pull resources from the center or perform self-identification. These actions are already atomic and cannot be further divided, nor can these requests be distributed to multiple workspaces (because Datakit needs to handle the return of these API requests and decide its subsequent behavior). Hence, these APIs can only be diverted to one workspace.
If multiple conditions are met in the diversion rules, these APIs will only be diverted to the workspace specified by the first rule that meets the condition.
Below is an example of such diversion:
We recommend adding the following rule in the Sinker rules, so that these API requests already present in Datakit can be routed to a specific workspace.
{
"strict": true,
"info": "Special workspace (used only for data pulling and similar APIs)",
"rules": [
{
"rules": [
"{ __dataway_api in ['/v1/datakit/pull', '/v1/election', '/v1/election/heartbeat', '/v1/query/raw', '/v1/workspace', '/v1/object/labels', '/v1/check/token'] }",
],
"url": "https://kodo.guance.com?token=<SOME-SPECIAL-WORKSPACE-TOKEN>"
}
]
}
Info
Explanation of these API URLs:
/v1/election
: Election request/v1/election/heartbeat
: Election heartbeat request/v1/datakit/pull
: Pull Pipeline and blacklist configurations from the center/v1/query/raw
: DQL query/v1/workspace
: Get workspace information/v1/object/labels
: Update/Delete object data/v1/check/token
: Check workspace Token information
Here, the key __dataway_api
does not need to be configured in the global_customer_keys
in datakit.conf. Dataway defaults this as a diversion Key, using the current request's API route as its value. That is, for a certain API:
Its final diversion effect is the same as the following:
Therefore, we can directly use the KV pair __dataway_api
in the Sink rule for matching. This also reminds us that in this special rule, do not include other important data upload APIs, such as /v1/write/...
interfaces, otherwise, the space where the data eventually lands is undefined.