smoke-test.sh 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681
  1. #!/bin/bash
  2. # Copyright 2019 The Kubernetes Authors.
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. # A small smoke test to run against a just-deployed kube-up cluster with Windows
  16. # nodes. Performs checks such as:
  17. # 1) Verifying that all Windows nodes have status Ready.
  18. # 2) Verifying that no system pods are attempting to run on Windows nodes.
  19. # 3) Verifying pairwise connectivity between most of the following: Linux
  20. # pods, Windows pods, K8s services, and the Internet.
  21. # 4) Verifying that basic DNS resolution works in Windows pods.
  22. #
  23. # This script assumes that it is run from the root of the kubernetes repository.
  24. #
  25. # TODOs:
  26. # - Implement the node-to-pod checks.
  27. # - Capture stdout for each command to a file and only print it when the test
  28. # fails.
  29. # - Move copy-pasted code into reusable functions.
  30. # - Continue running all checks after one fails.
  31. # - Test service connectivity by running a test pod with an http server and
  32. # exposing it as a service (rather than curl-ing from existing system
  33. # services that don't serve http requests).
  34. # - Add test retries for transient errors, such as:
  35. # "error: unable to upgrade connection: Authorization error
  36. # (user=kube-apiserver, verb=create, resource=nodes, subresource=proxy)"
  37. # Override this to use a different kubectl binary.
  38. kubectl=kubectl
  39. linux_deployment_timeout=60
  40. windows_deployment_timeout=300
  41. output_file=/tmp/k8s-smoke-test.out
  42. function check_windows_nodes_are_ready {
  43. # kubectl filtering is the worst.
  44. statuses=$(${kubectl} get nodes -l kubernetes.io/os=windows \
  45. -o jsonpath='{.items[*].status.conditions[?(@.type=="Ready")].status}')
  46. for status in $statuses; do
  47. if [[ $status == "False" ]]; then
  48. echo "ERROR: some Windows node has status != Ready"
  49. echo "kubectl get nodes -l kubernetes.io/os=windows"
  50. ${kubectl} get nodes -l kubernetes.io/os=windows
  51. exit 1
  52. fi
  53. done
  54. echo "Verified that all Windows nodes have status Ready"
  55. }
  56. function untaint_windows_nodes {
  57. # Untaint the windows nodes to allow test workloads without tolerations to be
  58. # scheduled onto them.
  59. WINDOWS_NODES=$(${kubectl} get nodes -l kubernetes.io/os=windows -o name)
  60. for node in $WINDOWS_NODES; do
  61. ${kubectl} taint node "$node" node.kubernetes.io/os:NoSchedule-
  62. done
  63. }
  64. function check_no_system_pods_on_windows_nodes {
  65. windows_system_pods=$(${kubectl} get pods --namespace kube-system \
  66. -o wide | grep -E "Pending|windows" | wc -w)
  67. if [[ $windows_system_pods -ne 0 ]]; then
  68. echo "ERROR: there are kube-system pods trying to run on Windows nodes"
  69. echo "kubectl get pods --namespace kube-system -o wide"
  70. ${kubectl} get pods --namespace kube-system -o wide
  71. exit 1
  72. fi
  73. echo "Verified that all system pods are running on Linux nodes"
  74. }
  75. linux_webserver_deployment=linux-nginx
  76. linux_webserver_pod_label=nginx
  77. linux_webserver_replicas=1
  78. function deploy_linux_webserver_pod {
  79. echo "Writing example deployment to $linux_webserver_deployment.yaml"
  80. cat <<EOF > $linux_webserver_deployment.yaml
  81. apiVersion: apps/v1
  82. kind: Deployment
  83. metadata:
  84. name: $linux_webserver_deployment
  85. labels:
  86. app: $linux_webserver_pod_label
  87. spec:
  88. replicas: $linux_webserver_replicas
  89. selector:
  90. matchLabels:
  91. app: $linux_webserver_pod_label
  92. template:
  93. metadata:
  94. labels:
  95. app: $linux_webserver_pod_label
  96. spec:
  97. containers:
  98. - name: nginx
  99. image: nginx:1.7.9
  100. nodeSelector:
  101. kubernetes.io/os: linux
  102. EOF
  103. if ! ${kubectl} create -f $linux_webserver_deployment.yaml; then
  104. echo "kubectl create -f $linux_webserver_deployment.yaml failed"
  105. exit 1
  106. fi
  107. timeout=$linux_deployment_timeout
  108. while [[ $timeout -gt 0 ]]; do
  109. echo "Waiting for $linux_webserver_replicas Linux $linux_webserver_pod_label pods to become Ready"
  110. statuses=$(${kubectl} get pods -l app=$linux_webserver_pod_label \
  111. -o jsonpath='{.items[*].status.conditions[?(@.type=="Ready")].status}' \
  112. | grep "True" | wc -w)
  113. if [[ $statuses -eq $linux_webserver_replicas ]]; then
  114. break
  115. else
  116. sleep 10
  117. (( timeout=timeout-10 ))
  118. fi
  119. done
  120. if [[ $timeout -gt 0 ]]; then
  121. echo "All $linux_webserver_pod_label pods became Ready"
  122. else
  123. echo "ERROR: Not all $linux_webserver_pod_label pods became Ready"
  124. echo "kubectl get pods -l app=$linux_webserver_pod_label"
  125. ${kubectl} get pods -l app=$linux_webserver_pod_label
  126. cleanup_deployments
  127. exit 1
  128. fi
  129. }
  130. # Returns the name of an arbitrary Linux webserver pod.
  131. function get_linux_webserver_pod_name {
  132. $kubectl get pods -l app=$linux_webserver_pod_label \
  133. -o jsonpath='{.items[0].metadata.name}'
  134. }
  135. # Returns the IP address of an arbitrary Linux webserver pod.
  136. function get_linux_webserver_pod_ip {
  137. $kubectl get pods -l app=$linux_webserver_pod_label \
  138. -o jsonpath='{.items[0].status.podIP}'
  139. }
  140. function undeploy_linux_webserver_pod {
  141. ${kubectl} delete deployment $linux_webserver_deployment
  142. }
  143. linux_command_deployment=linux-ubuntu
  144. linux_command_pod_label=ubuntu
  145. linux_command_replicas=1
  146. function deploy_linux_command_pod {
  147. echo "Writing example deployment to $linux_command_deployment.yaml"
  148. cat <<EOF > $linux_command_deployment.yaml
  149. apiVersion: apps/v1
  150. kind: Deployment
  151. metadata:
  152. name: $linux_command_deployment
  153. labels:
  154. app: $linux_command_pod_label
  155. spec:
  156. replicas: $linux_command_replicas
  157. selector:
  158. matchLabels:
  159. app: $linux_command_pod_label
  160. template:
  161. metadata:
  162. labels:
  163. app: $linux_command_pod_label
  164. spec:
  165. containers:
  166. - name: ubuntu
  167. image: ubuntu
  168. command: ["sleep", "123456"]
  169. nodeSelector:
  170. kubernetes.io/os: linux
  171. EOF
  172. if ! ${kubectl} create -f $linux_command_deployment.yaml; then
  173. echo "kubectl create -f $linux_command_deployment.yaml failed"
  174. exit 1
  175. fi
  176. timeout=$linux_deployment_timeout
  177. while [[ $timeout -gt 0 ]]; do
  178. echo "Waiting for $linux_command_replicas Linux $linux_command_pod_label pods to become Ready"
  179. statuses=$(${kubectl} get pods -l app=$linux_command_pod_label \
  180. -o jsonpath='{.items[*].status.conditions[?(@.type=="Ready")].status}' \
  181. | grep "True" | wc -w)
  182. if [[ $statuses -eq $linux_command_replicas ]]; then
  183. break
  184. else
  185. sleep 10
  186. (( timeout=timeout-10 ))
  187. fi
  188. done
  189. if [[ $timeout -gt 0 ]]; then
  190. echo "All $linux_command_pod_label pods became Ready"
  191. else
  192. echo "ERROR: Not all $linux_command_pod_label pods became Ready"
  193. echo "kubectl get pods -l app=$linux_command_pod_label"
  194. ${kubectl} get pods -l app=$linux_command_pod_label
  195. cleanup_deployments
  196. exit 1
  197. fi
  198. }
  199. # Returns the name of an arbitrary Linux command pod.
  200. function get_linux_command_pod_name {
  201. $kubectl get pods -l app=$linux_command_pod_label \
  202. -o jsonpath='{.items[0].metadata.name}'
  203. }
  204. # Returns the IP address of an arbitrary Linux command pod.
  205. function get_linux_command_pod_ip {
  206. $kubectl get pods -l app=$linux_command_pod_label \
  207. -o jsonpath='{.items[0].status.podIP}'
  208. }
  209. # Installs test executables (ping, curl) in the Linux command pod.
  210. # NOTE: this assumes that there is only one Linux "command pod".
  211. # TODO(pjh): fix this.
  212. function prepare_linux_command_pod {
  213. local linux_command_pod
  214. linux_command_pod="$(get_linux_command_pod_name)"
  215. echo "Installing test utilities in Linux command pod, may take a minute"
  216. $kubectl exec "$linux_command_pod" -- apt-get update > /dev/null
  217. $kubectl exec "$linux_command_pod" -- \
  218. apt-get install -y iputils-ping curl > /dev/null
  219. }
  220. function undeploy_linux_command_pod {
  221. ${kubectl} delete deployment $linux_command_deployment
  222. }
  223. windows_webserver_deployment=windows-agnhost
  224. windows_webserver_pod_label=agnhost
  225. # The default port for 'agnhost serve-hostname'. The documentation says that
  226. # this can be changed but the --port arg does not seem to work.
  227. windows_webserver_port=9376
  228. windows_webserver_replicas=1
  229. function deploy_windows_webserver_pod {
  230. echo "Writing example deployment to $windows_webserver_deployment.yaml"
  231. cat <<EOF > $windows_webserver_deployment.yaml
  232. # A multi-arch Windows container that runs an HTTP server on port
  233. # $windows_webserver_port that serves the container's hostname.
  234. # curl -s http://<pod_ip>:$windows_webserver_port
  235. apiVersion: apps/v1
  236. kind: Deployment
  237. metadata:
  238. name: $windows_webserver_deployment
  239. labels:
  240. app: $windows_webserver_pod_label
  241. spec:
  242. replicas: $windows_webserver_replicas
  243. selector:
  244. matchLabels:
  245. app: $windows_webserver_pod_label
  246. template:
  247. metadata:
  248. labels:
  249. app: $windows_webserver_pod_label
  250. spec:
  251. containers:
  252. - name: agnhost
  253. image: e2eteam/agnhost:2.8
  254. args:
  255. - serve-hostname
  256. nodeSelector:
  257. kubernetes.io/os: windows
  258. tolerations:
  259. - effect: NoSchedule
  260. key: node.kubernetes.io/os
  261. operator: Equal
  262. value: windows
  263. EOF
  264. if ! ${kubectl} create -f $windows_webserver_deployment.yaml; then
  265. echo "kubectl create -f $windows_webserver_deployment.yaml failed"
  266. exit 1
  267. fi
  268. timeout=$windows_deployment_timeout
  269. while [[ $timeout -gt 0 ]]; do
  270. echo "Waiting for $windows_webserver_replicas Windows $windows_webserver_pod_label pods to become Ready"
  271. statuses=$(${kubectl} get pods -l app=$windows_webserver_pod_label \
  272. -o jsonpath='{.items[*].status.conditions[?(@.type=="Ready")].status}' \
  273. | grep "True" | wc -w)
  274. if [[ $statuses -eq $windows_webserver_replicas ]]; then
  275. break
  276. else
  277. sleep 10
  278. (( timeout=timeout-10 ))
  279. fi
  280. done
  281. if [[ $timeout -gt 0 ]]; then
  282. echo "All $windows_webserver_pod_label pods became Ready"
  283. else
  284. echo "ERROR: Not all $windows_webserver_pod_label pods became Ready"
  285. echo "kubectl get pods -l app=$windows_webserver_pod_label"
  286. ${kubectl} get pods -l app=$windows_webserver_pod_label
  287. cleanup_deployments
  288. exit 1
  289. fi
  290. }
  291. function get_windows_webserver_pod_name {
  292. $kubectl get pods -l app=$windows_webserver_pod_label \
  293. -o jsonpath='{.items[0].metadata.name}'
  294. }
  295. function get_windows_webserver_pod_ip {
  296. $kubectl get pods -l app=$windows_webserver_pod_label \
  297. -o jsonpath='{.items[0].status.podIP}'
  298. }
  299. function undeploy_windows_webserver_pod {
  300. ${kubectl} delete deployment $windows_webserver_deployment
  301. }
  302. windows_command_deployment=windows-powershell
  303. windows_command_pod_label=powershell
  304. windows_command_replicas=1
  305. # Deploys a multi-arch Windows pod capable of running PowerShell.
  306. function deploy_windows_command_pod {
  307. echo "Writing example deployment to $windows_command_deployment.yaml"
  308. cat <<EOF > $windows_command_deployment.yaml
  309. apiVersion: apps/v1
  310. kind: Deployment
  311. metadata:
  312. name: $windows_command_deployment
  313. labels:
  314. app: $windows_command_pod_label
  315. spec:
  316. replicas: $windows_command_replicas
  317. selector:
  318. matchLabels:
  319. app: $windows_command_pod_label
  320. template:
  321. metadata:
  322. labels:
  323. app: $windows_command_pod_label
  324. spec:
  325. containers:
  326. - name: pause-win
  327. image: gcr.io/gke-release/pause-win:1.1.0
  328. nodeSelector:
  329. kubernetes.io/os: windows
  330. tolerations:
  331. - effect: NoSchedule
  332. key: node.kubernetes.io/os
  333. operator: Equal
  334. value: windows
  335. EOF
  336. if ! ${kubectl} create -f $windows_command_deployment.yaml; then
  337. echo "kubectl create -f $windows_command_deployment.yaml failed"
  338. exit 1
  339. fi
  340. timeout=$windows_deployment_timeout
  341. while [[ $timeout -gt 0 ]]; do
  342. echo "Waiting for $windows_command_replicas Windows $windows_command_pod_label pods to become Ready"
  343. statuses=$(${kubectl} get pods -l app=$windows_command_pod_label \
  344. -o jsonpath='{.items[*].status.conditions[?(@.type=="Ready")].status}' \
  345. | grep "True" | wc -w)
  346. if [[ $statuses -eq $windows_command_replicas ]]; then
  347. break
  348. else
  349. sleep 10
  350. (( timeout=timeout-10 ))
  351. fi
  352. done
  353. if [[ $timeout -gt 0 ]]; then
  354. echo "All $windows_command_pod_label pods became Ready"
  355. else
  356. echo "ERROR: Not all $windows_command_pod_label pods became Ready"
  357. echo "kubectl get pods -l app=$windows_command_pod_label"
  358. ${kubectl} get pods -l app=$windows_command_pod_label
  359. cleanup_deployments
  360. exit 1
  361. fi
  362. }
  363. function get_windows_command_pod_name {
  364. $kubectl get pods -l app=$windows_command_pod_label \
  365. -o jsonpath='{.items[0].metadata.name}'
  366. }
  367. function get_windows_command_pod_ip {
  368. $kubectl get pods -l app=$windows_command_pod_label \
  369. -o jsonpath='{.items[0].status.podIP}'
  370. }
  371. function undeploy_windows_command_pod {
  372. ${kubectl} delete deployment $windows_command_deployment
  373. }
  374. function test_linux_node_to_linux_pod {
  375. echo "TODO: ${FUNCNAME[0]}"
  376. }
  377. function test_linux_node_to_windows_pod {
  378. echo "TODO: ${FUNCNAME[0]}"
  379. }
  380. function test_linux_pod_to_linux_pod {
  381. echo "TEST: ${FUNCNAME[0]}"
  382. local linux_command_pod
  383. linux_command_pod="$(get_linux_command_pod_name)"
  384. local linux_webserver_pod_ip
  385. linux_webserver_pod_ip="$(get_linux_webserver_pod_ip)"
  386. if ! $kubectl exec "$linux_command_pod" -- curl -s -m 20 \
  387. "http://$linux_webserver_pod_ip" &> $output_file; then
  388. cleanup_deployments
  389. echo "Failing output: $(cat $output_file)"
  390. echo "FAILED: ${FUNCNAME[0]}"
  391. exit 1
  392. fi
  393. }
  394. # TODO(pjh): this test flakily fails on brand-new clusters, not sure why.
  395. # % Total % Received % Xferd Average Speed Time Time Time Current
  396. # Dload Upload Total Spent Left Speed
  397. # 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
  398. # curl: (6) Could not resolve host:
  399. # command terminated with exit code 6
  400. function test_linux_pod_to_windows_pod {
  401. echo "TEST: ${FUNCNAME[0]}"
  402. local linux_command_pod
  403. linux_command_pod="$(get_linux_command_pod_name)"
  404. local windows_webserver_pod_ip
  405. windows_webserver_pod_ip="$(get_windows_webserver_pod_ip)"
  406. if ! $kubectl exec "$linux_command_pod" -- curl -s -m 20 \
  407. "http://$windows_webserver_pod_ip:$windows_webserver_port" &> $output_file; then
  408. cleanup_deployments
  409. echo "Failing output: $(cat $output_file)"
  410. echo "FAILED: ${FUNCNAME[0]}"
  411. echo "This test seems to be flaky. TODO(pjh): investigate."
  412. exit 1
  413. fi
  414. }
  415. function test_linux_pod_to_internet {
  416. echo "TEST: ${FUNCNAME[0]}"
  417. local linux_command_pod
  418. linux_command_pod="$(get_linux_command_pod_name)"
  419. # A stable (hopefully) HTTP server provided by Cloudflare.
  420. local internet_ip="1.1.1.1"
  421. if ! $kubectl exec "$linux_command_pod" -- curl -s -m 20 \
  422. "http://$internet_ip" > $output_file; then
  423. cleanup_deployments
  424. echo "Failing output: $(cat $output_file)"
  425. echo "FAILED: ${FUNCNAME[0]}"
  426. exit 1
  427. fi
  428. }
  429. function test_linux_pod_to_k8s_service {
  430. echo "TEST: ${FUNCNAME[0]}"
  431. local linux_command_pod
  432. linux_command_pod="$(get_linux_command_pod_name)"
  433. local service="metrics-server"
  434. local service_ip
  435. service_ip=$($kubectl get service --namespace kube-system $service \
  436. -o jsonpath='{.spec.clusterIP}')
  437. local service_port
  438. service_port=$($kubectl get service --namespace kube-system $service \
  439. -o jsonpath='{.spec.ports[?(@.protocol=="TCP")].port}')
  440. echo "curl-ing $service address from Linux pod: $service_ip:$service_port"
  441. # curl-ing the metrics-server service downloads 14 bytes of unprintable binary
  442. # data and sets a return code of success (0).
  443. if ! $kubectl exec "$linux_command_pod" -- \
  444. curl -s -m 20 "http://$service_ip:$service_port" &> $output_file; then
  445. cleanup_deployments
  446. echo "Failing output: $(cat $output_file)"
  447. echo "FAILED: ${FUNCNAME[0]}"
  448. exit 1
  449. fi
  450. }
  451. function test_windows_node_to_linux_pod {
  452. echo "TODO: ${FUNCNAME[0]}"
  453. }
  454. function test_windows_node_to_windows_pod {
  455. echo "TODO: ${FUNCNAME[0]}"
  456. }
  457. # TODO(pjh): this test failed for me once with
  458. # error: unable to upgrade connection: container not found ("nettest")
  459. # Maybe the container crashed for some reason? Investigate if it happens more.
  460. #
  461. # TODO(pjh): another one-time failure:
  462. # error: unable to upgrade connection: Authorization error
  463. # (user=kube-apiserver, verb=create, resource=nodes, subresource=proxy)
  464. function test_windows_pod_to_linux_pod {
  465. echo "TEST: ${FUNCNAME[0]}"
  466. local windows_command_pod
  467. windows_command_pod="$(get_windows_command_pod_name)"
  468. local linux_webserver_pod_ip
  469. linux_webserver_pod_ip="$(get_linux_webserver_pod_ip)"
  470. if ! $kubectl exec "$windows_command_pod" -- powershell.exe \
  471. "curl -UseBasicParsing http://$linux_webserver_pod_ip" > \
  472. $output_file; then
  473. cleanup_deployments
  474. echo "Failing output: $(cat $output_file)"
  475. echo "FAILED: ${FUNCNAME[0]}"
  476. exit 1
  477. fi
  478. }
  479. function test_windows_pod_to_windows_pod {
  480. echo "TEST: ${FUNCNAME[0]}"
  481. local windows_command_pod
  482. windows_command_pod="$(get_windows_command_pod_name)"
  483. local windows_webserver_pod_ip
  484. windows_webserver_pod_ip="$(get_windows_webserver_pod_ip)"
  485. if ! $kubectl exec "$windows_command_pod" -- powershell.exe \
  486. "curl -UseBasicParsing http://$windows_webserver_pod_ip:$windows_webserver_port" \
  487. > $output_file; then
  488. cleanup_deployments
  489. echo "Failing output: $(cat $output_file)"
  490. echo "FAILED: ${FUNCNAME[0]}"
  491. exit 1
  492. fi
  493. }
  494. function test_windows_pod_to_internet {
  495. echo "TEST: ${FUNCNAME[0]}"
  496. local windows_command_pod
  497. windows_command_pod="$(get_windows_command_pod_name)"
  498. # A stable (hopefully) HTTP server provided by Cloudflare. If this ever stops
  499. # working, we can request from 8.8.8.8 (Google DNS) using https instead.
  500. local internet_ip="1.1.1.1"
  501. if ! $kubectl exec "$windows_command_pod" -- powershell.exe \
  502. "curl -UseBasicParsing http://$internet_ip" > $output_file; then
  503. cleanup_deployments
  504. echo "Failing output: $(cat $output_file)"
  505. echo "FAILED: ${FUNCNAME[0]}"
  506. exit 1
  507. fi
  508. }
  509. function test_windows_pod_to_k8s_service {
  510. echo "TEST: ${FUNCNAME[0]}"
  511. local windows_command_pod
  512. windows_command_pod="$(get_windows_command_pod_name)"
  513. local service="metrics-server"
  514. local service_ip
  515. service_ip=$($kubectl get service --namespace kube-system $service \
  516. -o jsonpath='{.spec.clusterIP}')
  517. local service_port
  518. service_port=$($kubectl get service --namespace kube-system $service \
  519. -o jsonpath='{.spec.ports[?(@.protocol=="TCP")].port}')
  520. local service_address="$service_ip:$service_port"
  521. echo "curl-ing $service address from Windows pod: $service_address"
  522. # curl-ing the metrics-server service results in a ServerProtocolViolation
  523. # ("The server committed a protocol violation. Section=ResponseStatusLine")
  524. # exception. Since we don't care about what the metrics-server actually gives
  525. # back to us, just that we can reach it, we check that we get the expected
  526. # exception code and not some other exception code.
  527. # TODO: it might be less fragile to check that we don't get the "Unable to
  528. # connect to the remote server" exception code (2) instead of specifically
  529. # expecting the protocol-violation exception code (11).
  530. if ! $kubectl exec "$windows_command_pod" -- powershell.exe \
  531. "\$result = try { \`
  532. curl -UseBasicParsing http://$service_address -ErrorAction Stop \`
  533. } catch [System.Net.WebException] { \`
  534. \$_ \`
  535. }; \`
  536. if ([int]\$result.Exception.Status -eq 11) { \`
  537. Write-Host \"curl $service_address got expected exception\"
  538. exit 0 \`
  539. } else { \`
  540. Write-Host \"curl $service_address got unexpected result/exception: \$result\"
  541. exit 1 \`
  542. }" > $output_file; then
  543. cleanup_deployments
  544. echo "Failing output: $(cat $output_file)"
  545. echo "FAILED: ${FUNCNAME[0]}"
  546. exit 1
  547. fi
  548. }
  549. function test_kube_dns_in_windows_pod {
  550. echo "TEST: ${FUNCNAME[0]}"
  551. local windows_command_pod
  552. windows_command_pod="$(get_windows_command_pod_name)"
  553. local service="kube-dns"
  554. local service_ip
  555. service_ip=$($kubectl get service --namespace kube-system $service \
  556. -o jsonpath='{.spec.clusterIP}')
  557. if ! $kubectl exec "$windows_command_pod" -- powershell.exe \
  558. "Resolve-DnsName www.bing.com -server $service_ip" > $output_file; then
  559. cleanup_deployments
  560. echo "Failing output: $(cat $output_file)"
  561. echo "FAILED: ${FUNCNAME[0]}"
  562. exit 1
  563. fi
  564. }
  565. function test_dns_just_works_in_windows_pod {
  566. echo "TEST: ${FUNCNAME[0]}"
  567. local windows_command_pod
  568. windows_command_pod="$(get_windows_command_pod_name)"
  569. if ! $kubectl exec "$windows_command_pod" -- powershell.exe \
  570. "curl -UseBasicParsing http://www.bing.com" > $output_file; then
  571. cleanup_deployments
  572. echo "Failing output: $(cat $output_file)"
  573. echo "FAILED: ${FUNCNAME[0]}"
  574. exit 1
  575. fi
  576. }
  577. function cleanup_deployments {
  578. undeploy_linux_webserver_pod
  579. undeploy_linux_command_pod
  580. undeploy_windows_webserver_pod
  581. undeploy_windows_command_pod
  582. }
  583. check_windows_nodes_are_ready
  584. untaint_windows_nodes
  585. check_no_system_pods_on_windows_nodes
  586. deploy_linux_webserver_pod
  587. deploy_linux_command_pod
  588. deploy_windows_webserver_pod
  589. deploy_windows_command_pod
  590. prepare_linux_command_pod
  591. echo ""
  592. test_linux_node_to_linux_pod
  593. test_linux_node_to_windows_pod
  594. test_linux_pod_to_linux_pod
  595. test_linux_pod_to_windows_pod
  596. test_linux_pod_to_k8s_service
  597. # Note: test_windows_node_to_k8s_service is not supported at this time.
  598. # https://docs.microsoft.com/en-us/virtualization/windowscontainers/kubernetes/common-problems#my-windows-node-cannot-access-my-services-using-the-service-ip
  599. test_windows_node_to_linux_pod
  600. test_windows_node_to_windows_pod
  601. test_windows_pod_to_linux_pod
  602. test_windows_pod_to_windows_pod
  603. test_windows_pod_to_internet
  604. test_windows_pod_to_k8s_service
  605. test_kube_dns_in_windows_pod
  606. test_dns_just_works_in_windows_pod
  607. echo ""
  608. cleanup_deployments
  609. echo "All tests passed!"
  610. exit 0