smoke-test.sh 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686
  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=180
  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 beta.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 beta.kubernetes.io/os=windows"
  50. ${kubectl} get nodes -l beta.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 beta.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. beta.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. beta.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-nettest
  224. windows_webserver_pod_label=nettest
  225. windows_webserver_replicas=1
  226. function deploy_windows_webserver_pod {
  227. echo "Writing example deployment to $windows_webserver_deployment.yaml"
  228. cat <<EOF > $windows_webserver_deployment.yaml
  229. # You can run a pod with the e2eteam/nettest:1.0 image (which should listen on
  230. # <podIP>:8080) and create another pod on a different node (linux would be
  231. # easier) to curl the http server:
  232. # curl http://<pod_ip>:8080/read
  233. apiVersion: apps/v1
  234. kind: Deployment
  235. metadata:
  236. name: $windows_webserver_deployment
  237. labels:
  238. app: $windows_webserver_pod_label
  239. spec:
  240. replicas: $windows_webserver_replicas
  241. selector:
  242. matchLabels:
  243. app: $windows_webserver_pod_label
  244. template:
  245. metadata:
  246. labels:
  247. app: $windows_webserver_pod_label
  248. spec:
  249. containers:
  250. - name: nettest
  251. image: e2eteam/nettest:1.0
  252. nodeSelector:
  253. beta.kubernetes.io/os: windows
  254. tolerations:
  255. - effect: NoSchedule
  256. key: node.kubernetes.io/os
  257. operator: Equal
  258. value: windows
  259. EOF
  260. if ! ${kubectl} create -f $windows_webserver_deployment.yaml; then
  261. echo "kubectl create -f $windows_webserver_deployment.yaml failed"
  262. exit 1
  263. fi
  264. timeout=$windows_deployment_timeout
  265. while [[ $timeout -gt 0 ]]; do
  266. echo "Waiting for $windows_webserver_replicas Windows $windows_webserver_pod_label pods to become Ready"
  267. statuses=$(${kubectl} get pods -l app=$windows_webserver_pod_label \
  268. -o jsonpath='{.items[*].status.conditions[?(@.type=="Ready")].status}' \
  269. | grep "True" | wc -w)
  270. if [[ $statuses -eq $windows_webserver_replicas ]]; then
  271. break
  272. else
  273. sleep 10
  274. (( timeout=timeout-10 ))
  275. fi
  276. done
  277. if [[ $timeout -gt 0 ]]; then
  278. echo "All $windows_webserver_pod_label pods became Ready"
  279. else
  280. echo "ERROR: Not all $windows_webserver_pod_label pods became Ready"
  281. echo "kubectl get pods -l app=$windows_webserver_pod_label"
  282. ${kubectl} get pods -l app=$windows_webserver_pod_label
  283. cleanup_deployments
  284. exit 1
  285. fi
  286. }
  287. function get_windows_webserver_pod_name {
  288. $kubectl get pods -l app=$windows_webserver_pod_label \
  289. -o jsonpath='{.items[0].metadata.name}'
  290. }
  291. function get_windows_webserver_pod_ip {
  292. $kubectl get pods -l app=$windows_webserver_pod_label \
  293. -o jsonpath='{.items[0].status.podIP}'
  294. }
  295. function undeploy_windows_webserver_pod {
  296. ${kubectl} delete deployment $windows_webserver_deployment
  297. }
  298. windows_command_deployment=windows-powershell
  299. windows_command_pod_label=powershell
  300. windows_command_replicas=1
  301. function deploy_windows_command_pod {
  302. echo "Writing example deployment to $windows_command_deployment.yaml"
  303. cat <<EOF > $windows_command_deployment.yaml
  304. apiVersion: apps/v1
  305. kind: Deployment
  306. metadata:
  307. name: $windows_command_deployment
  308. labels:
  309. app: $windows_command_pod_label
  310. spec:
  311. replicas: $windows_command_replicas
  312. selector:
  313. matchLabels:
  314. app: $windows_command_pod_label
  315. template:
  316. metadata:
  317. labels:
  318. app: $windows_command_pod_label
  319. spec:
  320. containers:
  321. - name: nettest
  322. image: e2eteam/nettest:1.0
  323. nodeSelector:
  324. beta.kubernetes.io/os: windows
  325. tolerations:
  326. - effect: NoSchedule
  327. key: node.kubernetes.io/os
  328. operator: Equal
  329. value: windows
  330. EOF
  331. if ! ${kubectl} create -f $windows_command_deployment.yaml; then
  332. echo "kubectl create -f $windows_command_deployment.yaml failed"
  333. exit 1
  334. fi
  335. timeout=$windows_deployment_timeout
  336. while [[ $timeout -gt 0 ]]; do
  337. echo "Waiting for $windows_command_replicas Windows $windows_command_pod_label pods to become Ready"
  338. statuses=$(${kubectl} get pods -l app=$windows_command_pod_label \
  339. -o jsonpath='{.items[*].status.conditions[?(@.type=="Ready")].status}' \
  340. | grep "True" | wc -w)
  341. if [[ $statuses -eq $windows_command_replicas ]]; then
  342. break
  343. else
  344. sleep 10
  345. (( timeout=timeout-10 ))
  346. fi
  347. done
  348. if [[ $timeout -gt 0 ]]; then
  349. echo "All $windows_command_pod_label pods became Ready"
  350. else
  351. echo "ERROR: Not all $windows_command_pod_label pods became Ready"
  352. echo "kubectl get pods -l app=$windows_command_pod_label"
  353. ${kubectl} get pods -l app=$windows_command_pod_label
  354. cleanup_deployments
  355. exit 1
  356. fi
  357. }
  358. function get_windows_command_pod_name {
  359. $kubectl get pods -l app=$windows_command_pod_label \
  360. -o jsonpath='{.items[0].metadata.name}'
  361. }
  362. function get_windows_command_pod_ip {
  363. $kubectl get pods -l app=$windows_command_pod_label \
  364. -o jsonpath='{.items[0].status.podIP}'
  365. }
  366. function undeploy_windows_command_pod {
  367. ${kubectl} delete deployment $windows_command_deployment
  368. }
  369. function test_linux_node_to_linux_pod {
  370. echo "TODO: ${FUNCNAME[0]}"
  371. }
  372. function test_linux_node_to_windows_pod {
  373. echo "TODO: ${FUNCNAME[0]}"
  374. }
  375. function test_linux_pod_to_linux_pod {
  376. echo "TEST: ${FUNCNAME[0]}"
  377. local linux_command_pod
  378. linux_command_pod="$(get_linux_command_pod_name)"
  379. local linux_webserver_pod_ip
  380. linux_webserver_pod_ip="$(get_linux_webserver_pod_ip)"
  381. if ! $kubectl exec "$linux_command_pod" -- curl -m 20 \
  382. "http://$linux_webserver_pod_ip" &> $output_file; then
  383. cleanup_deployments
  384. echo "Failing output: $(cat $output_file)"
  385. echo "FAILED: ${FUNCNAME[0]}"
  386. exit 1
  387. fi
  388. }
  389. # TODO(pjh): this test flakily fails on brand-new clusters, not sure why.
  390. # % Total % Received % Xferd Average Speed Time Time Time Current
  391. # Dload Upload Total Spent Left Speed
  392. # 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
  393. # curl: (6) Could not resolve host:
  394. # command terminated with exit code 6
  395. function test_linux_pod_to_windows_pod {
  396. echo "TEST: ${FUNCNAME[0]}"
  397. local linux_command_pod
  398. linux_command_pod="$(get_linux_command_pod_name)"
  399. local windows_webserver_pod_ip
  400. windows_webserver_pod_ip="$(get_windows_webserver_pod_ip)"
  401. if ! $kubectl exec "$linux_command_pod" -- curl -m 20 \
  402. "http://$windows_webserver_pod_ip:8080/read" &> $output_file; then
  403. cleanup_deployments
  404. echo "Failing output: $(cat $output_file)"
  405. echo "FAILED: ${FUNCNAME[0]}"
  406. echo "This test seems to be flaky. TODO(pjh): investigate."
  407. exit 1
  408. fi
  409. }
  410. function test_linux_pod_to_internet {
  411. echo "TEST: ${FUNCNAME[0]}"
  412. local linux_command_pod
  413. linux_command_pod="$(get_linux_command_pod_name)"
  414. local internet_ip="8.8.8.8" # Google DNS
  415. # This is expected to return 404 (not found).
  416. if ! $kubectl exec "$linux_command_pod" -- curl -m 20 \
  417. "http://$internet_ip" > $output_file; then
  418. cleanup_deployments
  419. echo "Failing output: $(cat $output_file)"
  420. echo "FAILED: ${FUNCNAME[0]}"
  421. exit 1
  422. fi
  423. }
  424. function test_linux_pod_to_k8s_service {
  425. echo "TEST: ${FUNCNAME[0]}"
  426. local linux_command_pod
  427. linux_command_pod="$(get_linux_command_pod_name)"
  428. local service="heapster"
  429. local service_ip
  430. service_ip=$($kubectl get service --namespace kube-system $service \
  431. -o jsonpath='{.spec.clusterIP}')
  432. local service_port
  433. service_port=$($kubectl get service --namespace kube-system $service \
  434. -o jsonpath='{.spec.ports[?(@.protocol=="TCP")].port}')
  435. echo "curl-ing $service address from Linux pod: $service_ip:$service_port"
  436. # curl-ing the heapster service results in an expected 404 response code. The
  437. # curl command does not set a failure return code in this case.
  438. if ! $kubectl exec "$linux_command_pod" -- \
  439. curl -m 20 "http://$service_ip:$service_port" &> $output_file; then
  440. cleanup_deployments
  441. echo "Failing output: $(cat $output_file)"
  442. echo "FAILED: ${FUNCNAME[0]}"
  443. exit 1
  444. fi
  445. }
  446. function test_windows_node_to_linux_pod {
  447. echo "TODO: ${FUNCNAME[0]}"
  448. }
  449. function test_windows_node_to_windows_pod {
  450. echo "TODO: ${FUNCNAME[0]}"
  451. }
  452. # TODO(pjh): this test failed for me once with
  453. # error: unable to upgrade connection: container not found ("nettest")
  454. # Maybe the container crashed for some reason? Investigate if it happens more.
  455. #
  456. # TODO(pjh): another one-time failure:
  457. # error: unable to upgrade connection: Authorization error
  458. # (user=kube-apiserver, verb=create, resource=nodes, subresource=proxy)
  459. function test_windows_pod_to_linux_pod {
  460. echo "TEST: ${FUNCNAME[0]}"
  461. local windows_command_pod
  462. windows_command_pod="$(get_windows_command_pod_name)"
  463. local linux_webserver_pod_ip
  464. linux_webserver_pod_ip="$(get_linux_webserver_pod_ip)"
  465. if ! $kubectl exec "$windows_command_pod" -- powershell.exe \
  466. "curl -UseBasicParsing http://$linux_webserver_pod_ip" > \
  467. $output_file; then
  468. cleanup_deployments
  469. echo "Failing output: $(cat $output_file)"
  470. echo "FAILED: ${FUNCNAME[0]}"
  471. exit 1
  472. fi
  473. }
  474. function test_windows_pod_to_windows_pod {
  475. echo "TEST: ${FUNCNAME[0]}"
  476. local windows_command_pod
  477. windows_command_pod="$(get_windows_command_pod_name)"
  478. local windows_webserver_pod_ip
  479. windows_webserver_pod_ip="$(get_windows_webserver_pod_ip)"
  480. if ! $kubectl exec "$windows_command_pod" -- powershell.exe \
  481. "curl -UseBasicParsing http://$windows_webserver_pod_ip:8080/read" \
  482. > $output_file; then
  483. cleanup_deployments
  484. echo "Failing output: $(cat $output_file)"
  485. echo "FAILED: ${FUNCNAME[0]}"
  486. exit 1
  487. fi
  488. }
  489. function test_windows_pod_to_internet {
  490. echo "TEST: ${FUNCNAME[0]}"
  491. local windows_command_pod
  492. windows_command_pod="$(get_windows_command_pod_name)"
  493. local internet_ip="8.8.8.8"
  494. # This snippet tests Internet connectivity without depending on DNS by
  495. # attempting to curl Google's well-known DNS IP, 8.8.8.8. On success we expect
  496. # to get back a 404 status code; on failure the response object will have a
  497. # status code of 0 or some other HTTP code.
  498. if ! $kubectl exec "$windows_command_pod" -- powershell.exe \
  499. "\$response = try { \`
  500. (curl -UseBasicParsing http://$internet_ip \`
  501. -ErrorAction Stop).BaseResponse \`
  502. } catch [System.Net.WebException] { \`
  503. \$_.Exception.Response \`
  504. }; \`
  505. \$statusCodeInt = [int]\$response.StatusCode; \`
  506. if (\$statusCodeInt -eq 404) { \`
  507. exit 0 \`
  508. } else { \`
  509. Write-Host \"curl $internet_ip got unexpected status code \$statusCodeInt\"
  510. exit 1 \`
  511. }" > $output_file; then
  512. cleanup_deployments
  513. echo "Failing output: $(cat $output_file)"
  514. echo "FAILED: ${FUNCNAME[0]}"
  515. exit 1
  516. fi
  517. }
  518. function test_windows_pod_to_k8s_service {
  519. echo "TEST: ${FUNCNAME[0]}"
  520. local windows_command_pod
  521. windows_command_pod="$(get_windows_command_pod_name)"
  522. local service="heapster"
  523. local service_ip
  524. service_ip=$($kubectl get service --namespace kube-system $service \
  525. -o jsonpath='{.spec.clusterIP}')
  526. local service_port
  527. service_port=$($kubectl get service --namespace kube-system $service \
  528. -o jsonpath='{.spec.ports[?(@.protocol=="TCP")].port}')
  529. local service_address="$service_ip:$service_port"
  530. echo "curl-ing $service address from Windows pod: $service_address"
  531. # Performing a web request to the heapster service results in an expected 404
  532. # response; this code snippet filters out the expected 404 from other status
  533. # codes that indicate failure.
  534. if ! $kubectl exec "$windows_command_pod" -- powershell.exe \
  535. "\$response = try { \`
  536. (curl -UseBasicParsing http://$service_address \`
  537. -ErrorAction Stop).BaseResponse \`
  538. } catch [System.Net.WebException] { \`
  539. \$_.Exception.Response \`
  540. }; \`
  541. \$statusCodeInt = [int]\$response.StatusCode; \`
  542. if (\$statusCodeInt -eq 404) { \`
  543. exit 0 \`
  544. } else { \`
  545. Write-Host \"curl $service_address got unexpected status code \$statusCodeInt\"
  546. exit 1 \`
  547. }" > $output_file; then
  548. cleanup_deployments
  549. echo "Failing output: $(cat $output_file)"
  550. echo "FAILED: ${FUNCNAME[0]}"
  551. exit 1
  552. fi
  553. }
  554. function test_kube_dns_in_windows_pod {
  555. echo "TEST: ${FUNCNAME[0]}"
  556. local windows_command_pod
  557. windows_command_pod="$(get_windows_command_pod_name)"
  558. local service="kube-dns"
  559. local service_ip
  560. service_ip=$($kubectl get service --namespace kube-system $service \
  561. -o jsonpath='{.spec.clusterIP}')
  562. if ! $kubectl exec "$windows_command_pod" -- powershell.exe \
  563. "Resolve-DnsName www.bing.com -server $service_ip" > $output_file; then
  564. cleanup_deployments
  565. echo "Failing output: $(cat $output_file)"
  566. echo "FAILED: ${FUNCNAME[0]}"
  567. exit 1
  568. fi
  569. }
  570. function test_dns_just_works_in_windows_pod {
  571. echo "TEST: ${FUNCNAME[0]}"
  572. local windows_command_pod
  573. windows_command_pod="$(get_windows_command_pod_name)"
  574. if ! $kubectl exec "$windows_command_pod" -- powershell.exe \
  575. "curl -UseBasicParsing http://www.bing.com" > $output_file; then
  576. cleanup_deployments
  577. echo "Failing output: $(cat $output_file)"
  578. echo "FAILED: ${FUNCNAME[0]}"
  579. exit 1
  580. fi
  581. }
  582. function cleanup_deployments {
  583. undeploy_linux_webserver_pod
  584. undeploy_linux_command_pod
  585. undeploy_windows_webserver_pod
  586. undeploy_windows_command_pod
  587. }
  588. check_windows_nodes_are_ready
  589. untaint_windows_nodes
  590. check_no_system_pods_on_windows_nodes
  591. deploy_linux_webserver_pod
  592. deploy_linux_command_pod
  593. deploy_windows_webserver_pod
  594. deploy_windows_command_pod
  595. prepare_linux_command_pod
  596. echo ""
  597. test_linux_node_to_linux_pod
  598. test_linux_node_to_windows_pod
  599. test_linux_pod_to_linux_pod
  600. test_linux_pod_to_windows_pod
  601. test_linux_pod_to_k8s_service
  602. # Note: test_windows_node_to_k8s_service is not supported at this time.
  603. # https://docs.microsoft.com/en-us/virtualization/windowscontainers/kubernetes/common-problems#my-windows-node-cannot-access-my-services-using-the-service-ip
  604. test_windows_node_to_linux_pod
  605. test_windows_node_to_windows_pod
  606. test_windows_pod_to_linux_pod
  607. test_windows_pod_to_windows_pod
  608. test_windows_pod_to_internet
  609. test_windows_pod_to_k8s_service
  610. test_kube_dns_in_windows_pod
  611. test_dns_just_works_in_windows_pod
  612. echo ""
  613. cleanup_deployments
  614. echo "All tests passed!"
  615. exit 0