commit 7dd7d19df5e2af4dc471fa1365e3f75fc436eb27 Author: ston1th Date: Mon Jan 20 20:03:26 2020 +0100 initial commit diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..dd57fd8 --- /dev/null +++ b/LICENSE @@ -0,0 +1,24 @@ +Copyright (C) 2020 Marius Schellenberger +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * The names of the authors and/or contributors may not be used to + endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL ston1th BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..0950ecc --- /dev/null +++ b/README.md @@ -0,0 +1,25 @@ +# nginx-ingress-proxy + +This is an ingress proxy to direct traffic to the ingress controller in small cloud environments without the need for a load balancer. + +This proxy runs in the host network of the kubernetes master on the ports `80` and `443`. + +Traffic is then redirected to the nginx ingress controller using the proxy protocol. + +## Usage + +**Note:** replace `MASTERNODE` with the hostname of your master node. + +``` +curl -s -O https://git.giftfish.de/ston1th/nginx-ingress-proxy/raw/branch/master/nginx-ingress-proxy.yaml + +sed -i 's/MASTERNODE/my-master/' nginx-ingress-proxy.yaml + +kubectl apply -f nginx-ingress-proxy.yaml +``` + +## Cleanup + +``` +kubectl delete -f nginx-ingress-proxy.yaml +``` diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..8e78c01 --- /dev/null +++ b/build.sh @@ -0,0 +1,7 @@ +#!/bin/sh +file=nginx-ingress-proxy.yaml +rm -f $file 2>/dev/null +for f in $(ls config/*.yaml); do + echo "# $f" >> $file + cat $f >> $file +done diff --git a/config/100-serviceaccount.yaml b/config/100-serviceaccount.yaml new file mode 100644 index 0000000..77b0df5 --- /dev/null +++ b/config/100-serviceaccount.yaml @@ -0,0 +1,6 @@ +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: nginx-ingress-proxy + namespace: ingress-nginx diff --git a/config/200-role.yaml b/config/200-role.yaml new file mode 100644 index 0000000..e6eabd3 --- /dev/null +++ b/config/200-role.yaml @@ -0,0 +1,15 @@ +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: nginx-ingress-proxy + namespace: ingress-nginx +rules: +- apiGroups: [""] + resources: ["configmaps"] + resourceNames: ["nginx-ingress-proxy-config"] + verbs: ["get"] +- apiGroups: ["policy"] + resources: ["podsecuritypolicies"] + resourceNames: ["nginx-ingress-proxy"] + verbs: ["use"] diff --git a/config/200-rolebinding.yaml b/config/200-rolebinding.yaml new file mode 100644 index 0000000..01852b8 --- /dev/null +++ b/config/200-rolebinding.yaml @@ -0,0 +1,13 @@ +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: nginx-ingress-proxy + namespace: ingress-nginx +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: nginx-ingress-proxy +subjects: +- kind: ServiceAccount + name: nginx-ingress-proxy diff --git a/config/300-psp.yaml b/config/300-psp.yaml new file mode 100644 index 0000000..37eddb4 --- /dev/null +++ b/config/300-psp.yaml @@ -0,0 +1,36 @@ +--- +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: nginx-ingress-proxy + annotations: + seccomp.security.alpha.kubernetes.io/allowedProfileNames: 'docker/default,runtime/default' + apparmor.security.beta.kubernetes.io/allowedProfileNames: 'runtime/default' + seccomp.security.alpha.kubernetes.io/defaultProfileName: 'runtime/default' + apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default' +spec: + allowedCapabilities: + - SETUID + - SETGID + - NET_BIND_SERVICE + requiredDropCapabilities: ["ALL"] + privileged: false + allowPrivilegeEscalation: false + readOnlyRootFilesystem: false + volumes: + - 'secret' + - 'configMap' + hostNetwork: true + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + hostPorts: + - min: 80 + max: 443 diff --git a/config/deployment.yaml b/config/deployment.yaml new file mode 100644 index 0000000..d69ca03 --- /dev/null +++ b/config/deployment.yaml @@ -0,0 +1,51 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx-ingress-proxy + namespace: ingress-nginx + labels: + app: nginx-ingress-proxy +spec: + replicas: 1 + selector: + matchLabels: + app: nginx-ingress-proxy + template: + metadata: + labels: + app: nginx-ingress-proxy + spec: + serviceAccountName: nginx-ingress-proxy + nodeSelector: + kubernetes.io/hostname: MASTERNODE + tolerations: + - operator: Exists + effect: NoSchedule + containers: + - name: nginx + image: nginx@sha256:2911ad2d54f4cf4dc7ad21af122c1eefce16836a34be751c63351ca1fb452d57 # nginx:mainline-alpine + volumeMounts: + - name: nginx-ingress-proxy-config + mountPath: /etc/nginx + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: ["ALL"] + add: + - SETUID + - SETGID + - NET_BIND_SERVICE + ports: + - name: http + containerPort: 80 + hostPort: 80 + protocol: TCP + - name: https + containerPort: 443 + hostPort: 443 + protocol: TCP + volumes: + - name: nginx-ingress-proxy-config + configMap: + name: nginx-ingress-proxy-config diff --git a/config/nginx-configmap.yaml b/config/nginx-configmap.yaml new file mode 100644 index 0000000..9d78799 --- /dev/null +++ b/config/nginx-configmap.yaml @@ -0,0 +1,31 @@ +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: nginx-ingress-proxy-config + namespace: ingress-nginx +data: + nginx.conf: | + user nginx; + worker_processes auto; + events { + worker_connections 1024; + } + stream { + upstream stream_backend_80 { + server ingress-nginx.ingress-nginx.svc:80; + } + upstream stream_backend_443 { + server ingress-nginx.ingress-nginx.svc:443; + } + server { + listen 80; + proxy_pass stream_backend_80; + proxy_protocol on; + } + server { + listen 443; + proxy_pass stream_backend_443; + proxy_protocol on; + } + } diff --git a/config/nginx-configuration.yaml b/config/nginx-configuration.yaml new file mode 100644 index 0000000..019c026 --- /dev/null +++ b/config/nginx-configuration.yaml @@ -0,0 +1,12 @@ +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: nginx-configuration + namespace: ingress-nginx + labels: + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx +data: + server-tokens: "false" + use-proxy-protocol: "true" diff --git a/nginx-ingress-proxy.yaml b/nginx-ingress-proxy.yaml new file mode 100644 index 0000000..9a516af --- /dev/null +++ b/nginx-ingress-proxy.yaml @@ -0,0 +1,171 @@ +# config/100-serviceaccount.yaml +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: nginx-ingress-proxy + namespace: ingress-nginx +# config/200-rolebinding.yaml +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: nginx-ingress-proxy + namespace: ingress-nginx +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: nginx-ingress-proxy +subjects: +- kind: ServiceAccount + name: nginx-ingress-proxy +# config/200-role.yaml +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: nginx-ingress-proxy + namespace: ingress-nginx +rules: +- apiGroups: [""] + resources: ["configmaps"] + resourceNames: ["nginx-ingress-proxy-config"] + verbs: ["get"] +- apiGroups: ["policy"] + resources: ["podsecuritypolicies"] + resourceNames: ["nginx-ingress-proxy"] + verbs: ["use"] +# config/300-psp.yaml +--- +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: nginx-ingress-proxy + annotations: + seccomp.security.alpha.kubernetes.io/allowedProfileNames: 'docker/default,runtime/default' + apparmor.security.beta.kubernetes.io/allowedProfileNames: 'runtime/default' + seccomp.security.alpha.kubernetes.io/defaultProfileName: 'runtime/default' + apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default' +spec: + allowedCapabilities: + - SETUID + - SETGID + - NET_BIND_SERVICE + requiredDropCapabilities: ["ALL"] + privileged: false + allowPrivilegeEscalation: false + readOnlyRootFilesystem: false + volumes: + - 'secret' + - 'configMap' + hostNetwork: true + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + hostPorts: + - min: 80 + max: 443 +# config/deployment.yaml +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx-ingress-proxy + namespace: ingress-nginx + labels: + app: nginx-ingress-proxy +spec: + replicas: 1 + selector: + matchLabels: + app: nginx-ingress-proxy + template: + metadata: + labels: + app: nginx-ingress-proxy + spec: + serviceAccountName: nginx-ingress-proxy + nodeSelector: + kubernetes.io/hostname: MASTERNODE + tolerations: + - operator: Exists + effect: NoSchedule + containers: + - name: nginx + image: nginx@sha256:2911ad2d54f4cf4dc7ad21af122c1eefce16836a34be751c63351ca1fb452d57 # nginx:mainline-alpine + volumeMounts: + - name: nginx-ingress-proxy-config + mountPath: /etc/nginx + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: ["ALL"] + add: + - SETUID + - SETGID + - NET_BIND_SERVICE + ports: + - name: http + containerPort: 80 + hostPort: 80 + protocol: TCP + - name: https + containerPort: 443 + hostPort: 443 + protocol: TCP + volumes: + - name: nginx-ingress-proxy-config + configMap: + name: nginx-ingress-proxy-config +# config/nginx-configmap.yaml +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: nginx-ingress-proxy-config + namespace: ingress-nginx +data: + nginx.conf: | + user nginx; + worker_processes auto; + events { + worker_connections 1024; + } + stream { + upstream stream_backend_80 { + server ingress-nginx.ingress-nginx.svc:80; + } + upstream stream_backend_443 { + server ingress-nginx.ingress-nginx.svc:443; + } + server { + listen 80; + proxy_pass stream_backend_80; + proxy_protocol on; + } + server { + listen 443; + proxy_pass stream_backend_443; + proxy_protocol on; + } + } +# config/nginx-configuration.yaml +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: nginx-configuration + namespace: ingress-nginx + labels: + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx +data: + server-tokens: "false" + use-proxy-protocol: "true"