Skip to content

Commit 9cc25a3

Browse files
authored
Fix CRD manifest installation (#989)
Problem: Deploying a CRD definition and an instantiation of that CRD in the same kubectl command will fail due to the kubectl cache not being updated for the existence of the CRD definition. They need to be run in separate commands. Solution: Separate the CRDs into a different file and install prior to installing the rest of the gateway resources.
1 parent 14cb7b1 commit 9cc25a3

File tree

7 files changed

+150
-139
lines changed

7 files changed

+150
-139
lines changed

.yamllint.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ rules:
3030
check-multi-line-strings: true
3131
ignore: |
3232
deploy/manifests/nginx-gateway.yaml
33+
deploy/manifests/crds
3334
key-duplicates: enable
3435
key-ordering: disable
3536
line-length:
@@ -39,6 +40,7 @@ rules:
3940
ignore: |
4041
.github/workflows/
4142
deploy/manifests/nginx-gateway.yaml
43+
deploy/manifests/crds
4244
new-line-at-end-of-file: enable
4345
new-lines: enable
4446
octal-values: disable

Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ KIND_KUBE_CONFIG=$${HOME}/.kube/kind/config## The location of the kind kubeconfi
2121
OUT_DIR ?= $(shell pwd)/build/out## The folder where the binary will be stored
2222
ARCH ?= amd64## The architecture of the image and/or binary. For example: amd64 or arm64
2323
override HELM_TEMPLATE_COMMON_ARGS += --set creator=template --set nameOverride=nginx-gateway## The common options for the Helm template command.
24-
override HELM_TEMPLATE_EXTRA_ARGS_FOR_ALL_MANIFESTS_FILE += --include-crds --set service.create=false## The options to be passed to the full Helm templating command only.
24+
override HELM_TEMPLATE_EXTRA_ARGS_FOR_ALL_MANIFESTS_FILE += --set service.create=false## The options to be passed to the full Helm templating command only.
2525
override NGINX_DOCKER_BUILD_OPTIONS += --build-arg NJS_DIR=$(NJS_DIR) --build-arg NGINX_CONF_DIR=$(NGINX_CONF_DIR)
2626
.DEFAULT_GOAL := help
2727

@@ -133,6 +133,7 @@ build-nkg-debug-image: debug-build build-nkg-image ## Build NKG image with debug
133133

134134
.PHONY: generate-manifests
135135
generate-manifests: ## Generate manifests using Helm.
136+
cp $(CHART_DIR)/crds/* $(MANIFEST_DIR)/crds/
136137
helm template nginx-gateway $(CHART_DIR) $(HELM_TEMPLATE_COMMON_ARGS) $(HELM_TEMPLATE_EXTRA_ARGS_FOR_ALL_MANIFESTS_FILE) -n nginx-gateway | cat $(strip $(MANIFEST_DIR))/namespace.yaml - > $(strip $(MANIFEST_DIR))/nginx-gateway.yaml
137138
helm template nginx-gateway $(CHART_DIR) $(HELM_TEMPLATE_COMMON_ARGS) -n nginx-gateway -s templates/deployment.yaml > conformance/provisioner/static-deployment.yaml
138139
helm template nginx-gateway $(CHART_DIR) $(HELM_TEMPLATE_COMMON_ARGS) -n nginx-gateway -s templates/service.yaml > $(strip $(MANIFEST_DIR))/service/loadbalancer.yaml

conformance/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ KIND_KUBE_CONFIG=$${HOME}/.kube/kind/config
88
TAG = latest
99
PREFIX = conformance-test-runner
1010
NKG_MANIFEST=../deploy/manifests/nginx-gateway.yaml
11-
CRDS=../deploy/helm-chart/crds/
11+
CRDS=../deploy/manifests/crds/
1212
SERVICE_MANIFEST=../deploy/manifests/service/nodeport.yaml
1313
STATIC_MANIFEST=provisioner/static-deployment.yaml
1414
PROVISIONER_MANIFEST=provisioner/provisioner.yaml
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
---
2+
apiVersion: apiextensions.k8s.io/v1
3+
kind: CustomResourceDefinition
4+
metadata:
5+
annotations:
6+
controller-gen.kubebuilder.io/version: v0.13.0
7+
name: nginxgateways.gateway.nginx.org
8+
spec:
9+
group: gateway.nginx.org
10+
names:
11+
kind: NginxGateway
12+
listKind: NginxGatewayList
13+
plural: nginxgateways
14+
singular: nginxgateway
15+
scope: Namespaced
16+
versions:
17+
- name: v1alpha1
18+
schema:
19+
openAPIV3Schema:
20+
description: NginxGateway represents the dynamic configuration for an NGINX
21+
Kubernetes Gateway control plane.
22+
properties:
23+
apiVersion:
24+
description: 'APIVersion defines the versioned schema of this representation
25+
of an object. Servers should convert recognized schemas to the latest
26+
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
27+
type: string
28+
kind:
29+
description: 'Kind is a string value representing the REST resource this
30+
object represents. Servers may infer this from the endpoint the client
31+
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
32+
type: string
33+
metadata:
34+
type: object
35+
spec:
36+
description: NginxGatewaySpec defines the desired state of the NginxGateway.
37+
properties:
38+
logging:
39+
description: Logging defines logging related settings for the control
40+
plane.
41+
properties:
42+
level:
43+
default: info
44+
description: Level defines the logging level.
45+
enum:
46+
- info
47+
- debug
48+
- error
49+
type: string
50+
type: object
51+
type: object
52+
status:
53+
description: NginxGatewayStatus defines the state of the NginxGateway.
54+
properties:
55+
conditions:
56+
items:
57+
description: "Condition contains details for one aspect of the current
58+
state of this API Resource. --- This struct is intended for direct
59+
use as an array at the field path .status.conditions. For example,
60+
\n type FooStatus struct{ // Represents the observations of a
61+
foo's current state. // Known .status.conditions.type are: \"Available\",
62+
\"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
63+
// +listType=map // +listMapKey=type Conditions []metav1.Condition
64+
`json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
65+
protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
66+
properties:
67+
lastTransitionTime:
68+
description: lastTransitionTime is the last time the condition
69+
transitioned from one status to another. This should be when
70+
the underlying condition changed. If that is not known, then
71+
using the time when the API field changed is acceptable.
72+
format: date-time
73+
type: string
74+
message:
75+
description: message is a human readable message indicating
76+
details about the transition. This may be an empty string.
77+
maxLength: 32768
78+
type: string
79+
observedGeneration:
80+
description: observedGeneration represents the .metadata.generation
81+
that the condition was set based upon. For instance, if .metadata.generation
82+
is currently 12, but the .status.conditions[x].observedGeneration
83+
is 9, the condition is out of date with respect to the current
84+
state of the instance.
85+
format: int64
86+
minimum: 0
87+
type: integer
88+
reason:
89+
description: reason contains a programmatic identifier indicating
90+
the reason for the condition's last transition. Producers
91+
of specific condition types may define expected values and
92+
meanings for this field, and whether the values are considered
93+
a guaranteed API. The value should be a CamelCase string.
94+
This field may not be empty.
95+
maxLength: 1024
96+
minLength: 1
97+
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
98+
type: string
99+
status:
100+
description: status of the condition, one of True, False, Unknown.
101+
enum:
102+
- "True"
103+
- "False"
104+
- Unknown
105+
type: string
106+
type:
107+
description: type of condition in CamelCase or in foo.example.com/CamelCase.
108+
--- Many .condition.type values are consistent across resources
109+
like Available, but because arbitrary conditions can be useful
110+
(see .node.status.conditions), the ability to deconflict is
111+
important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
112+
maxLength: 316
113+
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
114+
type: string
115+
required:
116+
- lastTransitionTime
117+
- message
118+
- reason
119+
- status
120+
- type
121+
type: object
122+
maxItems: 8
123+
type: array
124+
x-kubernetes-list-map-keys:
125+
- type
126+
x-kubernetes-list-type: map
127+
type: object
128+
required:
129+
- spec
130+
type: object
131+
served: true
132+
storage: true
133+
subresources:
134+
status: {}

deploy/manifests/nginx-gateway.yaml

Lines changed: 0 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -3,143 +3,6 @@ kind: Namespace
33
metadata:
44
name: nginx-gateway
55
---
6-
# Source: crds/gateway.nginx.org_nginxgateways.yaml
7-
---
8-
apiVersion: apiextensions.k8s.io/v1
9-
kind: CustomResourceDefinition
10-
metadata:
11-
annotations:
12-
controller-gen.kubebuilder.io/version: v0.13.0
13-
name: nginxgateways.gateway.nginx.org
14-
spec:
15-
group: gateway.nginx.org
16-
names:
17-
kind: NginxGateway
18-
listKind: NginxGatewayList
19-
plural: nginxgateways
20-
singular: nginxgateway
21-
scope: Namespaced
22-
versions:
23-
- name: v1alpha1
24-
schema:
25-
openAPIV3Schema:
26-
description: NginxGateway represents the dynamic configuration for an NGINX
27-
Kubernetes Gateway control plane.
28-
properties:
29-
apiVersion:
30-
description: 'APIVersion defines the versioned schema of this representation
31-
of an object. Servers should convert recognized schemas to the latest
32-
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
33-
type: string
34-
kind:
35-
description: 'Kind is a string value representing the REST resource this
36-
object represents. Servers may infer this from the endpoint the client
37-
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
38-
type: string
39-
metadata:
40-
type: object
41-
spec:
42-
description: NginxGatewaySpec defines the desired state of the NginxGateway.
43-
properties:
44-
logging:
45-
description: Logging defines logging related settings for the control
46-
plane.
47-
properties:
48-
level:
49-
default: info
50-
description: Level defines the logging level.
51-
enum:
52-
- info
53-
- debug
54-
- error
55-
type: string
56-
type: object
57-
type: object
58-
status:
59-
description: NginxGatewayStatus defines the state of the NginxGateway.
60-
properties:
61-
conditions:
62-
items:
63-
description: "Condition contains details for one aspect of the current
64-
state of this API Resource. --- This struct is intended for direct
65-
use as an array at the field path .status.conditions. For example,
66-
\n type FooStatus struct{ // Represents the observations of a
67-
foo's current state. // Known .status.conditions.type are: \"Available\",
68-
\"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
69-
// +listType=map // +listMapKey=type Conditions []metav1.Condition
70-
`json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
71-
protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
72-
properties:
73-
lastTransitionTime:
74-
description: lastTransitionTime is the last time the condition
75-
transitioned from one status to another. This should be when
76-
the underlying condition changed. If that is not known, then
77-
using the time when the API field changed is acceptable.
78-
format: date-time
79-
type: string
80-
message:
81-
description: message is a human readable message indicating
82-
details about the transition. This may be an empty string.
83-
maxLength: 32768
84-
type: string
85-
observedGeneration:
86-
description: observedGeneration represents the .metadata.generation
87-
that the condition was set based upon. For instance, if .metadata.generation
88-
is currently 12, but the .status.conditions[x].observedGeneration
89-
is 9, the condition is out of date with respect to the current
90-
state of the instance.
91-
format: int64
92-
minimum: 0
93-
type: integer
94-
reason:
95-
description: reason contains a programmatic identifier indicating
96-
the reason for the condition's last transition. Producers
97-
of specific condition types may define expected values and
98-
meanings for this field, and whether the values are considered
99-
a guaranteed API. The value should be a CamelCase string.
100-
This field may not be empty.
101-
maxLength: 1024
102-
minLength: 1
103-
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
104-
type: string
105-
status:
106-
description: status of the condition, one of True, False, Unknown.
107-
enum:
108-
- "True"
109-
- "False"
110-
- Unknown
111-
type: string
112-
type:
113-
description: type of condition in CamelCase or in foo.example.com/CamelCase.
114-
--- Many .condition.type values are consistent across resources
115-
like Available, but because arbitrary conditions can be useful
116-
(see .node.status.conditions), the ability to deconflict is
117-
important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
118-
maxLength: 316
119-
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
120-
type: string
121-
required:
122-
- lastTransitionTime
123-
- message
124-
- reason
125-
- status
126-
- type
127-
type: object
128-
maxItems: 8
129-
type: array
130-
x-kubernetes-list-map-keys:
131-
- type
132-
x-kubernetes-list-type: map
133-
type: object
134-
required:
135-
- spec
136-
type: object
137-
served: true
138-
storage: true
139-
subresources:
140-
status: {}
141-
142-
---
1436
# Source: nginx-kubernetes-gateway/templates/rbac.yaml
1447
apiVersion: v1
1458
kind: ServiceAccount

docs/developer/quickstart.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ This will build the docker images `nginx-kubernetes-gateway:<your-user>` and `ng
104104
105105
```shell
106106
make generate-manifests HELM_TEMPLATE_COMMON_ARGS="--set nginxGateway.image.repository=nginx-kubernetes-gateway --set nginxGateway.image.tag=$(whoami) --set nginxGateway.image.pullPolicy=Never --set nginx.image.repository=nginx-kubernetes-gateway/nginx --set nginx.image.tag=$(whoami) --set nginx.image.pullPolicy=Never"
107+
kubectl apply -f deploy/manifests/crds
107108
kubectl apply -f deploy/manifests/nginx-gateway.yaml
108109
kubectl apply -f deploy/manifests/service/nodeport.yaml
109110
```

docs/installation.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ page.
3030
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v0.7.1/standard-install.yaml
3131
```
3232

33+
1. Deploy the NGINX Kubernetes Gateway CRDs:
34+
35+
```shell
36+
kubectl apply -f deploy/manifests/crds
37+
```
38+
3339
1. Deploy the NGINX Kubernetes Gateway:
3440

3541
```shell
@@ -122,6 +128,10 @@ To get started, follow the tutorials in the [examples](../examples) directory.
122128
kubectl delete -f deploy/manifests/nginx-gateway.yaml
123129
```
124130

131+
```shell
132+
kubectl delete -f deploy/manifests/crds
133+
```
134+
125135
1. Uninstall the Gateway API resources from the standard channel (the CRDs and the validating webhook):
126136

127137
>**Warning: This command will delete all the corresponding custom resources in your cluster across all namespaces!

0 commit comments

Comments
 (0)