From 009042aa0d4bbf75cc5f78270332cbed1d066fb0 Mon Sep 17 00:00:00 2001 From: Nico Schottelius Date: Wed, 9 Jun 2021 11:45:25 +0200 Subject: [PATCH 01/16] ++k8s / no loadbalancer --- .../contents.lr | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 content/u/blog/ipv6-only-k8s-no-need-for-loadbalancer/contents.lr diff --git a/content/u/blog/ipv6-only-k8s-no-need-for-loadbalancer/contents.lr b/content/u/blog/ipv6-only-k8s-no-need-for-loadbalancer/contents.lr new file mode 100644 index 0000000..b60c614 --- /dev/null +++ b/content/u/blog/ipv6-only-k8s-no-need-for-loadbalancer/contents.lr @@ -0,0 +1,24 @@ +title: Kubernetes does not need a Loadbalancer +--- +pub_date: 2021-06-09 +--- +author: ungleich +--- +twitter_handle: ungleich +--- +_hidden: no +--- +_discoverable: no +--- +abstract: + +--- +body: + +## TL;DR + +You might be running services just fine without a loadbalancer +in Kubernetes. Using public ClusterIP is very easy, especially with +IPv6 only clusters. + +## From 3f6cc3bfc7637bfd7e0b6f3b17aa8591ea836bc3 Mon Sep 17 00:00:00 2001 From: Nico Schottelius Date: Wed, 9 Jun 2021 11:46:51 +0200 Subject: [PATCH 02/16] ++blog --- .../contents.lr | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/content/u/blog/ipv6-only-k8s-no-need-for-loadbalancer/contents.lr b/content/u/blog/ipv6-only-k8s-no-need-for-loadbalancer/contents.lr index b60c614..58d8d7a 100644 --- a/content/u/blog/ipv6-only-k8s-no-need-for-loadbalancer/contents.lr +++ b/content/u/blog/ipv6-only-k8s-no-need-for-loadbalancer/contents.lr @@ -1,4 +1,4 @@ -title: Kubernetes does not need a Loadbalancer +title: Kubernetes does not need a LoadBalancer nor ingress --- pub_date: 2021-06-09 --- @@ -21,4 +21,13 @@ You might be running services just fine without a loadbalancer in Kubernetes. Using public ClusterIP is very easy, especially with IPv6 only clusters. -## +## Background + +Typically in loadbalancer +ingress for public + + + +## DNS + +## Letsencrypt From 227db053038bdb587e645b9ce743c5dc8cd30f63 Mon Sep 17 00:00:00 2001 From: Nico Schottelius Date: Wed, 9 Jun 2021 18:24:07 +0200 Subject: [PATCH 03/16] ++k8s/ingress blog post --- .../contents.lr | 33 ---- .../kubernetes-without-ingress/contents.lr | 172 ++++++++++++++++++ 2 files changed, 172 insertions(+), 33 deletions(-) delete mode 100644 content/u/blog/ipv6-only-k8s-no-need-for-loadbalancer/contents.lr create mode 100644 content/u/blog/kubernetes-without-ingress/contents.lr diff --git a/content/u/blog/ipv6-only-k8s-no-need-for-loadbalancer/contents.lr b/content/u/blog/ipv6-only-k8s-no-need-for-loadbalancer/contents.lr deleted file mode 100644 index 58d8d7a..0000000 --- a/content/u/blog/ipv6-only-k8s-no-need-for-loadbalancer/contents.lr +++ /dev/null @@ -1,33 +0,0 @@ -title: Kubernetes does not need a LoadBalancer nor ingress ---- -pub_date: 2021-06-09 ---- -author: ungleich ---- -twitter_handle: ungleich ---- -_hidden: no ---- -_discoverable: no ---- -abstract: - ---- -body: - -## TL;DR - -You might be running services just fine without a loadbalancer -in Kubernetes. Using public ClusterIP is very easy, especially with -IPv6 only clusters. - -## Background - -Typically in loadbalancer -ingress for public - - - -## DNS - -## Letsencrypt diff --git a/content/u/blog/kubernetes-without-ingress/contents.lr b/content/u/blog/kubernetes-without-ingress/contents.lr new file mode 100644 index 0000000..88b475b --- /dev/null +++ b/content/u/blog/kubernetes-without-ingress/contents.lr @@ -0,0 +1,172 @@ +title: Kubernetes without Ingress +--- +pub_date: 2021-06-09 +--- +author: ungleich +--- +twitter_handle: ungleich +--- +_hidden: no +--- +_discoverable: no +--- +abstract: + +--- +body: + +## Introduction + +On our journey to build and define IPv6 only kubernetes clusters we +came accross some principles that seem awkward in the IPv6 world. Let +us today have a look at the *LoadBalancer* and *Ingress* concepts. + +## Ingress + +Let's have a look at the [Ingres +definition](https://kubernetes.io/docs/concepts/services-networking/ingress/) +definiton from the kubernetes website: + +``` +Ingress exposes HTTP and HTTPS routes from outside the cluster to +services within the cluster. Traffic routing is controlled by rules +defined on the Ingress resource. +``` + +So the ingress basically routes from outside to inside. But, in the +IPv6 world, services can already be publicly reachable, depending on +your network policy. + +## Services + +Let's have a look at how services in IPv6 only clusters look like: + +``` +% kubectl get svc +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +etherpad ClusterIP 2a0a:e5c0:13:e2::a94b 9001/TCP 19h +nginx-service ClusterIP 2a0a:e5c0:13:e2::3607 80/TCP 43h +postgres ClusterIP 2a0a:e5c0:13:e2::c9e0 5432/TCP 19h +... +``` +All these services are world reachable, so a theorethical ingress does +actually not do any work. Services are routed to the pods as usual. + +## ServiceTypes + +While we are at looking at the k8s primitives, let's have a closer +look at the **Service**, specifically at 3 of the **ServiceTypes** +supported by k8s, including it's definition: + +### ClusterIP + +The k8s website says + +``` +Exposes the Service on a cluster-internal IP. Choosing this value +makes the Service only reachable from within the cluster. This is the +default ServiceType. +``` + +So in the context of IPv6, this sounds wrong. There is nothing that +makes an global IPv6 address be "internal", besides possible network +policies. The concept is probably coming from the strict difference of +RFC1918 space usually used in k8s clusters and not public IPv4. + +This difference does not make a lot of sense in the IPv6 world though +and seeing services as public by default, makes more sense. + +### NodePort + +Let's have a look at the definition first again: + +``` +Exposes the Service on each Node's IP at a static port (the +NodePort). A ClusterIP Service, to which the NodePort Service routes, +is automatically created. You'll be able to contact the NodePort +Service, from outside the cluster, by requesting :. +``` + +Conceptually this can be similarily utilised in the IPv6 only world +like it does in the IPv4 world. However given that there are enough +addresses available with IPv6, this might not be such an interesting +ServiceType anymore. + + +### LoadBalancer + +Before we have a look at this type, let's take some steps back +first to ... + + +## ... Load Balancing + +There are a variety of possibilities to do load balancing. From simple +round robin, to ECMP based load balancing, to application aware, +potentially weighted load balancing. + +So for load balancing, there is usually more than one solution and +there is likely not one size fits all. + +So with this said, let.s have a look at the +**ServiceType LoadBalancer** definition: + +``` +Exposes the Service externally using a cloud provider's load +balancer. NodePort and ClusterIP Services, to which the external load +balancer routes, are automatically created. +``` + +So whatever the cloud provider offers, can be used, and that is a good +thing. However, let's have a look at how you get load balancing for +free in IPv6 only clusters: + +## Load Balancing in IPv6 only clusters + +So what is the most easy way of reliable load balancing in network? +ECMP (equal cost multi path) comes to the mind right away. Given that +kubernetes nodes can BGP peer with the network (upstream or the +switches), this basically gives load balancing to the world for free: + +``` + [ The Internet ] + | + [ k8s-node-1 ]-----------[ network ]-----------[ k8s-node-n] + [ ECMP ] + | + [ k8s-node-2] + +``` + +In the real world on a bird based BGP upstream router +this looks as follows: + +``` +[18:13:02] red.place7:~# birdc show route +BIRD 2.0.7 ready. +Table master6: +... +2a0a:e5c0:13:e2::/108 unicast [place7-server1 2021-06-07] * (100) [AS65534i] + via 2a0a:e5c0:13:0:225:b3ff:fe20:3554 on eth0 + unicast [place7-server4 2021-06-08] (100) [AS65534i] + via 2a0a:e5c0:13:0:225:b3ff:fe20:3564 on eth0 + unicast [place7-server2 2021-06-07] (100) [AS65534i] + via 2a0a:e5c0:13:0:225:b3ff:fe20:38cc on eth0 + unicast [place7-server3 2021-06-07] (100) [AS65534i] + via 2a0a:e5c0:13:0:224:81ff:fee0:db7a on eth0 +... +``` + +## TL;DR + +We know, a TL;DR at the end is not the right thing to do, but hey, we +are at ungleich, aren't we? + +In a nutshell, with IPv6 the concept of **Ingress**, +**Service** and the **LoadBalancer** ServiceType +types need to be revised, as IPv6 allows direct access without having +to jump through hoops. + +If you are interesting in continuing the discussion, +we are there for you in +[the #hacking:ungleich.ch Matrix channel](https://chat.with.ungleich.ch). From 5294a89d49ad45b69264d4a0500ce4b973372940 Mon Sep 17 00:00:00 2001 From: Nico Schottelius Date: Wed, 9 Jun 2021 18:27:41 +0200 Subject: [PATCH 04/16] ++journey link --- content/u/blog/kubernetes-without-ingress/contents.lr | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/content/u/blog/kubernetes-without-ingress/contents.lr b/content/u/blog/kubernetes-without-ingress/contents.lr index 88b475b..c8bb0f7 100644 --- a/content/u/blog/kubernetes-without-ingress/contents.lr +++ b/content/u/blog/kubernetes-without-ingress/contents.lr @@ -17,9 +17,11 @@ body: ## Introduction -On our journey to build and define IPv6 only kubernetes clusters we -came accross some principles that seem awkward in the IPv6 world. Let -us today have a look at the *LoadBalancer* and *Ingress* concepts. +On [our journey to build and define IPv6 only kubernetes +clusters](https://www.nico.schottelius.org/blog/k8s-ipv6-only-cluster/) +we came accross some principles that seem awkward in the IPv6 +world. Let us today have a look at the *LoadBalancer* and *Ingress* +concepts. ## Ingress From f97bf94487d0229f4481a90cc1a502df7f54770a Mon Sep 17 00:00:00 2001 From: Nico Schottelius Date: Wed, 9 Jun 2021 18:30:50 +0200 Subject: [PATCH 05/16] ++title change --- content/u/blog/kubernetes-without-ingress/contents.lr | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/u/blog/kubernetes-without-ingress/contents.lr b/content/u/blog/kubernetes-without-ingress/contents.lr index c8bb0f7..3d1e2e9 100644 --- a/content/u/blog/kubernetes-without-ingress/contents.lr +++ b/content/u/blog/kubernetes-without-ingress/contents.lr @@ -1,4 +1,4 @@ -title: Kubernetes without Ingress +title: Building Ingress-less Kubernetes Clusters --- pub_date: 2021-06-09 --- @@ -19,7 +19,7 @@ body: On [our journey to build and define IPv6 only kubernetes clusters](https://www.nico.schottelius.org/blog/k8s-ipv6-only-cluster/) -we came accross some principles that seem awkward in the IPv6 +we came accross some principles that seem awkward in the IPv6 only world. Let us today have a look at the *LoadBalancer* and *Ingress* concepts. From 92a26fb4415488a0e861db83f4a4a1eafdf0bdca Mon Sep 17 00:00:00 2001 From: Nico Schottelius Date: Wed, 9 Jun 2021 18:34:06 +0200 Subject: [PATCH 06/16] ++typos --- content/u/blog/kubernetes-without-ingress/contents.lr | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/u/blog/kubernetes-without-ingress/contents.lr b/content/u/blog/kubernetes-without-ingress/contents.lr index 3d1e2e9..f6ad26a 100644 --- a/content/u/blog/kubernetes-without-ingress/contents.lr +++ b/content/u/blog/kubernetes-without-ingress/contents.lr @@ -25,7 +25,7 @@ concepts. ## Ingress -Let's have a look at the [Ingres +Let's have a look at the [Ingress definition](https://kubernetes.io/docs/concepts/services-networking/ingress/) definiton from the kubernetes website: @@ -36,8 +36,8 @@ defined on the Ingress resource. ``` So the ingress basically routes from outside to inside. But, in the -IPv6 world, services can already be publicly reachable, depending on -your network policy. +IPv6 world, services are already publicly reachable. It just +depends on your network policy. ## Services From a2d4d7fe1a046c7837c4d9f1f4ad0f9720f768d3 Mon Sep 17 00:00:00 2001 From: Nico Schottelius Date: Wed, 9 Jun 2021 18:38:07 +0200 Subject: [PATCH 07/16] ++support --- content/u/blog/kubernetes-without-ingress/contents.lr | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/content/u/blog/kubernetes-without-ingress/contents.lr b/content/u/blog/kubernetes-without-ingress/contents.lr index f6ad26a..59078ba 100644 --- a/content/u/blog/kubernetes-without-ingress/contents.lr +++ b/content/u/blog/kubernetes-without-ingress/contents.lr @@ -75,8 +75,9 @@ makes an global IPv6 address be "internal", besides possible network policies. The concept is probably coming from the strict difference of RFC1918 space usually used in k8s clusters and not public IPv4. -This difference does not make a lot of sense in the IPv6 world though -and seeing services as public by default, makes more sense. +This difference does not make a lot of sense in the IPv6 world though. +Seeing **services as public by default**, makes much more sense. +And simplifies your clusters a lot. ### NodePort @@ -172,3 +173,6 @@ to jump through hoops. If you are interesting in continuing the discussion, we are there for you in [the #hacking:ungleich.ch Matrix channel](https://chat.with.ungleich.ch). + +Or if you are interested in an IPv6 only kubernetes cluster, +drop a mail to **support**-at-**ungleich.ch**. From c1eb274338801123fec80bc4db875d6c445ec766 Mon Sep 17 00:00:00 2001 From: Nico Schottelius Date: Wed, 9 Jun 2021 18:38:42 +0200 Subject: [PATCH 08/16] ++grammar --- content/u/blog/kubernetes-without-ingress/contents.lr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/u/blog/kubernetes-without-ingress/contents.lr b/content/u/blog/kubernetes-without-ingress/contents.lr index 59078ba..cfdbbf4 100644 --- a/content/u/blog/kubernetes-without-ingress/contents.lr +++ b/content/u/blog/kubernetes-without-ingress/contents.lr @@ -81,7 +81,7 @@ And simplifies your clusters a lot. ### NodePort -Let's have a look at the definition first again: +Let's first have a look at the definition again: ``` Exposes the Service on each Node's IP at a static port (the From dfd7ed90c1556a4c1acb19a9b45f8d2a0cedf432 Mon Sep 17 00:00:00 2001 From: Nico Schottelius Date: Wed, 9 Jun 2021 18:40:12 +0200 Subject: [PATCH 09/16] ++ecmp link --- content/u/blog/kubernetes-without-ingress/contents.lr | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/content/u/blog/kubernetes-without-ingress/contents.lr b/content/u/blog/kubernetes-without-ingress/contents.lr index cfdbbf4..ab046da 100644 --- a/content/u/blog/kubernetes-without-ingress/contents.lr +++ b/content/u/blog/kubernetes-without-ingress/contents.lr @@ -127,7 +127,8 @@ free in IPv6 only clusters: ## Load Balancing in IPv6 only clusters So what is the most easy way of reliable load balancing in network? -ECMP (equal cost multi path) comes to the mind right away. Given that +[ECMP (equal cost multi path)](https://en.wikipedia.org/wiki/Equal-cost_multi-path_routing) +comes to the mind right away. Given that kubernetes nodes can BGP peer with the network (upstream or the switches), this basically gives load balancing to the world for free: From f38688a4aa687ddcbc8fb6a6a5a4228b73027550 Mon Sep 17 00:00:00 2001 From: Nico Schottelius Date: Wed, 9 Jun 2021 18:42:10 +0200 Subject: [PATCH 10/16] ++chat signup --- content/u/blog/kubernetes-without-ingress/contents.lr | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/content/u/blog/kubernetes-without-ingress/contents.lr b/content/u/blog/kubernetes-without-ingress/contents.lr index ab046da..a7164e6 100644 --- a/content/u/blog/kubernetes-without-ingress/contents.lr +++ b/content/u/blog/kubernetes-without-ingress/contents.lr @@ -173,7 +173,9 @@ to jump through hoops. If you are interesting in continuing the discussion, we are there for you in -[the #hacking:ungleich.ch Matrix channel](https://chat.with.ungleich.ch). +**the #hacking:ungleich.ch Matrix channel** +[you can signup here if you don't have an +account](https://chat.with.ungleich.ch). Or if you are interested in an IPv6 only kubernetes cluster, drop a mail to **support**-at-**ungleich.ch**. From 74df18d1456750e641f9adb17b0d3fbf0f8995ba Mon Sep 17 00:00:00 2001 From: Nico Schottelius Date: Wed, 9 Jun 2021 18:44:13 +0200 Subject: [PATCH 11/16] ++icmp route --- content/u/blog/kubernetes-without-ingress/contents.lr | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/content/u/blog/kubernetes-without-ingress/contents.lr b/content/u/blog/kubernetes-without-ingress/contents.lr index a7164e6..fad6f6f 100644 --- a/content/u/blog/kubernetes-without-ingress/contents.lr +++ b/content/u/blog/kubernetes-without-ingress/contents.lr @@ -161,6 +161,16 @@ Table master6: ... ``` +Which results into the following kernel route: + +``` +2a0a:e5c0:13:e2::/108 proto bird metric 32 + nexthop via 2a0a:e5c0:13:0:224:81ff:fee0:db7a dev eth0 weight 1 + nexthop via 2a0a:e5c0:13:0:225:b3ff:fe20:3554 dev eth0 weight 1 + nexthop via 2a0a:e5c0:13:0:225:b3ff:fe20:3564 dev eth0 weight 1 + nexthop via 2a0a:e5c0:13:0:225:b3ff:fe20:38cc dev eth0 weight 1 pref medium +``` + ## TL;DR We know, a TL;DR at the end is not the right thing to do, but hey, we From 97d9ad7886f5cb0e4974c0f434cf05e61fc6b794 Mon Sep 17 00:00:00 2001 From: Nico Schottelius Date: Sun, 13 Jun 2021 20:39:22 +0200 Subject: [PATCH 12/16] [k8s] blog update, +dns --- .../contents.lr | 166 ++++++++++++++++++ .../kubernetes-without-ingress/contents.lr | 14 +- 2 files changed, 178 insertions(+), 2 deletions(-) create mode 100644 content/u/blog/kubernetes-making-dns-publicly-reachable/contents.lr diff --git a/content/u/blog/kubernetes-making-dns-publicly-reachable/contents.lr b/content/u/blog/kubernetes-making-dns-publicly-reachable/contents.lr new file mode 100644 index 0000000..0de0b75 --- /dev/null +++ b/content/u/blog/kubernetes-making-dns-publicly-reachable/contents.lr @@ -0,0 +1,166 @@ +title: Making kubernetes kube-dns publicly reachable +--- +pub_date: 2021-06-13 +--- +author: ungleich +--- +twitter_handle: ungleich +--- +_hidden: no +--- +_discoverable: no +--- +abstract: +Looking into IPv6 only DNS provided by kubernetes +--- +body: + +## Introduction + +If you have seen our +[article about running kubernetes +Ingress-less](/u/blog/kubernetes-without-ingress/), you are aware that +we are pushing IPv6 only kubernetes clusters at ungleich. + +Today, we are looking at making the "internal" kube-dns service world +reachable using IPv6 and global DNS servers. + +## The kubernetes DNS service + +If you have a look at your typical k8s cluster, you will notice that +you usually have two coredns pods running: + +``` +% kubectl -n kube-system get pods -l k8s-app=kube-dns +NAME READY STATUS RESTARTS AGE +coredns-558bd4d5db-gz5c7 1/1 Running 0 6d +coredns-558bd4d5db-hrzhz 1/1 Running 0 6d +``` + +These pods are usually served by the **kube-dns** service: + +``` +% kubectl -n kube-system get svc -l k8s-app=kube-dns +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +kube-dns ClusterIP 2a0a:e5c0:13:e2::a 53/UDP,53/TCP,9153/TCP 6d1h +``` + +As you can see, the kube-dns service is running on a publicly +reachable IPv6 address. + +## IPv6 only DNS + +IPv6 only DNS servers have one drawback: they cannot be reached via DNS +recursions, if the resolver is IPv4 only. + +At [ungleich we run a variety of +services](https://redmine.ungleich.ch/projects/open-infrastructure/wiki) +to make IPv6 only services usable in the real world. In case of DNS, +we are using **DNS forwarders**. They are acting similar to HTTP +proxies, but for DNS. + +So in our main DNS servers, dns1.ungleich.ch, dns2.ungleich.ch +and dns3.ungleich.ch we have added the following configuration: + +``` +zone "k8s.place7.ungleich.ch" { + type forward; + forward only; + forwarders { 2a0a:e5c0:13:e2::a; }; +}; +``` + +This tells the DNS servers to forward DNS queries that come in for +k8s.place7.ungleich.ch to **2a0a:e5c0:13:e2::a**. + +Additionally we have added **DNS delegation** in the +place7.ungleich.ch zone: + +``` +k8s NS dns1.ungleich.ch. +k8s NS dns2.ungleich.ch. +k8s NS dns3.ungleich.ch. +``` + +## Using the kubernetes DNS service in the wild + +With this configuration, we can now access IPv6 only +kubernetes services directly from the Internet. Let's first discover +the kube-dns service itself: + +``` +% dig kube-dns.kube-system.svc.k8s.place7.ungleich.ch. aaaa + +; <<>> DiG 9.16.16 <<>> kube-dns.kube-system.svc.k8s.place7.ungleich.ch. aaaa +;; global options: +cmd +;; Got answer: +;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 23274 +;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1 + +;; OPT PSEUDOSECTION: +; EDNS: version: 0, flags:; udp: 4096 +; COOKIE: f61925944f5218c9ac21e43960c64f254792e60f2b10f3f5 (good) +;; QUESTION SECTION: +;kube-dns.kube-system.svc.k8s.place7.ungleich.ch. IN AAAA + +;; ANSWER SECTION: +kube-dns.kube-system.svc.k8s.place7.ungleich.ch. 27 IN AAAA 2a0a:e5c0:13:e2::a + +;; AUTHORITY SECTION: +k8s.place7.ungleich.ch. 13 IN NS kube-dns.kube-system.svc.k8s.place7.ungleich.ch. + +;; Query time: 18 msec +;; SERVER: 192.168.4.188#53(192.168.4.188) +;; WHEN: Sun Jun 13 20:32:41 CEST 2021 +;; MSG SIZE rcvd: 146 +``` + +As you can see, the **kube-dns** service in the **kube-system** +namespace resolves to 2a0a:e5c0:13:e2::a, which is exactly what we +have configured. + +At the moment, there is also an etherpad test service +named "ungleich-etherpad" running: + +``` +% kubectl get svc -l app=ungleichetherpad +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +ungleich-etherpad ClusterIP 2a0a:e5c0:13:e2::b7db 9001/TCP 3d19h +``` + +Let's first verify that it resolves: + +``` +% dig +short ungleich-etherpad.default.svc.k8s.place7.ungleich.ch aaaa +2a0a:e5c0:13:e2::b7db +``` + +And if that works, well, then we should also be able to access the +service itself! + +``` +% curl -I http://ungleich-etherpad.default.svc.k8s.place7.ungleich.ch:9001/ +HTTP/1.1 200 OK +X-Powered-By: Express +X-UA-Compatible: IE=Edge,chrome=1 +Referrer-Policy: same-origin +Content-Type: text/html; charset=utf-8 +Content-Length: 6039 +ETag: W/"1797-Dq3+mr7XP0PQshikMNRpm5RSkGA" +Set-Cookie: express_sid=s%3AZGKdDe3FN1v5UPcS-7rsZW7CeloPrQ7p.VaL1V0M4780TBm8bT9hPVQMWPX5Lcte%2BzotO9Lsejlk; Path=/; HttpOnly; SameSite=Lax +Date: Sun, 13 Jun 2021 18:36:23 GMT +Connection: keep-alive +Keep-Alive: timeout=5 +``` + +(attention, this is a test service and might not be running when you +read this article at a later time) + +## More of this + +We are discussing +kubernetes and IPv6 related topics in +**the #hacking:ungleich.ch Matrix channel** +([you can signup here if you don't have an +account](https://chat.with.ungleich.ch)) and will post more about our +k8s journey in this blog. Stay tuned! diff --git a/content/u/blog/kubernetes-without-ingress/contents.lr b/content/u/blog/kubernetes-without-ingress/contents.lr index fad6f6f..3f8276e 100644 --- a/content/u/blog/kubernetes-without-ingress/contents.lr +++ b/content/u/blog/kubernetes-without-ingress/contents.lr @@ -39,6 +39,16 @@ So the ingress basically routes from outside to inside. But, in the IPv6 world, services are already publicly reachable. It just depends on your network policy. +### Update 2021-06-13: Ingress vs. Service + +As some people pointed out (thanks a lot!), a public service is +**not the same** as an Ingress. Ingress has also the possibility to +route based on layer 7 information like the path, domain name, etc. + +However, if all of the traffic from an Ingress points to a single +IPv6 HTTP/HTTPS Service, effectively the IPv6 service will do the +same, with one hop less. + ## Services Let's have a look at how services in IPv6 only clusters look like: @@ -51,8 +61,8 @@ nginx-service ClusterIP 2a0a:e5c0:13:e2::3607 5432/TCP 19h ... ``` -All these services are world reachable, so a theorethical ingress does -actually not do any work. Services are routed to the pods as usual. +All these services are world reachable, depending on your network +policy. ## ServiceTypes From aa2b780895403275a3940574977c1c438aeedd6d Mon Sep 17 00:00:00 2001 From: Nico Schottelius Date: Sun, 13 Jun 2021 20:44:18 +0200 Subject: [PATCH 13/16] ++discoverable --- .../u/blog/kubernetes-making-dns-publicly-reachable/contents.lr | 2 +- content/u/blog/kubernetes-without-ingress/contents.lr | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/content/u/blog/kubernetes-making-dns-publicly-reachable/contents.lr b/content/u/blog/kubernetes-making-dns-publicly-reachable/contents.lr index 0de0b75..f8dca6e 100644 --- a/content/u/blog/kubernetes-making-dns-publicly-reachable/contents.lr +++ b/content/u/blog/kubernetes-making-dns-publicly-reachable/contents.lr @@ -8,7 +8,7 @@ twitter_handle: ungleich --- _hidden: no --- -_discoverable: no +_discoverable: yes --- abstract: Looking into IPv6 only DNS provided by kubernetes diff --git a/content/u/blog/kubernetes-without-ingress/contents.lr b/content/u/blog/kubernetes-without-ingress/contents.lr index 3f8276e..370cbe9 100644 --- a/content/u/blog/kubernetes-without-ingress/contents.lr +++ b/content/u/blog/kubernetes-without-ingress/contents.lr @@ -8,7 +8,7 @@ twitter_handle: ungleich --- _hidden: no --- -_discoverable: no +_discoverable: yes --- abstract: From 4a6bebe069a28a1c832274e9485da06cedb00673 Mon Sep 17 00:00:00 2001 From: Nico Schottelius Date: Sun, 13 Jun 2021 20:53:28 +0200 Subject: [PATCH 14/16] Cut off the nameserver details --- .../kubernetes-making-dns-publicly-reachable/contents.lr | 5 ----- 1 file changed, 5 deletions(-) diff --git a/content/u/blog/kubernetes-making-dns-publicly-reachable/contents.lr b/content/u/blog/kubernetes-making-dns-publicly-reachable/contents.lr index f8dca6e..ce32c8c 100644 --- a/content/u/blog/kubernetes-making-dns-publicly-reachable/contents.lr +++ b/content/u/blog/kubernetes-making-dns-publicly-reachable/contents.lr @@ -108,11 +108,6 @@ kube-dns.kube-system.svc.k8s.place7.ungleich.ch. 27 IN AAAA 2a0a:e5c0:13:e2::a ;; AUTHORITY SECTION: k8s.place7.ungleich.ch. 13 IN NS kube-dns.kube-system.svc.k8s.place7.ungleich.ch. - -;; Query time: 18 msec -;; SERVER: 192.168.4.188#53(192.168.4.188) -;; WHEN: Sun Jun 13 20:32:41 CEST 2021 -;; MSG SIZE rcvd: 146 ``` As you can see, the **kube-dns** service in the **kube-system** From 617db5a79e155c1d2ac014fc1df95889ae363075 Mon Sep 17 00:00:00 2001 From: Nico Schottelius Date: Sun, 13 Jun 2021 21:05:22 +0200 Subject: [PATCH 15/16] ++image --- assets/u/image/k8s-v6-v4-dns.png | Bin 0 -> 89724 bytes .../contents.lr | 27 ++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 assets/u/image/k8s-v6-v4-dns.png diff --git a/assets/u/image/k8s-v6-v4-dns.png b/assets/u/image/k8s-v6-v4-dns.png new file mode 100644 index 0000000000000000000000000000000000000000..eab1caff0fb17de9c880171c3ec5b04f794550ea GIT binary patch literal 89724 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 Date: Sun, 13 Jun 2021 21:41:06 +0200 Subject: [PATCH 16/16] ++security Signed-off-by: Nico Schottelius --- .../contents.lr | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/content/u/blog/kubernetes-making-dns-publicly-reachable/contents.lr b/content/u/blog/kubernetes-making-dns-publicly-reachable/contents.lr index 0970ed0..39e7e2a 100644 --- a/content/u/blog/kubernetes-making-dns-publicly-reachable/contents.lr +++ b/content/u/blog/kubernetes-making-dns-publicly-reachable/contents.lr @@ -178,6 +178,45 @@ approaches: ![](/u/image/k8s-v6-v4-dns.png) +## Does this make sense? + +That clearly depends on your use-case. If you want your service DNS +records to be publicly accessible, then the clear answer is yes. + +If your cluster services are intended to be internal only +(see [previous blog post](/u/blog/kubernetes-without-ingress/), then +exposing the DNS service to the world might not be the best option. + +## Note on security + +CoreDNS inside kubernetes is by default configured to allow resolving +for *any* client that can reach it. Thus if you make your kube-dns +service world reachable, you also turn it into an open resolver. + +At the time of writing this blog article, the following coredns +configuration **does NOT** correctly block requests: + +``` + Corefile: | + .:53 { + acl k8s.place7.ungleich.ch { + allow net ::/0 + } + acl . { + allow net 2a0a:e5c0:13::/48 + block + } + forward . /etc/resolv.conf { + max_concurrent 1000 + } +... +``` + +Until this is solved, we recommend to place a firewall before your +public kube-dns service to only allow requests from the forwarding DNS +servers. + + ## More of this We are discussing