Open alfredkrohmer opened 8 months ago
@alfredkrohmer is this on a cloud -provider or on baremetal+metallb etc
/remove-kind bug
/triage needs-information
This is on OCI (OKE) with a Network Load Balancer as a service, but as I pointed out with the code references, this seems to be generic behavior that triggers when a new version of the controller is rolled out with a different label set than the old pods.
I saw it happen on minikube with metallb
just like another feature, this also impacts external-dns use-case
/triage accepted
I think it will be interesting to see if it happens when you set the LoadBalancer IP https://github.com/kubernetes/ingress-nginx/blob/9c384c7eb85b9833bad491e14fffcfe3b9c59ee5/charts/ingress-nginx/values.yaml#L469 (if OKE/OCI supports that field)
OKE does support that field, but only for public IPs and unfortunately we don't have test clusters with public subnets available 🙁
Not sure what the right approach to fix this would be. I can think of a couple of options:
Update: We realised we inject ec2-instance-id
labels to all pods in our cluster, and so the controller pods always think they are the last one, and so runs the cleanup. So our issue is unrelated to specifically controller version update.
I can add +1 to this, we see this often, even when not updating, e.g.
We see the same symptoms everytime the controller pod is terminated:
We run 2 replicas of the nginx-ingress-controller. We don't use Helm, we use the direct k8s manifest import.
I would expect that if one replica is terminated, as long as there is another replica that becomes leader, it should not update the statuses?
~Update: we also see some errors around leader election during the shutting down, similar to https://github.com/kubernetes/ingress-nginx/issues/8996 - so it may be compounded issue.~
Update: the leader election errors seem to be irrelevent.
If the DNS is queried at the right time (when no record exists), the negative cache TTL might extend the issue beyond the actual recovery, which makes this worse I think.
cc @strongjz @rikatz @tao12345666333
Any idea / opinion on how to fix this?
@alfredkrohmer any chance you can test setting the LoadBalancerIP in values file and update with behaviour https://github.com/kubernetes/ingress-nginx/blob/9c384c7eb85b9833bad491e14fffcfe3b9c59ee5/charts/ingress-nginx/values.yaml#L469
This doesn't really work for us as we don't pick the load balancer IP statically. It's coming from the status of the service for which a backing load balancer in the cloud will be created.
/assign
/kind feature /priority important-longterm
Any new regarding this issue ?
Oh wow, not sure why I haven't seen this before, but there is actually a flag to not remove the ingress status on shutdown :facepalm:
https://github.com/kubernetes/ingress-nginx/blob/886956e5728c318c3fa48792a08b940b7cdba4ff/pkg/flags/flags.go#L138
https://github.com/kubernetes/ingress-nginx/blob/886956e5728c318c3fa48792a08b940b7cdba4ff/internal/ingress/status/status.go#L113
Now I wonder if this should be set to false
by default in the Helm chart.
We have the same issue when upgrading to 4.10.x or 4.11.x versions. This led to the load balancer IP being removed from the status of all ingresses managed by the ingress controller, which in turn led to external-dns deleting all the DNS records for these ingresses. We are using AKS - 1.29.8 version
Hello there, I'm still facing this issue with multiple nginx ingress controller versions. I have tried the below ingress-nginx helm chart versions:
AWS EKS cluster - 1.30 version
It shows the below errors:
I have tried to change the permissions/scope of the ClusterRole and given it [create, get & update] but no luck
Any updates regarding this issue
Thanks in advance
There is a deprecated field you can try to use https://kubernetes.io/docs/concepts/services-networking/service/#external-ips but it depends on the cloud-provider too.
The values file key:value pair is here https://github.com/kubernetes/ingress-nginx/blob/c9d33b75d52de3f83fd49d37c85aa97618a5143b/charts/ingress-nginx/values.yaml#L502
@longwuyuan I'm using AWS and this field should be filled automatically by the DNS of the NLB. I can't put it statically
But the error is so misleading if this is the solution. In your opinion, is this issue related to tagging AWS resources ?
There are 2 aspects that are impacting this.
One factor is that the controller code does not contain anything to do with the AWS LB. The controller creates a service of --type LoadBlaancer. That itself is a upstream Kubernetes Resource and not a CRD that we create.
The second factor is that the cloud-controller-manager will watch for events related to a service of --type LoadBalancer. So if a service of --type LoadBalaner is created, then the cloud-controller-manager will trigger events in the cloud-iinfrastructure provider
That field is the closest we have to influence your situation
cc @Gacko as he sometimes tests on AWS. The project CI does not do any test on AWS and its also not easy to document and test all the possible migration path possibilities.
@hamza-louis I think you got lost here. It looks like your problem is absolutely unrelated to what is being discussed in this issue.
What happened:
When updating nginx-ingress-controller Helm chart to a new version (in this case: 4.9.1 to 4.10.0), the current leader pods logs these messages:
This led to the load balancer IP (
10.1.2.3
) being removed from the status of all ingresses managed by the ingress controller, which in turn led to external-dns deleting all the DNS records for these ingresses, which caused an outage.The newly elected leader from the updated deployment then put the load balancer IP back in the ingress status and external-dns recreated all the records.
This does not happen during normal pod restarts, only during version upgrades (we retroactively found the same logs during our last upgrade from 4.9.0 to 4.9.1).
What you expected to happen:
nginx-ingress-controller should not clear the status of ingresses when it shuts down during a version upgade.
NGINX Ingress controller version (exec into the pod and run nginx-ingress-controller --version.):
Kubernetes version (use
kubectl version
): v1.27.2Environment:
Cloud provider or hardware configuration: doesn't matter
OS (e.g. from /etc/os-release): doesn't matter
Kernel (e.g.
uname -a
): doesn't matterInstall tools: doesn't matter
Basic cluster related info: doesn't matter
How was the ingress-nginx-controller installed:
with
values.yaml
:How to reproduce this issue:
kubectl get ingress -A -w
in a background terminal to observe the load balancer IP being removed from all the ingresses manage by the controller.Anything else we need to know:
The error message seems to be coming from here: https://github.com/kubernetes/ingress-nginx/blob/9c384c7eb85b9833bad491e14fffcfe3b9c59ee5/internal/ingress/status/status.go#L135
This line is normally not reached when
isRunningMultiplePods
returnstrue
: https://github.com/kubernetes/ingress-nginx/blob/9c384c7eb85b9833bad491e14fffcfe3b9c59ee5/internal/ingress/status/status.go#L130-L133Judging by the code of this function: https://github.com/kubernetes/ingress-nginx/blob/9c384c7eb85b9833bad491e14fffcfe3b9c59ee5/internal/ingress/status/status.go#L238-L252
it tries to find pods with the same labels as the currently running pod and only returns true if it finds at least one such pod. During a version upgrade, it is very likely that this return
false
because the Helm chart adds the version of the chart and the version of the ingress controller as labels to the pods, hence the new pods of the updated deployment are not considered anymore by this function.