k8s.io/kubernetes@v1.29.3/pkg/kubelet/types/pod_update.go (about) 1 /* 2 Copyright 2014 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package types 18 19 import ( 20 "fmt" 21 22 v1 "k8s.io/api/core/v1" 23 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 24 "k8s.io/kubernetes/pkg/apis/scheduling" 25 ) 26 27 // Annotation keys for annotations used in this package. 28 const ( 29 ConfigSourceAnnotationKey = "kubernetes.io/config.source" 30 ConfigMirrorAnnotationKey = v1.MirrorPodAnnotationKey 31 ConfigFirstSeenAnnotationKey = "kubernetes.io/config.seen" 32 ConfigHashAnnotationKey = "kubernetes.io/config.hash" 33 ) 34 35 // PodOperation defines what changes will be made on a pod configuration. 36 type PodOperation int 37 38 // These constants identify the PodOperations that can be made on a pod configuration. 39 const ( 40 // SET is the current pod configuration. 41 SET PodOperation = iota 42 // ADD signifies pods that are new to this source. 43 ADD 44 // DELETE signifies pods that are gracefully deleted from this source. 45 DELETE 46 // REMOVE signifies pods that have been removed from this source. 47 REMOVE 48 // UPDATE signifies pods have been updated in this source. 49 UPDATE 50 // RECONCILE signifies pods that have unexpected status in this source, 51 // kubelet should reconcile status with this source. 52 RECONCILE 53 ) 54 55 // These constants identify the sources of pods. 56 const ( 57 // Filesource idenitified updates from a file. 58 FileSource = "file" 59 // HTTPSource identifies updates from querying a web page. 60 HTTPSource = "http" 61 // ApiserverSource identifies updates from Kubernetes API Server. 62 ApiserverSource = "api" 63 // AllSource identifies updates from all sources. 64 AllSource = "*" 65 ) 66 67 // NamespaceDefault is a string representing the default namespace. 68 const NamespaceDefault = metav1.NamespaceDefault 69 70 // PodUpdate defines an operation sent on the channel. You can add or remove single services by 71 // sending an array of size one and Op == ADD|REMOVE (with REMOVE, only the ID is required). 72 // For setting the state of the system to a given state for this source configuration, set 73 // Pods as desired and Op to SET, which will reset the system state to that specified in this 74 // operation for this source channel. To remove all pods, set Pods to empty object and Op to SET. 75 // 76 // Additionally, Pods should never be nil - it should always point to an empty slice. While 77 // functionally similar, this helps our unit tests properly check that the correct PodUpdates 78 // are generated. 79 type PodUpdate struct { 80 Pods []*v1.Pod 81 Op PodOperation 82 Source string 83 } 84 85 // GetValidatedSources gets all validated sources from the specified sources. 86 func GetValidatedSources(sources []string) ([]string, error) { 87 validated := make([]string, 0, len(sources)) 88 for _, source := range sources { 89 switch source { 90 case AllSource: 91 return []string{FileSource, HTTPSource, ApiserverSource}, nil 92 case FileSource, HTTPSource, ApiserverSource: 93 validated = append(validated, source) 94 case "": 95 // Skip 96 default: 97 return []string{}, fmt.Errorf("unknown pod source %q", source) 98 } 99 } 100 return validated, nil 101 } 102 103 // GetPodSource returns the source of the pod based on the annotation. 104 func GetPodSource(pod *v1.Pod) (string, error) { 105 if pod.Annotations != nil { 106 if source, ok := pod.Annotations[ConfigSourceAnnotationKey]; ok { 107 return source, nil 108 } 109 } 110 return "", fmt.Errorf("cannot get source of pod %q", pod.UID) 111 } 112 113 // SyncPodType classifies pod updates, eg: create, update. 114 type SyncPodType int 115 116 const ( 117 // SyncPodSync is when the pod is synced to ensure desired state 118 SyncPodSync SyncPodType = iota 119 // SyncPodUpdate is when the pod is updated from source 120 SyncPodUpdate 121 // SyncPodCreate is when the pod is created from source 122 SyncPodCreate 123 // SyncPodKill is when the pod should have no running containers. A pod stopped in this way could be 124 // restarted in the future due config changes. 125 SyncPodKill 126 ) 127 128 func (sp SyncPodType) String() string { 129 switch sp { 130 case SyncPodCreate: 131 return "create" 132 case SyncPodUpdate: 133 return "update" 134 case SyncPodSync: 135 return "sync" 136 case SyncPodKill: 137 return "kill" 138 default: 139 return "unknown" 140 } 141 } 142 143 // IsMirrorPod returns true if the passed Pod is a Mirror Pod. 144 func IsMirrorPod(pod *v1.Pod) bool { 145 if pod.Annotations == nil { 146 return false 147 } 148 _, ok := pod.Annotations[ConfigMirrorAnnotationKey] 149 return ok 150 } 151 152 // IsStaticPod returns true if the pod is a static pod. 153 func IsStaticPod(pod *v1.Pod) bool { 154 source, err := GetPodSource(pod) 155 return err == nil && source != ApiserverSource 156 } 157 158 // IsCriticalPod returns true if pod's priority is greater than or equal to SystemCriticalPriority. 159 func IsCriticalPod(pod *v1.Pod) bool { 160 if IsStaticPod(pod) { 161 return true 162 } 163 if IsMirrorPod(pod) { 164 return true 165 } 166 if pod.Spec.Priority != nil && IsCriticalPodBasedOnPriority(*pod.Spec.Priority) { 167 return true 168 } 169 return false 170 } 171 172 // Preemptable returns true if preemptor pod can preempt preemptee pod 173 // if preemptee is not critical or if preemptor's priority is greater than preemptee's priority 174 func Preemptable(preemptor, preemptee *v1.Pod) bool { 175 if IsCriticalPod(preemptor) && !IsCriticalPod(preemptee) { 176 return true 177 } 178 if (preemptor != nil && preemptor.Spec.Priority != nil) && 179 (preemptee != nil && preemptee.Spec.Priority != nil) { 180 return *(preemptor.Spec.Priority) > *(preemptee.Spec.Priority) 181 } 182 183 return false 184 } 185 186 // IsCriticalPodBasedOnPriority checks if the given pod is a critical pod based on priority resolved from pod Spec. 187 func IsCriticalPodBasedOnPriority(priority int32) bool { 188 return priority >= scheduling.SystemCriticalPriority 189 } 190 191 // IsNodeCriticalPod checks if the given pod is a system-node-critical 192 func IsNodeCriticalPod(pod *v1.Pod) bool { 193 return IsCriticalPod(pod) && (pod.Spec.PriorityClassName == scheduling.SystemNodeCritical) 194 } 195 196 // IsRestartableInitContainer returns true if the initContainer has 197 // ContainerRestartPolicyAlways. 198 func IsRestartableInitContainer(initContainer *v1.Container) bool { 199 if initContainer.RestartPolicy == nil { 200 return false 201 } 202 203 return *initContainer.RestartPolicy == v1.ContainerRestartPolicyAlways 204 }