{"id":29818,"date":"2025-10-28T17:11:19","date_gmt":"2025-10-28T11:41:19","guid":{"rendered":"https:\/\/opstree.com\/blog\/?p=29818"},"modified":"2025-11-20T14:47:27","modified_gmt":"2025-11-20T09:17:27","slug":"ingress-solution-with-envoy-proxy-on-kubernetes","status":"publish","type":"post","link":"https:\/\/opstree.com\/blog\/2025\/10\/28\/ingress-solution-with-envoy-proxy-on-kubernetes\/","title":{"rendered":"Building a High-Availability Ingress Solution with Envoy Proxy on Kubernetes"},"content":{"rendered":"<h2 id=\"aed6\" class=\"mj mk gm bg ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng bl\" data-selectable-paragraph=\"\">Moving from External Load Balancer to Cloud-Native Architecture<\/h2>\n<h3 id=\"cf43\" class=\"mj mk gm bg ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng bl\">The Challenge<\/h3>\n<p id=\"4849\" class=\"pw-post-body-paragraph nh ni gm nj b nk nl nm nn no np nq nr ns nt nu nv nw nx ny nz oa ob oc od oe gf bl\" data-selectable-paragraph=\"\">In on-premise Kubernetes deployments, achieving high availability for ingress traffic often relies on external load balancers running on dedicated VMs. While functional, this approach creates single points of failure, adds operational complexity, and wastes valuable infrastructure resources.<\/p>\n<p id=\"22eb\" class=\"pw-post-body-paragraph nh ni gm nj b nk of nm nn no og nq nr ns oh nu nv nw oi ny nz oa oj oc od oe gf bl\" data-selectable-paragraph=\"\">In this guide, I\u2019ll walk you through migrating from an external Envoy load balancer to a fully integrated, Kubernetes-native solution using DaemonSet deployments, Keepalived for VIP management, and host networking for optimal performance.<!--more--><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:700\/1*Y7sEWgIfFWBSci2duFmg6w.png\" \/><\/p>\n<h3 id=\"6da0\" class=\"mj mk gm bg ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng bl\">Architecture Overview<\/h3>\n<p id=\"45a8\" class=\"pw-post-body-paragraph nh ni gm nj b nk nl nm nn no np nq nr ns nt nu nv nw nx ny nz oa ob oc od oe gf bl\" data-selectable-paragraph=\"\"><strong class=\"nj gn\">Before: External VM Architecture<\/strong><\/p>\n<pre class=\"ok ol om on oo op oq or bq os bc bl\"><span id=\"6656\" class=\"ot mk gm oq b bh ou ov m ow ox\" data-selectable-paragraph=\"\">Internet \u2192 External VM (Envoy) \u2192 Kong Gateway \u2192 Applications\r\n         (<span class=\"hljs-number\">192.168<\/span>.<span class=\"hljs-number\">10.100<\/span>)\r\n         Single Point of Failure \u274c<\/span><\/pre>\n<figure class=\"ok ol om on oo md lv lw paragraph-image\">\n<div class=\"me mf em mg bi mh\" tabindex=\"0\" role=\"button\">\n<div class=\"lv lw oy\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:700\/1*4P07kWhblmR-y5rA5hl4Zw.png\" \/><\/div>\n<\/div>\n<\/figure>\n<p id=\"da18\" class=\"pw-post-body-paragraph nh ni gm nj b nk of nm nn no og nq nr ns oh nu nv nw oi ny nz oa oj oc od oe gf bl\" data-selectable-paragraph=\"\"><strong class=\"nj gn\">After: Cloud-Native Architecture<\/strong><\/p>\n<pre class=\"ok ol om on oo op oq or bq os bc bl\"><span id=\"4a30\" class=\"ot mk gm oq b bh ou ov m ow ox\" data-selectable-paragraph=\"\">Internet \u2192 Keepalived VIP \u2192 Envoy DaemonSet \u2192 Kong Gateway \u2192 Applications\r\n         (<span class=\"hljs-number\">192.168<\/span>.<span class=\"hljs-number\">10.200<\/span>)      (<span class=\"hljs-number\">5<\/span>+ nodes)\r\n         Highly Available \u2705<\/span><\/pre>\n<figure class=\"ok ol om on oo md lv lw paragraph-image\">\n<div class=\"me mf em mg bi mh\" tabindex=\"0\" role=\"button\">\n<div class=\"lv lw oz\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:700\/1*vUpqHkIbh9nLn2ux8_3lUg.png\" \/><\/div>\n<\/div>\n<\/figure>\n<div style=\"max-width: 700px; margin: 24px auto; padding: 16px 12px; background: #f8fafc; border-left: 4px solid #0056b3; border-radius: 6px; text-align: center;\">\n<p style=\"font-size: clamp(1rem,2.5vw,1.1rem); color: #1f2937; margin: 0;\">Also Read: <a href=\"https:\/\/opstree.com\/blog\/2025\/09\/09\/complete-guide-to-kubernetes-crds\/\">A Complete Guide to Kubernetes CRDs: Definition, Uses , Benefits, and Error Fixes<\/a>.<span style=\"background-color: #ffffff; color: #1a1a1a; font-size: 16px;\">\u00a0<\/span><\/p>\n<\/div>\n<h2 id=\"f5fd\" class=\"mj mk gm bg ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng bl\" data-selectable-paragraph=\"\">Our Infrastructure<\/h2>\n<ul class=\"\">\n<li id=\"9f5d\" class=\"nh ni gm nj b nk nl nm nn no np nq nr ns nt nu nv nw nx ny nz oa ob oc od oe pa pb pc bl\" data-selectable-paragraph=\"\"><strong class=\"nj gn\">Kubernetes Cluster<\/strong>: v1.31.4 with 3 control planes and 9 worker nodes<\/li>\n<li id=\"7892\" class=\"nh ni gm nj b nk pd nm nn no pe nq nr ns pf nu nv nw pg ny nz oa ph oc od oe pa pb pc bl\" data-selectable-paragraph=\"\"><strong class=\"nj gn\">Container Runtime<\/strong>: containerd 1.7.24<\/li>\n<li id=\"9e72\" class=\"nh ni gm nj b nk pd nm nn no pe nq nr ns pf nu nv nw pg ny nz oa ph oc od oe pa pb pc bl\" data-selectable-paragraph=\"\"><strong class=\"nj gn\">Ingress Controller<\/strong>: Kong Gateway 3.9.1<\/li>\n<li id=\"0a71\" class=\"nh ni gm nj b nk pd nm nn no pe nq nr ns pf nu nv nw pg ny nz oa ph oc od oe pa pb pc bl\" data-selectable-paragraph=\"\"><strong class=\"nj gn\">Load Balancer<\/strong>: Keepalived + IPVS<\/li>\n<li id=\"cf05\" class=\"nh ni gm nj b nk pd nm nn no pe nq nr ns pf nu nv nw pg ny nz oa ph oc od oe pa pb pc bl\" data-selectable-paragraph=\"\"><strong class=\"nj gn\">Proxy Layer<\/strong>: Envoy Proxy v1.31<\/li>\n<\/ul>\n<figure class=\"ok ol om on oo md lv lw paragraph-image\">\n<div class=\"me mf em mg bi mh\" tabindex=\"0\" role=\"button\">\n<div class=\"lv lw pi\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:700\/1*IUPOdhRcZ6e3Jd-5tRSwJQ.png\" \/><\/div>\n<\/div>\n<\/figure>\n<h3 id=\"ee5c\" class=\"mj mk gm bg ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng bl\">Step 1: Deploy Envoy as DaemonSet<\/h3>\n<p id=\"a6a7\" class=\"pw-post-body-paragraph nh ni gm nj b nk nl nm nn no np nq nr ns nt nu nv nw nx ny nz oa ob oc od oe gf bl\" data-selectable-paragraph=\"\">The first step is deploying Envoy on all worker nodes using a DaemonSet with host networking enabled. This ensures every worker node can receive traffic directly.<\/p>\n<h4 id=\"aec5\" class=\"pj mk gm bg ml pk pl pm mp pn po pp mt ns pq pr ps nw pt pu pv oa pw px py pz bl\">ConfigMap for Envoy Configuration<\/h4>\n<pre class=\"ok ol om on oo op oq or bq os bc bl\"><span id=\"4099\" class=\"ot mk gm oq b bh ou ov m ow ox\" data-selectable-paragraph=\"\"><span class=\"hljs-attr\">apiVersion:<\/span> <span class=\"hljs-string\">v1<\/span>\r\n<span class=\"hljs-attr\">kind:<\/span> <span class=\"hljs-string\">ConfigMap<\/span>\r\n<span class=\"hljs-attr\">metadata:<\/span>\r\n  <span class=\"hljs-attr\">name:<\/span> <span class=\"hljs-string\">envoy-config<\/span>\r\n  <span class=\"hljs-attr\">namespace:<\/span> <span class=\"hljs-string\">envoy-system<\/span>\r\n<span class=\"hljs-attr\">data:<\/span>\r\n  <span class=\"hljs-attr\">envoy.yaml:<\/span> <span class=\"hljs-string\">|\r\n    static_resources:\r\n      listeners:\r\n      - name: listener_http\r\n        address:\r\n          socket_address:\r\n            address: 0.0.0.0\r\n            port_value: 80\r\n        filter_chains:\r\n        - filters:\r\n          - name: envoy.filters.network.tcp_proxy\r\n            typed_config:\r\n              \"@type\": type.googleapis.com\/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy\r\n              stat_prefix: tcp_http\r\n              cluster: cluster_http<\/span><\/span><\/pre>\n<pre class=\"qa op oq qb qc ak qd bl\"><span id=\"8983\" class=\"pj mk gm oq b qe qf qg m qh ox\" data-selectable-paragraph=\"\">      - name: listener_https\r\n        address:\r\n          socket_address:\r\n            address: 0.0.0.0\r\n            port_value: 443\r\n        filter_chains:\r\n        - filters:\r\n          - name: envoy.filters.network.tcp_proxy\r\n            typed_config:\r\n              \"@type\": type.googleapis.com\/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy\r\n              stat_prefix: tcp_https\r\n              cluster: cluster_https<\/span><span id=\"4f29\" class=\"pj mk gm oq b qe qi qg m qh ox\" data-selectable-paragraph=\"\">      clusters:\r\n      - name: cluster_http\r\n        connect_timeout: 1s\r\n        type: strict_dns\r\n        lb_policy: round_robin\r\n        load_assignment:\r\n          cluster_name: cluster_http\r\n          endpoints:\r\n          - lb_endpoints:\r\n            - endpoint:\r\n                address:\r\n                  socket_address:\r\n                    address: kong-gateway-proxy.kong.svc.cluster.local\r\n                    port_value: 80<\/span><span id=\"5f73\" class=\"pj mk gm oq b qe qi qg m qh ox\" data-selectable-paragraph=\"\">      - name: cluster_https\r\n        connect_timeout: 1s\r\n        type: strict_dns\r\n        lb_policy: round_robin\r\n        load_assignment:\r\n          cluster_name: cluster_https\r\n          endpoints:\r\n          - lb_endpoints:\r\n            - endpoint:\r\n                address:\r\n                  socket_address:\r\n                    address: kong-gateway-proxy.kong.svc.cluster.local\r\n                    port_value: 443<\/span><span id=\"1207\" class=\"pj mk gm oq b qe qi qg m qh ox\" data-selectable-paragraph=\"\">    admin:\r\n      access_log_path: \/dev\/null\r\n      address:\r\n        socket_address:\r\n          address: 0.0.0.0\r\n          port_value: 9901<\/span><\/pre>\n<h4 id=\"2cf8\" class=\"pj mk gm bg ml pk pl pm mp pn po pp mt ns pq pr ps nw pt pu pv oa pw px py pz bl\">DaemonSet Configuration<\/h4>\n<pre class=\"ok ol om on oo op oq or bq os bc bl\"><span id=\"d218\" class=\"ot mk gm oq b bh ou ov m ow ox\" data-selectable-paragraph=\"\"><span class=\"hljs-attr\">apiVersion:<\/span> <span class=\"hljs-string\">apps\/v1<\/span>\r\n<span class=\"hljs-attr\">kind:<\/span> <span class=\"hljs-string\">DaemonSet<\/span>\r\n<span class=\"hljs-attr\">metadata:<\/span>\r\n  <span class=\"hljs-attr\">name:<\/span> <span class=\"hljs-string\">envoy-proxy<\/span>\r\n  <span class=\"hljs-attr\">namespace:<\/span> <span class=\"hljs-string\">envoy-system<\/span>\r\n  <span class=\"hljs-attr\">labels:<\/span>\r\n    <span class=\"hljs-attr\">app:<\/span> <span class=\"hljs-string\">envoy-proxy<\/span>\r\n<span class=\"hljs-attr\">spec:<\/span>\r\n  <span class=\"hljs-attr\">selector:<\/span>\r\n    <span class=\"hljs-attr\">matchLabels:<\/span>\r\n      <span class=\"hljs-attr\">app:<\/span> <span class=\"hljs-string\">envoy-proxy<\/span>\r\n  <span class=\"hljs-attr\">updateStrategy:<\/span>\r\n    <span class=\"hljs-attr\">type:<\/span> <span class=\"hljs-string\">RollingUpdate<\/span>\r\n    <span class=\"hljs-attr\">rollingUpdate:<\/span>\r\n      <span class=\"hljs-attr\">maxUnavailable:<\/span> <span class=\"hljs-number\">1<\/span>\r\n  <span class=\"hljs-attr\">template:<\/span>\r\n    <span class=\"hljs-attr\">metadata:<\/span>\r\n      <span class=\"hljs-attr\">labels:<\/span>\r\n        <span class=\"hljs-attr\">app:<\/span> <span class=\"hljs-string\">envoy-proxy<\/span>\r\n      <span class=\"hljs-attr\">annotations:<\/span>\r\n        <span class=\"hljs-attr\">prometheus.io\/scrape:<\/span> <span class=\"hljs-string\">\"true\"<\/span>\r\n        <span class=\"hljs-attr\">prometheus.io\/port:<\/span> <span class=\"hljs-string\">\"9901\"<\/span>\r\n        <span class=\"hljs-attr\">prometheus.io\/path:<\/span> <span class=\"hljs-string\">\"\/stats\/prometheus\"<\/span>\r\n    <span class=\"hljs-attr\">spec:<\/span>\r\n      <span class=\"hljs-attr\">hostNetwork:<\/span> <span class=\"hljs-literal\">true<\/span>\r\n      <span class=\"hljs-attr\">dnsPolicy:<\/span> <span class=\"hljs-string\">ClusterFirstWithHostNet<\/span>\r\n      <span class=\"hljs-attr\">nodeSelector:<\/span>\r\n        <span class=\"hljs-attr\">node-role.kubernetes.io\/worker:<\/span> <span class=\"hljs-string\">\"\"<\/span>\r\n      <span class=\"hljs-attr\">tolerations:<\/span>\r\n      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-attr\">key:<\/span> <span class=\"hljs-string\">node-role.kubernetes.io\/control-plane<\/span>\r\n        <span class=\"hljs-attr\">operator:<\/span> <span class=\"hljs-string\">Exists<\/span>\r\n        <span class=\"hljs-attr\">effect:<\/span> <span class=\"hljs-string\">NoSchedule<\/span>\r\n      <span class=\"hljs-attr\">containers:<\/span>\r\n      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-attr\">name:<\/span> <span class=\"hljs-string\">envoy<\/span>\r\n        <span class=\"hljs-attr\">image:<\/span> <span class=\"hljs-string\">envoyproxy\/envoy:v1.31-latest<\/span>\r\n        <span class=\"hljs-attr\">securityContext:<\/span>\r\n          <span class=\"hljs-attr\">capabilities:<\/span>\r\n            <span class=\"hljs-attr\">add:<\/span>\r\n            <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">NET_BIND_SERVICE<\/span>\r\n          <span class=\"hljs-attr\">runAsUser:<\/span> <span class=\"hljs-number\">0<\/span>\r\n        <span class=\"hljs-attr\">ports:<\/span>\r\n        <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-attr\">containerPort:<\/span> <span class=\"hljs-number\">80<\/span>\r\n          <span class=\"hljs-attr\">hostPort:<\/span> <span class=\"hljs-number\">80<\/span>\r\n          <span class=\"hljs-attr\">name:<\/span> <span class=\"hljs-string\">http<\/span>\r\n        <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-attr\">containerPort:<\/span> <span class=\"hljs-number\">443<\/span>\r\n          <span class=\"hljs-attr\">hostPort:<\/span> <span class=\"hljs-number\">443<\/span>\r\n          <span class=\"hljs-attr\">name:<\/span> <span class=\"hljs-string\">https<\/span>\r\n        <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-attr\">containerPort:<\/span> <span class=\"hljs-number\">9901<\/span>\r\n          <span class=\"hljs-attr\">hostPort:<\/span> <span class=\"hljs-number\">9901<\/span>\r\n          <span class=\"hljs-attr\">name:<\/span> <span class=\"hljs-string\">admin<\/span>\r\n        <span class=\"hljs-attr\">volumeMounts:<\/span>\r\n        <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-attr\">name:<\/span> <span class=\"hljs-string\">envoy-config<\/span>\r\n          <span class=\"hljs-attr\">mountPath:<\/span> <span class=\"hljs-string\">\/etc\/envoy<\/span>\r\n          <span class=\"hljs-attr\">readOnly:<\/span> <span class=\"hljs-literal\">true<\/span>\r\n        <span class=\"hljs-attr\">resources:<\/span>\r\n          <span class=\"hljs-attr\">requests:<\/span>\r\n            <span class=\"hljs-attr\">cpu:<\/span> <span class=\"hljs-string\">100m<\/span>\r\n            <span class=\"hljs-attr\">memory:<\/span> <span class=\"hljs-string\">128Mi<\/span>\r\n          <span class=\"hljs-attr\">limits:<\/span>\r\n            <span class=\"hljs-attr\">cpu:<\/span> <span class=\"hljs-string\">500m<\/span>\r\n            <span class=\"hljs-attr\">memory:<\/span> <span class=\"hljs-string\">256Mi<\/span>\r\n        <span class=\"hljs-attr\">livenessProbe:<\/span>\r\n          <span class=\"hljs-attr\">httpGet:<\/span>\r\n            <span class=\"hljs-attr\">path:<\/span> <span class=\"hljs-string\">\/ready<\/span>\r\n            <span class=\"hljs-attr\">port:<\/span> <span class=\"hljs-number\">9901<\/span>\r\n          <span class=\"hljs-attr\">initialDelaySeconds:<\/span> <span class=\"hljs-number\">15<\/span>\r\n          <span class=\"hljs-attr\">periodSeconds:<\/span> <span class=\"hljs-number\">10<\/span>\r\n        <span class=\"hljs-attr\">readinessProbe:<\/span>\r\n          <span class=\"hljs-attr\">httpGet:<\/span>\r\n            <span class=\"hljs-attr\">path:<\/span> <span class=\"hljs-string\">\/ready<\/span>\r\n            <span class=\"hljs-attr\">port:<\/span> <span class=\"hljs-number\">9901<\/span>\r\n          <span class=\"hljs-attr\">initialDelaySeconds:<\/span> <span class=\"hljs-number\">5<\/span>\r\n          <span class=\"hljs-attr\">periodSeconds:<\/span> <span class=\"hljs-number\">5<\/span>\r\n      <span class=\"hljs-attr\">volumes:<\/span>\r\n      <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-attr\">name:<\/span> <span class=\"hljs-string\">envoy-config<\/span>\r\n        <span class=\"hljs-attr\">configMap:<\/span>\r\n          <span class=\"hljs-attr\">name:<\/span> <span class=\"hljs-string\">envoy-config<\/span><\/span><\/pre>\n<p id=\"011c\" class=\"pw-post-body-paragraph nh ni gm nj b nk of nm nn no og nq nr ns oh nu nv nw oi ny nz oa oj oc od oe gf bl\" data-selectable-paragraph=\"\">Deploy the configuration:<\/p>\n<pre class=\"ok ol om on oo op oq or bq os bc bl\"><span id=\"9c15\" class=\"ot mk gm oq b bh ou ov m ow ox\" data-selectable-paragraph=\"\">kubectl <span class=\"hljs-built_in\">create<\/span> namespace envoy-system\r\nkubectl apply -f envoy-<span class=\"hljs-built_in\">config<\/span>.yaml\r\nkubectl apply -f envoy-daemonset.yaml<\/span><\/pre>\n<p id=\"8db4\" class=\"pw-post-body-paragraph nh ni gm nj b nk of nm nn no og nq nr ns oh nu nv nw oi ny nz oa oj oc od oe gf bl\" data-selectable-paragraph=\"\">Verify deployment:<\/p>\n<pre class=\"ok ol om on oo op oq or bq os bc bl\"><span id=\"164f\" class=\"ot mk gm oq b bh ou ov m ow ox\" data-selectable-paragraph=\"\">kubectl <span class=\"hljs-keyword\">get<\/span> pods <span class=\"hljs-operator\">-<\/span>n envoy<span class=\"hljs-operator\">-<\/span><span class=\"hljs-keyword\">system<\/span> <span class=\"hljs-operator\">-<\/span>o wide<\/span><\/pre>\n<p id=\"3dcd\" class=\"pw-post-body-paragraph nh ni gm nj b nk of nm nn no og nq nr ns oh nu nv nw oi ny nz oa oj oc od oe gf bl\" data-selectable-paragraph=\"\">You should see one Envoy pod running on each worker node.<\/p>\n<h3 id=\"53f1\" class=\"mj mk gm bg ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng bl\">Step 2: Configure Keepalived for High Availability<\/h3>\n<p id=\"3d1d\" class=\"pw-post-body-paragraph nh ni gm nj b nk nl nm nn no np nq nr ns nt nu nv nw nx ny nz oa ob oc od oe gf bl\" data-selectable-paragraph=\"\">Keepalived provides a Virtual IP (VIP) that floats between nodes, ensuring traffic always reaches a healthy endpoint.<\/p>\n<h4 id=\"bec5\" class=\"pj mk gm bg ml pk pl pm mp pn po pp mt ns pq pr ps nw pt pu pv oa pw px py pz bl\">Install Keepalived on Worker Nodes<\/h4>\n<p id=\"7720\" class=\"pw-post-body-paragraph nh ni gm nj b nk nl nm nn no np nq nr ns nt nu nv nw nx ny nz oa ob oc od oe gf bl\" data-selectable-paragraph=\"\">On the primary node (worker2):<\/p>\n<pre class=\"ok ol om on oo op oq or bq os bc bl\"><span id=\"fdec\" class=\"ot mk gm oq b bh ou ov m ow ox\" data-selectable-paragraph=\"\">sudo apt <span class=\"hljs-keyword\">update<\/span>\r\nsudo apt install keepalived ipvsadm <span class=\"hljs-operator\">-<\/span>y<\/span><\/pre>\n<h4 id=\"086d\" class=\"pj mk gm bg ml pk pl pm mp pn po pp mt ns pq pr ps nw pt pu pv oa pw px py pz bl\">Configure Keepalived (Primary Node)<\/h4>\n<p id=\"6149\" class=\"pw-post-body-paragraph nh ni gm nj b nk nl nm nn no np nq nr ns nt nu nv nw nx ny nz oa ob oc od oe gf bl\" data-selectable-paragraph=\"\">Create\u00a0<code class=\"de qj qk ql oq b\">\/etc\/keepalived\/keepalived.conf<\/code>:<\/p>\n<pre class=\"ok ol om on oo op oq or bq os bc bl\"><span id=\"1716\" class=\"ot mk gm oq b bh ou ov m ow ox\" data-selectable-paragraph=\"\">global_defs <span class=\"hljs-punctuation\">{<\/span>\r\n    router_id LVS_WORKER2\r\n<span class=\"hljs-punctuation\">}<\/span><\/span><\/pre>\n<pre class=\"qa op oq qb qc ak qd bl\"><span id=\"db27\" class=\"pj mk gm oq b qe qf qg m qh ox\" data-selectable-paragraph=\"\">vrrp_instance VI_1 {\r\n    state MASTER\r\n    interface ens18\r\n    virtual_router_id 51\r\n    priority 100\r\n    advert_int 1\r\n    \r\n    authentication {\r\n        auth_type PASS\r\n        auth_pass secret_pass\r\n    }\r\n    \r\n    virtual_ipaddress {\r\n        192.168.10.200\/24\r\n    }\r\n}<\/span><span id=\"b4e2\" class=\"pj mk gm oq b qe qi qg m qh ox\" data-selectable-paragraph=\"\">virtual_server 192.168.10.200 80 {\r\n    delay_loop 6\r\n    lb_algo rr\r\n    lb_kind NAT\r\n    protocol TCP\r\n    \r\n    real_server 192.168.0.0 80 {\r\n        weight 1\r\n        HTTP_GET {\r\n            url {\r\n                path \/\r\n                status_code 200 302 404\r\n            }\r\n            connect_timeout 3\r\n        }\r\n    }\r\n    \r\n    real_server 192.168.0.1 80 {\r\n        weight 1\r\n        HTTP_GET {\r\n            url {\r\n                path \/\r\n                status_code 200 302 404\r\n            }\r\n            connect_timeout 3\r\n        }\r\n    }\r\n    \r\n    # Add more worker nodes as needed\r\n}<\/span><span id=\"cbb5\" class=\"pj mk gm oq b qe qi qg m qh ox\" data-selectable-paragraph=\"\">virtual_server 192.168.10.200 443 {\r\n    delay_loop 6\r\n    lb_algo rr\r\n    lb_kind NAT\r\n    protocol TCP\r\n    \r\n    real_server 192.168.0.0 443 {\r\n        weight 1\r\n        TCP_CHECK {\r\n            connect_timeout 3\r\n        }\r\n    }\r\n    \r\n    real_server 192.168.0.1 443 {\r\n        weight 1\r\n        TCP_CHECK {\r\n            connect_timeout 3\r\n        }\r\n    }\r\n    \r\n    # Add more worker nodes as needed\r\n}<\/span><\/pre>\n<h4 id=\"cfb2\" class=\"pj mk gm bg ml pk pl pm mp pn po pp mt ns pq pr ps nw pt pu pv oa pw px py pz bl\">Configure Backup Nodes<\/h4>\n<p id=\"ae87\" class=\"pw-post-body-paragraph nh ni gm nj b nk nl nm nn no np nq nr ns nt nu nv nw nx ny nz oa ob oc od oe gf bl\" data-selectable-paragraph=\"\">On backup nodes (worker3, worker4, etc.), use the same configuration but change:<\/p>\n<pre class=\"ok ol om on oo op oq or bq os bc bl\"><span id=\"e636\" class=\"ot mk gm oq b bh ou ov m ow ox\" data-selectable-paragraph=\"\">vrrp_instance VI_1 {\r\n    <span class=\"hljs-keyword\">state<\/span> BACKUP      <span class=\"hljs-comment\"># Changed from MASTER<\/span>\r\n    priority <span class=\"hljs-number\">90<\/span>       <span class=\"hljs-comment\"># Lower than master (80, 70, 60 for others)<\/span>\r\n    <span class=\"hljs-comment\"># ... rest same<\/span>\r\n}<\/span><\/pre>\n<h4 id=\"8b26\" class=\"pj mk gm bg ml pk pl pm mp pn po pp mt ns pq pr ps nw pt pu pv oa pw px py pz bl\">Enable IP Forwarding<\/h4>\n<p id=\"8ac4\" class=\"pw-post-body-paragraph nh ni gm nj b nk nl nm nn no np nq nr ns nt nu nv nw nx ny nz oa ob oc od oe gf bl\" data-selectable-paragraph=\"\">On all Keepalived nodes:<\/p>\n<pre class=\"ok ol om on oo op oq or bq os bc bl\"><span id=\"c6f8\" class=\"ot mk gm oq b bh ou ov m ow ox\" data-selectable-paragraph=\"\">sudo sysctl -w net.ipv4.ip_forward=1\r\nsudo sysctl -w net.ipv4.vs.conntrack=1<\/span><\/pre>\n<pre class=\"qa op oq qb qc ak qd bl\"><span id=\"d31e\" class=\"pj mk gm oq b qe qf qg m qh ox\" data-selectable-paragraph=\"\">echo \"net.ipv4.ip_forward = 1\" | sudo tee -a \/etc\/sysctl.conf\r\necho \"net.ipv4.vs.conntrack = 1\" | sudo tee -a \/etc\/sysctl.conf\r\nsudo sysctl -p<\/span><\/pre>\n<h4 id=\"33f3\" class=\"pj mk gm bg ml pk pl pm mp pn po pp mt ns pq pr ps nw pt pu pv oa pw px py pz bl\">Start Keepalived<\/h4>\n<pre class=\"ok ol om on oo op oq or bq os bc bl\"><span id=\"9bc6\" class=\"ot mk gm oq b bh ou ov m ow ox\" data-selectable-paragraph=\"\">sudo systemctl <span class=\"hljs-built_in\">enable<\/span> keepalived\r\nsudo systemctl start keepalived\r\nsudo systemctl status keepalived<\/span><\/pre>\n<h4 id=\"db6c\" class=\"pj mk gm bg ml pk pl pm mp pn po pp mt ns pq pr ps nw pt pu pv oa pw px py pz bl\">Verify VIP and Load Balancing<\/h4>\n<pre class=\"ok ol om on oo op oq or bq os bc bl\"><span id=\"8706\" class=\"ot mk gm oq b bh ou ov m ow ox\" data-selectable-paragraph=\"\"><span class=\"hljs-comment\"># Check VIP is active<\/span>\r\nip addr show <span class=\"hljs-punctuation\">|<\/span> grep <span class=\"hljs-number\">192.168<\/span>.<span class=\"hljs-number\">10.200<\/span><\/span><\/pre>\n<pre class=\"qa op oq qb qc ak qd bl\"><span id=\"88d5\" class=\"pj mk gm oq b qe qf qg m qh ox\" data-selectable-paragraph=\"\"># Verify IPVS configuration\r\nsudo ipvsadm -L -n<\/span><span id=\"4f4d\" class=\"pj mk gm oq b qe qi qg m qh ox\" data-selectable-paragraph=\"\"># Test load balancing\r\nfor i in {1..10}; do\r\n  curl -s http:\/\/192.168.10.200 | head -1\r\ndone<\/span><\/pre>\n<h3 id=\"e2eb\" class=\"mj mk gm bg ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng bl\">Step 3: DNS Configuration<\/h3>\n<p id=\"2180\" class=\"pw-post-body-paragraph nh ni gm nj b nk nl nm nn no np nq nr ns nt nu nv nw nx ny nz oa ob oc od oe gf bl\" data-selectable-paragraph=\"\">Update your DNS to point to the VIP:<\/p>\n<p id=\"c309\" class=\"pw-post-body-paragraph nh ni gm nj b nk of nm nn no og nq nr ns oh nu nv nw oi ny nz oa oj oc od oe gf bl\" data-selectable-paragraph=\"\"><strong class=\"nj gn\">For Cloudflare:<\/strong><\/p>\n<pre class=\"ok ol om on oo op oq or bq os bc bl\"><span id=\"46ff\" class=\"ot mk gm oq b bh ou ov m ow ox\" data-selectable-paragraph=\"\"><span class=\"hljs-attr\">Type:<\/span> <span class=\"hljs-string\">A<\/span>\r\n<span class=\"hljs-attr\">Name:<\/span> <span class=\"hljs-string\">*.opstree.dev<\/span>\r\n<span class=\"hljs-attr\">Content:<\/span> <span class=\"hljs-number\">192.168<\/span><span class=\"hljs-number\">.10<\/span><span class=\"hljs-number\">.200<\/span>\r\n<span class=\"hljs-attr\">Proxy status:<\/span> <span class=\"hljs-string\">DNS<\/span> <span class=\"hljs-string\">only<\/span> <span class=\"hljs-string\">(Grey<\/span> <span class=\"hljs-string\">cloud<\/span> <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-string\">Important!)<\/span>\r\n<span class=\"hljs-attr\">TTL:<\/span> <span class=\"hljs-number\">300<\/span><\/span><\/pre>\n<p id=\"131d\" class=\"pw-post-body-paragraph nh ni gm nj b nk of nm nn no og nq nr ns oh nu nv nw oi ny nz oa oj oc od oe gf bl\" data-selectable-paragraph=\"\"><strong class=\"nj gn\">For internal DNS:<\/strong><\/p>\n<pre class=\"ok ol om on oo op oq or bq os bc bl\"><span id=\"c233\" class=\"ot mk gm oq b bh ou ov m ow ox\" data-selectable-paragraph=\"\"># Add <span class=\"hljs-selector-tag\">to<\/span> your DNS server\r\nmonitoring<span class=\"hljs-selector-class\">.k8s<\/span><span class=\"hljs-selector-class\">.opstree<\/span><span class=\"hljs-selector-class\">.dev<\/span>.  IN  <span class=\"hljs-selector-tag\">A<\/span>  <span class=\"hljs-number\">192.168<\/span>.<span class=\"hljs-number\">10.200<\/span>\r\nn8n<span class=\"hljs-selector-class\">.opstree<\/span><span class=\"hljs-selector-class\">.dev<\/span>.             IN  <span class=\"hljs-selector-tag\">A<\/span>  <span class=\"hljs-number\">192.168<\/span>.<span class=\"hljs-number\">10.200<\/span><\/span><\/pre>\n<h3 id=\"3213\" class=\"mj mk gm bg ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng bl\">Step 4: Testing and Verification<\/h3>\n<h4 id=\"b817\" class=\"pj mk gm bg ml pk pl pm mp pn po pp mt ns pq pr ps nw pt pu pv oa pw px py pz bl\">Test HTTP and HTTPS<\/h4>\n<pre class=\"ok ol om on oo op oq or bq os bc bl\"><span id=\"953d\" class=\"ot mk gm oq b bh ou ov m ow ox\" data-selectable-paragraph=\"\"><span class=\"hljs-meta\"># Test VIP directly<\/span>\r\ncurl http:<span class=\"hljs-comment\">\/\/192.168.10.200<\/span>\r\ncurl -k https:<span class=\"hljs-comment\">\/\/192.168.10.200<\/span><\/span><\/pre>\n<pre class=\"qa op oq qb qc ak qd bl\"><span id=\"c93e\" class=\"pj mk gm oq b qe qf qg m qh ox\" data-selectable-paragraph=\"\"># Test with domain\r\ncurl http:\/\/monitoring.k8s.opstree.dev\r\ncurl -k https:\/\/monitoring.k8s.opstree.dev<\/span><\/pre>\n<h4 id=\"faa1\" class=\"pj mk gm bg ml pk pl pm mp pn po pp mt ns pq pr ps nw pt pu pv oa pw px py pz bl\">Monitor Traffic Distribution<\/h4>\n<pre class=\"ok ol om on oo op oq or bq os bc bl\"><span id=\"93c1\" class=\"ot mk gm oq b bh ou ov m ow ox\" data-selectable-paragraph=\"\"><span class=\"hljs-comment\"># Watch IPVS statistics<\/span>\r\nwatch -n 2 <span class=\"hljs-string\">'sudo ipvsadm -L -n --stats'<\/span><\/span><\/pre>\n<pre class=\"qa op oq qb qc ak qd bl\"><span id=\"0564\" class=\"pj mk gm oq b qe qf qg m qh ox\" data-selectable-paragraph=\"\"># Check Envoy metrics\r\ncurl http:\/\/192.168.0.0:9901\/stats<\/span><span id=\"314b\" class=\"pj mk gm oq b qe qi qg m qh ox\" data-selectable-paragraph=\"\"># Monitor Envoy logs\r\nkubectl logs -n envoy-system -l app=envoy-proxy -f<\/span><\/pre>\n<h4 id=\"30d2\" class=\"pj mk gm bg ml pk pl pm mp pn po pp mt ns pq pr ps nw pt pu pv oa pw px py pz bl\">Test Failover<\/h4>\n<pre class=\"ok ol om on oo op oq or bq os bc bl\"><span id=\"6520\" class=\"ot mk gm oq b bh ou ov m ow ox\" data-selectable-paragraph=\"\"><span class=\"hljs-comment\"># Delete a pod to test failover<\/span>\r\nkubectl <span class=\"hljs-keyword\">delete<\/span> pod -n envoy-<span class=\"hljs-keyword\">system<\/span> envoy-proxy-xxxxx<\/span><\/pre>\n<pre class=\"qa op oq qb qc ak qd bl\"><span id=\"7547\" class=\"pj mk gm oq b qe qf qg m qh ox\" data-selectable-paragraph=\"\"># Traffic should continue without interruption\r\nwhile true; do curl -s http:\/\/192.168.10.200; sleep 1; done<\/span><\/pre>\n<h3 id=\"6b5e\" class=\"mj mk gm bg ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng bl\">Step 5: Cleanup External VM<\/h3>\n<p id=\"048c\" class=\"pw-post-body-paragraph nh ni gm nj b nk nl nm nn no np nq nr ns nt nu nv nw nx ny nz oa ob oc od oe gf bl\" data-selectable-paragraph=\"\">Once everything is verified working:<\/p>\n<pre class=\"ok ol om on oo op oq or bq os bc bl\"><span id=\"ddc3\" class=\"ot mk gm oq b bh ou ov m ow ox\" data-selectable-paragraph=\"\"><span class=\"hljs-comment\"># SSH to external VM<\/span>\r\nssh user<span class=\"hljs-meta\">@192<\/span>.<span class=\"hljs-number\">168.10<\/span>.<span class=\"hljs-number\">100<\/span><\/span><\/pre>\n<pre class=\"qa op oq qb qc ak qd bl\"><span id=\"88dd\" class=\"pj mk gm oq b qe qf qg m qh ox\" data-selectable-paragraph=\"\"># Stop Envoy\r\nsudo systemctl stop envoy\r\nsudo systemctl disable envoy<\/span><span id=\"1baf\" class=\"pj mk gm oq b qe qi qg m qh ox\" data-selectable-paragraph=\"\"># Backup configuration\r\nsudo tar -czf \/root\/envoy-backup-$(date +%Y%m%d).tar.gz \/etc\/envoy\/<\/span><span id=\"e734\" class=\"pj mk gm oq b qe qi qg m qh ox\" data-selectable-paragraph=\"\"># The VM is now free for other workloads<\/span><\/pre>\n<div style=\"max-width: 700px; margin: 24px auto; padding: 16px 12px; background: #f8fafc; border-left: 4px solid #0056b3; border-radius: 6px; text-align: center;\">\n<p style=\"font-size: clamp(1rem,2.5vw,1.1rem); color: #1f2937; margin: 0;\">\u00a0Are you looking <a href=\"https:\/\/opstree.com\/services\/middleware-database-and-data-engineering\/\" target=\"_blank\" rel=\"noopener\">Enterprise Data Engineering Company<\/a>. <span style=\"background-color: #ffffff; color: #1a1a1a; font-size: 16px;\">\u00a0<\/span><span style=\"background-color: #ffffff; color: #1a1a1a; font-size: 16px;\">\u00a0<\/span><\/p>\n<\/div>\n<h2 id=\"78f4\" class=\"mj mk gm bg ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng bl\" data-selectable-paragraph=\"\">Benefits Achieved<\/h2>\n<p id=\"db54\" class=\"pw-post-body-paragraph nh ni gm nj b nk nl nm nn no np nq nr ns nt nu nv nw nx ny nz oa ob oc od oe gf bl\" data-selectable-paragraph=\"\"><strong class=\"nj gn\">Performance Improvements:<\/strong><\/p>\n<ul class=\"\">\n<li id=\"76bc\" class=\"nh ni gm nj b nk of nm nn no og nq nr ns oh nu nv nw oi ny nz oa oj oc od oe pa pb pc bl\" data-selectable-paragraph=\"\">Eliminated extra network hop through external VM<\/li>\n<li id=\"3ad2\" class=\"nh ni gm nj b nk pd nm nn no pe nq nr ns pf nu nv nw pg ny nz oa ph oc od oe pa pb pc bl\" data-selectable-paragraph=\"\">Direct connection from worker nodes reduces latency<\/li>\n<li id=\"693f\" class=\"nh ni gm nj b nk pd nm nn no pe nq nr ns pf nu nv nw pg ny nz oa ph oc od oe pa pb pc bl\" data-selectable-paragraph=\"\">DNS-based service discovery simplifies configuration<\/li>\n<\/ul>\n<p id=\"29a9\" class=\"pw-post-body-paragraph nh ni gm nj b nk of nm nn no og nq nr ns oh nu nv nw oi ny nz oa oj oc od oe gf bl\" data-selectable-paragraph=\"\"><strong class=\"nj gn\">High Availability:<\/strong><\/p>\n<ul class=\"\">\n<li id=\"3335\" class=\"nh ni gm nj b nk of nm nn no og nq nr ns oh nu nv nw oi ny nz oa oj oc od oe pa pb pc bl\" data-selectable-paragraph=\"\">No single point of failure<\/li>\n<li id=\"8619\" class=\"nh ni gm nj b nk pd nm nn no pe nq nr ns pf nu nv nw pg ny nz oa ph oc od oe pa pb pc bl\" data-selectable-paragraph=\"\">Automatic VIP failover with Keepalived<\/li>\n<li id=\"9211\" class=\"nh ni gm nj b nk pd nm nn no pe nq nr ns pf nu nv nw pg ny nz oa ph oc od oe pa pb pc bl\" data-selectable-paragraph=\"\">Health checks ensure traffic only reaches healthy endpoints<\/li>\n<li id=\"c552\" class=\"nh ni gm nj b nk pd nm nn no pe nq nr ns pf nu nv nw pg ny nz oa ph oc od oe pa pb pc bl\" data-selectable-paragraph=\"\">Pod auto-healing through Kubernetes<\/li>\n<\/ul>\n<p id=\"9d47\" class=\"pw-post-body-paragraph nh ni gm nj b nk of nm nn no og nq nr ns oh nu nv nw oi ny nz oa oj oc od oe gf bl\" data-selectable-paragraph=\"\"><strong class=\"nj gn\">Operational Excellence:<\/strong><\/p>\n<ul class=\"\">\n<li id=\"061b\" class=\"nh ni gm nj b nk of nm nn no og nq nr ns oh nu nv nw oi ny nz oa oj oc od oe pa pb pc bl\" data-selectable-paragraph=\"\">Simplified management through kubectl<\/li>\n<li id=\"bdea\" class=\"nh ni gm nj b nk pd nm nn no pe nq nr ns pf nu nv nw pg ny nz oa ph oc od oe pa pb pc bl\" data-selectable-paragraph=\"\">GitOps-friendly configuration<\/li>\n<li id=\"9f55\" class=\"nh ni gm nj b nk pd nm nn no pe nq nr ns pf nu nv nw pg ny nz oa ph oc od oe pa pb pc bl\" data-selectable-paragraph=\"\">Prometheus metrics integration ready<\/li>\n<li id=\"6150\" class=\"nh ni gm nj b nk pd nm nn no pe nq nr ns pf nu nv nw pg ny nz oa ph oc od oe pa pb pc bl\" data-selectable-paragraph=\"\">Scales automatically with worker node additions<\/li>\n<\/ul>\n<p id=\"1fa9\" class=\"pw-post-body-paragraph nh ni gm nj b nk of nm nn no og nq nr ns oh nu nv nw oi ny nz oa oj oc od oe gf bl\" data-selectable-paragraph=\"\"><strong class=\"nj gn\">Resource Optimization:<\/strong><\/p>\n<ul class=\"\">\n<li id=\"9927\" class=\"nh ni gm nj b nk of nm nn no og nq nr ns oh nu nv nw oi ny nz oa oj oc od oe pa pb pc bl\" data-selectable-paragraph=\"\">External VM freed for other workloads<\/li>\n<li id=\"8f9b\" class=\"nh ni gm nj b nk pd nm nn no pe nq nr ns pf nu nv nw pg ny nz oa ph oc od oe pa pb pc bl\" data-selectable-paragraph=\"\">Better resource utilization across cluster<\/li>\n<li id=\"6e7f\" class=\"nh ni gm nj b nk pd nm nn no pe nq nr ns pf nu nv nw pg ny nz oa ph oc od oe pa pb pc bl\" data-selectable-paragraph=\"\">Reduced infrastructure costs<\/li>\n<\/ul>\n<div style=\"max-width: 700px; margin: 24px auto; padding: 16px 12px; background: #f8fafc; border-left: 4px solid #0056b3; border-radius: 6px; text-align: center;\">\n<p style=\"font-size: clamp(1rem,2.5vw,1.1rem); color: #1f2937; margin: 0;\">Good Read: <a href=\"https:\/\/opstree.com\/blog\/2025\/10\/25\/cloud-data-storage-for-big-data\/\" target=\"_blank\" rel=\"noopener\">Building a Reliable Cloud Data Storage Architecture for Big Data<\/a>.<span style=\"background-color: #ffffff; color: #1a1a1a; font-size: 16px;\">\u00a0<\/span><\/p>\n<\/div>\n<h2 id=\"5ab8\" class=\"mj mk gm bg ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng bl\" data-selectable-paragraph=\"\">Monitoring and Observability<\/h2>\n<h3 id=\"61a6\" class=\"pj mk gm bg ml pk pl pm mp pn po pp mt ns pq pr ps nw pt pu pv oa pw px py pz bl\" data-selectable-paragraph=\"\">Envoy Admin Interface<\/h3>\n<p id=\"9618\" class=\"pw-post-body-paragraph nh ni gm nj b nk nl nm nn no np nq nr ns nt nu nv nw nx ny nz oa ob oc od oe gf bl\" data-selectable-paragraph=\"\">Access Envoy\u2019s built-in admin interface:<\/p>\n<pre class=\"ok ol om on oo op oq or bq os bc bl\"><span id=\"1e04\" class=\"ot mk gm oq b bh ou ov m ow ox\" data-selectable-paragraph=\"\">kubectl port-forward -n envoy-system daemonset\/envoy-proxy 9901:9901<\/span><\/pre>\n<p id=\"615f\" class=\"pw-post-body-paragraph nh ni gm nj b nk of nm nn no og nq nr ns oh nu nv nw oi ny nz oa oj oc od oe gf bl\" data-selectable-paragraph=\"\">Visit\u00a0http:\/\/localhost:9901\u00a0for:<\/p>\n<ul class=\"\">\n<li id=\"7d4c\" class=\"nh ni gm nj b nk of nm nn no og nq nr ns oh nu nv nw oi ny nz oa oj oc od oe pa pb pc bl\" data-selectable-paragraph=\"\">Real-time stats<\/li>\n<li id=\"4e0c\" class=\"nh ni gm nj b nk pd nm nn no pe nq nr ns pf nu nv nw pg ny nz oa ph oc od oe pa pb pc bl\" data-selectable-paragraph=\"\">Configuration dump<\/li>\n<li id=\"c4b9\" class=\"nh ni gm nj b nk pd nm nn no pe nq nr ns pf nu nv nw pg ny nz oa ph oc od oe pa pb pc bl\" data-selectable-paragraph=\"\">Health checks<\/li>\n<li id=\"a8f6\" class=\"nh ni gm nj b nk pd nm nn no pe nq nr ns pf nu nv nw pg ny nz oa ph oc od oe pa pb pc bl\" data-selectable-paragraph=\"\">Cluster status<\/li>\n<\/ul>\n<h3 id=\"c364\" class=\"pj mk gm bg ml pk pl pm mp pn po pp mt ns pq pr ps nw pt pu pv oa pw px py pz bl\" data-selectable-paragraph=\"\">Prometheus Integration<\/h3>\n<p id=\"d5a4\" class=\"pw-post-body-paragraph nh ni gm nj b nk nl nm nn no np nq nr ns nt nu nv nw nx ny nz oa ob oc od oe gf bl\" data-selectable-paragraph=\"\">The DaemonSet is already configured with Prometheus annotations. Create a ServiceMonitor:<\/p>\n<pre class=\"ok ol om on oo op oq or bq os bc bl\"><span id=\"b921\" class=\"ot mk gm oq b bh ou ov m ow ox\" data-selectable-paragraph=\"\"><span class=\"hljs-attr\">apiVersion:<\/span> <span class=\"hljs-string\">monitoring.coreos.com\/v1<\/span>\r\n<span class=\"hljs-attr\">kind:<\/span> <span class=\"hljs-string\">ServiceMonitor<\/span>\r\n<span class=\"hljs-attr\">metadata:<\/span>\r\n  <span class=\"hljs-attr\">name:<\/span> <span class=\"hljs-string\">envoy-proxy<\/span>\r\n  <span class=\"hljs-attr\">namespace:<\/span> <span class=\"hljs-string\">envoy-system<\/span>\r\n<span class=\"hljs-attr\">spec:<\/span>\r\n  <span class=\"hljs-attr\">selector:<\/span>\r\n    <span class=\"hljs-attr\">matchLabels:<\/span>\r\n      <span class=\"hljs-attr\">app:<\/span> <span class=\"hljs-string\">envoy-proxy<\/span>\r\n  <span class=\"hljs-attr\">endpoints:<\/span>\r\n  <span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-attr\">port:<\/span> <span class=\"hljs-string\">admin<\/span>\r\n    <span class=\"hljs-attr\">path:<\/span> <span class=\"hljs-string\">\/stats\/prometheus<\/span><\/span><\/pre>\n<h3 id=\"71eb\" class=\"pj mk gm bg ml pk pl pm mp pn po pp mt ns pq pr ps nw pt pu pv oa pw px py pz bl\" data-selectable-paragraph=\"\">Key Metrics to Monitor<\/h3>\n<ul class=\"\">\n<li id=\"d834\" class=\"nh ni gm nj b nk nl nm nn no np nq nr ns nt nu nv nw nx ny nz oa ob oc od oe pa pb pc bl\" data-selectable-paragraph=\"\"><code class=\"de qj qk ql oq b\">envoy_cluster_upstream_rq_total<\/code>: Total requests to upstream<\/li>\n<li id=\"387b\" class=\"nh ni gm nj b nk pd nm nn no pe nq nr ns pf nu nv nw pg ny nz oa ph oc od oe pa pb pc bl\" data-selectable-paragraph=\"\"><code class=\"de qj qk ql oq b\">envoy_cluster_upstream_rq_time<\/code>: Request latency<\/li>\n<li id=\"a045\" class=\"nh ni gm nj b nk pd nm nn no pe nq nr ns pf nu nv nw pg ny nz oa ph oc od oe pa pb pc bl\" data-selectable-paragraph=\"\"><code class=\"de qj qk ql oq b\">envoy_cluster_upstream_cx_active<\/code>: Active connections<\/li>\n<li id=\"ffd0\" class=\"nh ni gm nj b nk pd nm nn no pe nq nr ns pf nu nv nw pg ny nz oa ph oc od oe pa pb pc bl\" data-selectable-paragraph=\"\"><code class=\"de qj qk ql oq b\">envoy_cluster_health_check_success<\/code>: Health check status<\/li>\n<\/ul>\n<h2 id=\"983a\" class=\"mj mk gm bg ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng bl\" data-selectable-paragraph=\"\">Troubleshooting Common Issues<\/h2>\n<h3 id=\"6af0\" class=\"pj mk gm bg ml pk pl pm mp pn po pp mt ns pq pr ps nw pt pu pv oa pw px py pz bl\" data-selectable-paragraph=\"\">Pods Not Starting<\/h3>\n<pre class=\"ok ol om on oo op oq or bq os bc bl\"><span id=\"4a3c\" class=\"ot mk gm oq b bh ou ov m ow ox\" data-selectable-paragraph=\"\"><span class=\"hljs-comment\"># Check for port conflicts<\/span>\r\nssh worker-node\r\nsudo netstat -tulpn | <span class=\"hljs-keyword\">grep<\/span> -E <span class=\"hljs-string\">':80|:443'<\/span><\/span><\/pre>\n<pre class=\"qa op oq qb qc ak qd bl\"><span id=\"3edf\" class=\"pj mk gm oq b qe qf qg m qh ox\" data-selectable-paragraph=\"\"># Stop conflicting services\r\nsudo systemctl stop nginx apache2<\/span><\/pre>\n<h3 id=\"39ee\" class=\"pj mk gm bg ml pk pl pm mp pn po pp mt ns pq pr ps nw pt pu pv oa pw px py pz bl\" data-selectable-paragraph=\"\">HTTPS Not Working<\/h3>\n<pre class=\"ok ol om on oo op oq or bq os bc bl\"><span id=\"205d\" class=\"ot mk gm oq b bh ou ov m ow ox\" data-selectable-paragraph=\"\"><span class=\"hljs-comment\"># Verify Kong service name<\/span>\r\nkubectl get svc -n kong kong-gateway-proxy<\/span><\/pre>\n<pre class=\"qa op oq qb qc ak qd bl\"><span id=\"bb66\" class=\"pj mk gm oq b qe qf qg m qh ox\" data-selectable-paragraph=\"\"># Test Kong HTTPS directly\r\ncurl -k https:\/\/kong-gateway-proxy.kong.svc.cluster.local<\/span><span id=\"e070\" class=\"pj mk gm oq b qe qi qg m qh ox\" data-selectable-paragraph=\"\"># Check Envoy cluster health\r\ncurl http:\/\/worker-ip:9901\/clusters | grep cluster_https<\/span><\/pre>\n<h3 id=\"3b64\" class=\"pj mk gm bg ml pk pl pm mp pn po pp mt ns pq pr ps nw pt pu pv oa pw px py pz bl\" data-selectable-paragraph=\"\">VIP Not Accessible<\/h3>\n<pre class=\"ok ol om on oo op oq or bq os bc bl\"><span id=\"9a95\" class=\"ot mk gm oq b bh ou ov m ow ox\" data-selectable-paragraph=\"\"># Check Keepalived <span class=\"hljs-built_in\">status<\/span>\r\nsudo systemctl <span class=\"hljs-built_in\">status<\/span> keepalived<\/span><\/pre>\n<pre class=\"qa op oq qb qc ak qd bl\"><span id=\"473e\" class=\"pj mk gm oq b qe qf qg m qh ox\" data-selectable-paragraph=\"\"># Verify IPVS rules\r\nsudo ipvsadm -L -n<\/span><span id=\"df61\" class=\"pj mk gm oq b qe qi qg m qh ox\" data-selectable-paragraph=\"\"># Check authentication matches on all nodes\r\nsudo journalctl -u keepalived | grep authentication<\/span><\/pre>\n<h2 id=\"42c1\" class=\"mj mk gm bg ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng bl\" data-selectable-paragraph=\"\">Best Practices<\/h2>\n<p id=\"531e\" class=\"pw-post-body-paragraph nh ni gm nj b nk nl nm nn no np nq nr ns nt nu nv nw nx ny nz oa ob oc od oe gf bl\" data-selectable-paragraph=\"\"><strong class=\"nj gn\">Security:<\/strong><\/p>\n<ul class=\"\">\n<li id=\"a6de\" class=\"nh ni gm nj b nk of nm nn no og nq nr ns oh nu nv nw oi ny nz oa oj oc od oe pa pb pc bl\" data-selectable-paragraph=\"\">Use network policies to restrict access to Envoy admin interface<\/li>\n<li id=\"ff45\" class=\"nh ni gm nj b nk pd nm nn no pe nq nr ns pf nu nv nw pg ny nz oa ph oc od oe pa pb pc bl\" data-selectable-paragraph=\"\">Implement proper TLS certificates (Let\u2019s Encrypt or internal CA)<\/li>\n<li id=\"1c15\" class=\"nh ni gm nj b nk pd nm nn no pe nq nr ns pf nu nv nw pg ny nz oa ph oc od oe pa pb pc bl\" data-selectable-paragraph=\"\">Regular security updates for Envoy image<\/li>\n<\/ul>\n<p id=\"6250\" class=\"pw-post-body-paragraph nh ni gm nj b nk of nm nn no og nq nr ns oh nu nv nw oi ny nz oa oj oc od oe gf bl\" data-selectable-paragraph=\"\"><strong class=\"nj gn\">Performance:<\/strong><\/p>\n<ul class=\"\">\n<li id=\"4b4e\" class=\"nh ni gm nj b nk of nm nn no og nq nr ns oh nu nv nw oi ny nz oa oj oc od oe pa pb pc bl\" data-selectable-paragraph=\"\">Tune Envoy buffer sizes for your workload<\/li>\n<li id=\"848d\" class=\"nh ni gm nj b nk pd nm nn no pe nq nr ns pf nu nv nw pg ny nz oa ph oc od oe pa pb pc bl\" data-selectable-paragraph=\"\">Monitor connection pool settings<\/li>\n<li id=\"7418\" class=\"nh ni gm nj b nk pd nm nn no pe nq nr ns pf nu nv nw pg ny nz oa ph oc od oe pa pb pc bl\" data-selectable-paragraph=\"\">Adjust worker threads based on CPU cores<\/li>\n<\/ul>\n<p id=\"0299\" class=\"pw-post-body-paragraph nh ni gm nj b nk of nm nn no og nq nr ns oh nu nv nw oi ny nz oa oj oc od oe gf bl\" data-selectable-paragraph=\"\"><strong class=\"nj gn\">High Availability:<\/strong><\/p>\n<ul class=\"\">\n<li id=\"0de5\" class=\"nh ni gm nj b nk of nm nn no og nq nr ns oh nu nv nw oi ny nz oa oj oc od oe pa pb pc bl\" data-selectable-paragraph=\"\">Deploy Keepalived on at least 3 nodes<\/li>\n<li id=\"e343\" class=\"nh ni gm nj b nk pd nm nn no pe nq nr ns pf nu nv nw pg ny nz oa ph oc od oe pa pb pc bl\" data-selectable-paragraph=\"\">Use different priority values for proper failover order<\/li>\n<li id=\"b499\" class=\"nh ni gm nj b nk pd nm nn no pe nq nr ns pf nu nv nw pg ny nz oa ph oc od oe pa pb pc bl\" data-selectable-paragraph=\"\">Monitor VIP location and failover events<\/li>\n<\/ul>\n<p id=\"2d03\" class=\"pw-post-body-paragraph nh ni gm nj b nk of nm nn no og nq nr ns oh nu nv nw oi ny nz oa oj oc od oe gf bl\" data-selectable-paragraph=\"\"><strong class=\"nj gn\">Scaling:<\/strong><\/p>\n<ul class=\"\">\n<li id=\"d3c1\" class=\"nh ni gm nj b nk of nm nn no og nq nr ns oh nu nv nw oi ny nz oa oj oc od oe pa pb pc bl\" data-selectable-paragraph=\"\">DaemonSet automatically scales with new worker nodes<\/li>\n<li id=\"c757\" class=\"nh ni gm nj b nk pd nm nn no pe nq nr ns pf nu nv nw pg ny nz oa ph oc od oe pa pb pc bl\" data-selectable-paragraph=\"\">Update Keepalived config when adding nodes<\/li>\n<li id=\"1a36\" class=\"nh ni gm nj b nk pd nm nn no pe nq nr ns pf nu nv nw pg ny nz oa ph oc od oe pa pb pc bl\" data-selectable-paragraph=\"\">Test failover scenarios regularly<\/li>\n<\/ul>\n<h2 id=\"0948\" class=\"mj mk gm bg ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng bl\" data-selectable-paragraph=\"\">Conclusion<\/h2>\n<p id=\"190b\" class=\"pw-post-body-paragraph nh ni gm nj b nk nl nm nn no np nq nr ns nt nu nv nw nx ny nz oa ob oc od oe gf bl\" data-selectable-paragraph=\"\">Migrating from an external load balancer to a <a href=\"https:\/\/www.buildpiper.io\/containerization-kubernetes-management\/\" target=\"_blank\" rel=\"noopener\">Kubernetes-native<\/a> Envoy solution provides significant benefits in reliability, performance, and operational simplicity. By leveraging DaemonSets for deployment and Keepalived for VIP management, we achieved a highly available ingress architecture without external dependencies.<\/p>\n<p id=\"ff30\" class=\"pw-post-body-paragraph nh ni gm nj b nk of nm nn no og nq nr ns oh nu nv nw oi ny nz oa oj oc od oe gf bl\" data-selectable-paragraph=\"\">The solution is production-ready, scales horizontally, and integrates seamlessly with existing Kubernetes tooling. Most importantly, it frees up infrastructure resources while improving overall system reliability.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Moving from External Load Balancer to Cloud-Native Architecture The Challenge In on-premise Kubernetes deployments, achieving high availability for ingress traffic often relies on external load balancers running on dedicated VMs. While functional, this approach creates single points of failure, adds operational complexity, and wastes valuable infrastructure resources. In this guide, I\u2019ll walk you through migrating &hellip; <a href=\"https:\/\/opstree.com\/blog\/2025\/10\/28\/ingress-solution-with-envoy-proxy-on-kubernetes\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Building a High-Availability Ingress Solution with Envoy Proxy on Kubernetes&#8221;<\/span><\/a><\/p>\n","protected":false},"author":244582710,"featured_media":29820,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[768739351],"tags":[768739309,719458036,343865],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/opstree.com\/blog\/wp-content\/uploads\/2025\/10\/Kubernetes.jpg","jetpack_likes_enabled":true,"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/pfDBOm-7KW","jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts\/29818"}],"collection":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/users\/244582710"}],"replies":[{"embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/comments?post=29818"}],"version-history":[{"count":6,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts\/29818\/revisions"}],"predecessor-version":[{"id":29920,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts\/29818\/revisions\/29920"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/media\/29820"}],"wp:attachment":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/media?parent=29818"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/categories?post=29818"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/tags?post=29818"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}