Prerequisites
Kubernetes cluster on a Linux Host with supported Kernel (5.10+)
Helm (for generating the base template)
(For cloud-connected mode) Registration Token: Valid registration token from app.qpoint.io
Deployment Steps
If you'd like to use our Helm Chart as a base for building a Kubernetes Manifest, you can do so with the following instructions. Otherwise, you can simply use the Cloud Connected or Local examples below.
Generate Base Kubernetes Manifest
First, use Helm to generate a base Kubernetes manifest:
Copy helm repo add qpoint https://helm.qpoint.io/
helm repo update
helm template qpoint-tap qpoint/qpoint-tap > qtap-base.yaml
This command generates a base manifest file named qtap-base.yaml
.
Modify the Generated Manifest
Edit qtap-base.yaml
to customize it for your deployment:
Cloud-Connected Mode
Add your registration token to the DaemonSet's environment variables:
Copy env :
- name : REGISTRATION_TOKEN
value : "your-registration-token-here"
Local Mode
Locate the ConfigMap in the generated YAML and replace the content of tap-config.yaml
with your Qtap configuration :
Copy apiVersion : v1
kind : ConfigMap
metadata :
name : qpoint-tap-config
data :
tap-config.yaml : |
# Your Qtap configuration goes here
stacks:
stdout:
middlewares:
- wasm: builtin
name: access_logs
config: '{"mode":"full"}'
tap:
direction: egress-external
audit_logs: stdout
audit_include_dns: false
ignore_loopback: false
http:
stack: stdout
Deploy Qtap
Apply the modified manifest to your cluster:
Copy kubectl apply -f qtap-base.yaml -n qpoint
Verifying the Deployment
To verify that Qtap is running:
Copy kubectl get pods -n qpoint
You should see pods named qpoint-tap-xxxx
in the Running state.
Uninstalling Qtap
To uninstall Qtap:
Copy kubectl delete -f qtap-base.yaml -n qpoint
Important Notes
The Qtap pod requires privileged access for eBPF operations. Ensure your cluster's security policies allow this.
For cloud-connected mode, keep your registration token secure and do not share it in public repositories.
For local mode, ensure your configuration is correctly formatted and contains all necessary settings.
The default configuration mounts the host's /sys
directory. Ensure this is allowed in your cluster.
You may need to adjust resource requests and limits based on your cluster's capacity and Qtap's requirements.
This deployment uses a DaemonSet to ensure Qtap runs on every node in your cluster. Adjust if this is not your intended behavior.
The base manifest generated by Helm may include additional resources or configurations. Review and adjust as necessary for your environment.
Customization
The generated manifest provides a starting point. You may need to customize various aspects such as:
Resource limits and requests
Node selectors or tolerations
Additional volume mounts or environment variables
Always review and test your modifications in a non-production environment before deploying to production.
Cloud Connected Example
Copy helm template qpoint-tap qpoint/qpoint-tap
Copy ---
# Source: qpoint-tap/templates/serviceaccount.yaml
apiVersion : v1
kind : ServiceAccount
metadata :
name : qpoint-tap
labels :
app.kubernetes.io/name : qpoint-tap
app.kubernetes.io/instance : qpoint-tap
app.kubernetes.io/version : "v0.5.12"
automountServiceAccountToken : true
---
# Source: qpoint-tap/templates/daemonset.yaml
apiVersion : apps/v1
kind : DaemonSet
metadata :
name : qpoint-tap
labels :
app.kubernetes.io/name : qpoint-tap
app.kubernetes.io/instance : qpoint-tap
app.kubernetes.io/version : "v0.5.12"
spec :
selector :
matchLabels :
app.kubernetes.io/name : qpoint-tap
app.kubernetes.io/instance : qpoint-tap
template :
metadata :
labels :
app.kubernetes.io/name : qpoint-tap
app.kubernetes.io/instance : qpoint-tap
app.kubernetes.io/version : "v0.5.12"
spec :
hostPID : true
hostNetwork : true
serviceAccountName : qpoint-tap
securityContext :
null
containers :
- name : qpoint-tap
securityContext :
allowPrivilegeEscalation : true
capabilities :
add :
- CAP_BPF
- CAP_SYS_ADMIN
privileged : true
readOnlyRootFilesystem : false
runAsGroup : 0
runAsNonRoot : false
runAsUser : 0
image : "us-docker.pkg.dev/qpoint-edge/public/qpoint:v0.5.12"
imagePullPolicy : IfNotPresent
args :
- tap
env :
- name : REGISTRATION_TOKEN
value : "your-registration-token-here"
- name : REGISTRATION_ENDPOINT
value : "https://api.qpoint.io"
- name : STATUS_LISTEN
value : "0.0.0.0:10001"
- name : LOG_LEVEL
value : "info"
- name : LOG_ENCODING
value : "json"
- name : TINI_SUBREAPER
value : "1"
ports :
- name : status
containerPort : 10001
protocol : TCP
startupProbe :
httpGet :
path : /readyz
port : status
initialDelaySeconds : 3
periodSeconds : 5
timeoutSeconds : 2
successThreshold : 1
failureThreshold : 20
readinessProbe :
httpGet :
path : /readyz
port : status
initialDelaySeconds : 3
periodSeconds : 5
timeoutSeconds : 2
successThreshold : 1
failureThreshold : 1
livenessProbe :
httpGet :
path : /healthz
port : status
initialDelaySeconds : 3
periodSeconds : 10
timeoutSeconds : 2
successThreshold : 1
failureThreshold : 3
resources :
limits :
cpu : 1000m
memory : 1Gi
requests :
cpu : 100m
memory : 128Mi
volumeMounts :
- mountPath : /sys
name : sys
readOnly : true
volumes :
- hostPath :
path : /sys
type : Directory
name : sys
Local Example
Copy helm template qpoint-tap qpoint/qpoint-tap
Copy ---
# Source: qpoint-tap/templates/serviceaccount.yaml
apiVersion : v1
kind : ServiceAccount
metadata :
name : qpoint-tap
labels :
app.kubernetes.io/name : qpoint-tap
app.kubernetes.io/instance : qpoint-tap
app.kubernetes.io/version : "v0.5.12"
automountServiceAccountToken : true
---
# Source: qpoint-tap/templates/configmap.yaml
apiVersion : v1
kind : ConfigMap
metadata :
name : qpoint-tap-config
labels :
app.kubernetes.io/name : qpoint-tap
app.kubernetes.io/instance : qpoint-tap
app.kubernetes.io/version : "v0.5.12"
data :
tap-config.yaml : |
stacks:
stdout:
middlewares:
- wasm: builtin
name: access_logs
config: '{"mode":"full"}'
tap:
direction: egress-external
audit_logs: stdout
audit_include_dns: false
ignore_loopback: false
http:
stack: stdout
---
# Source: qpoint-tap/templates/daemonset.yaml
apiVersion : apps/v1
kind : DaemonSet
metadata :
name : qpoint-tap
labels :
app.kubernetes.io/name : qpoint-tap
app.kubernetes.io/instance : qpoint-tap
app.kubernetes.io/version : "v0.5.12"
spec :
selector :
matchLabels :
app.kubernetes.io/name : qpoint-tap
app.kubernetes.io/instance : qpoint-tap
template :
metadata :
labels :
app.kubernetes.io/name : qpoint-tap
app.kubernetes.io/instance : qpoint-tap
app.kubernetes.io/version : "v0.5.12"
spec :
hostPID : true
hostNetwork : true
serviceAccountName : qpoint-tap
securityContext :
null
containers :
- name : qpoint-tap
securityContext :
allowPrivilegeEscalation : true
capabilities :
add :
- CAP_BPF
- CAP_SYS_ADMIN
privileged : true
readOnlyRootFilesystem : false
runAsGroup : 0
runAsNonRoot : false
runAsUser : 0
image : "us-docker.pkg.dev/qpoint-edge/public/qpoint:v0.5.12"
imagePullPolicy : IfNotPresent
args :
- tap
- --qpoint-config=/app/tap-config.yaml
env :
- name : STATUS_LISTEN
value : "0.0.0.0:10001"
- name : LOG_LEVEL
value : "info"
- name : LOG_ENCODING
value : "json"
- name : TINI_SUBREAPER
value : "1"
ports :
- name : status
containerPort : 10001
protocol : TCP
startupProbe :
httpGet :
path : /readyz
port : status
initialDelaySeconds : 3
periodSeconds : 5
timeoutSeconds : 2
successThreshold : 1
failureThreshold : 20
readinessProbe :
httpGet :
path : /readyz
port : status
initialDelaySeconds : 3
periodSeconds : 5
timeoutSeconds : 2
successThreshold : 1
failureThreshold : 1
livenessProbe :
httpGet :
path : /healthz
port : status
initialDelaySeconds : 3
periodSeconds : 10
timeoutSeconds : 2
successThreshold : 1
failureThreshold : 3
resources :
limits :
cpu : 1000m
memory : 1Gi
requests :
cpu : 100m
memory : 128Mi
volumeMounts :
- name : config-volume
mountPath : /app/tap-config.yaml
subPath : tap-config.yaml
- mountPath : /sys
name : sys
readOnly : true
volumes :
- name : config-volume
configMap :
name : qpoint-tap-config
items :
- key : tap-config.yaml
path : tap-config.yaml
- hostPath :
path : /sys
type : Directory
name : sys