Eric Radman : a Journal

OSPF and DNS NodePort

After bootstrapping up a basic Kubernetes Lab, a dynamic routing protocol provides effective routing at all layers because each router and switch understands how to route traffic effectively

# ospfctl show rib
Destination          Nexthop           Path Type    Type      Cost    Uptime
192.168.0.4          192.168.2.4       Intra-Area   Router    20      04:47:00
192.168.2.0/24       192.168.2.3     C Intra-Area   Network   20      05:06:25
10.244.1.0/24        192.168.2.35      Type 2 ext   Network   20      04:16:00
10.244.2.0/24        192.168.2.36      Type 2 ext   Network   20      04:16:00
10.244.3.0/24        192.168.2.37      Type 2 ext   Network   20      04:16:00

To make name resolution work, we will configure a stub zone and port forwarding for DNS

$ traceroute -n registry.default.svc.mykube.local
traceroute to registry.default.svc.mykube.local (10.244.2.64), 64 hops max, 40 byte packets
1  192.168.3.3  8.261 ms  9.663 ms  10.46 ms
2  192.168.2.36  5.138 ms  4.086 ms  11.426 ms
3  10.244.2.64  10.057 ms  4.597 ms  5.223 ms

OpenBSD Router and OSPF, OSPFv3

OSPF can be run over any interface. Here we will advertise on the interface vlan2

# /etc/ospfd.conf
router-id 192.168.0.3

area 0.0.0.2 {
  interface vlan2 {
    metric 20
  }
}

The configuration for OSPFv3 (for IPv6) is exactly the same.

Juniper EX

One advantage of using a dynamic routing protocol is that core switching, as well as the router on the edge can route this traffic

set protocols ospf area 0.0.0.2 interface irb.82
set protocols ospf import into-ospf
set protocols ospf3 area 0.0.0.2 interface irb.82
set protocols ospf3 import into-ospf
set policy-options policy-statement into-ospf term static then accept

PicOS

Even small PicOS switches from fs.com have full routing support.

set protocols ospf area 0.0.0.2
set protocols ospf network 192.168.2.0/24 area "0.0.0.2"
set protocols ospf interface vlan-82
set protocols ospf6 area 0.0.0.2
set protocols ospf6 interface vlan-82 area "0.0.0.2"

Tie it all together by redistributing static routes

edit protocols static
    set route 10.244.1.0/24 next-hop 192.168.2.35
    set route 10.244.2.0/24 next-hop 192.168.2.36
    set route 10.244.3.0/24 next-hop 192.168.2.37

    set route fd00:f4:1::/64 next-hop fd00:52::23
    set route fd00:f4:2::/64 next-hop fd00:53::24
    set route fd00:f4:3::/64 next-hop fd00:53::25
  exit
exit

set protocols ospf redistribute static
set protocols ospf6 redistribute static

Forwarding DNS using a NodePort Sevice

Kubernetes allows a special kind of service to be defined that only modifies forwarding rules

apiVersion: v1
kind: Service
metadata:
  name: kube-dns-external
  namespace: kube-system
spec:
  selector:
    k8s-app: kube-dns
  type: NodePort
  ports:
  - name: dns-udp
    port: 53
    targetPort: 53
    nodePort: 30053
    protocol: UDP
  sessionAffinity: None
$ kubectl get svc --namespace kube-system
NAME                TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                  AGE
kube-dns            ClusterIP   10.96.0.10       <none>        53/UDP,53/TCP,9153/TCP   19h
kube-dns-external   NodePort    10.103.147.139   <none>        53:30053/UDP             19h

Unbound is now able to use any Kubernetes node to answer nameserver queries!

# unbound.conf
stub-zone:
    name: "svc.mykube.local"
    stub-addr: 192.168.2.35@30053
    stub-addr: 192.168.2.36@30053
    stub-addr: 192.168.2.37@30053