From 5add6a36463065bd30c7e9ca57ae4bda97cd5195 Mon Sep 17 00:00:00 2001 From: evelynwei Date: Wed, 19 Feb 2025 17:30:53 +0800 Subject: [PATCH 01/17] =?UTF-8?q?feat:=20=E9=85=8D=E7=BD=AE=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E5=92=8C=E9=BB=91=E7=99=BD=E5=90=8D=E5=8D=95=E6=B3=A8?= =?UTF-8?q?=E5=85=A5=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/polaris-controller/app/config.go | 69 +- cmd/polaris-controller/app/options/polaris.go | 13 +- .../app/polaris-controller-manager.go | 20 +- .../admission-webhooks/mutating-webhook.yaml | 38 +- .../templates/controller-configmap-mesh.yaml | 16 +- deploy/kubernetes_v1.21/helm/values.yaml | 1 + .../kubernetes/configmap.yaml | 22 +- .../kubernetes_v1.21/kubernetes/injector.yaml | 38 + .../admission-webhooks/mutating-webhook.yaml | 38 +- .../templates/controller-configmap-mesh.yaml | 16 +- deploy/kubernetes_v1.22/helm/values.yaml | 1 + .../kubernetes/configmap.yaml | 22 +- .../kubernetes/polaris-controller.yaml | 38 + deploy/variables.txt | 1 + go.mod | 3 + pkg/inject/pkg/config/inject_config.go | 26 + pkg/inject/pkg/config/mesh/mesh.go | 102 ++- pkg/inject/pkg/config/safe_config.go | 164 +++++ pkg/inject/pkg/config/template_file.go | 123 ++++ .../pkg/kube/inject/apply/javaagent/patch.go | 7 +- .../pkg/kube/inject/apply/mesh/patch.go | 1 + pkg/inject/pkg/kube/inject/base.go | 244 +++++++ pkg/inject/pkg/kube/inject/base_test.go | 173 +++++ pkg/inject/pkg/kube/inject/common.go | 140 ++++ pkg/inject/pkg/kube/inject/inject.go | 677 +----------------- pkg/inject/pkg/kube/inject/inject_test.go | 113 +++ pkg/inject/pkg/kube/inject/pod.go | 193 +++++ pkg/inject/pkg/kube/inject/template_funcs.go | 248 +++++++ pkg/inject/pkg/kube/inject/validate_funcs.go | 110 +++ pkg/inject/pkg/kube/inject/webhook.go | 487 ++----------- pkg/util/types.go | 16 +- 31 files changed, 1972 insertions(+), 1188 deletions(-) create mode 100644 pkg/inject/pkg/config/inject_config.go create mode 100644 pkg/inject/pkg/config/safe_config.go create mode 100644 pkg/inject/pkg/config/template_file.go create mode 100644 pkg/inject/pkg/kube/inject/base.go create mode 100644 pkg/inject/pkg/kube/inject/base_test.go create mode 100644 pkg/inject/pkg/kube/inject/common.go create mode 100644 pkg/inject/pkg/kube/inject/inject_test.go create mode 100644 pkg/inject/pkg/kube/inject/pod.go create mode 100644 pkg/inject/pkg/kube/inject/template_funcs.go create mode 100644 pkg/inject/pkg/kube/inject/validate_funcs.go diff --git a/cmd/polaris-controller/app/config.go b/cmd/polaris-controller/app/config.go index 2dfbd8da..9b618107 100644 --- a/cmd/polaris-controller/app/config.go +++ b/cmd/polaris-controller/app/config.go @@ -21,10 +21,11 @@ import ( "gopkg.in/yaml.v2" "github.com/polarismesh/polaris-controller/cmd/polaris-controller/app/options" + "github.com/polarismesh/polaris-controller/common" "github.com/polarismesh/polaris-controller/common/log" ) -// ServiceSync controller 用到的配置 +// ProxyMetadata mesh envoy用到的配置 type ProxyMetadata struct { ServerAddress string `yaml:"serverAddress"` ClusterName string `yaml:"clusterName"` @@ -32,7 +33,7 @@ type ProxyMetadata struct { CAAddress string `yaml:"caAddress"` } -// DefaultConfig controller 用到的配置 +// DefaultConfig mesh envoy sidecar 用到的配置 type DefaultConfig struct { ProxyMetadata ProxyMetadata `yaml:"proxyMetadata"` } @@ -56,16 +57,66 @@ type Server struct { } type controllerConfig struct { - Logger map[string]*log.Options `yaml:"logger"` - ClusterName string `yaml:"clusterName"` - Server Server `yaml:"server"` - ServiceSync *options.ServiceSync `yaml:"serviceSync"` - ConfigSync *options.ConfigSync `yaml:"configSync"` - SidecarInject SidecarInject `yaml:"sidecarInject"` + // 北极星服务端地址 + ServerAddress string `yaml:"serverAddress"` + // 北极星服务端token(北极星开启鉴权时需要配置) + PolarisAccessToken string `yaml:"accessToken"` + // Operator 北极星主账户ID, 用于数据同步 + Operator string `yaml:"operator"` + // 容器集群名称或ID + ClusterName string `yaml:"clusterName"` + // k8s服务同步配置 + ServiceSync *options.ServiceSync `yaml:"serviceSync"` + // 配置同步配置 + ConfigSync *options.ConfigSync `yaml:"configSync"` + // sidecar注入相关配置 + SidecarInject SidecarInject `yaml:"sidecarInject"` + // mesh envoy 相关配置 + DefaultConfig DefaultConfig `yaml:"defaultConfig"` + // 组件日志配置 + Logger map[string]*log.Options `yaml:"logger"` + // 健康检查和对账配置 + Server Server `yaml:"server"` +} + +func (c *controllerConfig) getPolarisServerAddress() string { + // 新配置格式 + if c.ServerAddress != "" { + return c.ServerAddress + } + // 老的配置格式 + if c.ServiceSync.ServerAddress != "" { + return c.ServiceSync.ServerAddress + } + return common.PolarisServerAddress +} + +func (c *controllerConfig) getPolarisAccessToken() string { + // 新配置格式 + if c.PolarisAccessToken != "" { + return c.PolarisAccessToken + } + // 老的配置格式 + if c.ServiceSync.PolarisAccessToken != "" { + return c.ServiceSync.PolarisAccessToken + } + return "" +} + +func (c *controllerConfig) getPolarisOperator() string { + // 新配置格式 + if c.Operator != "" { + return c.Operator + } + // 老的配置格式 + if c.ServiceSync.Operator != "" { + return c.ServiceSync.Operator + } + return "" } func readConfFromFile() (*controllerConfig, error) { - buf, err := os.ReadFile(MeshFile) + buf, err := os.ReadFile(BootstrapConfigFile) if err != nil { log.Errorf("read file error, %v", err) return nil, err diff --git a/cmd/polaris-controller/app/options/polaris.go b/cmd/polaris-controller/app/options/polaris.go index 67a60726..1bb8247a 100644 --- a/cmd/polaris-controller/app/options/polaris.go +++ b/cmd/polaris-controller/app/options/polaris.go @@ -29,7 +29,8 @@ type PolarisControllerOptions struct { // ServiceSync 服务同步相关配置 type ServiceSync struct { - Mode string `yaml:"mode"` + Mode string `yaml:"mode"` + // deprecated, use SyncMode instead ServerAddress string `yaml:"serverAddress"` // 以下配置仅 polaris-server 开启 console auth // 调用 polaris-server OpenAPI 的凭据 @@ -40,15 +41,9 @@ type ServiceSync struct { Enable bool `yaml:"enable"` } -// ConfigSync 服务同步相关配置 +// ConfigSync 配置同步相关配置 type ConfigSync struct { - Mode string `yaml:"mode"` - ServerAddress string `yaml:"serverAddress"` - // 以下配置仅 polaris-server 开启 console auth - // 调用 polaris-server OpenAPI 的凭据 - PolarisAccessToken string `yaml:"accessToken"` - // Operator 用于数据同步的帐户ID - Operator string `yaml:"operator"` + Mode string `yaml:"mode"` // AllowDelete 允许向 Polaris 发起删除操作 AllowDelete bool `yaml:"allowDelete"` // SyncDirection 配置同步方向, kubernetesToPolaris/polarisToKubernetes/both diff --git a/cmd/polaris-controller/app/polaris-controller-manager.go b/cmd/polaris-controller/app/polaris-controller-manager.go index dafeb3aa..5f4778f4 100644 --- a/cmd/polaris-controller/app/polaris-controller-manager.go +++ b/cmd/polaris-controller/app/polaris-controller-manager.go @@ -48,6 +48,7 @@ import ( "github.com/polarismesh/polaris-controller/common" "github.com/polarismesh/polaris-controller/common/log" polarisController "github.com/polarismesh/polaris-controller/pkg/controller" + "github.com/polarismesh/polaris-controller/pkg/inject/pkg/config" "github.com/polarismesh/polaris-controller/pkg/inject/pkg/kube/inject" _ "github.com/polarismesh/polaris-controller/pkg/inject/pkg/kube/inject/apply/javaagent" _ "github.com/polarismesh/polaris-controller/pkg/inject/pkg/kube/inject/apply/mesh" @@ -68,7 +69,7 @@ const ( DnsConfigFile = "/etc/polaris-inject/inject/dns-config" JavaAgentConfigFile = "/etc/polaris-inject/inject/java-agent-config" ValuesFile = "/etc/polaris-inject/inject/values" - MeshFile = "/etc/polaris-inject/config/mesh" + BootstrapConfigFile = "/etc/polaris-inject/config/mesh" CertFile = "/etc/polaris-inject/certs/cert.pem" KeyFile = "/etc/polaris-inject/certs/key.pem" ) @@ -186,8 +187,7 @@ func initControllerConfig(s *options.KubeControllerManagerOptions) { if flags.polarisServerAddress != "" { polarisServerAddress = flags.polarisServerAddress } else { - // 启动参数没有指定,取 mesh config 中的地址 - polarisServerAddress = config.ServiceSync.ServerAddress + polarisServerAddress = config.getPolarisServerAddress() } // 去除前后的空格字符 polarisServerAddress = strings.TrimSpace(polarisServerAddress) @@ -196,9 +196,8 @@ func initControllerConfig(s *options.KubeControllerManagerOptions) { polarisapi.PolarisConfigGrpc = polarisServerAddress + ":8093" log.Infof("[Manager] polaris http address %s, discover grpc address %s, config grpc address %s", polarisapi.PolarisHttpURL, polarisapi.PolarisGrpc, polarisapi.PolarisConfigGrpc) - // 设置北极星开启鉴权之后,需要使用的访问token - polarisapi.PolarisAccessToken = config.ServiceSync.PolarisAccessToken - polarisapi.PolarisOperator = config.ServiceSync.Operator + polarisapi.PolarisAccessToken = config.getPolarisAccessToken() + polarisapi.PolarisOperator = config.getPolarisOperator() // 2. 配置 polaris 同步模式 if s.PolarisController.SyncMode == "" { @@ -247,15 +246,18 @@ func closeGrpcLog() { } func initPolarisSidecarInjector(c *options.CompletedConfig) error { - parameters := inject.WebhookParameters{ - DefaultSidecarMode: util.ParseSidecarMode(c.ComponentConfig.PolarisController.SidecarMode), + templateFilePath := config.TemplateFileConfig{ MeshConfigFile: MeshConfigFile, DnsConfigFile: DnsConfigFile, JavaAgentConfigFile: JavaAgentConfigFile, ValuesFile: ValuesFile, - MeshFile: MeshFile, + BootstrapConfigFile: BootstrapConfigFile, CertFile: CertFile, KeyFile: KeyFile, + } + parameters := inject.WebhookParameters{ + DefaultSidecarMode: util.ParseSidecarMode(c.ComponentConfig.PolarisController.SidecarMode), + TemplateFileConfig: templateFilePath, Port: flags.injectPort, HealthCheckInterval: 3 * time.Second, HealthCheckFile: "/tmp/health", diff --git a/deploy/kubernetes_v1.21/helm/templates/admission-webhooks/mutating-webhook.yaml b/deploy/kubernetes_v1.21/helm/templates/admission-webhooks/mutating-webhook.yaml index c1ec676e..84f00236 100644 --- a/deploy/kubernetes_v1.21/helm/templates/admission-webhooks/mutating-webhook.yaml +++ b/deploy/kubernetes_v1.21/helm/templates/admission-webhooks/mutating-webhook.yaml @@ -20,4 +20,40 @@ webhooks: failurePolicy: Fail namespaceSelector: matchLabels: - polaris-injection: enabled \ No newline at end of file + polaris-injection: enabled + - name: ns.injector.polarismesh.cn + clientConfig: + service: + name: polaris-sidecar-injector + namespace: polaris-system + path: "/inject" + caBundle: "" + rules: + - operations: ["CREATE"] + apiGroups: [""] + apiVersions: ["v1"] + resources: ["pods"] + admissionReviewVersions: ["v1"] + sideEffects: "None" + failurePolicy: Fail + namespaceSelector: + matchLabels: + polarismesh.cn/inject: enabled + - name: allowlist.polarismesh.cn + clientConfig: + service: + name: polaris-sidecar-injector + namespace: polaris-system + path: "/inject" + caBundle: "" + rules: + - operations: ["CREATE"] + apiGroups: [""] + apiVersions: ["v1"] + resources: ["pods"] + admissionReviewVersions: ["v1"] + sideEffects: "None" + failurePolicy: Fail + objectSelector: + matchLabels: + polarismesh.cn/inject: enabled \ No newline at end of file diff --git a/deploy/kubernetes_v1.21/helm/templates/controller-configmap-mesh.yaml b/deploy/kubernetes_v1.21/helm/templates/controller-configmap-mesh.yaml index e285c48b..db6c2fe4 100644 --- a/deploy/kubernetes_v1.21/helm/templates/controller-configmap-mesh.yaml +++ b/deploy/kubernetes_v1.21/helm/templates/controller-configmap-mesh.yaml @@ -61,22 +61,22 @@ data: - stdout errorOutputPaths: - stderr + # 北极星服务端地址 + serverAddress: {{ .Values.polaris.server.address }} + # 北极星服务端token(北极星开启鉴权时需要配置) + accessToken: {{ .Values.polaris.server.token }} + # 北极星主账户ID + operator: {{ .Values.polaris.server.operator }} # k8s cluster name clusterName: "{{ .Values.cluster.name }}" - # polaris-sidecar 注入的默认启动模式, 可以配置 mesh 或者 dns + # polaris-sidecar 注入的默认启动模式, 可以配置 java-agent, mesh 或者 dns sidecarInject: - mode: "{{ .Values.sidecar.mesh }}" + mode: "{{ .Values.sidecar.mode }}" # service sync serviceSync: mode: {{ .Values.polaris.sync.service.mode }} - serverAddress: {{ .Values.polaris.server.address }} - # 北极星开启鉴权时需要配置 - accessToken: {{ .Values.polaris.server.token }} configSync: enable: {{ .Values.polaris.sync.config.enable }} - serverAddress: {{ .Values.polaris.server.address }} - # 北极星开启鉴权时需要配置 - accessToken: {{ .Values.polaris.server.token }} allowDelete: {{ .Values.polaris.sync.config.allowDelete }} # 配置同步方向: kubernetesToPolaris|polarisToKubernetes|both syncDirection: {{ .Values.polaris.sync.config.direction }} diff --git a/deploy/kubernetes_v1.21/helm/values.yaml b/deploy/kubernetes_v1.21/helm/values.yaml index b37094de..1880651b 100644 --- a/deploy/kubernetes_v1.21/helm/values.yaml +++ b/deploy/kubernetes_v1.21/helm/values.yaml @@ -37,6 +37,7 @@ polaris: server: address: #POLARIS_HOST# token: #POLARIS_TOKEN# + operator: #POLARIS_OPERATOR# sync: service: mode: all diff --git a/deploy/kubernetes_v1.21/kubernetes/configmap.yaml b/deploy/kubernetes_v1.21/kubernetes/configmap.yaml index bf45c353..519e6243 100644 --- a/deploy/kubernetes_v1.21/kubernetes/configmap.yaml +++ b/deploy/kubernetes_v1.21/kubernetes/configmap.yaml @@ -61,25 +61,23 @@ data: - stdout errorOutputPaths: - stderr + # 北极星服务端地址 + serverAddress: #POLARIS_HOST# + # 北极星服务端token(北极星开启鉴权时需要配置) + accessToken: "#POLARIS_TOKEN#" + # 北极星主账户ID + operator: #POLARIS_OPERATOR# # k8s cluster name clusterName: "#CLUSTER_NAME#" - # polaris-sidecar 注入的默认启动模式, 可以配置 mesh 或者 dns + # polaris-sidecar 注入的默认启动模式, 可以配置 java-agent, mesh 或者 dns sidecarInject: - mode: "mesh" + mode: "" # service sync serviceSync: - enable: true - mode: "all" - serverAddress: #POLARIS_HOST# - # 北极星开启鉴权时需要配置 - accessToken: #POLARIS_TOKEN# + mode: #SYNC_MODE# configSync: - enable: true - serverAddress: #POLARIS_HOST# - # 北极星开启鉴权时需要配置 - accessToken: #POLARIS_TOKEN# + enable: false allowDelete: false - # 配置同步方向: kubernetesToPolaris|polarisToKubernetes|both syncDirection: both defaultGroup: "#CLUSTER_NAME#" defaultConfig: diff --git a/deploy/kubernetes_v1.21/kubernetes/injector.yaml b/deploy/kubernetes_v1.21/kubernetes/injector.yaml index a4ec5277..79fc1219 100644 --- a/deploy/kubernetes_v1.21/kubernetes/injector.yaml +++ b/deploy/kubernetes_v1.21/kubernetes/injector.yaml @@ -353,5 +353,43 @@ webhooks: namespaceSelector: matchLabels: polaris-injection: enabled + # 命名空间范围自动注入,新命名格式 + - name: ns.injector.polarismesh.cn + clientConfig: + service: + name: polaris-sidecar-injector + namespace: polaris-system + path: "/inject" + caBundle: "" + rules: + - operations: ["CREATE"] + apiGroups: [""] + apiVersions: ["v1"] + resources: ["pods"] + admissionReviewVersions: ["v1"] + sideEffects: "None" + failurePolicy: Fail + namespaceSelector: + matchLabels: + polarismesh.cn/inject: enabled + # 白名单功能, 支持按pod范围按需加载 + - name: allowlist.polarismesh.cn + clientConfig: + service: + name: polaris-sidecar-injector + namespace: polaris-system + path: "/inject" + caBundle: "" + rules: + - operations: ["CREATE"] + apiGroups: [""] + apiVersions: ["v1"] + resources: ["pods"] + admissionReviewVersions: ["v1"] + sideEffects: "None" + failurePolicy: Fail + objectSelector: + matchLabels: + polarismesh.cn/inject: enabled --- diff --git a/deploy/kubernetes_v1.22/helm/templates/admission-webhooks/mutating-webhook.yaml b/deploy/kubernetes_v1.22/helm/templates/admission-webhooks/mutating-webhook.yaml index aa494b7c..85740e5b 100644 --- a/deploy/kubernetes_v1.22/helm/templates/admission-webhooks/mutating-webhook.yaml +++ b/deploy/kubernetes_v1.22/helm/templates/admission-webhooks/mutating-webhook.yaml @@ -22,4 +22,40 @@ webhooks: failurePolicy: Fail namespaceSelector: matchLabels: - polaris-injection: enabled \ No newline at end of file + polaris-injection: enabled + - name: ns.injector.polarismesh.cn + clientConfig: + service: + name: polaris-sidecar-injector + namespace: polaris-system + path: "/inject" + caBundle: "" + rules: + - operations: ["CREATE"] + apiGroups: [""] + apiVersions: ["v1"] + resources: ["pods"] + admissionReviewVersions: ["v1"] + sideEffects: "None" + failurePolicy: Fail + namespaceSelector: + matchLabels: + polarismesh.cn/inject: enabled + - name: allowlist.polarismesh.cn + clientConfig: + service: + name: polaris-sidecar-injector + namespace: polaris-system + path: "/inject" + caBundle: "" + rules: + - operations: ["CREATE"] + apiGroups: [""] + apiVersions: ["v1"] + resources: ["pods"] + admissionReviewVersions: ["v1"] + sideEffects: "None" + failurePolicy: Fail + objectSelector: + matchLabels: + polarismesh.cn/inject: enabled \ No newline at end of file diff --git a/deploy/kubernetes_v1.22/helm/templates/controller-configmap-mesh.yaml b/deploy/kubernetes_v1.22/helm/templates/controller-configmap-mesh.yaml index e285c48b..db6c2fe4 100644 --- a/deploy/kubernetes_v1.22/helm/templates/controller-configmap-mesh.yaml +++ b/deploy/kubernetes_v1.22/helm/templates/controller-configmap-mesh.yaml @@ -61,22 +61,22 @@ data: - stdout errorOutputPaths: - stderr + # 北极星服务端地址 + serverAddress: {{ .Values.polaris.server.address }} + # 北极星服务端token(北极星开启鉴权时需要配置) + accessToken: {{ .Values.polaris.server.token }} + # 北极星主账户ID + operator: {{ .Values.polaris.server.operator }} # k8s cluster name clusterName: "{{ .Values.cluster.name }}" - # polaris-sidecar 注入的默认启动模式, 可以配置 mesh 或者 dns + # polaris-sidecar 注入的默认启动模式, 可以配置 java-agent, mesh 或者 dns sidecarInject: - mode: "{{ .Values.sidecar.mesh }}" + mode: "{{ .Values.sidecar.mode }}" # service sync serviceSync: mode: {{ .Values.polaris.sync.service.mode }} - serverAddress: {{ .Values.polaris.server.address }} - # 北极星开启鉴权时需要配置 - accessToken: {{ .Values.polaris.server.token }} configSync: enable: {{ .Values.polaris.sync.config.enable }} - serverAddress: {{ .Values.polaris.server.address }} - # 北极星开启鉴权时需要配置 - accessToken: {{ .Values.polaris.server.token }} allowDelete: {{ .Values.polaris.sync.config.allowDelete }} # 配置同步方向: kubernetesToPolaris|polarisToKubernetes|both syncDirection: {{ .Values.polaris.sync.config.direction }} diff --git a/deploy/kubernetes_v1.22/helm/values.yaml b/deploy/kubernetes_v1.22/helm/values.yaml index b37094de..1880651b 100644 --- a/deploy/kubernetes_v1.22/helm/values.yaml +++ b/deploy/kubernetes_v1.22/helm/values.yaml @@ -37,6 +37,7 @@ polaris: server: address: #POLARIS_HOST# token: #POLARIS_TOKEN# + operator: #POLARIS_OPERATOR# sync: service: mode: all diff --git a/deploy/kubernetes_v1.22/kubernetes/configmap.yaml b/deploy/kubernetes_v1.22/kubernetes/configmap.yaml index bf45c353..519e6243 100644 --- a/deploy/kubernetes_v1.22/kubernetes/configmap.yaml +++ b/deploy/kubernetes_v1.22/kubernetes/configmap.yaml @@ -61,25 +61,23 @@ data: - stdout errorOutputPaths: - stderr + # 北极星服务端地址 + serverAddress: #POLARIS_HOST# + # 北极星服务端token(北极星开启鉴权时需要配置) + accessToken: "#POLARIS_TOKEN#" + # 北极星主账户ID + operator: #POLARIS_OPERATOR# # k8s cluster name clusterName: "#CLUSTER_NAME#" - # polaris-sidecar 注入的默认启动模式, 可以配置 mesh 或者 dns + # polaris-sidecar 注入的默认启动模式, 可以配置 java-agent, mesh 或者 dns sidecarInject: - mode: "mesh" + mode: "" # service sync serviceSync: - enable: true - mode: "all" - serverAddress: #POLARIS_HOST# - # 北极星开启鉴权时需要配置 - accessToken: #POLARIS_TOKEN# + mode: #SYNC_MODE# configSync: - enable: true - serverAddress: #POLARIS_HOST# - # 北极星开启鉴权时需要配置 - accessToken: #POLARIS_TOKEN# + enable: false allowDelete: false - # 配置同步方向: kubernetesToPolaris|polarisToKubernetes|both syncDirection: both defaultGroup: "#CLUSTER_NAME#" defaultConfig: diff --git a/deploy/kubernetes_v1.22/kubernetes/polaris-controller.yaml b/deploy/kubernetes_v1.22/kubernetes/polaris-controller.yaml index c3361f9d..169d5021 100644 --- a/deploy/kubernetes_v1.22/kubernetes/polaris-controller.yaml +++ b/deploy/kubernetes_v1.22/kubernetes/polaris-controller.yaml @@ -51,6 +51,44 @@ webhooks: namespaceSelector: matchLabels: polaris-injection: enabled + # 命名空间范围自动注入,新命名格式 + - name: ns.injector.polarismesh.cn + clientConfig: + service: + name: polaris-sidecar-injector + namespace: polaris-system + path: "/inject" + caBundle: "" + rules: + - operations: ["CREATE"] + apiGroups: [""] + apiVersions: ["v1"] + resources: ["pods"] + admissionReviewVersions: ["v1"] + sideEffects: "None" + failurePolicy: Fail + namespaceSelector: + matchLabels: + polarismesh.cn/inject: enabled + # 白名单功能, 支持按pod范围按需加载 + - name: allowlist.polarismesh.cn + clientConfig: + service: + name: polaris-sidecar-injector + namespace: polaris-system + path: "/inject" + caBundle: "" + rules: + - operations: ["CREATE"] + apiGroups: [""] + apiVersions: ["v1"] + resources: ["pods"] + admissionReviewVersions: ["v1"] + sideEffects: "None" + failurePolicy: Fail + objectSelector: + matchLabels: + polarismesh.cn/inject: enabled --- apiVersion: apps/v1 kind: StatefulSet diff --git a/deploy/variables.txt b/deploy/variables.txt index e50d8a43..71849ad7 100644 --- a/deploy/variables.txt +++ b/deploy/variables.txt @@ -2,6 +2,7 @@ POLARIS_HOST:polaris.polaris-system CONTROLLER_VERSION:##VERSION## SIDECAR_VERSION:v1.5.1 POLARIS_TOKEN:nu/0WRA4EqSR1FagrjRj0fZwPXuGlMpX+zCuWu4uMqy8xr1vRjisSbA25aAC3mtU8MeeRsKhQiDAynUR09I= +POLARIS_OPERATOR:65e4789a6d5b49669adf1e9e8387549c ENVOY_VERSION:v1.26.2 CLUSTER_NAME:default JAVA_AGENT_INIT:v0.0.1 \ No newline at end of file diff --git a/go.mod b/go.mod index 68cc013f..6072bf27 100644 --- a/go.mod +++ b/go.mod @@ -32,9 +32,12 @@ require ( require ( github.com/polarismesh/specification v1.4.2-alpha.6 + github.com/stretchr/testify v1.8.2 google.golang.org/protobuf v1.33.0 ) +require github.com/pmezard/go-difflib v1.0.0 // indirect + require ( github.com/NYTimes/gziphandler v1.1.1 // indirect github.com/beorn7/perks v1.0.1 // indirect diff --git a/pkg/inject/pkg/config/inject_config.go b/pkg/inject/pkg/config/inject_config.go new file mode 100644 index 00000000..c057a0c2 --- /dev/null +++ b/pkg/inject/pkg/config/inject_config.go @@ -0,0 +1,26 @@ +package config + +import ( + "crypto/sha256" + "crypto/tls" + "encoding/hex" + + "github.com/polarismesh/polaris-controller/pkg/inject/pkg/config/mesh" +) + +// InjectConfigInfo is a struct that contains all the configuration +type InjectConfigInfo struct { + MeshInjectConf *TemplateConfig + DnsInjectConf *TemplateConfig + JavaAgentInjectConf *TemplateConfig + MeshEnvoyConf *mesh.MeshEnvoyConfig + ValuesConf string + CertPair *tls.Certificate +} + +// helper function to generate a template version identifier from a +// hash of the un-executed template contents. +func sidecarTemplateVersionHash(in string) string { + hash := sha256.Sum256([]byte(in)) + return hex.EncodeToString(hash[:]) +} diff --git a/pkg/inject/pkg/config/mesh/mesh.go b/pkg/inject/pkg/config/mesh/mesh.go index 835524f1..9cf50589 100644 --- a/pkg/inject/pkg/config/mesh/mesh.go +++ b/pkg/inject/pkg/config/mesh/mesh.go @@ -15,62 +15,98 @@ package mesh import ( + "fmt" "os" "github.com/hashicorp/go-multierror" "gopkg.in/yaml.v2" ) -type MeshConfig struct { - DefaultConfig *DefaultConfig `yaml:"defaultConfig"` +// MeshEnvoyConfig mesh 注入配置, envoy sidecar当前有用到 +type MeshEnvoyConfig struct { + defaultConfig *DefaultConfig `yaml:"DefaultConfig"` } -func (m *MeshConfig) Clone() *MeshConfig { - copyData := &MeshConfig{ - DefaultConfig: &DefaultConfig{ - ProxyMetadata: map[string]string{}, +// DefaultConfig 存储北极星proxy默认配置和用户自定义配置 +type DefaultConfig struct { + proxyMetadata map[string]string `yaml:"proxyMetadata"` +} + +// ReadMeshEnvoyConfig 读取mesh envoy sidecar注入配置 +func ReadMeshEnvoyConfig(filename string) (*MeshEnvoyConfig, error) { + yamlBytes, err := os.ReadFile(filename) + if err != nil { + return nil, multierror.Prefix(err, "cannot read mesh config file") + } + defaultConfig := &MeshEnvoyConfig{ + defaultConfig: &DefaultConfig{ + proxyMetadata: map[string]string{}, }, } + if err = yaml.Unmarshal(yamlBytes, defaultConfig); err != nil { + return nil, err + } + return defaultConfig, nil +} - for k, v := range m.DefaultConfig.ProxyMetadata { - copyData.DefaultConfig.ProxyMetadata[k] = v +// GetDefaultConfig 获取默认配置 +func (ic *MeshEnvoyConfig) GetDefaultConfig() *DefaultConfig { + if ic == nil { + return nil } - return copyData + return ic.defaultConfig } -type DefaultConfig struct { - ProxyMetadata map[string]string `yaml:"proxyMetadata"` +// SetDefaultConfig 设置默认配置 +func (ic *MeshEnvoyConfig) SetDefaultConfig(config *DefaultConfig) { + if ic == nil { + return + } + ic.defaultConfig = config } -// DefaultMeshConfig configuration -func DefaultMeshConfig() MeshConfig { - return MeshConfig{ - DefaultConfig: &DefaultConfig{ - ProxyMetadata: map[string]string{}, - }, +// GetProxyMetadata 获取 proxy 元数据 +func (dc *DefaultConfig) GetProxyMetadata() map[string]string { + if dc == nil { + return nil } + return dc.proxyMetadata } -// ApplyMeshConfig returns a new MeshConfig decoded from the -// input YAML with the provided defaults applied to omitted configuration values. -func ApplyMeshConfig(str string, defaultConfig MeshConfig) (*MeshConfig, error) { - if err := yaml.Unmarshal([]byte(str), &defaultConfig); err != nil { - return nil, err +// SetProxyMetadataWithKV 设置 proxy 元数据 +func (dc *MeshEnvoyConfig) SetProxyMetadataWithKV(k, v string) { + if dc == nil { + return } - return &defaultConfig, nil + dc.defaultConfig.proxyMetadata[k] = v } -// ApplyMeshConfigDefaults returns a new MeshConfig decoded from the -// input YAML with defaults applied to omitted configuration values. -func ApplyMeshConfigDefaults(yaml string) (*MeshConfig, error) { - return ApplyMeshConfig(yaml, DefaultMeshConfig()) +// String 返回 MeshEnvoyConfig 的字符串表示 +func (ic *MeshEnvoyConfig) String() string { + if ic == nil { + return "MeshEnvoyConfig{nil}" + } + + var defaultConfig string + if ic.defaultConfig == nil { + defaultConfig = "nil" + } else { + defaultConfig = ic.defaultConfig.String() + } + + return fmt.Sprintf("MeshEnvoyConfig{DefaultConfig: %s}", defaultConfig) } -// ReadMeshConfig gets mesh configuration from a config file -func ReadMeshConfig(filename string) (*MeshConfig, error) { - yaml, err := os.ReadFile(filename) - if err != nil { - return nil, multierror.Prefix(err, "cannot read mesh config file") +// String 返回 DefaultConfig 的字符串表示 +func (dc *DefaultConfig) String() string { + if dc == nil { + return "DefaultConfig{nil}" } - return ApplyMeshConfigDefaults(string(yaml)) + + metadata := "nil" + if dc.proxyMetadata != nil { + metadata = fmt.Sprintf("%v", dc.proxyMetadata) + } + + return fmt.Sprintf("DefaultConfig{proxyMetadata: %s}", metadata) } diff --git a/pkg/inject/pkg/config/safe_config.go b/pkg/inject/pkg/config/safe_config.go new file mode 100644 index 00000000..aacbaf8a --- /dev/null +++ b/pkg/inject/pkg/config/safe_config.go @@ -0,0 +1,164 @@ +package config + +import ( + "crypto/tls" + "sync" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/polarismesh/polaris-controller/common/log" + "github.com/polarismesh/polaris-controller/pkg/inject/pkg/config/mesh" +) + +type SafeTemplateConfig struct { + mu sync.RWMutex + // envoy mesh 场景下的 sidecar 注入配置 + sidecarMeshTemplate *TemplateConfig + sidecarMeshTemplateVersion string + // dns 场景下的 sidecar 注入配置 + sidecarDnsTemplate *TemplateConfig + sidecarDnsTemplateVersion string + // java agent 场景下的注入配置 + sidecarJavaAgentTemplate *TemplateConfig + sidecarJavaAgentTemplateVersion string + // 北极星proxy配置 + meshEnvoyConfig *mesh.MeshEnvoyConfig + valuesConfig string + cert *tls.Certificate +} + +// TemplateConfig specifies the sidecar injection configuration This includes +// the sidecar template and cluster-side injection policy. It is used +// by kube-inject, sidecar injector, and http endpoint. +type TemplateConfig struct { + Policy InjectionPolicy `json:"policy"` + + // Template is the templated version of `SidecarInjectionSpec` prior to + // expansion over the `SidecarTemplateData`. + Template string `json:"template"` + + // NeverInjectSelector: Refuses the injection on pods whose labels match this selector. + // It's an array of label selectors, that will be OR'ed, meaning we will iterate + // over it and stop at the first match + // Takes precedence over AlwaysInjectSelector. + NeverInjectSelector []metav1.LabelSelector `json:"neverInjectSelector"` + + // AlwaysInjectSelector: Forces the injection on pods whose labels match this selector. + // It's an array of label selectors, that will be OR'ed, meaning we will iterate + // over it and stop at the first match + AlwaysInjectSelector []metav1.LabelSelector `json:"alwaysInjectSelector"` + + // InjectedAnnotations are additional annotations that will be added to the pod spec after injection + // This is primarily to support PSP annotations. + InjectedAnnotations map[string]string `json:"injectedAnnotations"` +} + +// InjectionPolicy determines the policy for injecting the +// sidecar proxy into the watched namespace(s). +type InjectionPolicy string + +const ( + // InjectionPolicyDisabled specifies that the sidecar injector + // will not inject the sidecar into resources by default for the + // namespace(s) being watched. Resources can enable injection + // using the "sidecar.polarismesh.cn/inject" annotation with value of + // true. + InjectionPolicyDisabled InjectionPolicy = "disabled" + + // InjectionPolicyEnabled specifies that the sidecar injector will + // inject the sidecar into resources by default for the + // namespace(s) being watched. Resources can disable injection + // using the "sidecar.polarismesh.cn/inject" annotation with value of + // false. + InjectionPolicyEnabled InjectionPolicy = "enabled" +) + +// NewTemplateConfig 创建模板配置 +func NewTemplateConfig(p TemplateFileConfig) (*SafeTemplateConfig, error) { + injectConf, err := loadConfig(p) + if err != nil { + log.InjectScope().Errorf("Failed to load inject config: %v", err) + return nil, err + } + return &SafeTemplateConfig{ + sidecarMeshTemplate: injectConf.MeshInjectConf, + sidecarMeshTemplateVersion: sidecarTemplateVersionHash(injectConf.MeshInjectConf.Template), + sidecarDnsTemplate: injectConf.DnsInjectConf, + sidecarDnsTemplateVersion: sidecarTemplateVersionHash(injectConf.DnsInjectConf.Template), + sidecarJavaAgentTemplate: injectConf.JavaAgentInjectConf, + sidecarJavaAgentTemplateVersion: sidecarTemplateVersionHash(injectConf.JavaAgentInjectConf.Template), + meshEnvoyConfig: injectConf.MeshEnvoyConf, + valuesConfig: injectConf.ValuesConf, + cert: injectConf.CertPair, + }, nil +} + +// UpdateTemplateConfig 更新模板配置 +func (tc *SafeTemplateConfig) UpdateTemplateConfig(p TemplateFileConfig) error { + injectConf, err := loadConfig(p) + if err != nil { + log.InjectScope().Errorf("Failed to load inject config: %v", err) + return err + } + tc.mu.Lock() + defer tc.mu.Unlock() + tc.sidecarMeshTemplate = injectConf.MeshInjectConf + tc.sidecarMeshTemplateVersion = sidecarTemplateVersionHash(injectConf.MeshInjectConf.Template) + tc.sidecarDnsTemplate = injectConf.DnsInjectConf + tc.sidecarDnsTemplateVersion = sidecarTemplateVersionHash(injectConf.DnsInjectConf.Template) + tc.sidecarJavaAgentTemplate = injectConf.JavaAgentInjectConf + tc.sidecarJavaAgentTemplateVersion = sidecarTemplateVersionHash(injectConf.JavaAgentInjectConf.Template) + tc.meshEnvoyConfig = injectConf.MeshEnvoyConf + tc.valuesConfig = injectConf.ValuesConf + tc.cert = injectConf.CertPair + return nil +} + +// GetSidecarMeshTemplateAndVersion 获取sidecar mesh 注入配置模板 +func (tc *SafeTemplateConfig) GetSidecarMeshTemplateAndVersion() (*TemplateConfig, string) { + tc.mu.RLock() + defer tc.mu.RUnlock() + return tc.sidecarMeshTemplate, tc.sidecarMeshTemplateVersion +} + +// GetSidecarDnsTemplateAndVersion 获取sidecar dns 注入配置模板 +func (tc *SafeTemplateConfig) GetSidecarDnsTemplateAndVersion() (*TemplateConfig, string) { + tc.mu.RLock() + defer tc.mu.RUnlock() + return tc.sidecarDnsTemplate, tc.sidecarDnsTemplateVersion +} + +// GetSidecarJavaAgentTemplateAndVersion 获取sidecar java agent 注入配置模板 +func (tc *SafeTemplateConfig) GetSidecarJavaAgentTemplateAndVersion() (*TemplateConfig, string) { + tc.mu.RLock() + defer tc.mu.RUnlock() + return tc.sidecarJavaAgentTemplate, tc.sidecarJavaAgentTemplateVersion +} + +// GetCert 获取证书 +func (tc *SafeTemplateConfig) GetCert(*tls.ClientHelloInfo) (*tls.Certificate, error) { + tc.mu.RLock() + defer tc.mu.RUnlock() + return tc.cert, nil +} + +// GetMeshEnvoyConfig returns the mesh envoy configuration in a thread-safe way +func (s *SafeTemplateConfig) GetMeshEnvoyConfig() *mesh.MeshEnvoyConfig { + s.mu.RLock() + defer s.mu.RUnlock() + return s.meshEnvoyConfig +} + +// SetMeshEnvoyConfig sets the mesh envoy configuration in a thread-safe way +func (s *SafeTemplateConfig) SetMeshEnvoyConfigWithKV(k, v string) { + s.mu.Lock() + defer s.mu.Unlock() + s.meshEnvoyConfig.SetProxyMetadataWithKV(k, v) +} + +// GetValuesConfig returns the values configuration in a thread-safe way +func (s *SafeTemplateConfig) GetValuesConfig() string { + s.mu.RLock() + defer s.mu.RUnlock() + return s.valuesConfig +} diff --git a/pkg/inject/pkg/config/template_file.go b/pkg/inject/pkg/config/template_file.go new file mode 100644 index 00000000..d25326a2 --- /dev/null +++ b/pkg/inject/pkg/config/template_file.go @@ -0,0 +1,123 @@ +package config + +import ( + "crypto/sha256" + "crypto/tls" + "os" + "strings" + + gyaml "github.com/ghodss/yaml" + + "github.com/polarismesh/polaris-controller/common/log" + "github.com/polarismesh/polaris-controller/pkg/inject/pkg/config/mesh" +) + +type TemplateFileConfig struct { + // MeshConfigFile 处理 polaris-sidecar 运行模式为 mesh 的配置文件 + MeshConfigFile string + + // DnsConfigFile 处理 polaris-sidecar 运行模式为 dns 的配置文件 + DnsConfigFile string + + // JavaAgentConfigFile 处理运行模式为 javaagent 的配置文件 + JavaAgentConfigFile string + + ValuesFile string + + // BootstrapConfigFile is the path to the mesh configuration file. + BootstrapConfigFile string + + // CertFile is the path to the x509 certificate for https. + CertFile string + + // KeyFile is the path to the x509 private key matching `CertFile`. + KeyFile string +} + +// env will be used for other things besides meshEnvoyConfig - when webhook is running in Istiod it can take advantage +// of the config and endpoint cache. +// nolint +func loadConfig(p TemplateFileConfig) (*InjectConfigInfo, error) { + // 读取 mesh envoy模式的配置模板 + meshData, err := os.ReadFile(p.MeshConfigFile) + if err != nil { + return nil, err + } + var meshConf TemplateConfig + if err := gyaml.Unmarshal(meshData, &meshConf); err != nil { + log.InjectScope().Warnf("Failed to parse inject mesh config file %s", string(meshData)) + return nil, err + } + log.InjectScope().Infof("[MESH] New inject configuration: sha256sum %x", sha256.Sum256(meshData)) + log.InjectScope().Infof("[MESH] Policy: %v", meshConf.Policy) + log.InjectScope().Infof("[MESH] AlwaysInjectSelector: %v", meshConf.AlwaysInjectSelector) + log.InjectScope().Infof("[MESH] NeverInjectSelector: %v", meshConf.NeverInjectSelector) + log.InjectScope().Infof("[MESH] Template: |\n %v", strings.Replace(meshConf.Template, "\n", "\n ", -1)) + + // 读取 dns 模式的配置模板 + dnsData, err := os.ReadFile(p.DnsConfigFile) + if err != nil { + return nil, err + } + var dnsConf TemplateConfig + if err := gyaml.Unmarshal(dnsData, &dnsConf); err != nil { + log.InjectScope().Warnf("Failed to parse inject dns config file %s", string(dnsData)) + return nil, err + } + log.InjectScope().Infof("[DNS] New inject configuration: sha256sum %x", sha256.Sum256(dnsData)) + log.InjectScope().Infof("[DNS] Policy: %v", dnsConf.Policy) + log.InjectScope().Infof("[DNS] AlwaysInjectSelector: %v", dnsConf.AlwaysInjectSelector) + log.InjectScope().Infof("[DNS] NeverInjectSelector: %v", dnsConf.NeverInjectSelector) + log.InjectScope().Infof("[DNS] Template: |\n %v", strings.Replace(dnsConf.Template, "\n", "\n ", -1)) + + // 读取 javaagent 模式的配置模板 + javaAgentData, err := os.ReadFile(p.JavaAgentConfigFile) + if err != nil { + return nil, err + } + var javaAgentConf TemplateConfig + if err := gyaml.Unmarshal(javaAgentData, &javaAgentConf); err != nil { + log.InjectScope().Warnf("Failed to parse inject java-agent config file %s", string(dnsData)) + return nil, err + } + log.InjectScope().Infof("[JavaAgent] New inject configuration: sha256sum %x", sha256.Sum256(javaAgentData)) + log.InjectScope().Infof("[JavaAgent] AlwaysInjectSelector: %v", javaAgentConf.AlwaysInjectSelector) + log.InjectScope().Infof("[JavaAgent] NeverInjectSelector: %v", javaAgentConf.NeverInjectSelector) + log.InjectScope().Infof("[JavaAgent] Template: |\n %v", strings.Replace(javaAgentConf.Template, "\n", "\n ", -1)) + + // 读取 values + valuesConfig, err := os.ReadFile(p.ValuesFile) + if err != nil { + return nil, err + } + log.InjectScope().Infof("[ValuesConfig] New inject configuration: sha256sum %x", sha256.Sum256(valuesConfig)) + + // 读取 inject 配置 + meshEnvoyConfig, err := mesh.ReadMeshEnvoyConfig(p.BootstrapConfigFile) + if err != nil { + return nil, err + } + log.InjectScope().Infof("[MeshEnvoyConfig] New inject configuration: sha256sum %x", sha256.Sum256([]byte( + meshEnvoyConfig.String()))) + + // 读取 TLS 证书 + pair, err := tls.LoadX509KeyPair(p.CertFile, p.KeyFile) + if err != nil { + log.InjectScope().Errorf("Failed to load TLS certificate: %v", err) + return nil, err + } + log.InjectScope().Infof("[X509KeyPair] New inject configuration: sha256sum %x", sha256.Sum256(javaAgentData)) + + return &InjectConfigInfo{ + MeshInjectConf: &meshConf, + DnsInjectConf: &dnsConf, + JavaAgentInjectConf: &javaAgentConf, + MeshEnvoyConf: meshEnvoyConfig, + ValuesConf: string(valuesConfig), + CertPair: &pair, + }, nil +} + +func (p TemplateFileConfig) GetWatchList() []string { + return []string{p.MeshConfigFile, p.DnsConfigFile, p.JavaAgentConfigFile, p.CertFile, p.KeyFile} +} diff --git a/pkg/inject/pkg/kube/inject/apply/javaagent/patch.go b/pkg/inject/pkg/kube/inject/apply/javaagent/patch.go index 48235be4..0824d5bf 100644 --- a/pkg/inject/pkg/kube/inject/apply/javaagent/patch.go +++ b/pkg/inject/pkg/kube/inject/apply/javaagent/patch.go @@ -56,6 +56,8 @@ var oldAgentVersions = map[string]struct{}{ const ( ActiveJavaAgentCmd = "-javaagent:/app/lib/.polaris/java_agent/polaris-java-agent/polaris-agent-core-bootstrap.jar" OldActiveJavaAgentCmd = "-javaagent:/app/lib/.polaris/java_agent/polaris-java-agent-%s/polaris-agent-core-bootstrap.jar" + + javaagentInitContainer = "polaris-javaagent-init" ) func init() { @@ -75,7 +77,7 @@ func (pb *PodPatchBuilder) PatchContainer(req *inject.OperateContainerRequest) ( pod := req.Option.Pod added := req.External for index, add := range added { - if add.Name == "polaris-javaagent-init" { + if add.Name == javaagentInitContainer { log.InjectScope().Infof("begin deal polaris-javaagent-init inject for pod=[%s, %s]", pod.Namespace, pod.Name) if err := pb.handleJavaAgentInit(req.Option, pod, &add); err != nil { log.InjectScope().Errorf("handle polaris-javaagent-init inject for pod=[%s, %s] failed: %v", pod.Namespace, pod.Name, err) @@ -136,7 +138,8 @@ func (pb *PodPatchBuilder) handleJavaAgentInit(opt *inject.PatchOptions, pod *co } defaultParam := map[string]string{ - "MicroserviceName": opt.Annotations[util.SidecarServiceName], + "MicroserviceName": opt.Annotations[util.SidecarServiceName], + // TODO: 添加服务注册命名空间 "PolarisServerIP": strings.Split(polarisapi.PolarisGrpc, ":")[0], "PolarisDiscoverPort": strings.Split(polarisapi.PolarisGrpc, ":")[1], "PolarisConfigIP": strings.Split(polarisapi.PolarisConfigGrpc, ":")[0], diff --git a/pkg/inject/pkg/kube/inject/apply/mesh/patch.go b/pkg/inject/pkg/kube/inject/apply/mesh/patch.go index 434fd604..ba6db0e9 100644 --- a/pkg/inject/pkg/kube/inject/apply/mesh/patch.go +++ b/pkg/inject/pkg/kube/inject/apply/mesh/patch.go @@ -81,6 +81,7 @@ func (pb *PodPatchBuilder) PatchContainer(req *inject.OperateContainerRequest) ( return pb.PodPatchBuilder.PatchContainer(req) } +// handlePolarisSidecarEnvInject 处理polaris-sidecar容器的环境变量 func (pb *PodPatchBuilder) handlePolarisSidecarEnvInject(opt *inject.PatchOptions, pod *corev1.Pod, add *corev1.Container) (bool, error) { err := pb.ensureRootCertExist(opt.KubeClient, pod) diff --git a/pkg/inject/pkg/kube/inject/base.go b/pkg/inject/pkg/kube/inject/base.go new file mode 100644 index 00000000..e8b31574 --- /dev/null +++ b/pkg/inject/pkg/kube/inject/base.go @@ -0,0 +1,244 @@ +package inject + +import ( + "fmt" + "strings" + "text/template" + + "github.com/ghodss/yaml" + "github.com/hashicorp/go-multierror" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + + "github.com/polarismesh/polaris-controller/common/log" + "github.com/polarismesh/polaris-controller/pkg/inject/api/annotation" + "github.com/polarismesh/polaris-controller/pkg/inject/pkg/config" + utils "github.com/polarismesh/polaris-controller/pkg/util" +) + +// getPodPatch 处理 admission webhook 请求 +// 返回值: +// +// patchBytes: []byte - 包含需要应用到资源上的 JSON patch 数据。如果不需要修改,则为 nil +// err: error - 处理过程中遇到的错误 +// - nil: 表示处理成功 +// - non-nil: 表示处理过程中出现错误,错误信息包含在 error 中 +func (wh *Webhook) getPodPatch(p *podDataInfo) ([]byte, error) { + // 检查Pod元数据是否合法 + passed, err := p.checkPodData() + if err != nil || !passed { + log.InjectScope().Errorf("[Webhook] skip due to checkPodData result:%v, error: %v", passed, err) + return nil, err + } + + // 检查Pod是否需要注入,过滤掉某些不需要注入的pod + if !wh.requireInject(p) { + skipReason := fmt.Sprintf("policy check failed for namespace=%s, podName=%s, injectConfig=%v", + p.podObject.Namespace, p.podName, p.injectTemplateConfig) + log.InjectScope().Infof("Skipping due to: %s", skipReason) + return nil, nil + } + + // 获取注入后的annotations + sidecarTemplate := p.injectTemplateConfig.Template + values := map[string]interface{}{} + valuesConfig := wh.templateConfig.GetValuesConfig() + if err := yaml.Unmarshal([]byte(wh.templateConfig.GetValuesConfig()), &values); err != nil { + log.InjectScope().Infof("[Webhook] failed to parse values config: %v [%v]\n", err, valuesConfig) + return nil, multierror.Prefix(err, "could not parse configuration values:") + } + metadataCopy := p.podObject.ObjectMeta.DeepCopy() + metadataCopy.Annotations = p.injectedAnnotations + templateData := SidecarTemplateData{ + TypeMeta: p.workloadType, + DeploymentMeta: p.workloadMeta, + ObjectMeta: metadataCopy, + Spec: &p.podObject.Spec, + ProxyConfig: wh.templateConfig.GetMeshEnvoyConfig().GetDefaultConfig(), + Values: values, + } + + funcMap := template.FuncMap{ + "formatDuration": formatDuration, + "isset": isset, + "excludeInboundPort": excludeInboundPort, + "includeInboundPorts": includeInboundPorts, + "kubevirtInterfaces": kubevirtInterfaces, + "applicationPorts": applicationPorts, + "annotation": getAnnotation, + "valueOrDefault": valueOrDefault, + "toJSON": toJSON, + "toJson": toJSON, // Used by, e.g. Istio 1.0.5 template sidecar-injector-configmap.yaml + "fromJSON": fromJSON, + "structToJSON": structToJSON, + "protoToJSON": protoToJSON, + "toYaml": toYaml, + "indent": indent, + "directory": directory, + "contains": flippedContains, + "toLower": strings.ToLower, + "openTlsMode": openTlsMode, + "env": env, + "render": render, + } + + bbuf, err := parseTemplate(sidecarTemplate, funcMap, templateData) + if err != nil { + return nil, err + } + + var injectData SidecarInjectionSpec + if err := yaml.Unmarshal(bbuf.Bytes(), &injectData); err != nil { + // This usually means an invalid injector template; we can't check + // the template itself because it is merely a string. + log.InjectScope().Warnf("Failed to unmarshal template %v \n%s", err, bbuf.String()) + return nil, multierror.Prefix(err, "failed parsing injected YAML (check sidecar injector configuration):") + } + + // set sidecar --concurrency + applyConcurrency(injectData.Containers) + + // 生成POD修改的patch + opt := &PatchOptions{ + Pod: p.podObject, + KubeClient: wh.k8sClient, + PrevStatus: injectionStatus(p.podObject), + SidecarMode: p.injectMode, + WorkloadName: p.workloadMeta.Name, + Sic: &injectData, + Annotations: p.injectedAnnotations, + ExternalInfo: map[string]string{}, + } + patchBytes, err := createPatch(opt) + if err != nil { + log.InjectScope().Errorf(fmt.Sprintf("AdmissionResponse: err=%v injectData=%v\n", err, injectData)) + return nil, err + } + return patchBytes, err +} + +func (wh *Webhook) requireInject(p *podDataInfo) bool { + switch p.injectMode { + case utils.SidecarForMesh: + return wh.meshInjectRequired(p) + case utils.SidecarForJavaAgent, utils.SidecarForDns: + return wh.commonInjectRequired(p) + default: + return false + } +} + +// 是否需要注入, 规则参考istio官方定义 +// https://istio.io/latest/zh/docs/ops/common-problems/injection/ +func (wh *Webhook) commonInjectRequired(p *podDataInfo) bool { + pod := p.podObject + templateConfig := p.injectTemplateConfig + + if isIgnoredNamespace(pod.Namespace) { + return false + } + + // annotations为最高优先级 + injectionRequested, useDefaultPolicy := parseInjectionAnnotation(pod.GetAnnotations()) + log.InjectScope().Infof("parseInjectionAnnotation for %s/%s: UseDefault=%v injectionRequested=%v", + pod.Namespace, pod.Name, useDefaultPolicy, injectionRequested) + + // Labels为次优先级 + if useDefaultPolicy { + injectionRequested, useDefaultPolicy = evaluateSelectors(pod, templateConfig, p.podName) + log.InjectScope().Infof("evaluateSelectors for %s/%s: UseDefault=%v injectionRequested=%v", + pod.Namespace, pod.Name, useDefaultPolicy, injectionRequested) + } + + // Policy为最低优先级 + required := determineInjectionRequirement(templateConfig.Policy, useDefaultPolicy, injectionRequested) + log.InjectScope().Infof("determineInjectionRequirement for %s/%s: Policy=%s UseDefault=%v Requested=%v Required=%v", + pod.Namespace, pod.Name, templateConfig.Policy, useDefaultPolicy, injectionRequested, required) + + return required +} + +func isIgnoredNamespace(namespace string) bool { + for _, ignored := range ignoredNamespaces { + if namespace == ignored { + return true + } + } + return false +} + +// 解析Annotation, 用于注解位置的黑白名单功能 +func parseInjectionAnnotation(annotations map[string]string) (requested bool, useDefault bool) { + var value string + newFlag, newExists := annotations[utils.PolarisInjectionKey] + if newExists { + value = strings.ToLower(newFlag) + } else { + if flag, ok := annotations[annotation.SidecarInject.Name]; ok { + value = strings.ToLower(flag) + } + } + switch value { + case "y", "yes", "true", "on", "enable", "enabled": + // annotation白名单, 显示开启 + return true, false + case "n", "no", "false", "off", "disable", "disabled": + // annotation黑名单, 显示关闭 + return false, false + default: // including empty string + return false, true + } +} + +// 检查label的黑白名单功能 +func evaluateSelectors(pod *corev1.Pod, config *config.TemplateConfig, podName string) (bool, bool) { + // Check NeverInject selectors first + if inject, ok := checkSelectors(pod, config.NeverInjectSelector, "NeverInjectSelector", podName, false); ok { + return inject, false + } + + // Then check AlwaysInject selectors + if inject, ok := checkSelectors(pod, config.AlwaysInjectSelector, "AlwaysInjectSelector", podName, true); ok { + return inject, false + } + + return false, true +} + +func checkSelectors(pod *corev1.Pod, selectors []metav1.LabelSelector, selectorType string, podName string, + allowInject bool) (bool, bool) { + for _, selector := range selectors { + ls, err := metav1.LabelSelectorAsSelector(&selector) + if err != nil { + log.InjectScope().Warnf("Invalid %s: %v (%v)", selectorType, selector, err) + continue // Continue checking other selectors + } + + if !ls.Empty() && ls.Matches(labels.Set(pod.Labels)) { + log.InjectScope().Infof("Pod %s/%s: %s matched labels %v", + pod.Namespace, podName, selectorType, pod.Labels) + return allowInject, true + } + } + return false, false +} + +func determineInjectionRequirement(policy config.InjectionPolicy, useDefault bool, requested bool) bool { + switch policy { + case config.InjectionPolicyEnabled: + if useDefault { + return true + } + return requested + case config.InjectionPolicyDisabled: + if useDefault { + return false + } + return requested + default: + log.InjectScope().Errorf("Invalid injection policy: %s. Valid values: [%s, %s]", + policy, config.InjectionPolicyDisabled, config.InjectionPolicyEnabled) + return false + } +} diff --git a/pkg/inject/pkg/kube/inject/base_test.go b/pkg/inject/pkg/kube/inject/base_test.go new file mode 100644 index 00000000..5bcc047d --- /dev/null +++ b/pkg/inject/pkg/kube/inject/base_test.go @@ -0,0 +1,173 @@ +package inject + +import ( + "testing" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/polarismesh/polaris-controller/pkg/inject/api/annotation" + "github.com/polarismesh/polaris-controller/pkg/inject/pkg/config" + utils "github.com/polarismesh/polaris-controller/pkg/util" +) + +func TestCommonInjectRequired(t *testing.T) { + // 通用测试配置 + defaultTemplate := &config.TemplateConfig{ + NeverInjectSelector: []metav1.LabelSelector{{MatchLabels: map[string]string{ + utils.PolarisInjectionKey: utils.PolarisInjectionDisabled}}}, + AlwaysInjectSelector: []metav1.LabelSelector{{MatchLabels: map[string]string{ + utils.PolarisInjectionKey: utils.PolarisInjectionEnabled}}}, + Policy: config.InjectionPolicyEnabled, + } + + // 参考istio官方定义 + // https://istio.io/latest/zh/docs/ops/common-problems/injection/ + testCases := []struct { + name string + podSetup func(*corev1.Pod, *config.TemplateConfig) + expected bool + }{ + { + name: "在kube-system命名空间中跳过注入", + podSetup: func(p *corev1.Pod, _ *config.TemplateConfig) { + p.Namespace = "kube-system" + }, + expected: false, + }, + { + name: "Annotation白名单,当注解明确启用时应该注入", + podSetup: func(p *corev1.Pod, _ *config.TemplateConfig) { + p.Annotations = map[string]string{annotation.SidecarInject.Name: "true"} + }, + expected: true, + }, + { + name: "Annotation黑名单,当注解明确禁用时不注入", + podSetup: func(p *corev1.Pod, _ *config.TemplateConfig) { + p.Annotations = map[string]string{annotation.SidecarInject.Name: "false"} + }, + expected: false, + }, + { + name: "Label黑名单,当匹配NeverInjectSelector时不注入", + podSetup: func(p *corev1.Pod, _ *config.TemplateConfig) { + p.Labels = map[string]string{utils.PolarisInjectionKey: utils.PolarisInjectionDisabled} + }, + expected: false, + }, + { + name: "Label白名单功能,当匹配AlwaysInjectSelector时注入", + podSetup: func(p *corev1.Pod, _ *config.TemplateConfig) { + p.Labels = map[string]string{utils.PolarisInjectionKey: utils.PolarisInjectionEnabled} + }, + expected: true, + }, + { + name: "Policy白名单,默认策略启用时自动注入", + podSetup: func(p *corev1.Pod, defaultTemplate *config.TemplateConfig) { + defaultTemplate.Policy = config.InjectionPolicyEnabled + }, + expected: true, + }, + { + name: "Policy黑名单,默认策略禁用时不注入", + podSetup: func(p *corev1.Pod, defaultTemplate *config.TemplateConfig) { + defaultTemplate.Policy = config.InjectionPolicyDisabled + }, + expected: false, + }, + { + name: "Annotation白名单,Label黑名单,注入", + podSetup: func(p *corev1.Pod, _ *config.TemplateConfig) { + p.Annotations = map[string]string{annotation.SidecarInject.Name: "true"} + p.Labels = map[string]string{utils.PolarisInjectionKey: utils.PolarisInjectionDisabled} + }, + expected: true, + }, + { + name: "Annotation白名单,Policy黑名单,注入", + podSetup: func(p *corev1.Pod, defaultTemplate *config.TemplateConfig) { + p.Annotations = map[string]string{annotation.SidecarInject.Name: "true"} + defaultTemplate.Policy = config.InjectionPolicyDisabled + }, + expected: true, + }, + { + name: "Annotation黑名单,Label白名单,不注入", + podSetup: func(p *corev1.Pod, _ *config.TemplateConfig) { + p.Annotations = map[string]string{annotation.SidecarInject.Name: "false"} + p.Labels = map[string]string{utils.PolarisInjectionKey: utils.PolarisInjectionEnabled} + }, + expected: false, + }, + { + name: "Annotation黑名单,Policy白名单,不注入", + podSetup: func(p *corev1.Pod, _ *config.TemplateConfig) { + p.Annotations = map[string]string{annotation.SidecarInject.Name: "false"} + defaultTemplate.Policy = config.InjectionPolicyEnabled + }, + expected: false, + }, + { + name: "Label白名单功能,Policy黑名单,注入", + podSetup: func(p *corev1.Pod, defaultTemplate *config.TemplateConfig) { + p.Labels = map[string]string{utils.PolarisInjectionKey: utils.PolarisInjectionEnabled} + defaultTemplate.Policy = config.InjectionPolicyDisabled + }, + expected: true, + }, + { + name: "Label黑名单,Policy白名单,不注入", + podSetup: func(p *corev1.Pod, defaultTemplate *config.TemplateConfig) { + p.Labels = map[string]string{utils.PolarisInjectionKey: utils.PolarisInjectionDisabled} + defaultTemplate.Policy = config.InjectionPolicyEnabled + }, + expected: false, + }, + { + name: "Policy为空,默认策略为空时,完全禁止注入", + podSetup: func(p *corev1.Pod, defaultTemplate *config.TemplateConfig) { + defaultTemplate.Policy = "" + }, + expected: false, + }, + { + name: "Policy为空,尽管Annotation白名单,仍会禁止注入", + podSetup: func(p *corev1.Pod, defaultTemplate *config.TemplateConfig) { + p.Annotations = map[string]string{annotation.SidecarInject.Name: "true"} + defaultTemplate.Policy = "" + }, + expected: false, + }, + } + + wh := &Webhook{} + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + pod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-pod", + Namespace: "default", + Annotations: make(map[string]string), + Labels: make(map[string]string), + }, + Spec: corev1.PodSpec{}, + } + if tc.podSetup != nil { + tc.podSetup(pod, defaultTemplate) + } + + podInfo := &podDataInfo{ + podObject: pod, + injectTemplateConfig: defaultTemplate, + podName: pod.Name, + } + + result := wh.commonInjectRequired(podInfo) + if result != tc.expected { + t.Errorf("%s: 期望 %v 但得到 %v", tc.name, tc.expected, result) + } + }) + } +} diff --git a/pkg/inject/pkg/kube/inject/common.go b/pkg/inject/pkg/kube/inject/common.go new file mode 100644 index 00000000..2b3a1112 --- /dev/null +++ b/pkg/inject/pkg/kube/inject/common.go @@ -0,0 +1,140 @@ +package inject + +import "C" +import ( + "context" + "strings" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/polarismesh/polaris-controller/common/log" + utils "github.com/polarismesh/polaris-controller/pkg/util" +) + +// getInjectMode determines the injection mode for the pod based on annotations and namespace labels. +// The priority order is: +// 1. Pod annotations for Java agent mode +// 2. Pod annotations for Mesh mode +// 3. Pod annotations for custom sidecar mode +// 4. Namespace labels +// 5. Default sidecar mode from webhook configuration +func getInjectMode(wh *Webhook, p *podDataInfo) utils.SidecarMode { + pod := p.podObject + namespace := pod.Namespace + + // Check injection mode by priority + switch { + case isJavaAgentMode(pod.Annotations): + log.InjectScope().Infof("inject pod namespace %q mode is java agent", namespace) + return utils.SidecarForJavaAgent + case isMeshMode(pod.Annotations): + log.InjectScope().Infof("inject pod namespace %q mode is mesh envoy", namespace) + setMeshEnvoyConfig(wh, pod.Annotations) + return utils.SidecarForMesh + case hasSidecarModeAnnotation(pod.Annotations): + return utils.ParseSidecarMode(pod.Annotations[utils.PolarisSidecarMode]) + } + + return getNamespaceInjectMode(wh, namespace) +} + +// isJavaAgentMode checks if the pod should use Java agent injection mode +func isJavaAgentMode(annotations map[string]string) bool { + val, ok := annotations[utils.PolarisInjectModeLabelKeyJavaAgent] + return ok && val == utils.PolarisInjectModeLabelValueTrue +} + +// isMeshMode checks if the pod should use Mesh injection mode +func isMeshMode(annotations map[string]string) bool { + val, ok := annotations[utils.SidecarEnvoyInjectKey] + return ok && val == utils.PolarisInjectModeLabelValueTrue +} + +// hasSidecarModeAnnotation checks if the pod has custom sidecar mode annotation +func hasSidecarModeAnnotation(annotations map[string]string) bool { + _, ok := annotations[utils.PolarisSidecarMode] + return ok +} + +// setMeshEnvoyConfig sets the Mesh Envoy configuration metadata +func setMeshEnvoyConfig(wh *Webhook, annotations map[string]string) { + wh.templateConfig.SetMeshEnvoyConfigWithKV(utils.SidecarEnvoyInjectProxyKey, + annotations[utils.SidecarEnvoyInjectKey]) +} + +// getNamespaceInjectMode gets injection mode from namespace labels or returns default mode +func getNamespaceInjectMode(wh *Webhook, namespace string) utils.SidecarMode { + ns, err := wh.k8sClient.CoreV1().Namespaces().Get(context.TODO(), namespace, metav1.GetOptions{}) + if err != nil { + log.InjectScope().Errorf("get pod namespace %q failed: %v", namespace, err) + return wh.defaultSidecarMode + } + + if val, ok := ns.Labels[utils.PolarisSidecarModeLabel]; ok { + return utils.ParseSidecarMode(val) + } + return wh.defaultSidecarMode +} + +const ( + workloadDeployment = "Deployment" + workloadReplicaSet = "ReplicaSet" + + podTemplateHashLabel = "pod-template-hash" +) + +// getOwnerMetaAndType 获取Pod创建对象的元数据和类型信息 +func getOwnerMetaAndType(pod *corev1.Pod) (*metav1.ObjectMeta, *metav1.TypeMeta) { + deployMeta := pod.ObjectMeta.DeepCopy() + typeMetadata := &metav1.TypeMeta{ + Kind: "Pod", + APIVersion: "v1", + } + + // 如果不是通过Controller创建的Pod,直接返回Pod的元数据 + if len(pod.GenerateName) == 0 { + return deployMeta, typeMetadata + } + + // 获取Pod的Controller引用 + controllerRef := findControllerRef(pod.GetOwnerReferences()) + if controllerRef.Name == "" { + return deployMeta, typeMetadata + } + + // 更新类型元数据为Controller的信息 + typeMetadata.APIVersion = controllerRef.APIVersion + typeMetadata.Kind = controllerRef.Kind + + // 处理Deployment特殊场景 + if isDeploymentReplicaSet(typeMetadata.Kind, controllerRef.Name, pod.Labels) { + deployMeta.Name = getDeploymentName(controllerRef.Name, pod.Labels[podTemplateHashLabel]) + typeMetadata.Kind = workloadDeployment + } else { + deployMeta.Name = controllerRef.Name + } + + return deployMeta, typeMetadata +} + +// findControllerRef 从OwnerReferences中查找Pod的Controller引用 +func findControllerRef(refs []metav1.OwnerReference) metav1.OwnerReference { + for _, ref := range refs { + if ref.Controller != nil && *ref.Controller { + return ref + } + } + return metav1.OwnerReference{} +} + +// isDeploymentReplicaSet 判断是否为Deployment创建的ReplicaSet +func isDeploymentReplicaSet(kind, name string, labels map[string]string) bool { + return kind == workloadReplicaSet && labels[podTemplateHashLabel] != "" && + strings.HasSuffix(name, labels[podTemplateHashLabel]) +} + +// getDeploymentName 从ReplicaSet名称中提取Deployment名称 +func getDeploymentName(replicaSetName, podTemplateHash string) string { + return strings.TrimSuffix(replicaSetName, "-"+podTemplateHash) +} diff --git a/pkg/inject/pkg/kube/inject/inject.go b/pkg/inject/pkg/kube/inject/inject.go index b22f6c94..8cb39c16 100644 --- a/pkg/inject/pkg/kube/inject/inject.go +++ b/pkg/inject/pkg/kube/inject/inject.go @@ -15,35 +15,18 @@ package inject import ( - "bytes" - "context" - "crypto/sha256" - "encoding/hex" - "encoding/json" "fmt" - "net" - "os" - "path" - "strconv" "strings" - "text/template" - "github.com/ghodss/yaml" - "github.com/gogo/protobuf/jsonpb" - "github.com/gogo/protobuf/proto" - "github.com/gogo/protobuf/types" "github.com/hashicorp/go-multierror" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" "github.com/polarismesh/polaris-controller/common/log" "github.com/polarismesh/polaris-controller/pkg/inject/api/annotation" + "github.com/polarismesh/polaris-controller/pkg/inject/pkg/config" "github.com/polarismesh/polaris-controller/pkg/inject/pkg/config/mesh" - "github.com/polarismesh/polaris-controller/pkg/util" - utils "github.com/polarismesh/polaris-controller/pkg/util" ) type annotationValidationFunc func(value string) error @@ -54,7 +37,7 @@ var ( return nil } - annotationRegistry = map[string]annotationValidationFunc{ + annotationRegistryForMesh = map[string]annotationValidationFunc{ annotation.SidecarInject.Name: alwaysValidFunc, annotation.SidecarStatus.Name: alwaysValidFunc, annotation.SidecarRewriteAppHTTPProbers.Name: alwaysValidFunc, @@ -79,9 +62,9 @@ var ( } ) -func validateAnnotations(annotations map[string]string) (err error) { +func validateMeshAnnotations(annotations map[string]string) (err error) { for name, value := range annotations { - if v, ok := annotationRegistry[name]; ok { + if v, ok := annotationRegistryForMesh[name]; ok { if e := v(value); e != nil { err = multierror.Append(err, fmt.Errorf("invalid value '%s' for annotation '%s': %v", value, name, e)) } @@ -90,26 +73,6 @@ func validateAnnotations(annotations map[string]string) (err error) { return } -// InjectionPolicy determines the policy for injecting the -// sidecar proxy into the watched namespace(s). -type InjectionPolicy string - -const ( - // InjectionPolicyDisabled specifies that the sidecar injector - // will not inject the sidecar into resources by default for the - // namespace(s) being watched. Resources can enable injection - // using the "sidecar.polarismesh.cn/inject" annotation with value of - // true. - InjectionPolicyDisabled InjectionPolicy = "disabled" - - // InjectionPolicyEnabled specifies that the sidecar injector will - // inject the sidecar into resources by default for the - // namespace(s) being watched. Resources can disable injection - // using the "sidecar.polarismesh.cn/inject" annotation with value of - // false. - InjectionPolicyEnabled InjectionPolicy = "enabled" -) - const ( // ProxyContainerName is used by e2e integration tests for fetching logs ProxyContainerName = "polaris-proxy" @@ -140,165 +103,11 @@ type SidecarTemplateData struct { Values map[string]interface{} } -// Config specifies the sidecar injection configuration This includes -// the sidecar template and cluster-side injection policy. It is used -// by kube-inject, sidecar injector, and http endpoint. -type Config struct { - Policy InjectionPolicy `json:"policy"` - - // Template is the templated version of `SidecarInjectionSpec` prior to - // expansion over the `SidecarTemplateData`. - Template string `json:"template"` - - // NeverInjectSelector: Refuses the injection on pods whose labels match this selector. - // It's an array of label selectors, that will be OR'ed, meaning we will iterate - // over it and stop at the first match - // Takes precedence over AlwaysInjectSelector. - NeverInjectSelector []metav1.LabelSelector `json:"neverInjectSelector"` - - // AlwaysInjectSelector: Forces the injection on pods whose labels match this selector. - // It's an array of label selectors, that will be OR'ed, meaning we will iterate - // over it and stop at the first match - AlwaysInjectSelector []metav1.LabelSelector `json:"alwaysInjectSelector"` - - // InjectedAnnotations are additional annotations that will be added to the pod spec after injection - // This is primarily to support PSP annotations. - InjectedAnnotations map[string]string `json:"injectedAnnotations"` -} - -func validateCIDRList(cidrs string) error { - if len(cidrs) > 0 { - for _, cidr := range strings.Split(cidrs, ",") { - if _, _, err := net.ParseCIDR(cidr); err != nil { - return fmt.Errorf("failed parsing cidr '%s': %v", cidr, err) - } - } - } - return nil -} - -func splitPorts(portsString string) []string { - return strings.Split(portsString, ",") -} - -func parsePort(portStr string) (int, error) { - port, err := strconv.ParseUint(strings.TrimSpace(portStr), 10, 16) - if err != nil { - return 0, fmt.Errorf("failed parsing port '%d': %v", port, err) - } - return int(port), nil -} - -func parsePorts(portsString string) ([]int, error) { - portsString = strings.TrimSpace(portsString) - ports := make([]int, 0) - if len(portsString) > 0 { - for _, portStr := range splitPorts(portsString) { - port, err := parsePort(portStr) - if err != nil { - return nil, fmt.Errorf("failed parsing port '%d': %v", port, err) - } - ports = append(ports, port) - } - } - return ports, nil -} - -func validatePortList(parameterName, ports string) error { - if _, err := parsePorts(ports); err != nil { - return fmt.Errorf("%s invalid: %v", parameterName, err) - } - return nil -} - -// ValidateIncludeIPRanges validates the includeIPRanges parameter -func ValidateIncludeIPRanges(ipRanges string) error { - if ipRanges != "*" { - if e := validateCIDRList(ipRanges); e != nil { - return fmt.Errorf("includeIPRanges invalid: %v", e) - } - } - return nil -} - -// ValidateExcludeIPRanges validates the excludeIPRanges parameter -func ValidateExcludeIPRanges(ipRanges string) error { - if e := validateCIDRList(ipRanges); e != nil { - return fmt.Errorf("excludeIPRanges invalid: %v", e) - } - return nil -} - -// ValidateIncludeInboundPorts validates the includeInboundPorts parameter -func ValidateIncludeInboundPorts(ports string) error { - if ports != "*" { - return validatePortList("includeInboundPorts", ports) - } - return nil -} - -// ValidateExcludeInboundPorts validates the excludeInboundPorts parameter -func ValidateExcludeInboundPorts(ports string) error { - return validatePortList("excludeInboundPorts", ports) -} - -// ValidateExcludeOutboundPorts validates the excludeOutboundPorts parameter -func ValidateExcludeOutboundPorts(ports string) error { - return validatePortList("excludeOutboundPorts", ports) -} - -// validateStatusPort validates the statusPort parameter -func validateStatusPort(port string) error { - if _, e := parsePort(port); e != nil { - return fmt.Errorf("excludeInboundPorts invalid: %v", e) - } - return nil -} - -// nolint -// validateUInt32 validates that the given annotation value is a positive integer. -func validateUInt32(value string) error { - _, err := strconv.ParseUint(value, 10, 32) - return err -} - -// validateBool validates that the given annotation value is a boolean. -func validateBool(value string) error { - _, err := strconv.ParseBool(value) - return err -} - -// getSidecarMode 获取 sidecar 注入模式 -func (wh *Webhook) getSidecarMode(namespace string, pod *corev1.Pod) utils.SidecarMode { - // 这里主要是处理北极星 sidecar, 优先级: pod.annotations > namespace.labels > configmap - if val, ok := pod.Annotations["polarismesh.cn/javaagent"]; ok && val == "true" { - log.InjectScope().Infof("inject pod namespace %q mode is java agent", namespace) - return utils.SidecarForJavaAgent - } - sidecarMode := "" - // 1. pod.annotations - if val, ok := pod.Annotations[utils.PolarisSidecarMode]; ok { - sidecarMode = val - return utils.ParseSidecarMode(sidecarMode) - } - - // 2. namespace.labels - ns, err := wh.k8sClient.CoreV1().Namespaces().Get(context.TODO(), namespace, metav1.GetOptions{}) - if err != nil { - // 如果出现异常,则就采用配置文件中的 Sidecar 的注入模式 - log.InjectScope().Errorf("get pod namespace %q failed: %v", namespace, err) - } else { - if val, ok := ns.Labels[utils.PolarisSidecarModeLabel]; ok { - sidecarMode = val - } - return utils.ParseSidecarMode(sidecarMode) - } - - return wh.defaultSidecarMode -} - -func (wh *Webhook) injectRequired(ignored []string, config *Config, podSpec *corev1.PodSpec, - metadata *metav1.ObjectMeta) bool { +func (wh *Webhook) meshInjectRequired(p *podDataInfo) bool { + podSpec := &p.podObject.Spec + metadata := &p.podObject.ObjectMeta + templateConfig := p.injectTemplateConfig + podName := p.podName // Skip injection when host networking is enabled. The problem is // that the iptable changes are assumed to be within the pod when, // in fact, they are changing the routing at the host level. This @@ -310,7 +119,7 @@ func (wh *Webhook) injectRequired(ignored []string, config *Config, podSpec *cor } // skip special kubernetes system namespaces - for _, namespace := range ignored { + for _, namespace := range ignoredNamespaces { if metadata.Namespace == namespace { return false } @@ -325,9 +134,9 @@ func (wh *Webhook) injectRequired(ignored []string, config *Config, podSpec *cor var inject bool switch strings.ToLower(annos[annotation.SidecarInject.Name]) { // http://yaml.org/type/bool.html - case "y", "yes", "true", "on": + case "y", "yes", "true", "on", "enable", "enabled": inject = true - case "n", "no", "false", "off": + case "n", "no", "false", "off", "disable", "disabled": inject = false case "": useDefault = true @@ -335,14 +144,13 @@ func (wh *Webhook) injectRequired(ignored []string, config *Config, podSpec *cor // If an annotation is not explicitly given, check the LabelSelectors, starting with NeverInject if useDefault { - for _, neverSelector := range config.NeverInjectSelector { + for _, neverSelector := range templateConfig.NeverInjectSelector { selector, err := metav1.LabelSelectorAsSelector(&neverSelector) if err != nil { log.InjectScope().Warnf("Invalid selector for NeverInjectSelector: %v (%v)", neverSelector, err) } else if !selector.Empty() && selector.Matches(labels.Set(metadata.Labels)) { log.InjectScope().Infof("Explicitly disabling injection for pod %s/%s due to pod labels "+ - "matching NeverInjectSelector config map entry.", - metadata.Namespace, potentialPodName(metadata)) + "matching NeverInjectSelector templateConfig map entry.", metadata.Namespace, podName) inject = false useDefault = false break @@ -352,14 +160,13 @@ func (wh *Webhook) injectRequired(ignored []string, config *Config, podSpec *cor // If there's no annotation nor a NeverInjectSelector, check the AlwaysInject one if useDefault { - for _, alwaysSelector := range config.AlwaysInjectSelector { + for _, alwaysSelector := range templateConfig.AlwaysInjectSelector { selector, err := metav1.LabelSelectorAsSelector(&alwaysSelector) if err != nil { log.InjectScope().Warnf("Invalid selector for AlwaysInjectSelector: %v (%v)", alwaysSelector, err) } else if !selector.Empty() && selector.Matches(labels.Set(metadata.Labels)) { log.InjectScope().Infof("Explicitly enabling injection for pod %s/%s due to pod labels "+ - " matching AlwaysInjectSelector config map entry.", - metadata.Namespace, potentialPodName(metadata)) + " matching AlwaysInjectSelector templateConfig map entry.", metadata.Namespace, podName) inject = true useDefault = false break @@ -368,18 +175,18 @@ func (wh *Webhook) injectRequired(ignored []string, config *Config, podSpec *cor } var required bool - switch config.Policy { + switch templateConfig.Policy { default: // InjectionPolicyOff log.InjectScope().Errorf("Illegal value for autoInject:%s, must be one of [%s,%s]. Auto injection disabled!", - config.Policy, InjectionPolicyDisabled, InjectionPolicyEnabled) + templateConfig.Policy, config.InjectionPolicyDisabled, config.InjectionPolicyEnabled) required = false - case InjectionPolicyDisabled: + case config.InjectionPolicyDisabled: if useDefault { required = false } else { required = inject } - case InjectionPolicyEnabled: + case config.InjectionPolicyEnabled: if useDefault { required = true } else { @@ -389,7 +196,7 @@ func (wh *Webhook) injectRequired(ignored []string, config *Config, podSpec *cor // Build a log message for the annotations. annotationStr := "" - for name := range annotationRegistry { + for name := range annotationRegistryForMesh { value, ok := annos[name] if !ok { value = "(unset)" @@ -399,8 +206,8 @@ func (wh *Webhook) injectRequired(ignored []string, config *Config, podSpec *cor log.InjectScope().Infof("Sidecar injection for %v/%v: namespacePolicy:%v useDefault:%v inject:%v required:%v %s", metadata.Namespace, - potentialPodName(metadata), - config.Policy, + podName, + templateConfig.Policy, useDefault, inject, required, @@ -408,441 +215,3 @@ func (wh *Webhook) injectRequired(ignored []string, config *Config, podSpec *cor return required } - -func formatDuration(in *types.Duration) string { - dur, err := types.DurationFromProto(in) - if err != nil { - return "1s" - } - return dur.String() -} - -func isset(m map[string]string, key string) bool { - _, ok := m[key] - return ok -} - -func openTlsMode(m map[string]string, key string) bool { - if len(m) == 0 { - return false - } - - v, ok := m[key] - if !ok { - return false - } - - return v != util.MTLSModeNone -} - -func directory(filepath string) string { - dir, _ := path.Split(filepath) - return dir -} - -func flippedContains(needle, haystack string) bool { - return strings.Contains(haystack, needle) -} - -// InjectionData renders sidecarTemplate with valuesConfig. -func InjectionData(sidecarTemplate, valuesConfig, version string, typeMetadata *metav1.TypeMeta, - deploymentMetadata *metav1.ObjectMeta, spec *corev1.PodSpec, - metadata *metav1.ObjectMeta, proxyConfig *mesh.DefaultConfig) ( - *SidecarInjectionSpec, map[string]string, string, error) { - // If DNSPolicy is not ClusterFirst, the Envoy sidecar may not able to connect to polaris. - if spec.DNSPolicy != "" && spec.DNSPolicy != corev1.DNSClusterFirst { - podName := potentialPodName(metadata) - log.InjectScope().Errorf("[Webhook] %q's DNSPolicy is not %q. The Envoy sidecar may not able to "+ - " connect to PolarisMesh Control Plane", - metadata.Namespace+"/"+podName, corev1.DNSClusterFirst) - return nil, nil, "", nil - } - - if err := validateAnnotations(metadata.GetAnnotations()); err != nil { - log.InjectScope().Errorf("[Webhook] injection failed due to invalid annotations: %v", err) - return nil, nil, "", err - } - - values := map[string]interface{}{} - if err := yaml.Unmarshal([]byte(valuesConfig), &values); err != nil { - log.InjectScope().Infof("[Webhook] failed to parse values config: %v [%v]\n", err, valuesConfig) - return nil, nil, "", multierror.Prefix(err, "could not parse configuration values:") - } - - injectAnnonations := map[string]string{} - // 设置需要注入到 envoy 的 metadata - // 强制开启 XDS On-Demand 能力 - envoyMetadata := map[string]string{} - // 这里负责将需要额外塞入的 annonation 数据进行返回 - if len(metadata.Annotations) != 0 { - tlsMode := util.MTLSModeNone - if mode, ok := metadata.Annotations[util.PolarisTLSMode]; ok { - mode = strings.ToLower(mode) - if mode == util.MTLSModeStrict || mode == util.MTLSModePermissive { - tlsMode = mode - } - } - injectAnnonations[util.PolarisTLSMode] = tlsMode - envoyMetadata[util.PolarisTLSMode] = tlsMode - - // 按需加载能力需要显示开启 - if val, ok := metadata.Annotations["sidecar.polarismesh.cn/openOnDemand"]; ok { - envoyMetadata["sidecar.polarismesh.cn/openOnDemand"] = val - proxyConfig.ProxyMetadata["OPEN_DEMAND"] = val - } - } - // 这里需要将 sidecar 所属的服务信息注入到 annonation 中,方便下发到 envoy 的 bootstrap.yaml 中 - // 命名空间可以不太强要求用户设置,大部份场景都是保持和 kubernetes 部署所在的 namespace 保持一致的 - if _, ok := metadata.Annotations[utils.SidecarNamespaceName]; !ok { - injectAnnonations[utils.SidecarNamespaceName] = metadata.Namespace - envoyMetadata[utils.SidecarNamespaceName] = metadata.Namespace - } - if svcName, ok := metadata.Annotations[utils.SidecarServiceName]; !ok { - // 如果官方注解没有查询到,那就默认按照 istio 的约定,从 labels 中读取 app 这个标签的 value 作为服务名 - if val, ok := metadata.Labels["app"]; ok { - injectAnnonations[utils.SidecarServiceName] = val - envoyMetadata[utils.SidecarServiceName] = val - } - } else { - envoyMetadata[utils.SidecarServiceName] = svcName - } - - for k, v := range metadata.Labels { - envoyMetadata[k] = v - } - injectAnnonations[utils.SidecarEnvoyMetadata] = fmt.Sprintf("%q", toJSON(envoyMetadata)) - metadataCopy := metadata.DeepCopy() - metadataCopy.Annotations = injectAnnonations - data := SidecarTemplateData{ - TypeMeta: typeMetadata, - DeploymentMeta: deploymentMetadata, - ObjectMeta: metadataCopy, - Spec: spec, - ProxyConfig: proxyConfig, - Values: values, - } - - funcMap := template.FuncMap{ - "formatDuration": formatDuration, - "isset": isset, - "excludeInboundPort": excludeInboundPort, - "includeInboundPorts": includeInboundPorts, - "kubevirtInterfaces": kubevirtInterfaces, - "applicationPorts": applicationPorts, - "annotation": getAnnotation, - "valueOrDefault": valueOrDefault, - "toJSON": toJSON, - "toJson": toJSON, // Used by, e.g. Istio 1.0.5 template sidecar-injector-configmap.yaml - "fromJSON": fromJSON, - "structToJSON": structToJSON, - "protoToJSON": protoToJSON, - "toYaml": toYaml, - "indent": indent, - "directory": directory, - "contains": flippedContains, - "toLower": strings.ToLower, - "openTlsMode": openTlsMode, - } - - // Allows the template to use env variables from istiod. - // Istiod will use a custom template, without 'values.yaml', and the pod will have - // an optional 'vendor' configmap where additional settings can be defined. - funcMap["env"] = func(key string, def string) string { - val := os.Getenv(key) - if val == "" { - return def - } - return val - } - - // Need to use FuncMap and SidecarTemplateData context - funcMap["render"] = func(template string) string { - bbuf, err := parseTemplate(template, funcMap, data) - if err != nil { - return "" - } - - return bbuf.String() - } - - bbuf, err := parseTemplate(sidecarTemplate, funcMap, data) - if err != nil { - return nil, nil, "", err - } - - var sic SidecarInjectionSpec - if err := yaml.Unmarshal(bbuf.Bytes(), &sic); err != nil { - // This usually means an invalid injector template; we can't check - // the template itself because it is merely a string. - log.InjectScope().Warnf("Failed to unmarshal template %v \n%s", err, bbuf.String()) - return nil, nil, "", multierror.Prefix(err, "failed parsing injected YAML (check sidecar injector configuration):") - } - - // set sidecar --concurrency - applyConcurrency(sic.Containers) - - status := &SidecarInjectionStatus{Version: version} - for _, c := range sic.InitContainers { - status.InitContainers = append(status.InitContainers, corev1.Container{ - Name: c.Name, - }) - } - for _, c := range sic.Containers { - status.Containers = append(status.Containers, corev1.Container{ - Name: c.Name, - }) - } - for _, c := range sic.Volumes { - status.Volumes = append(status.Volumes, corev1.Volume{ - Name: c.Name, - }) - } - for _, c := range sic.ImagePullSecrets { - status.ImagePullSecrets = append(status.ImagePullSecrets, corev1.LocalObjectReference{ - Name: c.Name, - }) - } - statusAnnotationValue, err := json.Marshal(status) - if err != nil { - return nil, nil, "", fmt.Errorf("error encoded injection status: %v", err) - } - return &sic, injectAnnonations, string(statusAnnotationValue), err -} - -func parseTemplate(tmplStr string, funcMap map[string]interface{}, data SidecarTemplateData) (bytes.Buffer, error) { - var tmpl bytes.Buffer - temp := template.New("inject") - t, err := temp.Funcs(funcMap).Parse(tmplStr) - if err != nil { - log.InjectScope().Errorf("Failed to parse template: %v %v\n", err, tmplStr) - return bytes.Buffer{}, err - } - if err := t.Execute(&tmpl, &data); err != nil { - log.InjectScope().Errorf("Invalid template: %v %v\n", err, tmplStr) - return bytes.Buffer{}, err - } - - return tmpl, nil -} - -// FromRawToObject is used to convert from raw to the runtime object -func FromRawToObject(raw []byte) (runtime.Object, error) { - var typeMeta metav1.TypeMeta - if err := yaml.Unmarshal(raw, &typeMeta); err != nil { - return nil, err - } - - gvk := schema.FromAPIVersionAndKind(typeMeta.APIVersion, typeMeta.Kind) - obj, err := injectScheme.New(gvk) - if err != nil { - return nil, err - } - if err = yaml.Unmarshal(raw, obj); err != nil { - return nil, err - } - - return obj, nil -} - -func getPortsForContainer(container corev1.Container) []string { - parts := make([]string, 0) - for _, p := range container.Ports { - if p.Protocol == corev1.ProtocolUDP || p.Protocol == corev1.ProtocolSCTP { - continue - } - parts = append(parts, strconv.Itoa(int(p.ContainerPort))) - } - return parts -} - -func getContainerPorts(containers []corev1.Container, shouldIncludePorts func(corev1.Container) bool) string { - parts := make([]string, 0) - for _, c := range containers { - if shouldIncludePorts(c) { - parts = append(parts, getPortsForContainer(c)...) - } - } - - return strings.Join(parts, ",") -} - -// this function is no longer used by the template but kept around for backwards compatibility -func applicationPorts(containers []corev1.Container) string { - return getContainerPorts(containers, func(c corev1.Container) bool { - return c.Name != ProxyContainerName - }) -} - -func includeInboundPorts(containers []corev1.Container) string { - // Include the ports from all containers in the deployment. - return getContainerPorts(containers, func(corev1.Container) bool { return true }) -} - -func kubevirtInterfaces(s string) string { - return s -} - -func structToJSON(v interface{}) string { - if v == nil { - return "{}" - } - - ba, err := json.Marshal(v) - if err != nil { - log.InjectScope().Warnf("Unable to marshal %v", v) - return "{}" - } - - return string(ba) -} - -func protoToJSON(v proto.Message) string { - if v == nil { - return "{}" - } - - m := jsonpb.Marshaler{} - ba, err := m.MarshalToString(v) - if err != nil { - log.InjectScope().Warnf("Unable to marshal %v: %v", v, err) - return "{}" - } - - return ba -} - -func toJSON(m map[string]string) string { - if m == nil { - return "{}" - } - - ba, err := json.Marshal(m) - if err != nil { - log.InjectScope().Warnf("Unable to marshal %v", m) - return "{}" - } - - return string(ba) -} - -func fromJSON(j string) interface{} { - var m interface{} - err := json.Unmarshal([]byte(j), &m) - if err != nil { - log.InjectScope().Warnf("Unable to unmarshal %s", j) - return "{}" - } - - log.InjectScope().Warnf("%v", m) - return m -} - -func indent(spaces int, source string) string { - res := strings.Split(source, "\n") - for i, line := range res { - if i > 0 { - res[i] = fmt.Sprintf(fmt.Sprintf("%% %ds%%s", spaces), "", line) - } - } - return strings.Join(res, "\n") -} - -func toYaml(value interface{}) string { - y, err := yaml.Marshal(value) - if err != nil { - log.InjectScope().Warnf("Unable to marshal %v", value) - return "" - } - - return string(y) -} - -func getAnnotation(meta metav1.ObjectMeta, name string, defaultValue interface{}) string { - value, ok := meta.Annotations[name] - if !ok { - value = fmt.Sprint(defaultValue) - } - return value -} - -func excludeInboundPort(port interface{}, excludedInboundPorts string) string { - portStr := strings.TrimSpace(fmt.Sprint(port)) - if len(portStr) == 0 || portStr == "0" { - // Nothing to do. - return excludedInboundPorts - } - - // Exclude the readiness port if not already excluded. - ports := splitPorts(excludedInboundPorts) - outPorts := make([]string, 0, len(ports)) - for _, port := range ports { - if port == portStr { - // The port is already excluded. - return excludedInboundPorts - } - port = strings.TrimSpace(port) - if len(port) > 0 { - outPorts = append(outPorts, port) - } - } - - // The port was not already excluded - exclude it now. - outPorts = append(outPorts, portStr) - return strings.Join(outPorts, ",") -} - -func valueOrDefault(value interface{}, defaultValue interface{}) interface{} { - if value == "" || value == nil { - return defaultValue - } - return value -} - -// SidecarInjectionStatus contains basic information about the -// injected sidecar. This includes the names of added containers and -// volumes. -type SidecarInjectionStatus struct { - Version string `json:"version"` - InitContainers []corev1.Container `json:"initContainers"` - Containers []corev1.Container `json:"containers"` - Volumes []corev1.Volume `json:"volumes"` - ImagePullSecrets []corev1.LocalObjectReference `json:"imagePullSecrets"` -} - -// helper function to generate a template version identifier from a -// hash of the un-executed template contents. -func sidecarTemplateVersionHash(in string) string { - hash := sha256.Sum256([]byte(in)) - return hex.EncodeToString(hash[:]) -} - -func potentialPodName(metadata *metav1.ObjectMeta) string { - if metadata.Name != "" { - return metadata.Name - } - if metadata.GenerateName != "" { - return metadata.GenerateName + "***** (actual name not yet known)" - } - return "" -} - -// nolint -// rewriteCniPodSpec will check if values from the sidecar injector Helm -// values need to be inserted as Pod annotations so the CNI will apply -// the proper redirection rules. -func rewriteCniPodSpec(annotations map[string]string, spec *SidecarInjectionSpec) { - if spec == nil { - return - } - if len(spec.PodRedirectAnnot) == 0 { - return - } - for k := range annotationRegistry { - if spec.PodRedirectAnnot[k] != "" { - if annotations[k] == spec.PodRedirectAnnot[k] { - continue - } - annotations[k] = spec.PodRedirectAnnot[k] - } - } -} diff --git a/pkg/inject/pkg/kube/inject/inject_test.go b/pkg/inject/pkg/kube/inject/inject_test.go new file mode 100644 index 00000000..77c51687 --- /dev/null +++ b/pkg/inject/pkg/kube/inject/inject_test.go @@ -0,0 +1,113 @@ +package inject + +import ( + "testing" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/polarismesh/polaris-controller/pkg/inject/api/annotation" + "github.com/polarismesh/polaris-controller/pkg/inject/pkg/config" +) + +func TestMeshInjectRequired(t *testing.T) { + // 通用测试配置 + defaultTemplate := &config.TemplateConfig{ + NeverInjectSelector: []metav1.LabelSelector{{MatchLabels: map[string]string{"security": "high"}}}, + AlwaysInjectSelector: []metav1.LabelSelector{{MatchLabels: map[string]string{"env": "prod"}}}, + Policy: config.InjectionPolicyEnabled, + } + + testCases := []struct { + name string + podSetup func(*corev1.Pod) + expected bool + }{ + { + name: "当启用HostNetwork时无需注入", + podSetup: func(p *corev1.Pod) { + p.Spec.HostNetwork = true + }, + expected: false, + }, + { + name: "在kube-system命名空间中跳过注入", + podSetup: func(p *corev1.Pod) { + p.Namespace = "kube-system" + }, + expected: false, + }, + { + name: "当注解明确启用时应该注入", + podSetup: func(p *corev1.Pod) { + p.Annotations = map[string]string{annotation.SidecarInject.Name: "true"} + }, + expected: true, + }, + { + name: "当注解明确禁用时不注入", + podSetup: func(p *corev1.Pod) { + p.Annotations = map[string]string{annotation.SidecarInject.Name: "false"} + }, + expected: false, + }, + { + name: "当匹配NeverInjectSelector时不注入", + podSetup: func(p *corev1.Pod) { + p.Labels = map[string]string{"security": "high"} + }, + expected: false, + }, + { + name: "当匹配AlwaysInjectSelector时强制注入", + podSetup: func(p *corev1.Pod) { + p.Labels = map[string]string{"env": "prod"} + }, + expected: true, + }, + { + name: "默认策略启用时自动注入", + podSetup: func(p *corev1.Pod) { + // 无额外配置 + }, + expected: true, + }, + { + name: "当策略禁用时需要显式启用才注入", + podSetup: func(p *corev1.Pod) { + defaultTemplate.Policy = config.InjectionPolicyDisabled + p.Annotations = map[string]string{annotation.SidecarInject.Name: "true"} + }, + expected: true, + }, + } + + wh := &Webhook{} + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + pod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-pod", + Namespace: "default", + Annotations: make(map[string]string), + Labels: make(map[string]string), + }, + Spec: corev1.PodSpec{}, + } + if tc.podSetup != nil { + tc.podSetup(pod) + } + + podInfo := &podDataInfo{ + podObject: pod, + injectTemplateConfig: defaultTemplate, + podName: pod.Name, + } + + result := wh.meshInjectRequired(podInfo) + if result != tc.expected { + t.Errorf("%s: 期望 %v 但得到 %v", tc.name, tc.expected, result) + } + }) + } +} diff --git a/pkg/inject/pkg/kube/inject/pod.go b/pkg/inject/pkg/kube/inject/pod.go new file mode 100644 index 00000000..0f7265b9 --- /dev/null +++ b/pkg/inject/pkg/kube/inject/pod.go @@ -0,0 +1,193 @@ +package inject + +import ( + "encoding/json" + "fmt" + "strings" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/polarismesh/polaris-controller/common/log" + "github.com/polarismesh/polaris-controller/pkg/inject/pkg/config" + utils "github.com/polarismesh/polaris-controller/pkg/util" +) + +type podDataInfo struct { + podObject *corev1.Pod + podName string + injectMode utils.SidecarMode + injectTemplateConfig *config.TemplateConfig + injectTemplateVersion string + valuesConfig string + workloadMeta *metav1.ObjectMeta + workloadType *metav1.TypeMeta + injectedAnnotations map[string]string +} + +// 解析并填充 pod 的信息 +func assignPodDataInfo(raw []byte, namespace string, wh *Webhook) (*podDataInfo, error) { + var pod corev1.Pod + if err := json.Unmarshal(raw, &pod); err != nil { + handleError(fmt.Sprintf("Could not unmarshal raw object: %v %s", err, + string(raw))) + return nil, err + } + if pod.Namespace == "" { + pod.Namespace = namespace + } + podInfo := &podDataInfo{ + podObject: &pod, + } + podInfo.assignAll(wh) + return podInfo, nil +} + +// 初始化podDataInfo所有字段 +func (p *podDataInfo) assignAll(wh *Webhook) { + p.assignPodName() + p.assignInjectMode(wh) + p.assignInjectTemplateAndVersion(wh) + p.assignWorkloadMeta() + p.assignInjectAnnotations() +} + +func (p *podDataInfo) assignWorkloadMeta() { + p.workloadMeta, p.workloadType = getOwnerMetaAndType(p.podObject) +} + +// 通过Name或GenerateName获取Pod的名称 +func (p *podDataInfo) assignPodName() { + metadata := p.podObject.ObjectMeta + if metadata.Name != "" { + p.podName = metadata.Name + } else if metadata.GenerateName != "" { + p.podName = metadata.GenerateName + "***** (actual name not yet known)" + } +} + +// assignInjectTemplateAndVersion 获取注入配置 +func (p *podDataInfo) assignInjectTemplateAndVersion(wh *Webhook) { + switch p.injectMode { + case utils.SidecarForJavaAgent: + p.injectTemplateConfig, p.injectTemplateVersion = wh.templateConfig.GetSidecarJavaAgentTemplateAndVersion() + case utils.SidecarForDns: + p.injectTemplateConfig, p.injectTemplateVersion = wh.templateConfig.GetSidecarDnsTemplateAndVersion() + default: + // 向前兼容, 默认是mesh模式 + p.injectTemplateConfig, p.injectTemplateVersion = wh.templateConfig.GetSidecarMeshTemplateAndVersion() + } + log.InjectScope().Infof("podName=%s, injectMode=%s, injectTemplateConfig=%v", p.podName, + utils.ParseSidecarModeName(p.injectMode), p.injectTemplateConfig) + p.valuesConfig = wh.templateConfig.GetValuesConfig() + return +} + +// assignInjectMode 获取注入类型 +func (p *podDataInfo) assignInjectMode(wh *Webhook) { + p.injectMode = getInjectMode(wh, p) +} + +// 检查pod的spec和annotations是否符合要求 +func (p *podDataInfo) checkPodData() (bool, error) { + pod := p.podObject + if p.injectMode == utils.SidecarForMesh { + // If DNSPolicy is not ClusterFirst, the Envoy sidecar may not able to connect to polaris. + if pod.Spec.DNSPolicy != "" && pod.Spec.DNSPolicy != corev1.DNSClusterFirst { + log.InjectScope().Errorf("[Webhook] %q's DNSPolicy is not %q. The Envoy sidecar may not able to "+ + " connect to PolarisMesh Control Plane", + pod.Namespace+"/"+p.podName, corev1.DNSClusterFirst) + return false, nil + } + if err := validateMeshAnnotations(pod.GetAnnotations()); err != nil { + log.InjectScope().Errorf("[Webhook] injection failed due to invalid annotations: %v", err) + return false, err + } + } + return true, nil +} + +// 处理pod的annotations注入 +func (p *podDataInfo) assignInjectAnnotations() { + md := p.podObject.ObjectMeta + injectAnnotations := map[string]string{} + if p.injectMode == utils.SidecarForMesh { + // 设置需要注入到 envoy 的 md + // 强制开启 XDS On-Demand 能力 + envoyMetadata := map[string]string{} + // 这里负责将需要额外塞入的 annonation 数据进行返回 + if len(md.Annotations) != 0 { + tlsMode := utils.MTLSModeNone + if mode, ok := md.Annotations[utils.PolarisTLSMode]; ok { + mode = strings.ToLower(mode) + if mode == utils.MTLSModeStrict || mode == utils.MTLSModePermissive { + tlsMode = mode + } + } + injectAnnotations[utils.PolarisTLSMode] = tlsMode + envoyMetadata[utils.PolarisTLSMode] = tlsMode + + // 按需加载能力需要显示开启 + if val, ok := md.Annotations[utils.SidecarEnvoyInjectKey]; ok { + envoyMetadata[utils.SidecarEnvoyInjectKey] = val + } + } + // 这里需要将 sidecar 所属的服务信息注入到 annonation 中,方便下发到 envoy 的 bootstrap.yaml 中 + // 命名空间可以不太强要求用户设置,大部份场景都是保持和 kubernetes 部署所在的 namespace 保持一致的 + if _, ok := md.Annotations[utils.SidecarNamespaceName]; !ok { + injectAnnotations[utils.SidecarNamespaceName] = md.Namespace + envoyMetadata[utils.SidecarNamespaceName] = md.Namespace + } + if svcName, ok := md.Annotations[utils.SidecarServiceName]; !ok { + // 如果官方注解没有查询到,那就默认按照 istio 的约定,从 labels 中读取 app 这个标签的 value 作为服务名 + if val, ok := md.Labels["app"]; ok { + injectAnnotations[utils.SidecarServiceName] = val + envoyMetadata[utils.SidecarServiceName] = val + } + } else { + envoyMetadata[utils.SidecarServiceName] = svcName + } + + for k, v := range md.Labels { + envoyMetadata[k] = v + } + injectAnnotations[utils.SidecarEnvoyMetadata] = fmt.Sprintf("%q", toJSON(envoyMetadata)) + } + p.injectedAnnotations = injectAnnotations +} + +// SidecarInjectionStatus contains basic information about the +// injected sidecar. This includes the names of added containers and +// volumes. +type SidecarInjectionStatus struct { + Version string `json:"version"` + InitContainers []corev1.Container `json:"initContainers"` + Containers []corev1.Container `json:"containers"` + Volumes []corev1.Volume `json:"volumes"` + ImagePullSecrets []corev1.LocalObjectReference `json:"imagePullSecrets"` +} + +func (p *podDataInfo) getInjectStatus(version string, sic SidecarInjectionSpec) *SidecarInjectionStatus { + status := &SidecarInjectionStatus{Version: version} + for _, c := range sic.InitContainers { + status.InitContainers = append(status.InitContainers, corev1.Container{ + Name: c.Name, + }) + } + for _, c := range sic.Containers { + status.Containers = append(status.Containers, corev1.Container{ + Name: c.Name, + }) + } + for _, c := range sic.Volumes { + status.Volumes = append(status.Volumes, corev1.Volume{ + Name: c.Name, + }) + } + for _, c := range sic.ImagePullSecrets { + status.ImagePullSecrets = append(status.ImagePullSecrets, corev1.LocalObjectReference{ + Name: c.Name, + }) + } + return status +} diff --git a/pkg/inject/pkg/kube/inject/template_funcs.go b/pkg/inject/pkg/kube/inject/template_funcs.go new file mode 100644 index 00000000..105809c8 --- /dev/null +++ b/pkg/inject/pkg/kube/inject/template_funcs.go @@ -0,0 +1,248 @@ +package inject + +import ( + "bytes" + "encoding/json" + "fmt" + "os" + "path" + "strconv" + "strings" + "text/template" + + "github.com/ghodss/yaml" + "github.com/gogo/protobuf/jsonpb" + "github.com/gogo/protobuf/proto" + "github.com/gogo/protobuf/types" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/polarismesh/polaris-controller/common/log" + "github.com/polarismesh/polaris-controller/pkg/util" +) + +func formatDuration(in *types.Duration) string { + dur, err := types.DurationFromProto(in) + if err != nil { + return "1s" + } + return dur.String() +} + +func isset(m map[string]string, key string) bool { + _, ok := m[key] + return ok +} + +func excludeInboundPort(port interface{}, excludedInboundPorts string) string { + portStr := strings.TrimSpace(fmt.Sprint(port)) + if len(portStr) == 0 || portStr == "0" { + // Nothing to do. + return excludedInboundPorts + } + + // Exclude the readiness port if not already excluded. + ports := splitPorts(excludedInboundPorts) + outPorts := make([]string, 0, len(ports)) + for _, port := range ports { + if port == portStr { + // The port is already excluded. + return excludedInboundPorts + } + port = strings.TrimSpace(port) + if len(port) > 0 { + outPorts = append(outPorts, port) + } + } + + // The port was not already excluded - exclude it now. + outPorts = append(outPorts, portStr) + return strings.Join(outPorts, ",") +} + +func openTlsMode(m map[string]string, key string) bool { + if len(m) == 0 { + return false + } + + v, ok := m[key] + if !ok { + return false + } + + return v != util.MTLSModeNone +} + +func directory(filepath string) string { + dir, _ := path.Split(filepath) + return dir +} + +func flippedContains(needle, haystack string) bool { + return strings.Contains(haystack, needle) +} + +func parseTemplate(tmplStr string, funcMap map[string]interface{}, data SidecarTemplateData) (bytes.Buffer, error) { + var tmpl bytes.Buffer + temp := template.New("inject") + t, err := temp.Funcs(funcMap).Parse(tmplStr) + if err != nil { + log.InjectScope().Errorf("Failed to parse template: %v %v\n", err, tmplStr) + return bytes.Buffer{}, err + } + if err := t.Execute(&tmpl, &data); err != nil { + log.InjectScope().Errorf("Invalid template: %v %v\n", err, tmplStr) + return bytes.Buffer{}, err + } + + return tmpl, nil +} + +func toYaml(value interface{}) string { + y, err := yaml.Marshal(value) + if err != nil { + log.InjectScope().Warnf("Unable to marshal %v", value) + return "" + } + + return string(y) +} + +func getPortsForContainer(container corev1.Container) []string { + parts := make([]string, 0) + for _, p := range container.Ports { + if p.Protocol == corev1.ProtocolUDP || p.Protocol == corev1.ProtocolSCTP { + continue + } + parts = append(parts, strconv.Itoa(int(p.ContainerPort))) + } + return parts +} + +func getContainerPorts(containers []corev1.Container, shouldIncludePorts func(corev1.Container) bool) string { + parts := make([]string, 0) + for _, c := range containers { + if shouldIncludePorts(c) { + parts = append(parts, getPortsForContainer(c)...) + } + } + + return strings.Join(parts, ",") +} + +// this function is no longer used by the template but kept around for backwards compatibility +func applicationPorts(containers []corev1.Container) string { + return getContainerPorts(containers, func(c corev1.Container) bool { + return c.Name != ProxyContainerName + }) +} + +func includeInboundPorts(containers []corev1.Container) string { + // Include the ports from all containers in the deployment. + return getContainerPorts(containers, func(corev1.Container) bool { return true }) +} + +func kubevirtInterfaces(s string) string { + return s +} + +func structToJSON(v interface{}) string { + if v == nil { + return "{}" + } + + ba, err := json.Marshal(v) + if err != nil { + log.InjectScope().Warnf("Unable to marshal %v", v) + return "{}" + } + + return string(ba) +} + +func protoToJSON(v proto.Message) string { + if v == nil { + return "{}" + } + + m := jsonpb.Marshaler{} + ba, err := m.MarshalToString(v) + if err != nil { + log.InjectScope().Warnf("Unable to marshal %v: %v", v, err) + return "{}" + } + + return ba +} + +func toJSON(m map[string]string) string { + if m == nil { + return "{}" + } + + ba, err := json.Marshal(m) + if err != nil { + log.InjectScope().Warnf("Unable to marshal %v", m) + return "{}" + } + + return string(ba) +} + +func fromJSON(j string) interface{} { + var m interface{} + err := json.Unmarshal([]byte(j), &m) + if err != nil { + log.InjectScope().Warnf("Unable to unmarshal %s", j) + return "{}" + } + + log.InjectScope().Warnf("%v", m) + return m +} + +func indent(spaces int, source string) string { + res := strings.Split(source, "\n") + for i, line := range res { + if i > 0 { + res[i] = fmt.Sprintf(fmt.Sprintf("%% %ds%%s", spaces), "", line) + } + } + return strings.Join(res, "\n") +} + +func getAnnotation(meta metav1.ObjectMeta, name string, defaultValue interface{}) string { + value, ok := meta.Annotations[name] + if !ok { + value = fmt.Sprint(defaultValue) + } + return value +} + +func valueOrDefault(value interface{}, defaultValue interface{}) interface{} { + if value == "" || value == nil { + return defaultValue + } + return value +} + +// Allows the template to use env variables from istiod. +// Istiod will use a custom template, without 'values.yaml', and the pod will have +// an optional 'vendor' configmap where additional settings can be defined. +func env(key string, def string) string { + val := os.Getenv(key) + if val == "" { + return def + } + return val +} + +// Need to use FuncMap and SidecarTemplateData context +func render(template string, funcMap map[string]interface{}, data SidecarTemplateData) string { + bbuf, err := parseTemplate(template, funcMap, data) + if err != nil { + return "" + } + + return bbuf.String() +} diff --git a/pkg/inject/pkg/kube/inject/validate_funcs.go b/pkg/inject/pkg/kube/inject/validate_funcs.go new file mode 100644 index 00000000..8eeefa3a --- /dev/null +++ b/pkg/inject/pkg/kube/inject/validate_funcs.go @@ -0,0 +1,110 @@ +package inject + +import ( + "fmt" + "net" + "strconv" + "strings" +) + +func validateCIDRList(cidrs string) error { + if len(cidrs) > 0 { + for _, cidr := range strings.Split(cidrs, ",") { + if _, _, err := net.ParseCIDR(cidr); err != nil { + return fmt.Errorf("failed parsing cidr '%s': %v", cidr, err) + } + } + } + return nil +} + +func splitPorts(portsString string) []string { + return strings.Split(portsString, ",") +} + +func parsePort(portStr string) (int, error) { + port, err := strconv.ParseUint(strings.TrimSpace(portStr), 10, 16) + if err != nil { + return 0, fmt.Errorf("failed parsing port '%d': %v", port, err) + } + return int(port), nil +} + +func parsePorts(portsString string) ([]int, error) { + portsString = strings.TrimSpace(portsString) + ports := make([]int, 0) + if len(portsString) > 0 { + for _, portStr := range splitPorts(portsString) { + port, err := parsePort(portStr) + if err != nil { + return nil, fmt.Errorf("failed parsing port '%d': %v", port, err) + } + ports = append(ports, port) + } + } + return ports, nil +} + +func validatePortList(parameterName, ports string) error { + if _, err := parsePorts(ports); err != nil { + return fmt.Errorf("%s invalid: %v", parameterName, err) + } + return nil +} + +// ValidateIncludeIPRanges validates the includeIPRanges parameter +func ValidateIncludeIPRanges(ipRanges string) error { + if ipRanges != "*" { + if e := validateCIDRList(ipRanges); e != nil { + return fmt.Errorf("includeIPRanges invalid: %v", e) + } + } + return nil +} + +// ValidateExcludeIPRanges validates the excludeIPRanges parameter +func ValidateExcludeIPRanges(ipRanges string) error { + if e := validateCIDRList(ipRanges); e != nil { + return fmt.Errorf("excludeIPRanges invalid: %v", e) + } + return nil +} + +// ValidateIncludeInboundPorts validates the includeInboundPorts parameter +func ValidateIncludeInboundPorts(ports string) error { + if ports != "*" { + return validatePortList("includeInboundPorts", ports) + } + return nil +} + +// ValidateExcludeInboundPorts validates the excludeInboundPorts parameter +func ValidateExcludeInboundPorts(ports string) error { + return validatePortList("excludeInboundPorts", ports) +} + +// ValidateExcludeOutboundPorts validates the excludeOutboundPorts parameter +func ValidateExcludeOutboundPorts(ports string) error { + return validatePortList("excludeOutboundPorts", ports) +} + +// validateStatusPort validates the statusPort parameter +func validateStatusPort(port string) error { + if _, e := parsePort(port); e != nil { + return fmt.Errorf("excludeInboundPorts invalid: %v", e) + } + return nil +} + +// nolint +// validateUInt32 validates that the given annotation value is a positive integer. +func validateUInt32(value string) error { + _, err := strconv.ParseUint(value, 10, 32) + return err +} + +// validateBool validates that the given annotation value is a boolean. +func validateBool(value string) error { + _, err := strconv.ParseBool(value) + return err +} diff --git a/pkg/inject/pkg/kube/inject/webhook.go b/pkg/inject/pkg/kube/inject/webhook.go index 4762d164..49e6cafb 100644 --- a/pkg/inject/pkg/kube/inject/webhook.go +++ b/pkg/inject/pkg/kube/inject/webhook.go @@ -17,7 +17,6 @@ package inject import ( "bytes" "context" - "crypto/sha256" "crypto/tls" "encoding/json" "fmt" @@ -27,11 +26,9 @@ import ( "path/filepath" "sort" "strings" - "sync" "text/template" "time" - gyaml "github.com/ghodss/yaml" "github.com/howeyc/fsnotify" v1 "k8s.io/api/admission/v1" "k8s.io/api/admission/v1beta1" @@ -47,7 +44,7 @@ import ( "github.com/polarismesh/polaris-controller/common" "github.com/polarismesh/polaris-controller/common/log" "github.com/polarismesh/polaris-controller/pkg/inject/api/annotation" - "github.com/polarismesh/polaris-controller/pkg/inject/pkg/config/mesh" + "github.com/polarismesh/polaris-controller/pkg/inject/pkg/config" utils "github.com/polarismesh/polaris-controller/pkg/util" ) @@ -70,143 +67,25 @@ const ( // Webhook implements a mutating webhook for automatic proxy injection. type Webhook struct { defaultSidecarMode utils.SidecarMode - mu sync.RWMutex - - // envoy mesh 场景下的 sidecar 注入配置 - sidecarMeshConfig *Config - sidecarMeshTemplateVersion string - // dns 场景下的 sidecar 注入配置 - sidecarDnsConfig *Config - sidecarDnsTemplateVersion string - // java agent 场景下的注入配置 - sidecarJavaAgentConfig *Config - sidecarJavaAgentTemplateVersion string - meshConfig *mesh.MeshConfig - valuesConfig string + templateConfig *config.SafeTemplateConfig + templateFileConfig config.TemplateFileConfig healthCheckInterval time.Duration healthCheckFile string - server *http.Server - meshFile string - meshConfigFile string - dnsConfigFile string - javaAgentConfigFile string - valuesFile string - watcher *fsnotify.Watcher - certFile string - keyFile string - cert *tls.Certificate - + server *http.Server + watcher *fsnotify.Watcher k8sClient kubernetes.Interface } -type InjectConfigInfo struct { - MeshInjectConf *Config - DnsInjectConf *Config - JavaAgentInjectConf *Config - MeshConf *mesh.MeshConfig - ValuesConf string -} - -// env will be used for other things besides meshConfig - when webhook is running in Istiod it can take advantage -// of the config and endpoint cache. -// nolint -func loadConfig(injectMeshFile, injectDnsFile, injectJavaFile, meshFile, valuesFile string) (*InjectConfigInfo, error) { - // 处理 polaris-sidecar mesh 模式的注入 - meshData, err := os.ReadFile(injectMeshFile) - if err != nil { - return nil, err - } - var meshConf Config - if err := gyaml.Unmarshal(meshData, &meshConf); err != nil { - log.InjectScope().Warnf("Failed to parse inject mesh config file %s", string(meshData)) - return nil, err - } - - // 处理 polaris-sidecar dns 模式的注入 - dnsData, err := os.ReadFile(injectDnsFile) - if err != nil { - return nil, err - } - var dnsConf Config - if err := gyaml.Unmarshal(dnsData, &dnsConf); err != nil { - log.InjectScope().Warnf("Failed to parse inject dns config file %s", string(dnsData)) - return nil, err - } - - // 处理 java-agent 模式的注入 - javaAgentData, err := os.ReadFile(injectJavaFile) - if err != nil { - return nil, err - } - var javaAgentConf Config - if err := gyaml.Unmarshal(javaAgentData, &javaAgentConf); err != nil { - log.InjectScope().Warnf("Failed to parse inject java-agent config file %s", string(dnsData)) - return nil, err - } - - valuesConfig, err := os.ReadFile(valuesFile) - if err != nil { - return nil, err - } - - meshConfig, err := mesh.ReadMeshConfig(meshFile) - if err != nil { - return nil, err - } - - log.InjectScope().Infof("[MESH] New inject configuration: sha256sum %x", sha256.Sum256(meshData)) - log.InjectScope().Infof("[MESH] Policy: %v", meshConf.Policy) - log.InjectScope().Infof("[MESH] AlwaysInjectSelector: %v", meshConf.AlwaysInjectSelector) - log.InjectScope().Infof("[MESH] NeverInjectSelector: %v", meshConf.NeverInjectSelector) - log.InjectScope().Infof("[MESH] Template: |\n %v", strings.Replace(meshConf.Template, "\n", "\n ", -1)) - - log.InjectScope().Infof("[DNS] New inject configuration: sha256sum %x", sha256.Sum256(dnsData)) - log.InjectScope().Infof("[DNS] Policy: %v", dnsConf.Policy) - log.InjectScope().Infof("[DNS] AlwaysInjectSelector: %v", dnsConf.AlwaysInjectSelector) - log.InjectScope().Infof("[DNS] NeverInjectSelector: %v", dnsConf.NeverInjectSelector) - log.InjectScope().Infof("[DNS] Template: |\n %v", strings.Replace(dnsConf.Template, "\n", "\n ", -1)) - - log.InjectScope().Infof("[JavaAgent] New inject configuration: sha256sum %x", sha256.Sum256(javaAgentData)) - log.InjectScope().Infof("[JavaAgent] AlwaysInjectSelector: %v", javaAgentConf.AlwaysInjectSelector) - log.InjectScope().Infof("[JavaAgent] NeverInjectSelector: %v", javaAgentConf.NeverInjectSelector) - log.InjectScope().Infof("[JavaAgent] Template: |\n %v", strings.Replace(javaAgentConf.Template, "\n", "\n ", -1)) - - return &InjectConfigInfo{ - MeshInjectConf: &meshConf, - DnsInjectConf: &dnsConf, - JavaAgentInjectConf: &javaAgentConf, - MeshConf: meshConfig, - ValuesConf: string(valuesConfig), - }, nil -} - // WebhookParameters configures parameters for the sidecar injection // webhook. type WebhookParameters struct { // DefaultSidecarMode polaris-sidecar 默认的运行模式 DefaultSidecarMode utils.SidecarMode - // MeshConfigFile 处理 polaris-sidecar 运行模式为 mesh 的配置文件 - MeshConfigFile string - - // DnsConfigFile 处理 polaris-sidecar 运行模式为 dns 的配置文件 - DnsConfigFile string - - // JavaAgentConfigFile 处理运行模式为 javaagent 的配置文件 - JavaAgentConfigFile string - - ValuesFile string - - // MeshFile is the path to the mesh configuration file. - MeshFile string - - // CertFile is the path to the x509 certificate for https. - CertFile string - - // KeyFile is the path to the x509 private key matching `CertFile`. - KeyFile string + // TemplateFileConfig 模板配置文件位置 + TemplateFileConfig config.TemplateFileConfig // Port is the webhook port, e.g. typically 443 for https. Port int @@ -229,61 +108,31 @@ type WebhookParameters struct { // NewWebhook creates a new instance of a mutating webhook for automatic sidecar injection. func NewWebhook(p WebhookParameters) (*Webhook, error) { - // TODO: pass a pointer to mesh config from Pilot bootstrap, no need to watch and load 2 times - // This is needed before we implement advanced merging / patching of mesh config - injectConf, err := loadConfig(p.MeshConfigFile, p.DnsConfigFile, - p.JavaAgentConfigFile, p.MeshFile, p.ValuesFile) - - if err != nil { - return nil, err - } - pair, err := tls.LoadX509KeyPair(p.CertFile, p.KeyFile) - if err != nil { - return nil, err - } - watcher, err := fsnotify.NewWatcher() if err != nil { return nil, err } - - // TODO 直接监听 configmap // watch the parent directory of the target files so we can catch // symlink updates of k8s ConfigMaps volumes. - for _, file := range []string{p.MeshConfigFile, p.DnsConfigFile, p.MeshFile, p.CertFile, p.KeyFile} { - if file == p.MeshFile { - continue - } + for _, file := range p.TemplateFileConfig.GetWatchList() { watchDir, _ := filepath.Split(file) if err := watcher.Watch(watchDir); err != nil { return nil, fmt.Errorf("could not watch %v: %v", file, err) } } - + templateConfig, err := config.NewTemplateConfig(p.TemplateFileConfig) + if err != nil { + log.InjectScope().Errorf("NewTemplateConfig failed: %v", err) + return nil, err + } wh := &Webhook{ - sidecarMeshConfig: injectConf.MeshInjectConf, - sidecarMeshTemplateVersion: sidecarTemplateVersionHash(injectConf.MeshInjectConf.Template), - sidecarDnsConfig: injectConf.DnsInjectConf, - sidecarDnsTemplateVersion: sidecarTemplateVersionHash(injectConf.DnsInjectConf.Template), - sidecarJavaAgentConfig: injectConf.JavaAgentInjectConf, - sidecarJavaAgentTemplateVersion: sidecarTemplateVersionHash(injectConf.JavaAgentInjectConf.Template), - meshConfig: injectConf.MeshConf, - meshConfigFile: p.MeshConfigFile, - dnsConfigFile: p.DnsConfigFile, - javaAgentConfigFile: p.JavaAgentConfigFile, - valuesFile: p.ValuesFile, - valuesConfig: injectConf.ValuesConf, - meshFile: p.MeshFile, - watcher: watcher, - healthCheckInterval: p.HealthCheckInterval, - healthCheckFile: p.HealthCheckFile, - certFile: p.CertFile, - keyFile: p.KeyFile, - cert: &pair, - - // 新增查询 k8s 资源的操作者 - k8sClient: p.Client, - defaultSidecarMode: p.DefaultSidecarMode, + templateConfig: templateConfig, + templateFileConfig: p.TemplateFileConfig, + watcher: watcher, + healthCheckInterval: p.HealthCheckInterval, + healthCheckFile: p.HealthCheckFile, + k8sClient: p.Client, + defaultSidecarMode: p.DefaultSidecarMode, } if p.Mux != nil { @@ -292,7 +141,7 @@ func NewWebhook(p WebhookParameters) (*Webhook, error) { wh.server = &http.Server{ Addr: fmt.Sprintf(":%v", p.Port), // mtls disabled because apiserver webhook cert usage is still TBD. - TLSConfig: &tls.Config{GetCertificate: wh.getCert}, + TLSConfig: &tls.Config{GetCertificate: wh.templateConfig.GetCert}, } mux := http.NewServeMux() mux.HandleFunc("/inject", wh.serveInject) @@ -325,36 +174,9 @@ func (wh *Webhook) Run(stop <-chan struct{}) { select { case <-timerC: timerC = nil - injectConf, err := loadConfig(wh.meshConfigFile, wh.dnsConfigFile, wh.javaAgentConfigFile, wh.meshFile, wh.valuesFile) - if err != nil { - log.InjectScope().Errorf("update error: %v", err) - break + if err := wh.templateConfig.UpdateTemplateConfig(wh.templateFileConfig); err != nil { + log.InjectScope().Errorf("UpdateTemplateConfig failed: %v", err) } - - pair, err := tls.LoadX509KeyPair(wh.certFile, wh.keyFile) - if err != nil { - log.InjectScope().Errorf("reload cert error: %v", err) - break - } - - sidecarMeshConfig := injectConf.MeshInjectConf - sidecarDnsConfig := injectConf.DnsInjectConf - sidecarJavaagentConfig := injectConf.JavaAgentInjectConf - meshConfig := injectConf.MeshConf - valuesConfig := injectConf.ValuesConf - - wh.mu.Lock() - wh.sidecarMeshConfig = sidecarMeshConfig - wh.sidecarMeshTemplateVersion = sidecarTemplateVersionHash(sidecarMeshConfig.Template) - wh.sidecarDnsConfig = sidecarDnsConfig - wh.sidecarDnsTemplateVersion = sidecarTemplateVersionHash(sidecarDnsConfig.Template) - wh.sidecarJavaAgentConfig = sidecarJavaagentConfig - wh.sidecarJavaAgentTemplateVersion = sidecarTemplateVersionHash(sidecarJavaagentConfig.Template) - - wh.valuesConfig = valuesConfig - wh.meshConfig = meshConfig - wh.cert = &pair - wh.mu.Unlock() case event := <-wh.watcher.Event: log.InjectScope().Infof("Injector watch update: %+v", event) // use a timer to debounce configuration updates @@ -374,12 +196,6 @@ func (wh *Webhook) Run(stop <-chan struct{}) { } } -func (wh *Webhook) getCert(*tls.ClientHelloInfo) (*tls.Certificate, error) { - wh.mu.Lock() - defer wh.mu.Unlock() - return wh.cert, nil -} - // It would be great to use https://github.com/mattbaird/jsonpatch to // generate RFC6902 JSON patches. Unfortunately, it doesn't produce // correct patches for object removal. Fortunately, our patching needs @@ -582,30 +398,18 @@ func updateAnnotation(target map[string]string, added map[string]string) (patch return patch } -func (wh *Webhook) createPatch(sidecarMode utils.SidecarMode, pod *corev1.Pod, prevStatus *SidecarInjectionStatus, annotations map[string]string, sic *SidecarInjectionSpec, - workloadName string, -) ([]byte, error) { - +func createPatch(opt *PatchOptions) ([]byte, error) { + sidecarMode := opt.SidecarMode + pod := opt.Pod + prevStatus := opt.PrevStatus + sic := opt.Sic + annotations := opt.Annotations var patch []Rfc6902PatchOperation patchBuilder, ok := _PatchBuilders[utils.ParseSidecarModeName(sidecarMode)] if !ok { return nil, errors.NewInternalError(fmt.Errorf("sidecar-mode %+v not found target patch builder", sidecarMode)) } - if sidecarMode != utils.SidecarForMesh { - delete(annotations, utils.SidecarEnvoyMetadata) - } - - opt := &PatchOptions{ - Pod: pod, - KubeClient: wh.k8sClient, - PrevStatus: prevStatus, - SidecarMode: sidecarMode, - WorkloadName: workloadName, - Sic: sic, - Annotations: annotations, - ExternalInfo: map[string]string{}, - } // Remove any containers previously injected by kube-inject using // container and volume name as unique key for removal. @@ -778,117 +582,31 @@ func toV1beta1AdmissionResponse(err error) *v1beta1.AdmissionResponse { func (wh *Webhook) injectV1beta1(ar *v1beta1.AdmissionReview) *v1beta1.AdmissionResponse { req := ar.Request - var pod corev1.Pod - if err := json.Unmarshal(req.Object.Raw, &pod); err != nil { + log.InjectScope().Infof("Object: %v", string(req.Object.Raw)) + log.InjectScope().Infof("OldObject: %v", string(req.OldObject.Raw)) + // 解析原始对象 + podInfo, err := assignPodDataInfo(req.Object.Raw, req.Namespace, wh) + if err != nil { handleError(fmt.Sprintf("Could not unmarshal raw object: %v %s", err, string(req.Object.Raw))) return toV1beta1AdmissionResponse(err) } - - sidecarMode := wh.getSidecarMode(req.Namespace, &pod) - - // Deal with potential empty fields, e.g., when the pod is created by a deployment - podName := potentialPodName(&pod.ObjectMeta) - if pod.ObjectMeta.Namespace == "" { - pod.ObjectMeta.Namespace = req.Namespace - } - - log.InjectScope().Infof("AdmissionReview for Kind=%v Namespace=%v Name=%v (%v) UID=%v Rfc6902PatchOperation=%v UserInfo=%v", - req.Kind, req.Namespace, req.Name, podName, req.UID, req.Operation, req.UserInfo) - log.InjectScope().Infof("Object: %v", string(req.Object.Raw)) - log.InjectScope().Infof("OldObject: %v", string(req.OldObject.Raw)) - - config := wh.sidecarMeshConfig - tempVersion := wh.sidecarMeshTemplateVersion - if sidecarMode == utils.SidecarForDns { - config = wh.sidecarDnsConfig - tempVersion = wh.sidecarDnsTemplateVersion - } - if sidecarMode == utils.SidecarForJavaAgent { - config = wh.sidecarJavaAgentConfig - tempVersion = wh.sidecarJavaAgentTemplateVersion - } - - if !wh.injectRequired(ignoredNamespaces, config, &pod.Spec, &pod.ObjectMeta) { - log.InjectScope().Infof("Skipping %s/%s due to policy check", pod.ObjectMeta.Namespace, podName) - return &v1beta1.AdmissionResponse{ - Allowed: true, - } - } - // try to capture more useful namespace/name info for deployments, etc. - // TODO(dougreid): expand to enable lookup of OWNERs recursively a la kubernetesenv - deployMeta := pod.ObjectMeta.DeepCopy() - deployMeta.Namespace = req.Namespace - - typeMetadata := &metav1.TypeMeta{ - Kind: "Pod", - APIVersion: "v1", - } - - if len(pod.GenerateName) > 0 { - // if the pod name was generated (or is scheduled for generation), we can begin an investigation into the controlling reference for the pod. - var controllerRef metav1.OwnerReference - controllerFound := false - for _, ref := range pod.GetOwnerReferences() { - if *ref.Controller { - controllerRef = ref - controllerFound = true - break - } - } - if controllerFound { - typeMetadata.APIVersion = controllerRef.APIVersion - typeMetadata.Kind = controllerRef.Kind - - // heuristic for deployment detection - if typeMetadata.Kind == "ReplicaSet" && strings.HasSuffix(controllerRef.Name, pod.Labels["pod-template-hash"]) { - name := strings.TrimSuffix(controllerRef.Name, "-"+pod.Labels["pod-template-hash"]) - deployMeta.Name = name - typeMetadata.Kind = "Deployment" - } else { - deployMeta.Name = controllerRef.Name - } - } - } - - if deployMeta.Name == "" { - // if we haven't been able to extract a deployment name, then just give it the pod name - deployMeta.Name = pod.Name - } - proxyCfg := wh.meshConfig.DefaultConfig - spec, annotations, iStatus, err := InjectionData(config.Template, wh.valuesConfig, tempVersion, typeMetadata, - deployMeta, &pod.Spec, &pod.ObjectMeta, proxyCfg) + log.InjectScope().Infof("AdmissionReview for Kind=%v Namespace=%v Name=%v (%v) UID=%v Rfc6902PatchOperation=%v "+ + "UserInfo=%v", req.Kind, req.Namespace, req.Name, podInfo.podName, req.UID, req.Operation, req.UserInfo) + // 获取准入注入patch + patchBytes, err := wh.getPodPatch(podInfo) if err != nil { - handleError(fmt.Sprintf("Injection data: err=%v spec=%v\n", err, iStatus)) + handleError(fmt.Sprintf("Could not get admission patch: %v", err)) return toV1beta1AdmissionResponse(err) } - // 不需要做任何 POD 修改操作 - if spec == nil { - reviewResponse := v1beta1.AdmissionResponse{ + // 跳过注入 + if patchBytes == nil { + log.InjectScope().Infof("[Webhook] skipping %s/%s due to empty patchBytes", req.Namespace, podInfo.podName) + return &v1beta1.AdmissionResponse{ Allowed: true, } - return &reviewResponse - } - - if len(annotations) == 0 { - annotations = map[string]string{} - } - if len(iStatus) != 0 { - annotations[annotation.SidecarStatus.Name] = iStatus - } - // Add all additional injected annotations - for k, v := range config.InjectedAnnotations { - annotations[k] = v - } - - patchBytes, err := wh.createPatch(sidecarMode, &pod, injectionStatus(&pod), annotations, spec, deployMeta.Name) - if err != nil { - handleError(fmt.Sprintf("AdmissionResponse: err=%v spec=%v\n", err, spec)) - return toV1beta1AdmissionResponse(err) } - log.InjectScope().Infof("AdmissionResponse: patch=%v\n", string(patchBytes)) - reviewResponse := v1beta1.AdmissionResponse{ Allowed: true, Patch: patchBytes, @@ -903,120 +621,31 @@ func (wh *Webhook) injectV1beta1(ar *v1beta1.AdmissionReview) *v1beta1.Admission // inject istio 核心准入注入逻辑 func (wh *Webhook) injectV1(ar *v1.AdmissionReview) *v1.AdmissionResponse { req := ar.Request - var pod corev1.Pod - if err := json.Unmarshal(req.Object.Raw, &pod); err != nil { + log.InjectScope().Infof("Object: %v", string(req.Object.Raw)) + log.InjectScope().Infof("OldObject: %v", string(req.OldObject.Raw)) + // 解析原始对象 + podInfo, err := assignPodDataInfo(req.Object.Raw, req.Namespace, wh) + if err != nil { handleError(fmt.Sprintf("Could not unmarshal raw object: %v %s", err, string(req.Object.Raw))) return toV1AdmissionResponse(err) } - - sidecarMode := wh.getSidecarMode(req.Namespace, &pod) - - // Deal with potential empty fields, e.g., when the pod is created by a deployment - podName := potentialPodName(&pod.ObjectMeta) - if pod.ObjectMeta.Namespace == "" { - pod.ObjectMeta.Namespace = req.Namespace - } - - log.InjectScope().Infof("[Webhook] admissionReview for Kind=%v Namespace=%v Name=%v (%v) UID=%v Rfc6902PatchOperation=%v UserInfo=%v", - req.Kind, req.Namespace, req.Name, podName, req.UID, req.Operation, req.UserInfo) - log.InjectScope().Infof("[Webhook] object: %v", string(req.Object.Raw)) - log.InjectScope().Infof("[Webhook] oldObject: %v", string(req.OldObject.Raw)) - - config := wh.sidecarMeshConfig - tempVersion := wh.sidecarMeshTemplateVersion - if sidecarMode == utils.SidecarForDns { - config = wh.sidecarDnsConfig - tempVersion = wh.sidecarDnsTemplateVersion - } - if sidecarMode == utils.SidecarForJavaAgent { - config = wh.sidecarJavaAgentConfig - tempVersion = wh.sidecarJavaAgentTemplateVersion - } - - if !wh.injectRequired(ignoredNamespaces, config, &pod.Spec, &pod.ObjectMeta) { - log.InjectScope().Infof("[Webhook] skipping %s/%s due to policy check", pod.ObjectMeta.Namespace, podName) - return &v1.AdmissionResponse{ - Allowed: true, - } - } - - // try to capture more useful namespace/name info for deployments, etc. - // TODO(dougreid): expand to enable lookup of OWNERs recursively a la kubernetesenv - deployMeta := pod.ObjectMeta.DeepCopy() - deployMeta.Namespace = req.Namespace - - typeMetadata := &metav1.TypeMeta{ - Kind: "Pod", - APIVersion: "v1", - } - - if len(pod.GenerateName) > 0 { - // if the pod name was generated (or is scheduled for generation), we can begin an investigation into the controlling reference for the pod. - var controllerRef metav1.OwnerReference - controllerFound := false - for _, ref := range pod.GetOwnerReferences() { - if *ref.Controller { - controllerRef = ref - controllerFound = true - break - } - } - if controllerFound { - typeMetadata.APIVersion = controllerRef.APIVersion - typeMetadata.Kind = controllerRef.Kind - - // heuristic for deployment detection - if typeMetadata.Kind == "ReplicaSet" && strings.HasSuffix(controllerRef.Name, pod.Labels["pod-template-hash"]) { - name := strings.TrimSuffix(controllerRef.Name, "-"+pod.Labels["pod-template-hash"]) - deployMeta.Name = name - typeMetadata.Kind = "Deployment" - } else { - deployMeta.Name = controllerRef.Name - } - } - } - - if deployMeta.Name == "" { - // if we haven't been able to extract a deployment name, then just give it the pod name - deployMeta.Name = pod.Name - } - - copyProxyCfg := wh.meshConfig.Clone() - spec, annotations, iStatus, err := InjectionData(config.Template, wh.valuesConfig, tempVersion, typeMetadata, deployMeta, - &pod.Spec, &pod.ObjectMeta, copyProxyCfg.DefaultConfig) + log.InjectScope().Infof("AdmissionReview for Kind=%v Namespace=%v Name=%v (%v) UID=%v Rfc6902PatchOperation=%v "+ + "UserInfo=%v", req.Kind, req.Namespace, req.Name, podInfo.podName, req.UID, req.Operation, req.UserInfo) + // 获取准入注入patch + patchBytes, err := wh.getPodPatch(podInfo) if err != nil { - handleError(fmt.Sprintf("Injection data: err=%v spec=%v\n", err, iStatus)) + handleError(fmt.Sprintf("Could not get admission patch: %v", err)) return toV1AdmissionResponse(err) } - // 不需要做任何 POD 修改操作 - if spec == nil { - reviewResponse := v1.AdmissionResponse{ + // 跳过注入 + if patchBytes == nil { + log.InjectScope().Infof("[Webhook] skipping %s/%s due to empty patchBytes", req.Namespace, podInfo.podName) + return &v1.AdmissionResponse{ Allowed: true, } - return &reviewResponse } - - if len(annotations) == 0 { - annotations = map[string]string{} - } - if len(iStatus) != 0 { - annotations[annotation.SidecarStatus.Name] = iStatus - } - - // Add all additional injected annotations - for k, v := range config.InjectedAnnotations { - annotations[k] = v - } - - patchBytes, err := wh.createPatch(sidecarMode, &pod, injectionStatus(&pod), annotations, spec, deployMeta.Name) - if err != nil { - handleError(fmt.Sprintf("AdmissionResponse: err=%v spec=%v\n", err, spec)) - return toV1AdmissionResponse(err) - } - - log.InjectScope().Infof("[Webhook] admissionResponse: patch=%v\n", string(patchBytes)) - + log.InjectScope().Infof("AdmissionResponse: patch=%v\n", string(patchBytes)) reviewResponse := v1.AdmissionResponse{ Allowed: true, Patch: patchBytes, diff --git a/pkg/util/types.go b/pkg/util/types.go index d37915c3..572169cb 100644 --- a/pkg/util/types.go +++ b/pkg/util/types.go @@ -48,9 +48,23 @@ const ( // SidecarBindPort xds metadata key when node is run in sidecar mode SidecarBindPort = "sidecar.polarismesh.cn/bindPorts" // SidecarEnvoyMetadata - SidecarEnvoyMetadata = "sidecar.polarismesh.cn/envoyMetadata" + SidecarEnvoyMetadata = "sidecar.polarismesh.cn/envoyMetadata" + SidecarEnvoyInjectKey = "sidecar.polarismesh.cn/openOnDemand" + SidecarEnvoyInjectProxyKey = "OPEN_DEMAND" PolarisSidecarModeLabel = "polaris-sidecar-mode" + + // PolarisInjectionKey 标记是否开启注入 + PolarisInjectionKey = "polarismesh.cn/inject" + // PolarisInjectionEnabled 开启注入(白名单功能)的标记值 + PolarisInjectionEnabled = "enabled" + // PolarisInjectionDisabled 关闭注入(黑名单功能)的标记值 + PolarisInjectionDisabled = "disabled" + + // PolarisInjectModeLabelKeyJavaAgent 注入模式为 javaagent 的 pod label + PolarisInjectModeLabelKeyJavaAgent = "polarismesh.cn/javaagent" + // PolarisInjectModeLabelValueTrue 表示需要进行注入 的 pod label 的值 + PolarisInjectModeLabelValueTrue = "true" ) const ( From c0b9e464f68bb151ca6713f3da79047b48fc2af4 Mon Sep 17 00:00:00 2001 From: evelynwei Date: Wed, 19 Feb 2025 20:49:32 +0800 Subject: [PATCH 02/17] =?UTF-8?q?feat:=20=E8=A7=A3=E6=9E=90annotations?= =?UTF-8?q?=E6=B3=A8=E8=A7=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pkg/kube/inject/apply/javaagent/patch.go | 57 ++--- pkg/inject/pkg/kube/inject/base.go | 136 +---------- pkg/inject/pkg/kube/inject/base_test.go | 36 ++- pkg/inject/pkg/kube/inject/inject.go | 227 +++++++++++------- pkg/inject/pkg/kube/inject/inject_test.go | 113 --------- pkg/inject/pkg/kube/inject/pod.go | 28 ++- pkg/util/types.go | 7 + 7 files changed, 231 insertions(+), 373 deletions(-) delete mode 100644 pkg/inject/pkg/kube/inject/inject_test.go diff --git a/pkg/inject/pkg/kube/inject/apply/javaagent/patch.go b/pkg/inject/pkg/kube/inject/apply/javaagent/patch.go index 0824d5bf..d2a6b549 100644 --- a/pkg/inject/pkg/kube/inject/apply/javaagent/patch.go +++ b/pkg/inject/pkg/kube/inject/apply/javaagent/patch.go @@ -37,10 +37,9 @@ import ( // Java Agent 场景下的特殊 annonations 信息 const ( - customJavaAgentVersion = "polarismesh.cn/javaagentVersion" - customJavaAgentPluginFramework = "polarismesh.cn/javaagentFrameworkName" - customJavaAgentPluginFrameworkVersion = "polarismesh.cn/javaagentFrameworkVersion" - customJavaAgentPluginConfig = "polarismesh.cn/javaagentConfig" + envJavaAgentPluginType = "JAVA_AGENT_PLUGIN_TYPE" + envJavaAgentFrameworkName = "JAVA_AGENT_FRAMEWORK_NAME" + envJavaAgentFrameworkVersion = "JAVA_AGENT_FRAMEWORK_VERSION" ) var oldAgentVersions = map[string]struct{}{ @@ -102,20 +101,20 @@ func (pb *PodPatchBuilder) handleJavaAgentInit(opt *inject.PatchOptions, pod *co // 判断用户是否自定义了 javaagent 的版本 oldImageInfo := strings.Split(add.Image, ":") if len(oldImageInfo) > 1 { - opt.ExternalInfo[customJavaAgentVersion] = oldImageInfo[1] + opt.ExternalInfo[utils.CustomJavaAgentVersion] = oldImageInfo[1] } - if val, ok := annonations[customJavaAgentVersion]; ok && val != "" { + if val, ok := annonations[utils.CustomJavaAgentVersion]; ok && val != "" { add.Image = fmt.Sprintf("%s:%s", oldImageInfo[0], val) - opt.ExternalInfo[customJavaAgentVersion] = val + opt.ExternalInfo[utils.CustomJavaAgentVersion] = val } - frameworkName, frameworkNameOk := annonations[customJavaAgentPluginFramework] + frameworkName, frameworkNameOk := annonations[utils.CustomJavaAgentPluginFramework] if !frameworkNameOk { log.InjectScope().Warnf("handle polaris-javaagent-init inject for pod=[%s, %s] not found frameworkName", pod.Namespace, pod.Name) } - frameworkVersion, frameworkVersionOk := annonations[customJavaAgentPluginFrameworkVersion] + frameworkVersion, frameworkVersionOk := annonations[utils.CustomJavaAgentPluginFrameworkVersion] if !frameworkVersionOk { log.InjectScope().Warnf("handle polaris-javaagent-init inject for pod=[%s, %s] not found frameworkVersion", pod.Namespace, pod.Name) @@ -124,26 +123,26 @@ func (pb *PodPatchBuilder) handleJavaAgentInit(opt *inject.PatchOptions, pod *co pluginType := frameworkName + frameworkVersion if frameworkName != "" && frameworkVersion != "" { add.Env = append(add.Env, corev1.EnvVar{ - Name: "JAVA_AGENT_PLUGIN_TYPE", + Name: envJavaAgentPluginType, Value: pluginType, }) add.Env = append(add.Env, corev1.EnvVar{ - Name: "JAVA_AGENT_FRAMEWORK_NAME", + Name: envJavaAgentFrameworkName, Value: frameworkName, }) add.Env = append(add.Env, corev1.EnvVar{ - Name: "JAVA_AGENT_FRAMEWORK_VERSION", + Name: envJavaAgentFrameworkVersion, Value: frameworkVersion, }) } defaultParam := map[string]string{ - "MicroserviceName": opt.Annotations[util.SidecarServiceName], - // TODO: 添加服务注册命名空间 - "PolarisServerIP": strings.Split(polarisapi.PolarisGrpc, ":")[0], - "PolarisDiscoverPort": strings.Split(polarisapi.PolarisGrpc, ":")[1], - "PolarisConfigIP": strings.Split(polarisapi.PolarisConfigGrpc, ":")[0], - "PolarisConfigPort": strings.Split(polarisapi.PolarisConfigGrpc, ":")[1], + "MicroserviceNamespace": opt.Annotations[util.SidecarNamespaceName], + "MicroserviceName": opt.Annotations[util.SidecarServiceName], + "PolarisServerIP": strings.Split(polarisapi.PolarisGrpc, ":")[0], + "PolarisDiscoverPort": strings.Split(polarisapi.PolarisGrpc, ":")[1], + "PolarisConfigIP": strings.Split(polarisapi.PolarisConfigGrpc, ":")[0], + "PolarisConfigPort": strings.Split(polarisapi.PolarisConfigGrpc, ":")[1], } add.Env = append(add.Env, @@ -200,7 +199,7 @@ func (pb *PodPatchBuilder) handleJavaAgentInit(opt *inject.PatchOptions, pod *co } // 查看用户是否自定义了相关配置信息 // 需要根据用户的自定义参数信息,将 agent 的特定 application.properties 文件注入到 javaagent-init 中 - if properties, ok := annonations[customJavaAgentPluginConfig]; ok { + if properties, ok := annonations[utils.CustomJavaAgentPluginConfig]; ok { customProperties := map[string]string{} if err := json.Unmarshal([]byte(properties), &customProperties); err != nil { return err @@ -241,10 +240,10 @@ func (pb *PodPatchBuilder) updateContainer(opt *inject.PatchOptions, sidecarMode patchs := make([]inject.Rfc6902PatchOperation, 0, len(target)) annonations := pod.Annotations - if val, ok := annonations[customJavaAgentVersion]; ok && val != "" { - opt.ExternalInfo[customJavaAgentVersion] = val + if val, ok := annonations[utils.CustomJavaAgentVersion]; ok && val != "" { + opt.ExternalInfo[utils.CustomJavaAgentVersion] = val } else { - annonations[customJavaAgentVersion] = "latest" + annonations[utils.CustomJavaAgentVersion] = "latest" } defaultProperties := make(map[string]string) @@ -253,8 +252,8 @@ func (pb *PodPatchBuilder) updateContainer(opt *inject.PatchOptions, sidecarMode for index, container := range target { envs := container.Env javaEnvIndex := -1 - if _, valid := oldAgentVersions[annonations[customJavaAgentVersion]]; !valid { - if properties, ok := annonations[customJavaAgentPluginConfig]; ok { + if _, valid := oldAgentVersions[annonations[utils.CustomJavaAgentVersion]]; !valid { + if properties, ok := annonations[utils.CustomJavaAgentPluginConfig]; ok { customProperties := map[string]string{} if properties != "" { if err := json.Unmarshal([]byte(properties), &customProperties); err != nil { @@ -281,20 +280,22 @@ func (pb *PodPatchBuilder) updateContainer(opt *inject.PatchOptions, sidecarMode } } if javaEnvIndex != -1 { - if _, valid := oldAgentVersions[annonations[customJavaAgentVersion]]; !valid { + if _, valid := oldAgentVersions[annonations[utils.CustomJavaAgentVersion]]; !valid { envs[javaEnvIndex] = updateJavaEnvVar(envs[javaEnvIndex], ActiveJavaAgentCmd, javaToolOptionsValue) } else { - envs[javaEnvIndex] = updateJavaEnvVar(envs[javaEnvIndex], fmt.Sprintf(OldActiveJavaAgentCmd, opt.ExternalInfo[customJavaAgentVersion]), "") + envs[javaEnvIndex] = updateJavaEnvVar(envs[javaEnvIndex], fmt.Sprintf(OldActiveJavaAgentCmd, + opt.ExternalInfo[utils.CustomJavaAgentVersion]), "") } } } if javaEnvIndex == -1 { // 注入 java agent 需要用到的参数信息 var newEnvVar corev1.EnvVar - if _, valid := oldAgentVersions[annonations[customJavaAgentVersion]]; !valid { + if _, valid := oldAgentVersions[annonations[utils.CustomJavaAgentVersion]]; !valid { newEnvVar = updateJavaEnvVar(corev1.EnvVar{}, ActiveJavaAgentCmd, javaToolOptionsValue) } else { - newEnvVar = updateJavaEnvVar(corev1.EnvVar{}, fmt.Sprintf(OldActiveJavaAgentCmd, opt.ExternalInfo[customJavaAgentVersion]), "") + newEnvVar = updateJavaEnvVar(corev1.EnvVar{}, fmt.Sprintf(OldActiveJavaAgentCmd, + opt.ExternalInfo[utils.CustomJavaAgentVersion]), "") } container.Env = append(container.Env, newEnvVar) } diff --git a/pkg/inject/pkg/kube/inject/base.go b/pkg/inject/pkg/kube/inject/base.go index e8b31574..4901e5ef 100644 --- a/pkg/inject/pkg/kube/inject/base.go +++ b/pkg/inject/pkg/kube/inject/base.go @@ -7,14 +7,8 @@ import ( "github.com/ghodss/yaml" "github.com/hashicorp/go-multierror" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/labels" "github.com/polarismesh/polaris-controller/common/log" - "github.com/polarismesh/polaris-controller/pkg/inject/api/annotation" - "github.com/polarismesh/polaris-controller/pkg/inject/pkg/config" - utils "github.com/polarismesh/polaris-controller/pkg/util" ) // getPodPatch 处理 admission webhook 请求 @@ -98,7 +92,7 @@ func (wh *Webhook) getPodPatch(p *podDataInfo) ([]byte, error) { // set sidecar --concurrency applyConcurrency(injectData.Containers) - + injectStatus := p.addInjectStatusAnnotation(injectData) // 生成POD修改的patch opt := &PatchOptions{ Pod: p.podObject, @@ -112,133 +106,9 @@ func (wh *Webhook) getPodPatch(p *podDataInfo) ([]byte, error) { } patchBytes, err := createPatch(opt) if err != nil { - log.InjectScope().Errorf(fmt.Sprintf("AdmissionResponse: err=%v injectData=%v\n", err, injectData)) + log.InjectScope().Errorf(fmt.Sprintf("AdmissionResponse: err=%v injectStatus:%s injectData=%v\n", err, + injectStatus, injectData)) return nil, err } return patchBytes, err } - -func (wh *Webhook) requireInject(p *podDataInfo) bool { - switch p.injectMode { - case utils.SidecarForMesh: - return wh.meshInjectRequired(p) - case utils.SidecarForJavaAgent, utils.SidecarForDns: - return wh.commonInjectRequired(p) - default: - return false - } -} - -// 是否需要注入, 规则参考istio官方定义 -// https://istio.io/latest/zh/docs/ops/common-problems/injection/ -func (wh *Webhook) commonInjectRequired(p *podDataInfo) bool { - pod := p.podObject - templateConfig := p.injectTemplateConfig - - if isIgnoredNamespace(pod.Namespace) { - return false - } - - // annotations为最高优先级 - injectionRequested, useDefaultPolicy := parseInjectionAnnotation(pod.GetAnnotations()) - log.InjectScope().Infof("parseInjectionAnnotation for %s/%s: UseDefault=%v injectionRequested=%v", - pod.Namespace, pod.Name, useDefaultPolicy, injectionRequested) - - // Labels为次优先级 - if useDefaultPolicy { - injectionRequested, useDefaultPolicy = evaluateSelectors(pod, templateConfig, p.podName) - log.InjectScope().Infof("evaluateSelectors for %s/%s: UseDefault=%v injectionRequested=%v", - pod.Namespace, pod.Name, useDefaultPolicy, injectionRequested) - } - - // Policy为最低优先级 - required := determineInjectionRequirement(templateConfig.Policy, useDefaultPolicy, injectionRequested) - log.InjectScope().Infof("determineInjectionRequirement for %s/%s: Policy=%s UseDefault=%v Requested=%v Required=%v", - pod.Namespace, pod.Name, templateConfig.Policy, useDefaultPolicy, injectionRequested, required) - - return required -} - -func isIgnoredNamespace(namespace string) bool { - for _, ignored := range ignoredNamespaces { - if namespace == ignored { - return true - } - } - return false -} - -// 解析Annotation, 用于注解位置的黑白名单功能 -func parseInjectionAnnotation(annotations map[string]string) (requested bool, useDefault bool) { - var value string - newFlag, newExists := annotations[utils.PolarisInjectionKey] - if newExists { - value = strings.ToLower(newFlag) - } else { - if flag, ok := annotations[annotation.SidecarInject.Name]; ok { - value = strings.ToLower(flag) - } - } - switch value { - case "y", "yes", "true", "on", "enable", "enabled": - // annotation白名单, 显示开启 - return true, false - case "n", "no", "false", "off", "disable", "disabled": - // annotation黑名单, 显示关闭 - return false, false - default: // including empty string - return false, true - } -} - -// 检查label的黑白名单功能 -func evaluateSelectors(pod *corev1.Pod, config *config.TemplateConfig, podName string) (bool, bool) { - // Check NeverInject selectors first - if inject, ok := checkSelectors(pod, config.NeverInjectSelector, "NeverInjectSelector", podName, false); ok { - return inject, false - } - - // Then check AlwaysInject selectors - if inject, ok := checkSelectors(pod, config.AlwaysInjectSelector, "AlwaysInjectSelector", podName, true); ok { - return inject, false - } - - return false, true -} - -func checkSelectors(pod *corev1.Pod, selectors []metav1.LabelSelector, selectorType string, podName string, - allowInject bool) (bool, bool) { - for _, selector := range selectors { - ls, err := metav1.LabelSelectorAsSelector(&selector) - if err != nil { - log.InjectScope().Warnf("Invalid %s: %v (%v)", selectorType, selector, err) - continue // Continue checking other selectors - } - - if !ls.Empty() && ls.Matches(labels.Set(pod.Labels)) { - log.InjectScope().Infof("Pod %s/%s: %s matched labels %v", - pod.Namespace, podName, selectorType, pod.Labels) - return allowInject, true - } - } - return false, false -} - -func determineInjectionRequirement(policy config.InjectionPolicy, useDefault bool, requested bool) bool { - switch policy { - case config.InjectionPolicyEnabled: - if useDefault { - return true - } - return requested - case config.InjectionPolicyDisabled: - if useDefault { - return false - } - return requested - default: - log.InjectScope().Errorf("Invalid injection policy: %s. Valid values: [%s, %s]", - policy, config.InjectionPolicyDisabled, config.InjectionPolicyEnabled) - return false - } -} diff --git a/pkg/inject/pkg/kube/inject/base_test.go b/pkg/inject/pkg/kube/inject/base_test.go index 5bcc047d..53dd09a7 100644 --- a/pkg/inject/pkg/kube/inject/base_test.go +++ b/pkg/inject/pkg/kube/inject/base_test.go @@ -11,7 +11,7 @@ import ( utils "github.com/polarismesh/polaris-controller/pkg/util" ) -func TestCommonInjectRequired(t *testing.T) { +func TestRequireInject(t *testing.T) { // 通用测试配置 defaultTemplate := &config.TemplateConfig{ NeverInjectSelector: []metav1.LabelSelector{{MatchLabels: map[string]string{ @@ -24,10 +24,35 @@ func TestCommonInjectRequired(t *testing.T) { // 参考istio官方定义 // https://istio.io/latest/zh/docs/ops/common-problems/injection/ testCases := []struct { - name string - podSetup func(*corev1.Pod, *config.TemplateConfig) - expected bool + name string + podSetup func(*corev1.Pod, *config.TemplateConfig) + injectMode utils.SidecarMode + expected bool }{ + { + name: "mesh类型,当启用HostNetwork时无需注入", + podSetup: func(p *corev1.Pod, _ *config.TemplateConfig) { + p.Spec.HostNetwork = true + }, + injectMode: utils.SidecarForMesh, + expected: false, + }, + { + name: "dns类型,当启用HostNetwork时无需注入", + podSetup: func(p *corev1.Pod, _ *config.TemplateConfig) { + p.Spec.HostNetwork = true + }, + injectMode: utils.SidecarForDns, + expected: false, + }, + { + name: "javaagent,当启用HostNetwork时不影响注入", + podSetup: func(p *corev1.Pod, _ *config.TemplateConfig) { + p.Spec.HostNetwork = true + }, + injectMode: utils.SidecarForJavaAgent, + expected: true, + }, { name: "在kube-system命名空间中跳过注入", podSetup: func(p *corev1.Pod, _ *config.TemplateConfig) { @@ -160,11 +185,12 @@ func TestCommonInjectRequired(t *testing.T) { podInfo := &podDataInfo{ podObject: pod, + injectMode: tc.injectMode, injectTemplateConfig: defaultTemplate, podName: pod.Name, } - result := wh.commonInjectRequired(podInfo) + result := wh.requireInject(podInfo) if result != tc.expected { t.Errorf("%s: 期望 %v 但得到 %v", tc.name, tc.expected, result) } diff --git a/pkg/inject/pkg/kube/inject/inject.go b/pkg/inject/pkg/kube/inject/inject.go index 8cb39c16..79c0288e 100644 --- a/pkg/inject/pkg/kube/inject/inject.go +++ b/pkg/inject/pkg/kube/inject/inject.go @@ -27,6 +27,7 @@ import ( "github.com/polarismesh/polaris-controller/pkg/inject/api/annotation" "github.com/polarismesh/polaris-controller/pkg/inject/pkg/config" "github.com/polarismesh/polaris-controller/pkg/inject/pkg/config/mesh" + utils "github.com/polarismesh/polaris-controller/pkg/util" ) type annotationValidationFunc func(value string) error @@ -59,12 +60,30 @@ var ( annotation.SidecarTrafficIncludeInboundPorts.Name: ValidateIncludeInboundPorts, annotation.SidecarTrafficExcludeInboundPorts.Name: ValidateExcludeInboundPorts, annotation.SidecarTrafficExcludeOutboundPorts.Name: ValidateExcludeOutboundPorts, + utils.PolarisInjectionKey: alwaysValidFunc, + } + + annotationRegistryForDns = map[string]annotationValidationFunc{ + annotation.SidecarInject.Name: alwaysValidFunc, + annotation.SidecarStatus.Name: alwaysValidFunc, + utils.PolarisInjectionKey: alwaysValidFunc, + } + + annotationRegistryForJavaAgent = map[string]annotationValidationFunc{ + utils.CustomJavaAgentVersion: alwaysValidFunc, + utils.CustomJavaAgentPluginFramework: alwaysValidFunc, + utils.CustomJavaAgentPluginFrameworkVersion: alwaysValidFunc, + utils.CustomJavaAgentPluginConfig: alwaysValidFunc, + annotation.SidecarInject.Name: alwaysValidFunc, + annotation.SidecarStatus.Name: alwaysValidFunc, + utils.PolarisInjectionKey: alwaysValidFunc, } ) -func validateMeshAnnotations(annotations map[string]string) (err error) { +func validateAnnotations(injectMode utils.SidecarMode, annotations map[string]string) (err error) { + annotationRegistry := getAnnotationRegistry(injectMode) for name, value := range annotations { - if v, ok := annotationRegistryForMesh[name]; ok { + if v, ok := annotationRegistry[name]; ok { if e := v(value); e != nil { err = multierror.Append(err, fmt.Errorf("invalid value '%s' for annotation '%s': %v", value, name, e)) } @@ -103,115 +122,149 @@ type SidecarTemplateData struct { Values map[string]interface{} } -func (wh *Webhook) meshInjectRequired(p *podDataInfo) bool { - podSpec := &p.podObject.Spec - metadata := &p.podObject.ObjectMeta +// 是否需要注入, 规则参考istio官方定义 +// https://istio.io/latest/zh/docs/ops/common-problems/injection/ +func (wh *Webhook) requireInject(p *podDataInfo) bool { + pod := p.podObject templateConfig := p.injectTemplateConfig - podName := p.podName - // Skip injection when host networking is enabled. The problem is - // that the iptable changes are assumed to be within the pod when, - // in fact, they are changing the routing at the host level. This - // often results in routing failures within a node which can - // affect the network provider within the cluster causing - // additional pod failures. - if podSpec.HostNetwork { + + if pod.Spec.HostNetwork && (p.injectMode == utils.SidecarForMesh || p.injectMode == utils.SidecarForDns) { return false } - // skip special kubernetes system namespaces - for _, namespace := range ignoredNamespaces { - if metadata.Namespace == namespace { - return false - } + if isIgnoredNamespace(pod.Namespace) { + return false + } + + annotations := pod.GetAnnotations() + annotationStr := buildAnnotationLogString(p.injectMode, annotations) + // annotations为最高优先级 + injectionRequested, useDefaultPolicy := parseInjectionAnnotation(pod.GetAnnotations()) + log.InjectScope().Infof("parseInjectionAnnotation for %s/%s: UseDefault=%v injectionRequested=%v annotations=%s", + pod.Namespace, pod.Name, useDefaultPolicy, injectionRequested, annotationStr) + + // Labels为次优先级 + if useDefaultPolicy { + injectionRequested, useDefaultPolicy = evaluateSelectors(pod, templateConfig, p.podName) + log.InjectScope().Infof("evaluateSelectors for %s/%s: UseDefault=%v injectionRequested=%v", + pod.Namespace, pod.Name, useDefaultPolicy, injectionRequested) } - annos := metadata.GetAnnotations() - if annos == nil { - annos = map[string]string{} + // Policy为最低优先级 + required := determineInjectionRequirement(templateConfig.Policy, useDefaultPolicy, injectionRequested) + log.InjectScope().Infof("determineInjectionRequirement for %s/%s: Policy=%s UseDefault=%v Requested=%v Required=%v", + pod.Namespace, pod.Name, templateConfig.Policy, useDefaultPolicy, injectionRequested, required) + + return required +} + +func isIgnoredNamespace(namespace string) bool { + for _, ignored := range ignoredNamespaces { + if namespace == ignored { + return true + } } + return false +} - var useDefault bool - var inject bool - switch strings.ToLower(annos[annotation.SidecarInject.Name]) { - // http://yaml.org/type/bool.html +// 解析Annotation, 用于注解位置的黑白名单功能 +func parseInjectionAnnotation(annotations map[string]string) (requested bool, useDefault bool) { + var value string + newFlag, newExists := annotations[utils.PolarisInjectionKey] + if newExists { + value = strings.ToLower(newFlag) + } else { + if flag, ok := annotations[annotation.SidecarInject.Name]; ok { + value = strings.ToLower(flag) + } + } + switch value { case "y", "yes", "true", "on", "enable", "enabled": - inject = true + // annotation白名单, 显示开启 + return true, false case "n", "no", "false", "off", "disable", "disabled": - inject = false - case "": - useDefault = true - } - - // If an annotation is not explicitly given, check the LabelSelectors, starting with NeverInject - if useDefault { - for _, neverSelector := range templateConfig.NeverInjectSelector { - selector, err := metav1.LabelSelectorAsSelector(&neverSelector) - if err != nil { - log.InjectScope().Warnf("Invalid selector for NeverInjectSelector: %v (%v)", neverSelector, err) - } else if !selector.Empty() && selector.Matches(labels.Set(metadata.Labels)) { - log.InjectScope().Infof("Explicitly disabling injection for pod %s/%s due to pod labels "+ - "matching NeverInjectSelector templateConfig map entry.", metadata.Namespace, podName) - inject = false - useDefault = false - break - } - } + // annotation黑名单, 显示关闭 + return false, false + default: // including empty string + return false, true } +} - // If there's no annotation nor a NeverInjectSelector, check the AlwaysInject one - if useDefault { - for _, alwaysSelector := range templateConfig.AlwaysInjectSelector { - selector, err := metav1.LabelSelectorAsSelector(&alwaysSelector) - if err != nil { - log.InjectScope().Warnf("Invalid selector for AlwaysInjectSelector: %v (%v)", alwaysSelector, err) - } else if !selector.Empty() && selector.Matches(labels.Set(metadata.Labels)) { - log.InjectScope().Infof("Explicitly enabling injection for pod %s/%s due to pod labels "+ - " matching AlwaysInjectSelector templateConfig map entry.", metadata.Namespace, podName) - inject = true - useDefault = false - break - } +// 检查label的黑白名单功能 +func evaluateSelectors(pod *corev1.Pod, config *config.TemplateConfig, podName string) (bool, bool) { + // Check NeverInject selectors first + if inject, ok := checkSelectors(pod, config.NeverInjectSelector, "NeverInjectSelector", podName, false); ok { + return inject, false + } + + // Then check AlwaysInject selectors + if inject, ok := checkSelectors(pod, config.AlwaysInjectSelector, "AlwaysInjectSelector", podName, true); ok { + return inject, false + } + + return false, true +} + +func checkSelectors(pod *corev1.Pod, selectors []metav1.LabelSelector, selectorType string, podName string, + allowInject bool) (bool, bool) { + for _, selector := range selectors { + ls, err := metav1.LabelSelectorAsSelector(&selector) + if err != nil { + log.InjectScope().Warnf("Invalid %s: %v (%v)", selectorType, selector, err) + continue // Continue checking other selectors + } + + if !ls.Empty() && ls.Matches(labels.Set(pod.Labels)) { + log.InjectScope().Infof("Pod %s/%s: %s matched labels %v", + pod.Namespace, podName, selectorType, pod.Labels) + return allowInject, true } } + return false, false +} - var required bool - switch templateConfig.Policy { - default: // InjectionPolicyOff - log.InjectScope().Errorf("Illegal value for autoInject:%s, must be one of [%s,%s]. Auto injection disabled!", - templateConfig.Policy, config.InjectionPolicyDisabled, config.InjectionPolicyEnabled) - required = false - case config.InjectionPolicyDisabled: +func determineInjectionRequirement(policy config.InjectionPolicy, useDefault bool, requested bool) bool { + switch policy { + case config.InjectionPolicyEnabled: if useDefault { - required = false - } else { - required = inject + return true } - case config.InjectionPolicyEnabled: + return requested + case config.InjectionPolicyDisabled: if useDefault { - required = true - } else { - required = inject + return false } + return requested + default: + log.InjectScope().Errorf("Invalid injection policy: %s. Valid values: [%s, %s]", + policy, config.InjectionPolicyDisabled, config.InjectionPolicyEnabled) + return false } +} - // Build a log message for the annotations. - annotationStr := "" - for name := range annotationRegistryForMesh { - value, ok := annos[name] +// buildAnnotationLogString 构建注解日志字符串,格式为"key:value key2:value2" +func buildAnnotationLogString(injectMode utils.SidecarMode, annotations map[string]string) string { + registry := getAnnotationRegistry(injectMode) + var buf strings.Builder + for name := range registry { + value, ok := annotations[name] if !ok { value = "(unset)" } - annotationStr += fmt.Sprintf("%s:%s ", name, value) + buf.WriteString(fmt.Sprintf("%s:%s ", name, value)) } + return strings.TrimSpace(buf.String()) +} - log.InjectScope().Infof("Sidecar injection for %v/%v: namespacePolicy:%v useDefault:%v inject:%v required:%v %s", - metadata.Namespace, - podName, - templateConfig.Policy, - useDefault, - inject, - required, - annotationStr) - - return required +func getAnnotationRegistry(injectMode utils.SidecarMode) map[string]annotationValidationFunc { + var registry map[string]annotationValidationFunc + switch injectMode { + case utils.SidecarForMesh: + registry = annotationRegistryForMesh + case utils.SidecarForDns: + registry = annotationRegistryForDns + case utils.SidecarForJavaAgent: + registry = annotationRegistryForJavaAgent + } + return registry } diff --git a/pkg/inject/pkg/kube/inject/inject_test.go b/pkg/inject/pkg/kube/inject/inject_test.go deleted file mode 100644 index 77c51687..00000000 --- a/pkg/inject/pkg/kube/inject/inject_test.go +++ /dev/null @@ -1,113 +0,0 @@ -package inject - -import ( - "testing" - - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - "github.com/polarismesh/polaris-controller/pkg/inject/api/annotation" - "github.com/polarismesh/polaris-controller/pkg/inject/pkg/config" -) - -func TestMeshInjectRequired(t *testing.T) { - // 通用测试配置 - defaultTemplate := &config.TemplateConfig{ - NeverInjectSelector: []metav1.LabelSelector{{MatchLabels: map[string]string{"security": "high"}}}, - AlwaysInjectSelector: []metav1.LabelSelector{{MatchLabels: map[string]string{"env": "prod"}}}, - Policy: config.InjectionPolicyEnabled, - } - - testCases := []struct { - name string - podSetup func(*corev1.Pod) - expected bool - }{ - { - name: "当启用HostNetwork时无需注入", - podSetup: func(p *corev1.Pod) { - p.Spec.HostNetwork = true - }, - expected: false, - }, - { - name: "在kube-system命名空间中跳过注入", - podSetup: func(p *corev1.Pod) { - p.Namespace = "kube-system" - }, - expected: false, - }, - { - name: "当注解明确启用时应该注入", - podSetup: func(p *corev1.Pod) { - p.Annotations = map[string]string{annotation.SidecarInject.Name: "true"} - }, - expected: true, - }, - { - name: "当注解明确禁用时不注入", - podSetup: func(p *corev1.Pod) { - p.Annotations = map[string]string{annotation.SidecarInject.Name: "false"} - }, - expected: false, - }, - { - name: "当匹配NeverInjectSelector时不注入", - podSetup: func(p *corev1.Pod) { - p.Labels = map[string]string{"security": "high"} - }, - expected: false, - }, - { - name: "当匹配AlwaysInjectSelector时强制注入", - podSetup: func(p *corev1.Pod) { - p.Labels = map[string]string{"env": "prod"} - }, - expected: true, - }, - { - name: "默认策略启用时自动注入", - podSetup: func(p *corev1.Pod) { - // 无额外配置 - }, - expected: true, - }, - { - name: "当策略禁用时需要显式启用才注入", - podSetup: func(p *corev1.Pod) { - defaultTemplate.Policy = config.InjectionPolicyDisabled - p.Annotations = map[string]string{annotation.SidecarInject.Name: "true"} - }, - expected: true, - }, - } - - wh := &Webhook{} - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - pod := &corev1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-pod", - Namespace: "default", - Annotations: make(map[string]string), - Labels: make(map[string]string), - }, - Spec: corev1.PodSpec{}, - } - if tc.podSetup != nil { - tc.podSetup(pod) - } - - podInfo := &podDataInfo{ - podObject: pod, - injectTemplateConfig: defaultTemplate, - podName: pod.Name, - } - - result := wh.meshInjectRequired(podInfo) - if result != tc.expected { - t.Errorf("%s: 期望 %v 但得到 %v", tc.name, tc.expected, result) - } - }) - } -} diff --git a/pkg/inject/pkg/kube/inject/pod.go b/pkg/inject/pkg/kube/inject/pod.go index 0f7265b9..30c42a33 100644 --- a/pkg/inject/pkg/kube/inject/pod.go +++ b/pkg/inject/pkg/kube/inject/pod.go @@ -9,6 +9,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/polarismesh/polaris-controller/common/log" + "github.com/polarismesh/polaris-controller/pkg/inject/api/annotation" "github.com/polarismesh/polaris-controller/pkg/inject/pkg/config" utils "github.com/polarismesh/polaris-controller/pkg/util" ) @@ -91,6 +92,10 @@ func (p *podDataInfo) assignInjectMode(wh *Webhook) { // 检查pod的spec和annotations是否符合要求 func (p *podDataInfo) checkPodData() (bool, error) { pod := p.podObject + if err := validateAnnotations(p.injectMode, pod.GetAnnotations()); err != nil { + log.InjectScope().Errorf("[Webhook] injection failed due to invalid annotations: %v", err) + return false, err + } if p.injectMode == utils.SidecarForMesh { // If DNSPolicy is not ClusterFirst, the Envoy sidecar may not able to connect to polaris. if pod.Spec.DNSPolicy != "" && pod.Spec.DNSPolicy != corev1.DNSClusterFirst { @@ -99,10 +104,6 @@ func (p *podDataInfo) checkPodData() (bool, error) { pod.Namespace+"/"+p.podName, corev1.DNSClusterFirst) return false, nil } - if err := validateMeshAnnotations(pod.GetAnnotations()); err != nil { - log.InjectScope().Errorf("[Webhook] injection failed due to invalid annotations: %v", err) - return false, err - } } return true, nil } @@ -152,6 +153,14 @@ func (p *podDataInfo) assignInjectAnnotations() { envoyMetadata[k] = v } injectAnnotations[utils.SidecarEnvoyMetadata] = fmt.Sprintf("%q", toJSON(envoyMetadata)) + } else { + // 注入workload的namespace和name + if _, ok := md.Annotations[utils.SidecarNamespaceName]; !ok { + injectAnnotations[utils.SidecarNamespaceName] = md.Namespace + } + if _, ok := md.Annotations[utils.SidecarServiceName]; !ok { + injectAnnotations[utils.SidecarServiceName] = p.workloadMeta.Name + } } p.injectedAnnotations = injectAnnotations } @@ -167,8 +176,8 @@ type SidecarInjectionStatus struct { ImagePullSecrets []corev1.LocalObjectReference `json:"imagePullSecrets"` } -func (p *podDataInfo) getInjectStatus(version string, sic SidecarInjectionSpec) *SidecarInjectionStatus { - status := &SidecarInjectionStatus{Version: version} +func (p *podDataInfo) addInjectStatusAnnotation(sic SidecarInjectionSpec) string { + status := &SidecarInjectionStatus{Version: p.injectTemplateVersion} for _, c := range sic.InitContainers { status.InitContainers = append(status.InitContainers, corev1.Container{ Name: c.Name, @@ -189,5 +198,10 @@ func (p *podDataInfo) getInjectStatus(version string, sic SidecarInjectionSpec) Name: c.Name, }) } - return status + statusAnnotationValue, _ := json.Marshal(status) + result := string(statusAnnotationValue) + if len(result) != 0 { + p.injectedAnnotations[annotation.SidecarStatus.Name] = result + } + return result } diff --git a/pkg/util/types.go b/pkg/util/types.go index 572169cb..b272a149 100644 --- a/pkg/util/types.go +++ b/pkg/util/types.go @@ -61,10 +61,17 @@ const ( // PolarisInjectionDisabled 关闭注入(黑名单功能)的标记值 PolarisInjectionDisabled = "disabled" + //TODO: add workload flag + // PolarisInjectModeLabelKeyJavaAgent 注入模式为 javaagent 的 pod label PolarisInjectModeLabelKeyJavaAgent = "polarismesh.cn/javaagent" // PolarisInjectModeLabelValueTrue 表示需要进行注入 的 pod label 的值 PolarisInjectModeLabelValueTrue = "true" + // javaagent类型的annotations的key + CustomJavaAgentVersion = "polarismesh.cn/javaagentVersion" + CustomJavaAgentPluginFramework = "polarismesh.cn/javaagentFrameworkName" + CustomJavaAgentPluginFrameworkVersion = "polarismesh.cn/javaagentFrameworkVersion" + CustomJavaAgentPluginConfig = "polarismesh.cn/javaagentConfig" ) const ( From ca3582b37708d3c6dced504bbf5c09d71c8d7d5f Mon Sep 17 00:00:00 2001 From: evelynwei Date: Thu, 20 Feb 2025 19:34:01 +0800 Subject: [PATCH 03/17] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E4=BD=BF?= =?UTF-8?q?=E7=94=A8k8s=E5=91=BD=E5=90=8D=E7=A9=BA=E9=97=B4=E5=92=8C?= =?UTF-8?q?=E5=B7=A5=E4=BD=9C=E8=B4=9F=E8=BD=BD=E6=B3=A8=E5=86=8C=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller-configmap-javaagent.yaml | 6 +- .../controller-configmap-sidecar.yaml | 6 +- .../kubernetes_v1.21/kubernetes/injector.yaml | 6 +- .../kubernetes/javaagent-configmap.yaml | 10 +-- .../controller-configmap-javaagent.yaml | 8 +- .../controller-configmap-sidecar.yaml | 6 +- .../kubernetes_v1.22/kubernetes/injector.yaml | 6 +- .../kubernetes/javaagent-configmap.yaml | 10 +-- .../pkg/kube/inject/apply/javaagent/patch.go | 86 ++++++++++++++----- pkg/inject/pkg/kube/inject/base_test.go | 20 +++-- pkg/inject/pkg/kube/inject/common.go | 6 +- pkg/inject/pkg/kube/inject/inject.go | 23 +++-- pkg/inject/pkg/kube/inject/pod.go | 3 + pkg/util/types.go | 36 ++++---- 14 files changed, 141 insertions(+), 91 deletions(-) diff --git a/deploy/kubernetes_v1.21/helm/templates/controller-configmap-javaagent.yaml b/deploy/kubernetes_v1.21/helm/templates/controller-configmap-javaagent.yaml index 6bf29631..d26dd33f 100644 --- a/deploy/kubernetes_v1.21/helm/templates/controller-configmap-javaagent.yaml +++ b/deploy/kubernetes_v1.21/helm/templates/controller-configmap-javaagent.yaml @@ -16,7 +16,7 @@ data: # 启用 Java Agent 的 Spring Cloud Tencent 注册发现能力 spring.cloud.discovery.enabled=true # 配置服务注册发现的命名空间信息 - spring.cloud.polaris.discovery.namespace=default + spring.cloud.polaris.discovery.namespace={{ .MicroserviceNamespace }} # 启用从北极星 spring.cloud.polaris.discovery.enabled=true spring.cloud.polaris.discovery.register=true @@ -66,7 +66,7 @@ data: # 启用 Java Agent 的 Spring Cloud Tencent 注册发现能力 spring.cloud.discovery.enabled=true # 配置服务注册发现的命名空间信息 - spring.cloud.polaris.discovery.namespace=default + spring.cloud.polaris.discovery.namespace={{ .MicroserviceNamespace }} # 启用从北极星 spring.cloud.polaris.discovery.enabled=true spring.cloud.polaris.discovery.register=true @@ -116,7 +116,7 @@ data: # 启用 Java Agent 的 Spring Cloud Tencent 注册发现能力 spring.cloud.discovery.enabled=true # 配置服务注册发现的命名空间信息 - spring.cloud.polaris.discovery.namespace=default + spring.cloud.polaris.discovery.namespace={{ .MicroserviceNamespace }} # 启用从北极星 spring.cloud.polaris.discovery.enabled=true spring.cloud.polaris.discovery.register=true diff --git a/deploy/kubernetes_v1.21/helm/templates/controller-configmap-sidecar.yaml b/deploy/kubernetes_v1.21/helm/templates/controller-configmap-sidecar.yaml index f49281d5..4718c4a2 100644 --- a/deploy/kubernetes_v1.21/helm/templates/controller-configmap-sidecar.yaml +++ b/deploy/kubernetes_v1.21/helm/templates/controller-configmap-sidecar.yaml @@ -15,7 +15,7 @@ data: [] neverInjectSelector: - [] + [{"matchLabels":{"polarismesh.cn/inject":"disabled"}}] template: | containers: @@ -93,7 +93,7 @@ data: [] neverInjectSelector: - [] + [{"matchLabels":{"polarismesh.cn/inject":"disabled"}}] template: | initContainers: @@ -138,7 +138,7 @@ data: [] neverInjectSelector: - [] + [{"matchLabels":{"polarismesh.cn/inject":"disabled"}}] template: | containers: diff --git a/deploy/kubernetes_v1.21/kubernetes/injector.yaml b/deploy/kubernetes_v1.21/kubernetes/injector.yaml index 79fc1219..c384bdd9 100644 --- a/deploy/kubernetes_v1.21/kubernetes/injector.yaml +++ b/deploy/kubernetes_v1.21/kubernetes/injector.yaml @@ -30,7 +30,7 @@ data: [] neverInjectSelector: - [] + [{"matchLabels":{"polarismesh.cn/inject":"disabled"}}] template: | containers: @@ -113,7 +113,7 @@ data: [] neverInjectSelector: - [] + [{"matchLabels":{"polarismesh.cn/inject":"disabled"}}] template: | initContainers: @@ -156,7 +156,7 @@ data: [] neverInjectSelector: - [] + [{"matchLabels":{"polarismesh.cn/inject":"disabled"}}] template: |+ containers: diff --git a/deploy/kubernetes_v1.21/kubernetes/javaagent-configmap.yaml b/deploy/kubernetes_v1.21/kubernetes/javaagent-configmap.yaml index 8fd0e297..2f1090d2 100644 --- a/deploy/kubernetes_v1.21/kubernetes/javaagent-configmap.yaml +++ b/deploy/kubernetes_v1.21/kubernetes/javaagent-configmap.yaml @@ -16,7 +16,7 @@ data: # 启用 Java Agent 的 Spring Cloud Tencent 注册发现能力 spring.cloud.discovery.enabled=true # 配置服务注册发现的命名空间信息 - spring.cloud.polaris.discovery.namespace=default + spring.cloud.polaris.discovery.namespace={{ .MicroserviceNamespace }} # 启用从北极星 spring.cloud.polaris.discovery.enabled=true spring.cloud.polaris.discovery.register=true @@ -76,7 +76,7 @@ data: # 启用 Java Agent 的 Spring Cloud Tencent 注册发现能力 spring.cloud.discovery.enabled=true # 配置服务注册发现的命名空间信息 - spring.cloud.polaris.discovery.namespace=default + spring.cloud.polaris.discovery.namespace={{ .MicroserviceNamespace }} # 启用从北极星 spring.cloud.polaris.discovery.enabled=true spring.cloud.polaris.discovery.register=true @@ -139,7 +139,7 @@ data: # 启用 Java Agent 的 Spring Cloud Tencent 注册发现能力 spring.cloud.discovery.enabled=true # 配置服务注册发现的命名空间信息 - spring.cloud.polaris.discovery.namespace=default + spring.cloud.polaris.discovery.namespace={{ .MicroserviceNamespace }} # 启用从北极星 spring.cloud.polaris.discovery.enabled=true spring.cloud.polaris.discovery.register=true @@ -189,7 +189,7 @@ data: # 启用 Java Agent 的 Spring Cloud Tencent 注册发现能力 spring.cloud.discovery.enabled=true # 配置服务注册发现的命名空间信息 - spring.cloud.polaris.discovery.namespace=default + spring.cloud.polaris.discovery.namespace={{ .MicroserviceNamespace }} # 启用从北极星 spring.cloud.polaris.discovery.enabled=true spring.cloud.polaris.discovery.register=true @@ -239,7 +239,7 @@ data: # 启用 Java Agent 的 Spring Cloud Tencent 注册发现能力 spring.cloud.discovery.enabled=true # 配置服务注册发现的命名空间信息 - spring.cloud.polaris.discovery.namespace=default + spring.cloud.polaris.discovery.namespace={{ .MicroserviceNamespace }} # 启用从北极星 spring.cloud.polaris.discovery.enabled=true spring.cloud.polaris.discovery.register=true diff --git a/deploy/kubernetes_v1.22/helm/templates/controller-configmap-javaagent.yaml b/deploy/kubernetes_v1.22/helm/templates/controller-configmap-javaagent.yaml index c317063c..5b127929 100644 --- a/deploy/kubernetes_v1.22/helm/templates/controller-configmap-javaagent.yaml +++ b/deploy/kubernetes_v1.22/helm/templates/controller-configmap-javaagent.yaml @@ -16,7 +16,7 @@ data: # 启用 Java Agent 的 Spring Cloud Tencent 注册发现能力 spring.cloud.discovery.enabled=true # 配置服务注册发现的命名空间信息 - spring.cloud.polaris.discovery.namespace=default + spring.cloud.polaris.discovery.namespace={{ .MicroserviceNamespace }} # 启用从北极星 spring.cloud.polaris.discovery.enabled=true spring.cloud.polaris.discovery.register=true @@ -76,7 +76,7 @@ data: # 启用 Java Agent 的 Spring Cloud Tencent 注册发现能力 spring.cloud.discovery.enabled=true # 配置服务注册发现的命名空间信息 - spring.cloud.polaris.discovery.namespace=default + spring.cloud.polaris.discovery.namespace={{ .MicroserviceNamespace }} # 启用从北极星 spring.cloud.polaris.discovery.enabled=true spring.cloud.polaris.discovery.register=true @@ -126,7 +126,7 @@ data: # 启用 Java Agent 的 Spring Cloud Tencent 注册发现能力 spring.cloud.discovery.enabled=true # 配置服务注册发现的命名空间信息 - spring.cloud.polaris.discovery.namespace=default + spring.cloud.polaris.discovery.namespace={{ .MicroserviceNamespace }} # 启用从北极星 spring.cloud.polaris.discovery.enabled=true spring.cloud.polaris.discovery.register=true @@ -176,7 +176,7 @@ data: # 启用 Java Agent 的 Spring Cloud Tencent 注册发现能力 spring.cloud.discovery.enabled=true # 配置服务注册发现的命名空间信息 - spring.cloud.polaris.discovery.namespace=default + spring.cloud.polaris.discovery.namespace={{ .MicroserviceNamespace }} # 启用从北极星 spring.cloud.polaris.discovery.enabled=true spring.cloud.polaris.discovery.register=true diff --git a/deploy/kubernetes_v1.22/helm/templates/controller-configmap-sidecar.yaml b/deploy/kubernetes_v1.22/helm/templates/controller-configmap-sidecar.yaml index f49281d5..4718c4a2 100644 --- a/deploy/kubernetes_v1.22/helm/templates/controller-configmap-sidecar.yaml +++ b/deploy/kubernetes_v1.22/helm/templates/controller-configmap-sidecar.yaml @@ -15,7 +15,7 @@ data: [] neverInjectSelector: - [] + [{"matchLabels":{"polarismesh.cn/inject":"disabled"}}] template: | containers: @@ -93,7 +93,7 @@ data: [] neverInjectSelector: - [] + [{"matchLabels":{"polarismesh.cn/inject":"disabled"}}] template: | initContainers: @@ -138,7 +138,7 @@ data: [] neverInjectSelector: - [] + [{"matchLabels":{"polarismesh.cn/inject":"disabled"}}] template: | containers: diff --git a/deploy/kubernetes_v1.22/kubernetes/injector.yaml b/deploy/kubernetes_v1.22/kubernetes/injector.yaml index 5849f99a..98a25d29 100644 --- a/deploy/kubernetes_v1.22/kubernetes/injector.yaml +++ b/deploy/kubernetes_v1.22/kubernetes/injector.yaml @@ -15,7 +15,7 @@ data: [] neverInjectSelector: - [] + [{"matchLabels":{"polarismesh.cn/inject":"disabled"}}] template: | containers: @@ -98,7 +98,7 @@ data: [] neverInjectSelector: - [] + [{"matchLabels":{"polarismesh.cn/inject":"disabled"}}] template: | initContainers: @@ -142,7 +142,7 @@ data: [] neverInjectSelector: - [] + [{"matchLabels":{"polarismesh.cn/inject":"disabled"}}] template: | containers: diff --git a/deploy/kubernetes_v1.22/kubernetes/javaagent-configmap.yaml b/deploy/kubernetes_v1.22/kubernetes/javaagent-configmap.yaml index 96cbed60..8535131d 100644 --- a/deploy/kubernetes_v1.22/kubernetes/javaagent-configmap.yaml +++ b/deploy/kubernetes_v1.22/kubernetes/javaagent-configmap.yaml @@ -16,7 +16,7 @@ data: # 启用 Java Agent 的 Spring Cloud Tencent 注册发现能力 spring.cloud.discovery.enabled=true # 配置服务注册发现的命名空间信息 - spring.cloud.polaris.discovery.namespace=default + spring.cloud.polaris.discovery.namespace={{ .MicroserviceNamespace }} # 启用从北极星 spring.cloud.polaris.discovery.enabled=true spring.cloud.polaris.discovery.register=true @@ -76,7 +76,7 @@ data: # 启用 Java Agent 的 Spring Cloud Tencent 注册发现能力 spring.cloud.discovery.enabled=true # 配置服务注册发现的命名空间信息 - spring.cloud.polaris.discovery.namespace=default + spring.cloud.polaris.discovery.namespace={{ .MicroserviceNamespace }} # 启用从北极星 spring.cloud.polaris.discovery.enabled=true spring.cloud.polaris.discovery.register=true @@ -139,7 +139,7 @@ data: # 启用 Java Agent 的 Spring Cloud Tencent 注册发现能力 spring.cloud.discovery.enabled=true # 配置服务注册发现的命名空间信息 - spring.cloud.polaris.discovery.namespace=default + spring.cloud.polaris.discovery.namespace={{ .MicroserviceNamespace }} # 启用从北极星 spring.cloud.polaris.discovery.enabled=true spring.cloud.polaris.discovery.register=true @@ -189,7 +189,7 @@ data: # 启用 Java Agent 的 Spring Cloud Tencent 注册发现能力 spring.cloud.discovery.enabled=true # 配置服务注册发现的命名空间信息 - spring.cloud.polaris.discovery.namespace=default + spring.cloud.polaris.discovery.namespace={{ .MicroserviceNamespace }} # 启用从北极星 spring.cloud.polaris.discovery.enabled=true spring.cloud.polaris.discovery.register=true @@ -239,7 +239,7 @@ data: # 启用 Java Agent 的 Spring Cloud Tencent 注册发现能力 spring.cloud.discovery.enabled=true # 配置服务注册发现的命名空间信息 - spring.cloud.polaris.discovery.namespace=default + spring.cloud.polaris.discovery.namespace={{ .MicroserviceNamespace }} # 启用从北极星 spring.cloud.polaris.discovery.enabled=true spring.cloud.polaris.discovery.register=true diff --git a/pkg/inject/pkg/kube/inject/apply/javaagent/patch.go b/pkg/inject/pkg/kube/inject/apply/javaagent/patch.go index d2a6b549..9ea3e50e 100644 --- a/pkg/inject/pkg/kube/inject/apply/javaagent/patch.go +++ b/pkg/inject/pkg/kube/inject/apply/javaagent/patch.go @@ -89,7 +89,7 @@ func (pb *PodPatchBuilder) PatchContainer(req *inject.OperateContainerRequest) ( log.InjectScope().Infof("finish deal polaris-javaagent-init inject for pod=[%s, %s] added: %#v", pod.Namespace, pod.Name, added) return pb.PodPatchBuilder.PatchContainer(req) case inject.PatchType_Update: - return pb.updateContainer(req.Option, req.Option.SidecarMode, req.Option.Pod, req.Option.Pod.Spec.Containers, req.BasePath), nil + return pb.updateContainer(req.Option, req.Option.Pod, req.Option.Pod.Spec.Containers, req.BasePath), nil } return nil, nil } @@ -101,20 +101,20 @@ func (pb *PodPatchBuilder) handleJavaAgentInit(opt *inject.PatchOptions, pod *co // 判断用户是否自定义了 javaagent 的版本 oldImageInfo := strings.Split(add.Image, ":") if len(oldImageInfo) > 1 { - opt.ExternalInfo[utils.CustomJavaAgentVersion] = oldImageInfo[1] + opt.ExternalInfo[utils.AnnotationKeyJavaAgentVersion] = oldImageInfo[1] } - if val, ok := annonations[utils.CustomJavaAgentVersion]; ok && val != "" { + if val, ok := annonations[utils.AnnotationKeyJavaAgentVersion]; ok && val != "" { add.Image = fmt.Sprintf("%s:%s", oldImageInfo[0], val) - opt.ExternalInfo[utils.CustomJavaAgentVersion] = val + opt.ExternalInfo[utils.AnnotationKeyJavaAgentVersion] = val } - frameworkName, frameworkNameOk := annonations[utils.CustomJavaAgentPluginFramework] + frameworkName, frameworkNameOk := annonations[utils.AnnotationKeyJavaAgentPluginFramework] if !frameworkNameOk { log.InjectScope().Warnf("handle polaris-javaagent-init inject for pod=[%s, %s] not found frameworkName", pod.Namespace, pod.Name) } - frameworkVersion, frameworkVersionOk := annonations[utils.CustomJavaAgentPluginFrameworkVersion] + frameworkVersion, frameworkVersionOk := annonations[utils.AnnotationKeyJavaAgentPluginFrameworkVersion] if !frameworkVersionOk { log.InjectScope().Warnf("handle polaris-javaagent-init inject for pod=[%s, %s] not found frameworkVersion", pod.Namespace, pod.Name) @@ -136,9 +136,10 @@ func (pb *PodPatchBuilder) handleJavaAgentInit(opt *inject.PatchOptions, pod *co }) } + svcNs, svcName := getServiceNamespaceAndName(opt) defaultParam := map[string]string{ - "MicroserviceNamespace": opt.Annotations[util.SidecarNamespaceName], - "MicroserviceName": opt.Annotations[util.SidecarServiceName], + "MicroserviceNamespace": svcNs, + "MicroserviceName": svcName, "PolarisServerIP": strings.Split(polarisapi.PolarisGrpc, ":")[0], "PolarisDiscoverPort": strings.Split(polarisapi.PolarisGrpc, ":")[1], "PolarisConfigIP": strings.Split(polarisapi.PolarisConfigGrpc, ":")[0], @@ -170,6 +171,7 @@ func (pb *PodPatchBuilder) handleJavaAgentInit(opt *inject.PatchOptions, pod *co defaultProperties := make(map[string]string) // 判断是不是老版本,如果是老版本且客户填写的版本号不为空则走老的逻辑,否则走新的逻辑,只下发北极星的地址和端口信息 newImageInfo := strings.Split(add.Image, ":") + // RC5之前的版本走的逻辑, 向前兼容 if _, valid := oldAgentVersions[newImageInfo[1]]; valid { kubeClient := opt.KubeClient pluginCm, err := kubeClient.CoreV1().ConfigMaps(util.RootNamespace).Get(context.Background(), @@ -197,15 +199,23 @@ func (pb *PodPatchBuilder) handleJavaAgentInit(opt *inject.PatchOptions, pod *co } } } - // 查看用户是否自定义了相关配置信息 + // 查看用户是否自定义了相关配置信息, 优先级最高 // 需要根据用户的自定义参数信息,将 agent 的特定 application.properties 文件注入到 javaagent-init 中 - if properties, ok := annonations[utils.CustomJavaAgentPluginConfig]; ok { + if properties, ok := annonations[utils.AnnotationKeyJavaAgentPluginConfig]; ok { customProperties := map[string]string{} if err := json.Unmarshal([]byte(properties), &customProperties); err != nil { return err } // 先从 configmap 中获取 java-agent 不同 plugin-type 的默认配置信息 for k, v := range customProperties { + if defaultValue, defaultExist := defaultProperties[k]; defaultExist { + if defaultValue != v { + log.InjectScope().Infof("handle polaris-javaagent-init inject for pod=[%s, %s] "+ + "customProperties[%s]=%s should replace defaultProperties[%s]=%s", + pod.Namespace, pod.Name, k, v, k, defaultValue) + } + } + // 当和默认初始化配置存在冲突时,使用用户自定义配置 defaultProperties[k] = v } } @@ -223,6 +233,24 @@ func (pb *PodPatchBuilder) handleJavaAgentInit(opt *inject.PatchOptions, pod *co return nil } +func getServiceNamespaceAndName(opt *inject.PatchOptions) (string, string) { + serviceNs := "default" + serviceName := opt.Annotations[util.SidecarServiceName] + if useWorkloadNS, ok := opt.Annotations[utils.AnnotationKeyWorkloadNamespaceAsServiceNamespace]; ok && + useWorkloadNS == utils.InjectionValueTrue { + log.InjectScope().Infof("handle polaris-javaagent-init inject for pod=[%s, %s] useWorkloadNS=%s", + opt.Pod.Namespace, opt.Pod.Name, useWorkloadNS) + serviceNs = opt.Pod.Namespace + } + if useWorkloadName, ok := opt.Annotations[utils.AnnotationKeyWorkloadNameAsServiceName]; ok && + useWorkloadName == utils.InjectionValueTrue { + log.InjectScope().Infof("handle polaris-javaagent-init inject for pod=[%s, %s] useWorkloadName=%s", + opt.Pod.Namespace, opt.Pod.Name, useWorkloadName) + serviceName = opt.WorkloadName + } + return serviceNs, serviceName +} + func nameOfPluginDefault(v string) string { return v + "-default-properties" } @@ -234,26 +262,32 @@ func updateJavaEnvVar(envVar corev1.EnvVar, cmd string, version string) corev1.E } } -func (pb *PodPatchBuilder) updateContainer(opt *inject.PatchOptions, sidecarMode utils.SidecarMode, pod *corev1.Pod, - target []corev1.Container, basePath string) []inject.Rfc6902PatchOperation { +const ( + ServiceNameValueFromKey = "spring.application.name" + ServiceNamespaceValueFromKey = "spring.cloud.polaris.discovery.namespace" +) + +func (pb *PodPatchBuilder) updateContainer(opt *inject.PatchOptions, pod *corev1.Pod, target []corev1.Container, + basePath string) []inject.Rfc6902PatchOperation { patchs := make([]inject.Rfc6902PatchOperation, 0, len(target)) annonations := pod.Annotations - if val, ok := annonations[utils.CustomJavaAgentVersion]; ok && val != "" { - opt.ExternalInfo[utils.CustomJavaAgentVersion] = val + if val, ok := annonations[utils.AnnotationKeyJavaAgentVersion]; ok && val != "" { + opt.ExternalInfo[utils.AnnotationKeyJavaAgentVersion] = val } else { - annonations[utils.CustomJavaAgentVersion] = "latest" + annonations[utils.AnnotationKeyJavaAgentVersion] = "latest" } defaultProperties := make(map[string]string) + defaultProperties[ServiceNameValueFromKey], defaultProperties[ServiceNamespaceValueFromKey] = getServiceNamespaceAndName(opt) var javaToolOptionsValue string for index, container := range target { envs := container.Env javaEnvIndex := -1 - if _, valid := oldAgentVersions[annonations[utils.CustomJavaAgentVersion]]; !valid { - if properties, ok := annonations[utils.CustomJavaAgentPluginConfig]; ok { + if _, valid := oldAgentVersions[annonations[utils.AnnotationKeyJavaAgentVersion]]; !valid { + if properties, ok := annonations[utils.AnnotationKeyJavaAgentPluginConfig]; ok { customProperties := map[string]string{} if properties != "" { if err := json.Unmarshal([]byte(properties), &customProperties); err != nil { @@ -263,6 +297,13 @@ func (pb *PodPatchBuilder) updateContainer(opt *inject.PatchOptions, sidecarMode } // 先从 configmap 中获取 java-agent 不同 plugin-type 的默认配置信息 for k, v := range customProperties { + if existsValue, exists := defaultProperties[k]; exists { + if existsValue != v { + log.InjectScope().Errorf("updateContainer for pod=[%s, %s] customProperties[%s]=%s, "+ + "replace defaultProperties[%s]=%s", pod.Namespace, pod.Name, k, v, k, existsValue) + } + } + // 当和默认初始化配置存在冲突时,使用用户自定义配置 defaultProperties[k] = v } } @@ -279,23 +320,26 @@ func (pb *PodPatchBuilder) updateContainer(opt *inject.PatchOptions, sidecarMode break } } + // 环境变量 JAVA_TOOL_OPTIONS 已经存在, 往里面追加参数 if javaEnvIndex != -1 { - if _, valid := oldAgentVersions[annonations[utils.CustomJavaAgentVersion]]; !valid { + // RC5版本之后,不再需要javaagentVersion注解,并使用JAVA_TOOL_OPTIONS的参数传递自定义配置 + if _, valid := oldAgentVersions[annonations[utils.AnnotationKeyJavaAgentVersion]]; !valid { envs[javaEnvIndex] = updateJavaEnvVar(envs[javaEnvIndex], ActiveJavaAgentCmd, javaToolOptionsValue) } else { envs[javaEnvIndex] = updateJavaEnvVar(envs[javaEnvIndex], fmt.Sprintf(OldActiveJavaAgentCmd, - opt.ExternalInfo[utils.CustomJavaAgentVersion]), "") + opt.ExternalInfo[utils.AnnotationKeyJavaAgentVersion]), "") } } } + // 环境变量 JAVA_TOOL_OPTIONS 不存在, 新建 if javaEnvIndex == -1 { // 注入 java agent 需要用到的参数信息 var newEnvVar corev1.EnvVar - if _, valid := oldAgentVersions[annonations[utils.CustomJavaAgentVersion]]; !valid { + if _, valid := oldAgentVersions[annonations[utils.AnnotationKeyJavaAgentVersion]]; !valid { newEnvVar = updateJavaEnvVar(corev1.EnvVar{}, ActiveJavaAgentCmd, javaToolOptionsValue) } else { newEnvVar = updateJavaEnvVar(corev1.EnvVar{}, fmt.Sprintf(OldActiveJavaAgentCmd, - opt.ExternalInfo[utils.CustomJavaAgentVersion]), "") + opt.ExternalInfo[utils.AnnotationKeyJavaAgentVersion]), "") } container.Env = append(container.Env, newEnvVar) } diff --git a/pkg/inject/pkg/kube/inject/base_test.go b/pkg/inject/pkg/kube/inject/base_test.go index 53dd09a7..a9bf1695 100644 --- a/pkg/inject/pkg/kube/inject/base_test.go +++ b/pkg/inject/pkg/kube/inject/base_test.go @@ -1,6 +1,8 @@ package inject import ( + "encoding/json" + "log" "testing" corev1 "k8s.io/api/core/v1" @@ -15,11 +17,13 @@ func TestRequireInject(t *testing.T) { // 通用测试配置 defaultTemplate := &config.TemplateConfig{ NeverInjectSelector: []metav1.LabelSelector{{MatchLabels: map[string]string{ - utils.PolarisInjectionKey: utils.PolarisInjectionDisabled}}}, + utils.InjectAdmissionKey: utils.InjectAdmissionValueDisabled}}}, AlwaysInjectSelector: []metav1.LabelSelector{{MatchLabels: map[string]string{ - utils.PolarisInjectionKey: utils.PolarisInjectionEnabled}}}, + utils.InjectAdmissionKey: utils.InjectAdmissionValueEnabled}}}, Policy: config.InjectionPolicyEnabled, } + str, _ := json.Marshal(defaultTemplate.NeverInjectSelector) + log.Printf("defaultTemplate.NeverInjectSelector: %s", str) // 参考istio官方定义 // https://istio.io/latest/zh/docs/ops/common-problems/injection/ @@ -77,14 +81,14 @@ func TestRequireInject(t *testing.T) { { name: "Label黑名单,当匹配NeverInjectSelector时不注入", podSetup: func(p *corev1.Pod, _ *config.TemplateConfig) { - p.Labels = map[string]string{utils.PolarisInjectionKey: utils.PolarisInjectionDisabled} + p.Labels = map[string]string{utils.InjectAdmissionKey: utils.InjectAdmissionValueDisabled} }, expected: false, }, { name: "Label白名单功能,当匹配AlwaysInjectSelector时注入", podSetup: func(p *corev1.Pod, _ *config.TemplateConfig) { - p.Labels = map[string]string{utils.PolarisInjectionKey: utils.PolarisInjectionEnabled} + p.Labels = map[string]string{utils.InjectAdmissionKey: utils.InjectAdmissionValueEnabled} }, expected: true, }, @@ -106,7 +110,7 @@ func TestRequireInject(t *testing.T) { name: "Annotation白名单,Label黑名单,注入", podSetup: func(p *corev1.Pod, _ *config.TemplateConfig) { p.Annotations = map[string]string{annotation.SidecarInject.Name: "true"} - p.Labels = map[string]string{utils.PolarisInjectionKey: utils.PolarisInjectionDisabled} + p.Labels = map[string]string{utils.InjectAdmissionKey: utils.InjectAdmissionValueDisabled} }, expected: true, }, @@ -122,7 +126,7 @@ func TestRequireInject(t *testing.T) { name: "Annotation黑名单,Label白名单,不注入", podSetup: func(p *corev1.Pod, _ *config.TemplateConfig) { p.Annotations = map[string]string{annotation.SidecarInject.Name: "false"} - p.Labels = map[string]string{utils.PolarisInjectionKey: utils.PolarisInjectionEnabled} + p.Labels = map[string]string{utils.InjectAdmissionKey: utils.InjectAdmissionValueEnabled} }, expected: false, }, @@ -137,7 +141,7 @@ func TestRequireInject(t *testing.T) { { name: "Label白名单功能,Policy黑名单,注入", podSetup: func(p *corev1.Pod, defaultTemplate *config.TemplateConfig) { - p.Labels = map[string]string{utils.PolarisInjectionKey: utils.PolarisInjectionEnabled} + p.Labels = map[string]string{utils.InjectAdmissionKey: utils.InjectAdmissionValueEnabled} defaultTemplate.Policy = config.InjectionPolicyDisabled }, expected: true, @@ -145,7 +149,7 @@ func TestRequireInject(t *testing.T) { { name: "Label黑名单,Policy白名单,不注入", podSetup: func(p *corev1.Pod, defaultTemplate *config.TemplateConfig) { - p.Labels = map[string]string{utils.PolarisInjectionKey: utils.PolarisInjectionDisabled} + p.Labels = map[string]string{utils.InjectAdmissionKey: utils.InjectAdmissionValueDisabled} defaultTemplate.Policy = config.InjectionPolicyEnabled }, expected: false, diff --git a/pkg/inject/pkg/kube/inject/common.go b/pkg/inject/pkg/kube/inject/common.go index 2b3a1112..69d15df6 100644 --- a/pkg/inject/pkg/kube/inject/common.go +++ b/pkg/inject/pkg/kube/inject/common.go @@ -41,14 +41,14 @@ func getInjectMode(wh *Webhook, p *podDataInfo) utils.SidecarMode { // isJavaAgentMode checks if the pod should use Java agent injection mode func isJavaAgentMode(annotations map[string]string) bool { - val, ok := annotations[utils.PolarisInjectModeLabelKeyJavaAgent] - return ok && val == utils.PolarisInjectModeLabelValueTrue + val, ok := annotations[utils.AnnotationKeyInjectJavaAgent] + return ok && val == utils.InjectionValueTrue } // isMeshMode checks if the pod should use Mesh injection mode func isMeshMode(annotations map[string]string) bool { val, ok := annotations[utils.SidecarEnvoyInjectKey] - return ok && val == utils.PolarisInjectModeLabelValueTrue + return ok && val == utils.InjectionValueTrue } // hasSidecarModeAnnotation checks if the pod has custom sidecar mode annotation diff --git a/pkg/inject/pkg/kube/inject/inject.go b/pkg/inject/pkg/kube/inject/inject.go index 79c0288e..abe26bbd 100644 --- a/pkg/inject/pkg/kube/inject/inject.go +++ b/pkg/inject/pkg/kube/inject/inject.go @@ -60,23 +60,23 @@ var ( annotation.SidecarTrafficIncludeInboundPorts.Name: ValidateIncludeInboundPorts, annotation.SidecarTrafficExcludeInboundPorts.Name: ValidateExcludeInboundPorts, annotation.SidecarTrafficExcludeOutboundPorts.Name: ValidateExcludeOutboundPorts, - utils.PolarisInjectionKey: alwaysValidFunc, + utils.InjectAdmissionKey: alwaysValidFunc, } annotationRegistryForDns = map[string]annotationValidationFunc{ annotation.SidecarInject.Name: alwaysValidFunc, annotation.SidecarStatus.Name: alwaysValidFunc, - utils.PolarisInjectionKey: alwaysValidFunc, + utils.InjectAdmissionKey: alwaysValidFunc, } annotationRegistryForJavaAgent = map[string]annotationValidationFunc{ - utils.CustomJavaAgentVersion: alwaysValidFunc, - utils.CustomJavaAgentPluginFramework: alwaysValidFunc, - utils.CustomJavaAgentPluginFrameworkVersion: alwaysValidFunc, - utils.CustomJavaAgentPluginConfig: alwaysValidFunc, - annotation.SidecarInject.Name: alwaysValidFunc, - annotation.SidecarStatus.Name: alwaysValidFunc, - utils.PolarisInjectionKey: alwaysValidFunc, + utils.AnnotationKeyJavaAgentVersion: alwaysValidFunc, + utils.AnnotationKeyJavaAgentPluginFramework: alwaysValidFunc, + utils.AnnotationKeyJavaAgentPluginFrameworkVersion: alwaysValidFunc, + utils.AnnotationKeyJavaAgentPluginConfig: alwaysValidFunc, + annotation.SidecarInject.Name: alwaysValidFunc, + annotation.SidecarStatus.Name: alwaysValidFunc, + utils.InjectAdmissionKey: alwaysValidFunc, } ) @@ -170,7 +170,7 @@ func isIgnoredNamespace(namespace string) bool { // 解析Annotation, 用于注解位置的黑白名单功能 func parseInjectionAnnotation(annotations map[string]string) (requested bool, useDefault bool) { var value string - newFlag, newExists := annotations[utils.PolarisInjectionKey] + newFlag, newExists := annotations[utils.InjectAdmissionKey] if newExists { value = strings.ToLower(newFlag) } else { @@ -215,8 +215,7 @@ func checkSelectors(pod *corev1.Pod, selectors []metav1.LabelSelector, selectorT } if !ls.Empty() && ls.Matches(labels.Set(pod.Labels)) { - log.InjectScope().Infof("Pod %s/%s: %s matched labels %v", - pod.Namespace, podName, selectorType, pod.Labels) + log.InjectScope().Infof("Pod %s/%s: %s matched labels %v", pod.Namespace, podName, selectorType, pod.Labels) return allowInject, true } } diff --git a/pkg/inject/pkg/kube/inject/pod.go b/pkg/inject/pkg/kube/inject/pod.go index 30c42a33..bba98ed9 100644 --- a/pkg/inject/pkg/kube/inject/pod.go +++ b/pkg/inject/pkg/kube/inject/pod.go @@ -144,6 +144,9 @@ func (p *podDataInfo) assignInjectAnnotations() { if val, ok := md.Labels["app"]; ok { injectAnnotations[utils.SidecarServiceName] = val envoyMetadata[utils.SidecarServiceName] = val + } else { + injectAnnotations[utils.SidecarServiceName] = p.workloadMeta.Name + envoyMetadata[utils.SidecarServiceName] = p.workloadMeta.Name } } else { envoyMetadata[utils.SidecarServiceName] = svcName diff --git a/pkg/util/types.go b/pkg/util/types.go index b272a149..a385d8ff 100644 --- a/pkg/util/types.go +++ b/pkg/util/types.go @@ -54,24 +54,24 @@ const ( PolarisSidecarModeLabel = "polaris-sidecar-mode" - // PolarisInjectionKey 标记是否开启注入 - PolarisInjectionKey = "polarismesh.cn/inject" - // PolarisInjectionEnabled 开启注入(白名单功能)的标记值 - PolarisInjectionEnabled = "enabled" - // PolarisInjectionDisabled 关闭注入(黑名单功能)的标记值 - PolarisInjectionDisabled = "disabled" - - //TODO: add workload flag - - // PolarisInjectModeLabelKeyJavaAgent 注入模式为 javaagent 的 pod label - PolarisInjectModeLabelKeyJavaAgent = "polarismesh.cn/javaagent" - // PolarisInjectModeLabelValueTrue 表示需要进行注入 的 pod label 的值 - PolarisInjectModeLabelValueTrue = "true" - // javaagent类型的annotations的key - CustomJavaAgentVersion = "polarismesh.cn/javaagentVersion" - CustomJavaAgentPluginFramework = "polarismesh.cn/javaagentFrameworkName" - CustomJavaAgentPluginFrameworkVersion = "polarismesh.cn/javaagentFrameworkVersion" - CustomJavaAgentPluginConfig = "polarismesh.cn/javaagentConfig" + // InjectAdmissionKey 标记是否开启注入 + InjectAdmissionKey = "polarismesh.cn/inject" + // InjectAdmissionValueEnabled 开启注入(白名单功能)的标记值 + InjectAdmissionValueEnabled = "enabled" + // InjectAdmissionValueDisabled 关闭注入(黑名单功能)的标记值 + InjectAdmissionValueDisabled = "disabled" + // InjectionValueTrue 多处使用的标记值 + InjectionValueTrue = "true" + + AnnotationKeyWorkloadNamespaceAsServiceNamespace = "polarismesh.cn/workloadNamespaceAsServiceNamespace" + AnnotationKeyWorkloadNameAsServiceName = "polarismesh.cn/workloadNameAsServiceName" + + // AnnotationKeyInjectJavaAgent 注入模式为 javaagent 的标记 + AnnotationKeyInjectJavaAgent = "polarismesh.cn/javaagent" + AnnotationKeyJavaAgentVersion = "polarismesh.cn/javaagentVersion" + AnnotationKeyJavaAgentPluginFramework = "polarismesh.cn/javaagentFrameworkName" + AnnotationKeyJavaAgentPluginFrameworkVersion = "polarismesh.cn/javaagentFrameworkVersion" + AnnotationKeyJavaAgentPluginConfig = "polarismesh.cn/javaagentConfig" ) const ( From 49e7533c1aeef9e1d991dd7d529886980c2b2567 Mon Sep 17 00:00:00 2001 From: evelynwei Date: Thu, 20 Feb 2025 20:30:42 +0800 Subject: [PATCH 04/17] =?UTF-8?q?feat:=20InjectedAnnotations=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E6=B3=A8=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/inject/pkg/kube/inject/base_test.go | 7 ++++--- pkg/inject/pkg/kube/inject/pod.go | 4 ++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/pkg/inject/pkg/kube/inject/base_test.go b/pkg/inject/pkg/kube/inject/base_test.go index a9bf1695..c0ba313b 100644 --- a/pkg/inject/pkg/kube/inject/base_test.go +++ b/pkg/inject/pkg/kube/inject/base_test.go @@ -20,10 +20,11 @@ func TestRequireInject(t *testing.T) { utils.InjectAdmissionKey: utils.InjectAdmissionValueDisabled}}}, AlwaysInjectSelector: []metav1.LabelSelector{{MatchLabels: map[string]string{ utils.InjectAdmissionKey: utils.InjectAdmissionValueEnabled}}}, - Policy: config.InjectionPolicyEnabled, + InjectedAnnotations: map[string]string{utils.AnnotationKeyWorkloadNamespaceAsServiceNamespace: utils.InjectionValueTrue}, + Policy: config.InjectionPolicyEnabled, } - str, _ := json.Marshal(defaultTemplate.NeverInjectSelector) - log.Printf("defaultTemplate.NeverInjectSelector: %s", str) + str, _ := json.Marshal(defaultTemplate) + log.Printf("defaultTemplate: %s", str) // 参考istio官方定义 // https://istio.io/latest/zh/docs/ops/common-problems/injection/ diff --git a/pkg/inject/pkg/kube/inject/pod.go b/pkg/inject/pkg/kube/inject/pod.go index bba98ed9..a3181f82 100644 --- a/pkg/inject/pkg/kube/inject/pod.go +++ b/pkg/inject/pkg/kube/inject/pod.go @@ -112,6 +112,10 @@ func (p *podDataInfo) checkPodData() (bool, error) { func (p *podDataInfo) assignInjectAnnotations() { md := p.podObject.ObjectMeta injectAnnotations := map[string]string{} + // Add all additional injected annotations + for k, v := range p.injectTemplateConfig.InjectedAnnotations { + injectAnnotations[k] = v + } if p.injectMode == utils.SidecarForMesh { // 设置需要注入到 envoy 的 md // 强制开启 XDS On-Demand 能力 From 409670cd853667384f6f119d2fe402da3921f78f Mon Sep 17 00:00:00 2001 From: evelynwei Date: Thu, 20 Feb 2025 21:20:29 +0800 Subject: [PATCH 05/17] =?UTF-8?q?fix:=20howeyc/fsnotify=E5=BA=93=E5=B7=B2?= =?UTF-8?q?=E7=BB=8F=E5=BA=9F=E5=BC=83,=E6=9B=B4=E6=96=B0=E5=88=B0?= =?UTF-8?q?=E6=9C=80=E6=96=B0=E7=9A=84fsnotify/fsnotify=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/inject/pkg/config/template_file.go | 4 ++++ pkg/inject/pkg/kube/inject/webhook.go | 10 +++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/pkg/inject/pkg/config/template_file.go b/pkg/inject/pkg/config/template_file.go index d25326a2..055fd2e3 100644 --- a/pkg/inject/pkg/config/template_file.go +++ b/pkg/inject/pkg/config/template_file.go @@ -52,6 +52,7 @@ func loadConfig(p TemplateFileConfig) (*InjectConfigInfo, error) { log.InjectScope().Infof("[MESH] Policy: %v", meshConf.Policy) log.InjectScope().Infof("[MESH] AlwaysInjectSelector: %v", meshConf.AlwaysInjectSelector) log.InjectScope().Infof("[MESH] NeverInjectSelector: %v", meshConf.NeverInjectSelector) + log.InjectScope().Infof("[MESH] InjectedAnnotations: %v", meshConf.InjectedAnnotations) log.InjectScope().Infof("[MESH] Template: |\n %v", strings.Replace(meshConf.Template, "\n", "\n ", -1)) // 读取 dns 模式的配置模板 @@ -68,6 +69,7 @@ func loadConfig(p TemplateFileConfig) (*InjectConfigInfo, error) { log.InjectScope().Infof("[DNS] Policy: %v", dnsConf.Policy) log.InjectScope().Infof("[DNS] AlwaysInjectSelector: %v", dnsConf.AlwaysInjectSelector) log.InjectScope().Infof("[DNS] NeverInjectSelector: %v", dnsConf.NeverInjectSelector) + log.InjectScope().Infof("[DNS] InjectedAnnotations: %v", dnsConf.InjectedAnnotations) log.InjectScope().Infof("[DNS] Template: |\n %v", strings.Replace(dnsConf.Template, "\n", "\n ", -1)) // 读取 javaagent 模式的配置模板 @@ -81,8 +83,10 @@ func loadConfig(p TemplateFileConfig) (*InjectConfigInfo, error) { return nil, err } log.InjectScope().Infof("[JavaAgent] New inject configuration: sha256sum %x", sha256.Sum256(javaAgentData)) + log.InjectScope().Infof("[JavaAgent] Policy: %v", javaAgentConf.Policy) log.InjectScope().Infof("[JavaAgent] AlwaysInjectSelector: %v", javaAgentConf.AlwaysInjectSelector) log.InjectScope().Infof("[JavaAgent] NeverInjectSelector: %v", javaAgentConf.NeverInjectSelector) + log.InjectScope().Infof("[JavaAgent] InjectedAnnotations: %v", javaAgentConf.InjectedAnnotations) log.InjectScope().Infof("[JavaAgent] Template: |\n %v", strings.Replace(javaAgentConf.Template, "\n", "\n ", -1)) // 读取 values diff --git a/pkg/inject/pkg/kube/inject/webhook.go b/pkg/inject/pkg/kube/inject/webhook.go index 49e6cafb..efd49890 100644 --- a/pkg/inject/pkg/kube/inject/webhook.go +++ b/pkg/inject/pkg/kube/inject/webhook.go @@ -29,7 +29,7 @@ import ( "text/template" "time" - "github.com/howeyc/fsnotify" + "github.com/fsnotify/fsnotify" v1 "k8s.io/api/admission/v1" "k8s.io/api/admission/v1beta1" corev1 "k8s.io/api/core/v1" @@ -116,7 +116,7 @@ func NewWebhook(p WebhookParameters) (*Webhook, error) { // symlink updates of k8s ConfigMaps volumes. for _, file := range p.TemplateFileConfig.GetWatchList() { watchDir, _ := filepath.Split(file) - if err := watcher.Watch(watchDir); err != nil { + if err := watcher.Add(watchDir); err != nil { return nil, fmt.Errorf("could not watch %v: %v", file, err) } } @@ -177,13 +177,13 @@ func (wh *Webhook) Run(stop <-chan struct{}) { if err := wh.templateConfig.UpdateTemplateConfig(wh.templateFileConfig); err != nil { log.InjectScope().Errorf("UpdateTemplateConfig failed: %v", err) } - case event := <-wh.watcher.Event: + case event := <-wh.watcher.Events: log.InjectScope().Infof("Injector watch update: %+v", event) // use a timer to debounce configuration updates - if (event.IsModify() || event.IsCreate()) && timerC == nil { + if (event.Op&fsnotify.Write != 0 || event.Op&fsnotify.Create != 0) && timerC == nil { timerC = time.After(watchDebounceDelay) } - case err := <-wh.watcher.Error: + case err := <-wh.watcher.Errors: log.InjectScope().Errorf("Watcher error: %v", err) case <-healthC: content := []byte(`ok`) From 109e0fcb59862761b24f617b8e42d6b93654cb60 Mon Sep 17 00:00:00 2001 From: evelynwei Date: Fri, 21 Feb 2025 15:06:52 +0800 Subject: [PATCH 06/17] build: fix build failed --- Makefile | 2 +- build.sh | 6 +++++- go.mod | 16 ++++++---------- go.sum | 26 ++++++++++++-------------- pkg/inject/pkg/kube/inject/common.go | 1 - version | 2 +- 6 files changed, 25 insertions(+), 28 deletions(-) diff --git a/Makefile b/Makefile index 630a6ce4..848c0aea 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ ORG = polarismesh REPO = polaris-controller SIDECAR_INIT_REPO = polaris-sidecar-init ENVOY_SIDECAR_INIT_REPO = polaris-envoy-bootstrap-generator -IMAGE_TAG = v1.7.2 +IMAGE_TAG = v1.7.3 PLATFORMS = linux/amd64,linux/arm64 .PHONY: all diff --git a/build.sh b/build.sh index 66ab122e..e09ce1ba 100644 --- a/build.sh +++ b/build.sh @@ -26,7 +26,11 @@ else fi workdir=$(dirname $(realpath $0)) -sed -i "s/##VERSION##/$version/g" "$workdir"/deploy/variables.txt +if [ "$(uname)" == "Darwin" ]; then + sed -i "" "s/##VERSION##/$version/g" "$workdir"/deploy/variables.txt +else + sed -i "s/##VERSION##/$version/g" "$workdir"/deploy/variables.txt +fi cat "$workdir"/deploy/variables.txt function replaceVar() { diff --git a/go.mod b/go.mod index 6072bf27..2c5d6b2f 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,6 @@ require ( github.com/google/uuid v1.4.0 github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 - github.com/howeyc/fsnotify v0.9.0 github.com/natefinch/lumberjack v2.0.0+incompatible github.com/openshift/api v3.9.1-0.20191008181517-e4fd21196097+incompatible github.com/polarismesh/polaris-go v1.6.0-beta.2 @@ -19,8 +18,8 @@ require ( go.uber.org/atomic v1.11.0 go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.24.0 - golang.org/x/net v0.23.0 // indirect - golang.org/x/sys v0.18.0 // indirect + golang.org/x/net v0.33.0 // indirect + golang.org/x/sys v0.28.0 // indirect google.golang.org/grpc v1.59.0 gopkg.in/yaml.v2 v2.4.0 k8s.io/api v0.27.3 @@ -32,12 +31,9 @@ require ( require ( github.com/polarismesh/specification v1.4.2-alpha.6 - github.com/stretchr/testify v1.8.2 google.golang.org/protobuf v1.33.0 ) -require github.com/pmezard/go-difflib v1.0.0 // indirect - require ( github.com/NYTimes/gziphandler v1.1.1 // indirect github.com/beorn7/perks v1.0.1 // indirect @@ -48,7 +44,7 @@ require ( github.com/dlclark/regexp2 v1.10.0 // indirect github.com/emicklei/go-restful/v3 v3.9.0 // indirect github.com/felixge/httpsnoop v1.0.3 // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/fsnotify/fsnotify v1.6.0 github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect @@ -85,9 +81,9 @@ require ( go.opentelemetry.io/proto/otlp v0.19.0 // indirect go.uber.org/automaxprocs v1.5.3 golang.org/x/oauth2 v0.12.0 // indirect - golang.org/x/sync v0.3.0 // indirect - golang.org/x/term v0.18.0 // indirect - golang.org/x/text v0.14.0 // indirect + golang.org/x/sync v0.10.0 // indirect + golang.org/x/term v0.27.0 // indirect + golang.org/x/text v0.21.0 // indirect golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 // indirect diff --git a/go.sum b/go.sum index 5ffaf047..87d27f69 100644 --- a/go.sum +++ b/go.sum @@ -381,8 +381,6 @@ github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+l github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/howeyc/fsnotify v0.9.0 h1:0gtV5JmOKH4A8SsFxG2BczSeXWWPvcMT0euZt5gDAxY= -github.com/howeyc/fsnotify v0.9.0/go.mod h1:41HzSPxBGeFRQKEEwgh49TRw/nKBsYZ2cF1OzPjSJsA= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= @@ -652,8 +650,8 @@ golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -692,8 +690,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -767,13 +765,13 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= -golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -784,8 +782,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -846,8 +844,8 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= -golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/pkg/inject/pkg/kube/inject/common.go b/pkg/inject/pkg/kube/inject/common.go index 69d15df6..92f8638f 100644 --- a/pkg/inject/pkg/kube/inject/common.go +++ b/pkg/inject/pkg/kube/inject/common.go @@ -1,6 +1,5 @@ package inject -import "C" import ( "context" "strings" diff --git a/version b/version index 75e47606..0d687f1e 100644 --- a/version +++ b/version @@ -1 +1 @@ -v1.7.2 \ No newline at end of file +v1.7.3 \ No newline at end of file From d96c42912469fba0b54b90877953a7fcaca42b17 Mon Sep 17 00:00:00 2001 From: evelynwei Date: Fri, 21 Feb 2025 16:42:59 +0800 Subject: [PATCH 07/17] build: update helm files for javaagent --- deploy/kubernetes_v1.21/helm/templates/_helpers.tpl | 7 +++++++ .../helm/templates/controller-configmap-sidecar.yaml | 2 +- deploy/kubernetes_v1.21/helm/values.yaml | 5 +++++ deploy/kubernetes_v1.22/helm/templates/_helpers.tpl | 6 ++++++ .../helm/templates/controller-configmap-sidecar.yaml | 2 +- deploy/kubernetes_v1.22/helm/values.yaml | 5 +++++ 6 files changed, 25 insertions(+), 2 deletions(-) diff --git a/deploy/kubernetes_v1.21/helm/templates/_helpers.tpl b/deploy/kubernetes_v1.21/helm/templates/_helpers.tpl index d984542c..9a212e1a 100644 --- a/deploy/kubernetes_v1.21/helm/templates/_helpers.tpl +++ b/deploy/kubernetes_v1.21/helm/templates/_helpers.tpl @@ -55,6 +55,13 @@ Get specific image for sidecar init container {{- printf "%s:%s" .Values.sidecar.envoy.image.repo .Values.sidecar.envoy.image.tag -}} {{- end -}} +{{/* +Get specific image for javaagent init container +*/}} +{{- define "polaris-controller.sidecar.javaagent.image" -}} +{{- printf "%s:%s" .Values.sidecar.javaagent.image.repo .Values.sidecar.javaagent.image.tag -}} +{{- end -}} + {{/* Get specific image for sidecar init container */}} diff --git a/deploy/kubernetes_v1.21/helm/templates/controller-configmap-sidecar.yaml b/deploy/kubernetes_v1.21/helm/templates/controller-configmap-sidecar.yaml index 4718c4a2..1314e7dc 100644 --- a/deploy/kubernetes_v1.21/helm/templates/controller-configmap-sidecar.yaml +++ b/deploy/kubernetes_v1.21/helm/templates/controller-configmap-sidecar.yaml @@ -98,7 +98,7 @@ data: template: | initContainers: - name: polaris-javaagent-init - image: polarismesh/polaris-javaagent-init:#JAVA_AGENT_INIT# + image: {{ include "polaris-controller.sidecar.javaagent.image" . }} imagePullPolicy: Always env: - name: JAVA_AGENT_DIR diff --git a/deploy/kubernetes_v1.21/helm/values.yaml b/deploy/kubernetes_v1.21/helm/values.yaml index 1880651b..4b1ecda7 100644 --- a/deploy/kubernetes_v1.21/helm/values.yaml +++ b/deploy/kubernetes_v1.21/helm/values.yaml @@ -31,6 +31,11 @@ sidecar: image: repo: polarismesh/polaris-envoy-bootstrap-generator tag: #CONTROLLER_VERSION# + javaagent: + image: + repo: polarismesh/polaris-javaagent-init + tag: #JAVA_AGENT_INIT# + pullPolicy: Always ## polaris server config polaris: diff --git a/deploy/kubernetes_v1.22/helm/templates/_helpers.tpl b/deploy/kubernetes_v1.22/helm/templates/_helpers.tpl index 64df51ff..47f74d64 100644 --- a/deploy/kubernetes_v1.22/helm/templates/_helpers.tpl +++ b/deploy/kubernetes_v1.22/helm/templates/_helpers.tpl @@ -48,6 +48,12 @@ Get specific image for sidecar init container {{- printf "%s:%s" .Values.sidecar.envoy.image.repo .Values.sidecar.envoy.image.tag -}} {{- end -}} +{{/* +Get specific image for javaagent init container +*/}} +{{- define "polaris-controller.sidecar.javaagent.image" -}} +{{- printf "%s:%s" .Values.sidecar.javaagent.image.repo .Values.sidecar.javaagent.image.tag -}} +{{- end -}} {{/* Get specific image for sidecar init container diff --git a/deploy/kubernetes_v1.22/helm/templates/controller-configmap-sidecar.yaml b/deploy/kubernetes_v1.22/helm/templates/controller-configmap-sidecar.yaml index 4718c4a2..1314e7dc 100644 --- a/deploy/kubernetes_v1.22/helm/templates/controller-configmap-sidecar.yaml +++ b/deploy/kubernetes_v1.22/helm/templates/controller-configmap-sidecar.yaml @@ -98,7 +98,7 @@ data: template: | initContainers: - name: polaris-javaagent-init - image: polarismesh/polaris-javaagent-init:#JAVA_AGENT_INIT# + image: {{ include "polaris-controller.sidecar.javaagent.image" . }} imagePullPolicy: Always env: - name: JAVA_AGENT_DIR diff --git a/deploy/kubernetes_v1.22/helm/values.yaml b/deploy/kubernetes_v1.22/helm/values.yaml index 1880651b..4b1ecda7 100644 --- a/deploy/kubernetes_v1.22/helm/values.yaml +++ b/deploy/kubernetes_v1.22/helm/values.yaml @@ -31,6 +31,11 @@ sidecar: image: repo: polarismesh/polaris-envoy-bootstrap-generator tag: #CONTROLLER_VERSION# + javaagent: + image: + repo: polarismesh/polaris-javaagent-init + tag: #JAVA_AGENT_INIT# + pullPolicy: Always ## polaris server config polaris: From 530afa0d166467c10158b1501ba4497296ac78f7 Mon Sep 17 00:00:00 2001 From: evelynwei Date: Fri, 21 Feb 2025 17:41:21 +0800 Subject: [PATCH 08/17] test: update versions --- deploy/variables.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/variables.txt b/deploy/variables.txt index 71849ad7..2eb8de33 100644 --- a/deploy/variables.txt +++ b/deploy/variables.txt @@ -5,4 +5,4 @@ POLARIS_TOKEN:nu/0WRA4EqSR1FagrjRj0fZwPXuGlMpX+zCuWu4uMqy8xr1vRjisSbA25aAC3mtU8M POLARIS_OPERATOR:65e4789a6d5b49669adf1e9e8387549c ENVOY_VERSION:v1.26.2 CLUSTER_NAME:default -JAVA_AGENT_INIT:v0.0.1 \ No newline at end of file +JAVA_AGENT_INIT:latest \ No newline at end of file From bb1c5c6144840e513fe6111073ae0ed5194e2262 Mon Sep 17 00:00:00 2001 From: evelynwei Date: Fri, 21 Feb 2025 17:57:16 +0800 Subject: [PATCH 09/17] test: update helm webhook ca --- .../helm/templates/admission-webhooks/mutating-webhook.yaml | 4 ++-- .../helm/templates/admission-webhooks/mutating-webhook.yaml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/deploy/kubernetes_v1.21/helm/templates/admission-webhooks/mutating-webhook.yaml b/deploy/kubernetes_v1.21/helm/templates/admission-webhooks/mutating-webhook.yaml index 84f00236..a51951eb 100644 --- a/deploy/kubernetes_v1.21/helm/templates/admission-webhooks/mutating-webhook.yaml +++ b/deploy/kubernetes_v1.21/helm/templates/admission-webhooks/mutating-webhook.yaml @@ -27,7 +27,7 @@ webhooks: name: polaris-sidecar-injector namespace: polaris-system path: "/inject" - caBundle: "" + caBundle: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZpVENDQTNHZ0F3SUJBZ0lVSUJGZmZMeE84K2RNSTNrd3hOcXpibGg4Zm9Vd0RRWUpLb1pJaHZjTkFRRUwKQlFBd05qRTBNRElHQTFVRUF3d3JjRzlzWVhKcGN5MXphV1JsWTJGeUxXbHVhbVZqZEc5eUxuQnZiR0Z5YVhNdApjM2x6ZEdWdExuTjJZekFnRncweU1qQTNNRFF3TXpFNU1UaGFHQTh5TVRJeE1EWXhNREF6TVRreE9Gb3dOakUwCk1ESUdBMVVFQXd3cmNHOXNZWEpwY3kxemFXUmxZMkZ5TFdsdWFtVmpkRzl5TG5CdmJHRnlhWE10YzNsemRHVnQKTG5OMll6Q0NBaUl3RFFZSktvWklodmNOQVFFQkJRQURnZ0lQQURDQ0Fnb0NnZ0lCQUxMWmE4NzZkQnRmQlJ1cgpaSzZpK0UzRUs4UWJFWitlaG1lNWNhaXhsakRwTlJIdHFyb2I2NGExYldTUWQxU0IvMmVxbVdiY1ZXY24vVFRQCk45WFVHN2JsNExSaWRWQktYODE3ekdDWEYra3BqbTNOekFseEdEK3lteXhJeWhYS1U5K3A3VGk5SXpORXNPNE8KSlhaQm5iOVdzWGU2eGJJN0dlUUY5WXVCdit0ekNMNVJ0ZmRiUmtMVGQ2eWF3NlZYTFdEcDFrUUU4Q1pEc0g5ZApTZmxBeUhCUitaLzVqbzBtMnQzU3hiNTVPak9YcDhVNmV3bVRmdzZ0VXE1Z3dmZXBjWGNOUWlVTXJveFl0dXkxCkxnWGVBN3MvMFdCeDcrVlFPWXlGSGlaQUI0V1dkSEk1S0JIeFlpSFA3Y2N5aWEvM0gwQ2lYVSthYnd0NHk5TDQKdmVSMHQ5ZmMvbXZXUU01aFBjT1hwdzVJZU5sUG8wZE9vZ0NNdE1qaTkwTEFFS2RMQVNhemxDT0hzdVFqNkczaQp4Nk4rdzQrYy9VTGFxR1REUGc2K0c0UDl5UUVZNXVDNDRZWWpJSGxjQlhyR0YwVFFKTEZMM3F4dnU1VitpYXF1CnMvaWZyRzllY3RyY3lLczVWM0dESGlDdE93Y29MajI1TG1oYzF4MEdvT1RmWis3VFA1NjRyM1k3cVVhcUJ3WFgKMWREak4wREFtU1k1VW1tTGhhZ205bU9xcVo4T29XY0M2clFEVUJwbW1hTTUxVEVkeVEwbHNCc0g1T0Jvalp1UgpkeUZuTXkxWHdSRjVNenRrTW9nRnZKYWhnN1hVUTJBN1NBaUhxaUlCY1AyZTZKNDdUMVNqa0s4NUpwMU1WRW5PCjZhSFZxR29wQm9tUi9BNzBTUlRLeGp2UW52UC9BZ01CQUFHamdZd3dnWWt3SFFZRFZSME9CQllFRkNMTkZlMHUKd3Z3RGRiT0VRQWwxNFMwRTRBQzhNQjhHQTFVZEl3UVlNQmFBRkNMTkZlMHV3dndEZGJPRVFBbDE0UzBFNEFDOApNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdOZ1lEVlIwUkJDOHdMWUlyY0c5c1lYSnBjeTF6YVdSbFkyRnlMV2x1CmFtVmpkRzl5TG5CdmJHRnlhWE10YzNsemRHVnRMbk4yWXpBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQWdFQWx5aXQKVjdYaHRqZTFXK3RBMUtiUUtBUi8rendiUW1RUHpRTHpRdEdqUERvbmk5VVYyK3A1OEF5YmtvVVo3cEhXb2hFcgoxUGI2WGpKVVYxNjhGb3FZMUR4OS9SRCtDeC9mOWZ1MkswTTEvc2pYTk9oVERuMHZwZ2VvMFZJOVdCcUMrK1EyCllORmZNM2ZhaDQyaXVaSTBZNldnRldJM3dGbUQ3MTBWTC8xOVhMQ0dpditUbmc0ZnRwcHhOZW9rWlI1dU1janAKM0hNeExnUkExbnFYQ2ZhT3VrRVZLbnhvQ1hoQmRySXErV1VsOUZjZ09iVGxaU0RMNEpkZTl2R1B3cFBFRS9pVgo5cHhsMkhxWWdUZEdXZjJXeWluSmhZazFXempmZzFRTEY0TnJIQ2o3alJNbDBFbXZHM0hTNDM0ME9PUURKTlptClBDVHVrODV6L2dwaml5b3RxUlorcmNXSThBbVZDdURWbkg0VHVqb2swU1RXdUlWUDM5c21DUE5kUElwUVIxblIKSnZ1L2szV0IrTmlZbU94QzJ5SjRvMWRtYnZvS2ZadGIxVVBObVRJcmxXNThlMDdmUGV4QmNwR3JSRk5yVS9kaQpJbEpMNytXVVBKQWluTC8zL0FLQm5md1ZaemtrOVlUdld0b2xZeElhRExTd3JsdEdvZjBQUkptYnI0UDdxbm56ClFDUXVlZDFsUjRaUHJnYUlnZEdHSjdac1lESlVZbS8xd2g3N3FmR3FlYlRFZmorV09JYzV2S09vcEZTY0ZXd3oKNGVZVmVMYjBZdkc0dmc3ZHhCNFArbElzaFNpdmRVUE5XMW5ZY05pcFIrNnI2Q3h0ZnIwWjZWSkFjZjdTR1FHNwpYZkNuQXdMdlJtMEs2Q1Z6WUhPTFVRR2ZVSjBEbGFEeUR3c0JOc009Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K rules: - operations: ["CREATE"] apiGroups: [""] @@ -45,7 +45,7 @@ webhooks: name: polaris-sidecar-injector namespace: polaris-system path: "/inject" - caBundle: "" + caBundle: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZpVENDQTNHZ0F3SUJBZ0lVSUJGZmZMeE84K2RNSTNrd3hOcXpibGg4Zm9Vd0RRWUpLb1pJaHZjTkFRRUwKQlFBd05qRTBNRElHQTFVRUF3d3JjRzlzWVhKcGN5MXphV1JsWTJGeUxXbHVhbVZqZEc5eUxuQnZiR0Z5YVhNdApjM2x6ZEdWdExuTjJZekFnRncweU1qQTNNRFF3TXpFNU1UaGFHQTh5TVRJeE1EWXhNREF6TVRreE9Gb3dOakUwCk1ESUdBMVVFQXd3cmNHOXNZWEpwY3kxemFXUmxZMkZ5TFdsdWFtVmpkRzl5TG5CdmJHRnlhWE10YzNsemRHVnQKTG5OMll6Q0NBaUl3RFFZSktvWklodmNOQVFFQkJRQURnZ0lQQURDQ0Fnb0NnZ0lCQUxMWmE4NzZkQnRmQlJ1cgpaSzZpK0UzRUs4UWJFWitlaG1lNWNhaXhsakRwTlJIdHFyb2I2NGExYldTUWQxU0IvMmVxbVdiY1ZXY24vVFRQCk45WFVHN2JsNExSaWRWQktYODE3ekdDWEYra3BqbTNOekFseEdEK3lteXhJeWhYS1U5K3A3VGk5SXpORXNPNE8KSlhaQm5iOVdzWGU2eGJJN0dlUUY5WXVCdit0ekNMNVJ0ZmRiUmtMVGQ2eWF3NlZYTFdEcDFrUUU4Q1pEc0g5ZApTZmxBeUhCUitaLzVqbzBtMnQzU3hiNTVPak9YcDhVNmV3bVRmdzZ0VXE1Z3dmZXBjWGNOUWlVTXJveFl0dXkxCkxnWGVBN3MvMFdCeDcrVlFPWXlGSGlaQUI0V1dkSEk1S0JIeFlpSFA3Y2N5aWEvM0gwQ2lYVSthYnd0NHk5TDQKdmVSMHQ5ZmMvbXZXUU01aFBjT1hwdzVJZU5sUG8wZE9vZ0NNdE1qaTkwTEFFS2RMQVNhemxDT0hzdVFqNkczaQp4Nk4rdzQrYy9VTGFxR1REUGc2K0c0UDl5UUVZNXVDNDRZWWpJSGxjQlhyR0YwVFFKTEZMM3F4dnU1VitpYXF1CnMvaWZyRzllY3RyY3lLczVWM0dESGlDdE93Y29MajI1TG1oYzF4MEdvT1RmWis3VFA1NjRyM1k3cVVhcUJ3WFgKMWREak4wREFtU1k1VW1tTGhhZ205bU9xcVo4T29XY0M2clFEVUJwbW1hTTUxVEVkeVEwbHNCc0g1T0Jvalp1UgpkeUZuTXkxWHdSRjVNenRrTW9nRnZKYWhnN1hVUTJBN1NBaUhxaUlCY1AyZTZKNDdUMVNqa0s4NUpwMU1WRW5PCjZhSFZxR29wQm9tUi9BNzBTUlRLeGp2UW52UC9BZ01CQUFHamdZd3dnWWt3SFFZRFZSME9CQllFRkNMTkZlMHUKd3Z3RGRiT0VRQWwxNFMwRTRBQzhNQjhHQTFVZEl3UVlNQmFBRkNMTkZlMHV3dndEZGJPRVFBbDE0UzBFNEFDOApNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdOZ1lEVlIwUkJDOHdMWUlyY0c5c1lYSnBjeTF6YVdSbFkyRnlMV2x1CmFtVmpkRzl5TG5CdmJHRnlhWE10YzNsemRHVnRMbk4yWXpBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQWdFQWx5aXQKVjdYaHRqZTFXK3RBMUtiUUtBUi8rendiUW1RUHpRTHpRdEdqUERvbmk5VVYyK3A1OEF5YmtvVVo3cEhXb2hFcgoxUGI2WGpKVVYxNjhGb3FZMUR4OS9SRCtDeC9mOWZ1MkswTTEvc2pYTk9oVERuMHZwZ2VvMFZJOVdCcUMrK1EyCllORmZNM2ZhaDQyaXVaSTBZNldnRldJM3dGbUQ3MTBWTC8xOVhMQ0dpditUbmc0ZnRwcHhOZW9rWlI1dU1janAKM0hNeExnUkExbnFYQ2ZhT3VrRVZLbnhvQ1hoQmRySXErV1VsOUZjZ09iVGxaU0RMNEpkZTl2R1B3cFBFRS9pVgo5cHhsMkhxWWdUZEdXZjJXeWluSmhZazFXempmZzFRTEY0TnJIQ2o3alJNbDBFbXZHM0hTNDM0ME9PUURKTlptClBDVHVrODV6L2dwaml5b3RxUlorcmNXSThBbVZDdURWbkg0VHVqb2swU1RXdUlWUDM5c21DUE5kUElwUVIxblIKSnZ1L2szV0IrTmlZbU94QzJ5SjRvMWRtYnZvS2ZadGIxVVBObVRJcmxXNThlMDdmUGV4QmNwR3JSRk5yVS9kaQpJbEpMNytXVVBKQWluTC8zL0FLQm5md1ZaemtrOVlUdld0b2xZeElhRExTd3JsdEdvZjBQUkptYnI0UDdxbm56ClFDUXVlZDFsUjRaUHJnYUlnZEdHSjdac1lESlVZbS8xd2g3N3FmR3FlYlRFZmorV09JYzV2S09vcEZTY0ZXd3oKNGVZVmVMYjBZdkc0dmc3ZHhCNFArbElzaFNpdmRVUE5XMW5ZY05pcFIrNnI2Q3h0ZnIwWjZWSkFjZjdTR1FHNwpYZkNuQXdMdlJtMEs2Q1Z6WUhPTFVRR2ZVSjBEbGFEeUR3c0JOc009Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K rules: - operations: ["CREATE"] apiGroups: [""] diff --git a/deploy/kubernetes_v1.22/helm/templates/admission-webhooks/mutating-webhook.yaml b/deploy/kubernetes_v1.22/helm/templates/admission-webhooks/mutating-webhook.yaml index 85740e5b..050235f4 100644 --- a/deploy/kubernetes_v1.22/helm/templates/admission-webhooks/mutating-webhook.yaml +++ b/deploy/kubernetes_v1.22/helm/templates/admission-webhooks/mutating-webhook.yaml @@ -29,7 +29,7 @@ webhooks: name: polaris-sidecar-injector namespace: polaris-system path: "/inject" - caBundle: "" + caBundle: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZpVENDQTNHZ0F3SUJBZ0lVSUJGZmZMeE84K2RNSTNrd3hOcXpibGg4Zm9Vd0RRWUpLb1pJaHZjTkFRRUwKQlFBd05qRTBNRElHQTFVRUF3d3JjRzlzWVhKcGN5MXphV1JsWTJGeUxXbHVhbVZqZEc5eUxuQnZiR0Z5YVhNdApjM2x6ZEdWdExuTjJZekFnRncweU1qQTNNRFF3TXpFNU1UaGFHQTh5TVRJeE1EWXhNREF6TVRreE9Gb3dOakUwCk1ESUdBMVVFQXd3cmNHOXNZWEpwY3kxemFXUmxZMkZ5TFdsdWFtVmpkRzl5TG5CdmJHRnlhWE10YzNsemRHVnQKTG5OMll6Q0NBaUl3RFFZSktvWklodmNOQVFFQkJRQURnZ0lQQURDQ0Fnb0NnZ0lCQUxMWmE4NzZkQnRmQlJ1cgpaSzZpK0UzRUs4UWJFWitlaG1lNWNhaXhsakRwTlJIdHFyb2I2NGExYldTUWQxU0IvMmVxbVdiY1ZXY24vVFRQCk45WFVHN2JsNExSaWRWQktYODE3ekdDWEYra3BqbTNOekFseEdEK3lteXhJeWhYS1U5K3A3VGk5SXpORXNPNE8KSlhaQm5iOVdzWGU2eGJJN0dlUUY5WXVCdit0ekNMNVJ0ZmRiUmtMVGQ2eWF3NlZYTFdEcDFrUUU4Q1pEc0g5ZApTZmxBeUhCUitaLzVqbzBtMnQzU3hiNTVPak9YcDhVNmV3bVRmdzZ0VXE1Z3dmZXBjWGNOUWlVTXJveFl0dXkxCkxnWGVBN3MvMFdCeDcrVlFPWXlGSGlaQUI0V1dkSEk1S0JIeFlpSFA3Y2N5aWEvM0gwQ2lYVSthYnd0NHk5TDQKdmVSMHQ5ZmMvbXZXUU01aFBjT1hwdzVJZU5sUG8wZE9vZ0NNdE1qaTkwTEFFS2RMQVNhemxDT0hzdVFqNkczaQp4Nk4rdzQrYy9VTGFxR1REUGc2K0c0UDl5UUVZNXVDNDRZWWpJSGxjQlhyR0YwVFFKTEZMM3F4dnU1VitpYXF1CnMvaWZyRzllY3RyY3lLczVWM0dESGlDdE93Y29MajI1TG1oYzF4MEdvT1RmWis3VFA1NjRyM1k3cVVhcUJ3WFgKMWREak4wREFtU1k1VW1tTGhhZ205bU9xcVo4T29XY0M2clFEVUJwbW1hTTUxVEVkeVEwbHNCc0g1T0Jvalp1UgpkeUZuTXkxWHdSRjVNenRrTW9nRnZKYWhnN1hVUTJBN1NBaUhxaUlCY1AyZTZKNDdUMVNqa0s4NUpwMU1WRW5PCjZhSFZxR29wQm9tUi9BNzBTUlRLeGp2UW52UC9BZ01CQUFHamdZd3dnWWt3SFFZRFZSME9CQllFRkNMTkZlMHUKd3Z3RGRiT0VRQWwxNFMwRTRBQzhNQjhHQTFVZEl3UVlNQmFBRkNMTkZlMHV3dndEZGJPRVFBbDE0UzBFNEFDOApNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdOZ1lEVlIwUkJDOHdMWUlyY0c5c1lYSnBjeTF6YVdSbFkyRnlMV2x1CmFtVmpkRzl5TG5CdmJHRnlhWE10YzNsemRHVnRMbk4yWXpBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQWdFQWx5aXQKVjdYaHRqZTFXK3RBMUtiUUtBUi8rendiUW1RUHpRTHpRdEdqUERvbmk5VVYyK3A1OEF5YmtvVVo3cEhXb2hFcgoxUGI2WGpKVVYxNjhGb3FZMUR4OS9SRCtDeC9mOWZ1MkswTTEvc2pYTk9oVERuMHZwZ2VvMFZJOVdCcUMrK1EyCllORmZNM2ZhaDQyaXVaSTBZNldnRldJM3dGbUQ3MTBWTC8xOVhMQ0dpditUbmc0ZnRwcHhOZW9rWlI1dU1janAKM0hNeExnUkExbnFYQ2ZhT3VrRVZLbnhvQ1hoQmRySXErV1VsOUZjZ09iVGxaU0RMNEpkZTl2R1B3cFBFRS9pVgo5cHhsMkhxWWdUZEdXZjJXeWluSmhZazFXempmZzFRTEY0TnJIQ2o3alJNbDBFbXZHM0hTNDM0ME9PUURKTlptClBDVHVrODV6L2dwaml5b3RxUlorcmNXSThBbVZDdURWbkg0VHVqb2swU1RXdUlWUDM5c21DUE5kUElwUVIxblIKSnZ1L2szV0IrTmlZbU94QzJ5SjRvMWRtYnZvS2ZadGIxVVBObVRJcmxXNThlMDdmUGV4QmNwR3JSRk5yVS9kaQpJbEpMNytXVVBKQWluTC8zL0FLQm5md1ZaemtrOVlUdld0b2xZeElhRExTd3JsdEdvZjBQUkptYnI0UDdxbm56ClFDUXVlZDFsUjRaUHJnYUlnZEdHSjdac1lESlVZbS8xd2g3N3FmR3FlYlRFZmorV09JYzV2S09vcEZTY0ZXd3oKNGVZVmVMYjBZdkc0dmc3ZHhCNFArbElzaFNpdmRVUE5XMW5ZY05pcFIrNnI2Q3h0ZnIwWjZWSkFjZjdTR1FHNwpYZkNuQXdMdlJtMEs2Q1Z6WUhPTFVRR2ZVSjBEbGFEeUR3c0JOc009Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K rules: - operations: ["CREATE"] apiGroups: [""] @@ -47,7 +47,7 @@ webhooks: name: polaris-sidecar-injector namespace: polaris-system path: "/inject" - caBundle: "" + caBundle: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZpVENDQTNHZ0F3SUJBZ0lVSUJGZmZMeE84K2RNSTNrd3hOcXpibGg4Zm9Vd0RRWUpLb1pJaHZjTkFRRUwKQlFBd05qRTBNRElHQTFVRUF3d3JjRzlzWVhKcGN5MXphV1JsWTJGeUxXbHVhbVZqZEc5eUxuQnZiR0Z5YVhNdApjM2x6ZEdWdExuTjJZekFnRncweU1qQTNNRFF3TXpFNU1UaGFHQTh5TVRJeE1EWXhNREF6TVRreE9Gb3dOakUwCk1ESUdBMVVFQXd3cmNHOXNZWEpwY3kxemFXUmxZMkZ5TFdsdWFtVmpkRzl5TG5CdmJHRnlhWE10YzNsemRHVnQKTG5OMll6Q0NBaUl3RFFZSktvWklodmNOQVFFQkJRQURnZ0lQQURDQ0Fnb0NnZ0lCQUxMWmE4NzZkQnRmQlJ1cgpaSzZpK0UzRUs4UWJFWitlaG1lNWNhaXhsakRwTlJIdHFyb2I2NGExYldTUWQxU0IvMmVxbVdiY1ZXY24vVFRQCk45WFVHN2JsNExSaWRWQktYODE3ekdDWEYra3BqbTNOekFseEdEK3lteXhJeWhYS1U5K3A3VGk5SXpORXNPNE8KSlhaQm5iOVdzWGU2eGJJN0dlUUY5WXVCdit0ekNMNVJ0ZmRiUmtMVGQ2eWF3NlZYTFdEcDFrUUU4Q1pEc0g5ZApTZmxBeUhCUitaLzVqbzBtMnQzU3hiNTVPak9YcDhVNmV3bVRmdzZ0VXE1Z3dmZXBjWGNOUWlVTXJveFl0dXkxCkxnWGVBN3MvMFdCeDcrVlFPWXlGSGlaQUI0V1dkSEk1S0JIeFlpSFA3Y2N5aWEvM0gwQ2lYVSthYnd0NHk5TDQKdmVSMHQ5ZmMvbXZXUU01aFBjT1hwdzVJZU5sUG8wZE9vZ0NNdE1qaTkwTEFFS2RMQVNhemxDT0hzdVFqNkczaQp4Nk4rdzQrYy9VTGFxR1REUGc2K0c0UDl5UUVZNXVDNDRZWWpJSGxjQlhyR0YwVFFKTEZMM3F4dnU1VitpYXF1CnMvaWZyRzllY3RyY3lLczVWM0dESGlDdE93Y29MajI1TG1oYzF4MEdvT1RmWis3VFA1NjRyM1k3cVVhcUJ3WFgKMWREak4wREFtU1k1VW1tTGhhZ205bU9xcVo4T29XY0M2clFEVUJwbW1hTTUxVEVkeVEwbHNCc0g1T0Jvalp1UgpkeUZuTXkxWHdSRjVNenRrTW9nRnZKYWhnN1hVUTJBN1NBaUhxaUlCY1AyZTZKNDdUMVNqa0s4NUpwMU1WRW5PCjZhSFZxR29wQm9tUi9BNzBTUlRLeGp2UW52UC9BZ01CQUFHamdZd3dnWWt3SFFZRFZSME9CQllFRkNMTkZlMHUKd3Z3RGRiT0VRQWwxNFMwRTRBQzhNQjhHQTFVZEl3UVlNQmFBRkNMTkZlMHV3dndEZGJPRVFBbDE0UzBFNEFDOApNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdOZ1lEVlIwUkJDOHdMWUlyY0c5c1lYSnBjeTF6YVdSbFkyRnlMV2x1CmFtVmpkRzl5TG5CdmJHRnlhWE10YzNsemRHVnRMbk4yWXpBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQWdFQWx5aXQKVjdYaHRqZTFXK3RBMUtiUUtBUi8rendiUW1RUHpRTHpRdEdqUERvbmk5VVYyK3A1OEF5YmtvVVo3cEhXb2hFcgoxUGI2WGpKVVYxNjhGb3FZMUR4OS9SRCtDeC9mOWZ1MkswTTEvc2pYTk9oVERuMHZwZ2VvMFZJOVdCcUMrK1EyCllORmZNM2ZhaDQyaXVaSTBZNldnRldJM3dGbUQ3MTBWTC8xOVhMQ0dpditUbmc0ZnRwcHhOZW9rWlI1dU1janAKM0hNeExnUkExbnFYQ2ZhT3VrRVZLbnhvQ1hoQmRySXErV1VsOUZjZ09iVGxaU0RMNEpkZTl2R1B3cFBFRS9pVgo5cHhsMkhxWWdUZEdXZjJXeWluSmhZazFXempmZzFRTEY0TnJIQ2o3alJNbDBFbXZHM0hTNDM0ME9PUURKTlptClBDVHVrODV6L2dwaml5b3RxUlorcmNXSThBbVZDdURWbkg0VHVqb2swU1RXdUlWUDM5c21DUE5kUElwUVIxblIKSnZ1L2szV0IrTmlZbU94QzJ5SjRvMWRtYnZvS2ZadGIxVVBObVRJcmxXNThlMDdmUGV4QmNwR3JSRk5yVS9kaQpJbEpMNytXVVBKQWluTC8zL0FLQm5md1ZaemtrOVlUdld0b2xZeElhRExTd3JsdEdvZjBQUkptYnI0UDdxbm56ClFDUXVlZDFsUjRaUHJnYUlnZEdHSjdac1lESlVZbS8xd2g3N3FmR3FlYlRFZmorV09JYzV2S09vcEZTY0ZXd3oKNGVZVmVMYjBZdkc0dmc3ZHhCNFArbElzaFNpdmRVUE5XMW5ZY05pcFIrNnI2Q3h0ZnIwWjZWSkFjZjdTR1FHNwpYZkNuQXdMdlJtMEs2Q1Z6WUhPTFVRR2ZVSjBEbGFEeUR3c0JOc009Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K rules: - operations: ["CREATE"] apiGroups: [""] From 1d12d22eca1857453853a4cefd105ef953650706 Mon Sep 17 00:00:00 2001 From: evelynwei Date: Wed, 26 Feb 2025 10:22:39 +0800 Subject: [PATCH 10/17] fix: identified service namespace and name --- pkg/inject/pkg/kube/inject/apply/javaagent/patch.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/inject/pkg/kube/inject/apply/javaagent/patch.go b/pkg/inject/pkg/kube/inject/apply/javaagent/patch.go index 9ea3e50e..6e23b8d5 100644 --- a/pkg/inject/pkg/kube/inject/apply/javaagent/patch.go +++ b/pkg/inject/pkg/kube/inject/apply/javaagent/patch.go @@ -280,7 +280,8 @@ func (pb *PodPatchBuilder) updateContainer(opt *inject.PatchOptions, pod *corev1 } defaultProperties := make(map[string]string) - defaultProperties[ServiceNameValueFromKey], defaultProperties[ServiceNamespaceValueFromKey] = getServiceNamespaceAndName(opt) + defaultProperties[ServiceNamespaceValueFromKey], defaultProperties[ServiceNameValueFromKey] = + getServiceNamespaceAndName(opt) var javaToolOptionsValue string for index, container := range target { From 54edb631a55e37ef830fe2db2e23870f53709699 Mon Sep 17 00:00:00 2001 From: evelynwei Date: Wed, 26 Feb 2025 10:44:09 +0800 Subject: [PATCH 11/17] fix: identified config --- .../pkg/kube/inject/apply/javaagent/patch.go | 35 +++++++++---------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/pkg/inject/pkg/kube/inject/apply/javaagent/patch.go b/pkg/inject/pkg/kube/inject/apply/javaagent/patch.go index 6e23b8d5..6b1af4ed 100644 --- a/pkg/inject/pkg/kube/inject/apply/javaagent/patch.go +++ b/pkg/inject/pkg/kube/inject/apply/javaagent/patch.go @@ -287,26 +287,24 @@ func (pb *PodPatchBuilder) updateContainer(opt *inject.PatchOptions, pod *corev1 for index, container := range target { envs := container.Env javaEnvIndex := -1 - if _, valid := oldAgentVersions[annonations[utils.AnnotationKeyJavaAgentVersion]]; !valid { - if properties, ok := annonations[utils.AnnotationKeyJavaAgentPluginConfig]; ok { - customProperties := map[string]string{} - if properties != "" { - if err := json.Unmarshal([]byte(properties), &customProperties); err != nil { - log.InjectScope().Errorf("updateContainer for pod=[%s, %s] json error: %+v", pod.Namespace, - pod.Name, err) - } + if properties, ok := annonations[utils.AnnotationKeyJavaAgentPluginConfig]; ok { + customProperties := map[string]string{} + if properties != "" { + if err := json.Unmarshal([]byte(properties), &customProperties); err != nil { + log.InjectScope().Errorf("updateContainer for pod=[%s, %s] json error: %+v", pod.Namespace, + pod.Name, err) } - // 先从 configmap 中获取 java-agent 不同 plugin-type 的默认配置信息 - for k, v := range customProperties { - if existsValue, exists := defaultProperties[k]; exists { - if existsValue != v { - log.InjectScope().Errorf("updateContainer for pod=[%s, %s] customProperties[%s]=%s, "+ - "replace defaultProperties[%s]=%s", pod.Namespace, pod.Name, k, v, k, existsValue) - } + } + // 先从 configmap 中获取 java-agent 不同 plugin-type 的默认配置信息 + for k, v := range customProperties { + if existsValue, exists := defaultProperties[k]; exists { + if existsValue != v { + log.InjectScope().Errorf("updateContainer for pod=[%s, %s] customProperties[%s]=%s, "+ + "replace defaultProperties[%s]=%s", pod.Namespace, pod.Name, k, v, k, existsValue) } - // 当和默认初始化配置存在冲突时,使用用户自定义配置 - defaultProperties[k] = v } + // 当和默认初始化配置存在冲突时,使用用户自定义配置 + defaultProperties[k] = v } } @@ -323,10 +321,11 @@ func (pb *PodPatchBuilder) updateContainer(opt *inject.PatchOptions, pod *corev1 } // 环境变量 JAVA_TOOL_OPTIONS 已经存在, 往里面追加参数 if javaEnvIndex != -1 { - // RC5版本之后,不再需要javaagentVersion注解,并使用JAVA_TOOL_OPTIONS的参数传递自定义配置 + // RC5之后的版本,不再需要javaagentVersion注解,自动识别版本号 if _, valid := oldAgentVersions[annonations[utils.AnnotationKeyJavaAgentVersion]]; !valid { envs[javaEnvIndex] = updateJavaEnvVar(envs[javaEnvIndex], ActiveJavaAgentCmd, javaToolOptionsValue) } else { + // RC5之前的版本,需要注入javaagentVersion注解,在-javaagent参数里面指定版本号 envs[javaEnvIndex] = updateJavaEnvVar(envs[javaEnvIndex], fmt.Sprintf(OldActiveJavaAgentCmd, opt.ExternalInfo[utils.AnnotationKeyJavaAgentVersion]), "") } From 7e846ef15eed20d40497ccfb0fa7f96aa9dc54a2 Mon Sep 17 00:00:00 2001 From: evelynwei Date: Wed, 26 Feb 2025 16:49:12 +0800 Subject: [PATCH 12/17] test: add unit tests --- go.mod | 6 + .../pkg/kube/inject/apply/javaagent/patch.go | 77 ++-- .../kube/inject/apply/javaagent/patch_test.go | 339 ++++++++++++++++++ 3 files changed, 388 insertions(+), 34 deletions(-) create mode 100644 pkg/inject/pkg/kube/inject/apply/javaagent/patch_test.go diff --git a/go.mod b/go.mod index 2c5d6b2f..47c6601c 100644 --- a/go.mod +++ b/go.mod @@ -31,9 +31,15 @@ require ( require ( github.com/polarismesh/specification v1.4.2-alpha.6 + github.com/stretchr/testify v1.8.2 google.golang.org/protobuf v1.33.0 ) +require ( + github.com/evanphx/json-patch v4.12.0+incompatible // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect +) + require ( github.com/NYTimes/gziphandler v1.1.1 // indirect github.com/beorn7/perks v1.0.1 // indirect diff --git a/pkg/inject/pkg/kube/inject/apply/javaagent/patch.go b/pkg/inject/pkg/kube/inject/apply/javaagent/patch.go index 6b1af4ed..694889da 100644 --- a/pkg/inject/pkg/kube/inject/apply/javaagent/patch.go +++ b/pkg/inject/pkg/kube/inject/apply/javaagent/patch.go @@ -78,7 +78,7 @@ func (pb *PodPatchBuilder) PatchContainer(req *inject.OperateContainerRequest) ( for index, add := range added { if add.Name == javaagentInitContainer { log.InjectScope().Infof("begin deal polaris-javaagent-init inject for pod=[%s, %s]", pod.Namespace, pod.Name) - if err := pb.handleJavaAgentInit(req.Option, pod, &add); err != nil { + if err := pb.handleJavaAgentInit(req, &add); err != nil { log.InjectScope().Errorf("handle polaris-javaagent-init inject for pod=[%s, %s] failed: %v", pod.Namespace, pod.Name, err) } } @@ -89,12 +89,14 @@ func (pb *PodPatchBuilder) PatchContainer(req *inject.OperateContainerRequest) ( log.InjectScope().Infof("finish deal polaris-javaagent-init inject for pod=[%s, %s] added: %#v", pod.Namespace, pod.Name, added) return pb.PodPatchBuilder.PatchContainer(req) case inject.PatchType_Update: - return pb.updateContainer(req.Option, req.Option.Pod, req.Option.Pod.Spec.Containers, req.BasePath), nil + return pb.updateContainer(req), nil } return nil, nil } -func (pb *PodPatchBuilder) handleJavaAgentInit(opt *inject.PatchOptions, pod *corev1.Pod, add *corev1.Container) error { +func (pb *PodPatchBuilder) handleJavaAgentInit(req *inject.OperateContainerRequest, add *corev1.Container) error { + pod := req.Option.Pod + opt := req.Option annonations := pod.Annotations log.InjectScope().Infof("handle polaris-javaagent-init inject for pod=[%s, %s] annonations: %#v image: %s", pod.Namespace, pod.Name, pod.Annotations, add.Image) @@ -136,10 +138,9 @@ func (pb *PodPatchBuilder) handleJavaAgentInit(opt *inject.PatchOptions, pod *co }) } - svcNs, svcName := getServiceNamespaceAndName(opt) defaultParam := map[string]string{ - "MicroserviceNamespace": svcNs, - "MicroserviceName": svcName, + "MicroserviceNamespace": getServiceNamespace(opt), + "MicroserviceName": opt.Annotations[util.SidecarServiceName], "PolarisServerIP": strings.Split(polarisapi.PolarisGrpc, ":")[0], "PolarisDiscoverPort": strings.Split(polarisapi.PolarisGrpc, ":")[1], "PolarisConfigIP": strings.Split(polarisapi.PolarisConfigGrpc, ":")[0], @@ -233,22 +234,31 @@ func (pb *PodPatchBuilder) handleJavaAgentInit(opt *inject.PatchOptions, pod *co return nil } -func getServiceNamespaceAndName(opt *inject.PatchOptions) (string, string) { - serviceNs := "default" - serviceName := opt.Annotations[util.SidecarServiceName] - if useWorkloadNS, ok := opt.Annotations[utils.AnnotationKeyWorkloadNamespaceAsServiceNamespace]; ok && +func getDefaultProperties(opt *inject.PatchOptions) map[string]string { + defaultProperties := make(map[string]string) + if useWorkloadNS, ok := opt.Pod.Annotations[utils.AnnotationKeyWorkloadNamespaceAsServiceNamespace]; ok && useWorkloadNS == utils.InjectionValueTrue { log.InjectScope().Infof("handle polaris-javaagent-init inject for pod=[%s, %s] useWorkloadNS=%s", opt.Pod.Namespace, opt.Pod.Name, useWorkloadNS) - serviceNs = opt.Pod.Namespace + defaultProperties[ServiceNamespaceValueFromKey] = opt.Pod.Namespace } - if useWorkloadName, ok := opt.Annotations[utils.AnnotationKeyWorkloadNameAsServiceName]; ok && + if useWorkloadName, ok := opt.Pod.Annotations[utils.AnnotationKeyWorkloadNameAsServiceName]; ok && useWorkloadName == utils.InjectionValueTrue { log.InjectScope().Infof("handle polaris-javaagent-init inject for pod=[%s, %s] useWorkloadName=%s", - opt.Pod.Namespace, opt.Pod.Name, useWorkloadName) - serviceName = opt.WorkloadName + opt.Pod.Namespace, opt.Pod.Name, opt.WorkloadName) + defaultProperties[ServiceNameValueFromKey] = opt.WorkloadName + } + return defaultProperties +} + +func getServiceNamespace(opt *inject.PatchOptions) string { + if useWorkloadNS, ok := opt.Pod.Annotations[utils.AnnotationKeyWorkloadNamespaceAsServiceNamespace]; ok && + useWorkloadNS == utils.InjectionValueTrue { + log.InjectScope().Infof("handle polaris-javaagent-init inject for pod=[%s, %s] useWorkloadNS=%s", + opt.Pod.Namespace, opt.Pod.Name, useWorkloadNS) + return opt.Pod.Namespace } - return serviceNs, serviceName + return "default" } func nameOfPluginDefault(v string) string { @@ -267,27 +277,26 @@ const ( ServiceNamespaceValueFromKey = "spring.cloud.polaris.discovery.namespace" ) -func (pb *PodPatchBuilder) updateContainer(opt *inject.PatchOptions, pod *corev1.Pod, target []corev1.Container, - basePath string) []inject.Rfc6902PatchOperation { - - patchs := make([]inject.Rfc6902PatchOperation, 0, len(target)) +func (pb *PodPatchBuilder) updateContainer(req *inject.OperateContainerRequest) []inject.Rfc6902PatchOperation { + opt := req.Option + pod := req.Option.Pod + target := req.Option.Pod.Spec.Containers + basePath := req.BasePath + patches := make([]inject.Rfc6902PatchOperation, 0, len(target)) - annonations := pod.Annotations - if val, ok := annonations[utils.AnnotationKeyJavaAgentVersion]; ok && val != "" { + // 判断用户是否自定义了 javaagent 的版本 + if val, ok := pod.Annotations[utils.AnnotationKeyJavaAgentVersion]; ok && val != "" { opt.ExternalInfo[utils.AnnotationKeyJavaAgentVersion] = val } else { - annonations[utils.AnnotationKeyJavaAgentVersion] = "latest" + pod.Annotations[utils.AnnotationKeyJavaAgentVersion] = "latest" } - defaultProperties := make(map[string]string) - defaultProperties[ServiceNamespaceValueFromKey], defaultProperties[ServiceNameValueFromKey] = - getServiceNamespaceAndName(opt) - var javaToolOptionsValue string - + // 初始化默认配置和用户自定义配置 + defaultProperties := getDefaultProperties(opt) for index, container := range target { envs := container.Env javaEnvIndex := -1 - if properties, ok := annonations[utils.AnnotationKeyJavaAgentPluginConfig]; ok { + if properties, ok := pod.Annotations[utils.AnnotationKeyJavaAgentPluginConfig]; ok { customProperties := map[string]string{} if properties != "" { if err := json.Unmarshal([]byte(properties), &customProperties); err != nil { @@ -308,10 +317,11 @@ func (pb *PodPatchBuilder) updateContainer(opt *inject.PatchOptions, pod *corev1 } } + // 将配置转成-D参数, 并追加到JAVA_TOOL_OPTIONS + var javaToolOptionsValue string for key, value := range defaultProperties { javaToolOptionsValue += fmt.Sprintf(" -D%s=%s", key, value) } - if len(envs) != 0 { for i := range envs { if envs[i].Name == "JAVA_TOOL_OPTIONS" { @@ -322,7 +332,7 @@ func (pb *PodPatchBuilder) updateContainer(opt *inject.PatchOptions, pod *corev1 // 环境变量 JAVA_TOOL_OPTIONS 已经存在, 往里面追加参数 if javaEnvIndex != -1 { // RC5之后的版本,不再需要javaagentVersion注解,自动识别版本号 - if _, valid := oldAgentVersions[annonations[utils.AnnotationKeyJavaAgentVersion]]; !valid { + if _, valid := oldAgentVersions[pod.Annotations[utils.AnnotationKeyJavaAgentVersion]]; !valid { envs[javaEnvIndex] = updateJavaEnvVar(envs[javaEnvIndex], ActiveJavaAgentCmd, javaToolOptionsValue) } else { // RC5之前的版本,需要注入javaagentVersion注解,在-javaagent参数里面指定版本号 @@ -335,7 +345,7 @@ func (pb *PodPatchBuilder) updateContainer(opt *inject.PatchOptions, pod *corev1 if javaEnvIndex == -1 { // 注入 java agent 需要用到的参数信息 var newEnvVar corev1.EnvVar - if _, valid := oldAgentVersions[annonations[utils.AnnotationKeyJavaAgentVersion]]; !valid { + if _, valid := oldAgentVersions[pod.Annotations[utils.AnnotationKeyJavaAgentVersion]]; !valid { newEnvVar = updateJavaEnvVar(corev1.EnvVar{}, ActiveJavaAgentCmd, javaToolOptionsValue) } else { newEnvVar = updateJavaEnvVar(corev1.EnvVar{}, fmt.Sprintf(OldActiveJavaAgentCmd, @@ -350,16 +360,15 @@ func (pb *PodPatchBuilder) updateContainer(opt *inject.PatchOptions, pod *corev1 Name: "java-agent-dir", MountPath: "/app/lib/.polaris/java_agent", }) - path := basePath path += "/" + strconv.Itoa(index) - patchs = append(patchs, inject.Rfc6902PatchOperation{ + patches = append(patches, inject.Rfc6902PatchOperation{ Op: "replace", Path: path, Value: container, }) } - return patchs + return patches } func (pb *PodPatchBuilder) PatchVolumes(req *inject.OperateVolumesRequest) ([]inject.Rfc6902PatchOperation, error) { diff --git a/pkg/inject/pkg/kube/inject/apply/javaagent/patch_test.go b/pkg/inject/pkg/kube/inject/apply/javaagent/patch_test.go new file mode 100644 index 00000000..f6a1c1fb --- /dev/null +++ b/pkg/inject/pkg/kube/inject/apply/javaagent/patch_test.go @@ -0,0 +1,339 @@ +// ==== 原代码 ==== +// ... 省略其他代码 ... + +// ==== 修改后代码 ==== +package javaagent + +import ( + "testing" + + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes/fake" + + "github.com/polarismesh/polaris-controller/pkg/inject/pkg/kube/inject" + "github.com/polarismesh/polaris-controller/pkg/inject/pkg/kube/inject/apply/base" + "github.com/polarismesh/polaris-controller/pkg/util" +) + +func TestUpdateContainer(t *testing.T) { + // 定义测试用例 + tests := []struct { + name string + pod *corev1.Pod + opt *inject.PatchOptions + expectedCmd string + expectMount bool + }{ + { + name: "旧版本使用的javaagent参数需要带版本号", + pod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "test-ns", + Annotations: map[string]string{ + util.AnnotationKeyJavaAgentVersion: "1.7.0-RC1", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{{ + Name: "main", + Env: []corev1.EnvVar{{ + Name: "JAVA_TOOL_OPTIONS", + Value: "-Xmx512m", + }}, + }}, + }, + }, + opt: &inject.PatchOptions{ + WorkloadName: "test-workload", + ExternalInfo: map[string]string{}, + Pod: &corev1.Pod{}, + }, + expectedCmd: "-Xmx512m -javaagent:/app/lib/.polaris/java_agent/polaris-java-agent-1.7.0-RC1/polaris-agent-core-bootstrap.jar", + expectMount: true, + }, + { + name: "使用k8s工作负载和命名空间作为服务空间和服务名", + pod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "test-ns", + Annotations: map[string]string{ + util.AnnotationKeyInjectJavaAgent: util.InjectionValueTrue, + util.AnnotationKeyWorkloadNameAsServiceName: util.InjectionValueTrue, + util.AnnotationKeyWorkloadNamespaceAsServiceNamespace: util.InjectionValueTrue, + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{{ + Name: "main", + Env: []corev1.EnvVar{}, + }}, + }, + }, + opt: &inject.PatchOptions{ + ExternalInfo: make(map[string]string), + WorkloadName: "test-workload", + Annotations: map[string]string{}, + Pod: &corev1.Pod{}, + }, + expectedCmd: "-javaagent:/app/lib/.polaris/java_agent/polaris-java-agent/polaris-agent-core-bootstrap.jar -Dspring.cloud.polaris.discovery.namespace=test-ns -Dspring.application.name=test-workload", + expectMount: true, + }, + { + name: "自定义服务名和使用k8s工作负载作为服务名有冲突,使用自定义的服务名", + pod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "test-ns", + Annotations: map[string]string{ + util.AnnotationKeyJavaAgentVersion: "v1.10.0", + util.AnnotationKeyWorkloadNameAsServiceName: util.InjectionValueTrue, + util.AnnotationKeyWorkloadNamespaceAsServiceNamespace: util.InjectionValueTrue, + util.AnnotationKeyJavaAgentPluginConfig: `{"spring.application.name":"custom-service","spring.cloud.polaris.discovery.namespace":"custom-ns"}`, + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{{ + Name: "main", + Env: []corev1.EnvVar{}, + }}, + }, + }, + opt: &inject.PatchOptions{ + ExternalInfo: make(map[string]string), + WorkloadName: "test-workload", + Annotations: map[string]string{}, + Pod: &corev1.Pod{}, + }, + expectedCmd: "-javaagent:/app/lib/.polaris/java_agent/polaris-java-agent/polaris-agent-core-bootstrap.jar -Dspring.cloud.polaris.discovery.namespace=custom-ns -Dspring.application.name=custom-service", + expectMount: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // 初始化测试环境 + pb := &PodPatchBuilder{ + PodPatchBuilder: &base.PodPatchBuilder{}, + } + + // 构建请求 + req := &inject.OperateContainerRequest{ + Option: tt.opt, + BasePath: "/spec/containers", + } + tt.opt.Pod = tt.pod + + // 执行测试 + patches := pb.updateContainer(req) + + // 验证结果 + assert.NotEmpty(t, patches, "should generate patches") + if len(patches) > 0 { + container := patches[0].Value.(corev1.Container) + + // 验证环境变量 + var javaToolOptions string + for _, env := range container.Env { + if env.Name == "JAVA_TOOL_OPTIONS" { + javaToolOptions = env.Value + break + } + } + assert.Contains(t, javaToolOptions, tt.expectedCmd, "JAVA_TOOL_OPTIONS mismatch") + + // 验证Volume Mount + if tt.expectMount { + assert.Len(t, container.VolumeMounts, 1, "should have volume mount") + assert.Equal(t, "java-agent-dir", container.VolumeMounts[0].Name) + } + + // 验证补丁操作 + assert.Equal(t, "replace", patches[0].Op, "patch operation should be replace") + } + + // 验证版本处理 + if version, ok := tt.pod.Annotations[util.AnnotationKeyJavaAgentVersion]; ok { + if _, isOld := oldAgentVersions[version]; isOld { + assert.Contains(t, tt.opt.ExternalInfo, util.AnnotationKeyJavaAgentVersion, + "should store version in external info for old agents") + } + } + }) + } +} + +func TestHandleJavaAgentInit(t *testing.T) { + // Mock 测试用的 ConfigMap + mockConfigMap := &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: "plugin-default.properties", + Namespace: util.RootNamespace, + }, + Data: map[string]string{ + "spring-cloud-default-properties": `spring.application.name={{.MicroserviceName}} +spring.cloud.polaris.discovery.namespace={{.MicroserviceNamespace}}`, + }, + } + + tests := []struct { + name string + podAnnotations map[string]string + initContainer *corev1.Container + expected func(t *testing.T, c *corev1.Container) + }{ + { + name: "default_image_version", + podAnnotations: map[string]string{}, + initContainer: &corev1.Container{ + Image: "polarismesh/polaris-java-agent-init:1.7.0-RC5", + }, + expected: func(t *testing.T, c *corev1.Container) { + assert.Equal(t, "polarismesh/polaris-java-agent-init:1.7.0-RC5", c.Image) + assertContainsEnv(t, c, "POLARIS_SERVER_IP") + assertContainsEnv(t, c, "POLARIS_DISCOVER_PORT") + }, + }, + { + name: "custom_image_version", + podAnnotations: map[string]string{ + util.AnnotationKeyJavaAgentVersion: "v1.8.0", + }, + initContainer: &corev1.Container{ + Image: "polarismesh/polaris-java-agent-init:1.7.0-RC5", + }, + expected: func(t *testing.T, c *corev1.Container) { + assert.Equal(t, "polarismesh/polaris-java-agent-init:v1.8.0", c.Image) + }, + }, + { + name: "old_version_with_configmap", + podAnnotations: map[string]string{ + util.AnnotationKeyJavaAgentVersion: "1.7.0-RC5", + util.AnnotationKeyJavaAgentPluginConfig: `{"logging.level":"DEBUG"}`, + util.AnnotationKeyJavaAgentPluginFramework: "spring-cloud", + }, + initContainer: &corev1.Container{ + Image: "polarismesh/polaris-java-agent-init:1.7.0-RC5", + }, + expected: func(t *testing.T, c *corev1.Container) { + // 验证环境变量 + var pluginConf string + for _, env := range c.Env { + if env.Name == "JAVA_AGENT_PLUGIN_CONF" { + pluginConf = env.Value + } + } + assert.Contains(t, pluginConf, "spring.application.name=test-service") + assert.Contains(t, pluginConf, "logging.level=DEBUG") + assert.Contains(t, pluginConf, "spring.cloud.polaris.discovery.namespace=default") + }, + }, + { + name: "使用k8s命名空间和工作负载名称注册", + podAnnotations: map[string]string{ + util.AnnotationKeyJavaAgentVersion: "1.7.0-RC5", + util.AnnotationKeyJavaAgentPluginConfig: `{"logging.level":"DEBUG"}`, + util.AnnotationKeyJavaAgentPluginFramework: "spring-cloud", + util.AnnotationKeyWorkloadNameAsServiceName: util.InjectionValueTrue, + util.AnnotationKeyWorkloadNamespaceAsServiceNamespace: util.InjectionValueTrue, + }, + initContainer: &corev1.Container{ + Image: "polarismesh/polaris-java-agent-init:1.7.0-RC5", + }, + expected: func(t *testing.T, c *corev1.Container) { + // 验证环境变量 + var pluginConf string + for _, env := range c.Env { + if env.Name == "JAVA_AGENT_PLUGIN_CONF" { + pluginConf = env.Value + } + } + assert.Contains(t, pluginConf, "spring.application.name=test-service") + assert.Contains(t, pluginConf, "logging.level=DEBUG") + assert.Contains(t, pluginConf, "spring.cloud.polaris.discovery.namespace=test-ns") + }, + }, + { + name: "使用k8s命名空间和工作负载名称注册,和自定义配置冲突,使用自定义配置", + podAnnotations: map[string]string{ + util.AnnotationKeyJavaAgentVersion: "1.7.0-RC5", + util.AnnotationKeyJavaAgentPluginConfig: `{"logging.level":"DEBUG","spring.cloud.polaris.discovery.namespace":"custom-ns","spring.application.name":"custom-service"}`, + util.AnnotationKeyJavaAgentPluginFramework: "spring-cloud", + util.AnnotationKeyWorkloadNameAsServiceName: util.InjectionValueTrue, + util.AnnotationKeyWorkloadNamespaceAsServiceNamespace: util.InjectionValueTrue, + }, + initContainer: &corev1.Container{ + Image: "polarismesh/polaris-java-agent-init:1.7.0-RC5", + }, + expected: func(t *testing.T, c *corev1.Container) { + // 验证环境变量 + var pluginConf string + for _, env := range c.Env { + if env.Name == "JAVA_AGENT_PLUGIN_CONF" { + pluginConf = env.Value + } + } + assert.Contains(t, pluginConf, "spring.application.name=custom-service") + assert.Contains(t, pluginConf, "logging.level=DEBUG") + assert.Contains(t, pluginConf, "spring.cloud.polaris.discovery.namespace=custom-ns") + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // 初始化fake client + client := fake.NewSimpleClientset(mockConfigMap) + + // 构建测试请求 + req := &inject.OperateContainerRequest{ + Option: &inject.PatchOptions{ + KubeClient: client, + Pod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "test-ns", + Annotations: tt.podAnnotations, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{{ + Name: "main", + Image: "app:latest", + }}, + }, + }, + ExternalInfo: make(map[string]string), + WorkloadName: "test-service", + Annotations: map[string]string{util.SidecarServiceName: "test-service"}, + }, + External: []corev1.Container{*tt.initContainer}, + } + + pb := &PodPatchBuilder{ + PodPatchBuilder: &base.PodPatchBuilder{}, + } + + // 执行测试 + err := pb.handleJavaAgentInit(req, tt.initContainer) + + // 验证结果 + assert.NoError(t, err) + tt.expected(t, tt.initContainer) + + // 验证外部信息存储 + if version, ok := tt.podAnnotations[util.AnnotationKeyJavaAgentVersion]; ok { + assert.Equal(t, version, req.Option.ExternalInfo[util.AnnotationKeyJavaAgentVersion]) + } + }) + } +} + +// 辅助断言函数 +func assertContainsEnv(t *testing.T, container *corev1.Container, name string) { + for _, env := range container.Env { + if env.Name == name { + return + } + } + t.Errorf("Expected env %s not found", name) +} From d188aad069a6597d1e68159596aa42ec2f4bc748 Mon Sep 17 00:00:00 2001 From: evelynwei Date: Wed, 26 Feb 2025 16:50:00 +0800 Subject: [PATCH 13/17] =?UTF-8?q?chore:=20=E5=8E=BB=E6=8E=89=E6=97=A0?= =?UTF-8?q?=E7=94=A8=E7=9A=84=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/inject/pkg/kube/inject/apply/javaagent/patch_test.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pkg/inject/pkg/kube/inject/apply/javaagent/patch_test.go b/pkg/inject/pkg/kube/inject/apply/javaagent/patch_test.go index f6a1c1fb..cbe06365 100644 --- a/pkg/inject/pkg/kube/inject/apply/javaagent/patch_test.go +++ b/pkg/inject/pkg/kube/inject/apply/javaagent/patch_test.go @@ -1,7 +1,3 @@ -// ==== 原代码 ==== -// ... 省略其他代码 ... - -// ==== 修改后代码 ==== package javaagent import ( From 7edfc1fab33ec1878682668363eab35414b6d134 Mon Sep 17 00:00:00 2001 From: evelynwei Date: Thu, 27 Feb 2025 11:07:17 +0800 Subject: [PATCH 14/17] fix: fix mesh envoy yaml config --- pkg/inject/pkg/config/mesh/mesh.go | 2 +- pkg/inject/pkg/kube/inject/base.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/inject/pkg/config/mesh/mesh.go b/pkg/inject/pkg/config/mesh/mesh.go index 9cf50589..26b43811 100644 --- a/pkg/inject/pkg/config/mesh/mesh.go +++ b/pkg/inject/pkg/config/mesh/mesh.go @@ -24,7 +24,7 @@ import ( // MeshEnvoyConfig mesh 注入配置, envoy sidecar当前有用到 type MeshEnvoyConfig struct { - defaultConfig *DefaultConfig `yaml:"DefaultConfig"` + defaultConfig *DefaultConfig `yaml:"defaultConfig"` } // DefaultConfig 存储北极星proxy默认配置和用户自定义配置 diff --git a/pkg/inject/pkg/kube/inject/base.go b/pkg/inject/pkg/kube/inject/base.go index 4901e5ef..d8e106de 100644 --- a/pkg/inject/pkg/kube/inject/base.go +++ b/pkg/inject/pkg/kube/inject/base.go @@ -39,7 +39,7 @@ func (wh *Webhook) getPodPatch(p *podDataInfo) ([]byte, error) { values := map[string]interface{}{} valuesConfig := wh.templateConfig.GetValuesConfig() if err := yaml.Unmarshal([]byte(wh.templateConfig.GetValuesConfig()), &values); err != nil { - log.InjectScope().Infof("[Webhook] failed to parse values config: %v [%v]\n", err, valuesConfig) + log.InjectScope().Errorf("[Webhook] failed to parse values config: %v [%v]\n", err, valuesConfig) return nil, multierror.Prefix(err, "could not parse configuration values:") } metadataCopy := p.podObject.ObjectMeta.DeepCopy() From bb9a3297092fcd1b61c5576e5b20143dc199e758 Mon Sep 17 00:00:00 2001 From: evelynwei Date: Thu, 27 Feb 2025 11:23:19 +0800 Subject: [PATCH 15/17] fix: update mesh envoy yaml inject config --- pkg/inject/pkg/config/mesh/mesh.go | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/pkg/inject/pkg/config/mesh/mesh.go b/pkg/inject/pkg/config/mesh/mesh.go index 26b43811..aad730e4 100644 --- a/pkg/inject/pkg/config/mesh/mesh.go +++ b/pkg/inject/pkg/config/mesh/mesh.go @@ -24,12 +24,12 @@ import ( // MeshEnvoyConfig mesh 注入配置, envoy sidecar当前有用到 type MeshEnvoyConfig struct { - defaultConfig *DefaultConfig `yaml:"defaultConfig"` + DefaultConfig *DefaultConfig `yaml:"DefaultConfig"` } // DefaultConfig 存储北极星proxy默认配置和用户自定义配置 type DefaultConfig struct { - proxyMetadata map[string]string `yaml:"proxyMetadata"` + ProxyMetadata map[string]string `yaml:"ProxyMetadata"` } // ReadMeshEnvoyConfig 读取mesh envoy sidecar注入配置 @@ -39,8 +39,8 @@ func ReadMeshEnvoyConfig(filename string) (*MeshEnvoyConfig, error) { return nil, multierror.Prefix(err, "cannot read mesh config file") } defaultConfig := &MeshEnvoyConfig{ - defaultConfig: &DefaultConfig{ - proxyMetadata: map[string]string{}, + DefaultConfig: &DefaultConfig{ + ProxyMetadata: map[string]string{}, }, } if err = yaml.Unmarshal(yamlBytes, defaultConfig); err != nil { @@ -54,7 +54,7 @@ func (ic *MeshEnvoyConfig) GetDefaultConfig() *DefaultConfig { if ic == nil { return nil } - return ic.defaultConfig + return ic.DefaultConfig } // SetDefaultConfig 设置默认配置 @@ -62,7 +62,7 @@ func (ic *MeshEnvoyConfig) SetDefaultConfig(config *DefaultConfig) { if ic == nil { return } - ic.defaultConfig = config + ic.DefaultConfig = config } // GetProxyMetadata 获取 proxy 元数据 @@ -70,7 +70,7 @@ func (dc *DefaultConfig) GetProxyMetadata() map[string]string { if dc == nil { return nil } - return dc.proxyMetadata + return dc.ProxyMetadata } // SetProxyMetadataWithKV 设置 proxy 元数据 @@ -78,7 +78,7 @@ func (dc *MeshEnvoyConfig) SetProxyMetadataWithKV(k, v string) { if dc == nil { return } - dc.defaultConfig.proxyMetadata[k] = v + dc.DefaultConfig.ProxyMetadata[k] = v } // String 返回 MeshEnvoyConfig 的字符串表示 @@ -88,10 +88,10 @@ func (ic *MeshEnvoyConfig) String() string { } var defaultConfig string - if ic.defaultConfig == nil { + if ic.DefaultConfig == nil { defaultConfig = "nil" } else { - defaultConfig = ic.defaultConfig.String() + defaultConfig = ic.DefaultConfig.String() } return fmt.Sprintf("MeshEnvoyConfig{DefaultConfig: %s}", defaultConfig) @@ -104,9 +104,9 @@ func (dc *DefaultConfig) String() string { } metadata := "nil" - if dc.proxyMetadata != nil { - metadata = fmt.Sprintf("%v", dc.proxyMetadata) + if dc.ProxyMetadata != nil { + metadata = fmt.Sprintf("%v", dc.ProxyMetadata) } - return fmt.Sprintf("DefaultConfig{proxyMetadata: %s}", metadata) + return fmt.Sprintf("DefaultConfig{ProxyMetadata: %s}", metadata) } From 820e603266db318aa25c107e654a4767d4ec7e85 Mon Sep 17 00:00:00 2001 From: evelynwei Date: Tue, 15 Apr 2025 16:31:56 +0800 Subject: [PATCH 16/17] =?UTF-8?q?test:=20=E4=BC=98=E5=8C=96=E5=8D=95?= =?UTF-8?q?=E6=B5=8B,=20map=20=E7=9A=84=20for=20range=20=E9=81=8D=E5=8E=86?= =?UTF-8?q?=E9=A1=BA=E5=BA=8F=E6=98=AF=E9=9A=8F=E6=9C=BA=E7=9A=84,=20?= =?UTF-8?q?=E9=80=9A=E8=BF=87=E6=89=8B=E5=8A=A8=E5=A4=84=E7=90=86=E9=94=AE?= =?UTF-8?q?=E5=80=BC=E5=AF=B9=E7=9A=84=E6=8E=92=E5=BA=8F=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/inject/pkg/kube/inject/apply/javaagent/patch.go | 13 +++++++++++-- .../pkg/kube/inject/apply/javaagent/patch_test.go | 4 ++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/pkg/inject/pkg/kube/inject/apply/javaagent/patch.go b/pkg/inject/pkg/kube/inject/apply/javaagent/patch.go index 694889da..24121273 100644 --- a/pkg/inject/pkg/kube/inject/apply/javaagent/patch.go +++ b/pkg/inject/pkg/kube/inject/apply/javaagent/patch.go @@ -20,6 +20,7 @@ import ( "context" "encoding/json" "fmt" + "sort" "strconv" "strings" "text/template" @@ -317,9 +318,17 @@ func (pb *PodPatchBuilder) updateContainer(req *inject.OperateContainerRequest) } } - // 将配置转成-D参数, 并追加到JAVA_TOOL_OPTIONS + // 提取键到切片 + keys := make([]string, 0, len(defaultProperties)) + for k := range defaultProperties { + keys = append(keys, k) + } + // 排序(按字母升序) + sort.Strings(keys) + // 按顺序遍历, 将配置转成-D参数, 并追加到JAVA_TOOL_OPTIONS var javaToolOptionsValue string - for key, value := range defaultProperties { + for _, key := range keys { + value := defaultProperties[key] javaToolOptionsValue += fmt.Sprintf(" -D%s=%s", key, value) } if len(envs) != 0 { diff --git a/pkg/inject/pkg/kube/inject/apply/javaagent/patch_test.go b/pkg/inject/pkg/kube/inject/apply/javaagent/patch_test.go index cbe06365..a1e9e6c3 100644 --- a/pkg/inject/pkg/kube/inject/apply/javaagent/patch_test.go +++ b/pkg/inject/pkg/kube/inject/apply/javaagent/patch_test.go @@ -73,7 +73,7 @@ func TestUpdateContainer(t *testing.T) { Annotations: map[string]string{}, Pod: &corev1.Pod{}, }, - expectedCmd: "-javaagent:/app/lib/.polaris/java_agent/polaris-java-agent/polaris-agent-core-bootstrap.jar -Dspring.cloud.polaris.discovery.namespace=test-ns -Dspring.application.name=test-workload", + expectedCmd: "-javaagent:/app/lib/.polaris/java_agent/polaris-java-agent/polaris-agent-core-bootstrap.jar -Dspring.application.name=test-workload -Dspring.cloud.polaris.discovery.namespace=test-ns", expectMount: true, }, { @@ -101,7 +101,7 @@ func TestUpdateContainer(t *testing.T) { Annotations: map[string]string{}, Pod: &corev1.Pod{}, }, - expectedCmd: "-javaagent:/app/lib/.polaris/java_agent/polaris-java-agent/polaris-agent-core-bootstrap.jar -Dspring.cloud.polaris.discovery.namespace=custom-ns -Dspring.application.name=custom-service", + expectedCmd: "-javaagent:/app/lib/.polaris/java_agent/polaris-java-agent/polaris-agent-core-bootstrap.jar -Dspring.application.name=custom-service -Dspring.cloud.polaris.discovery.namespace=custom-ns", expectMount: true, }, } From ab1c359bf7bee162bf37a5f7517c34f088dc55a1 Mon Sep 17 00:00:00 2001 From: evelynwei Date: Tue, 15 Apr 2025 19:13:03 +0800 Subject: [PATCH 17/17] =?UTF-8?q?fix:=20=E4=BF=AE=E6=AD=A3mesh=20envoy?= =?UTF-8?q?=E6=B8=B2=E6=9F=93=E6=A8=A1=E7=89=88=E7=9A=84typo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deploy/kubernetes_v1.21/helm/templates/_params.tpl | 2 +- deploy/kubernetes_v1.21/kubernetes/injector.yaml | 2 +- deploy/kubernetes_v1.22/helm/templates/_params.tpl | 2 +- deploy/kubernetes_v1.22/kubernetes/injector.yaml | 2 +- pkg/inject/pkg/config/mesh/mesh.go | 4 ++-- pkg/util/types.go | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/deploy/kubernetes_v1.21/helm/templates/_params.tpl b/deploy/kubernetes_v1.21/helm/templates/_params.tpl index e783f52f..ebf4611e 100644 --- a/deploy/kubernetes_v1.21/helm/templates/_params.tpl +++ b/deploy/kubernetes_v1.21/helm/templates/_params.tpl @@ -64,7 +64,7 @@ Define the cmd envs for the bootstrap init container. - name: CLUSTER_NAME value: {{ "{{" }}.ProxyConfig.ProxyMetadata.clusterName{{ "}}" }} - name: OPEN_DEMAND - value: {{ "{{" }}.ProxyConfig.ProxyMetadata.opemDemand{{ "}}" }} + value: {{ "{{" }}.ProxyConfig.ProxyMetadata.openDemand{{ "}}" }} {{- end -}} diff --git a/deploy/kubernetes_v1.21/kubernetes/injector.yaml b/deploy/kubernetes_v1.21/kubernetes/injector.yaml index c384bdd9..9ead81f2 100644 --- a/deploy/kubernetes_v1.21/kubernetes/injector.yaml +++ b/deploy/kubernetes_v1.21/kubernetes/injector.yaml @@ -256,7 +256,7 @@ data: - name: CLUSTER_NAME value: {{.ProxyConfig.ProxyMetadata.clusterName}} - name: OPEN_DEMAND - value: {{.ProxyConfig.ProxyMetadata.opemDemand}} + value: {{.ProxyConfig.ProxyMetadata.openDemand}} volumeMounts: - mountPath: /var/lib/data name: envoy-bootstrap diff --git a/deploy/kubernetes_v1.22/helm/templates/_params.tpl b/deploy/kubernetes_v1.22/helm/templates/_params.tpl index ca3aaa5f..78918cb3 100644 --- a/deploy/kubernetes_v1.22/helm/templates/_params.tpl +++ b/deploy/kubernetes_v1.22/helm/templates/_params.tpl @@ -78,7 +78,7 @@ Define the cmd envs for the bootstrap init container. - name: CLUSTER_NAME value: {{ "{{" }}.ProxyConfig.ProxyMetadata.clusterName{{ "}}" }} - name: OPEN_DEMAND - value: {{ "{{" }}.ProxyConfig.ProxyMetadata.opemDemand{{ "}}" }} + value: {{ "{{" }}.ProxyConfig.ProxyMetadata.openDemand{{ "}}" }} {{- end -}} diff --git a/deploy/kubernetes_v1.22/kubernetes/injector.yaml b/deploy/kubernetes_v1.22/kubernetes/injector.yaml index 98a25d29..d41d85e0 100644 --- a/deploy/kubernetes_v1.22/kubernetes/injector.yaml +++ b/deploy/kubernetes_v1.22/kubernetes/injector.yaml @@ -244,7 +244,7 @@ data: - name: CLUSTER_NAME value: {{.ProxyConfig.ProxyMetadata.clusterName}} - name: OPEN_DEMAND - value: {{.ProxyConfig.ProxyMetadata.opemDemand}} + value: {{.ProxyConfig.ProxyMetadata.openDemand}} volumeMounts: - mountPath: /var/lib/data name: envoy-bootstrap diff --git a/pkg/inject/pkg/config/mesh/mesh.go b/pkg/inject/pkg/config/mesh/mesh.go index aad730e4..519fd817 100644 --- a/pkg/inject/pkg/config/mesh/mesh.go +++ b/pkg/inject/pkg/config/mesh/mesh.go @@ -24,12 +24,12 @@ import ( // MeshEnvoyConfig mesh 注入配置, envoy sidecar当前有用到 type MeshEnvoyConfig struct { - DefaultConfig *DefaultConfig `yaml:"DefaultConfig"` + DefaultConfig *DefaultConfig `yaml:"defaultConfig"` } // DefaultConfig 存储北极星proxy默认配置和用户自定义配置 type DefaultConfig struct { - ProxyMetadata map[string]string `yaml:"ProxyMetadata"` + ProxyMetadata map[string]string `yaml:"proxyMetadata"` } // ReadMeshEnvoyConfig 读取mesh envoy sidecar注入配置 diff --git a/pkg/util/types.go b/pkg/util/types.go index a385d8ff..d1feac21 100644 --- a/pkg/util/types.go +++ b/pkg/util/types.go @@ -50,7 +50,7 @@ const ( // SidecarEnvoyMetadata SidecarEnvoyMetadata = "sidecar.polarismesh.cn/envoyMetadata" SidecarEnvoyInjectKey = "sidecar.polarismesh.cn/openOnDemand" - SidecarEnvoyInjectProxyKey = "OPEN_DEMAND" + SidecarEnvoyInjectProxyKey = "openDemand" PolarisSidecarModeLabel = "polaris-sidecar-mode"