diff --git a/roles/kubernetes/control-plane/defaults/main/main.yml b/roles/kubernetes/control-plane/defaults/main/main.yml
index 7c2171327b13ff038f25d2d479613f2b79c96606..fd7047767cd269844846f4af886e37e4a641d058 100644
--- a/roles/kubernetes/control-plane/defaults/main/main.yml
+++ b/roles/kubernetes/control-plane/defaults/main/main.yml
@@ -235,3 +235,8 @@ kubeadm_upgrade_auto_cert_renewal: true
 
 # Bash alias of kubectl to interact with Kubernetes cluster much easier
 # kubectl_alias: k
+
+## Enable distributed tracing for kube-apiserver
+kube_apiserver_tracing: false
+kube_apiserver_tracing_endpoint: 0.0.0.0:4317
+kube_apiserver_tracing_sampling_rate_per_million: 100
diff --git a/roles/kubernetes/control-plane/tasks/kubeadm-setup.yml b/roles/kubernetes/control-plane/tasks/kubeadm-setup.yml
index dcad832ba89a83d8538d3577b7e7a5b8e7070d47..1f4ff20a3c64cdd804e0ad4ab9a0e3d525576d10 100644
--- a/roles/kubernetes/control-plane/tasks/kubeadm-setup.yml
+++ b/roles/kubernetes/control-plane/tasks/kubeadm-setup.yml
@@ -68,6 +68,20 @@
     mode: 0640
   when: kubernetes_audit_webhook | default(false)
 
+- name: Create apiserver tracing config directory
+  file:
+    path: "{{ kube_config_dir }}/tracing"
+    state: directory
+    mode: 0640
+  when: kube_apiserver_tracing
+
+- name: Write apiserver tracing config yaml
+  template:
+    src: apiserver-tracing.yaml.j2
+    dest: "{{ kube_config_dir }}/tracing/apiserver-tracing.yaml"
+    mode: 0640
+  when: kube_apiserver_tracing
+
 # Nginx LB(default), If kubeadm_config_api_fqdn is defined, use other LB by kubeadm controlPlaneEndpoint.
 - name: Set kubeadm_config_api_fqdn define
   set_fact:
diff --git a/roles/kubernetes/control-plane/templates/apiserver-tracing.yaml.j2 b/roles/kubernetes/control-plane/templates/apiserver-tracing.yaml.j2
new file mode 100644
index 0000000000000000000000000000000000000000..98decde86b8561debe1b676c6f7a7cef9606fd5d
--- /dev/null
+++ b/roles/kubernetes/control-plane/templates/apiserver-tracing.yaml.j2
@@ -0,0 +1,4 @@
+apiVersion: apiserver.config.k8s.io/v1beta1
+kind: TracingConfiguration
+endpoint: {{ kube_apiserver_tracing_endpoint }}
+samplingRatePerMillion: {{ kube_apiserver_tracing_sampling_rate_per_million }}
\ No newline at end of file
diff --git a/roles/kubernetes/control-plane/templates/kubeadm-config.v1beta3.yaml.j2 b/roles/kubernetes/control-plane/templates/kubeadm-config.v1beta3.yaml.j2
index cbb22182315cf200f009724c820b5b3c568adb2e..b11fb33431eddc5df9f6759a8688f2c6b11a8f89 100644
--- a/roles/kubernetes/control-plane/templates/kubeadm-config.v1beta3.yaml.j2
+++ b/roles/kubernetes/control-plane/templates/kubeadm-config.v1beta3.yaml.j2
@@ -227,6 +227,9 @@ apiServer:
 {% if kubelet_rotate_server_certificates %}
     kubelet-certificate-authority: {{ kube_cert_dir }}/ca.crt
 {% endif %}
+{% if kube_apiserver_tracing %}
+    tracing-config-file: {{ kube_config_dir }}/tracing/apiserver-tracing.yaml
+{% endif %}
 {% if kubernetes_audit or kube_token_auth | default(true) or kube_webhook_token_auth | default(false) or ( cloud_provider is defined and cloud_provider in ["openstack", "azure", "vsphere", "aws", "gce"] ) or apiserver_extra_volumes or ssl_ca_dirs | length %}
   extraVolumes:
 {% if cloud_provider is defined and cloud_provider in ["openstack", "azure", "vsphere", "aws", "gce"] %}
@@ -267,6 +270,13 @@ apiServer:
     readOnly: false
     pathType: DirectoryOrCreate
 {% endif %}
+{% if kube_apiserver_tracing %}
+  - name: tracing
+    hostPath: {{ kube_config_dir }}/tracing
+    mountPath: {{ kube_config_dir }}/tracing
+    readOnly: true
+    pathType: DirectoryOrCreate
+{% endif %}
 {% for volume in apiserver_extra_volumes %}
   - name: {{ volume.name }}
     hostPath: {{ volume.hostPath }}
diff --git a/roles/kubernetes/node/defaults/main.yml b/roles/kubernetes/node/defaults/main.yml
index 643551d9eaeaeb687ecd0929d68194a646ea2bdb..b3f8fbf10fab3c8bf6cf65b7b915e980988b32fb 100644
--- a/roles/kubernetes/node/defaults/main.yml
+++ b/roles/kubernetes/node/defaults/main.yml
@@ -253,3 +253,9 @@ kube_proxy_ipvs_modules:
 conntrack_modules:
   - nf_conntrack
   - nf_conntrack_ipv4
+
+
+## Enable distributed tracing for kubelet
+kubelet_tracing: false
+kubelet_tracing_endpoint: 0.0.0.0:4317
+kubelet_tracing_sampling_rate_per_million: 100
\ No newline at end of file
diff --git a/roles/kubernetes/node/templates/kubelet-config.v1beta1.yaml.j2 b/roles/kubernetes/node/templates/kubelet-config.v1beta1.yaml.j2
index 1cd00992af79d67666c5575cded2df8492e0fdc8..ba90fc9c8d3a203f38b44e0d81d3ee5f8d078698 100644
--- a/roles/kubernetes/node/templates/kubelet-config.v1beta1.yaml.j2
+++ b/roles/kubernetes/node/templates/kubelet-config.v1beta1.yaml.j2
@@ -166,3 +166,8 @@ topologyManagerPolicy: {{ kubelet_topology_manager_policy }}
 {% if kubelet_topology_manager_scope is defined %}
 topologyManagerScope: {{ kubelet_topology_manager_scope }}
 {% endif %}
+{% if kubelet_tracing %}
+tracing:
+  endpoint: {{ kubelet_tracing_endpoint }}
+  samplingRatePerMillion: {{ kubelet_tracing_sampling_rate_per_million }}
+{% endif %}
\ No newline at end of file