Skip to content

Allow configuring the Kubernetes API server endpoint to avoid kube-proxy startup dependency #659

Description

@tn20000

What happened:

On an EKS cluster where kube-proxy's initial iptables sync takes longer than usual, a new node can become Ready and start workloads before the Kubernetes Service ClusterIP is usable on that node. The network policy agent builds its Kubernetes client with rest.InClusterConfig(), so it initially targets that Service ClusterIP.

The resulting startup sequence is:

  1. the network policy agent starts before kube-proxy's initial sync completes;
  2. API requests to the Kubernetes Service IP time out;
  3. the PolicyEndpoint informer cache does not sync before its deadline;
  4. the manager exits and the agent restarts; and
  5. a later attempt succeeds after kube-proxy finishes programming Service rules.

This has been observed consistently across new-node launches in the affected cluster.

Attach logs

Representative, anonymized messages:

Get "https://<kubernetes-service-ip>:443/apis/networking.k8s.aws/v1alpha1/policyendpoints?...": dial tcp <kubernetes-service-ip>:443: i/o timeout
problem running manager: failed to wait for policyendpoint caches to sync

The network policy agent's RuntimeConfig already has an APIServer field, but it is not bound to a CLI flag and BuildRestConfig does not use it.

What you expected to happen:

The agent should optionally accept a direct Kubernetes API server URL, while continuing to use the normal in-cluster service-account token and CA configuration. When configured with the EKS API endpoint, informer cache sync can proceed before kube-proxy has programmed the Kubernetes Service ClusterIP, avoiding the startup restart loop.

A narrow implementation would:

  1. expose the existing field as an optional --apiserver flag;
  2. construct the REST config as it does today (in-cluster or --kubeconfig); and
  3. override only rest.Config.Host when --apiserver is set.

The default remains unchanged. This does not bypass informer cache synchronization; it only removes kube-proxy's Service VIP from the agent's bootstrap dependency chain. The deployment layer would still be responsible for supplying the endpoint.

How to reproduce it (as minimally and precisely as possible):

  1. Delay kube-proxy's first iptables sync on a new node.
  2. Start aws-node with network policy enabled on that node.
  3. Allow the node to become Ready before kube-proxy finishes its initial sync.
  4. Observe the network policy agent time out connecting to the Kubernetes Service ClusterIP and exit after its PolicyEndpoint cache-sync deadline.
  5. Observe a subsequent restart succeed only after kube-proxy completes its first sync.

Anything else we need to know?:

The EKS API endpoint is routable directly from the node before kube-proxy is ready. Dynamically calling DescribeCluster from the agent is not necessary; the endpoint can be injected by the deployment/add-on layer. The same unused APIServer field and in-cluster-only behavior are present in released and current source.

Detailed timestamps and environment versions can be shared privately if useful.

Environment:

  • Kubernetes version (use kubectl version): EKS (details available privately)
  • CNI Version: details available privately
  • Network Policy Agent Version: reproduced on a released version; current source has the same configuration gap
  • OS: Amazon Linux
  • Kernel: details available privately

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions