istio

Форк
0
/
podutil.go 
157 строк · 4.4 Кб
1
// Copyright Istio Authors
2
//
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
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14

15
package util
16

17
import (
18
	"context"
19
	"fmt"
20
	"net/netip"
21

22
	corev1 "k8s.io/api/core/v1"
23
	"k8s.io/apimachinery/pkg/api/errors"
24
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
25
	"k8s.io/apimachinery/pkg/types"
26
	"k8s.io/client-go/kubernetes"
27

28
	"istio.io/api/annotation"
29
	"istio.io/istio/pkg/config/constants"
30
	"istio.io/istio/pkg/util/sets"
31
)
32

33
var annotationPatch = []byte(fmt.Sprintf(
34
	`{"metadata":{"annotations":{"%s":"%s"}}}`,
35
	constants.AmbientRedirection,
36
	constants.AmbientRedirectionEnabled,
37
))
38

39
var annotationRemovePatch = []byte(fmt.Sprintf(
40
	`{"metadata":{"annotations":{"%s":null}}}`,
41
	constants.AmbientRedirection,
42
))
43

44
// TODO: we should use the upstream istio version of this function.
45
// PodRedirectionEnabled determines if a pod should or should not be configured
46
// to have traffic redirected thru the node proxy.
47
func PodRedirectionEnabled(namespace *corev1.Namespace, pod *corev1.Pod) bool {
48
	if namespace.GetLabels()[constants.DataplaneMode] != constants.DataplaneModeAmbient {
49
		// Namespace does not have ambient mode enabled
50
		return false
51
	}
52
	if podHasSidecar(pod) {
53
		// Ztunnel and sidecar for a single pod is currently not supported; opt out.
54
		return false
55
	}
56
	if pod.Annotations[constants.AmbientRedirection] == constants.AmbientRedirectionDisabled {
57
		// Pod explicitly asked to not have redirection enabled
58
		return false
59
	}
60
	return true
61
}
62

63
func podHasSidecar(pod *corev1.Pod) bool {
64
	if _, f := pod.GetAnnotations()[annotation.SidecarStatus.Name]; f {
65
		return true
66
	}
67
	return false
68
}
69

70
func IsZtunnelPod(systemNs string, pod *corev1.Pod) bool {
71
	return pod.Namespace == systemNs && pod.GetLabels()["app"] == "ztunnel"
72
}
73

74
func AnnotateEnrolledPod(client kubernetes.Interface, pod *metav1.ObjectMeta) error {
75
	_, err := client.CoreV1().
76
		Pods(pod.Namespace).
77
		Patch(
78
			context.Background(),
79
			pod.Name,
80
			types.MergePatchType,
81
			annotationPatch,
82
			metav1.PatchOptions{},
83
			// Both "pods" and "pods/status" can mutate the metadata. However, pods/status is lower privilege, so we use that instead.
84
			"status",
85
		)
86
	return err
87
}
88

89
func AnnotateUnenrollPod(client kubernetes.Interface, pod *metav1.ObjectMeta) error {
90
	if pod.Annotations[constants.AmbientRedirection] != constants.AmbientRedirectionEnabled {
91
		return nil
92
	}
93
	// TODO: do not overwrite if already none
94
	_, err := client.CoreV1().
95
		Pods(pod.Namespace).
96
		Patch(
97
			context.Background(),
98
			pod.Name,
99
			types.MergePatchType,
100
			annotationRemovePatch,
101
			metav1.PatchOptions{},
102
			// Both "pods" and "pods/status" can mutate the metadata. However, pods/status is lower privilege, so we use that instead.
103
			"status",
104
		)
105
	if errors.IsNotFound(err) {
106
		return nil
107
	}
108
	return err
109
}
110

111
func GetEnvFromPod(pod *corev1.Pod, envName string) string {
112
	for _, container := range pod.Spec.Containers {
113
		for _, env := range container.Env {
114
			if env.Name == envName {
115
				return env.Value
116
			}
117
		}
118
	}
119
	return ""
120
}
121

122
// GetUID is a nil safe UID accessor
123
func GetUID(o *corev1.Pod) types.UID {
124
	if o == nil {
125
		return ""
126
	}
127
	return o.GetUID()
128
}
129

130
func GetUniquePodUIDs(pods []*corev1.Pod) sets.Set[types.UID] {
131
	uids := sets.New[types.UID]()
132
	for _, pod := range pods {
133
		uids.Insert(GetUID(pod))
134
	}
135
	return uids
136
}
137

138
// Get any IPs currently assigned to the Pod.
139
//
140
// If 'PodIPs' exists, it is preferred (and should be guaranteed to contain the address in 'PodIP'),
141
// otherwise fallback to 'PodIP'.
142
//
143
// Note that very early in the pod's lifecycle (before all the node CNI plugin invocations finish)
144
// K8S may not have received the pod IPs yet, and may not report the pod as having any.
145
func GetPodIPsIfPresent(pod *corev1.Pod) []netip.Addr {
146
	var podIPs []netip.Addr
147
	if len(pod.Status.PodIPs) != 0 {
148
		for _, pip := range pod.Status.PodIPs {
149
			ip := netip.MustParseAddr(pip.IP)
150
			podIPs = append(podIPs, ip)
151
		}
152
	} else if len(pod.Status.PodIP) != 0 {
153
		ip := netip.MustParseAddr(pod.Status.PodIP)
154
		podIPs = append(podIPs, ip)
155
	}
156
	return podIPs
157
}
158

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.