Ingress Nginx
In this section we will try to deploy two ingress controllers in the same cluster. We will use the following ingress controllers:
- We will put the
external-nginx
ingress controller in theingress-nginx-external
namespace. - We will put the
internal-nginx
ingress controller in theingress-nginx-internal
namespace.
external-nginx-values.yaml
---
# Ref: https://github.com/kubernetes/ingress-nginx/blob/main/charts/ingress-nginx/values.yaml
controller:
# name: external-controller
# -- Election ID to use for status update, by default it uses the controller name combined with a suffix of 'leader'
# electionID: ""
config:
# https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/nginx-configuration/configmap.md#compute-full-forwarded-for
compute-full-forwarded-for: "true"
# https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/nginx-configuration/configmap.md#use-forwarded-headers
use-forwarded-headers: "true"
# https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/nginx-configuration/configmap.md#proxy-body-size
proxy-body-size: "0"
# This name we will reference this particular ingress controller
# incase you have multiple ingress controllers, you can use
# `ingressClassName` to specify which ingress controller to use.
# ALSO: For backwards compatibility with ingress.class annotation, use ingressClass. Algorithm is as follows, first ingressClassName is considered, if not present, controller looks for ingress.class annotation.
# Ref: https://github.com/kubernetes/ingress-nginx/tree/main/charts/ingress-nginx
# E.g. very often we have `internal` and `external` ingresses in the same cluster.
ingressClass: external-nginx
# New kubernetes APIs starting from 1.18 let us create an ingress class resource
ingressClassResource:
name: external-nginx
# ENABLED: Create the IngressClass or not
enabled: true
# DEFAULT: If true, Ingresses without ingressClassName get assigned to this IngressClass on creation. Ingress creation gets rejected if there are multiple default IngressClasses. Ref: https://kubernetes.io/docs/concepts/services-networking/ingress/#default-ingress-class
default: false
# Ref: https://kubernetes.github.io/ingress-nginx/user-guide/multiple-ingress/#using-ingressclasses
controllerValue: "k8s.io/ingress-nginx-external"
# Pod Anti-Affinity Role: deploys nginx ingress pods on a different nodes
# very helpful if you do NOT want to disrupt services during kubernetes rolling
# upgrades.
# IMPORTANT: try always to use it.
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values:
- ingress-nginx
topologyKey: "kubernetes.io/hostname"
# Should at least be 2 or configured auto-scaling
replicaCount: 1
# Admission webhooks: verifies the configuration before applying the ingress.
# E.g. syntax error in the configuration snippet annotation, the generated
# configuration becomes invalid
admissionWebhooks:
enabled: true
# Ingress is always deployed with some kind of a load balancer. You may use
# annotations supported by your cloud provider to configure it. E.g. in AWS
# you can use `aws-load-balancer-type` as the default is `classic`.
service:
annotations:
# Ref: https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.2/guide/service/annotations/
service.beta.kubernetes.io/aws-load-balancer-name: "load-balancer-external"
service.beta.kubernetes.io/aws-load-balancer-type: nlb
# service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
# Also, if you want to have an internal load balancer with only private
# IP address. That you can use within your VPC. you can use:
# Ref: https://docs.aws.amazon.com/elasticloadbalancing/latest/userguide/how-elastic-load-balancing-works.html
# service.beta.kubernetes.io/aws-load-balancer-scheme: "internet"
# service.beta.kubernetes.io/aws-load-balancer-internal: 0.0.0.0/0
# service.beta.kubernetes.io/aws-load-balancer-internal: "true"
# We want to enable prometheus metrics on the controller
metrics:
enabled: true
serviceMonitor:
enabled: true
# additionalLabels:
# prometheus: monitor
internal-nginx-values.yaml
---
# Ref: https://github.com/kubernetes/ingress-nginx/blob/main/charts/ingress-nginx/values.yaml
controller:
# name: external-controller
# -- Election ID to use for status update, by default it uses the controller name combined with a suffix of 'leader'
# electionID: ""
config:
# https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/nginx-configuration/configmap.md#compute-full-forwarded-for
compute-full-forwarded-for: "true"
# https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/nginx-configuration/configmap.md#use-forwarded-headers
use-forwarded-headers: "true"
# https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/nginx-configuration/configmap.md#proxy-body-size
proxy-body-size: "0"
# This name we will reference this particular ingress controller
# incase you have multiple ingress controllers, you can use
# `ingressClassName` to specify which ingress controller to use.
# ALSO: For backwards compatibility with ingress.class annotation, use ingressClass. Algorithm is as follows, first ingressClassName is considered, if not present, controller looks for ingress.class annotation.
# Ref: https://github.com/kubernetes/ingress-nginx/tree/main/charts/ingress-nginx
# E.g. very often we have `internal` and `external` ingresses in the same cluster.
ingressClass: internal-nginx
# New kubernetes APIs starting from 1.18 let us create an ingress class resource
ingressClassResource:
name: internal-nginx
# ENABLED: Create the IngressClass or not
enabled: true
# DEFAULT: If true, Ingresses without ingressClassName get assigned to this IngressClass on creation. Ingress creation gets rejected if there are multiple default IngressClasses. Ref: https://kubernetes.io/docs/concepts/services-networking/ingress/#default-ingress-class
default: true
# Ref: https://kubernetes.github.io/ingress-nginx/user-guide/multiple-ingress/#using-ingressclasses
controllerValue: "k8s.io/ingress-nginx-internal"
# Pod Anti-Affinity Role: deploys nginx ingress pods on a different nodes
# very helpful if you do NOT want to disrupt services during kubernetes rolling
# upgrades.
# IMPORTANT: try always to use it.
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values:
- ingress-nginx
topologyKey: "kubernetes.io/hostname"
# Should at least be 2 or configured auto-scaling
replicaCount: 1
# Admission webhooks: verifies the configuration before applying the ingress.
# E.g. syntax error in the configuration snippet annotation, the generated
# configuration becomes invalid
admissionWebhooks:
enabled: true
# Ingress is always deployed with some kind of a load balancer. You may use
# annotations supported by your cloud provider to configure it. E.g. in AWS
# you can use `aws-load-balancer-type` as the default is `classic`.
service:
external:
enabled: false
internal:
enabled: true
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: nlb
service.beta.kubernetes.io/aws-load-balancer-name: "load-balancer-internal"
service.beta.kubernetes.io/aws-load-balancer-schema: "internal"
# annotations:
# Ref: https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.2/guide/service/annotations/
# service.beta.kubernetes.io/aws-load-balancer-name: "load-balancer-external"
# service.beta.kubernetes.io/aws-load-balancer-type: nlb
# service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
# Also, if you want to have an internal load balancer with only private
# IP address. That you can use within your VPC. you can use:
# Ref: https://docs.aws.amazon.com/elasticloadbalancing/latest/userguide/how-elastic-load-balancing-works.html
# service.beta.kubernetes.io/aws-load-balancer-scheme: "internet"
# service.beta.kubernetes.io/aws-load-balancer-internal: 0.0.0.0/0
# service.beta.kubernetes.io/aws-load-balancer-internal: "true"
# We want to enable prometheus metrics on the controller
metrics:
enabled: true
serviceMonitor:
enabled: true
# additionalLabels:
# prometheus: monitor
internal-nginx-values.yaml
controller:
ingressClassByName: true
ingressClassResource:
name: nginx
enabled: true
default: true
controllerValue: "k8s.io/ingress-nginx"
service:
external:
enabled: false
internal:
enabled: true
annotations:
service.beta.kubernetes.io/aws-load-balancer-internal: "true"
service.beta.kubernetes.io/aws-load-balancer-name: "load-balancer-internal"
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp
service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
service.beta.kubernetes.io/aws-load-balancer-type: nlb
controller:
ingressClassByName: true
ingressClassResource:
name: nginx-public
enabled: true
default: false
controllerValue: "k8s.io/ingress-nginx-public"
ingressClass: nginx-public
service:
annotations:
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp
service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
service.beta.kubernetes.io/aws-load-balancer-type: nlb
# Disable the external LB
external:
enabled: true
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm search repo kube-prometheus-stack --max-col-width 23
# Release name: monitoring
# Helm chart name: kube-prometheus-stack
helm install monitoring prometheus-community/kube-prometheus-stack \
--values kube-prometheus-stack-values.yaml \
--version 58.1.3 \
--namespace monitoring \
--create-namespace
# Later when you are done
helm uninstall monitoring -n monitoring
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
helm search repo ingress-nginx --max-col-width 23
helm install ingress-nginx-external ingress-nginx/ingress-nginx \
--values external-nginx-values.yaml \
--version 4.10.0 \
--namespace ingress-nginx-external \
--create-namespace
helm install ingress-nginx-internal ingress-nginx/ingress-nginx \
--values internal-nginx-values.yaml \
--version 4.10.0 \
--namespace ingress-nginx-internal \
--create-namespace
# Later when you are done
helm uninstall ingress-nginx-external -n ingress-nginx-external
helm uninstall ingress-nginx-internal -n ingress-nginx-internal
kubectl -n ingress-nginx-external get po
kubectl -n ingress-nginx-internal get po
kubectl -n ingress-nginx-external get svc ingress-nginx-external-controller -o wide -w
kubectl -n ingress-nginx-internal get svc ingress-nginx-internal-controller-internal -o wide -w
kubectl -n ingress-nginx-external get svc ingress-nginx-external-controller -o json | jq .status.loadBalancer
kubectl -n ingress-nginx-internal get svc ingress-nginx-internal-controller-internal -o json | jq .status.loadBalancer
kubectl -n ingress-nginx-external get po -o custom-columns=POD:.metadata.name,NODE:.spec.nodeName
kubectl -n ingress-nginx-internal get po -o custom-columns=POD:.metadata.name,NODE:.spec.nodeName
Tested
external-nginx-values.yaml
---
# Ref: https://github.com/kubernetes/ingress-nginx/blob/main/charts/ingress-nginx/values.yaml
controller:
# name: controller
# -- Election ID to use for status update, by default it uses the controller name combined with a suffix of 'leader'
# electionID: ""
config:
# https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/nginx-configuration/configmap.md#compute-full-forwarded-for
compute-full-forwarded-for: "true"
# https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/nginx-configuration/configmap.md#use-forwarded-headers
use-forwarded-headers: "true"
# https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/nginx-configuration/configmap.md#proxy-body-size
proxy-body-size: "0"
# This name we will reference this particular ingress controller
# incase you have multiple ingress controllers, you can use
# `ingressClassName` to specify which ingress controller to use.
# ALSO: For backwards compatibility with ingress.class annotation, use ingressClass. Algorithm is as follows, first ingressClassName is considered, if not present, controller looks for ingress.class annotation.
# Ref: https://github.com/kubernetes/ingress-nginx/tree/main/charts/ingress-nginx
# E.g. very often we have `internal` and `external` ingresses in the same cluster.
ingressClass: external-nginx
# New kubernetes APIs starting from 1.18 let us create an ingress class resource
ingressClassResource:
name: external-nginx
# ENABLED: Create the IngressClass or not
enabled: true
# DEFAULT: If true, Ingresses without ingressClassName get assigned to this IngressClass on creation. Ingress creation gets rejected if there are multiple default IngressClasses. Ref: https://kubernetes.io/docs/concepts/services-networking/ingress/#default-ingress-class
default: false
# Ref: https://kubernetes.github.io/ingress-nginx/user-guide/multiple-ingress/#using-ingressclasses
controllerValue: "k8s.io/ingress-nginx-external"
# Pod Anti-Affinity Role: deploys nginx ingress pods on a different nodes
# very helpful if you do NOT want to disrupt services during kubernetes rolling
# upgrades.
# IMPORTANT: try always to use it.
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values:
- ingress-nginx
topologyKey: "kubernetes.io/hostname"
# Should at least be 2 or configured auto-scaling
replicaCount: 1
# Admission webhooks: verifies the configuration before applying the ingress.
# E.g. syntax error in the configuration snippet annotation, the generated
# configuration becomes invalid
admissionWebhooks:
enabled: true
# Ingress is always deployed with some kind of a load balancer. You may use
# annotations supported by your cloud provider to configure it. E.g. in AWS
# you can use `aws-load-balancer-type` as the default is `classic`.
service:
annotations:
# Ref: https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.2/guide/service/annotations/
service.beta.kubernetes.io/aws-load-balancer-name: "load-balancer-external"
service.beta.kubernetes.io/aws-load-balancer-type: nlb
# service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
# We want to enable prometheus metrics on the controller
metrics:
enabled: true
serviceMonitor:
enabled: true
# additionalLabels:
# prometheus: monitor
internal-nginx-values.yaml
---
# Ref: https://github.com/kubernetes/ingress-nginx/blob/main/charts/ingress-nginx/values.yaml
controller:
# name: controller
# -- Election ID to use for status update, by default it uses the controller name combined with a suffix of 'leader'
# electionID: ""
config:
# https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/nginx-configuration/configmap.md#compute-full-forwarded-for
compute-full-forwarded-for: "true"
# https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/nginx-configuration/configmap.md#use-forwarded-headers
use-forwarded-headers: "true"
# https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/nginx-configuration/configmap.md#proxy-body-size
proxy-body-size: "0"
# This name we will reference this particular ingress controller
# incase you have multiple ingress controllers, you can use
# `ingressClassName` to specify which ingress controller to use.
# ALSO: For backwards compatibility with ingress.class annotation, use ingressClass. Algorithm is as follows, first ingressClassName is considered, if not present, controller looks for ingress.class annotation.
# Ref: https://github.com/kubernetes/ingress-nginx/tree/main/charts/ingress-nginx
# E.g. very often we have `internal` and `external` ingresses in the same cluster.
ingressClass: internal-nginx
# New kubernetes APIs starting from 1.18 let us create an ingress class resource
ingressClassResource:
name: internal-nginx
# ENABLED: Create the IngressClass or not
enabled: true
# DEFAULT: If true, Ingresses without ingressClassName get assigned to this IngressClass on creation. Ingress creation gets rejected if there are multiple default IngressClasses. Ref: https://kubernetes.io/docs/concepts/services-networking/ingress/#default-ingress-class
default: true
# Ref: https://kubernetes.github.io/ingress-nginx/user-guide/multiple-ingress/#using-ingressclasses
controllerValue: "k8s.io/ingress-nginx-internal"
# Pod Anti-Affinity Role: deploys nginx ingress pods on a different nodes
# very helpful if you do NOT want to disrupt services during kubernetes rolling
# upgrades.
# IMPORTANT: try always to use it.
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values:
- ingress-nginx
topologyKey: "kubernetes.io/hostname"
# Should at least be 2 or configured auto-scaling
replicaCount: 1
# Admission webhooks: verifies the configuration before applying the ingress.
# E.g. syntax error in the configuration snippet annotation, the generated
# configuration becomes invalid
admissionWebhooks:
enabled: true
# Ingress is always deployed with some kind of a load balancer. You may use
# annotations supported by your cloud provider to configure it. E.g. in AWS
# you can use `aws-load-balancer-type` as the default is `classic`.
service:
external:
enabled: false
internal:
enabled: true
annotations:
# Ref: https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.2/guide/service/annotations/
# if you want to have an internal load balancer with only private
# IP address. That you can use within your VPC. you can use:
# Ref: https://docs.aws.amazon.com/elasticloadbalancing/latest/userguide/how-elastic-load-balancing-works.html
service.beta.kubernetes.io/aws-load-balancer-type: nlb
service.beta.kubernetes.io/aws-load-balancer-name: "load-balancer-internal"
service.beta.kubernetes.io/aws-load-balancer-schema: "internal"
# service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
# We want to enable prometheus metrics on the controller
metrics:
enabled: true
serviceMonitor:
enabled: true
# additionalLabels:
# prometheus: monitor
After they are applied, aws will create two load balancers:
load-balancer-external
:- The nodes of an
internet-facing
load balancer havepublic IP addresses
. The DNS name of an internet-facing load balancer ispublicly resolvable to the public IP addresses
of the nodes. Therefore, internet-facing load balancers can route requests from clients over the internet.
- The nodes of an
load-balancer-internal
:- The nodes of an
internal
load balancer haveonly private IP addresses
. The DNS name of an internal load balancer ispublicly resolvable to the private IP addresses
of the nodes. Therefore, internal load balancers can only route requests from clients with access to the VPC for the load balancer.
- The nodes of an
We will have two DNS records:
- For
load-balancer-external
: aws will craeteload-balancer-external-<hash>.elb.amazonaws.com
. - For
load-balancer-internal
: aws will craeteload-balancer-internal-<hash>.elb.amazonaws.com
.
We will access the load-balancer-external
from the internet and the load-balancer-internal
with VPN.
For route53, we delegated the *.k8s.sreboy.com
from Namecheap to Route53.
Create a wildcard CNAME in the public hosted zone to point to the load-balancer-external
.
Create a wildcard CNAME in the private hosted zone to point to the load-balancer-internal
.
goviolin-ingress.yaml
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: goviolin
namespace: goviolin
annotations:
cert-manager.io/issuer: letsencrypt-dns01-production-cluster-issuer
spec:
ingressClassName: external-nginx
tls:
- hosts:
- goviolin.k8s.sreboy.com
secretName: goviolin-k8s-sreboy-com-key-pair
rules:
- host: goviolin.k8s.sreboy.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: goviolin
port:
number: 80
monitoring-ingress.yaml
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: grafana
namespace: monitoring
annotations:
cert-manager.io/issuer: letsencrypt-dns01-production-cluster-issuer
spec:
ingressClassName: internal-nginx
tls:
- hosts:
- grafana.k8s.sreboy.com
secretName: grafana-k8s-sreboy-com-key-pair
rules:
- host: grafana.k8s.sreboy.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: monitoring-grafana
port:
number: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: prometheus
namespace: monitoring
annotations:
cert-manager.io/issuer: letsencrypt-dns01-production-cluster-issuer
spec:
ingressClassName: internal-nginx
tls:
- hosts:
- prometheus.k8s.sreboy.com
secretName: prometheus-k8s-sreboy-com-key-pair
rules:
- host: prometheus.k8s.sreboy.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: monitoring-kube-prometheus-prometheus
port:
number: 9090
---
monitoring-ingress.yaml
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: monitoring
namespace: monitoring
annotations:
cert-manager.io/issuer: letsencrypt-dns01-production-cluster-issuer
spec:
ingressClassName: internal-nginx
tls:
- hosts:
- grafana.k8s.sreboy.com
secretName: grafana-k8s-sreboy-com-key-pair
- hosts:
- prometheus.k8s.sreboy.com
secretName: prometheus-k8s-sreboy-com-key-pair
- hosts:
- alertmanager.k8s.sreboy.com
secretName: alertmanager-k8s-sreboy-com-key-pair
- hosts:
- kube-state-metrics.k8s.sreboy.com
secretName: kube-state-metrics-k8s-sreboy-com-key-pair
rules:
- host: grafana.k8s.sreboy.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: monitoring-grafana
port:
number: 80
- host: prometheus.k8s.sreboy.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: monitoring-kube-prometheus-prometheus
port:
number: 9090
- host: alertmanager.k8s.sreboy.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: monitoring-kube-prometheus-alertmanager
port:
number: 9093
- host: kube-state-metrics.k8s.sreboy.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: monitoring-kube-state-metrics
port:
number: 8080
---