From 33e7e8dfd242b929738da5b38efb29ab5d09e6a5 Mon Sep 17 00:00:00 2001 From: marcel-dempers Date: Fri, 24 Apr 2020 18:09:20 +1000 Subject: [PATCH] nginx-ingress files --- .../nginx/cluster-role-binding.yaml | 12 +++ .../controller/nginx/cluster-role.yaml | 53 +++++++++++++ .../ingress/controller/nginx/configMap.yaml | 35 +++++++++ .../nginx/custom-snippets.configmap.yaml | 37 +++++++++ .../ingress/controller/nginx/deployment.yaml | 77 +++++++++++++++++++ .../ingress/controller/nginx/namespace.yaml | 4 + .../controller/nginx/service-account.yaml | 5 ++ .../ingress/controller/nginx/service.yaml | 17 ++++ .../ingress/controller/nginx/tls-secret.yaml | 9 +++ .../{ => traefik}/traefik-configmap.yaml | 0 .../{ => traefik}/traefik-deployment.yaml | 0 .../{ => traefik}/traefik-rbac.yaml | 0 .../{ => traefik}/traefik-webui.yaml | 0 kubernetes/ingress/ingress-nginx-example.yaml | 21 +++++ 14 files changed, 270 insertions(+) create mode 100644 kubernetes/ingress/controller/nginx/cluster-role-binding.yaml create mode 100644 kubernetes/ingress/controller/nginx/cluster-role.yaml create mode 100644 kubernetes/ingress/controller/nginx/configMap.yaml create mode 100644 kubernetes/ingress/controller/nginx/custom-snippets.configmap.yaml create mode 100644 kubernetes/ingress/controller/nginx/deployment.yaml create mode 100644 kubernetes/ingress/controller/nginx/namespace.yaml create mode 100644 kubernetes/ingress/controller/nginx/service-account.yaml create mode 100644 kubernetes/ingress/controller/nginx/service.yaml create mode 100644 kubernetes/ingress/controller/nginx/tls-secret.yaml rename kubernetes/ingress/controller/{ => traefik}/traefik-configmap.yaml (100%) rename kubernetes/ingress/controller/{ => traefik}/traefik-deployment.yaml (100%) rename kubernetes/ingress/controller/{ => traefik}/traefik-rbac.yaml (100%) rename kubernetes/ingress/controller/{ => traefik}/traefik-webui.yaml (100%) create mode 100644 kubernetes/ingress/ingress-nginx-example.yaml diff --git a/kubernetes/ingress/controller/nginx/cluster-role-binding.yaml b/kubernetes/ingress/controller/nginx/cluster-role-binding.yaml new file mode 100644 index 0000000..ecc8fa8 --- /dev/null +++ b/kubernetes/ingress/controller/nginx/cluster-role-binding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRoleBinding +metadata: + name: nginx-ingress-clusterrole-nisa-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: nginx-ingress-clusterrole +subjects: + - kind: ServiceAccount + name: nginx-ingress-serviceaccount + namespace: ingress-nginx diff --git a/kubernetes/ingress/controller/nginx/cluster-role.yaml b/kubernetes/ingress/controller/nginx/cluster-role.yaml new file mode 100644 index 0000000..72d22cb --- /dev/null +++ b/kubernetes/ingress/controller/nginx/cluster-role.yaml @@ -0,0 +1,53 @@ +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRole +metadata: + name: nginx-ingress-clusterrole +rules: + - apiGroups: + - "" + resources: + - configmaps + - endpoints + - nodes + - pods + - secrets + verbs: + - list + - watch + - apiGroups: + - "" + resources: + - nodes + verbs: + - get + - apiGroups: + - "" + resources: + - services + verbs: + - get + - list + - watch + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch + - apiGroups: + - "extensions" + - "networking.k8s.io" + resources: + - ingresses + verbs: + - get + - list + - watch + - apiGroups: + - "extensions" + - "networking.k8s.io" + resources: + - ingresses/status + verbs: + - update \ No newline at end of file diff --git a/kubernetes/ingress/controller/nginx/configMap.yaml b/kubernetes/ingress/controller/nginx/configMap.yaml new file mode 100644 index 0000000..5f41172 --- /dev/null +++ b/kubernetes/ingress/controller/nginx/configMap.yaml @@ -0,0 +1,35 @@ +kind: ConfigMap +apiVersion: v1 +metadata: + name: nginx-configuration + namespace: ingress-nginx + labels: + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx +data: + client-body-buffer-size: 60k + client-header-buffer-size: 16k + error-log-level: warn + http2-max-field-size: 16k + large-client-header-buffers: 4 16k + log-format-escape-json: "true" + log-format-upstream: '{"time":"$time_iso8601","remote_addr":"$remote_addr","proxy_protocol_addr":"$proxy_protocol_addr","proxy_protocol_port":"$proxy_protocol_port","x_forward_for":"$proxy_add_x_forwarded_for","remote_user":"$remote_user","host":"$host","request_method":"$request_method","request_uri":"$request_uri","server_protocol":"$server_protocol","status":$status,"request_time":$request_time,"request_length":$request_length,"bytes_sent":$bytes_sent,"upstream_name":"$proxy_upstream_name","upstream_addr":"$upstream_addr","upstream_uri":"$uri","upstream_response_length":$upstream_response_length,"upstream_response_time":$upstream_response_time,"upstream_status":$upstream_status,"http_referrer":"$http_referer","http_user_agent":"$http_user_agent","http_cookie":"$http_cookie"}' + location-snippet: "include /etc/nginx/custom-snippets/location-custom.conf;" +--- +kind: ConfigMap +apiVersion: v1 +metadata: + name: tcp-services + namespace: ingress-nginx + labels: + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx +--- +kind: ConfigMap +apiVersion: v1 +metadata: + name: udp-services + namespace: ingress-nginx + labels: + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx \ No newline at end of file diff --git a/kubernetes/ingress/controller/nginx/custom-snippets.configmap.yaml b/kubernetes/ingress/controller/nginx/custom-snippets.configmap.yaml new file mode 100644 index 0000000..da8ef5a --- /dev/null +++ b/kubernetes/ingress/controller/nginx/custom-snippets.configmap.yaml @@ -0,0 +1,37 @@ +kind: ConfigMap +apiVersion: v1 +metadata: + name: custom-snippets + namespace: ingress-nginx +data: + location-custom.conf: | + set $globalcors ""; + + if ($http_origin ~* '^(http|https)?://(localhost(:[0-9]+)?)$') { + set $globalcors "true"; + } + + if ($request_method = 'OPTIONS') { + set $globalcors "${globalcors}options"; + } + + if ($globalcors = "trueoptions") { + add_header 'Access-Control-Allow-Origin' "$http_origin"; + add_header 'Access-Control-Allow-Credentials' 'true'; + add_header 'Access-Control-Allow-Methods' 'GET, POST, HEAD, PUT, DELETE, OPTIONS'; + add_header 'Access-Control-Allow-Headers' 'X-CSRF-Token,Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With'; + add_header 'Access-Control-Max-Age' 1728000; + add_header 'Content-Type' 'text/plain charset=UTF-8'; + add_header 'Content-Length' 0; + + return 204; + } + + if ($request_method ~* "(GET|POST|HEAD)") { + add_header "Access-Control-Allow-Origin" "$http_origin"; + add_header 'Access-Control-Allow-Credentials' 'true'; + add_header 'Access-Control-Allow-Headers' 'X-CSRF-Token,Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With'; + add_header 'X-Frame-Options' 'sameorigin'; + } + +--- \ No newline at end of file diff --git a/kubernetes/ingress/controller/nginx/deployment.yaml b/kubernetes/ingress/controller/nginx/deployment.yaml new file mode 100644 index 0000000..ea7ce2f --- /dev/null +++ b/kubernetes/ingress/controller/nginx/deployment.yaml @@ -0,0 +1,77 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx-ingress-controller + namespace: ingress-nginx +spec: + replicas: 2 + selector: + matchLabels: + app: nginx-ingress + template: + metadata: + labels: + app: nginx-ingress + annotations: + prometheus.io/port: "10254" + prometheus.io/scrape: "true" + spec: + serviceAccountName: nginx-ingress-serviceaccount + containers: + - name: nginx-ingress-controller + image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.25.1 + args: + - /nginx-ingress-controller + - --configmap=$(POD_NAMESPACE)/nginx-configuration + - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services + - --udp-services-configmap=$(POD_NAMESPACE)/udp-services + - --publish-service=$(POD_NAMESPACE)/ingress-nginx + - --annotations-prefix=nginx.ingress.kubernetes.io + securityContext: + allowPrivilegeEscalation: true + capabilities: + drop: + - ALL + add: + - NET_BIND_SERVICE + runAsUser: 33 + volumeMounts: + - name: custom-snippets + mountPath: /etc/nginx/custom-snippets/ + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + ports: + - name: http + containerPort: 80 + - name: https + containerPort: 443 + livenessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 10254 + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 10 + readinessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 10254 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 10 + volumes: + - name: custom-snippets + configMap: + name: custom-snippets diff --git a/kubernetes/ingress/controller/nginx/namespace.yaml b/kubernetes/ingress/controller/nginx/namespace.yaml new file mode 100644 index 0000000..bc9ce85 --- /dev/null +++ b/kubernetes/ingress/controller/nginx/namespace.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: ingress-nginx \ No newline at end of file diff --git a/kubernetes/ingress/controller/nginx/service-account.yaml b/kubernetes/ingress/controller/nginx/service-account.yaml new file mode 100644 index 0000000..666f700 --- /dev/null +++ b/kubernetes/ingress/controller/nginx/service-account.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: nginx-ingress-serviceaccount + namespace: ingress-nginx \ No newline at end of file diff --git a/kubernetes/ingress/controller/nginx/service.yaml b/kubernetes/ingress/controller/nginx/service.yaml new file mode 100644 index 0000000..64e8f62 --- /dev/null +++ b/kubernetes/ingress/controller/nginx/service.yaml @@ -0,0 +1,17 @@ +kind: Service +apiVersion: v1 +metadata: + name: ingress-nginx + namespace: ingress-nginx +spec: + externalTrafficPolicy: Local + selector: + app: nginx-ingress + type: LoadBalancer + ports: + - name: http + port: 80 + targetPort: http + - name: https + port: 443 + targetPort: https \ No newline at end of file diff --git a/kubernetes/ingress/controller/nginx/tls-secret.yaml b/kubernetes/ingress/controller/nginx/tls-secret.yaml new file mode 100644 index 0000000..59176f8 --- /dev/null +++ b/kubernetes/ingress/controller/nginx/tls-secret.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +data: + tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVYVENDQTBXZ0F3SUJBZ0lVY0J6TFRRNWl0K21UUkt2TWJiYTcxN0Z6MTRNd0RRWUpLb1pJaHZjTkFRRUwKQlFBd1VqRUxNQWtHQTFVRUJoTUNRVlV4RURBT0JnTlZCQWdUQjBWNFlXMXdiR1V4RWpBUUJnTlZCQWNUQ1UxbApiR0p2ZFhKdVpURVFNQTRHQTFVRUNoTUhSWGhoYlhCc1pURUxNQWtHQTFVRUN4TUNRMEV3SGhjTk1qQXdOREkwCk1EUXdNakF3V2hjTk1qRXdOREkwTURRd01qQXdXakJ4TVFzd0NRWURWUVFHRXdKQlZURVJNQThHQTFVRUNCTUkKVm1samRHOXlhV0V4RWpBUUJnTlZCQWNUQ1UxbGJHSnZkWEp1WlRFVE1CRUdBMVVFQ2hNS1MzVmlaWEp1WlhSbApjekVPTUF3R0ExVUVDeE1GVm1GMWJIUXhGakFVQmdOVkJBTVREWFpoZFd4MExXVjRZVzF3YkdVd2dnRWlNQTBHCkNTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCQVFEb3pnbUVjVHo2V2FYd1RiUEFqL3c2cmFXNUZUMGwKclBwa3IzUnUwcldBenM2VVlhZEdjS2ZnQ1RvY0hNcUhoUmRJUTlmZnVYL3BWU0xXYkF4SE16WFhHV2QveGQ0UApzb2RwU1Z2ekVxMEpNbmx4MHNJd0h1b0U3Q2k2WG8wZEYxQlUyTHVWZFdnS1ZSNjdYWXZZSVcrUW14bTMzMG9OCjNYcVhreVpUWmp2S0M1Y1J2VVRobng3OWw1dFhFWi92ZzJVemZCRGg1LzIzOTMrcWU3elNxT2loOVZjL2N6NzAKMVlLZkZHRUFJTThHZS9VbkR4OFpBbUI1cSs3TWNJTG13Y1E2QTM4ZmlxSkRhbHdkS2dtcnB0SENmdFRCc1dQLwo2dUhPVVJEVUtSd0M5eUJLVGE5S3BuOGh5eW9INk5CUXdodG0yRVFjclFWYnpKTC9ncXlXNnVYMUFnTUJBQUdqCmdnRUtNSUlCQmpBT0JnTlZIUThCQWY4RUJBTUNCYUF3SFFZRFZSMGxCQll3RkFZSUt3WUJCUVVIQXdFR0NDc0cKQVFVRkJ3TUNNQXdHQTFVZEV3RUIvd1FDTUFBd0hRWURWUjBPQkJZRUZESzJld1kyRzZ2VVpkVEtnb1ZFQ3c1eQpCaGZhTUI4R0ExVWRJd1FZTUJhQUZGbnN0c1hRSU80YmhicWY3RFV4Y241Qm5vMm5NSUdHQmdOVkhSRUVmekI5CmdndHRZWEpqWld3dWRHVnpkSUlOZG1GMWJIUXRaWGhoYlhCc1pZSXRkbUYxYkhRdFpYaGhiWEJzWlM1MllYVnMKZEMxbGVHRnRjR3hsTG5OMll5NWpiSFZ6ZEdWeUxteHZZMkZzZ2g5MllYVnNkQzFsZUdGdGNHeGxMblpoZFd4MApMV1Y0WVcxd2JHVXVjM1pqZ2dsc2IyTmhiR2h2YzNTSEJIOEFBQUV3RFFZSktvWklodmNOQVFFTEJRQURnZ0VCCkFHNHdhWkNpb2xxR2JOSUQvbE4velVOREpjR2xWdlhQblpURG1CRkdXQ1pWN3dObWpwRFd1NHc2MFZQbVdHMGsKd1JDeGk2Um1SSDJGWlI1SjVZVnh6RDJRQ0h1ZkVPeWlCeDUveWNJSUo3V3M0T2k5WjdWK1VoYzdWSHVTRGFxZwprTkNDV2ZCOUd0UTZZL2hNejNhbG14QXNzSXEwZytBUXlKaGUwVitEWHZqRFRTNWpyZHhxYVczYkdvTVdQZlZCCi9zV2NhL05UV1BCWng4R05JVCs5WEw3cm9lQ20zRjB5eS9UZ0NKSkl1T2NpNUJtUjhJZ3Q4VGVOTk5qUmRZcTIKQldaZVFkM3RzamxsTEJYVFZrZkJRTkhBSnkraTFUeDRmN3VSS1FYZjVtZHNTR0xjQkJzMmxSSS9xZUpQZFVKMwpzZ3JnM1NvbjQ5ZUxRUERPQkREY3VmTT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= + tls.key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcEFJQkFBS0NBUUVBNk00SmhIRTgrbG1sOEUyendJLzhPcTJsdVJVOUphejZaSzkwYnRLMWdNN09sR0duClJuQ240QWs2SEJ6S2g0VVhTRVBYMzdsLzZWVWkxbXdNUnpNMTF4bG5mOFhlRDdLSGFVbGI4eEt0Q1RKNWNkTEMKTUI3cUJPd291bDZOSFJkUVZOaTdsWFZvQ2xVZXUxMkwyQ0Z2a0pzWnQ5OUtEZDE2bDVNbVUyWTd5Z3VYRWIxRQo0WjhlL1plYlZ4R2Y3NE5sTTN3UTRlZjl0L2QvcW51ODBxam9vZlZYUDNNKzlOV0NueFJoQUNEUEJudjFKdzhmCkdRSmdlYXZ1ekhDQzVzSEVPZ04vSDRxaVEycGNIU29KcTZiUnduN1V3YkZqLytyaHpsRVExQ2tjQXZjZ1NrMnYKU3FaL0ljc3FCK2pRVU1JYlp0aEVISzBGVzh5Uy80S3NsdXJsOVFJREFRQUJBb0lCQUVlV3ZEUi9BZXBXVVFIUgpVeG8rN0tnNnA4Qi9lSHN5Y3hrdEh4ZkpNY2szVHkwdnpsbUo0UVd5c0t6ZWFhVTgxd2tBMjh4UFpiY2gyQUdwCjNpaXk1YmFNZUZoQlIyVDZXRXVYSkhCZDZObndMSXBFN2pRUC9aU2Y3bkpKQ3duTUZvYlEwdlpGMFVXRUlWd3EKaXd0ZVZNbForSkdqVjBsbU53R1BYWFM5OWxyTm1YRmliVjlyWGtHTWF0NStCY0NsMWx4Ty9COTBkUGlJOCtXSwo3MDVqUnhDMVhrcWpNTTE5aUt5dUVEMjJYMG4rM01TMWl5YzhDcjFKallsQXMzV3dSVzdvMDdrOXBESWNialIrCmxKZm9qNzljU29LNDNQZytzdjZMTllvMHpBSnlQS1p0NUN1RkdNaWZkelV4a2xqVWdWaDIySEFYK1I5VVpFck0KRjB3TDYyMENnWUVBOTZRdS9hK1BqNFRlemZiblE1N1FkNEl1eWZZbHBaK1ZlTU03T1Z4MURSYmQ5UUg0MWVvdwpmdDVpN3R0Uzl6NmhEYnVwS3ptYWJxYXkwdnU1M25GdVFMdGptU1QyVmY5MWtrQzBNRHk3RndiVTlYUXZ3NThOCmZGVmYvYjNiK3JJWXBCVzFROHJCU3RkRi9xMGcrL1ZlNnBPL3Z3WVNhQVd3RTQ5RkVVR2NyNGNDZ1lFQThLbW4KakE4N29YSjJxb0h1VXU2WnFaZEU5c0t5UG9aSjZWbXJJVmROU0d0ZDdDcldSWVFOekZQYjB0Q3FYU2ZaTVMxMAprQWdEdFB4eHI2UDRtV0JoOThsajNwVzlXUTl5amg3cFd1R3RHSjdnNDh5azUvaFpwd0RTT3lXRDFxVkd0ZXNxCmk2dXR0dWV6cHJET2tWNnhLODZ2ZTBIUVVjTndJQk54RUpEYWhhTUNnWUVBMDZrNkhNeUVhTWZKWThObjBTMFoKd3p1NjRCWUtBWERQNGVNRWFMZTB1QlpXYWNaZ3QvMnRxNUpLZnh0bzR6aGRrWTVYUGtIQzFGYVl1Nm82S0gxTgpIZmpNWFNYeGdubVJOUXNtdDZBQXpPS2kvSlJ0Q3NlVVVEUHNrc1ZIRXhSTDZWdEFqZ3ZyZ0J0VmtTTEs4Vys4Cnk4U3kvQU9sa2RGaXVLVVpCSEhQQ1ZzQ2dZQTBtcERCMzQ2RU1wWFhuVUR2cGJHMnpSYkk3VE95MFAyVTRRR3oKN3ZZNGp5ZGZlTm1QSmxjeHcxNjRUTjRBTUxhYnRqalZScnN3czBGU1NBQU4zbkJyamZ5amFZMlN5dnFhTUEySAp6TzVlQkZSWjFxQnhCK3Jvd3hnd3ozbHEwSU9OUGhMMXBwZjQ4OXBqNUIreXpNVGpNM0ZOK3N2REkzbjl1T0lzCjRjeXlDd0tCZ1FDbUxzbXVRZEVYZ0oxVmhNSFRMYWdDU2ZtaGVHK3lWa2xjYkpmOHlWK3ZhWnk4bjkrMmhPU1MKSU5pT1poMjVyWUQ5NmR6WUVYZVhzSmVoalh1ZU8xdENhZE5uMXVEY3d0MlJQTnBmMWtCd2Rtb0xISENJOVp5NApVcVFTcHY3c3lZYlVhbHIyUEt4VWFrN2FPanhKYlBGNUpTV1ZOaUFrdDdxa0hBNGJXenVvN0E9PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo= +kind: Secret +metadata: + name: marcel-tls-secret + namespace: example-app +type: kubernetes.io/tls diff --git a/kubernetes/ingress/controller/traefik-configmap.yaml b/kubernetes/ingress/controller/traefik/traefik-configmap.yaml similarity index 100% rename from kubernetes/ingress/controller/traefik-configmap.yaml rename to kubernetes/ingress/controller/traefik/traefik-configmap.yaml diff --git a/kubernetes/ingress/controller/traefik-deployment.yaml b/kubernetes/ingress/controller/traefik/traefik-deployment.yaml similarity index 100% rename from kubernetes/ingress/controller/traefik-deployment.yaml rename to kubernetes/ingress/controller/traefik/traefik-deployment.yaml diff --git a/kubernetes/ingress/controller/traefik-rbac.yaml b/kubernetes/ingress/controller/traefik/traefik-rbac.yaml similarity index 100% rename from kubernetes/ingress/controller/traefik-rbac.yaml rename to kubernetes/ingress/controller/traefik/traefik-rbac.yaml diff --git a/kubernetes/ingress/controller/traefik-webui.yaml b/kubernetes/ingress/controller/traefik/traefik-webui.yaml similarity index 100% rename from kubernetes/ingress/controller/traefik-webui.yaml rename to kubernetes/ingress/controller/traefik/traefik-webui.yaml diff --git a/kubernetes/ingress/ingress-nginx-example.yaml b/kubernetes/ingress/ingress-nginx-example.yaml new file mode 100644 index 0000000..3168109 --- /dev/null +++ b/kubernetes/ingress/ingress-nginx-example.yaml @@ -0,0 +1,21 @@ +apiVersion: networking.k8s.io/v1beta1 +kind: Ingress +metadata: + annotations: + kubernetes.io/ingress.class: "nginx" + nginx.ingress.kubernetes.io/rewrite-target: / #new + name: example-app + namespace: example-app +spec: + tls: + - hosts: + - marcel.test + secretName: marcel-tls-secret + rules: + - host: marcel.test + http: + paths: + - path: / + backend: + serviceName: example-service + servicePort: 80