-
Notifications
You must be signed in to change notification settings - Fork 105
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Readiness gate support for 100% ingress HA #582
Comments
When you create a Service with
Once the traffic is sent to the Node Port on any Kubernetes node, Kubernetes/CNI is now responsible for the traffic. Usually kube-proxy or your CNI then checks where Pods for the service are running, and forwards the traffic to one the pods. It does not matter on which Node the pod is running. If you have Pods marked as Ready in your Service, which are actually not ready to receive traffic, that would explain your problem. |
@apricote ok, I'll explain problem with more detail because you don't understand what I mean :D So, here is usecase:
Status in Hetzner LoadBalancer is:
Now, the problematic scenario:
This is real problem, the only solution for this is to run ingress-nginx as DaemonSet so Hetzner will always point to all nodes. Altough, recreating those pods will still have same problem. Readiness Gate can inject information from external LB about it's state, so Kubernetes will be aware that new pod (on new node) is not ready yet (even though application started and is ready) until external loadbalancer will have it in healtly state. Check this how it works in AWS: https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.1/deploy/pod_readiness_gate/ especially usecase: "Rollout of new pods takes less time than it takes the AWS Load Balancer controller to register the new pods and for their health state turn »Healthy« in the target group" |
How do you deploy Looking at the AWS docs, I think they need this because they route directly from the Load Balancer to the Internal IP of the Pod (through ENI), which is not something that Hetzner Cloud Load Balancers do, they always target your Nodes. |
@apricote I'm deploying NGINX as regular Also - to be honest - I would prefer my current behaviour over "Kubernetes accepting traffic and routing it everywhere", because then I have control over where my traffic goes from LB to nodes (for example if I would like to limit traffic from LB to node to be only in single region - I don't want traffic to go from Falkenstein to Helsinki because latency there is terrible 22ms!)
Helm Config for my ingress-nginx: controller:
service:
externalTrafficPolicy: Local
annotations:
external-dns.alpha.kubernetes.io/hostname: "*.k8s.trng.me,*.example.com"
load-balancer.hetzner.cloud/name: "kube"
load-balancer.hetzner.cloud/location: fsn1
load-balancer.hetzner.cloud/use-private-ip: "true"
load-balancer.hetzner.cloud/uses-proxyprotocol: "true"
# ExternalIP as hostname NEEDS TO BE set, otherwise
# hcloud-loadbalancer-controller will put here real extIP of LB and
# kube-proxy will route that traffic internall instead of to real LB,
# and traffic will be broken because non-proxied traffic will to into proxy-expected nginx
load-balancer.hetzner.cloud/hostname: kube-lb.example.com
config:
use-proxy-protocol: true
use-forwarded-headers: "true"
compute-full-forwarded-for: "true"
extraArgs:
default-ssl-certificate: "infra/tls-default"
watchIngressWithoutClass: false
ingressClassByName: false
ingressClassResource:
name: ohcs-nginx # default: nginx
#enabled: true
default: true
controllerValue: "k8s.io/ohcs-nginx" # default: k8s.io/ingress-nginx
replicaCount: 2
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 0
minReadySeconds: 30
resources:
requests:
cpu: 15m
memory: 128Mi
limits:
#cpu: 1
memory: 192Mi
tolerations:
- key: node-role.kubernetes.io/control-plane
operator: Exists
effect: NoSchedule
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 10
preference:
matchExpressions:
- key: node-role.kubernetes.io/control-plane
operator: Exists
- weight: 20
preference:
matchExpressions:
- key: kubernetes.io/arch
operator: In
values:
- arm64
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- podAffinityTerm:
labelSelector:
matchLabels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
topologyKey: kubernetes.io/hostname
weight: 50
tcp:
22: "gitlab/gitlab-gitlab-shell:22" |
Okay,
You can do this with the |
@apricote I know I can use label, but... I don't want to use it because I still want to be able to use Helsinki as a last resort in case of failure of other regions ;) I think this makes sense. Direct traffic from LB just makes more sense than random balancing which will be balanced again by Kube. Latency is the answer for "but why"... |
This issue has been marked as stale because it has not had recent activity. The bot will close the issue if no further action occurs. |
Please add support for Readiness Gates, so Ingress NGINX (and others) will have injected information if Hetzner Cloud already have target properly attached.
Right now, without that information when I redeploy NGINX to other nodes, it creates new Pods too fast on different nodes in comparizon to Hetzner and it just breaks ingress for half a minute until Hetzner reconfigured their load balancer which takes time.
The text was updated successfully, but these errors were encountered: