8000 rewrite probe only when the port needs to be intercepted by psikka1 · Pull Request #56387 · istio/istio · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

rewrite probe only when the port needs to be intercepted #56387

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,5 @@ var/
/manifests/charts/**/charts/
/manifests/charts/**/Chart.lock
coverage.out
/cni/pkg/plugin/istio-cni.log
/cni/pkg/plugin/istio-cni.log
.qodo
159 changes: 144 additions & 15 deletions pkg/kube/inject/app_probe.go
8000 8000
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package inject
import (
"encoding/json"
"strconv"
"strings"

corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/intstr"
Expand Down Expand Up @@ -167,11 +168,15 @@ type Prober struct {
// Also update the probers so that all usages of named port will be resolved to integer.
func DumpAppProbers(pod *corev1.Pod, targetPort int32) string {
out := KubeAppProbers{}
updateNamedPort := func(p *Prober, portMap map[string]int32) *Prober {
updateNamedPort := func(p *Prober, portMap map[int32]bool, containerName string) *Prober {
if p == nil {
return nil
}
if p.GRPC != nil {
grpcPort := p.GRPC.Port
if _, exists := portMap[grpcPort]; !exists && (len(portMap) > 0 || isPortExcluded(pod, intstr.FromInt32(grpcPort))) {
return nil
}
// don't need to update for gRPC probe port as it only supports integer
return p
}
Expand All @@ -187,42 +192,60 @@ func DumpAppProbers(pod *corev1.Pod, targetPort int32) string {
}

if probePort.Type == intstr.String {
port, exists := portMap[probePort.StrVal]
if !exists {
// First, check if the string port refers to a named port in the specific container
containerPortNum := lookupNamedPort(pod, probePort.StrVal, containerName)
if containerPortNum > 0 {
// Found a matching named port in container
portValInt := containerPortNum
if _, exists := portMap[portValInt]; !exists && (len(portMap) > 0 || isPortExcluded(pod, intstr.FromInt32(portValInt))) {
return nil
}
*probePort = intstr.FromInt32(portValInt)
} else {
// No named port found, try to parse as integer
portValInt64, err := strconv.ParseInt(probePort.StrVal, 10, 32)
if err != nil {
// If we can't parse it as an integer and it's not a named port, we can't continue
return nil
}
portValInt := int32(portValInt64)
if _, exists := portMap[portValInt]; !exists && (len(portMap) > 0 || isPortExcluded(pod, intstr.FromInt32(portValInt))) {
return nil
}
*probePort = intstr.FromInt32(portValInt)
}
} else if probePort.Type == intstr.Int {
if _, exists := portMap[probePort.IntVal]; !exists && (len(portMap) > 0 || isPortExcluded(pod, intstr.FromInt32(probePort.IntVal))) {
return nil
}
*probePort = intstr.FromInt32(port)
*probePort = intstr.FromInt32(probePort.IntVal)
} else if probePort.IntVal == targetPort {
// Already is rewritten
return nil
}
return p
}
portMap := getIncludedPorts(pod)
for _, c := range allContainers(pod) {
if c.Name == ProxyContainerName {
continue
}
readyz, livez, startupz, prestopz, poststartz := status.FormatProberURL(c.Name)
portMap := map[string]int32{}
for _, p := range c.Ports {
if p.Name != "" {
portMap[p.Name] = p.ContainerPort
}
}
if h := updateNamedPort(kubeProbeToInternalProber(c.ReadinessProbe), portMap); h != nil {

if h := updateNamedPort(kubeProbeToInternalProber(c.ReadinessProbe), portMap, c.Name); h != nil {
out[readyz] = h
}
if h := updateNamedPort(kubeProbeToInternalProber(c.LivenessProbe), portMap); h != nil {
if h := updateNamedPort(kubeProbeToInternalProber(c.LivenessProbe), portMap, c.Name); h != nil {
out[livez] = h
}
if h := updateNamedPort(kubeProbeToInternalProber(c.StartupProbe), portMap); h != nil {
if h := updateNamedPort(kubeProbeToInternalProber(c.StartupProbe), portMap, c.Name); h != nil {
out[startupz] = h
}
if c.Lifecycle != nil {
if h := updateNamedPort(kubeLifecycleHandlerToInternalProber(c.Lifecycle.PreStop), portMap); h != nil {
if h := updateNamedPort(kubeLifecycleHandlerToInternalProber(c.Lifecycle.PreStop), portMap, c.Name); h != nil {
out[prestopz] = h
}
if h := updateNamedPort(kubeLifecycleHandlerToInternalProber(c.Lifecycle.PostStart), portMap); h != nil {
if h := updateNamedPort(kubeLifecycleHandlerToInternalProber(c.Lifecycle.PostStart), portMap, c.Name); h != nil {
out[poststartz] = h
}
}
Expand All @@ -239,6 +262,112 @@ func DumpAppProbers(pod *corev1.Pod, targetPort int32) string {
return string(b)
}

// lookupNamedPort finds the port number for a named port in the pod containers
// If containerName is specified, it will first look for the port in that container before checking other containers
func lookupNamedPort(pod *corev1.Pod, name string, containerName string) int32 {
// First look in the specified container if provided
if containerName != "" {
// Check regular containers
for _, container := range pod.Spec.Containers {
if container.Name == containerName {
for _, port := range container.Ports {
if port.Name == name {
return port.ContainerPort
}
}
break // Found the container but no matching port
}
}

// Check init containers
for _, container := range pod.Spec.InitContainers {
if container.Name == containerName {
for _, port := range container.Ports {
if port.Name == name {
return port.ContainerPort
}
}
break // Found the container but no matching port
}
}
}

// Fall back to checking all containers if not found in the specified container
for _, container := range allContainers(pod) {
// Skip the container we already checked
if container.Name == containerName {
continue
}
for _, port := range container.Ports {
if port.Name == name {
return port.ContainerPort
}
}
}
return 0
}

func getIncludedPorts(pod *corev1.Pod) map[int32]bool {
// Get pod annotations
blankPorts := make(map[int32]bool)
annotations := pod.Annotations
if annotations == nil {
// If no annotations, include all ports by default
return blankPorts
}

includedPorts := make(map[int32]bool)

includeInboundPortsKey := annotation.SidecarTrafficIncludeInboundPorts.Name
// Check if includeInboundPorts annotation is present
if includePortsStr, exists := annotations[includeInboundPortsKey]; exists && includePortsStr != "" {
// If includeInboundPorts is specified, only include those ports
if includePortsStr == "*" {
// "*" means include all ports
return blankPorts
}

// Parse comma-separated list of ports
for _, portStr := range splitPorts(includePortsStr) {
if port, err := strconv.Atoi(strings.TrimSpace(portStr)); err == nil {
includedPorts[int32(port)] = true
} else {
log.Errorf("Failed to parse port %v from includeInboundPorts: %v", portStr, err)
}
}
} else {
excludeInboundPortsKey := annotation.SidecarTrafficExcludeInboundPorts.Name
// Then exclude ports specified in excludeInboundPorts
if excludePortsStr, exists := annotations[excludeInboundPortsKey]; exists && excludePortsStr != "" {
for _, portStr := range splitPorts(excludePortsStr) {
if port, err := strconv.Atoi(portStr); err == nil {
delete(includedPorts, int32(port))
} else {
log.Errorf("Failed to parse port %v from excludeInboundPorts: %v", portStr, err)
}
}
}
}
return includedPorts
}

func isPortExcluded(pod *corev1.Pod, port intstr.IntOrString) bool {
portIntVal := port.IntVal
excludeInboundPortsKey := annotation.SidecarTrafficExcludeInboundPorts.Name
if excludePortsStr, exists := pod.Annotations[excludeInboundPortsKey]; exists && excludePortsStr != "" {
for _, portStr := range splitPorts(excludePortsStr) {
if excludedPort, err := strconv.Atoi(portStr); err == nil {
if excludedPort == int(portIntVal) {
return true
}
} else {
log.Errorf("Failed to parse port %v from excludeInboundPorts: %v", portStr, err)
}
}
}
return false
}

func allContainers(pod *corev1.Pod) []corev1.Container {
return append(slices.Clone(pod.Spec.InitContainers), pod.Spec.Containers...)
}
Expand Down
Loading
0