validation_test.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. /*
  2. Copyright 2018 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package componentconfigs
  14. import (
  15. "strings"
  16. "testing"
  17. "time"
  18. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  19. "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
  20. kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
  21. kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config"
  22. kubeproxyconfig "k8s.io/kubernetes/pkg/proxy/apis/config"
  23. utilpointer "k8s.io/utils/pointer"
  24. )
  25. func TestValidateKubeProxyConfiguration(t *testing.T) {
  26. var tests = []struct {
  27. name string
  28. clusterConfig *kubeadm.ClusterConfiguration
  29. msg string
  30. expectErr bool
  31. }{
  32. {
  33. name: "valid config",
  34. clusterConfig: &kubeadm.ClusterConfiguration{
  35. ComponentConfigs: kubeadm.ComponentConfigs{
  36. KubeProxy: &kubeproxyconfig.KubeProxyConfiguration{
  37. BindAddress: "192.168.59.103",
  38. HealthzBindAddress: "0.0.0.0:10256",
  39. MetricsBindAddress: "127.0.0.1:10249",
  40. ClusterCIDR: "192.168.59.0/24",
  41. UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second},
  42. ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
  43. IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
  44. MasqueradeAll: true,
  45. SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
  46. MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
  47. },
  48. IPVS: kubeproxyconfig.KubeProxyIPVSConfiguration{
  49. SyncPeriod: metav1.Duration{Duration: 10 * time.Second},
  50. MinSyncPeriod: metav1.Duration{Duration: 5 * time.Second},
  51. },
  52. Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
  53. MaxPerCore: utilpointer.Int32Ptr(1),
  54. Min: utilpointer.Int32Ptr(1),
  55. TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
  56. TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
  57. },
  58. },
  59. },
  60. },
  61. expectErr: false,
  62. },
  63. {
  64. name: "invalid BindAddress",
  65. clusterConfig: &kubeadm.ClusterConfiguration{
  66. ComponentConfigs: kubeadm.ComponentConfigs{
  67. KubeProxy: &kubeproxyconfig.KubeProxyConfiguration{
  68. // only BindAddress is invalid
  69. BindAddress: "10.10.12.11:2000",
  70. HealthzBindAddress: "0.0.0.0:10256",
  71. MetricsBindAddress: "127.0.0.1:10249",
  72. ClusterCIDR: "192.168.59.0/24",
  73. UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second},
  74. ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
  75. IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
  76. MasqueradeAll: true,
  77. SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
  78. MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
  79. },
  80. IPVS: kubeproxyconfig.KubeProxyIPVSConfiguration{
  81. SyncPeriod: metav1.Duration{Duration: 10 * time.Second},
  82. MinSyncPeriod: metav1.Duration{Duration: 5 * time.Second},
  83. },
  84. Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
  85. MaxPerCore: utilpointer.Int32Ptr(1),
  86. Min: utilpointer.Int32Ptr(1),
  87. TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
  88. TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
  89. },
  90. },
  91. },
  92. },
  93. msg: "not a valid textual representation of an IP address",
  94. expectErr: true,
  95. },
  96. {
  97. name: "invalid HealthzBindAddress",
  98. clusterConfig: &kubeadm.ClusterConfiguration{
  99. ComponentConfigs: kubeadm.ComponentConfigs{
  100. KubeProxy: &kubeproxyconfig.KubeProxyConfiguration{
  101. BindAddress: "10.10.12.11",
  102. // only HealthzBindAddress is invalid
  103. HealthzBindAddress: "0.0.0.0",
  104. MetricsBindAddress: "127.0.0.1:10249",
  105. ClusterCIDR: "192.168.59.0/24",
  106. UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second},
  107. ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
  108. IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
  109. MasqueradeAll: true,
  110. SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
  111. MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
  112. },
  113. IPVS: kubeproxyconfig.KubeProxyIPVSConfiguration{
  114. SyncPeriod: metav1.Duration{Duration: 10 * time.Second},
  115. MinSyncPeriod: metav1.Duration{Duration: 5 * time.Second},
  116. },
  117. Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
  118. MaxPerCore: utilpointer.Int32Ptr(1),
  119. Min: utilpointer.Int32Ptr(1),
  120. TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
  121. TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
  122. },
  123. },
  124. },
  125. },
  126. msg: "must be IP:port",
  127. expectErr: true,
  128. },
  129. {
  130. name: "invalid MetricsBindAddress",
  131. clusterConfig: &kubeadm.ClusterConfiguration{
  132. ComponentConfigs: kubeadm.ComponentConfigs{
  133. KubeProxy: &kubeproxyconfig.KubeProxyConfiguration{
  134. BindAddress: "10.10.12.11",
  135. HealthzBindAddress: "0.0.0.0:12345",
  136. // only MetricsBindAddress is invalid
  137. MetricsBindAddress: "127.0.0.1",
  138. ClusterCIDR: "192.168.59.0/24",
  139. UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second},
  140. ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
  141. IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
  142. MasqueradeAll: true,
  143. SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
  144. MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
  145. },
  146. IPVS: kubeproxyconfig.KubeProxyIPVSConfiguration{
  147. SyncPeriod: metav1.Duration{Duration: 10 * time.Second},
  148. MinSyncPeriod: metav1.Duration{Duration: 5 * time.Second},
  149. },
  150. Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
  151. MaxPerCore: utilpointer.Int32Ptr(1),
  152. Min: utilpointer.Int32Ptr(1),
  153. TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
  154. TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
  155. },
  156. },
  157. },
  158. },
  159. msg: "must be IP:port",
  160. expectErr: true,
  161. },
  162. {
  163. name: "invalid ClusterCIDR",
  164. clusterConfig: &kubeadm.ClusterConfiguration{
  165. ComponentConfigs: kubeadm.ComponentConfigs{
  166. KubeProxy: &kubeproxyconfig.KubeProxyConfiguration{
  167. BindAddress: "10.10.12.11",
  168. HealthzBindAddress: "0.0.0.0:12345",
  169. MetricsBindAddress: "127.0.0.1:10249",
  170. // only ClusterCIDR is invalid
  171. ClusterCIDR: "192.168.59.0",
  172. UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second},
  173. ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
  174. IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
  175. MasqueradeAll: true,
  176. SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
  177. MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
  178. },
  179. IPVS: kubeproxyconfig.KubeProxyIPVSConfiguration{
  180. SyncPeriod: metav1.Duration{Duration: 10 * time.Second},
  181. MinSyncPeriod: metav1.Duration{Duration: 5 * time.Second},
  182. },
  183. Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
  184. MaxPerCore: utilpointer.Int32Ptr(1),
  185. Min: utilpointer.Int32Ptr(1),
  186. TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
  187. TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
  188. },
  189. },
  190. },
  191. },
  192. msg: "must be a valid CIDR block (e.g. 10.100.0.0/16)",
  193. expectErr: true,
  194. },
  195. {
  196. name: "invalid UDPIdleTimeout",
  197. clusterConfig: &kubeadm.ClusterConfiguration{
  198. ComponentConfigs: kubeadm.ComponentConfigs{
  199. KubeProxy: &kubeproxyconfig.KubeProxyConfiguration{
  200. BindAddress: "10.10.12.11",
  201. HealthzBindAddress: "0.0.0.0:12345",
  202. MetricsBindAddress: "127.0.0.1:10249",
  203. ClusterCIDR: "192.168.59.0/24",
  204. // only UDPIdleTimeout is invalid
  205. UDPIdleTimeout: metav1.Duration{Duration: -1 * time.Second},
  206. ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
  207. IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
  208. MasqueradeAll: true,
  209. SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
  210. MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
  211. },
  212. IPVS: kubeproxyconfig.KubeProxyIPVSConfiguration{
  213. SyncPeriod: metav1.Duration{Duration: 10 * time.Second},
  214. MinSyncPeriod: metav1.Duration{Duration: 5 * time.Second},
  215. },
  216. Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
  217. MaxPerCore: utilpointer.Int32Ptr(1),
  218. Min: utilpointer.Int32Ptr(1),
  219. TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
  220. TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
  221. },
  222. },
  223. },
  224. },
  225. msg: "must be greater than 0",
  226. expectErr: true,
  227. },
  228. {
  229. name: "invalid ConfigSyncPeriod",
  230. clusterConfig: &kubeadm.ClusterConfiguration{
  231. ComponentConfigs: kubeadm.ComponentConfigs{
  232. KubeProxy: &kubeproxyconfig.KubeProxyConfiguration{
  233. BindAddress: "10.10.12.11",
  234. HealthzBindAddress: "0.0.0.0:12345",
  235. MetricsBindAddress: "127.0.0.1:10249",
  236. ClusterCIDR: "192.168.59.0/24",
  237. UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second},
  238. // only ConfigSyncPeriod is invalid
  239. ConfigSyncPeriod: metav1.Duration{Duration: -1 * time.Second},
  240. IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
  241. MasqueradeAll: true,
  242. SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
  243. MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
  244. },
  245. IPVS: kubeproxyconfig.KubeProxyIPVSConfiguration{
  246. SyncPeriod: metav1.Duration{Duration: 10 * time.Second},
  247. MinSyncPeriod: metav1.Duration{Duration: 5 * time.Second},
  248. },
  249. Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
  250. MaxPerCore: utilpointer.Int32Ptr(1),
  251. Min: utilpointer.Int32Ptr(1),
  252. TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
  253. TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
  254. },
  255. },
  256. },
  257. },
  258. msg: "must be greater than 0",
  259. expectErr: true,
  260. },
  261. }
  262. for i, rt := range tests {
  263. t.Run(rt.name, func(t *testing.T) {
  264. err := ValidateKubeProxyConfiguration(rt.clusterConfig, nil).ToAggregate()
  265. if (err != nil) != rt.expectErr {
  266. t.Errorf("%d failed ValidateKubeProxyConfiguration: expected error %t, got error %t", i, rt.expectErr, err != nil)
  267. }
  268. if err != nil && !strings.Contains(err.Error(), rt.msg) {
  269. t.Errorf("%d failed ValidateKubeProxyConfiguration: unexpected error: %v, expected: %s", i, err, rt.msg)
  270. }
  271. })
  272. }
  273. }
  274. func TestValidateKubeletConfiguration(t *testing.T) {
  275. var tests = []struct {
  276. name string
  277. clusterConfig *kubeadm.ClusterConfiguration
  278. expectErr bool
  279. }{
  280. {
  281. name: "valid configuration",
  282. clusterConfig: &kubeadm.ClusterConfiguration{
  283. ComponentConfigs: kubeadm.ComponentConfigs{
  284. Kubelet: &kubeletconfig.KubeletConfiguration{
  285. CgroupsPerQOS: true,
  286. EnforceNodeAllocatable: []string{"pods", "system-reserved", "kube-reserved"},
  287. SystemReservedCgroup: "/system.slice",
  288. KubeReservedCgroup: "/kubelet.service",
  289. SystemCgroups: "",
  290. CgroupRoot: "",
  291. EventBurst: 10,
  292. EventRecordQPS: 5,
  293. HealthzPort: kubeadmconstants.KubeletHealthzPort,
  294. ImageGCHighThresholdPercent: 85,
  295. ImageGCLowThresholdPercent: 80,
  296. IPTablesDropBit: 15,
  297. IPTablesMasqueradeBit: 14,
  298. KubeAPIBurst: 10,
  299. KubeAPIQPS: 5,
  300. MaxOpenFiles: 1000000,
  301. MaxPods: 110,
  302. OOMScoreAdj: -999,
  303. PodsPerCore: 100,
  304. Port: 65535,
  305. ReadOnlyPort: 0,
  306. RegistryBurst: 10,
  307. RegistryPullQPS: 5,
  308. HairpinMode: "promiscuous-bridge",
  309. NodeLeaseDurationSeconds: 40,
  310. },
  311. },
  312. },
  313. expectErr: false,
  314. },
  315. {
  316. name: "invalid configuration",
  317. clusterConfig: &kubeadm.ClusterConfiguration{
  318. ComponentConfigs: kubeadm.ComponentConfigs{
  319. Kubelet: &kubeletconfig.KubeletConfiguration{
  320. CgroupsPerQOS: false,
  321. EnforceNodeAllocatable: []string{"pods", "system-reserved", "kube-reserved", "illegal-key"},
  322. SystemCgroups: "/",
  323. CgroupRoot: "",
  324. EventBurst: -10,
  325. EventRecordQPS: -10,
  326. HealthzPort: -10,
  327. ImageGCHighThresholdPercent: 101,
  328. ImageGCLowThresholdPercent: 101,
  329. IPTablesDropBit: -10,
  330. IPTablesMasqueradeBit: -10,
  331. KubeAPIBurst: -10,
  332. KubeAPIQPS: -10,
  333. MaxOpenFiles: -10,
  334. MaxPods: -10,
  335. OOMScoreAdj: -1001,
  336. PodsPerCore: -10,
  337. Port: 0,
  338. ReadOnlyPort: -10,
  339. RegistryBurst: -10,
  340. RegistryPullQPS: -10,
  341. },
  342. },
  343. },
  344. expectErr: true,
  345. },
  346. }
  347. for i, rt := range tests {
  348. t.Run(rt.name, func(t *testing.T) {
  349. err := ValidateKubeletConfiguration(rt.clusterConfig, nil).ToAggregate()
  350. if (err != nil) != rt.expectErr {
  351. t.Errorf("%d failed ValidateKubeletConfiguration: expected error %t, got error %t", i, rt.expectErr, err != nil)
  352. }
  353. })
  354. }
  355. }