Skip to content

Add readiness probe for NGINX on pod startup #3629

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

Merged
merged 5 commits into from
Jul 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 33 additions & 8 deletions apis/v1alpha2/nginxproxy_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,11 @@ type KubernetesSpec struct {

// Deployment is the configuration for the NGINX Deployment.
type DeploymentSpec struct {
// Container defines container fields for the NGINX container.
//
// +optional
Container ContainerSpec `json:"container"`

// Number of desired Pods.
//
// +optional
Expand All @@ -399,24 +404,19 @@ type DeploymentSpec struct {
//
// +optional
Pod PodSpec `json:"pod"`
}

// DaemonSet is the configuration for the NGINX DaemonSet.
type DaemonSetSpec struct {
// Container defines container fields for the NGINX container.
//
// +optional
Container ContainerSpec `json:"container"`
}

// DaemonSet is the configuration for the NGINX DaemonSet.
type DaemonSetSpec struct {
// Pod defines Pod-specific fields.
//
// +optional
Pod PodSpec `json:"pod"`

// Container defines container fields for the NGINX container.
//
// +optional
Container ContainerSpec `json:"container"`
}

// PodSpec defines Pod-specific fields.
Expand Down Expand Up @@ -486,6 +486,11 @@ type ContainerSpec struct {
// +optional
Lifecycle *corev1.Lifecycle `json:"lifecycle,omitempty"`

// ReadinessProbe defines the readiness probe for the NGINX container.
//
// +optional
ReadinessProbe *ReadinessProbeSpec `json:"readinessProbe,omitempty"`

// HostPorts are the list of ports to expose on the host.
//
// +optional
Expand All @@ -497,6 +502,26 @@ type ContainerSpec struct {
VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty"`
}

// ReadinessProbeSpec defines the configuration for the NGINX readiness probe.
type ReadinessProbeSpec struct {
// Port is the port on which the readiness endpoint is exposed.
// If not specified, the default port is 8081.
//
// +optional
// +kubebuilder:validation:Minimum=1
// +kubebuilder:validation:Maximum=65535
Port *int32 `json:"port,omitempty"`

// InitialDelaySeconds is the number of seconds after the container has
// started before the readiness probe is initiated.
// If not specified, the default is 3 seconds.
//
// +optional
// +kubebuilder:validation:Minimum=0
// +kubebuilder:validation:Maximum=3600
InitialDelaySeconds *int32 `json:"initialDelaySeconds,omitempty"`
}

// Image is the NGINX image to use.
type Image struct {
// Repository is the image path.
Expand Down
34 changes: 32 additions & 2 deletions apis/v1alpha2/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions charts/nginx-gateway-fabric/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -264,9 +264,9 @@ The following table lists the configurable parameters of the NGINX Gateway Fabri
| `certGenerator.ttlSecondsAfterFinished` | How long to wait after the cert generator job has finished before it is removed by the job controller. | int | `30` |
| `clusterDomain` | The DNS cluster domain of your Kubernetes cluster. | string | `"cluster.local"` |
| `gateways` | A list of Gateway objects. View https://gateway-api.sigs.k8s.io/reference/spec/#gateway for full Gateway reference. | list | `[]` |
| `nginx` | The nginx section contains the configuration for all NGINX data plane deployments installed by the NGINX Gateway Fabric control plane. | object | `{"config":{},"container":{"hostPorts":[],"lifecycle":{},"resources":{},"volumeMounts":[]},"debug":false,"image":{"pullPolicy":"Always","repository":"ghcr.io/nginx/nginx-gateway-fabric/nginx","tag":"edge"},"imagePullSecret":"","imagePullSecrets":[],"kind":"deployment","plus":false,"pod":{},"replicas":1,"service":{"externalTrafficPolicy":"Local","loadBalancerClass":"","loadBalancerIP":"","loadBalancerSourceRanges":[],"nodePorts":[],"type":"LoadBalancer"},"usage":{"caSecretName":"","clientSSLSecretName":"","endpoint":"","resolver":"","secretName":"nplus-license","skipVerify":false}}` |
| `nginx` | The nginx section contains the configuration for all NGINX data plane deployments installed by the NGINX Gateway Fabric control plane. | object | `{"config":{},"container":{"hostPorts":[],"lifecycle":{},"readinessProbe":{},"resources":{},"volumeMounts":[]},"debug":false,"image":{"pullPolicy":"Always","repository":"ghcr.io/nginx/nginx-gateway-fabric/nginx","tag":"edge"},"imagePullSecret":"","imagePullSecrets":[],"kind":"deployment","plus":false,"pod":{},"replicas":1,"service":{"externalTrafficPolicy":"Local","loadBalancerClass":"","loadBalancerIP":"","loadBalancerSourceRanges":[],"nodePorts":[],"type":"LoadBalancer"},"usage":{"caSecretName":"","clientSSLSecretName":"","endpoint":"","resolver":"","secretName":"nplus-license","skipVerify":false}}` |
| `nginx.config` | The configuration for the data plane that is contained in the NginxProxy resource. This is applied globally to all Gateways managed by this instance of NGINX Gateway Fabric. | object | `{}` |
| `nginx.container` | The container configuration for the NGINX container. This is applied globally to all Gateways managed by this instance of NGINX Gateway Fabric. | object | `{"hostPorts":[],"lifecycle":{},"resources":{},"volumeMounts":[]}` |
| `nginx.container` | The container configuration for the NGINX container. This is applied globally to all Gateways managed by this instance of NGINX Gateway Fabric. | object | `{"hostPorts":[],"lifecycle":{},"readinessProbe":{},"resources":{},"volumeMounts":[]}` |
| `nginx.container.hostPorts` | A list of HostPorts to expose on the host. This configuration allows containers to bind to a specific port on the host node, enabling external network traffic to reach the container directly through the host's IP address and port. Use this option when you need to expose container ports on the host for direct access, such as for debugging, legacy integrations, or when NodePort/LoadBalancer services are not suitable. Note: Using hostPort may have security and scheduling implications, as it ties pods to specific nodes and ports. | list | `[]` |
| `nginx.container.lifecycle` | The lifecycle of the NGINX container. | object | `{}` |
| `nginx.container.resources` | The resource requirements of the NGINX container. | object | `{}` |
Expand Down
6 changes: 6 additions & 0 deletions charts/nginx-gateway-fabric/values.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,12 @@
"title": "lifecycle",
"type": "object"
},
"readinessProbe": {
"description": "# -- Defines the settings for the data plane readiness probe. This probe returns Ready when the NGINX data plane is ready to serve traffic.",
"required": [],
"title": "readinessProbe",
"type": "object"
},
"resources": {
"description": "The resource requirements of the NGINX container.",
"required": [],
Expand Down
13 changes: 13 additions & 0 deletions charts/nginx-gateway-fabric/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,19 @@ nginx:
# -- volumeMounts are the additional volume mounts for the NGINX container.
volumeMounts: []

## -- Defines the settings for the data plane readiness probe. This probe returns Ready when the NGINX data plane is ready to serve traffic.
readinessProbe: {}
# @schema
# type: integer
# minimum: 1
# maximum: 65535
# @schema
# -- Port in which the readiness endpoint is exposed.
# port: 8081

# -- The number of seconds after the Pod has started before the readiness probes are initiated.
# initialDelaySeconds: 3

# -- The service configuration for the NGINX data plane. This is applied globally to all Gateways managed by this
# instance of NGINX Gateway Fabric.
service:
Expand Down
44 changes: 44 additions & 0 deletions config/crd/bases/gateway.nginx.org_nginxproxies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,28 @@ spec:
StopSignal can only be set for Pods with a non-empty .spec.os.name
type: string
type: object
readinessProbe:
description: ReadinessProbe defines the readiness probe
for the NGINX container.
properties:
initialDelaySeconds:
description: |-
InitialDelaySeconds is the number of seconds after the container has
started before the readiness probe is initiated.
If not specified, the default is 3 seconds.
format: int32
maximum: 3600
minimum: 0
type: integer
port:
description: |-
Port is the port on which the readiness endpoint is exposed.
If not specified, the default port is 8081.
format: int32
maximum: 65535
minimum: 1
type: integer
type: object
resources:
description: Resources describes the compute resource
requirements.
Expand Down Expand Up @@ -3773,6 +3795,28 @@ spec:
StopSignal can only be set for Pods with a non-empty .spec.os.name
type: string
type: object
readinessProbe:
description: ReadinessProbe defines the readiness probe
for the NGINX container.
properties:
initialDelaySeconds:
description: |-
InitialDelaySeconds is the number of seconds after the container has
started before the readiness probe is initiated.
If not specified, the default is 3 seconds.
format: int32
maximum: 3600
minimum: 0
type: integer
port:
description: |-
Port is the port on which the readiness endpoint is exposed.
If not specified, the default port is 8081.
format: int32
maximum: 65535
minimum: 1
type: integer
type: object
resources:
description: Resources describes the compute resource
requirements.
Expand Down
44 changes: 44 additions & 0 deletions deploy/crds.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -947,6 +947,28 @@ spec:
StopSignal can only be set for Pods with a non-empty .spec.os.name
type: string
type: object
readinessProbe:
description: ReadinessProbe defines the readiness probe
for the NGINX container.
properties:
initialDelaySeconds:
description: |-
InitialDelaySeconds is the number of seconds after the container has
started before the readiness probe is initiated.
If not specified, the default is 3 seconds.
format: int32
maximum: 3600
minimum: 0
type: integer
port:
description: |-
Port is the port on which the readiness endpoint is exposed.
If not specified, the default port is 8081.
format: int32
maximum: 65535
minimum: 1
type: integer
type: object
resources:
description: Resources describes the compute resource
requirements.
Expand Down Expand Up @@ -4358,6 +4380,28 @@ spec:
StopSignal can only be set for Pods with a non-empty .spec.os.name
type: string
type: object
readinessProbe:
description: ReadinessProbe defines the readiness probe
for the NGINX container.
properties:
initialDelaySeconds:
description: |-
InitialDelaySeconds is the number of seconds after the container has
started before the readiness probe is initiated.
If not specified, the default is 3 seconds.
format: int32
maximum: 3600
minimum: 0
type: integer
port:
description: |-
Port is the port on which the readiness endpoint is exposed.
If not specified, the default port is 8081.
format: int32
maximum: 65535
minimum: 1
type: integer
type: object
resources:
description: Resources describes the compute resource
requirements.
Expand Down
10 changes: 6 additions & 4 deletions internal/controller/nginx/config/base_http_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,18 @@ import (
var baseHTTPTemplate = gotemplate.Must(gotemplate.New("baseHttp").Parse(baseHTTPTemplateText))

type httpConfig struct {
Includes []shared.Include
HTTP2 bool
Includes []shared.Include
HTTP2 bool
NginxReadinessProbePort int32
}

func executeBaseHTTPConfig(conf dataplane.Configuration) []executeResult {
includes := createIncludesFromSnippets(conf.BaseHTTPConfig.Snippets)

hc := httpConfig{
HTTP2: conf.BaseHTTPConfig.HTTP2,
Includes: includes,
HTTP2: conf.BaseHTTPConfig.HTTP2,
Includes: includes,
NginxReadinessProbePort: conf.BaseHTTPConfig.NginxReadinessProbePort,
}

results := make([]executeResult, 0, len(includes)+1)
Expand Down
10 changes: 10 additions & 0 deletions internal/controller/nginx/config/base_http_config_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,16 @@ map $request_uri $request_uri_path {
"~^(?P<path>[^?]*)(\?.*)?$" $path;
}

# NGINX health check server block.
server {
listen {{ .NginxReadinessProbePort }};

location = /readyz {
access_log off;
return 200;
}
}

{{ range $i := .Includes -}}
include {{ $i.Name }};
{{ end -}}
Expand Down
Loading