diff --git a/inventory/group_vars/k8s-cluster.yml b/inventory/group_vars/k8s-cluster.yml
index 8f79f3297653c0ebdb5d843f393208aaed8d1a8e..24b036662f6eeb8dfa7099e5253bf1932bd09438 100644
--- a/inventory/group_vars/k8s-cluster.yml
+++ b/inventory/group_vars/k8s-cluster.yml
@@ -109,6 +109,10 @@ kube_apiserver_insecure_port: 8080 # (http)
 # Set to 0 to disable insecure port - Requires RBAC in authorization_modes and kube_api_anonymous_auth: true
 #kube_apiserver_insecure_port: 0 # (disabled)
 
+# Kube-proxy proxyMode configuration.
+# Can be ipvs, iptables
+kube_proxy_mode: iptables 
+
 # DNS configuration.
 # Kubernetes cluster name, also will be used as DNS domain
 cluster_name: cluster.local
diff --git a/roles/kubernetes/master/templates/kubeadm-config.yaml.j2 b/roles/kubernetes/master/templates/kubeadm-config.yaml.j2
index 26e3b46a46de4db10a9b88056f121dd3f21ba510..c1bb41f74b3dcbf896c67ae80825b277d4680b3c 100644
--- a/roles/kubernetes/master/templates/kubeadm-config.yaml.j2
+++ b/roles/kubernetes/master/templates/kubeadm-config.yaml.j2
@@ -19,6 +19,12 @@ kubernetesVersion: {{ kube_version }}
 {% if cloud_provider is defined and cloud_provider != "gce" %}
 cloudProvider: {{ cloud_provider }}
 {% endif %}
+{% if kube_proxy_mode == 'ipvs' %}
+kubeProxy:
+  config:
+    featureGates: SupportIPVSProxyMode=true
+    mode: ipvs
+{% endif %}
 authorizationModes:
 {% for mode in authorization_modes %}
 - {{ mode }}
diff --git a/roles/kubernetes/node/defaults/main.yml b/roles/kubernetes/node/defaults/main.yml
index 037c5989625a167102d1fbfe6e12c13e98697855..8540aa1597799c6834d91e41228f6236e6447e4e 100644
--- a/roles/kubernetes/node/defaults/main.yml
+++ b/roles/kubernetes/node/defaults/main.yml
@@ -14,6 +14,7 @@ kubelet_bind_address: "{{ ip | default('0.0.0.0') }}"
 # resolv.conf to base dns config
 kube_resolv_conf: "/etc/resolv.conf"
 
+# Can be ipvs, iptables
 kube_proxy_mode: iptables
 
 # If using the pure iptables proxy, SNAT everything. Note that it breaks any
diff --git a/roles/kubernetes/node/tasks/main.yml b/roles/kubernetes/node/tasks/main.yml
index 100c38c468c7d7e7df451b5e82ef87a5a9fa24d6..58fabb937a8b491d3ed4020640f51914b36b48e5 100644
--- a/roles/kubernetes/node/tasks/main.yml
+++ b/roles/kubernetes/node/tasks/main.yml
@@ -104,6 +104,20 @@
     - net.bridge.bridge-nf-call-arptables
     - net.bridge.bridge-nf-call-ip6tables
 
+- name: Modprode Kernel Module for IPVS
+  modprobe:
+    name: "{{ item }}"
+    state: present
+  when: kube_proxy_mode == 'ipvs'
+  with_items:
+    - ip_vs
+    - ip_vs_rr
+    - ip_vs_wrr
+    - ip_vs_sh
+    - nf_conntrack_ipv4
+  tags:
+    - kube-proxy
+
 - name: Write proxy manifest
   template:
     src: manifests/kube-proxy.manifest.j2
diff --git a/roles/kubernetes/node/templates/manifests/kube-proxy.manifest.j2 b/roles/kubernetes/node/templates/manifests/kube-proxy.manifest.j2
index daf0fcb4f825d56958fbc36cd8016c4820a62fb7..55862944f1c70f35c1ce464c2989a3ae80c6af6c 100644
--- a/roles/kubernetes/node/templates/manifests/kube-proxy.manifest.j2
+++ b/roles/kubernetes/node/templates/manifests/kube-proxy.manifest.j2
@@ -33,6 +33,13 @@ spec:
     - --proxy-mode={{ kube_proxy_mode }}
 {% if kube_proxy_masquerade_all and kube_proxy_mode == "iptables" %}
     - --masquerade-all
+{% elif kube_proxy_mode == 'ipvs' %}
+    - --masquerade-all
+    - --feature-gates=SupportIPVSProxyMode=true
+    - --proxy-mode=ipvs
+    - --ipvs-min-sync-period=5s
+    - --ipvs-sync-period=5s
+    - --ipvs-scheduler=rr
 {% endif %}
     securityContext:
       privileged: true