kube_apiserver_test.go 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. /*
  2. Copyright 2017 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 master
  14. import (
  15. "encoding/json"
  16. "fmt"
  17. "net/http"
  18. "reflect"
  19. "strings"
  20. "testing"
  21. "time"
  22. appsv1 "k8s.io/api/apps/v1"
  23. corev1 "k8s.io/api/core/v1"
  24. "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
  25. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  26. "k8s.io/apimachinery/pkg/util/wait"
  27. "k8s.io/apiserver/pkg/registry/generic/registry"
  28. "k8s.io/client-go/kubernetes"
  29. "k8s.io/kube-aggregator/pkg/apis/apiregistration"
  30. kubeapiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing"
  31. "k8s.io/kubernetes/test/integration/framework"
  32. )
  33. func TestRun(t *testing.T) {
  34. server := kubeapiservertesting.StartTestServerOrDie(t, nil, nil, framework.SharedEtcd())
  35. defer server.TearDownFn()
  36. client, err := kubernetes.NewForConfig(server.ClientConfig)
  37. if err != nil {
  38. t.Fatalf("unexpected error: %v", err)
  39. }
  40. // test whether the server is really healthy after /healthz told us so
  41. t.Logf("Creating Deployment directly after being healthy")
  42. var replicas int32 = 1
  43. _, err = client.AppsV1().Deployments("default").Create(&appsv1.Deployment{
  44. TypeMeta: metav1.TypeMeta{
  45. Kind: "Deployment",
  46. APIVersion: "apps/v1",
  47. },
  48. ObjectMeta: metav1.ObjectMeta{
  49. Namespace: "default",
  50. Name: "test",
  51. Labels: map[string]string{"foo": "bar"},
  52. },
  53. Spec: appsv1.DeploymentSpec{
  54. Replicas: &replicas,
  55. Strategy: appsv1.DeploymentStrategy{
  56. Type: appsv1.RollingUpdateDeploymentStrategyType,
  57. },
  58. Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}},
  59. Template: corev1.PodTemplateSpec{
  60. ObjectMeta: metav1.ObjectMeta{
  61. Labels: map[string]string{"foo": "bar"},
  62. },
  63. Spec: corev1.PodSpec{
  64. Containers: []corev1.Container{
  65. {
  66. Name: "foo",
  67. Image: "foo",
  68. },
  69. },
  70. },
  71. },
  72. },
  73. })
  74. if err != nil {
  75. t.Fatalf("Failed to create deployment: %v", err)
  76. }
  77. }
  78. // TestOpenAPIDelegationChainPlumbing is a smoke test that checks for
  79. // the existence of some representative paths from the
  80. // apiextensions-server and the kube-aggregator server, both part of
  81. // the delegation chain in kube-apiserver.
  82. func TestOpenAPIDelegationChainPlumbing(t *testing.T) {
  83. server := kubeapiservertesting.StartTestServerOrDie(t, nil, nil, framework.SharedEtcd())
  84. defer server.TearDownFn()
  85. kubeclient, err := kubernetes.NewForConfig(server.ClientConfig)
  86. if err != nil {
  87. t.Fatalf("unexpected error: %v", err)
  88. }
  89. result := kubeclient.RESTClient().Get().AbsPath("/openapi/v2").Do()
  90. status := 0
  91. result.StatusCode(&status)
  92. if status != http.StatusOK {
  93. t.Fatalf("GET /openapi/v2 failed: expected status=%d, got=%d", http.StatusOK, status)
  94. }
  95. raw, err := result.Raw()
  96. if err != nil {
  97. t.Fatalf("Unexpected error: %v", err)
  98. }
  99. type openAPISchema struct {
  100. Paths map[string]interface{} `json:"paths"`
  101. }
  102. var doc openAPISchema
  103. err = json.Unmarshal(raw, &doc)
  104. if err != nil {
  105. t.Fatalf("Failed to unmarshal: %v", err)
  106. }
  107. matchedExtension := false
  108. extensionsPrefix := "/apis/" + apiextensions.GroupName
  109. matchedRegistration := false
  110. registrationPrefix := "/apis/" + apiregistration.GroupName
  111. for path := range doc.Paths {
  112. if strings.HasPrefix(path, extensionsPrefix) {
  113. matchedExtension = true
  114. }
  115. if strings.HasPrefix(path, registrationPrefix) {
  116. matchedRegistration = true
  117. }
  118. if matchedExtension && matchedRegistration {
  119. return
  120. }
  121. }
  122. if !matchedExtension {
  123. t.Errorf("missing path: %q", extensionsPrefix)
  124. }
  125. if !matchedRegistration {
  126. t.Errorf("missing path: %q", registrationPrefix)
  127. }
  128. }
  129. // return the unique endpoint IPs
  130. func getEndpointIPs(endpoints *corev1.Endpoints) []string {
  131. endpointMap := make(map[string]bool)
  132. ips := make([]string, 0)
  133. for _, subset := range endpoints.Subsets {
  134. for _, address := range subset.Addresses {
  135. if _, ok := endpointMap[address.IP]; !ok {
  136. endpointMap[address.IP] = true
  137. ips = append(ips, address.IP)
  138. }
  139. }
  140. }
  141. return ips
  142. }
  143. func verifyEndpointsWithIPs(servers []*kubeapiservertesting.TestServer, ips []string) bool {
  144. listenAddresses := make([]string, 0)
  145. for _, server := range servers {
  146. listenAddresses = append(listenAddresses, server.ServerOpts.GenericServerRunOptions.AdvertiseAddress.String())
  147. }
  148. return reflect.DeepEqual(listenAddresses, ips)
  149. }
  150. func testReconcilersMasterLease(t *testing.T, leaseCount int, masterCount int) {
  151. var leaseServers []*kubeapiservertesting.TestServer
  152. var masterCountServers []*kubeapiservertesting.TestServer
  153. etcd := framework.SharedEtcd()
  154. instanceOptions := &kubeapiservertesting.TestServerInstanceOptions{
  155. DisableStorageCleanup: true,
  156. }
  157. // cleanup the registry storage
  158. defer registry.CleanupStorage()
  159. // 1. start masterCount api servers
  160. for i := 0; i < masterCount; i++ {
  161. // start master count api server
  162. server := kubeapiservertesting.StartTestServerOrDie(t, instanceOptions, []string{
  163. "--endpoint-reconciler-type", "master-count",
  164. "--advertise-address", fmt.Sprintf("10.0.1.%v", i+1),
  165. "--apiserver-count", fmt.Sprintf("%v", masterCount),
  166. }, etcd)
  167. masterCountServers = append(masterCountServers, server)
  168. }
  169. // 2. verify master count servers have registered
  170. if err := wait.PollImmediate(3*time.Second, 2*time.Minute, func() (bool, error) {
  171. client, err := kubernetes.NewForConfig(masterCountServers[0].ClientConfig)
  172. endpoints, err := client.CoreV1().Endpoints("default").Get("kubernetes", metav1.GetOptions{})
  173. if err != nil {
  174. t.Logf("error fetching endpoints: %v", err)
  175. return false, nil
  176. }
  177. return verifyEndpointsWithIPs(masterCountServers, getEndpointIPs(endpoints)), nil
  178. }); err != nil {
  179. t.Fatalf("master count endpoints failed to register: %v", err)
  180. }
  181. // 3. start lease api servers
  182. for i := 0; i < leaseCount; i++ {
  183. options := []string{
  184. "--endpoint-reconciler-type", "lease",
  185. "--advertise-address", fmt.Sprintf("10.0.1.%v", i+10),
  186. }
  187. server := kubeapiservertesting.StartTestServerOrDie(t, instanceOptions, options, etcd)
  188. defer server.TearDownFn()
  189. leaseServers = append(leaseServers, server)
  190. }
  191. time.Sleep(3 * time.Second)
  192. // 4. Shutdown the masterCount server
  193. for _, server := range masterCountServers {
  194. server.TearDownFn()
  195. }
  196. // 5. verify only leaseEndpoint servers left
  197. if err := wait.PollImmediate(3*time.Second, 2*time.Minute, func() (bool, error) {
  198. client, err := kubernetes.NewForConfig(leaseServers[0].ClientConfig)
  199. if err != nil {
  200. t.Logf("create client error: %v", err)
  201. return false, nil
  202. }
  203. endpoints, err := client.CoreV1().Endpoints("default").Get("kubernetes", metav1.GetOptions{})
  204. if err != nil {
  205. t.Logf("error fetching endpoints: %v", err)
  206. return false, nil
  207. }
  208. return verifyEndpointsWithIPs(leaseServers, getEndpointIPs(endpoints)), nil
  209. }); err != nil {
  210. t.Fatalf("did not find only lease endpoints: %v", err)
  211. }
  212. }
  213. func TestReconcilerMasterLeaseCombined(t *testing.T) {
  214. testReconcilersMasterLease(t, 1, 3)
  215. }
  216. func TestReconcilerMasterLeaseMultiMoreMasters(t *testing.T) {
  217. testReconcilersMasterLease(t, 3, 2)
  218. }
  219. func TestReconcilerMasterLeaseMultiCombined(t *testing.T) {
  220. testReconcilersMasterLease(t, 3, 3)
  221. }