at 24.11-pre 7.2 kB view raw
1import ../make-test-python.nix ( 2 { 3 pkgs, 4 lib, 5 k3s, 6 ... 7 }: 8 let 9 imageEnv = pkgs.buildEnv { 10 name = "k3s-pause-image-env"; 11 paths = with pkgs; [ 12 tini 13 bashInteractive 14 coreutils 15 socat 16 ]; 17 }; 18 pauseImage = pkgs.dockerTools.streamLayeredImage { 19 name = "test.local/pause"; 20 tag = "local"; 21 contents = imageEnv; 22 config.Entrypoint = [ 23 "/bin/tini" 24 "--" 25 "/bin/sleep" 26 "inf" 27 ]; 28 }; 29 # A daemonset that responds 'server' on port 8000 30 networkTestDaemonset = pkgs.writeText "test.yml" '' 31 apiVersion: apps/v1 32 kind: DaemonSet 33 metadata: 34 name: test 35 labels: 36 name: test 37 spec: 38 selector: 39 matchLabels: 40 name: test 41 template: 42 metadata: 43 labels: 44 name: test 45 spec: 46 containers: 47 - name: test 48 image: test.local/pause:local 49 imagePullPolicy: Never 50 resources: 51 limits: 52 memory: 20Mi 53 command: ["socat", "TCP4-LISTEN:8000,fork", "EXEC:echo server"] 54 ''; 55 tokenFile = pkgs.writeText "token" "p@s$w0rd"; 56 in 57 { 58 name = "${k3s.name}-multi-node"; 59 60 nodes = { 61 server = 62 { pkgs, ... }: 63 { 64 environment.systemPackages = with pkgs; [ 65 gzip 66 jq 67 ]; 68 # k3s uses enough resources the default vm fails. 69 virtualisation.memorySize = 1536; 70 virtualisation.diskSize = 4096; 71 72 services.k3s = { 73 inherit tokenFile; 74 enable = true; 75 role = "server"; 76 package = k3s; 77 clusterInit = true; 78 extraFlags = builtins.toString [ 79 "--disable" 80 "coredns" 81 "--disable" 82 "local-storage" 83 "--disable" 84 "metrics-server" 85 "--disable" 86 "servicelb" 87 "--disable" 88 "traefik" 89 "--node-ip" 90 "192.168.1.1" 91 "--pause-image" 92 "test.local/pause:local" 93 ]; 94 }; 95 networking.firewall.allowedTCPPorts = [ 96 2379 97 2380 98 6443 99 ]; 100 networking.firewall.allowedUDPPorts = [ 8472 ]; 101 networking.firewall.trustedInterfaces = [ "flannel.1" ]; 102 networking.useDHCP = false; 103 networking.defaultGateway = "192.168.1.1"; 104 networking.interfaces.eth1.ipv4.addresses = pkgs.lib.mkForce [ 105 { 106 address = "192.168.1.1"; 107 prefixLength = 24; 108 } 109 ]; 110 }; 111 112 server2 = 113 { pkgs, ... }: 114 { 115 environment.systemPackages = with pkgs; [ 116 gzip 117 jq 118 ]; 119 virtualisation.memorySize = 1536; 120 virtualisation.diskSize = 4096; 121 122 services.k3s = { 123 inherit tokenFile; 124 enable = true; 125 serverAddr = "https://192.168.1.1:6443"; 126 clusterInit = false; 127 extraFlags = builtins.toString [ 128 "--disable" 129 "coredns" 130 "--disable" 131 "local-storage" 132 "--disable" 133 "metrics-server" 134 "--disable" 135 "servicelb" 136 "--disable" 137 "traefik" 138 "--node-ip" 139 "192.168.1.3" 140 "--pause-image" 141 "test.local/pause:local" 142 ]; 143 }; 144 networking.firewall.allowedTCPPorts = [ 145 2379 146 2380 147 6443 148 ]; 149 networking.firewall.allowedUDPPorts = [ 8472 ]; 150 networking.firewall.trustedInterfaces = [ "flannel.1" ]; 151 networking.useDHCP = false; 152 networking.defaultGateway = "192.168.1.3"; 153 networking.interfaces.eth1.ipv4.addresses = pkgs.lib.mkForce [ 154 { 155 address = "192.168.1.3"; 156 prefixLength = 24; 157 } 158 ]; 159 }; 160 161 agent = 162 { pkgs, ... }: 163 { 164 virtualisation.memorySize = 1024; 165 virtualisation.diskSize = 2048; 166 services.k3s = { 167 inherit tokenFile; 168 enable = true; 169 role = "agent"; 170 serverAddr = "https://192.168.1.3:6443"; 171 extraFlags = lib.concatStringsSep " " [ 172 "--pause-image" 173 "test.local/pause:local" 174 "--node-ip" 175 "192.168.1.2" 176 ]; 177 }; 178 networking.firewall.allowedTCPPorts = [ 6443 ]; 179 networking.firewall.allowedUDPPorts = [ 8472 ]; 180 networking.firewall.trustedInterfaces = [ "flannel.1" ]; 181 networking.useDHCP = false; 182 networking.defaultGateway = "192.168.1.2"; 183 networking.interfaces.eth1.ipv4.addresses = pkgs.lib.mkForce [ 184 { 185 address = "192.168.1.2"; 186 prefixLength = 24; 187 } 188 ]; 189 }; 190 }; 191 192 meta.maintainers = k3s.meta.maintainers; 193 194 testScript = '' 195 machines = [server, server2, agent] 196 for m in machines: 197 m.start() 198 m.wait_for_unit("k3s") 199 200 is_aarch64 = "${toString pkgs.stdenv.isAarch64}" == "1" 201 202 # wait for the agent to show up 203 server.wait_until_succeeds("k3s kubectl get node agent") 204 205 for m in machines: 206 # Fix-Me: Tests fail for 'aarch64-linux' as: "CONFIG_CGROUP_FREEZER: missing (fail)" 207 if not is_aarch64: 208 m.succeed("k3s check-config") 209 m.succeed( 210 "${pauseImage} | k3s ctr image import -" 211 ) 212 213 server.succeed("k3s kubectl cluster-info") 214 # Also wait for our service account to show up; it takes a sec 215 server.wait_until_succeeds("k3s kubectl get serviceaccount default") 216 217 # Now create a pod on each node via a daemonset and verify they can talk to each other. 218 server.succeed("k3s kubectl apply -f ${networkTestDaemonset}") 219 server.wait_until_succeeds(f'[ "$(k3s kubectl get ds test -o json | jq .status.numberReady)" -eq {len(machines)} ]') 220 221 # Get pod IPs 222 pods = server.succeed("k3s kubectl get po -o json | jq '.items[].metadata.name' -r").splitlines() 223 pod_ips = [server.succeed(f"k3s kubectl get po {name} -o json | jq '.status.podIP' -cr").strip() for name in pods] 224 225 # Verify each server can ping each pod ip 226 for pod_ip in pod_ips: 227 server.succeed(f"ping -c 1 {pod_ip}") 228 agent.succeed(f"ping -c 1 {pod_ip}") 229 230 # Verify the pods can talk to each other 231 resp = server.wait_until_succeeds(f"k3s kubectl exec {pods[0]} -- socat TCP:{pod_ips[1]}:8000 -") 232 assert resp.strip() == "server" 233 resp = server.wait_until_succeeds(f"k3s kubectl exec {pods[1]} -- socat TCP:{pod_ips[0]}:8000 -") 234 assert resp.strip() == "server" 235 236 # Cleanup 237 server.succeed("k3s kubectl delete -f ${networkTestDaemonset}") 238 239 for m in machines: 240 m.shutdown() 241 ''; 242 } 243)