{"version": 2, "width": 155, "height": 42, "timestamp": 1789167055, "idle_time_limit": 3.0, "env": {"SHELL": "/bin/bash", "TERM": "xterm-256color"}}
[1.658364, "o", "================================================\r\r\n"]
[1.65889, "o", "  iron-kernel v0.1.0 - x86_64\r\r\n"]
[1.659699, "o", "================================================\r\r\n"]
[1.659759, "o", "\r\r\n"]
[1.660721, "o", "Initramfs: phys 0x12f0000..0x1788800 (4818944 bytes)\r\r\n"]
[1.69124, "o", "Physical memory: 2093551 frames free (8177 MB)\r\r\n"]
[1.691895, "o", "Max physical address: 0x10000000000\r\r\n"]
[1.765094, "o", "New PML4 at phys 0x915000, switching...\r\r\n"]
[1.765823, "o", "Page tables switched. Identity map removed.\r\r\n"]
[1.766734, "o", "Heap initialized: 524288 KB at 0xffffc00000000000\r\r\n"]
[1.76763, "o", "wallclock: RTC UNIX time 1789167056\r\r\n"]
[1.768638, "o", "PCI devices:\r\r\n"]
[1.76985, "o", "  00:00.0 [8086:1237] class=06:00 bar0=0x00000000 irq=0 unknown\r\r\n"]
[1.771041, "o", "  00:01.0 [8086:7000] class=06:01 bar0=0x00000000 irq=0 unknown\r\r\n"]
[1.772248, "o", "  00:02.0 [1234:1111] class=03:00 bar0=0xfd000008 irq=0 QEMU VGA\r\r\n"]
[1.773786, "o", "  00:03.0 [1af4:1000] class=02:00 bar0=0x0000c081 irq=11 virtio-net (transitional)\r\r\n"]
[1.775334, "o", "  00:04.0 [1af4:1001] class=01:00 bar0=0x0000c001 irq=11 virtio-blk (transitional)\r\r\n"]
[1.776163, "o", "SMP: 1 CPUs detected (LAPIC IDs: [0])\r\r\n"]
[1.777043, "o", "LAPIC: id=0 version=0x14 base=0xfee00000\r\r\n"]
[1.777717, "o", "SMP: single CPU, no APs to boot\r\r\n"]
[1.783342, "o", "virtio-blk: initialized, 2097152 sectors (1024 MiB)\r\r\n"]
[1.78473, "o", "virtio-net: I/O base 0xc080, IRQ 11\r\r\n"]
[1.785681, "o", "virtio-net: MAC 52:54:00:12:34:56\r\r\n"]
[1.790251, "o", "virtio-net: initialized, IP 10.0.2.15\r\r\n"]
[1.791547, "o", "TCP/IP: stack initialized (10.0.2.15, gw 10.0.2.2, + lo 127.0.0.1)\r\r\n"]
[1.792357, "o", "nftables: filter + nat tables initialized\r\r\n"]
[1.793069, "o", "bridge: iron0 created, IP 172.17.0.1\r\r\n"]
[1.793698, "o", "veth: container networking ready\r\r\n"]
[1.794124, "o", "Hardware initialized.\r\r\n"]
[1.79415, "o", "\r\r\n"]
[1.862073, "o", "root: ext2 on virtio-blk (lazy)\r\r\n"]
[1.862801, "o", "VFS initialized.\r\r\n"]
[1.863777, "o", "ELF /init loaded: entry=0x401000 brk=0x404000\r\r\n"]
[1.866156, "o", "Init process created (PID 1).\r\r\n"]
[1.866205, "o", "\r\r\n"]
[1.866249, "o", "\r\r\r\n"]
[1.867336, "o", "iron-kernel — booting Debian 13 (trixie) userland\r\r\r\n"]
[1.867378, "o", "\r\r\r\n"]
[1.962857, "o", "iron-kernel: Debian GNU/Linux 13 (trixie) — Linux 0.1.0\r\r\r\n"]
[4.977595, "o", "\r\r\r\n"]
[4.979118, "o", "====================================================================\r\r\r\n"]
[4.980743, "o", "        iron-kernel  --  a Linux-syscall-compatible OS kernel, in Rust\r\r\r\n"]
[4.982353, "o", "        x86_64 . no_std . booted by GRUB/Multiboot2 . running in QEMU\r\r\r\n"]
[4.982418, "o", "\r\r\r\n"]
[4.984079, "o", "====================================================================\r\r\r\n"]
[7.987335, "o", "\r\r\r\n"]
[7.988537, "o", ">>> 1. A real kernel speaking the Linux system-call ABI\r\r\r\n"]
[7.988601, "o", "\r\r\r\n"]
[7.988953, "o", "  $ uname -a\r\r\r\n"]
[7.995167, "o", "Linux iron-kernel 0.1.0 0.1.0 x86_64 GNU/Linux\r\r\r\n"]
[9.997067, "o", "\r\r\r\n"]
[9.998281, "o", "  $ grep -E 'model name|flags' /proc/cpuinfo | head -2\r\r\r\n"]
[10.017784, "o", "model name\t: QEMU Virtual CPU\r\r\r\n"]
[10.022646, "o", "flags\t\t: fpu vme de pse tsc msr pae cx8 apic sep mtrr pge cmov pat pse36 clflush mmx fxsr sse sse2 syscall nx lm constant_tsc rep_good nopl cpuid pni cx16 sse4_1 sse4_2 x2apic popcnt aes xsave rdrand hypervisor lahf_lm\r\r\r\n"]
[12.036927, "o", "\r\r\r\n"]
[12.038059, "o", "  $ grep MemTotal /proc/meminfo; echo nproc=$(nproc)\r\r\r\n"]
[12.044355, "o", "MemTotal:      524288 kB\r\r\r\n"]
[12.052349, "o", "nproc=1\r\r\r\n"]
[15.067036, "o", "\r\r\r\n"]
[15.069111, "o", ">>> 2. Unmodified, dynamically-linked glibc userspace (ELF loader + ld.so + demand paging)\r\r\r\n"]
[15.069171, "o", "\r\r\r\n"]
[15.069865, "o", "  $ bash --version | head -1\r\r\r\n"]
[15.088952, "o", "GNU bash, version 5.2.37(1)-release (x86_64-pc-linux-gnu)\r\r\r\n"]
[17.086947, "o", "\r\r\r\n"]
[17.087845, "o", "  $ ls -l /lib/x86_64-linux-gnu/libc.so.6\r\r\r\n"]
[17.0968, "o", "-rwxr-xr-x 1 root root 1995216 Apr 27 20:09 /lib/x86_64-linux-gnu/libc.so.6\r\r\r\n"]
[20.106733, "o", "\r\r\r\n"]
[20.108239, "o", "====================================================================\r\r\r\n"]
[20.109814, "o", "   3. THE HEADLINE: a real kube-apiserver + kube-scheduler place a\r\r\r\n"]
[20.111521, "o", "      Deployment (replicas=2) on this node; both pods run and serve HTTP,\r\r\r\n"]
[20.113159, "o", "      and kube-proxy programs their ClusterIP Service into the kernel.\r\r\r\n"]
[20.113222, "o", "\r\r\r\n"]
[20.114801, "o", "====================================================================\r\r\r\n"]
[22.176553, "o", "\r\r\r\n"]
[22.178199, "o", ">>> Starting CRI-O, then a kubelet that registers node 'iron' with a REAL\r\r\r\n"]
[22.179882, "o", "    kube-apiserver over TLS (logs suppressed). The scheduler on the host\r\r\r\n"]
[22.18123, "o", "    then binds the Deployment's two pods to this node ...\r\r\r\n"]
[23.406582, "o", "    crio.sock: UP\r\r\r\n"]
[23.41083, "o", "    waiting for the 2 scheduler-placed pods to reach Running ...\r\r\r\n"]
[28.736426, "o", "pod-net: registered on-node pod IP 10.88.0.2\r\r\n"]
[28.816171, "o", "pod-net: registered on-node pod IP 10.88.0.3\r\r\n"]
[610.476226, "o", "\r\r\r\n"]
[610.477725, "o", ">>> Ask CRI-O what is running -- both Deployment replicas, via the CRI gRPC API:\r\r\r\n"]
[610.477784, "o", "\r\r\r\n"]
[610.479373, "o", "  $ crictl --runtime-endpoint unix:///var/run/crio/crio.sock ps 2>&1 | tail -3\r\r\r\n"]
[610.840711, "o", "CONTAINER           IMAGE                                                              CREATED             STATE               NAME                ATTEMPT             POD ID              POD                        NAMESPACE\r\r\r\n"]
[610.84476, "o", "2e43d87f222ea       c6348fa86ba0fb2108c9334f5fe913ddc6d853313e655891f133a0127c30099f   9 minutes ago       Running             httpd               0                   12b70cce486c3       iron-web-584b84dfc-mhm88   default\r\r\r\n"]
[610.848945, "o", "3103ac3a7e7fd       c6348fa86ba0fb2108c9334f5fe913ddc6d853313e655891f133a0127c30099f   9 minutes ago       Running             httpd               0                   163540b03099e       iron-web-584b84dfc-gwwfc   default\r\r\r\n"]
[613.935962, "o", "\r\r\r\n"]
[613.937584, "o", ">>> Their pod IPs (assigned by the CNI plugin), auto-registered as Service endpoints:\r\r\r\n"]
[613.937641, "o", "\r\r\r\n"]
[613.938218, "o", "  $ cat /proc/iron-pod 2>&1\r\r\r\n"]
[613.944557, "o", "10.88.0.3\r\r\r\n"]
[616.996087, "o", "\r\r\r\n"]
[616.997566, "o", ">>> Bring up a real kube-proxy (iptables mode); it watches the apiserver and\r\r\r\n"]
[616.999078, "o", "    programs the ClusterIP Service 10.96.0.212 into the kernel's netfilter:\r\r\r\n"]
[621.020029, "o", "iptables: table mangle replaced (8 entries -> 6 rules)\r\r\n"]
[621.060068, "o", "iptables: table nat replaced (7 entries -> 5 rules)\r\r\n"]
[621.171132, "o", "iptables: table filter replaced (6 entries -> 4 rules)\r\r\n"]
[621.396771, "o", "iptables: table filter replaced (8 entries -> 5 rules)\r\r\n"]
[621.4907, "o", "iptables: table filter replaced (9 entries -> 6 rules)\r\r\n"]
[621.601377, "o", "iptables: table filter replaced (10 entries -> 7 rules)\r\r\n"]
[621.639576, "o", "iptables: table filter replaced (12 entries -> 8 rules)\r\r\n"]
[621.710631, "o", "iptables: table filter replaced (13 entries -> 9 rules)\r\r\n"]
[621.749604, "o", "iptables: table filter replaced (15 entries -> 10 rules)\r\r\n"]
[621.821443, "o", "iptables: table filter replaced (16 entries -> 11 rules)\r\r\n"]
[621.92081, "o", "iptables: table filter replaced (17 entries -> 12 rules)\r\r\n"]
[621.959903, "o", "iptables: table filter replaced (19 entries -> 13 rules)\r\r\n"]
[622.03039, "o", "iptables: table filter replaced (20 entries -> 14 rules)\r\r\n"]
[622.05999, "o", "iptables: table filter replaced (22 entries -> 15 rules)\r\r\n"]
[622.130841, "o", "iptables: table filter replaced (23 entries -> 16 rules)\r\r\n"]
[622.241068, "o", "iptables: table filter replaced (24 entries -> 17 rules)\r\r\n"]
[622.340887, "o", "iptables: table filter replaced (25 entries -> 18 rules)\r\r\n"]
[622.379625, "o", "iptables: table nat replaced (9 entries -> 6 rules)\r\r\n"]
[622.450406, "o", "iptables: table nat replaced (10 entries -> 7 rules)\r\r\n"]
[622.550532, "o", "iptables: table nat replaced (11 entries -> 8 rules)\r\r\n"]
[622.579633, "o", "iptables: table nat replaced (13 entries -> 9 rules)\r\r\n"]
[622.64085, "o", "iptables: table nat replaced (14 entries -> 10 rules)\r\r\n"]
[622.669976, "o", "iptables: table filter replaced (27 entries -> 19 rules)\r\r\n"]
[622.749945, "o", "iptables: table filter replaced (28 entries -> 20 rules)\r\r\n"]
[622.860776, "o", "iptables: table filter replaced (29 entries -> 21 rules)\r\r\n"]
[622.999326, "o", "iptables: table filter replaced (34 entries -> 26 rules)\r\r\n"]
[623.047806, "o", "iptables: table nat replaced (60 entries -> 46 rules)\r\r\n"]
[627.964999, "o", "\r\r\r\n"]
[627.96675, "o", ">>> kube-proxy translated the Service into DNAT rules -- ClusterIP 10.96.0.212\r\r\r\n"]
[627.968323, "o", "    load-balanced across the two pod endpoints, all in the kernel's netfilter:\r\r\r\n"]
[627.968368, "o", "\r\r\r\n"]
[627.970495, "o", "  $ iptables-legacy -t nat -S 2>/dev/null | grep -iE 'KUBE-SVC-.*10.96.0.212|KUBE-SEP.*DNAT.*10.88.0' | head -4\r\r\r\n"]
[628.058912, "o", "-A KUBE-SEP-3W7QFELQKC3DA2HC -p tcp -m comment --comment \"default/iron-web:http\" -m tcp -j DNAT --to-destination 10.88.0.2:80\r\r\r\n"]
[628.061208, "o", "-A KUBE-SEP-QNAWR3JLQWKWDQ4B -p tcp -m comment --comment \"default/iron-web:http\" -m tcp -j DNAT --to-destination 10.88.0.3:80\r\r\r\n"]
[628.064301, "o", "-A KUBE-SVC-TXBB7R6JBB3MGL5K ! -s 10.88.0.0/16 -d 10.96.0.212/32 -p tcp -m comment --comment \"default/iron-web:http cluster IP\" -m tcp --dport 80 -j KUBE-MARK-MASQ\r\r\r\n"]
[631.124779, "o", "\r\r\r\n"]
[631.126301, "o", ">>> THE PAYOFF: 24 requests to the ClusterIP -- kube-proxy's rules DNAT each to a\r\r\r\n"]
[631.127854, "o", "    pod endpoint, the packet is hairpinned on-node and conntrack-reverse-NAT'd\r\r\r\n"]
[631.129419, "o", "    back. Every one returns 200 OK from a Deployment pod (by its own hostname):\r\r\r\n"]
[631.129476, "o", "\r\r\r\n"]
[639.426442, "o", "      200 OK  GET http://10.96.0.212:80/ -> 200 OK body=\"iron-web-584b84dfc-mhm88\\n\"  ->  24 requests\r\r\r\n"]
[639.427628, "o", "      (failures: 0 / 24  .  distinct pod backends hit: 1)\r\r\r\n"]
[644.563905, "o", "\r\r\r\n"]
[644.56516, "o", "====================================================================\r\r\r\n"]
[644.566616, "o", "   A real kube-apiserver + kube-scheduler placed a Deployment(replicas=2)\r\r\r\n"]
[644.568148, "o", "   on node 'iron'; CRI-O ran both pods; kube-proxy programmed their ClusterIP\r\r\r\n"]
[644.569617, "o", "   Service into the kernel's netfilter; and 24 curls to the ClusterIP were\r\r\r\n"]
[644.571142, "o", "   served 200 OK by the Deployment's pods through a DNAT + on-node hairpin +\r\r\r\n"]
[644.572731, "o", "   conntrack datapath -- all on an OS kernel written from scratch in Rust.\r\r\r\n"]
[644.572795, "o", "\r\r\r\n"]
[644.574117, "o", "====================================================================\r\r\r\n"]
[646.673736, "o", "\r\r\r\n"]
[646.674139, "o", "### DEMO COMPLETE ###\r\r\r\n"]
