Skip to content
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

implement an admission webhook server #617

Merged
merged 1 commit into from
Apr 22, 2021
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,4 @@ Session.vim
/www/test_out
.*.timestamp
/site
admission
26 changes: 26 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Copyright 2021 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

FROM golang:1.16 AS build-env
RUN mkdir -p /go/src/sig.k8s.io/gateway-api
WORKDIR /go/src/sig.k8s.io/gateway-api
COPY . .
RUN useradd -u 10001 webhook
RUN cd cmd/admission/ && CGO_ENABLED=0 GOOS=linux go build -a -o gateway-api-webhook && chmod +x gateway-api-webhook

FROM scratch
COPY --from=build-env /go/src/sig.k8s.io/gateway-api/cmd/admission/gateway-api-webhook .
COPY --from=build-env /etc/passwd /etc/passwd
USER webhook
ENTRYPOINT ["/gateway-api-webhook"]
103 changes: 103 additions & 0 deletions cmd/admission/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
Copyright 2021 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import (
"context"
"crypto/tls"
"errors"
"flag"
"fmt"
"net/http"
"os"
"os/signal"
"sync"
"syscall"

"k8s.io/klog/v2"

"sigs.k8s.io/gateway-api/pkg/admission"
)

var (
tlsCertFilePath, tlsKeyFilePath string
showVersion, help bool
)

const version = "0.0.1"

func main() {
flag.StringVar(&tlsCertFilePath, "tlsCertFile", "/etc/certs/tls.crt", "File with x509 certificate")
flag.StringVar(&tlsKeyFilePath, "tlsKeyFile", "/etc/certs/tls.key", "File with private key to tlsCertFile")
flag.BoolVar(&showVersion, "version", false, "Show release version and exit")
flag.BoolVar(&help, "help", false, "Show flag defaults and exit")
klog.InitFlags(nil)
flag.Parse()

if showVersion {
printVersion()
os.Exit(0)
}

if help {
printVersion()
flag.PrintDefaults()
os.Exit(0)
}

printVersion()

certs, err := tls.LoadX509KeyPair(tlsCertFilePath, tlsKeyFilePath)
if err != nil {
klog.Fatalf("failed to load TLS cert-key for admission-webhook-server: %v", err)
}

server := &http.Server{
Addr: ":8443",
// Require at least TLS12 to satisfy golint G402.
TLSConfig: &tls.Config{MinVersion: tls.VersionTLS12, Certificates: []tls.Certificate{certs}},
}
mux := http.NewServeMux()
mux.HandleFunc("/validate", admission.ServeHTTP)
server.Handler = mux

var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
err := server.ListenAndServeTLS("", "")
if errors.Is(err, http.ErrServerClosed) {
klog.Fatalf("admission-webhook-server stopped: %v", err)
}
}()
klog.Info("admission webhook server started and listening on :8443")

// gracefully shutdown
signalChan := make(chan os.Signal, 1)
signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM)
<-signalChan

klog.Info("admission webhook received kill signal")
if err := server.Shutdown(context.Background()); err != nil {
klog.Fatalf("server shutdown failed:%+v", err)
}
wg.Wait()
}

func printVersion() {
fmt.Printf("gateway-api-admission-webhook version: %v\n", version)
}
96 changes: 96 additions & 0 deletions deploy/admission_webhook.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
apiVersion: v1
kind: Namespace
metadata:
name: gateway-api
labels:
name: gateway-api
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: gateway-api-admission
webhooks:
- name: validate.networking.x-k8s.io
matchPolicy: Equivalent
rules:
- operations: [ "CREATE" , "UPDATE" ]
apiGroups: [ "networking.x-k8s.io" ]
apiVersions: [ "v1alpha1" ]
resources: [ "httproutes" ]
failurePolicy: Fail
sideEffects: None
admissionReviewVersions:
- v1
clientConfig:
service:
name: gateway-api-admission-server
namespace: gateway-api
path: "/validate"
---
apiVersion: v1
kind: Service
metadata:
labels:
name: gateway-api-webhook-server
version: 0.0.1
name: gateway-api-admission-server
namespace: gateway-api
spec:
type: ClusterIP
ports:
- name: https-webhook
port: 443
targetPort: 8443
selector:
name: gateway-api-admission-server
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: gateway-api-admission-server
namespace: gateway-api
labels:
name: gateway-api-admission-server
spec:
replicas: 1
selector:
matchLabels:
name: gateway-api-admission-server
template:
metadata:
name: gateway-api-admission-server
labels:
name: gateway-api-admission-server
spec:
containers:
- name: webhook
# TODO(hbagdi): Swap image name to the k8s official image once
# https://github.com/kubernetes-sigs/gateway-api/pull/621 merges in
image: TODO
imagePullPolicy: Always
args:
- -logtostderr
- --tlsCertFile=/etc/certs/cert
- --tlsKeyFile=/etc/certs/key
- -v=10
- 2>&1
ports:
- containerPort: 8443
name: webhook
resources:
limits:
memory: 50Mi
cpu: 100m
requests:
memory: 50Mi
cpu: 100m
volumeMounts:
- name: webhook-certs
mountPath: /etc/certs
readOnly: true
securityContext:
readOnlyRootFilesystem: true
volumes:
- name: webhook-certs
secret:
secretName: gateway-api-admission
161 changes: 161 additions & 0 deletions deploy/certificate_config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
apiVersion: v1
kind: Namespace
metadata:
name: gateway-api
labels:
name: gateway-api
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: gateway-api-admission
labels:
name: gateway-api-webhook
version: 0.0.1
namespace: gateway-api
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: gateway-api-admission
labels:
name: gateway-api
version: 0.0.1
rules:
- apiGroups:
- admissionregistration.k8s.io
resources:
- validatingwebhookconfigurations
verbs:
- get
- update
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: gateway-api-admission
annotations:
labels:
name: gateway-api-webhook
version: 0.0.1
namespace: gateway-api
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: gateway-api-admission
subjects:
- kind: ServiceAccount
name: gateway-api-admission
namespace: gateway-api
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: gateway-api-admission
annotations:
labels:
name: gateway-api-webhook
version: 0.0.1
namespace: gateway-api
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- get
- create
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: gateway-api-admission
annotations:
labels:
name: gateway-api-webhook
version: 0.0.1
namespace: gateway-api
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: gateway-api-admission
subjects:
- kind: ServiceAccount
name: gateway-api-admission
namespace: gateway-api
---
apiVersion: batch/v1
kind: Job
metadata:
name: gateway-api-admission
annotations:
labels:
name: gateway-api-webhook
version: 0.0.1
namespace: gateway-api
spec:
template:
metadata:
name: gateway-api-admission-create
labels:
name: gateway-api-webhook
version: 0.0.1
spec:
containers:
- name: create
image: docker.io/jettech/kube-webhook-certgen:v1.5.0
imagePullPolicy: IfNotPresent
args:
- create
- --host=gateway-api-admission-server,gateway-api-admission-server.gateway-api.svc
- --namespace=gateway-api
- --secret-name=gateway-api-admission
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
restartPolicy: OnFailure
serviceAccountName: gateway-api-admission
securityContext:
runAsNonRoot: true
runAsUser: 2000
---
apiVersion: batch/v1
kind: Job
metadata:
name: gateway-api-admission-patch
labels:
name: gateway-api-webhook
version: 0.0.1
namespace: gateway-api
spec:
template:
metadata:
name: gateway-api-admission-patch
labels:
name: gateway-api-webhook
version: 0.0.1
spec:
containers:
- name: patch
image: docker.io/jettech/kube-webhook-certgen:v1.5.0
imagePullPolicy: IfNotPresent
args:
- patch
- --webhook-name=gateway-api-admission
- --namespace=gateway-api
- --patch-mutating=false
- --patch-validating=true
- --secret-name=gateway-api-admission
- --patch-failure-policy=Fail
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
restartPolicy: OnFailure
serviceAccountName: gateway-api-admission
securityContext:
runAsNonRoot: true
runAsUser: 2000
Loading