Skip to content

Commit c66c94a

Browse files
committed
CP/DP Split: write configuration to agent (#2999)
This commit adds functionality to send nginx configuration to the agent. It also adds support for the single nginx Deployment to be scaled, and send configuration to all replicas. This requires tracking all Subscriptions for a particular deployment, and receiving all responses from those replicas to determine the status to write to the Gateway.
1 parent 53725d5 commit c66c94a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+5319
-604
lines changed

build/Dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ FROM golang:1.24 AS ca-certs-provider
1414
FROM scratch AS common
1515
# CA certs are needed for telemetry report so that NGF can verify the server's certificate.
1616
COPY --from=ca-certs-provider --link /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
17-
USER 102:1001
17+
USER 101:1001
1818
ARG BUILD_AGENT
1919
ENV BUILD_AGENT=${BUILD_AGENT}
2020
ENTRYPOINT [ "/usr/bin/gateway" ]

charts/nginx-gateway-fabric/README.md

-1
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,6 @@ The following table lists the configurable parameters of the NGINX Gateway Fabri
268268
| `nginx.image.tag` | | string | `"edge"` |
269269
| `nginx.lifecycle` | The lifecycle of the nginx container. | object | `{}` |
270270
| `nginx.plus` | Is NGINX Plus image being used | bool | `false` |
271-
| `nginx.securityContext.allowPrivilegeEscalation` | Some environments may need this set to true in order for the control plane to successfully reload NGINX. | bool | `false` |
272271
| `nginx.usage.caSecretName` | The name of the Secret containing the NGINX Instance Manager CA certificate. Must exist in the same namespace that the NGINX Gateway Fabric control plane is running in (default namespace: nginx-gateway). | string | `""` |
273272
| `nginx.usage.clientSSLSecretName` | The name of the Secret containing the client certificate and key for authenticating with NGINX Instance Manager. Must exist in the same namespace that the NGINX Gateway Fabric control plane is running in (default namespace: nginx-gateway). | string | `""` |
274273
| `nginx.usage.endpoint` | The endpoint of the NGINX Plus usage reporting server. Default: product.connect.nginx.com | string | `""` |

charts/nginx-gateway-fabric/templates/clusterrole.yaml

+1-15
Original file line numberDiff line numberDiff line change
@@ -11,35 +11,21 @@ rules:
1111
- namespaces
1212
- services
1313
- secrets
14+
- pods
1415
{{- if .Values.nginxGateway.gwAPIExperimentalFeatures.enable }}
1516
- configmaps
1617
{{- end }}
1718
verbs:
1819
- get
1920
- list
2021
- watch
21-
{{- if or .Values.nginxGateway.productTelemetry.enable .Values.nginx.plus }}
22-
- apiGroups:
23-
- ""
24-
resources:
25-
- pods
26-
verbs:
27-
- get
2822
- apiGroups:
2923
- apps
3024
resources:
3125
- replicasets
3226
verbs:
3327
- get
34-
{{- end }}
35-
{{- if .Values.nginx.plus }}
36-
- apiGroups:
37-
- apps
38-
resources:
39-
- replicasets
40-
verbs:
4128
- list
42-
{{- end }}
4329
{{- if or .Values.nginxGateway.productTelemetry.enable .Values.nginx.plus }}
4430
- apiGroups:
4531
- ""

charts/nginx-gateway-fabric/templates/deployment.yaml

+2-1
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,9 @@ spec:
145145
capabilities:
146146
drop:
147147
- ALL
148+
allowPrivilegeEscalation: false
148149
readOnlyRootFilesystem: true
149-
runAsUser: 102
150+
runAsUser: 101
150151
runAsGroup: 1001
151152
{{- with .Values.nginxGateway.extraVolumeMounts -}}
152153
{{ toYaml . | nindent 8 }}
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1+
# TODO(sberman): will need an SCC for nginx ServiceAccounts as well.
12
{{- if .Capabilities.APIVersions.Has "security.openshift.io/v1/SecurityContextConstraints" }}
23
kind: SecurityContextConstraints
34
apiVersion: security.openshift.io/v1
45
metadata:
56
name: {{ include "nginx-gateway.scc-name" . }}
6-
allowPrivilegeEscalation: {{ .Values.nginx.securityContext.allowPrivilegeEscalation }}
7+
allowPrivilegeEscalation: false
78
allowHostDirVolumePlugin: false
89
allowHostIPC: false
910
allowHostNetwork: false
@@ -14,7 +15,7 @@ readOnlyRootFilesystem: true
1415
runAsUser:
1516
type: MustRunAsRange
1617
uidRangeMin: 101
17-
uidRangeMax: 102
18+
uidRangeMax: 101
1819
fsGroup:
1920
type: MustRunAs
2021
ranges:
@@ -29,16 +30,8 @@ seLinuxContext:
2930
type: MustRunAs
3031
seccompProfiles:
3132
- runtime/default
32-
volumes:
33-
- emptyDir
34-
- secret
35-
- configMap
36-
- projected
3733
users:
3834
- {{ printf "system:serviceaccount:%s:%s" .Release.Namespace (include "nginx-gateway.serviceAccountName" .) }}
39-
allowedCapabilities:
40-
- NET_BIND_SERVICE
41-
- KILL
4235
requiredDropCapabilities:
4336
- ALL
4437
{{- end }}

charts/nginx-gateway-fabric/templates/tmp-nginx-agent-conf.yaml

+24
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,29 @@ data:
1515
- /var/run/nginx
1616
features:
1717
- connection
18+
- configuration
19+
- certificates
20+
- metrics
21+
{{- if .Values.nginx.plus }}
22+
- api-action
23+
{{- end }}
1824
log:
1925
level: debug
26+
collector:
27+
receivers:
28+
host_metrics:
29+
collection_interval: 1m0s
30+
initial_delay: 1s
31+
scrapers:
32+
cpu: {}
33+
memory: {}
34+
disk: {}
35+
network: {}
36+
filesystem: {}
37+
processors:
38+
batch: {}
39+
exporters:
40+
prometheus_exporter:
41+
server:
42+
host: "0.0.0.0"
43+
port: 9113

charts/nginx-gateway-fabric/templates/tmp-nginx-deployment.yaml

+28-10
Original file line numberDiff line numberDiff line change
@@ -13,30 +13,37 @@ spec:
1313
labels:
1414
app.kubernetes.io/name: tmp-nginx-deployment
1515
app.kubernetes.io/instance: {{ .Release.Name }}
16+
annotations:
17+
{{- if .Values.metrics.enable }}
18+
prometheus.io/scrape: "true"
19+
prometheus.io/port: "{{ .Values.metrics.port }}"
20+
{{- if .Values.metrics.secure }}
21+
prometheus.io/scheme: "https"
22+
{{- end }}
23+
{{- end }}
1624
spec:
1725
initContainers:
18-
- name: sleep # wait for a bit for control plane to be ready
19-
image: {{ .Values.nginxGateway.image.repository }}:{{ default .Chart.AppVersion .Values.nginxGateway.image.tag }}
20-
imagePullPolicy: {{ .Values.nginxGateway.image.pullPolicy }}
21-
command:
22-
- /usr/bin/gateway
23-
- sleep
24-
- --duration=15s
2526
- name: init
2627
image: {{ .Values.nginxGateway.image.repository }}:{{ default .Chart.AppVersion .Values.nginxGateway.image.tag }}
2728
imagePullPolicy: {{ .Values.nginxGateway.image.pullPolicy }}
2829
command:
2930
- /usr/bin/gateway
3031
- initialize
3132
- --source
33+
- /agent/nginx-agent.conf
34+
- --destination
35+
- /etc/nginx-agent
36+
- --source
3237
- /includes/main.conf
38+
- --destination
39+
- /etc/nginx/main-includes
3340
{{- if .Values.nginx.plus }}
3441
- --source
3542
- /includes/mgmt.conf
3643
- --nginx-plus
37-
{{- end }}
3844
- --destination
3945
- /etc/nginx/main-includes
46+
{{- end }}
4047
env:
4148
- name: POD_UID
4249
valueFrom:
@@ -49,9 +56,13 @@ spec:
4956
drop:
5057
- ALL
5158
readOnlyRootFilesystem: true
52-
runAsUser: 102
59+
runAsUser: 101
5360
runAsGroup: 1001
5461
volumeMounts:
62+
- name: nginx-agent-config
63+
mountPath: /agent
64+
- name: nginx-agent
65+
mountPath: /etc/nginx-agent
5566
- name: nginx-includes-bootstrap
5667
mountPath: /includes
5768
- name: nginx-main-includes
@@ -69,10 +80,11 @@ spec:
6980
name: http
7081
- containerPort: 443
7182
name: https
83+
- name: metrics
84+
containerPort: {{ .Values.metrics.port }}
7285
securityContext:
7386
seccompProfile:
7487
type: RuntimeDefault
75-
allowPrivilegeEscalation: {{ .Values.nginx.securityContext.allowPrivilegeEscalation }}
7688
capabilities:
7789
add:
7890
- NET_BIND_SERVICE
@@ -84,6 +96,8 @@ spec:
8496
volumeMounts:
8597
- name: nginx-agent
8698
mountPath: /etc/nginx-agent
99+
- name: nginx-agent-log
100+
mountPath: /var/log/nginx-agent
87101
- name: nginx-conf
88102
mountPath: /etc/nginx/conf.d
89103
- name: nginx-stream-conf
@@ -140,8 +154,12 @@ spec:
140154
{{- end }}
141155
volumes:
142156
- name: nginx-agent
157+
emptyDir: {}
158+
- name: nginx-agent-config
143159
configMap:
144160
name: nginx-agent-config
161+
- name: nginx-agent-log
162+
emptyDir: {}
145163
- name: nginx-conf
146164
emptyDir: {}
147165
- name: nginx-stream-conf

charts/nginx-gateway-fabric/values.schema.json

-14
Original file line numberDiff line numberDiff line change
@@ -298,20 +298,6 @@
298298
"title": "plus",
299299
"type": "boolean"
300300
},
301-
"securityContext": {
302-
"properties": {
303-
"allowPrivilegeEscalation": {
304-
"default": false,
305-
"description": "Some environments may need this set to true in order for the control plane to successfully reload NGINX.",
306-
"required": [],
307-
"title": "allowPrivilegeEscalation",
308-
"type": "boolean"
309-
}
310-
},
311-
"required": [],
312-
"title": "securityContext",
313-
"type": "object"
314-
},
315301
"usage": {
316302
"description": "Configuration for NGINX Plus usage reporting.",
317303
"properties": {

charts/nginx-gateway-fabric/values.yaml

-4
Original file line numberDiff line numberDiff line change
@@ -134,10 +134,6 @@ nginx:
134134
# @schema
135135
pullPolicy: Always
136136

137-
securityContext:
138-
# -- Some environments may need this set to true in order for the control plane to successfully reload NGINX.
139-
allowPrivilegeEscalation: false
140-
141137
# -- Is NGINX Plus image being used
142138
plus: false
143139

cmd/gateway/commands.go

+16-11
Original file line numberDiff line numberDiff line change
@@ -519,14 +519,14 @@ func createInitializeCommand() *cobra.Command {
519519

520520
// flag values
521521
var srcFiles []string
522-
var dest string
522+
var destDirs []string
523523
var plus bool
524524

525525
cmd := &cobra.Command{
526526
Use: "initialize",
527527
Short: "Write initial configuration files",
528528
RunE: func(_ *cobra.Command, _ []string) error {
529-
if err := validateCopyArgs(srcFiles, dest); err != nil {
529+
if err := validateCopyArgs(srcFiles, destDirs); err != nil {
530530
return err
531531
}
532532

@@ -546,7 +546,7 @@ func createInitializeCommand() *cobra.Command {
546546
logger.Info(
547547
"Starting init container",
548548
"source filenames to copy", srcFiles,
549-
"destination directory", dest,
549+
"destination directories", destDirs,
550550
"nginx-plus",
551551
plus,
552552
)
@@ -558,16 +558,21 @@ func createInitializeCommand() *cobra.Command {
558558
Logger: logger.WithName("deployCtxCollector"),
559559
})
560560

561+
files := make([]fileToCopy, 0, len(srcFiles))
562+
for i, src := range srcFiles {
563+
files = append(files, fileToCopy{
564+
destDirName: destDirs[i],
565+
srcFileName: src,
566+
})
567+
}
568+
561569
return initialize(initializeConfig{
562570
fileManager: file.NewStdLibOSFileManager(),
563571
fileGenerator: ngxConfig.NewGeneratorImpl(plus, nil, logger.WithName("generator")),
564572
logger: logger,
565573
plus: plus,
566574
collector: dcc,
567-
copy: copyFiles{
568-
srcFileNames: srcFiles,
569-
destDirName: dest,
570-
},
575+
copy: files,
571576
})
572577
},
573578
}
@@ -579,11 +584,11 @@ func createInitializeCommand() *cobra.Command {
579584
"The source files to be copied",
580585
)
581586

582-
cmd.Flags().StringVar(
583-
&dest,
587+
cmd.Flags().StringSliceVar(
588+
&destDirs,
584589
destFlag,
585-
"",
586-
"The destination directory for the source files to be copied to",
590+
[]string{},
591+
"The destination directories for the source files at the same array index to be copied to",
587592
)
588593

589594
cmd.Flags().BoolVar(

cmd/gateway/initialize.go

+12-7
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package main
33
import (
44
"context"
55
"fmt"
6+
"os"
67
"path/filepath"
78
"time"
89

@@ -17,23 +18,23 @@ const (
1718
collectDeployCtxTimeout = 10 * time.Second
1819
)
1920

20-
type copyFiles struct {
21-
destDirName string
22-
srcFileNames []string
21+
type fileToCopy struct {
22+
destDirName string
23+
srcFileName string
2324
}
2425

2526
type initializeConfig struct {
2627
collector licensing.Collector
2728
fileManager file.OSFileManager
2829
fileGenerator config.Generator
2930
logger logr.Logger
30-
copy copyFiles
31+
copy []fileToCopy
3132
plus bool
3233
}
3334

3435
func initialize(cfg initializeConfig) error {
35-
for _, src := range cfg.copy.srcFileNames {
36-
if err := copyFile(cfg.fileManager, src, cfg.copy.destDirName); err != nil {
36+
for _, f := range cfg.copy {
37+
if err := copyFile(cfg.fileManager, f.srcFileName, f.destDirName); err != nil {
3738
return err
3839
}
3940
}
@@ -58,7 +59,7 @@ func initialize(cfg initializeConfig) error {
5859
return fmt.Errorf("failed to generate deployment context file: %w", err)
5960
}
6061

61-
if err := file.Write(cfg.fileManager, depCtxFile); err != nil {
62+
if err := file.Write(cfg.fileManager, file.Convert(depCtxFile)); err != nil {
6263
return fmt.Errorf("failed to write deployment context file: %w", err)
6364
}
6465

@@ -84,5 +85,9 @@ func copyFile(osFileManager file.OSFileManager, src, dest string) error {
8485
return fmt.Errorf("error copying file contents: %w", err)
8586
}
8687

88+
if err := osFileManager.Chmod(destFile, os.FileMode(file.RegularFileModeInt)); err != nil {
89+
return fmt.Errorf("error setting file permissions: %w", err)
90+
}
91+
8792
return nil
8893
}

0 commit comments

Comments
 (0)