From 20dd36cff4ee3e68796faf93326443114a7fbb2a Mon Sep 17 00:00:00 2001 From: Thomas Date: Sun, 30 Jan 2022 10:11:49 +0100 Subject: [PATCH] add traefik base --- .gitignore | 3 + traefik/README.md | 3 + traefik/crd.yml | 93 ++++++++++++++++++++++ traefik/deploy_traefik.rb | 34 ++++++++ traefik/deployment_base.yml | 153 ++++++++++++++++++++++++++++++++++++ traefik/mini-test.yml | 67 ++++++++++++++++ traefik/rbac.yml | 66 ++++++++++++++++ 7 files changed, 419 insertions(+) create mode 100644 traefik/README.md create mode 100644 traefik/crd.yml create mode 100644 traefik/deploy_traefik.rb create mode 100644 traefik/deployment_base.yml create mode 100644 traefik/mini-test.yml create mode 100644 traefik/rbac.yml diff --git a/.gitignore b/.gitignore index 9a9f906..2685885 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ infra/.terraform* infra/terraform-gcp-service-account.json infra/terraform.tfstate* +traefik/*service-account.json +traefik/deployment.yml +traefik/*.htpass \ No newline at end of file diff --git a/traefik/README.md b/traefik/README.md new file mode 100644 index 0000000..57785e9 --- /dev/null +++ b/traefik/README.md @@ -0,0 +1,3 @@ +# README + +This folder contains the traefik configuration to set it up in the GKE cluster in GCP. diff --git a/traefik/crd.yml b/traefik/crd.yml new file mode 100644 index 0000000..78416b5 --- /dev/null +++ b/traefik/crd.yml @@ -0,0 +1,93 @@ +--- +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: ingressroutes.traefik.containo.us +spec: + group: traefik.containo.us + version: v1alpha1 + names: + kind: IngressRoute + plural: ingressroutes + singular: ingressroute + scope: Namespaced +--- +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: middlewares.traefik.containo.us + +spec: + group: traefik.containo.us + version: v1alpha1 + names: + kind: Middleware + plural: middlewares + singular: middleware + scope: Namespaced +--- +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: ingressroutetcps.traefik.containo.us +spec: + group: traefik.containo.us + version: v1alpha1 + names: + kind: IngressRouteTCP + plural: ingressroutetcps + singular: ingressroutetcp + scope: Namespaced +--- +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: ingressrouteudps.traefik.containo.us +spec: + group: traefik.containo.us + version: v1alpha1 + names: + kind: IngressRouteUDP + plural: ingressrouteudps + singular: ingressrouteudp + scope: Namespaced +--- +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: tlsoptions.traefik.containo.us +spec: + group: traefik.containo.us + version: v1alpha1 + names: + kind: TLSOption + plural: tlsoptions + singular: tlsoption + scope: Namespaced +--- +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: tlsstores.traefik.containo.us +spec: + group: traefik.containo.us + version: v1alpha1 + names: + kind: TLSStore + plural: tlsstores + singular: tlsstore + scope: Namespaced +--- +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: traefikservices.traefik.containo.us +spec: + group: traefik.containo.us + version: v1alpha1 + names: + kind: TraefikService + plural: traefikservices + singular: traefikservice + scope: Namespaced +--- \ No newline at end of file diff --git a/traefik/deploy_traefik.rb b/traefik/deploy_traefik.rb new file mode 100644 index 0000000..d160ca8 --- /dev/null +++ b/traefik/deploy_traefik.rb @@ -0,0 +1,34 @@ +if ENV['GCE_PROJECT'] && ENV['GCE_DOMAIN'] && ENV['DNS_EMAIL'] && ENV['GCE_REGION'] + if !File.exist?('traefik-service-account.json') + puts "File traefik-service-account.json is missing" + exit 1 + end + + if !File.exist?('traefik.htpass') + puts "File traefik.htpass is missing" + exit 1 + end + puts "Get credentials" + system("gcloud container clusters get-credentials app-cluster --region #{ENV['GCE_REGION']}") + + puts "Create namespace in cluster" + system("HTTPS_PROXY=localhost:8888 kubectl create namespace traefik") + + puts "Handle the custom resource definitions" + system("HTTPS_PROXY=localhost:8888 kubectl apply -f crd.yml") + + puts "Handle the Role-Based Access Control needed by traefik" + system("HTTPS_PROXY=localhost:8888 kubectl apply -f rbac.yml") + + puts "Create kubernetes secrets for traefik" + system("HTTPS_PROXY=localhost:8888 kubectl create secret generic traefik-auth --from-file traefik.htpass --namespace=traefik") + system("HTTPS_PROXY=localhost:8888 kubectl create secret generic traefik-service-account --from-file=traefik-service-account.json=traefik-service-account.json --namespace=traefik") + + puts "Deploy traefik itself" + system("envsubst < deployment_base.yml > deployment.yml") + system("HTTPS_PROXY=localhost:8888 kubectl apply -f deployment.yml") + +else + puts "Missing env vars, did you define GCE_PROJECT, GCE_DOMAIN, GCE_REGION and DNS_EMAIL ?" + exit 1 +end \ No newline at end of file diff --git a/traefik/deployment_base.yml b/traefik/deployment_base.yml new file mode 100644 index 0000000..8620af1 --- /dev/null +++ b/traefik/deployment_base.yml @@ -0,0 +1,153 @@ +--- +apiVersion: v1 +kind: Service +metadata: + namespace: traefik + name: traefik + labels: + app.kubernetes.io/name: traefik +spec: + type: LoadBalancer + selector: + app.kubernetes.io/name: traefik + ports: + - protocol: TCP + name: http + port: 80 + - protocol: TCP + name: https + port: 443 +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + namespace: traefik + name: traefik + labels: + app.kubernetes.io/name: traefik +spec: + replicas: 1 + serviceName: traefik + selector: + matchLabels: + app.kubernetes.io/name: traefik + template: + metadata: + labels: + app.kubernetes.io/name: traefik + spec: + serviceAccountName: traefik-ingress-controller + containers: + - name: traefik + image: traefik:v2.3.5 + args: + - --ping + - --api.dashboard + - --api.insecure=false + - --entrypoints.http.Address=:80 + - --entrypoints.https.Address=:443 + - --providers.kubernetesingress + - --providers.kubernetescrd + - --certificatesResolvers.letsencrypt.acme.storage=/acme/acme.json + - --certificatesResolvers.letsencrypt.acme.email=${DNS_EMAIL} + - --certificatesResolvers.letsencrypt.acme.dnsChallenge.provider=gcloud + env: + - name: GCE_PROJECT + value: ${GCE_PROJECT} + - name: GCE_DOMAIN + value: ${GCE_DOMAIN} + - name: GCE_SERVICE_ACCOUNT_FILE + value: /service-account/traefik-service-account.json + ports: + - name: http + containerPort: 80 + - name: https + containerPort: 443 + volumeMounts: + - name: acme + mountPath: /acme + - name: traefik-service-account + mountPath: /service-account + readOnly: true + readinessProbe: + httpGet: + path: /ping + port: 8080 + livenessProbe: + httpGet: + path: /ping + port: 8080 + volumes: + - name: traefik-service-account + secret: + secretName: traefik-service-account + volumeClaimTemplates: + - metadata: + name: acme + spec: + accessModes: [ "ReadWriteOnce" ] + resources: + requests: + storage: 1Gi +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + namespace: traefik + name: traefik-auth +spec: + basicAuth: + secret: traefik-auth +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: IngressRoute +metadata: + namespace: traefik + name: traefik-dashboard + labels: + app.kubernetes.io/name: traefik-dashboard +spec: + entryPoints: + - https + routes: + - match: Host(`traefik.${GCE_DOMAIN}`) + kind: Rule + services: + - name: api@internal + kind: TraefikService + middlewares: + - name: traefik-auth + tls: + certResolver: letsencrypt + domains: + - main: "*.${GCE_DOMAIN}" +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: redirect-https + namespace: traefik +spec: + redirectScheme: + scheme: https + permanent: true + port: "443" +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: IngressRoute +metadata: + name: http-to-https + namespace: traefik +spec: + entryPoints: + - http + routes: + - match: HostRegexp(`{any:.+}`) + kind: Rule + services: + - name: noop@internal + kind: TraefikService + middlewares: + - name: redirect-https + namespace: traefik +--- \ No newline at end of file diff --git a/traefik/mini-test.yml b/traefik/mini-test.yml new file mode 100644 index 0000000..bb54f44 --- /dev/null +++ b/traefik/mini-test.yml @@ -0,0 +1,67 @@ +--- +apiVersion: v1 +kind: Service +metadata: + namespace: whoami + name: whoami-branch1 + labels: + app.kubernetes.io/name: whoami + app.kubernetes.io/instance: branch1 +spec: + selector: + app.kubernetes.io/name: whoami + app.kubernetes.io/instance: branch1 + ports: + - protocol: TCP + name: http + port: 80 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: whoami + name: whoami-branch1 + labels: + app.kubernetes.io/name: whoami + app.kubernetes.io/instance: branch1 +spec: + replicas: 3 + selector: + matchLabels: + app.kubernetes.io/name: whoami + app.kubernetes.io/instance: branch1 + template: + metadata: + labels: + app.kubernetes.io/name: whoami + app.kubernetes.io/instance: branch1 + spec: + containers: + - name: whoami + image: containous/whoami + ports: + - name: http + containerPort: 80 +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: IngressRoute +metadata: + namespace: whoami + name: whoami-branch1 + labels: + app.kubernetes.io/name: whoami + app.kubernetes.io/instance: branch1 +spec: + entryPoints: + - https + routes: + - match: Host(`branch1.whoami.[DOMAIN]`) + kind: Rule + services: + - namespace: whoami + name: whoami-branch1 + port: 80 + tls: + certResolver: letsencrypt + domains: + - main: "*.pw.rails.imfiny.com" \ No newline at end of file diff --git a/traefik/rbac.yml b/traefik/rbac.yml new file mode 100644 index 0000000..fa986da --- /dev/null +++ b/traefik/rbac.yml @@ -0,0 +1,66 @@ +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRole +metadata: + name: traefik-ingress-controller +rules: + - apiGroups: + - "" + resources: + - services + - endpoints + - secrets + verbs: + - get + - list + - watch + - apiGroups: + - extensions + - networking.k8s.io + resources: + - ingresses + - ingressclasses + verbs: + - get + - list + - watch + - apiGroups: + - extensions + resources: + - ingresses/status + verbs: + - update + - apiGroups: + - traefik.containo.us + resources: + - middlewares + - ingressroutes + - traefikservices + - ingressroutetcps + - ingressrouteudps + - tlsoptions + - tlsstores + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRoleBinding +metadata: + name: traefik-ingress-controller +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: traefik-ingress-controller +subjects: + - kind: ServiceAccount + namespace: traefik + name: traefik-ingress-controller +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + namespace: traefik + name: traefik-ingress-controller +--- \ No newline at end of file