mirror_client.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /*
  2. Copyright 2015 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 pod
  14. import (
  15. "github.com/golang/glog"
  16. "k8s.io/kubernetes/pkg/api"
  17. "k8s.io/kubernetes/pkg/api/errors"
  18. clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
  19. kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
  20. kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
  21. )
  22. // MirrorClient knows how to create/delete a mirror pod in the API server.
  23. type MirrorClient interface {
  24. // CreateMirrorPod creates a mirror pod in the API server for the given
  25. // pod or returns an error. The mirror pod will have the same annotations
  26. // as the given pod as well as an extra annotation containing the hash of
  27. // the static pod.
  28. CreateMirrorPod(pod *api.Pod) error
  29. // DeleteMirrorPod deletes the mirror pod with the given full name from
  30. // the API server or returns an error.
  31. DeleteMirrorPod(podFullName string) error
  32. }
  33. // basicMirrorClient is a functional MirrorClient. Mirror pods are stored in
  34. // the kubelet directly because they need to be in sync with the internal
  35. // pods.
  36. type basicMirrorClient struct {
  37. apiserverClient clientset.Interface
  38. }
  39. // NewBasicMirrorClient returns a new MirrorClient.
  40. func NewBasicMirrorClient(apiserverClient clientset.Interface) MirrorClient {
  41. return &basicMirrorClient{apiserverClient: apiserverClient}
  42. }
  43. func (mc *basicMirrorClient) CreateMirrorPod(pod *api.Pod) error {
  44. if mc.apiserverClient == nil {
  45. return nil
  46. }
  47. // Make a copy of the pod.
  48. copyPod := *pod
  49. copyPod.Annotations = make(map[string]string)
  50. for k, v := range pod.Annotations {
  51. copyPod.Annotations[k] = v
  52. }
  53. hash := getPodHash(pod)
  54. copyPod.Annotations[kubetypes.ConfigMirrorAnnotationKey] = hash
  55. apiPod, err := mc.apiserverClient.Core().Pods(copyPod.Namespace).Create(&copyPod)
  56. if err != nil && errors.IsAlreadyExists(err) {
  57. // Check if the existing pod is the same as the pod we want to create.
  58. if h, ok := apiPod.Annotations[kubetypes.ConfigMirrorAnnotationKey]; ok && h == hash {
  59. return nil
  60. }
  61. }
  62. return err
  63. }
  64. func (mc *basicMirrorClient) DeleteMirrorPod(podFullName string) error {
  65. if mc.apiserverClient == nil {
  66. return nil
  67. }
  68. name, namespace, err := kubecontainer.ParsePodFullName(podFullName)
  69. if err != nil {
  70. glog.Errorf("Failed to parse a pod full name %q", podFullName)
  71. return err
  72. }
  73. glog.V(4).Infof("Deleting a mirror pod %q", podFullName)
  74. // TODO(random-liu): Delete the mirror pod with uid precondition in mirror pod manager
  75. if err := mc.apiserverClient.Core().Pods(namespace).Delete(name, api.NewDeleteOptions(0)); err != nil && !errors.IsNotFound(err) {
  76. glog.Errorf("Failed deleting a mirror pod %q: %v", podFullName, err)
  77. }
  78. return nil
  79. }
  80. func IsStaticPod(pod *api.Pod) bool {
  81. source, err := kubetypes.GetPodSource(pod)
  82. return err == nil && source != kubetypes.ApiserverSource
  83. }
  84. func IsMirrorPod(pod *api.Pod) bool {
  85. _, ok := pod.Annotations[kubetypes.ConfigMirrorAnnotationKey]
  86. return ok
  87. }
  88. func getHashFromMirrorPod(pod *api.Pod) (string, bool) {
  89. hash, ok := pod.Annotations[kubetypes.ConfigMirrorAnnotationKey]
  90. return hash, ok
  91. }
  92. func getPodHash(pod *api.Pod) string {
  93. // The annotation exists for all static pods.
  94. return pod.Annotations[kubetypes.ConfigHashAnnotationKey]
  95. }