// getServicePorts returns the po func getServicePorts(kubeClient *unversioned.Client, ns, name string) (ports []string, err error) { var svc *api.Service glog.Infof("Waiting for %v/%v", ns, name) wait.Poll(1*time.Second, 5*time.Minute, func() (bool, error) { svc, err = kubeClient.Services(ns).Get(name) if err != nil { if glog.V(2) { glog.Errorf("%v", err) } return false, nil } for _, p := range svc.Spec.Ports { if p.Port != 0 { ports = append(ports, strconv.Itoa(p.Port)) break } } glog.Infof("Ports for %v/%v : %v", ns, name, ports) return true, nil }) return }
func runServiceAndRCForResourceConsumer(c *client.Client, ns, name string, replicas int, cpuLimitMillis, memLimitMb int64) { By(fmt.Sprintf("Running consuming RC %s with %v replicas", name, replicas)) _, err := c.Services(ns).Create(&api.Service{ ObjectMeta: api.ObjectMeta{ Name: name, }, Spec: api.ServiceSpec{ Ports: []api.ServicePort{{ Port: port, TargetPort: util.NewIntOrStringFromInt(targetPort), }}, Selector: map[string]string{ "name": name, }, }, }) expectNoError(err) config := RCConfig{ Client: c, Image: resourceConsumerImage, Name: name, Namespace: ns, Timeout: timeoutRC, Replicas: replicas, CpuRequest: cpuLimitMillis, CpuLimit: cpuLimitMillis, MemRequest: memLimitMb * 1024 * 1024, // MemLimit is in bytes MemLimit: memLimitMb * 1024 * 1024, } expectNoError(RunRC(config)) // Make sure endpoints are propagated. // TODO(piosz): replace sleep with endpoints watch. time.Sleep(10 * time.Second) }
func openService(ns string, serviceName string, c *k8sclient.Client, printURL bool, retry bool) { if retry { if err := RetryAfter(40, func() error { return CheckService(ns, serviceName, c) }, 10*time.Second); err != nil { util.Errorf("Could not find finalized endpoint being pointed to by %s: %v", serviceName, err) os.Exit(1) } } svcs, err := c.Services(ns).List(kubeApi.ListOptions{}) if err != nil { util.Errorf("No services found %v\n", err) } found := false for _, service := range svcs.Items { if serviceName == service.Name { url := service.ObjectMeta.Annotations[exposeURLAnnotation] if printURL { util.Successf("%s\n", url) } else { util.Successf("\nOpening URL %s\n", url) browser.OpenURL(url) } found = true break } } if !found { util.Errorf("No service %s in namespace %s\n", serviceName, ns) } }
// Creates a replication controller that serves its hostname and a service on top of it. func startServeHostnameService(c *client.Client, ns, name string, port, replicas int) ([]string, string, error) { podNames := make([]string, replicas) By("creating service " + name + " in namespace " + ns) _, err := c.Services(ns).Create(&api.Service{ ObjectMeta: api.ObjectMeta{ Name: name, }, Spec: api.ServiceSpec{ Ports: []api.ServicePort{{ Port: port, TargetPort: util.NewIntOrStringFromInt(9376), Protocol: "TCP", }}, Selector: map[string]string{ "name": name, }, }, }) if err != nil { return podNames, "", err } var createdPods []*api.Pod maxContainerFailures := 0 config := RCConfig{ Client: c, Image: "gcr.io/google_containers/serve_hostname:1.1", Name: name, Namespace: ns, PollInterval: 3 * time.Second, Timeout: podReadyBeforeTimeout, Replicas: replicas, CreatedPods: &createdPods, MaxContainerFailures: &maxContainerFailures, } err = RunRC(config) if err != nil { return podNames, "", err } if len(createdPods) != replicas { return podNames, "", fmt.Errorf("Incorrect number of running pods: %v", len(createdPods)) } for i := range createdPods { podNames[i] = createdPods[i].ObjectMeta.Name } sort.StringSlice(podNames).Sort() service, err := c.Services(ns).Get(name) if err != nil { return podNames, "", err } if service.Spec.ClusterIP == "" { return podNames, "", fmt.Errorf("Service IP is blank for %v", name) } serviceIP := service.Spec.ClusterIP return podNames, serviceIP, nil }
func startService(c *client.Client, ns, name string, replicas int) { c.Services(ns).Create(&api.Service{ ObjectMeta: api.ObjectMeta{ Name: name, }, Spec: api.ServiceSpec{ Ports: []api.ServicePort{{ Port: port, TargetPort: util.NewIntOrStringFromInt(targetPort), }}, Selector: map[string]string{ "name": name, }, }, }) config := RCConfig{ Client: c, Image: image, Name: name, Namespace: ns, Timeout: timeoutRC, Replicas: replicas, } expectNoError(RunRC(config)) }
func createService(client *kubeclient.Client, meta kube.ObjectMeta, clusterIP string, dnsPort int) error { service := &kube.Service{ ObjectMeta: meta, Spec: kube.ServiceSpec{ ClusterIP: clusterIP, Ports: []kube.ServicePort{ { Name: "dns", Port: 53, TargetPort: intstr.FromInt(dnsPort), Protocol: kube.ProtocolUDP, }, { Name: "dns-tcp", Port: 53, TargetPort: intstr.FromInt(dnsPort), Protocol: kube.ProtocolTCP, }, }, }, } _, err := client.Services(meta.Namespace).Create(service) if err != nil { return err } return nil }
func runServiceAndRCForResourceConsumer(c *client.Client, ns, name string, replicas int, cpuLimitMillis, memLimitMb int64) { _, err := c.Services(ns).Create(&api.Service{ ObjectMeta: api.ObjectMeta{ Name: name, }, Spec: api.ServiceSpec{ Ports: []api.ServicePort{{ Port: port, TargetPort: util.NewIntOrStringFromInt(targetPort), }}, Selector: map[string]string{ "name": name, }, }, }) expectNoError(err) config := RCConfig{ Client: c, Image: image, Name: name, Namespace: ns, Timeout: timeoutRC, Replicas: replicas, CpuLimit: cpuLimitMillis, MemLimit: memLimitMb * 1024 * 1024, // MemLimit is in bytes } expectNoError(RunRC(config)) }
func getAppServices(kubeClient *client.Client) (*api.ServiceList, error) { serviceClient := kubeClient.Services(api.NamespaceAll) services, err := serviceClient.List(servicesSelector) if err != nil { return nil, err } return services, nil }
func stopServeHostnameService(c *client.Client, ns, name string) error { if err := DeleteRC(c, ns, name); err != nil { return err } if err := c.Services(ns).Delete(name); err != nil { return err } return nil }
func runServiceAndWorkloadForResourceConsumer(c *client.Client, ns, name, kind string, replicas int, cpuLimitMillis, memLimitMb int64) { By(fmt.Sprintf("Running consuming RC %s via %s with %v replicas", name, kind, replicas)) _, err := c.Services(ns).Create(&api.Service{ ObjectMeta: api.ObjectMeta{ Name: name, }, Spec: api.ServiceSpec{ Ports: []api.ServicePort{{ Port: port, TargetPort: intstr.FromInt(targetPort), }}, Selector: map[string]string{ "name": name, }, }, }) framework.ExpectNoError(err) rcConfig := framework.RCConfig{ Client: c, Image: resourceConsumerImage, Name: name, Namespace: ns, Timeout: timeoutRC, Replicas: replicas, CpuRequest: cpuLimitMillis, CpuLimit: cpuLimitMillis, MemRequest: memLimitMb * 1024 * 1024, // MemLimit is in bytes MemLimit: memLimitMb * 1024 * 1024, } switch kind { case kindRC: framework.ExpectNoError(framework.RunRC(rcConfig)) break case kindDeployment: dpConfig := framework.DeploymentConfig{ RCConfig: rcConfig, } framework.ExpectNoError(framework.RunDeployment(dpConfig)) break case kindReplicaSet: rsConfig := framework.ReplicaSetConfig{ RCConfig: rcConfig, } framework.ExpectNoError(framework.RunReplicaSet(rsConfig)) break default: framework.Failf(invalidKind) } // Make sure endpoints are propagated. // TODO(piosz): replace sleep with endpoints watch. time.Sleep(10 * time.Second) }
func validateJenkinshiftService(c *k8sclient.Client, f *cmdutil.Factory) (Result, error) { ns, _, err := f.DefaultNamespace() if err != nil { return Failure, err } svc, err := c.Services(ns).Get("jenkinshift") if svc != nil { return Success, err } return Failure, err }
func getAppServices(kubeClient *client.Client) (*api.ServiceList, error) { serviceClient := kubeClient.Services(api.NamespaceAll) servicesSelector, err := labels.Parse("routable==true") if err != nil { return nil, err } services, err := serviceClient.List(servicesSelector) if err != nil { return nil, err } return services, nil }
// unsecuredRoute will return a route with enough info so that it can direct traffic to // the service provided by --service. Callers of this helper are responsible for providing // tls configuration, path, and the hostname of the route. func unsecuredRoute(kc *kclient.Client, namespace, routeName, serviceName, portString string) (*api.Route, error) { if len(routeName) == 0 { routeName = serviceName } svc, err := kc.Services(namespace).Get(serviceName) if err != nil { if len(portString) == 0 { return nil, fmt.Errorf("you need to provide a route port via --port when exposing a non-existent service") } return &api.Route{ ObjectMeta: kapi.ObjectMeta{ Name: routeName, }, Spec: api.RouteSpec{ To: kapi.ObjectReference{ Name: serviceName, }, Port: resolveRoutePort(portString), }, }, nil } ok, port := supportsTCP(svc) if !ok { return nil, fmt.Errorf("service %q doesn't support TCP", svc.Name) } route := &api.Route{ ObjectMeta: kapi.ObjectMeta{ Name: routeName, Labels: svc.Labels, }, Spec: api.RouteSpec{ To: kapi.ObjectReference{ Name: serviceName, }, }, } // If the service has multiple ports and the user didn't specify --port, // then default the route port to a service port name. if len(port.Name) > 0 && len(portString) == 0 { route.Spec.Port = resolveRoutePort(port.Name) } // --port uber alles if len(portString) > 0 { route.Spec.Port = resolveRoutePort(portString) } return route, nil }
func deleteServices(c *k8sclient.Client, ns string, selector labels.Selector) error { services, err := c.Services(ns).List(api.ListOptions{LabelSelector: selector}) if err != nil { return err } for _, s := range services.Items { err := c.Services(ns).Delete(s.Name) if err != nil { return errors.Wrap(err, fmt.Sprintf("failed to delete Service %s", s.Name)) } } return nil }
func isValidService(kubeClient *unversioned.Client, name string) error { if name == "" { return fmt.Errorf("empty string is not a valid service name") } parts := strings.Split(name, "/") if len(parts) != 2 { return fmt.Errorf("invalid name format (namespace/name) in service '%v'", name) } _, err := kubeClient.Services(parts[0]).Get(parts[1]) return err }
// getBuilderService will return the service named "deis-builder" from the same namespace as // the router, but will return nil (without error) if no such service exists. func getBuilderService(kubeClient *client.Client) (*api.Service, error) { serviceClient := kubeClient.Services(namespace) service, err := serviceClient.Get("deis-builder") if err != nil { statusErr, ok := err.(*errors.StatusError) // If the issue is just that no deis-builder was found, that's ok. if ok && statusErr.Status().Code == 404 { // We'll just return nil instead of a found *api.Service. return nil, nil } return nil, err } return service, nil }
func getAllServices(kubeClient *kclient.Client) ([]kapi.Service, error) { filtered_srvs := []kapi.Service{} serviceList, err := kubeClient.Services(kapi.NamespaceAll).List(kapi.ListOptions{}) if err != nil { return filtered_srvs, err } for _, srv := range serviceList.Items { if len(srv.Spec.ClusterIP) == 0 || srv.Spec.ClusterIP == kapi.ClusterIPNone { continue } filtered_srvs = append(filtered_srvs, srv) } return filtered_srvs, nil }
// waitForKubernetesService waits for the "Kuberntes" master service. // Since the health probe on the kube2sky container is essentially an nslookup // of this service, we cannot serve any DNS records if it doesn't show up. // Once the Service is found, we start replying on this containers readiness // probe endpoint. func waitForKubernetesService(client *kclient.Client) (svc *kapi.Service) { name := fmt.Sprintf("%v/%v", kapi.NamespaceDefault, kubernetesSvcName) glog.Infof("Waiting for service: %v", name) var err error servicePollInterval := 1 * time.Second for { svc, err = client.Services(kapi.NamespaceDefault).Get(kubernetesSvcName) if err != nil || svc == nil { glog.Infof("Ignoring error while waiting for service %v: %v. Sleeping %v before retrying.", name, err, servicePollInterval) time.Sleep(servicePollInterval) continue } break } return }
func runMasterServiceTest(client *client.Client) { time.Sleep(12 * time.Second) svcList, err := client.Services(api.NamespaceDefault).List(labels.Everything()) if err != nil { glog.Fatalf("unexpected error listing services: %v", err) } var foundRW bool found := util.StringSet{} for i := range svcList.Items { found.Insert(svcList.Items[i].Name) if svcList.Items[i].Name == "kubernetes" { foundRW = true } } if foundRW { ep, err := client.Endpoints(api.NamespaceDefault).Get("kubernetes") if err != nil { glog.Fatalf("unexpected error listing endpoints for kubernetes service: %v", err) } if countEndpoints(ep) == 0 { glog.Fatalf("no endpoints for kubernetes service: %v", ep) } } else { glog.Errorf("no RW service found: %v", found) glog.Fatal("Kubernetes service test failed") } glog.Infof("Master service test passed.") }
func expectedServicesExist(c *client.Client) error { serviceList, err := c.Services(api.NamespaceSystem).List(api.ListOptions{}) if err != nil { return err } for _, service := range serviceList.Items { if _, ok := expectedServices[service.Name]; ok { expectedServices[service.Name] = true } } for service, found := range expectedServices { if !found { return fmt.Errorf("Service %q not found", service) } } return nil }
// GetReplicationControllerList returns a list of all Replication Controllers in the cluster. func GetReplicationControllerList(client *client.Client) (*ReplicationControllerList, error) { log.Printf("Getting list of all replication controllers in the cluster") listEverything := api.ListOptions{ LabelSelector: labels.Everything(), FieldSelector: fields.Everything(), } replicationControllers, err := client.ReplicationControllers(api.NamespaceAll).List(listEverything) if err != nil { return nil, err } services, err := client.Services(api.NamespaceAll).List(listEverything) if err != nil { return nil, err } pods, err := client.Pods(api.NamespaceAll).List(listEverything) if err != nil { return nil, err } eventsList, err := client.Events(api.NamespaceAll).List(api.ListOptions{ LabelSelector: labels.Everything(), FieldSelector: fields.Everything(), }) if err != nil { return nil, err } // Anonymous callback function to get pods warnings. // Function fulfils GetPodsEventWarningsFunc type contract. // Based on list of api pods returns list of pod related warning events getPodsEventWarningsFn := func(pods []api.Pod) []Event { return GetPodsEventWarnings(eventsList, pods) } // Anonymous callback function to get nodes by their names. getNodeFn := func(nodeName string) (*api.Node, error) { return client.Nodes().Get(nodeName) } result, err := getReplicationControllerList(replicationControllers.Items, services.Items, pods.Items, getPodsEventWarningsFn, getNodeFn) if err != nil { return nil, err } return result, nil }
// getServicePorts returns the ports defined in a service spec func getServicePorts(kubeClient *unversioned.Client, ns, name string) (ports []string, err error) { var svc *api.Service glog.Infof("Checking service %v/%v", ns, name) svc, err = kubeClient.Services(ns).Get(name) if err != nil { return } for _, p := range svc.Spec.Ports { if p.Port != 0 { ports = append(ports, strconv.Itoa(p.Port)) break } } glog.Infof("Ports for %v/%v : %v", ns, name, ports) return }
func waitForLoadBalancerDestroy(c *client.Client, serviceName, namespace string) (*api.Service, error) { // TODO: once support ticket 21807001 is resolved, reduce this timeout back to something reasonable // TODO: this should actually test that the LB was released at the cloud provider const timeout = 10 * time.Minute var service *api.Service By(fmt.Sprintf("waiting up to %v for service %s in namespace %s to have no LoadBalancer ingress points", timeout, serviceName, namespace)) for start := time.Now(); time.Since(start) < timeout; time.Sleep(5 * time.Second) { service, err := c.Services(namespace).Get(serviceName) if err != nil { Logf("Get service failed, ignoring for 5s: %v", err) continue } if len(service.Status.LoadBalancer.Ingress) == 0 { return service, nil } Logf("Waiting for service %s in namespace %s to have no LoadBalancer ingress points (%v)", serviceName, namespace, time.Since(start)) } return service, fmt.Errorf("service %s in namespace %s still has LoadBalancer ingress points after %.2f seconds", serviceName, namespace, timeout.Seconds()) }
// updateService fetches a service, calls the update function on it, // and then attempts to send the updated service. It retries up to 2 // times in the face of timeouts and conflicts. func updateService(c *client.Client, namespace, serviceName string, update func(*api.Service)) (*api.Service, error) { var service *api.Service var err error for i := 0; i < 3; i++ { service, err = c.Services(namespace).Get(serviceName) if err != nil { return service, err } update(service) service, err = c.Services(namespace).Update(service) if !errors.IsConflict(err) && !errors.IsServerTimeout(err) { return service, err } } return service, err }
func createRoutesForDomain(ns string, domain string, c *k8sclient.Client, oc *oclient.Client, fac *cmdutil.Factory) error { rapi.AddToScheme(kapi.Scheme) rapiv1.AddToScheme(kapi.Scheme) rc, err := c.Services(ns).List(kapi.ListOptions{}) if err != nil { util.Errorf("Failed to load services in namespace %s with error %v", ns, err) return err } var labels = make(map[string]string) labels["provider"] = "fabric8" items := rc.Items for _, service := range items { // TODO use the external load balancer as a way to know if we should create a route? name := service.ObjectMeta.Name if name != "kubernetes" { routes := oc.Routes(ns) _, err = routes.Get(name) if err != nil { hostName := name + "." + domain route := rapi.Route{ ObjectMeta: kapi.ObjectMeta{ Labels: labels, Name: name, }, Spec: rapi.RouteSpec{ Host: hostName, To: kapi.ObjectReference{Name: name}, }, } // lets create the route _, err = routes.Create(&route) if err != nil { util.Errorf("Failed to create the route %s with error %v", name, err) return err } } } } return nil }
// createApp will create a single RC and Svc. The Svc will match pods of the // RC using the selector: 'name'=<name arg> func createApp(c *client.Client, ns string, i int) { name := fmt.Sprintf("%v%d", appPrefix, i) l := map[string]string{} Logf("Creating svc %v", name) svc := svcByName(name, httpContainerPort) svc.Spec.Type = api.ServiceTypeNodePort _, err := c.Services(ns).Create(svc) Expect(err).NotTo(HaveOccurred()) Logf("Creating rc %v", name) rc := rcByNamePort(name, 1, testImage, httpContainerPort, api.ProtocolTCP, l) rc.Spec.Template.Spec.Containers[0].Args = []string{ "--num=1", fmt.Sprintf("--start=%d", i), fmt.Sprintf("--prefix=%v", pathPrefix), fmt.Sprintf("--port=%d", httpContainerPort), } _, err = c.ReplicationControllers(ns).Create(rc) Expect(err).NotTo(HaveOccurred()) }
// CheckService waits for the specified service to be ready by returning an error until the service is up // The check is done by polling the endpoint associated with the service and when the endpoint exists, returning no error->service-online // Credits: https://github.com/kubernetes/minikube/blob/v0.9.0/cmd/minikube/cmd/service.go#L89 func CheckService(ns string, service string, c *k8sclient.Client) error { svc, err := c.Services(ns).Get(service) if err != nil { return err } url := svc.ObjectMeta.Annotations[exposeURLAnnotation] if url == "" { util.Info(".") return errors.New("") } endpoints := c.Endpoints(ns) if endpoints == nil { util.Errorf("No endpoints found in namespace %s\n", ns) } endpoint, err := endpoints.Get(service) if err != nil { util.Errorf("No endpoints found for service %s\n", service) return err } return CheckEndpointReady(endpoint) }
func waitForLoadBalancerIngress(c *client.Client, serviceName, namespace string) (*api.Service, error) { // TODO: once support ticket 21807001 is resolved, reduce this timeout back to something reasonable const timeout = 20 * time.Minute var service *api.Service By(fmt.Sprintf("waiting up to %v for service %s in namespace %s to have a LoadBalancer ingress point", timeout, serviceName, namespace)) i := 1 for start := time.Now(); time.Since(start) < timeout; time.Sleep(3 * time.Second) { service, err := c.Services(namespace).Get(serviceName) if err != nil { Logf("Get service failed, ignoring for 5s: %v", err) continue } if len(service.Status.LoadBalancer.Ingress) > 0 { return service, nil } if i%5 == 0 { Logf("Waiting for service %s in namespace %s to have a LoadBalancer ingress point (%v)", serviceName, namespace, time.Since(start)) } i++ } return service, fmt.Errorf("service %s in namespace %s doesn't have a LoadBalancer ingress point after %.2f seconds", serviceName, namespace, timeout.Seconds()) }
func updateServices(kubeClient *kube.Client) (podToServiceMap map[string]string) { serviceList, apiErr := kubeClient.Services("").List(kubeLabels.Everything(), kubeFields.Everything()) if apiErr != nil { glog.Errorf("Failed to list kubernetes services. Error: %v\n", apiErr) return nil } podToServiceMap = make(map[string]string, 2) for _, service := range serviceList.Items { podList, apiErr := kubeClient.Pods("").List(kubeLabels.SelectorFromSet(service.Spec.Selector), kubeFields.Everything()) if apiErr != nil { glog.Errorf("Failed to list kubernetes pods. Error: %v\n", apiErr) } else { for _, pod := range podList.Items { //fmt.Printf("%v -> %v\n", pod.ObjectMeta.Name, service.ObjectMeta.Name) podToServiceMap[pod.ObjectMeta.Name] = service.ObjectMeta.Name } } } return podToServiceMap }
// Returns detailed information about the given replica set in the given namespace. func GetReplicaSetDetail(client *client.Client, namespace string, name string) ( *ReplicaSetDetail, error) { replicaSetWithPods, err := getRawReplicaSetWithPods(client, namespace, name) if err != nil { return nil, err } replicaSet := replicaSetWithPods.ReplicaSet pods := replicaSetWithPods.Pods services, err := client.Services(namespace).List(unversioned.ListOptions{ LabelSelector: unversioned.LabelSelector{labels.Everything()}, FieldSelector: unversioned.FieldSelector{fields.Everything()}, }) if err != nil { return nil, err } replicaSetDetail := &ReplicaSetDetail{ Name: replicaSet.Name, Namespace: replicaSet.Namespace, Labels: replicaSet.ObjectMeta.Labels, LabelSelector: replicaSet.Spec.Selector, PodsRunning: replicaSet.Status.Replicas, PodsDesired: replicaSet.Spec.Replicas, } matchingServices := getMatchingServices(services.Items, replicaSet) for _, service := range matchingServices { replicaSetDetail.Services = append(replicaSetDetail.Services, getServiceDetail(service)) } for _, container := range replicaSet.Spec.Template.Spec.Containers { replicaSetDetail.ContainerImages = append(replicaSetDetail.ContainerImages, container.Image) } for _, pod := range pods.Items { podDetail := ReplicaSetPod{ Name: pod.Name, StartTime: pod.Status.StartTime, PodIP: pod.Status.PodIP, NodeName: pod.Spec.NodeName, RestartCount: getRestartCount(pod), } replicaSetDetail.Pods = append(replicaSetDetail.Pods, podDetail) } return replicaSetDetail, nil }