diff --git a/Makefile b/Makefile index 848c0aea..810d86b7 100644 --- a/Makefile +++ b/Makefile @@ -1,68 +1,80 @@ -REGISTRY = "" -ORG = polarismesh +IMAGE_TAG ?= v2.1.0 +ORG ?= polarismesh REPO = polaris-controller SIDECAR_INIT_REPO = polaris-sidecar-init ENVOY_SIDECAR_INIT_REPO = polaris-envoy-bootstrap-generator -IMAGE_TAG = v1.7.3 PLATFORMS = linux/amd64,linux/arm64 .PHONY: all -all: fmt build-amd64 build-arm64 build-multi-arch-image \ - build-sidecar-init build-envoy-sidecar-init push-image +all: push-all-image + +.PHONY: push-all-image +push-all-image: push-controller-image push-init-image + +.PHONY: gen-all-image +gen-all-image: gen-controller-image gen-init-image + +.PHONY: clean +clean: + rm -rf bin + rm -rf polaris-controller-release* + +.PHONY: fmt +fmt: ## Run go fmt against code. + go fmt ./... .PHONY: build-amd64 -build-amd64: +build-amd64: clean fmt @echo "------------------" @echo "--> Building binary for polaris-controller (linux/amd64)" @echo "------------------" CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o ./bin/amd64/polaris-controller ./cmd/polaris-controller/main.go .PHONY: build-arm64 -build-arm64: +build-arm64: clean fmt @echo "------------------" @echo "--> Building binary for polaris-controller (linux/arm64)" @echo "------------------" CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -a -o ./bin/arm64/polaris-controller ./cmd/polaris-controller/main.go -.PHONY: build-multi-arch-image -build-multi-arch-image: +.PHONY: bin +bin: build-amd64 build-arm64 @echo "------------------" - @echo "--> Building multi-arch docker image for polaris-controller" + @echo "--> Building binary for polaris-controller" @echo "------------------" - @docker buildx build -f ./docker/Dockerfile --tag $(ORG)/$(REPO):$(IMAGE_TAG) --platform $(PLATFORMS) --push ./ - -.PHONY: build-sidecar-init -build-sidecar-init: - docker build ./sidecar/polaris-sidecar-init -f ./sidecar/polaris-sidecar-init/Dockerfile -t $(REGISTRY)$(ORG)/$(SIDECAR_INIT_REPO):$(IMAGE_TAG) -.PHONY: build-envoy-sidecar-init -build-envoy-sidecar-init: - docker build ./sidecar/envoy-bootstrap-config-generator -f ./sidecar/envoy-bootstrap-config-generator/Dockerfile -t $(REGISTRY)$(ORG)/$(ENVOY_SIDECAR_INIT_REPO):$(IMAGE_TAG) - -.PHONY: push-image -push-image: - docker push $(REGISTRY)$(ORG)/$(SIDECAR_INIT_REPO):$(IMAGE_TAG) - docker push $(REGISTRY)$(ORG)/$(ENVOY_SIDECAR_INIT_REPO):$(IMAGE_TAG) - -.PHONY: clean -clean: - rm -rf bin - rm -rf polaris-controller-release* +.PHONY: gen-controller-image +gen-controller-image: bin + @echo "------------------" + @echo "--> Generate multi-arch docker image to registry for polaris-controller" + @echo "------------------" + @docker buildx build ./ --file ./docker/Dockerfile --tag $(ORG)/$(REPO):$(IMAGE_TAG) --platform $(PLATFORMS) -.PHONY: fmt -fmt: ## Run go fmt against code. - go fmt ./... +.PHONY: push-controller-image +push-controller-image: bin + @echo "------------------" + @echo "--> Building and push multi-arch docker image for polaris-controller" + @echo "------------------" + @docker buildx build ./ --file ./docker/Dockerfile --tag $(ORG)/$(REPO):$(IMAGE_TAG) --platform $(PLATFORMS) --push -.PHONY: generate-multi-arch-image -generate-multi-arch-image: fmt build-amd64 build-arm64 +.PHONY: gen-init-image +gen-init-image: @echo "------------------" - @echo "--> Generate multi-arch docker image to registry for polaris-controller" + @echo "--> Building multi-arch docker image for polaris-sidecar-init" + @echo "------------------" + @docker buildx build ./sidecar/polaris-sidecar-init --file ./sidecar/polaris-sidecar-init/Dockerfile --tag $(ORG)/$(SIDECAR_INIT_REPO):$(IMAGE_TAG) --platform $(PLATFORMS) @echo "------------------" - @docker buildx build -f ./docker/Dockerfile --tag $(ORG)/$(REPO):$(IMAGE_TAG) --platform $(PLATFORMS) ./ + @echo "--> Building multi-arch docker image for envoy-bootstrap-config-generator" + @echo "------------------" + @docker buildx build ./sidecar/envoy-bootstrap-config-generator --file ./sidecar/envoy-bootstrap-config-generator/Dockerfile --tag $(ORG)/$(ENVOY_SIDECAR_INIT_REPO):$(IMAGE_TAG) --platform $(PLATFORMS) -.PHONY: push-multi-arch-image -push-multi-arch-image: generate-multi-arch-image +.PHONY: push-init-image +push-init-image: + @echo "------------------" + @echo "--> Building and push multi-arch docker image for polaris-sidecar-init" + @echo "------------------" + @docker buildx build ./sidecar/polaris-sidecar-init --file ./sidecar/polaris-sidecar-init/Dockerfile --tag $(ORG)/$(SIDECAR_INIT_REPO):$(IMAGE_TAG) --platform $(PLATFORMS) --push @echo "------------------" - @echo "--> Push multi-arch docker image to registry for polaris-controller" + @echo "--> Building and push multi-arch docker image for envoy-bootstrap-config-generator" @echo "------------------" - @docker image push $(ORG)/$(REPO):$(IMAGE_TAG) --platform $(PLATFORMS) \ No newline at end of file + @docker buildx build ./sidecar/envoy-bootstrap-config-generator --file ./sidecar/envoy-bootstrap-config-generator/Dockerfile --tag $(ORG)/$(ENVOY_SIDECAR_INIT_REPO):$(IMAGE_TAG) --platform $(PLATFORMS) --push diff --git a/deploy/kubernetes_v1.21/kubernetes/injector.yaml b/deploy/kubernetes_v1.21/kubernetes/injector.yaml index 9ead81f2..e54d9b68 100644 --- a/deploy/kubernetes_v1.21/kubernetes/injector.yaml +++ b/deploy/kubernetes_v1.21/kubernetes/injector.yaml @@ -22,7 +22,7 @@ metadata: app: sidecar-injector data: values: |- - {"clusterResources":true,"global":{"arch":{"amd64":2,"ppc64le":2,"s390x":2},"configNamespace":"polaris-system","configValidation":"false","controlPlaneSecurityEnabled":true,"defaultNodeSelector":{},"defaultPodDisruptionBudget":{"enabled":true},"defaultResources":{"requests":{"cpu":"10m"}},"disablePolicyChecks":true,"enableHelmTest":false,"enableTracing":true,"hub":"istio","imagePullPolicy":"Always","imagePullSecrets":[],"istioNamespace":"polaris-system","k8sIngress":{"enableHttps":false,"enabled":false,"gatewayName":"ingressgateway"},"localityLbSetting":{"enabled":true},"logAsJson":false,"logging":{"level":"default:info"},"meshExpansion":{"enabled":false,"useILB":false},"meshID":"","meshNetworks":{},"mtls":{"enabled":false},"multiCluster":{"enabled":false},"oneNamespace":false,"outboundTrafficPolicy":{"mode":"ALLOW_ANY"},"policyCheckFailOpen":false,"policyNamespace":"polaris-system","priorityClassName":"","prometheusNamespace":"polaris-system","proxy":{"accessLogEncoding":"TEXT","accessLogFile":"","accessLogFormat":"","autoInject":"enabled","clusterDomain":"cluster.local","componentLogLevel":"misc:error","concurrency":2,"dnsRefreshRate":"300s","enableCoreDump":false,"envoyAccessLogService":{"enabled":false,"host":null,"port":null},"envoyMetricsService":{"enabled":false,"host":null,"port":null},"envoyStatsd":{"enabled":false,"host":null,"port":null},"excludeIPRanges":"","excludeInboundPorts":"","excludeOutboundPorts":"","image":"proxyv2","includeIPRanges":"*","includeInboundPorts":"*","kubevirtInterfaces":"","logLevel":"warning","privileged":false,"protocolDetectionTimeout":"10ms","readinessFailureThreshold":30,"readinessInitialDelaySeconds":1,"readinessPeriodSeconds":2,"resources":{"limits":{"cpu":"2000m","memory":"1024Mi"},"requests":{"cpu":"100m","memory":"128Mi"}},"statusPort":15020,"tag":"1.7.0","tracer":"zipkin"},"proxy_init":{"image":"proxyv2","resources":{"limits":{"cpu":"100m","memory":"50Mi"},"requests":{"cpu":"10m","memory":"10Mi"}}},"sds":{"enabled":false,"udsPath":""},"tag":"1.5.8","telemetryNamespace":"polaris-system","tracer":{"datadog":{"address":"$(HOST_IP):8126"},"lightstep":{"accessToken":"","address":"","cacertPath":"","secure":true},"zipkin":{"address":""}},"trustDomain":"","useMCP":true,"xdsApiVersion":"v3"},"istio_cni":{"enabled":false},"sidecarInjectorWebhook":{"alwaysInjectSelector":[],"enableAccessLog":false,"enableNamespacesByDefault":false,"image":"sidecar_injector","injectLabel":"istio-injection","neverInjectSelector":[],"nodeSelector":{},"podAntiAffinityLabelSelector":[],"podAntiAffinityTermLabelSelector":[],"replicaCount":2,"rewriteAppHTTPProbe":false,"rollingMaxSurge":"100%","rollingMaxUnavailable":"25%","selfSigned":true,"tolerations":[]},"version":""} + {"clusterResources":true,"global":{"proxy":{"resources":{"limits":{"cpu":"2000m","memory":"1024Mi"},"requests":{"cpu":"100m","memory":"128Mi"}}}}} dns-config: |- policy: enabled @@ -52,11 +52,11 @@ data: imagePullPolicy: Always resources: limits: - cpu: 200m - memory: 200Mi + cpu: 500m + memory: 500Mi requests: - cpu: 100m - memory: 50Mi + cpu: 200m + memory: 300Mi volumeMounts: - mountPath: /root/polaris defaultMode: 777 @@ -150,21 +150,21 @@ data: - name: java-agent-dir emptyDir: {} - mesh-config: |+ + mesh-config: |- policy: enabled alwaysInjectSelector: [] - + neverInjectSelector: [{"matchLabels":{"polarismesh.cn/inject":"disabled"}}] - + template: |+ containers: - name: envoy image: envoyproxy/envoy:#ENVOY_VERSION# imagePullPolicy: Always command: ["/usr/local/bin/envoy"] - args: ["-c", "/etc/envoy/envoy.yaml", "--log-path", "/etc/envoy_logs/envoy.log", "--log-level", "debug"] + args: ["-c", "/etc/envoy/envoy.yaml", "--log-path", "/etc/envoy_logs/envoy.log"] resources: {{- if or (isset .ObjectMeta.Annotations `polarismesh.cn/proxyCPU`) (isset .ObjectMeta.Annotations `polarismesh.cn/proxyMemory`) (isset .ObjectMeta.Annotations `polarismesh.cn/proxyCPULimit`) (isset .ObjectMeta.Annotations `polarismesh.cn/proxyMemoryLimit`) }} {{- if or (isset .ObjectMeta.Annotations `polarismesh.cn/proxyCPU`) (isset .ObjectMeta.Annotations `polarismesh.cn/proxyMemory`) }} @@ -217,6 +217,12 @@ data: cpu: 100m memory: 50Mi volumeMounts: + - mountPath: /root/polaris + defaultMode: 777 + name: polaris-dir + - mountPath: /root/log + defaultMode: 777 + name: polaris-log - mountPath: /tmp/polaris-sidecar defaultMode: 777 name: polaris-socket diff --git a/deploy/kubernetes_v1.21/kubernetes/rbac.yaml b/deploy/kubernetes_v1.21/kubernetes/rbac.yaml index 30353200..6bf81e9b 100644 --- a/deploy/kubernetes_v1.21/kubernetes/rbac.yaml +++ b/deploy/kubernetes_v1.21/kubernetes/rbac.yaml @@ -26,6 +26,7 @@ rules: - events - configmaps - endpoints + - secrets verbs: - create - update diff --git a/deploy/kubernetes_v1.22/kubernetes/injector.yaml b/deploy/kubernetes_v1.22/kubernetes/injector.yaml index d41d85e0..8a57f165 100644 --- a/deploy/kubernetes_v1.22/kubernetes/injector.yaml +++ b/deploy/kubernetes_v1.22/kubernetes/injector.yaml @@ -7,7 +7,7 @@ metadata: app: sidecar-injector data: values: |- - {"clusterResources":true,"global":{"arch":{"amd64":2,"ppc64le":2,"s390x":2},"configNamespace":"polaris-system","configValidation":"false","controlPlaneSecurityEnabled":true,"defaultNodeSelector":{},"defaultPodDisruptionBudget":{"enabled":true},"defaultResources":{"requests":{"cpu":"10m"}},"disablePolicyChecks":true,"enableHelmTest":false,"enableTracing":true,"hub":"istio","imagePullPolicy":"Always","imagePullSecrets":[],"istioNamespace":"polaris-system","k8sIngress":{"enableHttps":false,"enabled":false,"gatewayName":"ingressgateway"},"localityLbSetting":{"enabled":true},"logAsJson":false,"logging":{"level":"default:info"},"meshExpansion":{"enabled":false,"useILB":false},"meshID":"","meshNetworks":{},"mtls":{"enabled":false},"multiCluster":{"enabled":false},"oneNamespace":false,"outboundTrafficPolicy":{"mode":"ALLOW_ANY"},"policyCheckFailOpen":false,"policyNamespace":"polaris-system","priorityClassName":"","prometheusNamespace":"polaris-system","proxy":{"accessLogEncoding":"TEXT","accessLogFile":"","accessLogFormat":"","autoInject":"enabled","clusterDomain":"cluster.local","componentLogLevel":"misc:error","concurrency":2,"dnsRefreshRate":"300s","enableCoreDump":false,"envoyAccessLogService":{"enabled":false,"host":null,"port":null},"envoyMetricsService":{"enabled":false,"host":null,"port":null},"envoyStatsd":{"enabled":false,"host":null,"port":null},"excludeIPRanges":"","excludeInboundPorts":"","excludeOutboundPorts":"","image":"proxyv2","includeIPRanges":"*","includeInboundPorts":"*","kubevirtInterfaces":"","logLevel":"warning","privileged":false,"protocolDetectionTimeout":"10ms","readinessFailureThreshold":30,"readinessInitialDelaySeconds":1,"readinessPeriodSeconds":2,"resources":{"limits":{"cpu":"2000m","memory":"1024Mi"},"requests":{"cpu":"100m","memory":"128Mi"}},"statusPort":15020,"tag":"1.7.0","tracer":"zipkin"},"proxy_init":{"image":"proxyv2","resources":{"limits":{"cpu":"100m","memory":"50Mi"},"requests":{"cpu":"10m","memory":"10Mi"}}},"sds":{"enabled":false,"udsPath":""},"tag":"1.5.8","telemetryNamespace":"polaris-system","tracer":{"datadog":{"address":"$(HOST_IP):8126"},"lightstep":{"accessToken":"","address":"","cacertPath":"","secure":true},"zipkin":{"address":""}},"trustDomain":"","useMCP":true,"xdsApiVersion":"v3"},"istio_cni":{"enabled":false},"sidecarInjectorWebhook":{"alwaysInjectSelector":[],"enableAccessLog":false,"enableNamespacesByDefault":false,"image":"sidecar_injector","injectLabel":"istio-injection","neverInjectSelector":[],"nodeSelector":{},"podAntiAffinityLabelSelector":[],"podAntiAffinityTermLabelSelector":[],"replicaCount":2,"rewriteAppHTTPProbe":false,"rollingMaxSurge":"100%","rollingMaxUnavailable":"25%","selfSigned":true,"tolerations":[]},"version":""} + {"clusterResources":true,"global":{"proxy":{"resources":{"limits":{"cpu":"2000m","memory":"1024Mi"},"requests":{"cpu":"100m","memory":"128Mi"}}}}} dns-config: |- policy: enabled @@ -37,11 +37,11 @@ data: imagePullPolicy: Always resources: limits: - cpu: 200m - memory: 200Mi + cpu: 500m + memory: 500Mi requests: - cpu: 100m - memory: 50Mi + cpu: 200m + memory: 300Mi volumeMounts: - mountPath: /root/polaris defaultMode: 777 @@ -135,7 +135,6 @@ data: - name: java-agent-dir emptyDir: {} - mesh-config: |- policy: enabled alwaysInjectSelector: @@ -212,6 +211,10 @@ data: - mountPath: /tmp/polaris-sidecar defaultMode: 777 name: polaris-socket + {{ if ( openTlsMode .ObjectMeta.Annotations `polarismesh.cn/tls-mode` ) }} + - name: root-ca + mountPath: /etc/polaris-sidecar/certs + {{ end }} initContainers: - name: polaris-bootstrap-writer image: polarismesh/polaris-envoy-bootstrap-generator:#CONTROLLER_VERSION# @@ -281,6 +284,16 @@ data: - mountPath: /data/polaris-client-config name: polaris-client-config volumes: + - name: sds + emptyDir: {} + {{ if ( openTlsMode .ObjectMeta.Annotations `polarismesh.cn/tls-mode` ) }} + - name: root-ca + secret: + secretName: polaris-sidecar-secret + items: + - key: root-cert + path: rootca.pem + {{ end }} - name: polaris-client-config emptyDir: {} - name: envoy-bootstrap diff --git a/deploy/kubernetes_v1.22/kubernetes/rbac.yaml b/deploy/kubernetes_v1.22/kubernetes/rbac.yaml index dc4cb819..5785df3d 100644 --- a/deploy/kubernetes_v1.22/kubernetes/rbac.yaml +++ b/deploy/kubernetes_v1.22/kubernetes/rbac.yaml @@ -26,6 +26,7 @@ rules: - events - configmaps - endpoints + - secrets verbs: - create - update diff --git a/pkg/inject/pkg/kube/inject/apply/mesh/patch.go b/pkg/inject/pkg/kube/inject/apply/mesh/patch.go index ba6db0e9..9a13ca12 100644 --- a/pkg/inject/pkg/kube/inject/apply/mesh/patch.go +++ b/pkg/inject/pkg/kube/inject/apply/mesh/patch.go @@ -83,32 +83,41 @@ func (pb *PodPatchBuilder) PatchContainer(req *inject.OperateContainerRequest) ( // handlePolarisSidecarEnvInject 处理polaris-sidecar容器的环境变量 func (pb *PodPatchBuilder) handlePolarisSidecarEnvInject(opt *inject.PatchOptions, pod *corev1.Pod, add *corev1.Container) (bool, error) { - + annotations := pod.Annotations err := pb.ensureRootCertExist(opt.KubeClient, pod) if err != nil { return false, err } envMap := make(map[string]string) + // 基础通用默认配置 + envMap[EnvSidecarNamespace] = pod.GetNamespace() + envMap[EnvPolarisAddress] = common.PolarisServerGrpcAddress envMap[EnvSidecarPort] = strconv.Itoa(ValueListenPort) envMap[EnvSidecarRecurseEnable] = strconv.FormatBool(true) + envMap[EnvSidecarLogLevel] = "info" if opt.SidecarMode == utils.SidecarForDns { + // dns mode envMap[EnvSidecarDnsEnable] = strconv.FormatBool(true) envMap[EnvSidecarMeshEnable] = strconv.FormatBool(false) - envMap[EnvSidecarMetricEnable] = strconv.FormatBool(false) - envMap[EnvSidecarMetricListenPort] = strconv.Itoa(ValueMetricListenPort) + envMap[EnvSidecarDnsRouteLabels] = buildLabelsStr(pod.Labels) + } else { + // mesh mode envMap[EnvSidecarDnsEnable] = strconv.FormatBool(false) envMap[EnvSidecarMeshEnable] = strconv.FormatBool(true) envMap[EnvSidecarRLSEnable] = strconv.FormatBool(true) envMap[EnvSidecarMetricEnable] = strconv.FormatBool(true) envMap[EnvSidecarMetricListenPort] = strconv.Itoa(ValueMetricListenPort) + if inject.EnableMtls(pod) { + envMap[EnvSidecarMtlsEnable] = strconv.FormatBool(true) + } } - envMap[EnvSidecarLogLevel] = "info" - envMap[EnvSidecarNamespace] = pod.GetNamespace() - envMap[EnvPolarisAddress] = common.PolarisServerGrpcAddress - envMap[EnvSidecarDnsRouteLabels] = buildLabelsStr(pod.Labels) - if inject.EnableMtls(pod) { - envMap[EnvSidecarMtlsEnable] = strconv.FormatBool(true) + if sidecarConfig, ok := annotations[utils.AnnotationKeySidecarConfig]; ok { + config, err := getSidecarConfig(sidecarConfig) + if err != nil { + return false, err + } + fillEnv(envMap, config, opt.SidecarMode) } log.InjectScope().Infof("pod=[%s, %s] inject polaris-sidecar mode %s, env map %v", pod.Namespace, pod.Name, utils.ParseSidecarModeName(opt.SidecarMode), envMap) diff --git a/pkg/inject/pkg/kube/inject/apply/mesh/sidecar.go b/pkg/inject/pkg/kube/inject/apply/mesh/sidecar.go new file mode 100644 index 00000000..d6bc4f13 --- /dev/null +++ b/pkg/inject/pkg/kube/inject/apply/mesh/sidecar.go @@ -0,0 +1,176 @@ +/** + * Tencent is pleased to support the open source community by making Polaris available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * Unless required by applicable law or agreed to in writing, software distributed + * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +package mesh + +import ( + "encoding/json" + "strconv" + + "github.com/polarismesh/polaris-controller/common/log" + utils "github.com/polarismesh/polaris-controller/pkg/util" +) + +const ( + EnvPolarisAddress = "POLARIS_ADDRESS" + EnvSidecarBind = "SIDECAR_BIND" + EnvSidecarPort = "SIDECAR_PORT" + EnvSidecarNamespace = "SIDECAR_NAMESPACE" + EnvSidecarRecurseEnable = "SIDECAR_RECURSE_ENABLE" + EnvSidecarRecurseTimeout = "SIDECAR_RECURSE_TIMEOUT" + EnvSidecarRegion = "SIDECAR_REGION" + EnvSidecarZone = "SIDECAR_ZONE" + EnvSidecarCampus = "SIDECAR_CAMPUS" + EnvSidecarNearbyMatchLevel = "SIDECAR_NEARBY_MATCH_LEVEL" + EnvSidecarLogRotateOutputPath = "SIDECAR_LOG_ROTATE_OUTPUT_PATH" + EnvSidecarLogErrorRotateOutputPath = "SIDECAR_LOG_ERROR_ROTATE_OUTPUT_PATH" + EnvSidecarLogRotationMaxSize = "SIDECAR_LOG_ROTATION_MAX_SIZE" + EnvSidecarLogRotationMaxBackups = "SIDECAR_LOG_ROTATION_MAX_BACKUPS" + EnvSidecarLogRotationMaxAge = "SIDECAR_LOG_ROTATION_MAX_AGE" + EnvSidecarLogLevel = "SIDECAR_LOG_LEVEL" + EnvSidecarDnsTtl = "SIDECAR_DNS_TTL" + EnvSidecarDnsEnable = "SIDECAR_DNS_ENABLE" + EnvSidecarDnsSuffix = "SIDECAR_DNS_SUFFIX" + EnvSidecarDnsRouteLabels = "SIDECAR_DNS_ROUTE_LABELS" + EnvSidecarMeshTtl = "SIDECAR_MESH_TTL" + EnvSidecarMeshEnable = "SIDECAR_MESH_ENABLE" + EnvSidecarMeshReloadInterval = "SIDECAR_MESH_RELOAD_INTERVAL" + EnvSidecarMeshAnswerIp = "SIDECAR_MESH_ANSWER_IP" + EnvSidecarMtlsEnable = "SIDECAR_MTLS_ENABLE" + EnvSidecarMtlsCAServer = "SIDECAR_MTLS_CA_SERVER" + EnvSidecarMetricEnable = "SIDECAR_METRIC_ENABLE" + EnvSidecarMetricListenPort = "SIDECAR_METRIC_LISTEN_PORT" + EnvSidecarRLSEnable = "SIDECAR_RLS_ENABLE" + + ValueListenPort = 15053 + ValueMetricListenPort = 15985 +) + +// SidecarConfig 定义了polaris-sidecar的配置 +type SidecarConfig struct { + Recurse *RecurseConfig `json:"recurse"` + Dns *DnsConfig `json:"dns"` + Location *Location `json:"location"` + LogOptions *LogOptions `json:"log"` +} + +// DnsConfig 定义了polaris-sidecar的dns配置 +type DnsConfig struct { + Suffix *string `json:"suffix"` + TTL *int `json:"ttl"` +} + +// RecurseConfig 定义了polaris-sidecar的递归配置 +type RecurseConfig struct { + Enabled *bool `json:"enabled"` + Timeout *int `json:"timeout"` +} + +// Location 定义了polaris-sidecar的部署位置 +type Location struct { + Region *string `json:"region"` + Zone *string `json:"zone"` + Campus *string `json:"campus"` + MatchLevel *string `json:"match_level"` +} + +type LogOptions struct { + OutputLevel *string `json:"output_level"` + RotationMaxSize *int `json:"rotation_max_size"` + RotationMaxAge *int `json:"rotation_max_age"` + RotationMaxBackups *int `json:"rotation_max_backups"` +} + +func getSidecarConfig(data string) (*SidecarConfig, error) { + config := SidecarConfig{} + err := json.Unmarshal([]byte(data), &config) + if err != nil { + log.InjectScope().Errorf("getSidecarConfig failed: %v, raw:%s", err, data) + return nil, err + } + log.InjectScope().Infof("getSidecarConfig: %s, raw:%s", utils.JsonString(config), data) + return &config, nil +} + +func fillEnv(envMap map[string]string, config *SidecarConfig, mode utils.SidecarMode) { + // dns config + if mode == utils.SidecarForDns && config.Dns != nil { + if config.Dns.Suffix != nil { + envMap[EnvSidecarDnsSuffix] = *config.Dns.Suffix + } + if config.Dns.TTL != nil && *config.Dns.TTL > 0 { + envMap[EnvSidecarDnsTtl] = strconv.Itoa(*config.Dns.TTL) + } + } + // recurse config + if config.Recurse != nil { + if config.Recurse.Enabled != nil && *config.Recurse.Enabled == false { + envMap[EnvSidecarRecurseEnable] = strconv.FormatBool(*config.Recurse.Enabled) + } + if config.Recurse.Timeout != nil && *config.Recurse.Timeout > 0 { + envMap[EnvSidecarRecurseTimeout] = strconv.Itoa(*config.Recurse.Timeout) + } + } + // location + if config.Location != nil { + if config.Location.Region != nil { + envMap[EnvSidecarRegion] = *config.Location.Region + } + if config.Location.Zone != nil { + envMap[EnvSidecarZone] = *config.Location.Zone + } + if config.Location.Campus != nil { + envMap[EnvSidecarCampus] = *config.Location.Campus + } + if config.Location.MatchLevel != nil { + if _, ok := stringToMatchLevel[*config.Location.MatchLevel]; ok { + envMap[EnvSidecarNearbyMatchLevel] = *config.Location.MatchLevel + } + } + } + // log + if config.LogOptions != nil { + if config.LogOptions.OutputLevel != nil && *config.LogOptions.OutputLevel != "" { + if _, ok := stringToLevel[*config.LogOptions.OutputLevel]; ok { + envMap[EnvSidecarLogLevel] = *config.LogOptions.OutputLevel + } + } + if config.LogOptions.RotationMaxSize != nil && *config.LogOptions.RotationMaxSize > 0 { + envMap[EnvSidecarLogRotationMaxSize] = strconv.Itoa(*config.LogOptions.RotationMaxSize) + } + if config.LogOptions.RotationMaxAge != nil && *config.LogOptions.RotationMaxAge > 0 { + envMap[EnvSidecarLogRotationMaxAge] = strconv.Itoa(*config.LogOptions.RotationMaxAge) + } + if config.LogOptions.RotationMaxBackups != nil && *config.LogOptions.RotationMaxBackups > 0 { + envMap[EnvSidecarLogRotationMaxBackups] = strconv.Itoa(*config.LogOptions.RotationMaxBackups) + } + } +} + +var stringToMatchLevel = map[string]bool{ + "region": true, + "zone": true, + "campus": true, +} + +var stringToLevel = map[string]bool{ + "debug": true, + "info": true, + "warn": true, + "error": true, + "fatal": true, +} diff --git a/pkg/inject/pkg/kube/inject/apply/mesh/sidecar_env.go b/pkg/inject/pkg/kube/inject/apply/mesh/sidecar_env.go deleted file mode 100644 index 4b6f379c..00000000 --- a/pkg/inject/pkg/kube/inject/apply/mesh/sidecar_env.go +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Tencent is pleased to support the open source community by making Polaris available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * Unless required by applicable law or agreed to in writing, software distributed - * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ - -package mesh - -const ( - EnvSidecarBind = "SIDECAR_BIND" - EnvSidecarPort = "SIDECAR_PORT" - EnvSidecarNamespace = "SIDECAR_NAMESPACE" - EnvSidecarRecurseEnable = "SIDECAR_RECURSE_ENABLE" - EnvSidecarRecurseTimeout = "SIDECAR_RECURSE_TIMEOUT" - EnvSidecarLogRotateOutputPath = "SIDECAR_LOG_ROTATE_OUTPUT_PATH" - EnvSidecarLogErrorRotateOutputPath = "SIDECAR_LOG_ERROR_ROTATE_OUTPUT_PATH" - EnvSidecarLogRotationMaxSize = "SIDECAR_LOG_ROTATION_MAX_SIZE" - EnvSidecarLogRotationMaxBackups = "SIDECAR_LOG_ROTATION_MAX_BACKUPS" - EnvSidecarLogRotationMaxAge = "SIDECAR_LOG_ROTATION_MAX_AGE" - EnvSidecarLogLevel = "SIDECAR_LOG_LEVEL" - EnvSidecarDnsTtl = "SIDECAR_DNS_TTL" - EnvSidecarDnsEnable = "SIDECAR_DNS_ENABLE" - EnvSidecarDnsSuffix = "SIDECAR_DNS_SUFFIX" - EnvSidecarDnsRouteLabels = "SIDECAR_DNS_ROUTE_LABELS" - EnvSidecarMeshTtl = "SIDECAR_MESH_TTL" - EnvSidecarMeshEnable = "SIDECAR_MESH_ENABLE" - EnvSidecarMeshReloadInterval = "SIDECAR_MESH_RELOAD_INTERVAL" - EnvSidecarMeshAnswerIp = "SIDECAR_MESH_ANSWER_IP" - EnvSidecarMtlsEnable = "SIDECAR_MTLS_ENABLE" - EnvSidecarMtlsCAServer = "SIDECAR_MTLS_CA_SERVER" - EnvPolarisAddress = "POLARIS_ADDRESS" - EnvSidecarMetricEnable = "SIDECAR_METRIC_ENABLE" - EnvSidecarMetricListenPort = "SIDECAR_METRIC_LISTEN_PORT" - EnvSidecarRLSEnable = "SIDECAR_RLS_ENABLE" - - ValueListenPort = 15053 - ValueMetricListenPort = 15985 -) diff --git a/pkg/inject/pkg/kube/inject/apply/mesh/sidecar_test.go b/pkg/inject/pkg/kube/inject/apply/mesh/sidecar_test.go new file mode 100644 index 00000000..4e233c35 --- /dev/null +++ b/pkg/inject/pkg/kube/inject/apply/mesh/sidecar_test.go @@ -0,0 +1,243 @@ +package mesh + +import ( + "reflect" + "testing" + + utils "github.com/polarismesh/polaris-controller/pkg/util" +) + +func TestGetSidecarConfig(t *testing.T) { + tests := []struct { + name string + input string + want *SidecarConfig + wantErr bool + }{ + { + name: "valid full config", + input: `{"dns":{"suffix":"cluster.local","ttl":30},"recurse":{"enabled":true,"timeout":500}}`, + want: &SidecarConfig{ + Dns: &DnsConfig{ + Suffix: stringPtr("cluster.local"), + TTL: intPtr(30), + }, + Recurse: &RecurseConfig{ + Enabled: boolPtr(true), + Timeout: intPtr(500), + }, + }, + wantErr: false, + }, + { + name: "partial config", + input: `{"dns":{"suffix":"local","ttl":10}}`, + want: &SidecarConfig{ + Dns: &DnsConfig{ + Suffix: stringPtr("local"), + TTL: intPtr(10), + }, + }, + wantErr: false, + }, + { + name: "empty string", + input: "", + want: nil, + wantErr: true, + }, + { + name: "invalid json", + input: `{"dns":{"suffix":"local","ttl":}}`, + want: nil, + wantErr: true, + }, + { + name: "empty json object", + input: `{}`, + want: &SidecarConfig{}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := getSidecarConfig(tt.input) + if (err != nil) != tt.wantErr { + t.Errorf("getSidecarConfig() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !compareSidecarConfig(got, tt.want) { + t.Errorf("getSidecarConfig() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestFillEnv(t *testing.T) { + tests := []struct { + name string + config *SidecarConfig + mode utils.SidecarMode + expected map[string]string + }{ + { + name: "TestLocationConfig", + config: &SidecarConfig{ + Location: &Location{ + Region: utils.StringPtr("ap-guangzhou"), + Zone: utils.StringPtr("zone-1"), + Campus: utils.StringPtr("campus-1"), + MatchLevel: utils.StringPtr("region"), + }, + }, + mode: utils.SidecarForDns, + expected: map[string]string{ + EnvSidecarRegion: "ap-guangzhou", + EnvSidecarZone: "zone-1", + EnvSidecarCampus: "campus-1", + EnvSidecarNearbyMatchLevel: "region", + }, + }, + { + name: "TestInvalidLogLevel", + config: &SidecarConfig{ + LogOptions: &LogOptions{ + OutputLevel: utils.StringPtr("invalid"), + }, + }, + mode: utils.SidecarForDns, + expected: map[string]string{}, + }, + { + name: "TestNonSidecarForDnsMode", + config: &SidecarConfig{ + Dns: &DnsConfig{ + Suffix: utils.StringPtr("cluster.local"), + TTL: utils.IntPtr(30), + }, + }, + mode: utils.SidecarForMesh, + expected: map[string]string{}, + }, + { + name: "TestRecurseConfigDisabled", + config: &SidecarConfig{ + Recurse: &RecurseConfig{ + Enabled: utils.BoolPtr(false), + Timeout: utils.IntPtr(500), + }, + }, + mode: utils.SidecarForDns, + expected: map[string]string{ + EnvSidecarRecurseEnable: "false", + EnvSidecarRecurseTimeout: "500", + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + envMap := make(map[string]string) + fillEnv(envMap, tt.config, tt.mode) + if !reflect.DeepEqual(envMap, tt.expected) { + t.Errorf("fillEnv() = %v, want %v", envMap, tt.expected) + } + }) + } +} + +// 辅助函数用于比较SidecarConfig +func compareSidecarConfig(a, b *SidecarConfig) bool { + if a == nil && b == nil { + return true + } + if a == nil || b == nil { + return false + } + return compareDnsConfig(a.Dns, b.Dns) && + compareRecurseConfig(a.Recurse, b.Recurse) && + compareLocation(a.Location, b.Location) && + compareLogOptions(a.LogOptions, b.LogOptions) +} + +func compareDnsConfig(a, b *DnsConfig) bool { + if a == nil && b == nil { + return true + } + if a == nil || b == nil { + return false + } + return equalStringPtr(a.Suffix, b.Suffix) && + equalIntPtr(a.TTL, b.TTL) +} + +func compareRecurseConfig(a, b *RecurseConfig) bool { + if a == nil && b == nil { + return true + } + if a == nil || b == nil { + return false + } + return equalBoolPtr(a.Enabled, b.Enabled) && + equalIntPtr(a.Timeout, b.Timeout) +} + +func compareLocation(a, b *Location) bool { + if a == nil && b == nil { + return true + } + if a == nil || b == nil { + return false + } + return equalStringPtr(a.Region, b.Region) && + equalStringPtr(a.Zone, b.Zone) && + equalStringPtr(a.Campus, b.Campus) +} + +func compareLogOptions(a, b *LogOptions) bool { + if a == nil && b == nil { + return true + } + if a == nil || b == nil { + return false + } + return equalStringPtr(a.OutputLevel, b.OutputLevel) && + equalIntPtr(a.RotationMaxSize, b.RotationMaxSize) && + equalIntPtr(a.RotationMaxAge, b.RotationMaxAge) && + equalIntPtr(a.RotationMaxBackups, b.RotationMaxBackups) +} + +func equalStringPtr(a, b *string) bool { + if a == nil && b == nil { + return true + } + if a == nil || b == nil { + return false + } + return *a == *b +} + +func equalIntPtr(a, b *int) bool { + if a == nil && b == nil { + return true + } + if a == nil || b == nil { + return false + } + return *a == *b +} + +func equalBoolPtr(a, b *bool) bool { + if a == nil && b == nil { + return true + } + if a == nil || b == nil { + return false + } + return *a == *b +} + +// 辅助函数用于创建指针值 +func stringPtr(s string) *string { return &s } +func intPtr(i int) *int { return &i } +func boolPtr(b bool) *bool { return &b } diff --git a/pkg/inject/pkg/kube/inject/base.go b/pkg/inject/pkg/kube/inject/base.go index d8e106de..501b9ab5 100644 --- a/pkg/inject/pkg/kube/inject/base.go +++ b/pkg/inject/pkg/kube/inject/base.go @@ -38,7 +38,7 @@ func (wh *Webhook) getPodPatch(p *podDataInfo) ([]byte, error) { sidecarTemplate := p.injectTemplateConfig.Template values := map[string]interface{}{} valuesConfig := wh.templateConfig.GetValuesConfig() - if err := yaml.Unmarshal([]byte(wh.templateConfig.GetValuesConfig()), &values); err != nil { + if err := yaml.Unmarshal([]byte(valuesConfig), &values); err != nil { log.InjectScope().Errorf("[Webhook] failed to parse values config: %v [%v]\n", err, valuesConfig) return nil, multierror.Prefix(err, "could not parse configuration values:") } diff --git a/pkg/util/common.go b/pkg/util/common.go index 7c5de651..5709abc2 100644 --- a/pkg/util/common.go +++ b/pkg/util/common.go @@ -15,6 +15,10 @@ package util +import ( + "encoding/json" +) + // IntPtr 类型转换 func IntPtr(v int) *int { return &v @@ -131,3 +135,12 @@ func Uint64(v uint64) *uint64 { func String(v string) *string { return &v } + +// JsonString returns a JSON string representation of the given value. +func JsonString(v interface{}) string { + b, err := json.Marshal(v) + if err != nil { + return "" + } + return string(b) +} diff --git a/pkg/util/types.go b/pkg/util/types.go index d1feac21..17f714f1 100644 --- a/pkg/util/types.go +++ b/pkg/util/types.go @@ -72,6 +72,9 @@ const ( AnnotationKeyJavaAgentPluginFramework = "polarismesh.cn/javaagentFrameworkName" AnnotationKeyJavaAgentPluginFrameworkVersion = "polarismesh.cn/javaagentFrameworkVersion" AnnotationKeyJavaAgentPluginConfig = "polarismesh.cn/javaagentConfig" + + // AnnotationKeySidecarConfig 注入模式为 sidecar 的标记 + AnnotationKeySidecarConfig = "polarismesh.cn/sidecarConfig" ) const ( diff --git a/sidecar/envoy-bootstrap-config-generator/Dockerfile b/sidecar/envoy-bootstrap-config-generator/Dockerfile index f61a0370..d13cb599 100644 --- a/sidecar/envoy-bootstrap-config-generator/Dockerfile +++ b/sidecar/envoy-bootstrap-config-generator/Dockerfile @@ -13,7 +13,9 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. -FROM alpine:3.8 +FROM alpine:3.22 + +ARG TARGETARCH RUN apk update upgrade && \ apk add --no-cache bash util-linux diff --git a/sidecar/polaris-sidecar-init/Dockerfile b/sidecar/polaris-sidecar-init/Dockerfile index 140214a3..44c4d471 100644 --- a/sidecar/polaris-sidecar-init/Dockerfile +++ b/sidecar/polaris-sidecar-init/Dockerfile @@ -13,7 +13,9 @@ # CONDITIONS OF ANY KIND, either express or implied. See the License for the # specific language governing permissions and limitations under the License. -FROM alpine:3.18.6 +FROM alpine:3.22 + +ARG TARGETARCH # Copy Startup Script COPY start.sh /start.sh diff --git a/version b/version index 0d687f1e..852700e1 100644 --- a/version +++ b/version @@ -1 +1 @@ -v1.7.3 \ No newline at end of file +v2.1.0 \ No newline at end of file