From a7a6f5543b0335bc9ac0385a72b5600dcdf6ed42 Mon Sep 17 00:00:00 2001 From: Alain Kaeslin Date: Tue, 27 Aug 2024 09:16:29 +0200 Subject: [PATCH 1/6] Add command to show log. --- examples/nginx-hello.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/nginx-hello.yml b/examples/nginx-hello.yml index 407365e..4b40a18 100644 --- a/examples/nginx-hello.yml +++ b/examples/nginx-hello.yml @@ -12,6 +12,10 @@ # # curl http://$(kubectl get service hello -o jsonpath='{.status.loadBalancer.ingress[0].ip}') # +# If you follow the nginx log, you will see that nginx sees a cluster internal +# IP address as source of requests: +# +# kubectl logs -l "app=hello" --- apiVersion: apps/v1 kind: Deployment From 5073ddd50e29d971524ec544b696c2b5c258901c Mon Sep 17 00:00:00 2001 From: Alain Kaeslin Date: Tue, 27 Aug 2024 09:16:48 +0200 Subject: [PATCH 2/6] Add ingress example. --- examples/ingress.yaml | 117 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 examples/ingress.yaml diff --git a/examples/ingress.yaml b/examples/ingress.yaml new file mode 100644 index 0000000..455253d --- /dev/null +++ b/examples/ingress.yaml @@ -0,0 +1,117 @@ +# Deploys two nginxdemos/hello:plain-text containers ("blue" and "red") +# and creates a ClusterIP services named "blue-svc" and "red-svc" for the +# deployments. Additionally, an Ingress resource named "simple" is set +# up to route requests for "/red" to "red-svc" service and +# requests for "/blue" to the "blue-svc" service. +# +# This examples needs ingress-nginx to work, see: +# https://kubernetes.github.io/ingress-nginx/deploy/#quick-start +# +# export KUBECONFIG=path/to/kubeconfig +# kubectl apply -f ingress.yaml +# +# Wait for `kubectl describe service ingress-nginx-controller -n ingress-nginx` to +# show "Loadbalancer Ensured", then use the IP address found under "LoadBalancer +# Ingress" to connect to the service. +# +# You can also use the following shortcut: +# +# curl http://$(kubectl get service ingress-nginx-controller -n ingress-nginx -o jsonpath='{.status.loadBalancer.ingress[0].ip}')/blue +# curl http://$(kubectl get service ingress-nginx-controller -n ingress-nginx -o jsonpath='{.status.loadBalancer.ingress[0].ip}')/red +# + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: blue + name: blue +spec: + replicas: 1 + selector: + matchLabels: + app: blue + template: + metadata: + labels: + app: blue + spec: + containers: + - image: nginxdemos/hello:plain-text + name: hello +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app: blue + name: blue-svc +spec: + ports: + - port: 80 + protocol: TCP + targetPort: 80 + selector: + app: blue +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: red + name: red +spec: + replicas: 1 + selector: + matchLabels: + app: red + template: + metadata: + labels: + app: red + spec: + containers: + - image: nginxdemos/hello:plain-text + name: hello + resources: { } +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app: red + name: red-svc +spec: + ports: + - port: 80 + protocol: TCP + targetPort: 80 + selector: + app: red +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: simple + annotations: + nginx.ingress.kubernetes.io/rewrite-target: / +spec: + ingressClassName: nginx + rules: + - http: + paths: + - backend: + service: + name: red-svc + port: + number: 80 + path: /red + pathType: Exact + - backend: + service: + name: blue-svc + port: + number: 80 + path: /blue + pathType: Exact From 649939fbdf07fa769123efcd2aa3a0c7ff4defbe Mon Sep 17 00:00:00 2001 From: Alain Kaeslin Date: Tue, 27 Aug 2024 09:17:46 +0200 Subject: [PATCH 3/6] Add PROXYv2 example. --- examples/proxy-v2-protocol.yml | 130 +++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 examples/proxy-v2-protocol.yml diff --git a/examples/proxy-v2-protocol.yml b/examples/proxy-v2-protocol.yml new file mode 100644 index 0000000..defc10b --- /dev/null +++ b/examples/proxy-v2-protocol.yml @@ -0,0 +1,130 @@ +# This example is the same as nginx-hello.yml, except that it uses +# the PROXYv2 protocol between the load balancer and the nginx server +# in order to preserve the original source IP. +# +# export KUBECONFIG=path/to/kubeconfig +# kubectl apply -f proxy-v2-protocol.yml +# +# Wait for `kubectl describe service proxy-hello` to show "Loadbalancer Ensured", +# then use the IP address found under "LoadBalancer Ingress" to connect to the +# service. +# +# You can also use the following shortcut: +# +# curl http://$(kubectl get service proxy-hello -o jsonpath='{.status.loadBalancer.ingress[0].ip}') +# +# If you follow the nginx log, you will see that nginx sees the original source +# IP address as source of requests (also not the nginx config injected using +# config maps): +# +# kubectl logs -l "app=proxy-hello" +# +# Starting with Kubernetes 1.30 requests originating from within the cluster work out of the box too: +# +# kubectl run -it --rm --restart=Never curl --image=curlimages/curl -- curl http://$(kubectl get service proxy-hello -o jsonpath='{.status.loadBalancer.ingress[0].ip}') +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: proxy-hello +spec: + replicas: 2 + selector: + matchLabels: + app: proxy-hello + template: + metadata: + labels: + app: proxy-hello + spec: + containers: + - name: proxy-hello + image: nginxdemos/hello:plain-text + volumeMounts: + - name: nginx-config-volume + mountPath: /etc/nginx/nginx.conf + subPath: nginx.conf + - name: hello-plain-config-volume + mountPath: /etc/nginx/conf.d/hello-plain-text.conf + subPath: hello-plain-text.conf + volumes: + - name: nginx-config-volume + configMap: + name: nginx-config + - name: hello-plain-config-volume + configMap: + name: hello-plain-config +--- +apiVersion: v1 +data: + nginx.conf: |2 + + user nginx; + worker_processes auto; + + error_log /var/log/nginx/error.log notice; + pid /var/run/nginx.pid; + + + events { + worker_connections 1024; + } + + + http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$proxy_protocol_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + sendfile on; + #tcp_nopush on; + + keepalive_timeout 65; + + #gzip on; + + include /etc/nginx/conf.d/*.conf; + } +kind: ConfigMap +metadata: + name: nginx-config +--- +apiVersion: v1 +data: + hello-plain-text.conf: | + server { + listen 80 proxy_protocol; + listen [::]:80 proxy_protocol; + + location / { + default_type text/plain; + expires -1; + return 200 'Server address: $server_addr:$server_port\nServer name: $hostname\nDate: $time_local\nURI: $request_uri\nRequest ID: $request_id\n'; + } + } +kind: ConfigMap +metadata: + name: hello-plain-config +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app: proxy-hello + name: proxy-hello + annotations: + k8s.cloudscale.ch/loadbalancer-pool-protocol: proxyv2 +spec: + ports: + - port: 80 + protocol: TCP + targetPort: 80 + name: http + selector: + app: proxy-hello + type: LoadBalancer From e5a943c5d7fcc62f5cc59304baa27a887b4a7268 Mon Sep 17 00:00:00 2001 From: Alain Kaeslin Date: Tue, 27 Aug 2024 09:17:57 +0200 Subject: [PATCH 4/6] Add external traffic policy example. --- examples/external-traffic-policy-local.yml | 62 ++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 examples/external-traffic-policy-local.yml diff --git a/examples/external-traffic-policy-local.yml b/examples/external-traffic-policy-local.yml new file mode 100644 index 0000000..631cb3a --- /dev/null +++ b/examples/external-traffic-policy-local.yml @@ -0,0 +1,62 @@ +# This example is the same as nginx-hello.yml, except that it uses +# externalTrafficPolicy: Local on the loadbalancer service. +# +# export KUBECONFIG=path/to/kubeconfig +# kubectl apply -f external-traffic-policy-local.yml +# +# Wait for `kubectl describe service hello` to show "Loadbalancer Ensured", +# then use the IP address found under "LoadBalancer Ingress" to connect to the +# service. +# +# You can also use the following shortcut: +# +# curl http://$(kubectl get service local-hello -o jsonpath='{.status.loadBalancer.ingress[0].ip}') +# +# If you follow the nginx log, you will see that nginx sees one of load balancer IPs as source of +# requests: +# +# kubectl logs -l "app=local-hello" +# +# A load balancer health monitor has been configured to check which node a replica is scheduled on. +# You can use the following script to mimic the check performed by the load balancer health monitor: +# +# HEALTH_CHECK_PORT=$(kubectl get svc local-hello -o jsonpath='{.spec.healthCheckNodePort}') +# NODE_IPS=$(kubectl get nodes --selector='!node.kubernetes.io/exclude-from-external-load-balancers' -o jsonpath='{.items[*].status.addresses[1].address}') +# for NODE_IP in $NODE_IPS; do curl -s -o /dev/null -w "%{remote_ip}\t%{http_code}\t%{url_effective}\n" "http://$NODE_IP:$HEALTH_CHECK_PORT/livez"; done + + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: local-hello +spec: + replicas: 2 + selector: + matchLabels: + app: local-hello + template: + metadata: + labels: + app: local-hello + spec: + containers: + - name: hello + image: nginxdemos/hello:plain-text +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app: local-hello + name: local-hello +spec: + ports: + - port: 80 + protocol: TCP + targetPort: 80 + name: http + selector: + app: local-hello + type: LoadBalancer + externalTrafficPolicy: Local From 9624197fc117a3703bed2766db17f1f34471201b Mon Sep 17 00:00:00 2001 From: Alain Kaeslin Date: Tue, 27 Aug 2024 09:33:14 +0200 Subject: [PATCH 5/6] Fix name mistake. --- examples/external-traffic-policy-local.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/external-traffic-policy-local.yml b/examples/external-traffic-policy-local.yml index 631cb3a..1217707 100644 --- a/examples/external-traffic-policy-local.yml +++ b/examples/external-traffic-policy-local.yml @@ -4,7 +4,7 @@ # export KUBECONFIG=path/to/kubeconfig # kubectl apply -f external-traffic-policy-local.yml # -# Wait for `kubectl describe service hello` to show "Loadbalancer Ensured", +# Wait for `kubectl describe service local-hello` to show "Loadbalancer Ensured", # then use the IP address found under "LoadBalancer Ingress" to connect to the # service. # From c644a68c3e9cf2a472f255b2256ead638b86387e Mon Sep 17 00:00:00 2001 From: Alain Kaeslin Date: Tue, 27 Aug 2024 10:42:48 +0200 Subject: [PATCH 6/6] Unify white space and fix a typo. --- examples/external-traffic-policy-local.yml | 5 ++--- examples/ingress.yaml | 3 +-- examples/nginx-hello.yml | 1 + examples/proxy-v2-protocol.yml | 1 + 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/external-traffic-policy-local.yml b/examples/external-traffic-policy-local.yml index 1217707..8f4e271 100644 --- a/examples/external-traffic-policy-local.yml +++ b/examples/external-traffic-policy-local.yml @@ -22,9 +22,8 @@ # # HEALTH_CHECK_PORT=$(kubectl get svc local-hello -o jsonpath='{.spec.healthCheckNodePort}') # NODE_IPS=$(kubectl get nodes --selector='!node.kubernetes.io/exclude-from-external-load-balancers' -o jsonpath='{.items[*].status.addresses[1].address}') -# for NODE_IP in $NODE_IPS; do curl -s -o /dev/null -w "%{remote_ip}\t%{http_code}\t%{url_effective}\n" "http://$NODE_IP:$HEALTH_CHECK_PORT/livez"; done - - +# for NODE_IP in $NODE_IPS; do curl -s -o /dev/null -w "%{remote_ip}\t%{http_code}\t%{url_effective}\n" "http://$NODE_IP:$HEALTH_CHECK_PORT/livez"; done +# --- apiVersion: apps/v1 kind: Deployment diff --git a/examples/ingress.yaml b/examples/ingress.yaml index 455253d..25b1bbb 100644 --- a/examples/ingress.yaml +++ b/examples/ingress.yaml @@ -1,5 +1,5 @@ # Deploys two nginxdemos/hello:plain-text containers ("blue" and "red") -# and creates a ClusterIP services named "blue-svc" and "red-svc" for the +# and creates ClusterIP services named "blue-svc" and "red-svc" for the # deployments. Additionally, an Ingress resource named "simple" is set # up to route requests for "/red" to "red-svc" service and # requests for "/blue" to the "blue-svc" service. @@ -19,7 +19,6 @@ # curl http://$(kubectl get service ingress-nginx-controller -n ingress-nginx -o jsonpath='{.status.loadBalancer.ingress[0].ip}')/blue # curl http://$(kubectl get service ingress-nginx-controller -n ingress-nginx -o jsonpath='{.status.loadBalancer.ingress[0].ip}')/red # - --- apiVersion: apps/v1 kind: Deployment diff --git a/examples/nginx-hello.yml b/examples/nginx-hello.yml index 4b40a18..306a9fb 100644 --- a/examples/nginx-hello.yml +++ b/examples/nginx-hello.yml @@ -16,6 +16,7 @@ # IP address as source of requests: # # kubectl logs -l "app=hello" +# --- apiVersion: apps/v1 kind: Deployment diff --git a/examples/proxy-v2-protocol.yml b/examples/proxy-v2-protocol.yml index defc10b..8bf2e38 100644 --- a/examples/proxy-v2-protocol.yml +++ b/examples/proxy-v2-protocol.yml @@ -22,6 +22,7 @@ # Starting with Kubernetes 1.30 requests originating from within the cluster work out of the box too: # # kubectl run -it --rm --restart=Never curl --image=curlimages/curl -- curl http://$(kubectl get service proxy-hello -o jsonpath='{.status.loadBalancer.ingress[0].ip}') +# --- apiVersion: apps/v1 kind: Deployment