Skip to content

Commit 1779604

Browse files
committed
Add initial version
- Gateway is a pod with two containers - control plane and data plane - Data plane is NGINX configured with a simple config - Control plane is an app that fetches and validates the GatewayClass resource and then does nothing
1 parent 8d24d8e commit 1779604

File tree

9 files changed

+1253
-0
lines changed

9 files changed

+1253
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,6 @@
1313

1414
# Dependency directories (remove the comment below to include it)
1515
# vendor/
16+
17+
# GoLand IDE
18+
.idea

Makefile

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
VERSION = 0.0.1
2+
TAG = $(VERSION)
3+
PREFIX = nginx-gateway
4+
5+
GIT_COMMIT = $(shell git rev-parse HEAD)
6+
DATE = $(shell date -u +"%Y-%m-%dT%H:%M:%SZ")
7+
8+
KIND_KUBE_CONFIG_FOLDER = $${HOME}/.kube/kind
9+
10+
.PHONY: container
11+
container:
12+
docker build --build-arg VERSION=$(VERSION) --build-arg GIT_COMMIT=$(GIT_COMMIT) --build-arg DATE=$(DATE) --target container -f build/Dockerfile -t $(PREFIX):$(TAG) .
13+
14+
.PHONY: deps
15+
deps:
16+
@go mod tidy && go mod verify && go mod download
17+
18+
.PHONY: create-kind-cluster
19+
create-kind-cluster:
20+
kind create cluster --image kindest/node:v1.22.1
21+
kind export kubeconfig --kubeconfig $(KIND_KUBE_CONFIG_FOLDER)/config
22+
23+
.PHONY: delete-kind-cluster
24+
delete-kind-cluster:
25+
kind delete cluster

README.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,59 @@
11
# nginx-gateway-kubernetes
2+
23
NGINX Gateway is an open source project managed by NGINX, Inc. It implements a collection of resources that model service networking in Kubernetes.
4+
5+
## Run NGINX Gateway
6+
7+
### Prepare Kubernetes Cluster
8+
9+
If you'd like to use that Makefile to create a cluster, run:
10+
```
11+
make create-kind-cluster
12+
```
13+
14+
### Build NGINX Gateway
15+
16+
1. Build the image:
17+
```
18+
make container
19+
```
20+
1. Push the image to your registry. If you're using Kind, run:
21+
```
22+
kind load docker-image nginx-gateway:0.0.1
23+
```
24+
25+
## Deploy NGINX Gateway
26+
27+
1. Install Gateway APIs CRDs:
28+
```
29+
kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd?ref=v0.4.0" \
30+
| kubectl apply -f -
31+
```
32+
1. Create the GatewayClass resource:
33+
```
34+
kubectl apply -f deploy/manifests/gatewayclass.yaml
35+
```
36+
1. Deploy the NGINX Gateway:
37+
38+
If you're not using Kind, before deploying, make sure to edit the Deployment spec in `nginx-gateway.yaml` so that the image for `nginx-gateway` container points to your registry.
39+
```
40+
kubectl apply -f deploy/manifests/nginx-gateway.yaml
41+
```
42+
1. Confirm the NGINX Gateway is running in `nginx-gateway` namespace:
43+
```
44+
kubectl get pods -n nginx-gateway
45+
NAME READY STATUS RESTARTS AGE
46+
nginx-gateway-5d4f4c7db7-xk2kq 2/2 Running 0 112s
47+
```
48+
49+
## Use NGINX Gateway
50+
51+
1. Forward local port 8080 to port 80 of the NGINX Gateway pod:
52+
```
53+
kubectl -n nginx-gateway port-forward <pod-name> 8080:80
54+
```
55+
1. Curl port 8080:
56+
```
57+
curl localhost:8080
58+
hello from nginx-gateway-5d4f4c7db7-xk2kq
59+
```

build/Dockerfile

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
FROM golang:1.17 as builder
2+
ARG VERSION
3+
ARG GIT_COMMIT
4+
ARG DATE
5+
6+
WORKDIR /go/src/github.com/nginxinc/nginx-gateway-kubernetes/cmd/gateway
7+
8+
COPY go.mod go.sum /go/src/github.com/nginxinc/nginx-gateway-kubernetes
9+
RUN go mod download
10+
11+
COPY cmd /go/src/github.com/nginxinc/nginx-gateway-kubernetes/cmd
12+
RUN CGO_ENABLED=0 GOOS=linux go build -trimpath -a -ldflags "-s -w -X main.version=${VERSION} -X main.commit=${GIT_COMMIT} -X main.date=${DATE}" -o gateway .
13+
14+
FROM scratch as container
15+
COPY --from=builder /go/src/github.com/nginxinc/nginx-gateway-kubernetes/cmd/gateway/gateway /usr/bin/
16+
USER 1001:1001
17+
ENTRYPOINT [ "/usr/bin/gateway" ]

cmd/gateway/main.go

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"flag"
6+
"fmt"
7+
"os"
8+
"os/signal"
9+
"syscall"
10+
"time"
11+
12+
"go.uber.org/zap"
13+
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
14+
"k8s.io/client-go/rest"
15+
"sigs.k8s.io/gateway-api/pkg/client/clientset/gateway/versioned"
16+
)
17+
18+
var (
19+
// Set during go build
20+
version string
21+
commit string
22+
date string
23+
24+
// Command-line flags
25+
gatewayClass = flag.String("gatewayclass", "", "Tha name of the GatewayClass resource")
26+
)
27+
28+
func main() {
29+
flag.Parse()
30+
31+
if *gatewayClass == "" {
32+
fmt.Fprintln(os.Stderr, "-gatewayclass argument must be set")
33+
os.Exit(1)
34+
}
35+
36+
logger, err := zap.NewProduction()
37+
if err != nil {
38+
fmt.Fprintf(os.Stderr, "Failed to initialize logging: %v\n", err)
39+
os.Exit(1)
40+
}
41+
sugar := logger.Sugar()
42+
43+
sugar.Infow("Starting NGINX Gateway",
44+
"version", version,
45+
"commit", commit,
46+
"date", date)
47+
48+
config, err := rest.InClusterConfig()
49+
if err != nil {
50+
sugar.Fatalw("Failed to create InClusterConfig",
51+
"error", err)
52+
}
53+
54+
gatewayClient, err := versioned.NewForConfig(config)
55+
if err != nil {
56+
sugar.Fatalw("Failed to create a client for Gateway APIs",
57+
"error", err)
58+
}
59+
60+
gc, err := gatewayClient.GatewayV1alpha2().GatewayClasses().Get(context.TODO(), *gatewayClass, meta_v1.GetOptions{})
61+
if err != nil {
62+
sugar.Fatalw("Failed to get the GatewayClass",
63+
"name", *gatewayClass,
64+
"error", err)
65+
}
66+
67+
if gc.Spec.ControllerName != "k8s-gateway.nginx.org/gateway" {
68+
sugar.Fatalw("Wrong ControllerName in the GatewayClass resource",
69+
"expected", "k8s-gateway.nginx.org/gateway",
70+
"got", "gc.Spec.ControllerName")
71+
}
72+
73+
sugar.Infow("Gateway class info",
74+
"name", gc.Name,
75+
"creation timestamp", gc.CreationTimestamp)
76+
77+
signalChan := make(chan os.Signal, 1)
78+
signal.Notify(signalChan, os.Interrupt, syscall.SIGTERM)
79+
go func() {
80+
sugar.Infow("Terminating because of the signal",
81+
"signal", <-signalChan)
82+
83+
os.Exit(0)
84+
}()
85+
86+
for {
87+
sugar.Infow("Gateway is running")
88+
time.Sleep(30 * time.Second)
89+
}
90+
}

deploy/manifests/gatewayclass.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
apiVersion: gateway.networking.k8s.io/v1alpha2
2+
kind: GatewayClass
3+
metadata:
4+
name: nginx
5+
spec:
6+
controllerName: k8s-gateway.nginx.org/gateway

deploy/manifests/nginx-gateway.yaml

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
apiVersion: v1
2+
kind: Namespace
3+
metadata:
4+
name: nginx-gateway
5+
---
6+
apiVersion: v1
7+
kind: ServiceAccount
8+
metadata:
9+
name: nginx-gateway
10+
namespace: nginx-gateway
11+
---
12+
kind: ClusterRole
13+
apiVersion: rbac.authorization.k8s.io/v1
14+
metadata:
15+
name: nginx-gateway
16+
rules:
17+
- apiGroups:
18+
- gateway.networking.k8s.io
19+
resources:
20+
- gatewayclasses
21+
verbs:
22+
- get
23+
---
24+
kind: ClusterRoleBinding
25+
apiVersion: rbac.authorization.k8s.io/v1
26+
metadata:
27+
name: nginx-gateway
28+
subjects:
29+
- kind: ServiceAccount
30+
name: nginx-gateway
31+
namespace: nginx-gateway
32+
roleRef:
33+
kind: ClusterRole
34+
name: nginx-gateway
35+
apiGroup: rbac.authorization.k8s.io
36+
---
37+
apiVersion: apps/v1
38+
kind: Deployment
39+
metadata:
40+
name: nginx-gateway
41+
namespace: nginx-gateway
42+
spec:
43+
replicas: 1
44+
selector:
45+
matchLabels:
46+
app: nginx-gateway
47+
template:
48+
metadata:
49+
labels:
50+
app: nginx-gateway
51+
spec:
52+
serviceAccountName: nginx-gateway
53+
volumes:
54+
- name: nginx-config
55+
emptyDir: { }
56+
initContainers:
57+
- image: busybox:1.34
58+
name: nginx-config-initializer
59+
command: [ 'sh', '-c', 'echo "events {} http { server { default_type text/plain; return 200 \"hello from \$hostname\n\"; } }" > /etc/nginx/nginx.conf' ]
60+
volumeMounts:
61+
- name: nginx-config
62+
mountPath: /etc/nginx
63+
containers:
64+
- image: nginx-gateway:0.0.1
65+
imagePullPolicy: IfNotPresent
66+
name: nginx-gateway
67+
args:
68+
- -gatewayclass=nginx
69+
- image: nginx:1.21.3
70+
imagePullPolicy: IfNotPresent
71+
name: nginx
72+
ports:
73+
- name: http
74+
containerPort: 80
75+
volumeMounts:
76+
- name: nginx-config
77+
mountPath: /etc/nginx

go.mod

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
module github.com/nginxinc/nginx-gateway-kubernetes
2+
3+
go 1.17
4+
5+
require (
6+
go.uber.org/zap v1.19.1
7+
k8s.io/apimachinery v0.22.1
8+
k8s.io/client-go v0.22.1
9+
sigs.k8s.io/gateway-api v0.4.0
10+
)
11+
12+
require (
13+
github.com/davecgh/go-spew v1.1.1 // indirect
14+
github.com/go-logr/logr v0.4.0 // indirect
15+
github.com/gogo/protobuf v1.3.2 // indirect
16+
github.com/golang/protobuf v1.5.2 // indirect
17+
github.com/google/go-cmp v0.5.6 // indirect
18+
github.com/google/gofuzz v1.1.0 // indirect
19+
github.com/googleapis/gnostic v0.5.5 // indirect
20+
github.com/json-iterator/go v1.1.11 // indirect
21+
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
22+
github.com/modern-go/reflect2 v1.0.1 // indirect
23+
go.uber.org/atomic v1.9.0 // indirect
24+
go.uber.org/multierr v1.7.0 // indirect
25+
golang.org/x/net v0.0.0-20210520170846-37e1c6afe023 // indirect
26+
golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602 // indirect
27+
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect
28+
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d // indirect
29+
golang.org/x/text v0.3.6 // indirect
30+
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
31+
google.golang.org/appengine v1.6.7 // indirect
32+
google.golang.org/protobuf v1.26.0 // indirect
33+
gopkg.in/inf.v0 v0.9.1 // indirect
34+
gopkg.in/yaml.v2 v2.4.0 // indirect
35+
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
36+
k8s.io/api v0.22.1 // indirect
37+
k8s.io/klog/v2 v2.10.0 // indirect
38+
k8s.io/utils v0.0.0-20210820185131-d34e5cb4466e // indirect
39+
sigs.k8s.io/structured-merge-diff/v4 v4.1.2 // indirect
40+
sigs.k8s.io/yaml v1.2.0 // indirect
41+
)

0 commit comments

Comments
 (0)