Are Services in Kubernetes simply reverse proxies that allow a constant point of contact? - dns

I'm researching Kubernetes Services (that is one of the kinds of k8s components, much like Pods and ReplicaSets). They seem to function like reverse proxies, but I know k8s internally uses DNS, so perhaps they are some kind of load balancing DNS? Also it would somehow mean, that since a Pod can be relocated or exist on many nodes it couldn't simply be a Reverse Proxy since it too would need to be addressable, but share a single IP on many machines... (obviously struggling to imagine how they were built without looking directly at the source code -- yet).
What makes up a K8s Service? DNS + Reverse Proxy, or something more/less? Some kind of networking trick?

Regular ClusterIP services
Ensuring network connectivity for type: ClusterIP Services is the responsibility of the kube-proxy -- a component that typically runs on each and every node of your cluster. The kube-proxy does this by intercepting outgoing traffic from Pods on each node and filtering traffic targeted at service IPs. Since it is connected to the Kubernetes API, the kube-proxy can determine which Pod IPs are associated with each service IP and can forward the traffic accordingly.
Conceptually, the kube-proxy might be considered similar to a reverse proxy (hence the name), but typically uses IPtables rules (or, starting at Kubernetes 1.9 optionally IPVS). Each created service will result in a set of IPtables rules on every node that intercepts and forwards traffic targeted at the service IP to the respective Pod IPs (service IPs are purely virtual and exist only in these IPtables rules; nowhere in the entire cluster you will find an actual network interface holding that IP).
Load balancing is also implemented via IPtables rules (or IPVS). Load balancing always occurs on the source node that the traffic originates from.
Here's an example from the Debug Services section of the documentation:
u#node$ iptables-save | grep hostnames
-A KUBE-SEP-57KPRZ3JQVENLNBR -s 10.244.3.6/32 -m comment --comment "default/hostnames:" -j MARK --set-xmark 0x00004000/0x00004000
-A KUBE-SEP-57KPRZ3JQVENLNBR -p tcp -m comment --comment "default/hostnames:" -m tcp -j DNAT --to-destination 10.244.3.6:9376
-A KUBE-SEP-WNBA2IHDGP2BOBGZ -s 10.244.1.7/32 -m comment --comment "default/hostnames:" -j MARK --set-xmark 0x00004000/0x00004000
-A KUBE-SEP-WNBA2IHDGP2BOBGZ -p tcp -m comment --comment "default/hostnames:" -m tcp -j DNAT --to-destination 10.244.1.7:9376
-A KUBE-SEP-X3P2623AGDH6CDF3 -s 10.244.2.3/32 -m comment --comment "default/hostnames:" -j MARK --set-xmark 0x00004000/0x00004000
-A KUBE-SEP-X3P2623AGDH6CDF3 -p tcp -m comment --comment "default/hostnames:" -m tcp -j DNAT --to-destination 10.244.2.3:9376
-A KUBE-SERVICES -d 10.0.1.175/32 -p tcp -m comment --comment "default/hostnames: cluster IP" -m tcp --dport 80 -j KUBE-SVC-NWV5X2332I4OT4T3
-A KUBE-SVC-NWV5X2332I4OT4T3 -m comment --comment "default/hostnames:" -m statistic --mode random --probability 0.33332999982 -j KUBE-SEP-WNBA2IHDGP2BOBGZ
-A KUBE-SVC-NWV5X2332I4OT4T3 -m comment --comment "default/hostnames:" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-X3P2623AGDH6CDF3
-A KUBE-SVC-NWV5X2332I4OT4T3 -m comment --comment "default/hostnames:" -j KUBE-SEP-57KPRZ3JQVENLNBR
For more information, have a look at the Virtual IPs and Service Proxies section in the manual.
Headless services
Besides regular ClusterIP services, there are also Headless Services (which are declares by specifying the property clusterIP: None when creating the service). These will not use the kube-proxy; instead, their DNS hostname will directly resolve to all Pod IPs that are associated with the service. Load balancing is achieved via regular DNS round-robin.

For services and routing within the cluster mostly iptables except when you are explicitly using ipvs (which would partially use iptables) or something like Cillium (which allows you to plugin BFP). The kube-proxy in each node manages the iptable rules. More information on how the proxy modes here.
On the DNS side, Kubernetes runs either kube-dns (1.10 or older) or coredns (1.11 or newer) and essentially all services and pods get registered in the that DNS service for other pods/containers to find them. For example, a service will have an FQDN like this: my-service.my-namespace.svc.cluster.local More information on that here.

Related

Azure: How to set a default route without losing connectivity

Currently I have a Linux VM on Azure. I want to remove the default route (which is pointing to outside internet). However, if I do so I lose connectivity to the VM itself. How do I do this? I've looked into adding a load balancer to use inbound source NAT but it doesn't seem to work for me.
Thank you
So after looking heavily into Load Balancers and such, it seems I can't do this with any Azure Resources. Here's my solution: I create a lightweight VM to act as a router, attach it with a public IP, have it on the same private network as my Main VM. The lightweight VM is Linux with iptables routing rules to forward RDP packets to my main VM (copy from another stackoverflow thread):
iptables -t nat -A PREROUTING -p tcp --dport 3389 -j DNAT --to-destination <WINDOWS SERVER IP>
iptables -A FORWARD -p tcp --dport 3389 -j ACCEPT
iptables -t nat -A POSTROUTING -j MASQUERADE
So users would connect to the IP of the routingVM which would then forward to MainVM. Now you can delete the default routes in the mainVM without getting disconnected.

Point client domain to my domain

I have a website with subdomains for my clients (wildcard subdomain)
client1.test.com
client2.test.com
I want my clients to use their own domain If they want.
what kind of record needs to be added to point
client1.com => client1.test.com
shop.client1.com => client1.test.com
I´m using the free plan of cloudflare for www.test.com but I´m open to
change it if it can´t be done
CNAME records would work for that. You could also use A records to point to the same IP as test.com
You need modify the cname to redirect your client1 IP on their domain provider to client1.test.com
You need modify the cname to redirect your client2 IP on their domain provider to client2.test.com
CNAME setup on cloud flare is for paid plans only
https://support.cloudflare.com/hc/en-us/articles/200168706-How-do-I-do-CNAME-setup-
You might also want to check
https://support.cloudflare.com/hc/en-us/articles/200168826-Does-Cloudflare-support-wildcard-DNS-entries-
You simply need to understand DNS records and how they work. You can find a good resource for this here, the most important of which is 'A record' in your case.
In summary however, before your clients can point their own domain to your system, they will have to configure their domain host records to point to your server/IP address.
For you, you don't have to do anything in Cloudflare but on your server. Say you have configured your webserver to recognize client1.test.com but client1 decides to use a domain client1.com and shop.client1.com, you have to set your webserver block for client1.test.com to also recognize these two domains aliases in addition to the original subdomain.
With Nginx, this will look like:
Server {
...
ServerName client1.test.com shop.client1.com client1.com
...
You could take a look at this script if you are looking for how to automate this process.
Maybe you could use CNAME Record like this:
client1.com CNAME client1.test.com.
shop.client1.com CNAME client1.test.com.
The dot at the end is to tell the DNS not to complete your entry with the default-Domainname.
If you not must use an DNS to redirect, you also be free to use You even could do it by IPTables Forwarding. Good at this solution... you can decide which port will point to which ip... this way you could forward webserver to the Server of your Customer, but leave Mail at your server (for example)
Here how forward a port to another host that has an external IP:
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport $port -j LOG --log-prefix="PreRouting $port..:"
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport $port -j DNAT --to $ip:$port
sudo iptables -t nat -A POSTROUTING -j MASQUERADE
sudo iptables -A FORWARD -p tcp -i eth0 -o eth0 -s $ip --sport $port -j LOG --log-prefix="S Forward $port.."
sudo iptables -A FORWARD -p tcp -i eth0 -o eth0 -s $ip --sport $port -j ACCEPT
sudo iptables -A FORWARD -p tcp -i eth0 -o eth0 -d $ip --dport $port -j LOG --log-prefix="D Forward $port.."
sudo iptables -A FORWARD -p tcp -i eth0 -o eth0 -d $ip --dport $port -j ACCEPT
You also have to add this command to set on your network stack:
sudo sysctl -w net.ipv4.ip_forward=1
This will work in a default DENY IPTables setup.

Why i see DST="127.0.0.53" on -j REDIRECTed packets?

I am confused about situation in my NATed network. I start dnsmasq on router, with listen-address=192.168.100.1 and -p 5353 option for DNS port. Afterwards, i add iptables rule for hosts inside that network:
iptables -t nat -I PREROUTING -s 192.168.100.0/24 \
-d 192.168.100.1 -p udp --dport 53 -j REDIRECT --to-ports 5353
But this didn't work first time, since my INPUT policy is DROP: when i add this rule, everything starts to work:
iptables -I INPUT -p udp --dport 53 -d 127.0.0.53 -j ACCEPT
I discovered this address with help of -j LOG on my INPUT chain, where i saw packets dropped like SRC=127.0.0.1 DST=127.0.0.53 ..., when NATed host is trying to resolve hostname.
As i am writing automated script that generates correct netfilter rules for situation, i need to know from where this 127.0.0.53 could come from.
I see the same address in /etc/resolv.conf. But i don't understand who's routing this packet to this address when it is "redirected", if even close to understanding what happens.
systemd-resolved sets up a stub listener for dns requests locally on 127.0.0.53:53
try disabling it to proceed sudo systemctl disable systemd-resolved

In-kernel packet forwarding from one port to multiple ports

On a Linux-based system I need data incoming on a TCP port to be automatically redirected to other 50 local ports without going through user-space's send/recv. Each port needs to receive a copy of all incoming traffic. All ports are local to the same machine.
I've discarded the splice syscall due to the limit of one endpoint being a file. I guess that iptables is the right tool for this purpose, but I can't figure out the right syntax for this purpose. It should be something similar to:
iptables -t nat -A PREROUTING -p tcp --dport <in_port> -j REDIRECT --to-ports <out_port1>-<out_port50>
I wonder e.g. if the option -m multiport is needed.

Iptables or something to redirect IP in gateway (GNU/Linux)

Im writing a bash scripting to account traffic in my network server:
WAN:eth1 -> GNU/Linux Server:eth0 -> Users
The GNU/Linux server uses squid, bind, QoS, mysql, lighttpd.
After an IP exceed the established quota a new QoS rule is applied for that IP (user) too exist one "flag" to decide when is restored the IP counter to Zero.
Some IPs and subnets work without quotas, other gruop of ips/subnets work with new QoS after quota is exceeded, and now I wanna work with a third group with redirection after quota is exceeded.
When an IP exceed the established quota all http traffic must be redirected to host (lighttpd runing on GNU/Linux ) and DROP all other traffic generated for that IP. In webserver exist a webpage with: "You exceed your daily quote of traffic, please wait "x" hours or call to your provider to purchase an extra navigation package" or something like that.
Is possible using a chain, or how can I do that?.
The most topics that I found in Internet, are related to block all and create a new chain to let out to Internet (not work for me). And other redirect only IP by IP, but how can I create something that a "chain" and attach the IPs to must me redirected to can after restore that IPs easly?
Thanks for help and sorry for my poor English :S.
Are you looking for something like this?
iptables -t nat -A PREROUTING -s 192.168.100.66 -p tcp --dport 80 -j REDIRECT --to-ports 80
iptables -I INPUT 1 -i lo -s 192.168.100.66 -j ACCEPT
iptables -I INPUT 2 -i eth1 -d 192.168.100.66 -j DROP
This will redirect packets from 192.168.100.66 on port 80 to the local webserver on the loopback interface, allow that conversation, then reject all other packets being routed to 192.168.100.66 on the WAN interface.
To restore the connection back to normal you will want to delete those firewall entries:
iptables -t nat -D PREROUTING -s 192.168.100.66 -p tcp --dport 80 -j REDIRECT --to-ports 80
iptables -D INPUT -i lo -s 192.168.100.66 -j ACCEPT
iptables -D INPUT -i eth1 -d 192.168.100.66 -j DROP
Note that iptables itself (well, the xtables-addons extension set providing quota2) can already do the quota matching magic and you can (re)set the values through procfs, combined with REDIRECT as #resmon6 says:
-t nat -s user1addr -m quota2 --name user1 ! --quota 0 -j REDIRECT...
-t nat -s user2addr -m quota2 --name user2 ! --quota 0 -j REDIRECT...
The syntax is a arguably a little odd right now (0 is the initial value only and is independent from the runtime quota test involving the negational !. Noticing this just now, a patch may make it in to unroll this confusing syntax in the future).

Resources