You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

common.go 5.4 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. /*
  2. Copyright 2021 The KubeEdge 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 globalmanager
  14. import (
  15. "context"
  16. "fmt"
  17. "math"
  18. "strings"
  19. "time"
  20. v1 "k8s.io/api/core/v1"
  21. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  22. "k8s.io/apimachinery/pkg/labels"
  23. "k8s.io/apimachinery/pkg/util/intstr"
  24. "k8s.io/client-go/kubernetes"
  25. "k8s.io/client-go/util/workqueue"
  26. "k8s.io/klog/v2"
  27. )
  28. const (
  29. // DefaultBackOff is the default backoff period
  30. DefaultBackOff = 10 * time.Second
  31. // MaxBackOff is the max backoff period
  32. MaxBackOff = 360 * time.Second
  33. statusUpdateRetries = 3
  34. bigModelPort int32 = 5000
  35. )
  36. // GetNodeIPByName get node ip by node name
  37. func GetNodeIPByName(kubeClient kubernetes.Interface, name string) (string, error) {
  38. n, err := kubeClient.CoreV1().Nodes().Get(context.Background(), name, metav1.GetOptions{})
  39. if err != nil {
  40. return "", err
  41. }
  42. typeToAddress := make(map[v1.NodeAddressType]string)
  43. for _, addr := range n.Status.Addresses {
  44. typeToAddress[addr.Type] = addr.Address
  45. }
  46. address, found := typeToAddress[v1.NodeExternalIP]
  47. if found {
  48. return address, nil
  49. }
  50. address, found = typeToAddress[v1.NodeInternalIP]
  51. if found {
  52. return address, nil
  53. }
  54. return "", fmt.Errorf("can't found node ip for node %s", name)
  55. }
  56. // CreateKubernetesService creates a k8s service for an object given ip and port
  57. func CreateKubernetesService(kubeClient kubernetes.Interface, object CommonInterface, inputPort int32, inputIP string) (int32, error) {
  58. ctx := context.Background()
  59. name := object.GetName()
  60. namespace := object.GetNamespace()
  61. kind := object.GroupVersionKind().Kind
  62. targePort := intstr.IntOrString{
  63. IntVal: inputPort,
  64. }
  65. serviceSpec := &v1.Service{
  66. ObjectMeta: metav1.ObjectMeta{
  67. Namespace: object.GetNamespace(),
  68. GenerateName: name + "-" + "service" + "-",
  69. OwnerReferences: []metav1.OwnerReference{
  70. *metav1.NewControllerRef(object, object.GroupVersionKind()),
  71. },
  72. Labels: GenerateLabels(object),
  73. },
  74. Spec: v1.ServiceSpec{
  75. Selector: GenerateLabels(object),
  76. ExternalIPs: []string{
  77. inputIP,
  78. },
  79. Type: v1.ServiceTypeNodePort,
  80. Ports: []v1.ServicePort{
  81. {
  82. Port: inputPort,
  83. TargetPort: targePort,
  84. },
  85. },
  86. },
  87. }
  88. service, err := kubeClient.CoreV1().Services(namespace).Create(ctx, serviceSpec, metav1.CreateOptions{})
  89. if err != nil {
  90. klog.Warningf("failed to create service for %v %v/%v, err:%s", kind, namespace, name, err)
  91. return 0, err
  92. }
  93. klog.V(2).Infof("Service %s is created successfully for %v %v/%v", service.Name, kind, namespace, name)
  94. return service.Spec.Ports[0].NodePort, nil
  95. }
  96. // getBackoff calc the next wait time for the key
  97. func getBackoff(queue workqueue.RateLimitingInterface, key interface{}) time.Duration {
  98. exp := queue.NumRequeues(key)
  99. if exp <= 0 {
  100. return time.Duration(0)
  101. }
  102. // The backoff is capped such that 'calculated' value never overflows.
  103. backoff := float64(DefaultBackOff.Nanoseconds()) * math.Pow(2, float64(exp-1))
  104. if backoff > math.MaxInt64 {
  105. return MaxBackOff
  106. }
  107. calculated := time.Duration(backoff)
  108. if calculated > MaxBackOff {
  109. return MaxBackOff
  110. }
  111. return calculated
  112. }
  113. func calcActivePodCount(pods []*v1.Pod) int32 {
  114. var result int32 = 0
  115. for _, p := range pods {
  116. if v1.PodSucceeded != p.Status.Phase &&
  117. v1.PodFailed != p.Status.Phase &&
  118. p.DeletionTimestamp == nil {
  119. result++
  120. }
  121. }
  122. return result
  123. }
  124. // GenerateLabels generates labels for an object
  125. func GenerateLabels(object CommonInterface) map[string]string {
  126. kind := object.GroupVersionKind().Kind
  127. group := object.GroupVersionKind().Group
  128. keyPrefix := strings.ToLower(kind + "." + group + "/")
  129. labels := make(map[string]string)
  130. labels[keyPrefix+"name"] = object.GetName()
  131. labels[keyPrefix+"uid"] = string(object.GetUID())
  132. return labels
  133. }
  134. // GenerateSelector generates the selector for an object
  135. func GenerateSelector(object CommonInterface) (labels.Selector, error) {
  136. ls := &metav1.LabelSelector{
  137. MatchLabels: GenerateLabels(object),
  138. }
  139. return metav1.LabelSelectorAsSelector(ls)
  140. }
  141. // ConvertK8SValidName converts to the k8s valid name
  142. func ConvertK8SValidName(name string) string {
  143. // the name(e.g. pod/volume name) should be a lowercase RFC 1123 label:
  144. // [a-z0-9]([-a-z0-9]*[a-z0-9])?
  145. // and no more than 63 characters
  146. limitCount := 63
  147. var fixName []byte
  148. for _, c := range []byte(strings.ToLower(name)) {
  149. if ('a' <= c && c <= 'z') ||
  150. ('0' <= c && c <= '9') ||
  151. c == '-' {
  152. fixName = append(fixName, c)
  153. continue
  154. }
  155. // the first char not '-'
  156. // and no two consecutive '-'
  157. if len(fixName) > 0 && fixName[len(fixName)-1] != '-' {
  158. fixName = append(fixName, '-')
  159. }
  160. }
  161. // fix limitCount
  162. if len(fixName) > limitCount {
  163. fixName = fixName[:limitCount]
  164. }
  165. // fix the end character
  166. if len(fixName) > 0 && fixName[len(fixName)-1] == '-' {
  167. fixName[len(fixName)-1] = 'z'
  168. }
  169. return string(fixName)
  170. }