From b7e0a80ee990d480afa5ce65abc38feff70649bc Mon Sep 17 00:00:00 2001 From: dove0012 Date: Tue, 27 Jan 2026 11:31:13 +0800 Subject: [PATCH 01/17] =?UTF-8?q?=E6=B7=BB=E5=8A=A0istio=E7=AD=96=E7=95=A5?= =?UTF-8?q?=E4=B8=8B=E5=8F=91=E6=9C=8D=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 5 + .../controllers/service_controller.go | 269 ++++++++++++++++++ .../controllers/util.go | 157 ++++++++++ .../istio-policy-controller/etc/config.yaml | 24 ++ .../istio-policy-controller/go.mod | 120 ++++++++ .../internal/metric/metric.go | 75 +++++ .../internal/option/option.go | 46 +++ .../istio-policy-controller/main.go | 107 +++++++ .../pkg/config/config.go | 44 +++ .../pkg/config/types.go | 48 ++++ .../istio-policy-controller/Dockerfile | 14 + .../container-start.sh | 46 +++ 12 files changed, 955 insertions(+) create mode 100644 bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go create mode 100644 bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/util.go create mode 100644 bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/etc/config.yaml create mode 100644 bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/go.mod create mode 100644 bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/internal/metric/metric.go create mode 100644 bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/internal/option/option.go create mode 100644 bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/main.go create mode 100644 bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/pkg/config/config.go create mode 100644 bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/pkg/config/types.go create mode 100644 install/conf/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/Dockerfile create mode 100644 install/conf/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/container-start.sh diff --git a/Makefile b/Makefile index 7545ebffed..b973ecf02d 100644 --- a/Makefile +++ b/Makefile @@ -181,6 +181,11 @@ webhook-server:pre cp -R ${BCS_CONF_COMPONENT_PATH}/bcs-webhook-server ${PACKAGEPATH}/bcs-runtime/bcs-k8s/bcs-component cd ${BCS_COMPONENT_PATH}/bcs-webhook-server && go mod tidy && go build ${LDFLAG} -o ${WORKSPACE}/${PACKAGEPATH}/bcs-runtime/bcs-k8s/bcs-component/bcs-webhook-server/bcs-webhook-server ./cmd/server.go +istio-policy:pre + mkdir -p ${PACKAGEPATH}/bcs-runtime/bcs-k8s/bcs-component + cp -R ${BCS_CONF_COMPONENT_PATH}/istio-policy-controller ${PACKAGEPATH}/bcs-runtime/bcs-k8s/bcs-component + cd ${BCS_COMPONENT_PATH}/istio-policy-controller && go mod tidy && go build ${LDFLAG} -o ${WORKSPACE}/${PACKAGEPATH}/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/istio-policy-controller main.go + tools:pre tongsuo mkdir -p ${PACKAGEPATH}/bcs-services cd ${BCS_INSTALL_PATH}/cryptool && go mod tidy && $(CGO_BUILD_FLAGS) go build ${LDFLAG} -o ${WORKSPACE}/${PACKAGEPATH}/bcs-services/cryptools main.go diff --git a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go new file mode 100644 index 0000000000..a4fd37b9d5 --- /dev/null +++ b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go @@ -0,0 +1,269 @@ +/* + * Tencent is pleased to support the open source community by making Blueking Container Service available. + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * http://opensource.org/licenses/MIT + * 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 xxx +package controllers + +import ( + "context" + "fmt" + "time" + + "github.com/Tencent/bk-bcs/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/internal/option" + "github.com/Tencent/bk-bcs/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/pkg/config" + "github.com/go-logr/logr" + "istio.io/client-go/pkg/clientset/versioned" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + k8scorev1 "k8s.io/api/core/v1" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/event" + "sigs.k8s.io/controller-runtime/pkg/predicate" +) + +// ServiceReconciler reconciler for k8s svc +type ServiceReconciler struct { + // Client client for reconciler + client.Client + IstioClient *versioned.Clientset + Log logr.Logger + // Option option for controller + Option *option.ControllerOption +} + +func getServicePredicate() predicate.Predicate { + return predicate.Funcs{ + CreateFunc: func(e event.CreateEvent) bool { + svc, ok := e.Object.(*k8scorev1.Service) + if !ok { + return false + } + ctrl.Log.WithName("event").Info(fmt.Sprintf("Create event svc name: %s, namespace: %s", + svc.GetName(), svc.GetNamespace())) + return true + }, + UpdateFunc: func(e event.UpdateEvent) bool { + newSvc, newOk := e.ObjectNew.(*k8scorev1.Service) + oldSvc, oldOk := e.ObjectOld.(*k8scorev1.Service) + if !newOk || !oldOk { + return false + } + if newSvc.DeletionTimestamp != nil { + return true + } + + ctrl.Log.WithName("event").Info(fmt.Sprintf("Update event new svc name: %s, old svc name: %s, namespace: %s", + newSvc.GetName(), oldSvc.GetName(), newSvc.GetNamespace())) + return true + }, + DeleteFunc: func(e event.DeleteEvent) bool { + svc, ok := e.Object.(*k8scorev1.Service) + if !ok { + return false + } + + ctrl.Log.WithName("event").Info(fmt.Sprintf("Delete event svc name: %s, namespace: %s", + svc.GetName(), svc.GetNamespace())) + return true + }, + } +} + +// SetupWithManager set node reconciler +func (sr *ServiceReconciler) SetupWithManager(mgr ctrl.Manager) error { + err := ctrl.NewControllerManagedBy(mgr). + For(&k8scorev1.Service{}). + WithEventFilter(getServicePredicate()). + Complete(sr) + if err != nil { + return err + } + + // 开启一个线程,遍历所有svc + go sr.updateExistSvcs() + + return nil +} + +// Reconcile reconcile k8s node info +func (sr *ServiceReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + // 尝试获取 Service 对象 + var svc corev1.Service + if err := sr.Get(ctx, req.NamespacedName, &svc); err != nil { + // 如果 err 是 NotFound,说明是删除事件 + if client.IgnoreNotFound(err) != nil { + sr.Log.Error(err, "unable to fetch Service") + return ctrl.Result{}, err + } + + sr.Log.Info(fmt.Sprintf("Service deleted, name: %s, namespace: %s", req.Name, req.Namespace)) + // 在这里处理删除逻辑 + err = sr.deletePolicy(ctx, req.Namespace, req.Name) + if err != nil { + return ctrl.Result{}, err + } + + return ctrl.Result{}, nil + } + + // 如果走到这里,说明是创建或更新 + sr.Log.Info(fmt.Sprintf("Service created or updated, name: %s, namespace: %s", req.Name, req.Namespace)) + // 在这里添加你的业务逻辑 + err := sr.createOrUpdatePolicy(req.Namespace, req.Name) + if err != nil { + return ctrl.Result{}, err + } + + return ctrl.Result{}, nil +} + +func (sr *ServiceReconciler) createOrUpdatePolicy(namespace, name string) error { + dr, err := sr.IstioClient.NetworkingV1().DestinationRules(namespace).Get(context.Background(), + name, metav1.GetOptions{}) + if err != nil { + if client.IgnoreNotFound(err) != nil { + sr.Log.Error(err, "failed to get DestinationRule") + return err + } + + // 创建 DestinationRule 的逻辑 + sr.Log.Info("Creating DestinationRule", "name", name, "namespace", namespace) + err = sr.createDr(context.Background(), namespace, name) + if err != nil { + return err + } + } + + _, err = sr.IstioClient.NetworkingV1().VirtualServices(namespace).Get(context.Background(), + name, metav1.GetOptions{}) + if err != nil { + if client.IgnoreNotFound(err) != nil { + sr.Log.Error(err, "failed to get VirtualServices") + return err + } + + // 创建 VirtualServices 的逻辑 + sr.Log.Info("Creating VirtualServices", "name", name, "namespace", namespace) + err = sr.createVs(context.Background(), namespace, name) + if err != nil { + return err + } + } + + // 更新 DestinationRule 的逻辑 + sr.Log.Info("Updating DestinationRule", "name", name, "namespace", namespace) + for _, svc := range config.G.Services { + if svc.Name == name && svc.Namespace == namespace { + if svc.Setting.MergeMode == MergeModeMerge { + if svc.TrafficPolicy != nil { + if svc.TrafficPolicy.LoadBalancer != nil { + dr.Spec.TrafficPolicy.LoadBalancer = svc.TrafficPolicy.LoadBalancer + } + if svc.TrafficPolicy.ConnectionPool != nil { + dr.Spec.TrafficPolicy.ConnectionPool = svc.TrafficPolicy.ConnectionPool + } + if svc.TrafficPolicy.OutlierDetection != nil { + dr.Spec.TrafficPolicy.OutlierDetection = svc.TrafficPolicy.OutlierDetection + } + if svc.TrafficPolicy.Tls != nil { + dr.Spec.TrafficPolicy.Tls = svc.TrafficPolicy.Tls + } + if svc.TrafficPolicy.PortLevelSettings != nil { + dr.Spec.TrafficPolicy.PortLevelSettings = svc.TrafficPolicy.PortLevelSettings + } + if svc.TrafficPolicy.Tunnel != nil { + dr.Spec.TrafficPolicy.Tunnel = svc.TrafficPolicy.Tunnel + } + if svc.TrafficPolicy.ProxyProtocol != nil { + dr.Spec.TrafficPolicy.ProxyProtocol = svc.TrafficPolicy.ProxyProtocol + } + // if svc.TrafficPolicy.RetryBudget != nil { + // dr.Spec.TrafficPolicy.RetryBudget = svc.TrafficPolicy.RetryBudget + // } + } + } else { + dr.Spec.TrafficPolicy = svc.TrafficPolicy + } + } + } + + _, err = sr.IstioClient.NetworkingV1().DestinationRules(dr.Namespace). + Update(context.Background(), dr, metav1.UpdateOptions{}) + + return err +} + +func (sr *ServiceReconciler) deletePolicy(ctx context.Context, namespace, name string) error { + dr, err := sr.IstioClient.NetworkingV1().DestinationRules(namespace).Get(ctx, name, metav1.GetOptions{}) + if err != nil { + if client.IgnoreNotFound(err) != nil { + sr.Log.Error(err, "failed to get DestinationRule") + } + } + + vs, err := sr.IstioClient.NetworkingV1().VirtualServices(namespace).Get(ctx, name, metav1.GetOptions{}) + if err != nil { + if client.IgnoreNotFound(err) != nil { + sr.Log.Error(err, "failed to get VirtualService") + } + } + + for _, svc := range config.G.Services { + if svc.Name == name && svc.Namespace == namespace && svc.Setting.DeletePolicyOnServiceDelete { + return sr.deleteDrAndVs(ctx, dr, vs) + } + } + + if config.G.Global.Setting.DeletePolicyOnServiceDelete { + return sr.deleteDrAndVs(ctx, dr, vs) + } + + return nil +} + +// updateExistSvcs update exist services +func (sr *ServiceReconciler) updateExistSvcs() { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) + defer cancel() + + ticker := time.NewTicker(10 * time.Second) + defer ticker.Stop() + + for { + select { + case <-ctx.Done(): + return + case <-ticker.C: + svcList := &corev1.ServiceList{} + if err := sr.Client.List(context.Background(), svcList); err != nil { + sr.Log.Error(err, "failed to list services") + continue + } + // 处理逻辑 + + for _, svc := range svcList.Items { + // 处理每个 Service + sr.Log.Info("Found service", "namespace", svc.Namespace, "name", svc.Name) + // 你的业务逻辑... + err := sr.createOrUpdatePolicy(svc.Namespace, svc.Name) + if err != nil { + sr.Log.Error(err, "failed to create or update policy", + "namespace", svc.Namespace, "name", svc.Name) + continue + } + } + + return + } + } +} diff --git a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/util.go b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/util.go new file mode 100644 index 0000000000..4e0a834d53 --- /dev/null +++ b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/util.go @@ -0,0 +1,157 @@ +/* + * Tencent is pleased to support the open source community by making Blueking Container Service available. + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * http://opensource.org/licenses/MIT + * 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 controllers + +import ( + "context" + "fmt" + "strings" + + "github.com/Tencent/bk-bcs/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/pkg/config" + "istio.io/api/networking/v1alpha3" + networkingv1 "istio.io/client-go/pkg/apis/networking/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + LabelKey = "managed-by" + LabelValue = "istio-policy-controller" + + MergeModeMerge = "merge" + MergeModeOverride = "override" +) + +func (sr *ServiceReconciler) createDr(ctx context.Context, namespace, name string) error { + dr := &networkingv1.DestinationRule{ + TypeMeta: metav1.TypeMeta{ + Kind: "DestinationRule", + APIVersion: "networking.istio.io/v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Spec: v1alpha3.DestinationRule{ + Host: fmt.Sprintf("%s.%s.svc.cluster.local", name, namespace), + TrafficPolicy: &v1alpha3.TrafficPolicy{}, + }, + } + + var tp *v1alpha3.TrafficPolicy + for _, svc := range config.G.Services { + if svc.Name == name && svc.Namespace == namespace { + tp = svc.TrafficPolicy + } + } + + if tp == nil { + tp = config.G.Global.TrafficPolicy + } + + _, err := sr.IstioClient.NetworkingV1().DestinationRules(namespace). + Create(context.Background(), dr, metav1.CreateOptions{}) + if err != nil { + return err + } + + return nil +} + +func (sr *ServiceReconciler) createVs(ctx context.Context, namespace, name string) error { + vs := &networkingv1.VirtualService{ + TypeMeta: metav1.TypeMeta{ + Kind: "VirtualService", + APIVersion: "networking.istio.io/v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Spec: v1alpha3.VirtualService{ + Hosts: []string{fmt.Sprintf("%s.%s.svc.cluster.local", name, namespace)}, + Http: []*v1alpha3.HTTPRoute{ + { + Route: []*v1alpha3.HTTPRouteDestination{ + { + Destination: &v1alpha3.Destination{ + Host: fmt.Sprintf("%s.%s.svc.cluster.local", name, namespace), + }, + }, + }, + }, + }, + }, + } + + for _, svc := range config.G.Services { + if svc.Name == name && svc.Namespace == namespace { + if svc.Setting.AutoGenerateVS { + _, err := sr.IstioClient.NetworkingV1().VirtualServices(namespace). + Create(context.Background(), vs, metav1.CreateOptions{}) + if err != nil { + return err + } + } + } + } + + if config.G.Global.Setting.AutoGenerateVS { + _, err := sr.IstioClient.NetworkingV1().VirtualServices(namespace). + Create(context.Background(), vs, metav1.CreateOptions{}) + if err != nil { + return err + } + } + + return nil +} + +func (sr *ServiceReconciler) deleteDrAndVs(ctx context.Context, dr *networkingv1.DestinationRule, + vs *networkingv1.VirtualService) error { + + var drErr, vsErr error + if dr != nil { + if v, ok := dr.GetLabels()[LabelKey]; ok && v == LabelValue { + drErr = sr.IstioClient.NetworkingV1().DestinationRules(dr.Namespace).Delete(ctx, + dr.Name, metav1.DeleteOptions{}) + if drErr != nil { + sr.Log.Error(drErr, "failed to delete DestinationRule") + } + } + } + + if vs != nil { + if v, ok := vs.GetLabels()[LabelKey]; ok && v == LabelValue { + vsErr = sr.IstioClient.NetworkingV1().VirtualServices(vs.Namespace).Delete(ctx, + vs.Name, metav1.DeleteOptions{}) + if vsErr != nil { + sr.Log.Error(vsErr, "failed to delete VirtualService") + return vsErr + } + } + } + + if drErr != nil || vsErr != nil { + errs := make([]string, 0) + if drErr != nil { + errs = append(errs, drErr.Error()) + } + if vsErr != nil { + errs = append(errs, vsErr.Error()) + } + + return fmt.Errorf(strings.Join(errs, ";")) + } + + return nil +} diff --git a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/etc/config.yaml b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/etc/config.yaml new file mode 100644 index 0000000000..d3094dc099 --- /dev/null +++ b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/etc/config.yaml @@ -0,0 +1,24 @@ +global: + trafficPolicy: + connectionPool: {} + loadBalancer: + simple: RANDOM + localityLbSetting: + enabled: true + failover: + - from: sh + to: nj + setting: + mergeMode: merge + deletePolicyOnServiceDelete: true + updateUnmanagedResources: true +services: + - name: my-svc + namespace: bcs-system + trafficPolicy: + loadBalancer: + simple: RANDOM + setting: + mergeMode: override + deletePolicyOnServiceDelete: true + updateUnmanagedResources: true diff --git a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/go.mod b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/go.mod new file mode 100644 index 0000000000..b8691545f5 --- /dev/null +++ b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/go.mod @@ -0,0 +1,120 @@ +module github.com/Tencent/bk-bcs/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller + +go 1.23.0 + +replace ( + bitbucket.org/ww/goautoneg => github.com/adjust/goautoneg v0.0.0-20150426214442-d788f35a0315 + github.com/Tencent/bk-bcs/bcs-runtime/bcs-k8s/kubernetes/common => github.com/Tencent/bk-bcs/bcs-runtime/bcs-k8s/kubernetes/common v0.0.0-20220117082205-1fdc9e155811 + github.com/Tencent/bk-bcs/bcs-scenarios/kourse => github.com/TencentBlueKing/bk-bcs/bcs-scenarios/kourse v0.0.0-20230620070606-922d3a7a9517 + github.com/coreos/bbolt v1.3.4 => go.etcd.io/bbolt v1.3.4 + github.com/mholt/caddy => github.com/caddyserver/caddy v0.11.1 + go.etcd.io/bbolt v1.3.4 => github.com/coreos/bbolt v1.3.4 + google.golang.org/grpc => google.golang.org/grpc v1.26.0 + k8s.io/api => k8s.io/api v0.26.15 + k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.20.0 + k8s.io/apimachinery => k8s.io/apimachinery v0.26.15 + k8s.io/apiserver => k8s.io/apiserver v0.20.0 + k8s.io/cli-runtime => k8s.io/cli-runtime v0.20.0 + k8s.io/client-go => k8s.io/client-go v0.26.15 + k8s.io/cloud-provider => k8s.io/cloud-provider v0.20.0 + k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.20.0 + k8s.io/code-generator => k8s.io/code-generator v0.20.0 + k8s.io/component-base => k8s.io/component-base v0.20.0 + k8s.io/component-helpers => k8s.io/component-helpers v0.20.0 + k8s.io/controller-manager => k8s.io/controller-manager v0.20.0 + k8s.io/cri-api => k8s.io/cri-api v0.20.0 + k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.20.0 + k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.20.0 + k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.20.0 + k8s.io/kube-openapi => k8s.io/kube-openapi v0.0.0-20220603121420-31174f50af60 + k8s.io/kube-proxy => k8s.io/kube-proxy v0.20.0 + k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.20.0 + k8s.io/kubectl => k8s.io/kubectl v0.20.0 + k8s.io/kubelet => k8s.io/kubelet v0.20.0 + k8s.io/kubernetes => k8s.io/kubernetes v1.20.0 + k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.20.0 + k8s.io/metrics => k8s.io/metrics v0.20.0 + k8s.io/mount-utils => k8s.io/mount-utils v0.20.0 + k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.20.0 +) + +require ( + github.com/Tencent/bk-bcs/bcs-common v0.0.0-20230707084844-155f32c8f606 + github.com/prometheus/client_golang v1.16.0 + k8s.io/api v0.32.1 + k8s.io/apiextensions-apiserver v0.26.10 // indirect + k8s.io/apimachinery v0.32.1 + k8s.io/client-go v0.32.1 +) + +require github.com/pkg/errors v0.9.1 // indirect + +require ( + k8s.io/klog/v2 v2.130.1 // indirect + k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect +) + +require ( + github.com/go-logr/logr v1.4.2 + istio.io/api v1.28.2-0.20251205082437-fde1452f70bc + istio.io/client-go v1.28.3 +) + +require ( + github.com/beorn7/perks v1.0.1 // indirect + github.com/bitly/go-simplejson v0.5.0 // indirect + github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/google/go-cmp v0.6.0 // indirect + github.com/google/gofuzz v1.2.0 // indirect + github.com/imdario/mergo v0.3.13 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/prometheus/client_model v0.4.0 // indirect + github.com/prometheus/common v0.44.0 // indirect + github.com/prometheus/procfs v0.10.1 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/ugorji/go/codec v1.2.11 // indirect + golang.org/x/net v0.43.0 // indirect + golang.org/x/oauth2 v0.23.0 // indirect + golang.org/x/sys v0.35.0 // indirect + golang.org/x/term v0.34.0 // indirect + golang.org/x/text v0.28.0 // indirect + golang.org/x/time v0.7.0 // indirect + google.golang.org/protobuf v1.36.7 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f // indirect + sigs.k8s.io/controller-runtime v0.14.7 + sigs.k8s.io/structured-merge-diff/v4 v4.7.0 // indirect + sigs.k8s.io/yaml v1.4.0 +) + +require ( + github.com/emicklei/go-restful/v3 v3.11.0 // indirect + github.com/evanphx/json-patch/v5 v5.6.0 // indirect + github.com/go-logr/zapr v1.2.3 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect + github.com/go-openapi/jsonreference v0.20.2 // indirect + github.com/go-openapi/swag v0.23.0 // indirect + github.com/google/gnostic v0.5.7-v3refs // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + go.uber.org/atomic v1.10.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.24.0 // indirect + gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250811230008-5f3141c8851a // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + k8s.io/component-base v0.26.10 // indirect + sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect +) diff --git a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/internal/metric/metric.go b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/internal/metric/metric.go new file mode 100644 index 0000000000..813cb142d0 --- /dev/null +++ b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/internal/metric/metric.go @@ -0,0 +1,75 @@ +/* + * Tencent is pleased to support the open source community by making Blueking Container Service available. + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * http://opensource.org/licenses/MIT + * 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 metric + +import ( + "strconv" + "time" + + "github.com/prometheus/client_golang/prometheus" + "sigs.k8s.io/controller-runtime/pkg/metrics" +) + +var ( + // RequestResultSuccess request successfully + RequestResultSuccess = "ok" + // RequestResultFailed request return error + RequestResultFailed = "failed" + // RequestResultPartialFailed partial failed result + RequestResultPartialFailed = "partialfailed" +) + +// declare metrics +var ( + cliReqCounter = prometheus.NewCounterVec( + prometheus.CounterOpts{ + Namespace: "bcs_network", + Subsystem: "cloudnetcontroller", + Name: "cli_request_total", + Help: "total request counter as client", + }, + []string{"module", "rpc", "errcode", "result"}, + ) + cliRespSummary = prometheus.NewSummaryVec( + prometheus.SummaryOpts{ + Namespace: "bcs_network", + Subsystem: "cloudnetcontroller", + Name: "cli_response_time", + Help: "response time(ms) of other module summary.", + }, + []string{"module", "rpc"}, + ) +) + +func init() { + metrics.Registry.MustRegister(cliReqCounter) + metrics.Registry.MustRegister(cliRespSummary) +} + +// StatClientRequest report client request metrics +func StatClientRequest(module, rpc string, respCode int, result string, inTime, outTime time.Time) { + cliReqCounter.With(prometheus.Labels{ + "module": module, + "rpc": rpc, + "errcode": strconv.Itoa(respCode), + "result": result, + }).Inc() + + cost := toMSTimestamp(outTime) - toMSTimestamp(inTime) + cliRespSummary.With(prometheus.Labels{"module": module, "rpc": rpc}).Observe(float64(cost)) +} + +// toMSTimestamp converts time.Time to millisecond timestamp. +func toMSTimestamp(t time.Time) int64 { + return t.UnixNano() / 1e6 +} diff --git a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/internal/option/option.go b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/internal/option/option.go new file mode 100644 index 0000000000..62d0fd0946 --- /dev/null +++ b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/internal/option/option.go @@ -0,0 +1,46 @@ +/* + * Tencent is pleased to support the open source community by making Blueking Container Service available. + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * http://opensource.org/licenses/MIT + * 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 option + +import ( + "github.com/Tencent/bk-bcs/bcs-common/common/conf" +) + +// ControllerOption controller option +type ControllerOption struct { + // Address address for server + Address string + + // Port port for server + Port int + + // MetricPort port for metric server + MetricPort int + + // CloudMod + Cloud string + + // Cluster cluster id for bcs + Cluster string + + // CloudNetServiceEndpoints + CloudNetServiceEndpoints []string + + // IPCleanCheckMinute check interval for unused fixed ip + IPCleanCheckMinute int + + // IPCleanMaxReservedMinute max reserved time for unused fixed ip + IPCleanMaxReservedMinute int + + conf.LogConfig +} diff --git a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/main.go b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/main.go new file mode 100644 index 0000000000..96f2566ae9 --- /dev/null +++ b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/main.go @@ -0,0 +1,107 @@ +/* + * Tencent is pleased to support the open source community by making Blueking Container Service available. + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * http://opensource.org/licenses/MIT + * 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 xxx +package main + +import ( + "flag" + "os" + "strconv" + + "github.com/Tencent/bk-bcs/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers" + "github.com/Tencent/bk-bcs/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/internal/option" + "github.com/Tencent/bk-bcs/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/pkg/config" + networkingv1 "istio.io/client-go/pkg/apis/networking/v1" + "istio.io/client-go/pkg/clientset/versioned" + + "k8s.io/apimachinery/pkg/runtime" + _ "k8s.io/client-go/plugin/pkg/client/auth/gcp" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +var ( + scheme = runtime.NewScheme() + setupLog = ctrl.Log.WithName("setup") + Config string +) + +func main() { + opts := &option.ControllerOption{} + + flag.StringVar(&opts.Address, "address", "127.0.0.1", "address for controller") + flag.IntVar(&opts.MetricPort, "metric_port", 8081, "metric port for controller") + flag.StringVar(&opts.LogDir, "log_dir", "./logs", "If non-empty, write log files in this directory") + flag.Uint64Var(&opts.LogMaxSize, "log_max_size", 500, "Max size (MB) per log file.") + flag.IntVar(&opts.LogMaxNum, "log_max_num", 10, "Max num of log file.") + flag.BoolVar(&opts.ToStdErr, "logtostderr", false, "log to standard error instead of files") + flag.StringVar(&Config, "config", "./etc/config.yaml", "config file path") + + flag.Parse() + + ctrl.SetLogger(zap.New(zap.UseDevMode(true))) + + setupLog.Info("starting init config") + // 初始化配置 + err := config.Init(Config) + if err != nil { + setupLog.Error(err, "unable to init config") + os.Exit(1) + } + + cfg, err := ctrl.GetConfig() + if err != nil { + setupLog.Error(err, "unable to get kubeconfig") + os.Exit(1) + } + + // 创建 Istio client + istioClient, err := versioned.NewForConfig(cfg) + if err != nil { + setupLog.Error(err, "unable to create Istio client") + os.Exit(1) + } + + mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ + Scheme: scheme, + MetricsBindAddress: opts.Address + ":" + strconv.Itoa(opts.MetricPort), + LeaderElection: true, + LeaderElectionID: "333fb49e.istioconroller.bkbcs.tencent.com", + LeaderElectionNamespace: "default", + }) + if err != nil { + setupLog.Error(err, "unable to start manager") + os.Exit(1) // nolint + } + + // 注册 Istio networking v1 类型 + if err = networkingv1.AddToScheme(mgr.GetScheme()); err != nil { + setupLog.Error(err, "unable to add Istio networking v1 to scheme") + os.Exit(1) + } + + if err = (&controllers.ServiceReconciler{ + Client: mgr.GetClient(), + Log: ctrl.Log.WithName("controllers").WithName("service"), + Option: opts, + IstioClient: istioClient, + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create k8s Service controller", "controller", "Service") + os.Exit(1) + } + + setupLog.Info("starting manager") + if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil { + setupLog.Error(err, "problem running manager") + os.Exit(1) + } +} diff --git a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/pkg/config/config.go b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/pkg/config/config.go new file mode 100644 index 0000000000..32a70f8b93 --- /dev/null +++ b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/pkg/config/config.go @@ -0,0 +1,44 @@ +/* + * Tencent is pleased to support the open source community by making Blueking Container Service available. + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * http://opensource.org/licenses/MIT + * 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 xxx +package config + +import ( + "fmt" + "os" + + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/yaml" +) + +// G is the global configuration +var G = &Configuration{} + +// Init init config +func Init(name string) error { + if name == "" { + return fmt.Errorf("config file name is empty") + } + + content, err := os.ReadFile(name) + if err != nil { + return err + } + + ctrl.Log.WithName("config").Info(fmt.Sprintf("config content: %s", string(content))) + + if err := yaml.Unmarshal(content, G); err != nil { + return err + } + + return nil +} diff --git a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/pkg/config/types.go b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/pkg/config/types.go new file mode 100644 index 0000000000..2725737d79 --- /dev/null +++ b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/pkg/config/types.go @@ -0,0 +1,48 @@ +/* + * Tencent is pleased to support the open source community by making Blueking Container Service available. + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * http://opensource.org/licenses/MIT + * 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 xxx +package config + +import ( + "istio.io/api/networking/v1alpha3" +) + +// ConnectionPoolSettings_HTTPSettings_H2UpgradePolicy Policy for upgrading http1.1 connections to http2. +type ConnectionPoolSettings_HTTPSettings_H2UpgradePolicy int32 + +// Configuration 是整个 YAML 配置的根结构 +type Configuration struct { + Global Global + Services []Service +} + +// Global 对应 global 字段 +type Global struct { + TrafficPolicy *v1alpha3.TrafficPolicy + Setting Setting +} + +// Service 单个服务的配置 +type Service struct { + Name string + Namespace string + TrafficPolicy *v1alpha3.TrafficPolicy + Setting Setting +} + +// Setting 全局设置 +type Setting struct { + MergeMode string // e.g., "merge" + DeletePolicyOnServiceDelete bool + AutoGenerateVS bool + UpdateUnmanagedResources bool +} diff --git a/install/conf/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/Dockerfile b/install/conf/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/Dockerfile new file mode 100644 index 0000000000..035cc95899 --- /dev/null +++ b/install/conf/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/Dockerfile @@ -0,0 +1,14 @@ +FROM tencentos/tencentos4-minimal + +#for command envsubst +RUN yum install -y gettext + +RUN mkdir -p /data/bcs/logs/bcs /data/bcs/cert +RUN mkdir -p /data/bcs/istio-policy-controller + +ADD istio-policy-controller /data/bcs/istio-policy-controller/ +ADD container-start.sh /data/bcs/istio-policy-controller/ +RUN chmod +x /data/bcs/istio-policy-controller/container-start.sh + +WORKDIR /data/bcs/istio-policy-controller/ +CMD ["/data/bcs/istio-policy-controller/container-start.sh"] diff --git a/install/conf/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/container-start.sh b/install/conf/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/container-start.sh new file mode 100644 index 0000000000..9f99bda23c --- /dev/null +++ b/install/conf/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/container-start.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +module="istio-policy-controller" + +cd /data/bcs/${module} +chmod +x ${module} + +#check configuration render +if [[ $BCS_CONFIG_TYPE == "render" ]]; then + cat ${module}.json.template | envsubst | tee ${module}.json +fi + +#ready to start +exec /data/bcs/${module}/${module} $@ + +# Usage of ./istio-policy-controller: +# -address string +# address for controller (default "127.0.0.1") +# -alsologtostderr +# log to standard error as well as files +# -cloud string +# cloud mode for bcs network controller (default "tencentcloud") +# -kubeconfig string +# Paths to a kubeconfig. Only required if out-of-cluster. +# -log_backtrace_at string +# when logging hits line file:N, emit a stack trace +# -log_dir string +# If non-empty, write log files in this directory (default "./logs") +# -log_max_num int +# Max num of log file. (default 10) +# -log_max_size uint +# Max size (MB) per log file. (default 500) +# -logtostderr +# log to standard error instead of files +# -master --kubeconfig +# (Deprecated: switch to --kubeconfig) The address of the Kubernetes API server. Overrides any value in kubeconfig. Only required if out-of-cluster. +# -metric_port int +# metric port for controller (default 8081) +# -port int +# por for controller (default 8080) +# -stderrthreshold string +# logs at or above this threshold go to stderr (default "2") +# -v int +# log level for V logs +# -vmodule string +# comma-separated list of pattern=N settings for file-filtered logging \ No newline at end of file From abc68bd624696beeda65f2f6ca10755d3e7f5dee Mon Sep 17 00:00:00 2001 From: dove0012 Date: Wed, 28 Jan 2026 09:20:17 +0800 Subject: [PATCH 02/17] =?UTF-8?q?=E4=BF=AE=E5=A4=8Ddr=E7=AD=96=E7=95=A5?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E3=80=81=E6=9B=B4=E6=96=B0=E5=92=8C=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E7=9A=84=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controllers/service_controller.go | 209 ++++++++++++--- .../controllers/util.go | 239 ++++++++++-------- .../istio-policy-controller/go.mod | 1 + .../istio-policy-controller/main.go | 7 + .../pkg/config/config.go | 2 + 5 files changed, 316 insertions(+), 142 deletions(-) diff --git a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go index a4fd37b9d5..bea28b2da5 100644 --- a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go +++ b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go @@ -14,12 +14,15 @@ package controllers import ( "context" + "errors" "fmt" "time" "github.com/Tencent/bk-bcs/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/internal/option" "github.com/Tencent/bk-bcs/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/pkg/config" "github.com/go-logr/logr" + "istio.io/api/networking/v1alpha3" + networkingv1 "istio.io/client-go/pkg/apis/networking/v1" "istio.io/client-go/pkg/clientset/versioned" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -41,6 +44,7 @@ type ServiceReconciler struct { Option *option.ControllerOption } +// getServicePredicate 获取 Service 事件的 Predicate func getServicePredicate() predicate.Predicate { return predicate.Funcs{ CreateFunc: func(e event.CreateEvent) bool { @@ -89,13 +93,13 @@ func (sr *ServiceReconciler) SetupWithManager(mgr ctrl.Manager) error { return err } - // 开启一个线程,遍历所有svc - go sr.updateExistSvcs() + // 开启一个线程,遍历所有svc更新关联的策略 + go sr.updateExistPolicies() return nil } -// Reconcile reconcile k8s node info +// Reconcile reconcile for k8s svc func (sr *ServiceReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { // 尝试获取 Service 对象 var svc corev1.Service @@ -127,6 +131,7 @@ func (sr *ServiceReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c return ctrl.Result{}, nil } +// createOrUpdatePolicy 创建或更新策略 func (sr *ServiceReconciler) createOrUpdatePolicy(namespace, name string) error { dr, err := sr.IstioClient.NetworkingV1().DestinationRules(namespace).Get(context.Background(), name, metav1.GetOptions{}) @@ -166,30 +171,7 @@ func (sr *ServiceReconciler) createOrUpdatePolicy(namespace, name string) error if svc.Name == name && svc.Namespace == namespace { if svc.Setting.MergeMode == MergeModeMerge { if svc.TrafficPolicy != nil { - if svc.TrafficPolicy.LoadBalancer != nil { - dr.Spec.TrafficPolicy.LoadBalancer = svc.TrafficPolicy.LoadBalancer - } - if svc.TrafficPolicy.ConnectionPool != nil { - dr.Spec.TrafficPolicy.ConnectionPool = svc.TrafficPolicy.ConnectionPool - } - if svc.TrafficPolicy.OutlierDetection != nil { - dr.Spec.TrafficPolicy.OutlierDetection = svc.TrafficPolicy.OutlierDetection - } - if svc.TrafficPolicy.Tls != nil { - dr.Spec.TrafficPolicy.Tls = svc.TrafficPolicy.Tls - } - if svc.TrafficPolicy.PortLevelSettings != nil { - dr.Spec.TrafficPolicy.PortLevelSettings = svc.TrafficPolicy.PortLevelSettings - } - if svc.TrafficPolicy.Tunnel != nil { - dr.Spec.TrafficPolicy.Tunnel = svc.TrafficPolicy.Tunnel - } - if svc.TrafficPolicy.ProxyProtocol != nil { - dr.Spec.TrafficPolicy.ProxyProtocol = svc.TrafficPolicy.ProxyProtocol - } - // if svc.TrafficPolicy.RetryBudget != nil { - // dr.Spec.TrafficPolicy.RetryBudget = svc.TrafficPolicy.RetryBudget - // } + mergePolicy(dr, svc.TrafficPolicy) } } else { dr.Spec.TrafficPolicy = svc.TrafficPolicy @@ -197,12 +179,143 @@ func (sr *ServiceReconciler) createOrUpdatePolicy(namespace, name string) error } } + if config.G.Global.Setting.MergeMode == MergeModeMerge { + mergePolicy(dr, config.G.Global.TrafficPolicy) + } else { + dr.Spec.TrafficPolicy = config.G.Global.TrafficPolicy + } + _, err = sr.IstioClient.NetworkingV1().DestinationRules(dr.Namespace). Update(context.Background(), dr, metav1.UpdateOptions{}) return err } +// createDr 创建 DestinationRule +func (sr *ServiceReconciler) createDr(ctx context.Context, namespace, name string) error { + dr := &networkingv1.DestinationRule{ + TypeMeta: metav1.TypeMeta{ + Kind: "DestinationRule", + APIVersion: "networking.istio.io/v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + Labels: map[string]string{ + LabelKey: LabelValue, + namespace: namespace, + name: name, + }, + }, + Spec: v1alpha3.DestinationRule{ + Host: fmt.Sprintf("%s.%s.svc.cluster.local", name, namespace), + TrafficPolicy: &v1alpha3.TrafficPolicy{}, + }, + } + + var tp *v1alpha3.TrafficPolicy + for _, svc := range config.G.Services { + if svc.Name == name && svc.Namespace == namespace { + tp = svc.TrafficPolicy + } + } + + if tp == nil { + tp = config.G.Global.TrafficPolicy + } + + dr.Spec.TrafficPolicy = tp + + if isEmptyStruct(dr.Spec.TrafficPolicy.LoadBalancer) { + dr.Spec.TrafficPolicy.LoadBalancer = nil + } + if isEmptyStruct(dr.Spec.TrafficPolicy.ConnectionPool) { + dr.Spec.TrafficPolicy.ConnectionPool = nil + } + if isEmptyStruct(dr.Spec.TrafficPolicy.OutlierDetection) { + dr.Spec.TrafficPolicy.OutlierDetection = nil + } + if isEmptyStruct(dr.Spec.TrafficPolicy.Tls) { + dr.Spec.TrafficPolicy.Tls = nil + } + if len(dr.Spec.TrafficPolicy.PortLevelSettings) == 0 { + dr.Spec.TrafficPolicy.PortLevelSettings = nil + } + if isEmptyStruct(dr.Spec.TrafficPolicy.Tunnel) { + dr.Spec.TrafficPolicy.Tunnel = nil + } + if isEmptyStruct(dr.Spec.TrafficPolicy.ProxyProtocol) { + dr.Spec.TrafficPolicy.ProxyProtocol = nil + } + if isEmptyStruct(dr.Spec.TrafficPolicy.RetryBudget) { + dr.Spec.TrafficPolicy.RetryBudget = nil + } + + _, err := sr.IstioClient.NetworkingV1().DestinationRules(namespace). + Create(ctx, dr, metav1.CreateOptions{}) + if err != nil { + return err + } + + return nil +} + +// createVs 创建 VirtualService +func (sr *ServiceReconciler) createVs(ctx context.Context, namespace, name string) error { + vs := &networkingv1.VirtualService{ + TypeMeta: metav1.TypeMeta{ + Kind: "VirtualService", + APIVersion: "networking.istio.io/v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + Labels: map[string]string{ + LabelKey: LabelValue, + namespace: namespace, + name: name, + }, + }, + Spec: v1alpha3.VirtualService{ + Hosts: []string{fmt.Sprintf("%s.%s.svc.cluster.local", name, namespace)}, + Http: []*v1alpha3.HTTPRoute{ + { + Route: []*v1alpha3.HTTPRouteDestination{ + { + Destination: &v1alpha3.Destination{ + Host: fmt.Sprintf("%s.%s.svc.cluster.local", name, namespace), + }, + }, + }, + }, + }, + }, + } + + for _, svc := range config.G.Services { + if svc.Name == name && svc.Namespace == namespace { + if svc.Setting.AutoGenerateVS { + _, err := sr.IstioClient.NetworkingV1().VirtualServices(namespace). + Create(ctx, vs, metav1.CreateOptions{}) + if err != nil { + return err + } + } + } + } + + if config.G.Global.Setting.AutoGenerateVS { + _, err := sr.IstioClient.NetworkingV1().VirtualServices(namespace). + Create(ctx, vs, metav1.CreateOptions{}) + if err != nil { + return err + } + } + + return nil +} + +// deletePolicy 删除策略 func (sr *ServiceReconciler) deletePolicy(ctx context.Context, namespace, name string) error { dr, err := sr.IstioClient.NetworkingV1().DestinationRules(namespace).Get(ctx, name, metav1.GetOptions{}) if err != nil { @@ -231,22 +344,51 @@ func (sr *ServiceReconciler) deletePolicy(ctx context.Context, namespace, name s return nil } -// updateExistSvcs update exist services -func (sr *ServiceReconciler) updateExistSvcs() { +// deleteDrAndVs 删除 DestinationRule 和 VirtualService +func (sr *ServiceReconciler) deleteDrAndVs(ctx context.Context, dr *networkingv1.DestinationRule, + vs *networkingv1.VirtualService) error { + + var drErr, vsErr error + if dr != nil { + if v, ok := dr.GetLabels()[LabelKey]; ok && v == LabelValue { + drErr = sr.IstioClient.NetworkingV1().DestinationRules(dr.Namespace).Delete(ctx, + dr.Name, metav1.DeleteOptions{}) + if drErr != nil { + sr.Log.Error(drErr, "failed to delete DestinationRule") + } + } + } + + if vs != nil { + if v, ok := vs.GetLabels()[LabelKey]; ok && v == LabelValue { + vsErr = sr.IstioClient.NetworkingV1().VirtualServices(vs.Namespace).Delete(ctx, + vs.Name, metav1.DeleteOptions{}) + if vsErr != nil { + sr.Log.Error(vsErr, "failed to delete VirtualService") + return vsErr + } + } + } + + return errors.Join(drErr, vsErr) +} + +// updateExistPolicies 更新已存在的策略 +func (sr *ServiceReconciler) updateExistPolicies() { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() - ticker := time.NewTicker(10 * time.Second) - defer ticker.Stop() - for { select { case <-ctx.Done(): + sr.Log.Error(fmt.Errorf("updateExistSvcs timeout"), "error") return - case <-ticker.C: + default: + time.Sleep(time.Second * 10) svcList := &corev1.ServiceList{} if err := sr.Client.List(context.Background(), svcList); err != nil { sr.Log.Error(err, "failed to list services") + continue } // 处理逻辑 @@ -259,7 +401,6 @@ func (sr *ServiceReconciler) updateExistSvcs() { if err != nil { sr.Log.Error(err, "failed to create or update policy", "namespace", svc.Namespace, "name", svc.Name) - continue } } diff --git a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/util.go b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/util.go index 4e0a834d53..ef2ae80df1 100644 --- a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/util.go +++ b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/util.go @@ -13,145 +13,168 @@ package controllers import ( - "context" - "fmt" - "strings" + "reflect" - "github.com/Tencent/bk-bcs/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/pkg/config" "istio.io/api/networking/v1alpha3" - networkingv1 "istio.io/client-go/pkg/apis/networking/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "istio.io/client-go/pkg/apis/networking/v1" ) const ( - LabelKey = "managed-by" + // LabelKey label key + LabelKey = "managed-by" + // LabelValue label value LabelValue = "istio-policy-controller" - - MergeModeMerge = "merge" + // MergeModeMerge merge mode merge + MergeModeMerge = "merge" + // MergeModeOverride merge mode override MergeModeOverride = "override" ) -func (sr *ServiceReconciler) createDr(ctx context.Context, namespace, name string) error { - dr := &networkingv1.DestinationRule{ - TypeMeta: metav1.TypeMeta{ - Kind: "DestinationRule", - APIVersion: "networking.istio.io/v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: namespace, - }, - Spec: v1alpha3.DestinationRule{ - Host: fmt.Sprintf("%s.%s.svc.cluster.local", name, namespace), - TrafficPolicy: &v1alpha3.TrafficPolicy{}, - }, +func mergePolicy(dr *v1.DestinationRule, tp *v1alpha3.TrafficPolicy) { + if tp == nil { + return } - var tp *v1alpha3.TrafficPolicy - for _, svc := range config.G.Services { - if svc.Name == name && svc.Namespace == namespace { - tp = svc.TrafficPolicy + if tp.LoadBalancer != nil { + if isEmptyStruct(tp.LoadBalancer) { + dr.Spec.TrafficPolicy.LoadBalancer = nil + } else { + dr.Spec.TrafficPolicy.LoadBalancer = tp.LoadBalancer } } - - if tp == nil { - tp = config.G.Global.TrafficPolicy + if tp.ConnectionPool != nil { + if isEmptyStruct(tp.ConnectionPool) { + dr.Spec.TrafficPolicy.ConnectionPool = nil + } else { + dr.Spec.TrafficPolicy.ConnectionPool = tp.ConnectionPool + } } - - _, err := sr.IstioClient.NetworkingV1().DestinationRules(namespace). - Create(context.Background(), dr, metav1.CreateOptions{}) - if err != nil { - return err + if tp.OutlierDetection != nil { + if isEmptyStruct(tp.OutlierDetection) { + dr.Spec.TrafficPolicy.OutlierDetection = nil + } else { + dr.Spec.TrafficPolicy.OutlierDetection = tp.OutlierDetection + } + } + if tp.Tls != nil { + if isEmptyStruct(tp.Tls) { + dr.Spec.TrafficPolicy.Tls = nil + } else { + dr.Spec.TrafficPolicy.Tls = tp.Tls + } + } + if tp.PortLevelSettings != nil { + if len(tp.PortLevelSettings) == 0 { + dr.Spec.TrafficPolicy.PortLevelSettings = nil + } else { + dr.Spec.TrafficPolicy.PortLevelSettings = tp.PortLevelSettings + } + } + if tp.Tunnel != nil { + if isEmptyStruct(tp.Tunnel) { + dr.Spec.TrafficPolicy.Tunnel = nil + } else { + dr.Spec.TrafficPolicy.Tunnel = tp.Tunnel + } + } + if tp.ProxyProtocol != nil { + if isEmptyStruct(tp.ProxyProtocol) { + dr.Spec.TrafficPolicy.ProxyProtocol = nil + } else { + dr.Spec.TrafficPolicy.ProxyProtocol = tp.ProxyProtocol + } + } + if tp.RetryBudget != nil { + if isEmptyStruct(tp.RetryBudget) { + dr.Spec.TrafficPolicy.RetryBudget = nil + } else { + dr.Spec.TrafficPolicy.RetryBudget = tp.RetryBudget + } } - - return nil } -func (sr *ServiceReconciler) createVs(ctx context.Context, namespace, name string) error { - vs := &networkingv1.VirtualService{ - TypeMeta: metav1.TypeMeta{ - Kind: "VirtualService", - APIVersion: "networking.istio.io/v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: namespace, - }, - Spec: v1alpha3.VirtualService{ - Hosts: []string{fmt.Sprintf("%s.%s.svc.cluster.local", name, namespace)}, - Http: []*v1alpha3.HTTPRoute{ - { - Route: []*v1alpha3.HTTPRouteDestination{ - { - Destination: &v1alpha3.Destination{ - Host: fmt.Sprintf("%s.%s.svc.cluster.local", name, namespace), - }, - }, - }, - }, - }, - }, +// isEmptyStruct 判断任意结构体是否逻辑上为零(注意: 不能用于非结构体类型,如 chan、func、interface、array、map等) +func isEmptyStruct(v interface{}) bool { + if v == nil { + return true } - for _, svc := range config.G.Services { - if svc.Name == name && svc.Namespace == namespace { - if svc.Setting.AutoGenerateVS { - _, err := sr.IstioClient.NetworkingV1().VirtualServices(namespace). - Create(context.Background(), vs, metav1.CreateOptions{}) - if err != nil { - return err - } - } + rv := reflect.ValueOf(v) + rt := reflect.TypeOf(v) + + // 解引用指针(支持多层) + for rv.Kind() == reflect.Ptr { + if rv.IsNil() { + return true } + rv = rv.Elem() + rt = rt.Elem() } - if config.G.Global.Setting.AutoGenerateVS { - _, err := sr.IstioClient.NetworkingV1().VirtualServices(namespace). - Create(context.Background(), vs, metav1.CreateOptions{}) - if err != nil { - return err - } + if rv.Kind() != reflect.Struct { + panic("IsStructLogicallyZero only accepts struct or pointer to struct") } - return nil + return isLogicallyZero(rv, rt) } -func (sr *ServiceReconciler) deleteDrAndVs(ctx context.Context, dr *networkingv1.DestinationRule, - vs *networkingv1.VirtualService) error { - - var drErr, vsErr error - if dr != nil { - if v, ok := dr.GetLabels()[LabelKey]; ok && v == LabelValue { - drErr = sr.IstioClient.NetworkingV1().DestinationRules(dr.Namespace).Delete(ctx, - dr.Name, metav1.DeleteOptions{}) - if drErr != nil { - sr.Log.Error(drErr, "failed to delete DestinationRule") - } +// isLogicallyZero 递归判断任意 reflect.Value 是否逻辑上为零 +func isLogicallyZero(val reflect.Value, typ reflect.Type) bool { + switch val.Kind() { + case reflect.Bool: + return !val.Bool() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return val.Int() == 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return val.Uint() == 0 + case reflect.Float32, reflect.Float64: + return val.Float() == 0 + case reflect.Complex64, reflect.Complex128: + return val.Complex() == 0 + case reflect.String: + return val.String() == "" + case reflect.Ptr: + if val.IsNil() { + return true } - } - - if vs != nil { - if v, ok := vs.GetLabels()[LabelKey]; ok && v == LabelValue { - vsErr = sr.IstioClient.NetworkingV1().VirtualServices(vs.Namespace).Delete(ctx, - vs.Name, metav1.DeleteOptions{}) - if vsErr != nil { - sr.Log.Error(vsErr, "failed to delete VirtualService") - return vsErr + return isLogicallyZero(val.Elem(), typ.Elem()) + case reflect.Slice, reflect.Map: + return val.IsNil() // 若想认为空 slice/map 为零,改为 val.Len() == 0 + case reflect.Array: + elemType := typ.Elem() + for i := 0; i < val.Len(); i++ { + if !isLogicallyZero(val.Index(i), elemType) { + return false } } - } + return true + case reflect.Struct: + // 遍历所有字段,跳过未导出的 + for i := 0; i < val.NumField(); i++ { + fieldVal := val.Field(i) + fieldType := typ.Field(i) + + // 跳过未导出字段:PkgPath 非空表示未导出 + if fieldType.PkgPath != "" { + continue + } - if drErr != nil || vsErr != nil { - errs := make([]string, 0) - if drErr != nil { - errs = append(errs, drErr.Error()) + if !isLogicallyZero(fieldVal, fieldType.Type) { + return false + } } - if vsErr != nil { - errs = append(errs, vsErr.Error()) + return true + case reflect.Interface: + if val.IsNil() { + return true } - - return fmt.Errorf(strings.Join(errs, ";")) + // 获取接口中实际存储的值 + actualVal := val.Elem() + // 递归判断实际值是否为零,使用其自身的 Type + return isLogicallyZero(actualVal, actualVal.Type()) + case reflect.Chan, reflect.Func, reflect.UnsafePointer: + return val.IsNil() + default: + return false // 未知类型视为非零 } - - return nil } diff --git a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/go.mod b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/go.mod index b8691545f5..8372d9eaba 100644 --- a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/go.mod +++ b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/go.mod @@ -55,6 +55,7 @@ require ( ) require ( + github.com/Tencent/bk-bcs/bcs-runtime/bcs-k8s/kubernetes v0.0.0-20260123071131-ef141ea25696 github.com/go-logr/logr v1.4.2 istio.io/api v1.28.2-0.20251205082437-fde1452f70bc istio.io/client-go v1.28.3 diff --git a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/main.go b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/main.go index 96f2566ae9..5264cae296 100644 --- a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/main.go +++ b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/main.go @@ -20,10 +20,12 @@ import ( "github.com/Tencent/bk-bcs/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers" "github.com/Tencent/bk-bcs/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/internal/option" "github.com/Tencent/bk-bcs/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/pkg/config" + cloudv1 "github.com/Tencent/bk-bcs/bcs-runtime/bcs-k8s/kubernetes/apis/cloud/v1" networkingv1 "istio.io/client-go/pkg/apis/networking/v1" "istio.io/client-go/pkg/clientset/versioned" "k8s.io/apimachinery/pkg/runtime" + clientgoscheme "k8s.io/client-go/kubernetes/scheme" _ "k8s.io/client-go/plugin/pkg/client/auth/gcp" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/log/zap" @@ -35,6 +37,11 @@ var ( Config string ) +func init() { + _ = clientgoscheme.AddToScheme(scheme) + _ = cloudv1.AddToScheme(scheme) +} + func main() { opts := &option.ControllerOption{} diff --git a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/pkg/config/config.go b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/pkg/config/config.go index 32a70f8b93..4042d3de30 100644 --- a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/pkg/config/config.go +++ b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/pkg/config/config.go @@ -40,5 +40,7 @@ func Init(name string) error { return err } + ctrl.Log.WithName("config").Info(fmt.Sprintf("%#v", G)) + return nil } From 942a2a267a182e51f35806103806432bfeb787a3 Mon Sep 17 00:00:00 2001 From: dove0012 Date: Wed, 28 Jan 2026 11:34:58 +0800 Subject: [PATCH 03/17] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controllers/service_controller.go | 64 +++------------ .../controllers/util.go | 52 ++++++++++++- .../istio-policy-controller/etc/config.yaml | 24 ------ .../internal/option/option.go | 77 +++++++++++++++---- .../istio-policy-controller/main.go | 18 ++++- .../pkg/config/config.go | 46 ----------- .../pkg/config/types.go | 48 ------------ 7 files changed, 138 insertions(+), 191 deletions(-) delete mode 100644 bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/etc/config.yaml delete mode 100644 bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/pkg/config/config.go delete mode 100644 bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/pkg/config/types.go diff --git a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go index bea28b2da5..62f3aab8ef 100644 --- a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go +++ b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go @@ -19,7 +19,6 @@ import ( "time" "github.com/Tencent/bk-bcs/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/internal/option" - "github.com/Tencent/bk-bcs/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/pkg/config" "github.com/go-logr/logr" "istio.io/api/networking/v1alpha3" networkingv1 "istio.io/client-go/pkg/apis/networking/v1" @@ -30,8 +29,6 @@ import ( k8scorev1 "k8s.io/api/core/v1" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/event" - "sigs.k8s.io/controller-runtime/pkg/predicate" ) // ServiceReconciler reconciler for k8s svc @@ -44,45 +41,6 @@ type ServiceReconciler struct { Option *option.ControllerOption } -// getServicePredicate 获取 Service 事件的 Predicate -func getServicePredicate() predicate.Predicate { - return predicate.Funcs{ - CreateFunc: func(e event.CreateEvent) bool { - svc, ok := e.Object.(*k8scorev1.Service) - if !ok { - return false - } - ctrl.Log.WithName("event").Info(fmt.Sprintf("Create event svc name: %s, namespace: %s", - svc.GetName(), svc.GetNamespace())) - return true - }, - UpdateFunc: func(e event.UpdateEvent) bool { - newSvc, newOk := e.ObjectNew.(*k8scorev1.Service) - oldSvc, oldOk := e.ObjectOld.(*k8scorev1.Service) - if !newOk || !oldOk { - return false - } - if newSvc.DeletionTimestamp != nil { - return true - } - - ctrl.Log.WithName("event").Info(fmt.Sprintf("Update event new svc name: %s, old svc name: %s, namespace: %s", - newSvc.GetName(), oldSvc.GetName(), newSvc.GetNamespace())) - return true - }, - DeleteFunc: func(e event.DeleteEvent) bool { - svc, ok := e.Object.(*k8scorev1.Service) - if !ok { - return false - } - - ctrl.Log.WithName("event").Info(fmt.Sprintf("Delete event svc name: %s, namespace: %s", - svc.GetName(), svc.GetNamespace())) - return true - }, - } -} - // SetupWithManager set node reconciler func (sr *ServiceReconciler) SetupWithManager(mgr ctrl.Manager) error { err := ctrl.NewControllerManagedBy(mgr). @@ -167,11 +125,11 @@ func (sr *ServiceReconciler) createOrUpdatePolicy(namespace, name string) error // 更新 DestinationRule 的逻辑 sr.Log.Info("Updating DestinationRule", "name", name, "namespace", namespace) - for _, svc := range config.G.Services { + for _, svc := range sr.Option.Cfg.Services { if svc.Name == name && svc.Namespace == namespace { if svc.Setting.MergeMode == MergeModeMerge { if svc.TrafficPolicy != nil { - mergePolicy(dr, svc.TrafficPolicy) + mergeDrPolicy(dr, svc.TrafficPolicy) } } else { dr.Spec.TrafficPolicy = svc.TrafficPolicy @@ -179,10 +137,10 @@ func (sr *ServiceReconciler) createOrUpdatePolicy(namespace, name string) error } } - if config.G.Global.Setting.MergeMode == MergeModeMerge { - mergePolicy(dr, config.G.Global.TrafficPolicy) + if sr.Option.Cfg.Global.Setting.MergeMode == MergeModeMerge { + mergeDrPolicy(dr, sr.Option.Cfg.Global.TrafficPolicy) } else { - dr.Spec.TrafficPolicy = config.G.Global.TrafficPolicy + dr.Spec.TrafficPolicy = sr.Option.Cfg.Global.TrafficPolicy } _, err = sr.IstioClient.NetworkingV1().DestinationRules(dr.Namespace). @@ -214,14 +172,14 @@ func (sr *ServiceReconciler) createDr(ctx context.Context, namespace, name strin } var tp *v1alpha3.TrafficPolicy - for _, svc := range config.G.Services { + for _, svc := range sr.Option.Cfg.Services { if svc.Name == name && svc.Namespace == namespace { tp = svc.TrafficPolicy } } if tp == nil { - tp = config.G.Global.TrafficPolicy + tp = sr.Option.Cfg.Global.TrafficPolicy } dr.Spec.TrafficPolicy = tp @@ -292,7 +250,7 @@ func (sr *ServiceReconciler) createVs(ctx context.Context, namespace, name strin }, } - for _, svc := range config.G.Services { + for _, svc := range sr.Option.Cfg.Services { if svc.Name == name && svc.Namespace == namespace { if svc.Setting.AutoGenerateVS { _, err := sr.IstioClient.NetworkingV1().VirtualServices(namespace). @@ -304,7 +262,7 @@ func (sr *ServiceReconciler) createVs(ctx context.Context, namespace, name strin } } - if config.G.Global.Setting.AutoGenerateVS { + if sr.Option.Cfg.Global.Setting.AutoGenerateVS { _, err := sr.IstioClient.NetworkingV1().VirtualServices(namespace). Create(ctx, vs, metav1.CreateOptions{}) if err != nil { @@ -331,13 +289,13 @@ func (sr *ServiceReconciler) deletePolicy(ctx context.Context, namespace, name s } } - for _, svc := range config.G.Services { + for _, svc := range sr.Option.Cfg.Services { if svc.Name == name && svc.Namespace == namespace && svc.Setting.DeletePolicyOnServiceDelete { return sr.deleteDrAndVs(ctx, dr, vs) } } - if config.G.Global.Setting.DeletePolicyOnServiceDelete { + if sr.Option.Cfg.Global.Setting.DeletePolicyOnServiceDelete { return sr.deleteDrAndVs(ctx, dr, vs) } diff --git a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/util.go b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/util.go index ef2ae80df1..5600216395 100644 --- a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/util.go +++ b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/util.go @@ -13,10 +13,15 @@ package controllers import ( + "fmt" "reflect" "istio.io/api/networking/v1alpha3" v1 "istio.io/client-go/pkg/apis/networking/v1" + k8scorev1 "k8s.io/api/core/v1" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/event" + "sigs.k8s.io/controller-runtime/pkg/predicate" ) const ( @@ -30,11 +35,56 @@ const ( MergeModeOverride = "override" ) -func mergePolicy(dr *v1.DestinationRule, tp *v1alpha3.TrafficPolicy) { +// getServicePredicate 获取 Service 事件的 Predicate +func getServicePredicate() predicate.Predicate { + return predicate.Funcs{ + CreateFunc: func(e event.CreateEvent) bool { + svc, ok := e.Object.(*k8scorev1.Service) + if !ok { + return false + } + ctrl.Log.WithName("event").Info(fmt.Sprintf("Create service, name: %s, namespace: %s", + svc.GetName(), svc.GetNamespace())) + return true + }, + UpdateFunc: func(e event.UpdateEvent) bool { + newSvc, newOk := e.ObjectNew.(*k8scorev1.Service) + oldSvc, oldOk := e.ObjectOld.(*k8scorev1.Service) + if !newOk || !oldOk { + return false + } + if newSvc.DeletionTimestamp != nil { + return true + } + + ctrl.Log.WithName("event").Info(fmt.Sprintf( + "Update new service, new service name: %s, old service name: %s, namespace: %s", + newSvc.GetName(), oldSvc.GetName(), newSvc.GetNamespace())) + return true + }, + DeleteFunc: func(e event.DeleteEvent) bool { + svc, ok := e.Object.(*k8scorev1.Service) + if !ok { + return false + } + + ctrl.Log.WithName("event").Info(fmt.Sprintf("Delete service, name: %s, namespace: %s", + svc.GetName(), svc.GetNamespace())) + return true + }, + } +} + +// mergeDrPolicy merge destination policy +func mergeDrPolicy(dr *v1.DestinationRule, tp *v1alpha3.TrafficPolicy) { if tp == nil { return } + if dr.Spec.TrafficPolicy == nil { + dr.Spec.TrafficPolicy = &v1alpha3.TrafficPolicy{} + } + if tp.LoadBalancer != nil { if isEmptyStruct(tp.LoadBalancer) { dr.Spec.TrafficPolicy.LoadBalancer = nil diff --git a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/etc/config.yaml b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/etc/config.yaml deleted file mode 100644 index d3094dc099..0000000000 --- a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/etc/config.yaml +++ /dev/null @@ -1,24 +0,0 @@ -global: - trafficPolicy: - connectionPool: {} - loadBalancer: - simple: RANDOM - localityLbSetting: - enabled: true - failover: - - from: sh - to: nj - setting: - mergeMode: merge - deletePolicyOnServiceDelete: true - updateUnmanagedResources: true -services: - - name: my-svc - namespace: bcs-system - trafficPolicy: - loadBalancer: - simple: RANDOM - setting: - mergeMode: override - deletePolicyOnServiceDelete: true - updateUnmanagedResources: true diff --git a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/internal/option/option.go b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/internal/option/option.go index 62d0fd0946..cccfce3b17 100644 --- a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/internal/option/option.go +++ b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/internal/option/option.go @@ -9,38 +9,85 @@ * either express or implied. See the License for the specific language governing permissions and * limitations under the License. */ - +// package xxx package option import ( + "fmt" + "os" + "github.com/Tencent/bk-bcs/bcs-common/common/conf" + "istio.io/api/networking/v1alpha3" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/yaml" ) +// ConnectionPoolSettings_HTTPSettings_H2UpgradePolicy Policy for upgrading http1.1 connections to http2. +type ConnectionPoolSettings_HTTPSettings_H2UpgradePolicy int32 + +// Configuration 是整个 YAML 配置的根结构 +type Configuration struct { + Global Global + Services []Service +} + +// Global 对应 global 字段 +type Global struct { + TrafficPolicy *v1alpha3.TrafficPolicy + Setting Setting +} + +// Service 单个服务的配置 +type Service struct { + Name string + Namespace string + TrafficPolicy *v1alpha3.TrafficPolicy + Setting Setting +} + +// Setting 全局设置 +type Setting struct { + MergeMode string // e.g., "merge" + DeletePolicyOnServiceDelete bool + AutoGenerateVS bool + UpdateUnmanagedResources bool +} + // ControllerOption controller option type ControllerOption struct { // Address address for server Address string - // Port port for server - Port int - // MetricPort port for metric server MetricPort int - // CloudMod - Cloud string + conf.LogConfig + + // ConfigPath config file path + ConfigPath string + // Cfg config object + Cfg *Configuration +} + +// InitCfg init config +func (o *ControllerOption) InitCfg() error { + if o.ConfigPath == "" { + return fmt.Errorf("config file name is empty") + } - // Cluster cluster id for bcs - Cluster string + content, err := os.ReadFile(o.ConfigPath) + if err != nil { + return err + } - // CloudNetServiceEndpoints - CloudNetServiceEndpoints []string + ctrl.Log.WithName("config").Info(fmt.Sprintf("config content: %s", string(content))) - // IPCleanCheckMinute check interval for unused fixed ip - IPCleanCheckMinute int + o.Cfg = &Configuration{} + if err := yaml.Unmarshal(content, o.Cfg); err != nil { + return err + } - // IPCleanMaxReservedMinute max reserved time for unused fixed ip - IPCleanMaxReservedMinute int + ctrl.Log.WithName("config").Info(fmt.Sprintf("%#v", o.Cfg)) - conf.LogConfig + return nil } diff --git a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/main.go b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/main.go index 5264cae296..6fa17222b1 100644 --- a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/main.go +++ b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/main.go @@ -19,7 +19,6 @@ import ( "github.com/Tencent/bk-bcs/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers" "github.com/Tencent/bk-bcs/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/internal/option" - "github.com/Tencent/bk-bcs/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/pkg/config" cloudv1 "github.com/Tencent/bk-bcs/bcs-runtime/bcs-k8s/kubernetes/apis/cloud/v1" networkingv1 "istio.io/client-go/pkg/apis/networking/v1" "istio.io/client-go/pkg/clientset/versioned" @@ -34,7 +33,8 @@ import ( var ( scheme = runtime.NewScheme() setupLog = ctrl.Log.WithName("setup") - Config string + + verbosity int ) func init() { @@ -47,19 +47,29 @@ func main() { flag.StringVar(&opts.Address, "address", "127.0.0.1", "address for controller") flag.IntVar(&opts.MetricPort, "metric_port", 8081, "metric port for controller") + flag.StringVar(&opts.LogDir, "log_dir", "./logs", "If non-empty, write log files in this directory") flag.Uint64Var(&opts.LogMaxSize, "log_max_size", 500, "Max size (MB) per log file.") flag.IntVar(&opts.LogMaxNum, "log_max_num", 10, "Max num of log file.") flag.BoolVar(&opts.ToStdErr, "logtostderr", false, "log to standard error instead of files") - flag.StringVar(&Config, "config", "./etc/config.yaml", "config file path") + flag.BoolVar(&opts.AlsoToStdErr, "alsologtostderr", false, "log to standard error as well as files") + + flag.IntVar(&verbosity, "v", 0, "log level for V logs") + flag.StringVar(&opts.StdErrThreshold, "stderrthreshold", "2", "logs at or above this threshold go to stderr") + flag.StringVar(&opts.VModule, "vmodule", "", "comma-separated list of pattern=N settings for file-filtered logging") + flag.StringVar(&opts.TraceLocation, "log_backtrace_at", "", "when logging hits line file:N, emit a stack trace") + + flag.StringVar(&opts.ConfigPath, "config", "./etc/config.yaml", "config file path") flag.Parse() + opts.Verbosity = int32(verbosity) + ctrl.SetLogger(zap.New(zap.UseDevMode(true))) setupLog.Info("starting init config") // 初始化配置 - err := config.Init(Config) + err := opts.InitCfg() if err != nil { setupLog.Error(err, "unable to init config") os.Exit(1) diff --git a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/pkg/config/config.go b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/pkg/config/config.go deleted file mode 100644 index 4042d3de30..0000000000 --- a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/pkg/config/config.go +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Blueking Container Service available. - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * Licensed under the MIT License (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * http://opensource.org/licenses/MIT - * 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 xxx -package config - -import ( - "fmt" - "os" - - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/yaml" -) - -// G is the global configuration -var G = &Configuration{} - -// Init init config -func Init(name string) error { - if name == "" { - return fmt.Errorf("config file name is empty") - } - - content, err := os.ReadFile(name) - if err != nil { - return err - } - - ctrl.Log.WithName("config").Info(fmt.Sprintf("config content: %s", string(content))) - - if err := yaml.Unmarshal(content, G); err != nil { - return err - } - - ctrl.Log.WithName("config").Info(fmt.Sprintf("%#v", G)) - - return nil -} diff --git a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/pkg/config/types.go b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/pkg/config/types.go deleted file mode 100644 index 2725737d79..0000000000 --- a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/pkg/config/types.go +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Blueking Container Service available. - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * Licensed under the MIT License (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * http://opensource.org/licenses/MIT - * 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 xxx -package config - -import ( - "istio.io/api/networking/v1alpha3" -) - -// ConnectionPoolSettings_HTTPSettings_H2UpgradePolicy Policy for upgrading http1.1 connections to http2. -type ConnectionPoolSettings_HTTPSettings_H2UpgradePolicy int32 - -// Configuration 是整个 YAML 配置的根结构 -type Configuration struct { - Global Global - Services []Service -} - -// Global 对应 global 字段 -type Global struct { - TrafficPolicy *v1alpha3.TrafficPolicy - Setting Setting -} - -// Service 单个服务的配置 -type Service struct { - Name string - Namespace string - TrafficPolicy *v1alpha3.TrafficPolicy - Setting Setting -} - -// Setting 全局设置 -type Setting struct { - MergeMode string // e.g., "merge" - DeletePolicyOnServiceDelete bool - AutoGenerateVS bool - UpdateUnmanagedResources bool -} From 658aff0ba451ffe7e75f26e51a468cd7a7481274 Mon Sep 17 00:00:00 2001 From: dove0012 Date: Wed, 28 Jan 2026 14:47:37 +0800 Subject: [PATCH 04/17] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=9B=B4=E6=96=B0dr?= =?UTF-8?q?=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controllers/service_controller.go | 81 +++++++++---------- 1 file changed, 40 insertions(+), 41 deletions(-) diff --git a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go index 62f3aab8ef..494815ba3c 100644 --- a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go +++ b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go @@ -24,6 +24,7 @@ import ( networkingv1 "istio.io/client-go/pkg/apis/networking/v1" "istio.io/client-go/pkg/clientset/versioned" corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" k8scorev1 "k8s.io/api/core/v1" @@ -69,7 +70,6 @@ func (sr *ServiceReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c } sr.Log.Info(fmt.Sprintf("Service deleted, name: %s, namespace: %s", req.Name, req.Namespace)) - // 在这里处理删除逻辑 err = sr.deletePolicy(ctx, req.Namespace, req.Name) if err != nil { return ctrl.Result{}, err @@ -78,10 +78,8 @@ func (sr *ServiceReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c return ctrl.Result{}, nil } - // 如果走到这里,说明是创建或更新 sr.Log.Info(fmt.Sprintf("Service created or updated, name: %s, namespace: %s", req.Name, req.Namespace)) - // 在这里添加你的业务逻辑 - err := sr.createOrUpdatePolicy(req.Namespace, req.Name) + err := sr.createOrUpdatePolicy(ctx, req.Namespace, req.Name) if err != nil { return ctrl.Result{}, err } @@ -90,8 +88,8 @@ func (sr *ServiceReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c } // createOrUpdatePolicy 创建或更新策略 -func (sr *ServiceReconciler) createOrUpdatePolicy(namespace, name string) error { - dr, err := sr.IstioClient.NetworkingV1().DestinationRules(namespace).Get(context.Background(), +func (sr *ServiceReconciler) createOrUpdatePolicy(ctx context.Context, namespace, name string) error { + dr, err := sr.IstioClient.NetworkingV1().DestinationRules(namespace).Get(ctx, name, metav1.GetOptions{}) if err != nil { if client.IgnoreNotFound(err) != nil { @@ -99,15 +97,41 @@ func (sr *ServiceReconciler) createOrUpdatePolicy(namespace, name string) error return err } - // 创建 DestinationRule 的逻辑 - sr.Log.Info("Creating DestinationRule", "name", name, "namespace", namespace) - err = sr.createDr(context.Background(), namespace, name) - if err != nil { - return err + if apierrors.IsNotFound(err) { + sr.Log.Info("Creating DestinationRule", "name", name, "namespace", namespace) + err = sr.createDr(ctx, namespace, name) + if err != nil { + return err + } + } else { + sr.Log.Info("Updating DestinationRule", "name", name, "namespace", namespace) + for _, svc := range sr.Option.Cfg.Services { + if svc.Name == name && svc.Namespace == namespace { + if svc.Setting.MergeMode == MergeModeMerge { + if svc.TrafficPolicy != nil { + mergeDrPolicy(dr, svc.TrafficPolicy) + } + } else { + dr.Spec.TrafficPolicy = svc.TrafficPolicy + } + } + } + + if sr.Option.Cfg.Global.Setting.MergeMode == MergeModeMerge { + mergeDrPolicy(dr, sr.Option.Cfg.Global.TrafficPolicy) + } else { + dr.Spec.TrafficPolicy = sr.Option.Cfg.Global.TrafficPolicy + } + + _, err = sr.IstioClient.NetworkingV1().DestinationRules(dr.Namespace). + Update(context.Background(), dr, metav1.UpdateOptions{}) + if err != nil { + return err + } } } - _, err = sr.IstioClient.NetworkingV1().VirtualServices(namespace).Get(context.Background(), + _, err = sr.IstioClient.NetworkingV1().VirtualServices(namespace).Get(ctx, name, metav1.GetOptions{}) if err != nil { if client.IgnoreNotFound(err) != nil { @@ -115,38 +139,15 @@ func (sr *ServiceReconciler) createOrUpdatePolicy(namespace, name string) error return err } - // 创建 VirtualServices 的逻辑 + // 创建 VirtualServices sr.Log.Info("Creating VirtualServices", "name", name, "namespace", namespace) - err = sr.createVs(context.Background(), namespace, name) + err = sr.createVs(ctx, namespace, name) if err != nil { return err } } - // 更新 DestinationRule 的逻辑 - sr.Log.Info("Updating DestinationRule", "name", name, "namespace", namespace) - for _, svc := range sr.Option.Cfg.Services { - if svc.Name == name && svc.Namespace == namespace { - if svc.Setting.MergeMode == MergeModeMerge { - if svc.TrafficPolicy != nil { - mergeDrPolicy(dr, svc.TrafficPolicy) - } - } else { - dr.Spec.TrafficPolicy = svc.TrafficPolicy - } - } - } - - if sr.Option.Cfg.Global.Setting.MergeMode == MergeModeMerge { - mergeDrPolicy(dr, sr.Option.Cfg.Global.TrafficPolicy) - } else { - dr.Spec.TrafficPolicy = sr.Option.Cfg.Global.TrafficPolicy - } - - _, err = sr.IstioClient.NetworkingV1().DestinationRules(dr.Namespace). - Update(context.Background(), dr, metav1.UpdateOptions{}) - - return err + return nil } // createDr 创建 DestinationRule @@ -349,13 +350,11 @@ func (sr *ServiceReconciler) updateExistPolicies() { continue } - // 处理逻辑 for _, svc := range svcList.Items { // 处理每个 Service sr.Log.Info("Found service", "namespace", svc.Namespace, "name", svc.Name) - // 你的业务逻辑... - err := sr.createOrUpdatePolicy(svc.Namespace, svc.Name) + err := sr.createOrUpdatePolicy(context.Background(), svc.Namespace, svc.Name) if err != nil { sr.Log.Error(err, "failed to create or update policy", "namespace", svc.Namespace, "name", svc.Name) From 813a73aca042f0822df94960001147d81d7dae62 Mon Sep 17 00:00:00 2001 From: dove0012 Date: Wed, 28 Jan 2026 15:47:47 +0800 Subject: [PATCH 05/17] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controllers/service_controller.go | 91 ++++++++++++------- 1 file changed, 59 insertions(+), 32 deletions(-) diff --git a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go index 494815ba3c..6504b20758 100644 --- a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go +++ b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go @@ -24,7 +24,6 @@ import ( networkingv1 "istio.io/client-go/pkg/apis/networking/v1" "istio.io/client-go/pkg/clientset/versioned" corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" k8scorev1 "k8s.io/api/core/v1" @@ -97,37 +96,16 @@ func (sr *ServiceReconciler) createOrUpdatePolicy(ctx context.Context, namespace return err } - if apierrors.IsNotFound(err) { - sr.Log.Info("Creating DestinationRule", "name", name, "namespace", namespace) - err = sr.createDr(ctx, namespace, name) - if err != nil { - return err - } - } else { - sr.Log.Info("Updating DestinationRule", "name", name, "namespace", namespace) - for _, svc := range sr.Option.Cfg.Services { - if svc.Name == name && svc.Namespace == namespace { - if svc.Setting.MergeMode == MergeModeMerge { - if svc.TrafficPolicy != nil { - mergeDrPolicy(dr, svc.TrafficPolicy) - } - } else { - dr.Spec.TrafficPolicy = svc.TrafficPolicy - } - } - } - - if sr.Option.Cfg.Global.Setting.MergeMode == MergeModeMerge { - mergeDrPolicy(dr, sr.Option.Cfg.Global.TrafficPolicy) - } else { - dr.Spec.TrafficPolicy = sr.Option.Cfg.Global.TrafficPolicy - } - - _, err = sr.IstioClient.NetworkingV1().DestinationRules(dr.Namespace). - Update(context.Background(), dr, metav1.UpdateOptions{}) - if err != nil { - return err - } + sr.Log.Info("Creating DestinationRule", "name", name, "namespace", namespace) + err = sr.createDr(ctx, namespace, name) + if err != nil { + return err + } + } else if dr != nil && dr.GetName() != "" { + sr.Log.Info("Updating DestinationRule", "name", name, "namespace", namespace) + err = sr.updateDr(ctx, dr) + if err != nil { + return err } } @@ -274,6 +252,55 @@ func (sr *ServiceReconciler) createVs(ctx context.Context, namespace, name strin return nil } +// updateDr 更新 DestinationRule +func (sr *ServiceReconciler) updateDr(ctx context.Context, dr *networkingv1.DestinationRule) error { + label := dr.GetLabels() + if len(label) == 0 { + label = map[string]string{} + } + label[LabelKey] = LabelValue + label[dr.GetName()] = dr.GetName() + label[dr.GetNamespace()] = dr.GetNamespace() + dr.SetLabels(label) + + for _, svc := range sr.Option.Cfg.Services { + if svc.Name == dr.GetName() && svc.Namespace == dr.GetNamespace() { + if v, ok := dr.GetLabels()[LabelKey]; (ok && v == LabelValue) || svc.Setting.UpdateUnmanagedResources { + if svc.Setting.MergeMode == MergeModeMerge { + if svc.TrafficPolicy != nil { + mergeDrPolicy(dr, svc.TrafficPolicy) + } + } else { + dr.Spec.TrafficPolicy = svc.TrafficPolicy + } + + _, err := sr.IstioClient.NetworkingV1().DestinationRules(dr.GetNamespace()). + Update(ctx, dr, metav1.UpdateOptions{}) + + return err + } + + return nil + } + } + + if v, ok := dr.GetLabels()[LabelKey]; (ok && v == LabelValue) || + sr.Option.Cfg.Global.Setting.UpdateUnmanagedResources { + if sr.Option.Cfg.Global.Setting.MergeMode == MergeModeMerge { + mergeDrPolicy(dr, sr.Option.Cfg.Global.TrafficPolicy) + } else { + dr.Spec.TrafficPolicy = sr.Option.Cfg.Global.TrafficPolicy + } + + _, err := sr.IstioClient.NetworkingV1().DestinationRules(dr.GetNamespace()). + Update(ctx, dr, metav1.UpdateOptions{}) + + return err + } + + return nil +} + // deletePolicy 删除策略 func (sr *ServiceReconciler) deletePolicy(ctx context.Context, namespace, name string) error { dr, err := sr.IstioClient.NetworkingV1().DestinationRules(namespace).Get(ctx, name, metav1.GetOptions{}) From 22f4ae530139edf26835466c4520d39f4b708066 Mon Sep 17 00:00:00 2001 From: dove0012 Date: Wed, 28 Jan 2026 16:07:24 +0800 Subject: [PATCH 06/17] =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=86=97=E4=BD=99?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controllers/service_controller.go | 39 +------------------ .../internal/option/option.go | 2 - 2 files changed, 1 insertion(+), 40 deletions(-) diff --git a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go index 6504b20758..e6def80299 100644 --- a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go +++ b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go @@ -16,7 +16,6 @@ import ( "context" "errors" "fmt" - "time" "github.com/Tencent/bk-bcs/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/internal/option" "github.com/go-logr/logr" @@ -51,9 +50,6 @@ func (sr *ServiceReconciler) SetupWithManager(mgr ctrl.Manager) error { return err } - // 开启一个线程,遍历所有svc更新关联的策略 - go sr.updateExistPolicies() - return nil } @@ -261,6 +257,7 @@ func (sr *ServiceReconciler) updateDr(ctx context.Context, dr *networkingv1.Dest label[LabelKey] = LabelValue label[dr.GetName()] = dr.GetName() label[dr.GetNamespace()] = dr.GetNamespace() + label["test"] = "test" dr.SetLabels(label) for _, svc := range sr.Option.Cfg.Services { @@ -358,37 +355,3 @@ func (sr *ServiceReconciler) deleteDrAndVs(ctx context.Context, dr *networkingv1 return errors.Join(drErr, vsErr) } - -// updateExistPolicies 更新已存在的策略 -func (sr *ServiceReconciler) updateExistPolicies() { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) - defer cancel() - - for { - select { - case <-ctx.Done(): - sr.Log.Error(fmt.Errorf("updateExistSvcs timeout"), "error") - return - default: - time.Sleep(time.Second * 10) - svcList := &corev1.ServiceList{} - if err := sr.Client.List(context.Background(), svcList); err != nil { - sr.Log.Error(err, "failed to list services") - - continue - } - - for _, svc := range svcList.Items { - // 处理每个 Service - sr.Log.Info("Found service", "namespace", svc.Namespace, "name", svc.Name) - err := sr.createOrUpdatePolicy(context.Background(), svc.Namespace, svc.Name) - if err != nil { - sr.Log.Error(err, "failed to create or update policy", - "namespace", svc.Namespace, "name", svc.Name) - } - } - - return - } - } -} diff --git a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/internal/option/option.go b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/internal/option/option.go index cccfce3b17..fe90867217 100644 --- a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/internal/option/option.go +++ b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/internal/option/option.go @@ -87,7 +87,5 @@ func (o *ControllerOption) InitCfg() error { return err } - ctrl.Log.WithName("config").Info(fmt.Sprintf("%#v", o.Cfg)) - return nil } From c25937521dacdb60963d3505a62369b54709ef42 Mon Sep 17 00:00:00 2001 From: dove0012 Date: Thu, 29 Jan 2026 09:10:30 +0800 Subject: [PATCH 07/17] =?UTF-8?q?=E5=AE=8C=E5=96=84=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controllers/service_controller.go | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go index e6def80299..8178ca70f9 100644 --- a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go +++ b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go @@ -95,14 +95,20 @@ func (sr *ServiceReconciler) createOrUpdatePolicy(ctx context.Context, namespace sr.Log.Info("Creating DestinationRule", "name", name, "namespace", namespace) err = sr.createDr(ctx, namespace, name) if err != nil { + sr.Log.Error(err, "failed to create DestinationRule") return err } + + sr.Log.Info("DestinationRule created successfully") } else if dr != nil && dr.GetName() != "" { sr.Log.Info("Updating DestinationRule", "name", name, "namespace", namespace) err = sr.updateDr(ctx, dr) if err != nil { + sr.Log.Error(err, "failed to update DestinationRule") return err } + + sr.Log.Info("DestinationRule updated successfully") } _, err = sr.IstioClient.NetworkingV1().VirtualServices(namespace).Get(ctx, @@ -117,8 +123,11 @@ func (sr *ServiceReconciler) createOrUpdatePolicy(ctx context.Context, namespace sr.Log.Info("Creating VirtualServices", "name", name, "namespace", namespace) err = sr.createVs(ctx, namespace, name) if err != nil { + sr.Log.Error(err, "failed to create VirtualServices") return err } + + sr.Log.Info("VirtualServices created successfully") } return nil @@ -257,7 +266,6 @@ func (sr *ServiceReconciler) updateDr(ctx context.Context, dr *networkingv1.Dest label[LabelKey] = LabelValue label[dr.GetName()] = dr.GetName() label[dr.GetNamespace()] = dr.GetNamespace() - label["test"] = "test" dr.SetLabels(label) for _, svc := range sr.Option.Cfg.Services { @@ -339,6 +347,8 @@ func (sr *ServiceReconciler) deleteDrAndVs(ctx context.Context, dr *networkingv1 if drErr != nil { sr.Log.Error(drErr, "failed to delete DestinationRule") } + + sr.Log.Info("DestinationRule deleted successfully") } } @@ -350,6 +360,8 @@ func (sr *ServiceReconciler) deleteDrAndVs(ctx context.Context, dr *networkingv1 sr.Log.Error(vsErr, "failed to delete VirtualService") return vsErr } + + sr.Log.Info("VirtualService deleted successfully") } } From 09c1fee1891f329e96c6182368e6e681f7568400 Mon Sep 17 00:00:00 2001 From: dove0012 Date: Thu, 29 Jan 2026 16:51:26 +0800 Subject: [PATCH 08/17] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dbug=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0prometheu=E6=8C=87=E6=A0=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controllers/service_controller.go | 115 ++++++++---------- .../controllers/util.go | 49 +++++++- .../internal/metric/metric.go | 70 ++++------- .../internal/option/option.go | 4 +- .../istio-policy-controller/main.go | 2 +- .../container-start.sh | 34 +----- 6 files changed, 127 insertions(+), 147 deletions(-) diff --git a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go index 8178ca70f9..b61d02eee5 100644 --- a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go +++ b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go @@ -9,7 +9,7 @@ * either express or implied. See the License for the specific language governing permissions and * limitations under the License. */ -// package xxx +// package controllers contains the reconcile logic for the istio-policy-controller. package controllers import ( @@ -17,6 +17,7 @@ import ( "errors" "fmt" + "github.com/Tencent/bk-bcs/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/internal/metric" "github.com/Tencent/bk-bcs/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/internal/option" "github.com/go-logr/logr" "istio.io/api/networking/v1alpha3" @@ -92,6 +93,7 @@ func (sr *ServiceReconciler) createOrUpdatePolicy(ctx context.Context, namespace return err } + metric.PolicyGeneratedTotal.Inc() sr.Log.Info("Creating DestinationRule", "name", name, "namespace", namespace) err = sr.createDr(ctx, namespace, name) if err != nil { @@ -99,8 +101,10 @@ func (sr *ServiceReconciler) createOrUpdatePolicy(ctx context.Context, namespace return err } + metric.PolicySuccessTotal.Inc() sr.Log.Info("DestinationRule created successfully") } else if dr != nil && dr.GetName() != "" { + metric.PolicyConflictTotal.Inc() sr.Log.Info("Updating DestinationRule", "name", name, "namespace", namespace) err = sr.updateDr(ctx, dr) if err != nil { @@ -144,62 +148,41 @@ func (sr *ServiceReconciler) createDr(ctx context.Context, namespace, name strin Name: name, Namespace: namespace, Labels: map[string]string{ - LabelKey: LabelValue, - namespace: namespace, - name: name, + LabelKeyManagedBy: ControllerName, + LabelKeyServiceNamespace: namespace, + LabelKeyServiceName: name, }, }, Spec: v1alpha3.DestinationRule{ - Host: fmt.Sprintf("%s.%s.svc.cluster.local", name, namespace), - TrafficPolicy: &v1alpha3.TrafficPolicy{}, + Host: sprintfHost(name, namespace), }, } - var tp *v1alpha3.TrafficPolicy for _, svc := range sr.Option.Cfg.Services { if svc.Name == name && svc.Namespace == namespace { - tp = svc.TrafficPolicy - } - } - - if tp == nil { - tp = sr.Option.Cfg.Global.TrafficPolicy - } + if svc.TrafficPolicy == nil { + return errors.New("no traffic policy found in service config") + } - dr.Spec.TrafficPolicy = tp + dr.Spec.TrafficPolicy = svc.TrafficPolicy + overrideDrPolicy(dr) + _, err := sr.IstioClient.NetworkingV1().DestinationRules(namespace). + Create(ctx, dr, metav1.CreateOptions{}) - if isEmptyStruct(dr.Spec.TrafficPolicy.LoadBalancer) { - dr.Spec.TrafficPolicy.LoadBalancer = nil - } - if isEmptyStruct(dr.Spec.TrafficPolicy.ConnectionPool) { - dr.Spec.TrafficPolicy.ConnectionPool = nil - } - if isEmptyStruct(dr.Spec.TrafficPolicy.OutlierDetection) { - dr.Spec.TrafficPolicy.OutlierDetection = nil - } - if isEmptyStruct(dr.Spec.TrafficPolicy.Tls) { - dr.Spec.TrafficPolicy.Tls = nil - } - if len(dr.Spec.TrafficPolicy.PortLevelSettings) == 0 { - dr.Spec.TrafficPolicy.PortLevelSettings = nil - } - if isEmptyStruct(dr.Spec.TrafficPolicy.Tunnel) { - dr.Spec.TrafficPolicy.Tunnel = nil - } - if isEmptyStruct(dr.Spec.TrafficPolicy.ProxyProtocol) { - dr.Spec.TrafficPolicy.ProxyProtocol = nil + return err + } } - if isEmptyStruct(dr.Spec.TrafficPolicy.RetryBudget) { - dr.Spec.TrafficPolicy.RetryBudget = nil + + if sr.Option.Cfg.Global.TrafficPolicy == nil { + return errors.New("no traffic policy found in global config") } + dr.Spec.TrafficPolicy = sr.Option.Cfg.Global.TrafficPolicy + overrideDrPolicy(dr) _, err := sr.IstioClient.NetworkingV1().DestinationRules(namespace). Create(ctx, dr, metav1.CreateOptions{}) - if err != nil { - return err - } - return nil + return err } // createVs 创建 VirtualService @@ -213,19 +196,19 @@ func (sr *ServiceReconciler) createVs(ctx context.Context, namespace, name strin Name: name, Namespace: namespace, Labels: map[string]string{ - LabelKey: LabelValue, - namespace: namespace, - name: name, + LabelKeyManagedBy: ControllerName, + LabelKeyServiceNamespace: namespace, + LabelKeyServiceName: name, }, }, Spec: v1alpha3.VirtualService{ - Hosts: []string{fmt.Sprintf("%s.%s.svc.cluster.local", name, namespace)}, + Hosts: []string{sprintfHost(name, namespace)}, Http: []*v1alpha3.HTTPRoute{ { Route: []*v1alpha3.HTTPRouteDestination{ { Destination: &v1alpha3.Destination{ - Host: fmt.Sprintf("%s.%s.svc.cluster.local", name, namespace), + Host: sprintfHost(name, namespace), }, }, }, @@ -235,13 +218,11 @@ func (sr *ServiceReconciler) createVs(ctx context.Context, namespace, name strin } for _, svc := range sr.Option.Cfg.Services { - if svc.Name == name && svc.Namespace == namespace { - if svc.Setting.AutoGenerateVS { - _, err := sr.IstioClient.NetworkingV1().VirtualServices(namespace). - Create(ctx, vs, metav1.CreateOptions{}) - if err != nil { - return err - } + if svc.Setting.AutoGenerateVS && svc.Name == name && svc.Namespace == namespace { + _, err := sr.IstioClient.NetworkingV1().VirtualServices(namespace). + Create(ctx, vs, metav1.CreateOptions{}) + if err != nil { + return err } } } @@ -263,21 +244,25 @@ func (sr *ServiceReconciler) updateDr(ctx context.Context, dr *networkingv1.Dest if len(label) == 0 { label = map[string]string{} } - label[LabelKey] = LabelValue + label[LabelKeyManagedBy] = ControllerName label[dr.GetName()] = dr.GetName() label[dr.GetNamespace()] = dr.GetNamespace() - dr.SetLabels(label) for _, svc := range sr.Option.Cfg.Services { if svc.Name == dr.GetName() && svc.Namespace == dr.GetNamespace() { - if v, ok := dr.GetLabels()[LabelKey]; (ok && v == LabelValue) || svc.Setting.UpdateUnmanagedResources { + if v, ok := dr.GetLabels()[LabelKeyManagedBy]; (ok && v == ControllerName) || + svc.Setting.UpdateUnmanagedResources { + if svc.TrafficPolicy == nil { + return errors.New("no traffic policy found in service config") + } + if svc.Setting.MergeMode == MergeModeMerge { - if svc.TrafficPolicy != nil { - mergeDrPolicy(dr, svc.TrafficPolicy) - } + mergeDrPolicy(dr, svc.TrafficPolicy) } else { dr.Spec.TrafficPolicy = svc.TrafficPolicy + overrideDrPolicy(dr) } + dr.SetLabels(label) _, err := sr.IstioClient.NetworkingV1().DestinationRules(dr.GetNamespace()). Update(ctx, dr, metav1.UpdateOptions{}) @@ -289,13 +274,19 @@ func (sr *ServiceReconciler) updateDr(ctx context.Context, dr *networkingv1.Dest } } - if v, ok := dr.GetLabels()[LabelKey]; (ok && v == LabelValue) || + if v, ok := dr.GetLabels()[LabelKeyManagedBy]; (ok && v == ControllerName) || sr.Option.Cfg.Global.Setting.UpdateUnmanagedResources { + if sr.Option.Cfg.Global.TrafficPolicy == nil { + return errors.New("no traffic policy found in global config") + } + if sr.Option.Cfg.Global.Setting.MergeMode == MergeModeMerge { mergeDrPolicy(dr, sr.Option.Cfg.Global.TrafficPolicy) } else { dr.Spec.TrafficPolicy = sr.Option.Cfg.Global.TrafficPolicy + overrideDrPolicy(dr) } + dr.SetLabels(label) _, err := sr.IstioClient.NetworkingV1().DestinationRules(dr.GetNamespace()). Update(ctx, dr, metav1.UpdateOptions{}) @@ -341,7 +332,7 @@ func (sr *ServiceReconciler) deleteDrAndVs(ctx context.Context, dr *networkingv1 var drErr, vsErr error if dr != nil { - if v, ok := dr.GetLabels()[LabelKey]; ok && v == LabelValue { + if v, ok := dr.GetLabels()[LabelKeyManagedBy]; ok && v == ControllerName { drErr = sr.IstioClient.NetworkingV1().DestinationRules(dr.Namespace).Delete(ctx, dr.Name, metav1.DeleteOptions{}) if drErr != nil { @@ -353,7 +344,7 @@ func (sr *ServiceReconciler) deleteDrAndVs(ctx context.Context, dr *networkingv1 } if vs != nil { - if v, ok := vs.GetLabels()[LabelKey]; ok && v == LabelValue { + if v, ok := vs.GetLabels()[LabelKeyManagedBy]; ok && v == ControllerName { vsErr = sr.IstioClient.NetworkingV1().VirtualServices(vs.Namespace).Delete(ctx, vs.Name, metav1.DeleteOptions{}) if vsErr != nil { diff --git a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/util.go b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/util.go index 5600216395..7193eb3f4b 100644 --- a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/util.go +++ b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/util.go @@ -9,7 +9,7 @@ * either express or implied. See the License for the specific language governing permissions and * limitations under the License. */ - +// package controllers contains the reconcile logic for the istio-policy-controller. package controllers import ( @@ -25,16 +25,27 @@ import ( ) const ( - // LabelKey label key - LabelKey = "managed-by" - // LabelValue label value - LabelValue = "istio-policy-controller" + // ControllerName controller name + ControllerName = "istio-policy-controller" + + // LabelKeyManagedBy label key for istio-policy-controller + LabelKeyManagedBy = "managed-by" + // LabelKeyServiceNamespace label key for service namespace + LabelKeyServiceNamespace = "service-namespace" + // LabelKeyServiceName label key for service name + LabelKeyServiceName = "service-name" + // MergeModeMerge merge mode merge MergeModeMerge = "merge" // MergeModeOverride merge mode override MergeModeOverride = "override" ) +// sprintfHost 格式化 host 字符串 +func sprintfHost(name, namespace string) string { + return fmt.Sprintf("%s.%s.svc.cluster.local", name, namespace) +} + // getServicePredicate 获取 Service 事件的 Predicate func getServicePredicate() predicate.Predicate { return predicate.Funcs{ @@ -75,6 +86,34 @@ func getServicePredicate() predicate.Predicate { } } +// overrideDrPolicy override destination policy +func overrideDrPolicy(dr *v1.DestinationRule) { + if isEmptyStruct(dr.Spec.TrafficPolicy.LoadBalancer) { + dr.Spec.TrafficPolicy.LoadBalancer = nil + } + if isEmptyStruct(dr.Spec.TrafficPolicy.ConnectionPool) { + dr.Spec.TrafficPolicy.ConnectionPool = nil + } + if isEmptyStruct(dr.Spec.TrafficPolicy.OutlierDetection) { + dr.Spec.TrafficPolicy.OutlierDetection = nil + } + if isEmptyStruct(dr.Spec.TrafficPolicy.Tls) { + dr.Spec.TrafficPolicy.Tls = nil + } + if len(dr.Spec.TrafficPolicy.PortLevelSettings) == 0 { + dr.Spec.TrafficPolicy.PortLevelSettings = nil + } + if isEmptyStruct(dr.Spec.TrafficPolicy.Tunnel) { + dr.Spec.TrafficPolicy.Tunnel = nil + } + if isEmptyStruct(dr.Spec.TrafficPolicy.ProxyProtocol) { + dr.Spec.TrafficPolicy.ProxyProtocol = nil + } + if isEmptyStruct(dr.Spec.TrafficPolicy.RetryBudget) { + dr.Spec.TrafficPolicy.RetryBudget = nil + } +} + // mergeDrPolicy merge destination policy func mergeDrPolicy(dr *v1.DestinationRule, tp *v1alpha3.TrafficPolicy) { if tp == nil { diff --git a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/internal/metric/metric.go b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/internal/metric/metric.go index 813cb142d0..2bdc47e9c9 100644 --- a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/internal/metric/metric.go +++ b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/internal/metric/metric.go @@ -9,67 +9,49 @@ * either express or implied. See the License for the specific language governing permissions and * limitations under the License. */ - +// package metric is used to collect metrics for controller package metric import ( - "strconv" - "time" - "github.com/prometheus/client_golang/prometheus" "sigs.k8s.io/controller-runtime/pkg/metrics" ) -var ( - // RequestResultSuccess request successfully - RequestResultSuccess = "ok" - // RequestResultFailed request return error - RequestResultFailed = "failed" - // RequestResultPartialFailed partial failed result - RequestResultPartialFailed = "partialfailed" +const ( + // ControllerName controller name + ControllerName = "istio_policy_controller" ) // declare metrics var ( - cliReqCounter = prometheus.NewCounterVec( + // PolicyGeneratedTotal 策略生成数量 + PolicyGeneratedTotal = prometheus.NewCounter( + prometheus.CounterOpts{ + Subsystem: ControllerName, + Name: "policy_generated_total", + Help: "Total number of policies generated.", + }, + ) + // PolicySuccessTotal 策略下发成功数量 + PolicySuccessTotal = prometheus.NewCounter( prometheus.CounterOpts{ - Namespace: "bcs_network", - Subsystem: "cloudnetcontroller", - Name: "cli_request_total", - Help: "total request counter as client", + Subsystem: ControllerName, + Name: "policy_applied_success_total", + Help: "Total number of policies successfully applied.", }, - []string{"module", "rpc", "errcode", "result"}, ) - cliRespSummary = prometheus.NewSummaryVec( - prometheus.SummaryOpts{ - Namespace: "bcs_network", - Subsystem: "cloudnetcontroller", - Name: "cli_response_time", - Help: "response time(ms) of other module summary.", + // PolicyConflictTotal 策略冲突数量 + PolicyConflictTotal = prometheus.NewCounter( + prometheus.CounterOpts{ + Subsystem: ControllerName, + Name: "policy_conflict_total", + Help: "Total number of policy conflicts detected.", }, - []string{"module", "rpc"}, ) ) func init() { - metrics.Registry.MustRegister(cliReqCounter) - metrics.Registry.MustRegister(cliRespSummary) -} - -// StatClientRequest report client request metrics -func StatClientRequest(module, rpc string, respCode int, result string, inTime, outTime time.Time) { - cliReqCounter.With(prometheus.Labels{ - "module": module, - "rpc": rpc, - "errcode": strconv.Itoa(respCode), - "result": result, - }).Inc() - - cost := toMSTimestamp(outTime) - toMSTimestamp(inTime) - cliRespSummary.With(prometheus.Labels{"module": module, "rpc": rpc}).Observe(float64(cost)) -} - -// toMSTimestamp converts time.Time to millisecond timestamp. -func toMSTimestamp(t time.Time) int64 { - return t.UnixNano() / 1e6 + metrics.Registry.MustRegister(PolicyGeneratedTotal) + metrics.Registry.MustRegister(PolicySuccessTotal) + metrics.Registry.MustRegister(PolicyConflictTotal) } diff --git a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/internal/option/option.go b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/internal/option/option.go index fe90867217..a2f101839c 100644 --- a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/internal/option/option.go +++ b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/internal/option/option.go @@ -9,7 +9,7 @@ * either express or implied. See the License for the specific language governing permissions and * limitations under the License. */ -// package xxx +// package option app 配置 package option import ( @@ -80,7 +80,7 @@ func (o *ControllerOption) InitCfg() error { return err } - ctrl.Log.WithName("config").Info(fmt.Sprintf("config content: %s", string(content))) + ctrl.Log.WithName("config").Info(fmt.Sprintf("loaded config from %s", o.ConfigPath)) o.Cfg = &Configuration{} if err := yaml.Unmarshal(content, o.Cfg); err != nil { diff --git a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/main.go b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/main.go index 6fa17222b1..97fca5efa0 100644 --- a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/main.go +++ b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/main.go @@ -9,7 +9,7 @@ * either express or implied. See the License for the specific language governing permissions and * limitations under the License. */ -// package xxx +// package main is the entry point of the program. package main import ( diff --git a/install/conf/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/container-start.sh b/install/conf/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/container-start.sh index 9f99bda23c..42e6741c1b 100644 --- a/install/conf/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/container-start.sh +++ b/install/conf/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/container-start.sh @@ -11,36 +11,4 @@ if [[ $BCS_CONFIG_TYPE == "render" ]]; then fi #ready to start -exec /data/bcs/${module}/${module} $@ - -# Usage of ./istio-policy-controller: -# -address string -# address for controller (default "127.0.0.1") -# -alsologtostderr -# log to standard error as well as files -# -cloud string -# cloud mode for bcs network controller (default "tencentcloud") -# -kubeconfig string -# Paths to a kubeconfig. Only required if out-of-cluster. -# -log_backtrace_at string -# when logging hits line file:N, emit a stack trace -# -log_dir string -# If non-empty, write log files in this directory (default "./logs") -# -log_max_num int -# Max num of log file. (default 10) -# -log_max_size uint -# Max size (MB) per log file. (default 500) -# -logtostderr -# log to standard error instead of files -# -master --kubeconfig -# (Deprecated: switch to --kubeconfig) The address of the Kubernetes API server. Overrides any value in kubeconfig. Only required if out-of-cluster. -# -metric_port int -# metric port for controller (default 8081) -# -port int -# por for controller (default 8080) -# -stderrthreshold string -# logs at or above this threshold go to stderr (default "2") -# -v int -# log level for V logs -# -vmodule string -# comma-separated list of pattern=N settings for file-filtered logging \ No newline at end of file +exec /data/bcs/${module}/${module} $@ \ No newline at end of file From 9a5e522d9a9ef8f7b586b4d7a649443142122be9 Mon Sep 17 00:00:00 2001 From: dove0012 Date: Thu, 29 Jan 2026 17:04:59 +0800 Subject: [PATCH 09/17] =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=A4=9A=E4=BD=99?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bcs-component/istio-policy-controller/controllers/util.go | 2 +- .../istio-policy-controller/internal/option/option.go | 3 --- .../bcs-k8s/bcs-component/istio-policy-controller/main.go | 2 +- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/util.go b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/util.go index 7193eb3f4b..6296f16654 100644 --- a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/util.go +++ b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/util.go @@ -201,7 +201,7 @@ func isEmptyStruct(v interface{}) bool { } if rv.Kind() != reflect.Struct { - panic("IsStructLogicallyZero only accepts struct or pointer to struct") + panic("isEmptyStruct only accepts struct or pointer to struct") } return isLogicallyZero(rv, rt) diff --git a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/internal/option/option.go b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/internal/option/option.go index a2f101839c..ef59f29370 100644 --- a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/internal/option/option.go +++ b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/internal/option/option.go @@ -22,9 +22,6 @@ import ( "sigs.k8s.io/yaml" ) -// ConnectionPoolSettings_HTTPSettings_H2UpgradePolicy Policy for upgrading http1.1 connections to http2. -type ConnectionPoolSettings_HTTPSettings_H2UpgradePolicy int32 - // Configuration 是整个 YAML 配置的根结构 type Configuration struct { Global Global diff --git a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/main.go b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/main.go index 97fca5efa0..d748a26e67 100644 --- a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/main.go +++ b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/main.go @@ -92,7 +92,7 @@ func main() { Scheme: scheme, MetricsBindAddress: opts.Address + ":" + strconv.Itoa(opts.MetricPort), LeaderElection: true, - LeaderElectionID: "333fb49e.istioconroller.bkbcs.tencent.com", + LeaderElectionID: "i8a4x2f5.istio-conroller.bkbcs.tencent.com", LeaderElectionNamespace: "default", }) if err != nil { From c504acccb438a456a4239968472eff59ff599a81 Mon Sep 17 00:00:00 2001 From: dove0012 Date: Thu, 29 Jan 2026 17:17:52 +0800 Subject: [PATCH 10/17] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E7=AD=96=E7=95=A5=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controllers/service_controller.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go index b61d02eee5..8d9de6a3b7 100644 --- a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go +++ b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go @@ -314,8 +314,12 @@ func (sr *ServiceReconciler) deletePolicy(ctx context.Context, namespace, name s } for _, svc := range sr.Option.Cfg.Services { - if svc.Name == name && svc.Namespace == namespace && svc.Setting.DeletePolicyOnServiceDelete { - return sr.deleteDrAndVs(ctx, dr, vs) + if svc.Name == name && svc.Namespace == namespace { + if svc.Setting.DeletePolicyOnServiceDelete { + return sr.deleteDrAndVs(ctx, dr, vs) + } + + return nil } } From 3f589ad368e25a5fbce5035bad52a568cdf5579b Mon Sep 17 00:00:00 2001 From: dove0012 Date: Fri, 30 Jan 2026 09:49:05 +0800 Subject: [PATCH 11/17] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=88=9B=E5=BB=BAvs?= =?UTF-8?q?=E6=B5=81=E7=A8=8B=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controllers/service_controller.go | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go index 8d9de6a3b7..67cb6e364d 100644 --- a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go +++ b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go @@ -218,12 +218,16 @@ func (sr *ServiceReconciler) createVs(ctx context.Context, namespace, name strin } for _, svc := range sr.Option.Cfg.Services { - if svc.Setting.AutoGenerateVS && svc.Name == name && svc.Namespace == namespace { - _, err := sr.IstioClient.NetworkingV1().VirtualServices(namespace). - Create(ctx, vs, metav1.CreateOptions{}) - if err != nil { - return err + if svc.Name == name && svc.Namespace == namespace { + if svc.Setting.AutoGenerateVS { + _, err := sr.IstioClient.NetworkingV1().VirtualServices(namespace). + Create(ctx, vs, metav1.CreateOptions{}) + if err != nil { + return err + } } + + return nil } } From c0ecb8c7f93a34f0194e45938ba0101acba75541 Mon Sep 17 00:00:00 2001 From: dove0012 Date: Fri, 30 Jan 2026 18:26:06 +0800 Subject: [PATCH 12/17] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bcs-component/istio-policy-controller/main.go | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/main.go b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/main.go index d748a26e67..2b382fc125 100644 --- a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/main.go +++ b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/main.go @@ -89,11 +89,10 @@ func main() { } mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ - Scheme: scheme, - MetricsBindAddress: opts.Address + ":" + strconv.Itoa(opts.MetricPort), - LeaderElection: true, - LeaderElectionID: "i8a4x2f5.istio-conroller.bkbcs.tencent.com", - LeaderElectionNamespace: "default", + Scheme: scheme, + MetricsBindAddress: opts.Address + ":" + strconv.Itoa(opts.MetricPort), + LeaderElection: true, + LeaderElectionID: "i8a4x2f5.istio-conroller.bkbcs.tencent.com", }) if err != nil { setupLog.Error(err, "unable to start manager") From dccd00d2ecf50be6d7e3c1aa119b9c9170e6dd2e Mon Sep 17 00:00:00 2001 From: dove0012 Date: Fri, 30 Jan 2026 21:00:04 +0800 Subject: [PATCH 13/17] =?UTF-8?q?=E6=B7=BB=E5=8A=A0istio=E7=AD=96=E7=95=A5?= =?UTF-8?q?=E4=B8=8B=E5=8F=91helm?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../helm/istio-policy-controller/.helmignore | 23 +++ .../helm/istio-policy-controller/Chart.yaml | 24 +++ .../templates/NOTES.txt | 35 ++++ .../templates/_helpers.tpl | 62 +++++++ .../templates/configmap.yaml | 39 +++++ .../templates/deployment.yaml | 41 +++++ .../templates/full-access-sa.yaml | 61 +++++++ .../templates/tests/test-connection.yaml | 16 ++ .../helm/istio-policy-controller/values.yaml | 161 ++++++++++++++++++ 9 files changed, 462 insertions(+) create mode 100644 install/helm/istio-policy-controller/.helmignore create mode 100644 install/helm/istio-policy-controller/Chart.yaml create mode 100644 install/helm/istio-policy-controller/templates/NOTES.txt create mode 100644 install/helm/istio-policy-controller/templates/_helpers.tpl create mode 100644 install/helm/istio-policy-controller/templates/configmap.yaml create mode 100644 install/helm/istio-policy-controller/templates/deployment.yaml create mode 100644 install/helm/istio-policy-controller/templates/full-access-sa.yaml create mode 100644 install/helm/istio-policy-controller/templates/tests/test-connection.yaml create mode 100644 install/helm/istio-policy-controller/values.yaml diff --git a/install/helm/istio-policy-controller/.helmignore b/install/helm/istio-policy-controller/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/install/helm/istio-policy-controller/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/install/helm/istio-policy-controller/Chart.yaml b/install/helm/istio-policy-controller/Chart.yaml new file mode 100644 index 0000000000..40cab6cbda --- /dev/null +++ b/install/helm/istio-policy-controller/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v2 +name: istio-policy-controller +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.16.0" diff --git a/install/helm/istio-policy-controller/templates/NOTES.txt b/install/helm/istio-policy-controller/templates/NOTES.txt new file mode 100644 index 0000000000..ff7a68202e --- /dev/null +++ b/install/helm/istio-policy-controller/templates/NOTES.txt @@ -0,0 +1,35 @@ +1. Get the application URL by running these commands: +{{- if .Values.httpRoute.enabled }} +{{- if .Values.httpRoute.hostnames }} + export APP_HOSTNAME={{ .Values.httpRoute.hostnames | first }} +{{- else }} + export APP_HOSTNAME=$(kubectl get --namespace {{(first .Values.httpRoute.parentRefs).namespace | default .Release.Namespace }} gateway/{{ (first .Values.httpRoute.parentRefs).name }} -o jsonpath="{.spec.listeners[0].hostname}") + {{- end }} +{{- if and .Values.httpRoute.rules (first .Values.httpRoute.rules).matches (first (first .Values.httpRoute.rules).matches).path.value }} + echo "Visit http://$APP_HOSTNAME{{ (first (first .Values.httpRoute.rules).matches).path.value }} to use your application" + + NOTE: Your HTTPRoute depends on the listener configuration of your gateway and your HTTPRoute rules. + The rules can be set for path, method, header and query parameters. + You can check the gateway configuration with 'kubectl get --namespace {{(first .Values.httpRoute.parentRefs).namespace | default .Release.Namespace }} gateway/{{ (first .Values.httpRoute.parentRefs).name }} -o yaml' +{{- end }} +{{- else if .Values.ingress.enabled }} +{{- range $host := .Values.ingress.hosts }} + {{- range .paths }} + http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }} + {{- end }} +{{- end }} +{{- else if contains "NodePort" .Values.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "istio-policy-controller.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT +{{- else if contains "LoadBalancer" .Values.service.type }} + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch its status by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "istio-policy-controller.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "istio-policy-controller.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") + echo http://$SERVICE_IP:{{ .Values.service.port }} +{{- else if contains "ClusterIP" .Values.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "istio-policy-controller.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT +{{- end }} diff --git a/install/helm/istio-policy-controller/templates/_helpers.tpl b/install/helm/istio-policy-controller/templates/_helpers.tpl new file mode 100644 index 0000000000..554cc4672c --- /dev/null +++ b/install/helm/istio-policy-controller/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "istio-policy-controller.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "istio-policy-controller.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "istio-policy-controller.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "istio-policy-controller.labels" -}} +helm.sh/chart: {{ include "istio-policy-controller.chart" . }} +{{ include "istio-policy-controller.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "istio-policy-controller.selectorLabels" -}} +app.kubernetes.io/name: {{ include "istio-policy-controller.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "istio-policy-controller.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "istio-policy-controller.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/install/helm/istio-policy-controller/templates/configmap.yaml b/install/helm/istio-policy-controller/templates/configmap.yaml new file mode 100644 index 0000000000..1cdf4a75c6 --- /dev/null +++ b/install/helm/istio-policy-controller/templates/configmap.yaml @@ -0,0 +1,39 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: istio-policy-config + namespace: {{ .Release.Namespace }} + labels: + {{- include "istio-policy-controller.labels" . | nindent 4 }} + annotations: + meta.helm.sh/release-name: {{ .Release.Name }} + meta.helm.sh/release-namespace: {{ .Release.Namespace }} +data: + config.yaml: | + global: + trafficPolicy: + connectionPool: {} + tunnel: {} + loadBalancer: + simple: RANDOM + localityLbSetting: + enabled: true + failover: + - from: gz + to: nj + setting: + mergeMode: override + deletePolicyOnServiceDelete: true + updateUnmanagedResources: true + autoGenerateVS: true + services: + - name: my-svc + namespace: bcs-system + trafficPolicy: + loadBalancer: + simple: RANDOM + setting: + mergeMode: override + deletePolicyOnServiceDelete: true + updateUnmanagedResources: true + diff --git a/install/helm/istio-policy-controller/templates/deployment.yaml b/install/helm/istio-policy-controller/templates/deployment.yaml new file mode 100644 index 0000000000..7538a18ea8 --- /dev/null +++ b/install/helm/istio-policy-controller/templates/deployment.yaml @@ -0,0 +1,41 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "istio-policy-controller.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "istio-policy-controller.labels" . | nindent 4 }} + annotations: + meta.helm.sh/release-name: {{ .Release.Name }} + meta.helm.sh/release-namespace: {{ .Release.Namespace }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "istio-policy-controller.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "istio-policy-controller.labels" . | nindent 8 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + serviceAccountName: istio-policy-controller-sa + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + volumeMounts: + - name: istio-policy-config + mountPath: /data/bcs/istio-policy-controller/etc + volumes: + - name: istio-policy-config + configMap: + name: istio-policy-config diff --git a/install/helm/istio-policy-controller/templates/full-access-sa.yaml b/install/helm/istio-policy-controller/templates/full-access-sa.yaml new file mode 100644 index 0000000000..a6f89b4bf9 --- /dev/null +++ b/install/helm/istio-policy-controller/templates/full-access-sa.yaml @@ -0,0 +1,61 @@ +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: istio-policy-controller-sa + namespace: {{ .Release.Namespace }} + labels: + {{- include "istio-policy-controller.labels" . | nindent 4 }} + annotations: + meta.helm.sh/release-name: {{ .Release.Name }} + meta.helm.sh/release-namespace: {{ .Release.Namespace }} + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: istio-policy-controller-role + labels: + {{- include "istio-policy-controller.labels" . | nindent 4 }} + annotations: + meta.helm.sh/release-name: {{ .Release.Name }} + meta.helm.sh/release-namespace: {{ .Release.Namespace }} +rules: +- apiGroups: ["networking.istio.io"] + resources: ["serviceentries"] + verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] +- apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] +- apiGroups: ["*"] + resources: ["events"] + verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] +- apiGroups: ["networking.istio.io"] + resources: ["destinationrules"] + verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] +- apiGroups: ["networking.istio.io"] + resources: ["virtualservices"] + verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] +- apiGroups: [""] + resources: ["services"] + verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: istio-policy-controller-rolebinding + namespace: {{ .Release.Namespace }} + labels: + {{- include "istio-policy-controller.labels" . | nindent 4 }} + annotations: + meta.helm.sh/release-name: {{ .Release.Name }} + meta.helm.sh/release-namespace: {{ .Release.Namespace }} +subjects: +- kind: ServiceAccount + name: istio-policy-controller-sa + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: istio-policy-controller-role + apiGroup: rbac.authorization.k8s.io \ No newline at end of file diff --git a/install/helm/istio-policy-controller/templates/tests/test-connection.yaml b/install/helm/istio-policy-controller/templates/tests/test-connection.yaml new file mode 100644 index 0000000000..8718f99a7a --- /dev/null +++ b/install/helm/istio-policy-controller/templates/tests/test-connection.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "istio-policy-controller.fullname" . }}-test-connection" + namespace: {{ .Release.Namespace }} + labels: + {{- include "istio-policy-controller.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['{{ include "istio-policy-controller.fullname" . }}:{{ .Values.service.port }}'] + restartPolicy: Never diff --git a/install/helm/istio-policy-controller/values.yaml b/install/helm/istio-policy-controller/values.yaml new file mode 100644 index 0000000000..203ef7deb7 --- /dev/null +++ b/install/helm/istio-policy-controller/values.yaml @@ -0,0 +1,161 @@ +# Default values for istio-policy-controller. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# This will set the replicaset count more information can be found here: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/ +replicaCount: 1 + +# This sets the container image more information can be found here: https://kubernetes.io/docs/concepts/containers/images/ +image: + repository: ccr.ccs.tencentyun.com/dove0012/istio-policy + # This sets the pull policy for images. + pullPolicy: Always + # Overrides the image tag whose default is the chart appVersion. + tag: "sit-cloud" + +# This is for the secrets for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ +imagePullSecrets: [] +# This is to override the chart name. +nameOverride: "" +fullnameOverride: "" + +# This section builds out the service account more information can be found here: https://kubernetes.io/docs/concepts/security/service-accounts/ +serviceAccount: + # Specifies whether a service account should be created. + create: true + # Automatically mount a ServiceAccount's API credentials? + automount: true + # Annotations to add to the service account. + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template. + name: "" + +# This is for setting Kubernetes Annotations to a Pod. +# For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ +podAnnotations: {} +# This is for setting Kubernetes Labels to a Pod. +# For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ +podLabels: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +# This is for setting up a service more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/ +service: + # This sets the service type more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: ClusterIP + # This sets the ports more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#field-spec-ports + port: 80 + +# This block is for setting up the ingress for more information can be found here: https://kubernetes.io/docs/concepts/services-networking/ingress/ +ingress: + enabled: false + className: "" + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + hosts: + - host: chart-example.local + paths: + - path: / + pathType: ImplementationSpecific + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + +# -- Expose the service via gateway-api HTTPRoute +# Requires Gateway API resources and suitable controller installed within the cluster +# (see: https://gateway-api.sigs.k8s.io/guides/) +httpRoute: + # HTTPRoute enabled. + enabled: false + # HTTPRoute annotations. + annotations: {} + # Which Gateways this Route is attached to. + parentRefs: + - name: gateway + sectionName: http + # namespace: default + # Hostnames matching HTTP header. + hostnames: + - chart-example.local + # List of rules and filters applied. + rules: + - matches: + - path: + type: PathPrefix + value: /headers + # filters: + # - type: RequestHeaderModifier + # requestHeaderModifier: + # set: + # - name: My-Overwrite-Header + # value: this-is-the-only-value + # remove: + # - User-Agent + # - matches: + # - path: + # type: PathPrefix + # value: /echo + # headers: + # - name: version + # value: v2 + +resources: {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +# This is to setup the liveness and readiness probes more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ +livenessProbe: + httpGet: + path: / + port: http +readinessProbe: + httpGet: + path: / + port: http + +# This section is for setting up autoscaling more information can be found here: https://kubernetes.io/docs/concepts/workloads/autoscaling/ +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 100 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +# Additional volumes on the output Deployment definition. +volumes: [] + # - name: foo + # secret: + # secretName: mysecret + # optional: false + +# Additional volumeMounts on the output Deployment definition. +volumeMounts: [] + # - name: foo + # mountPath: "/etc/foo" + # readOnly: true + +nodeSelector: {} + +tolerations: [] + +affinity: {} From b8550ad6768ac2ef78665c9fa7e8d596ef7905b0 Mon Sep 17 00:00:00 2001 From: dove0012 Date: Sat, 31 Jan 2026 15:29:20 +0800 Subject: [PATCH 14/17] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=9B=B4=E6=96=B0label?= =?UTF-8?q?=20map=E5=BC=95=E7=94=A8=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controllers/service_controller.go | 20 +++---------------- .../controllers/util.go | 14 +++++++++++++ 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go index 67cb6e364d..f17825cb9f 100644 --- a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go +++ b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/service_controller.go @@ -147,11 +147,7 @@ func (sr *ServiceReconciler) createDr(ctx context.Context, namespace, name strin ObjectMeta: metav1.ObjectMeta{ Name: name, Namespace: namespace, - Labels: map[string]string{ - LabelKeyManagedBy: ControllerName, - LabelKeyServiceNamespace: namespace, - LabelKeyServiceName: name, - }, + Labels: setLabel(namespace, name, nil), }, Spec: v1alpha3.DestinationRule{ Host: sprintfHost(name, namespace), @@ -195,11 +191,7 @@ func (sr *ServiceReconciler) createVs(ctx context.Context, namespace, name strin ObjectMeta: metav1.ObjectMeta{ Name: name, Namespace: namespace, - Labels: map[string]string{ - LabelKeyManagedBy: ControllerName, - LabelKeyServiceNamespace: namespace, - LabelKeyServiceName: name, - }, + Labels: setLabel(namespace, name, nil), }, Spec: v1alpha3.VirtualService{ Hosts: []string{sprintfHost(name, namespace)}, @@ -244,13 +236,7 @@ func (sr *ServiceReconciler) createVs(ctx context.Context, namespace, name strin // updateDr 更新 DestinationRule func (sr *ServiceReconciler) updateDr(ctx context.Context, dr *networkingv1.DestinationRule) error { - label := dr.GetLabels() - if len(label) == 0 { - label = map[string]string{} - } - label[LabelKeyManagedBy] = ControllerName - label[dr.GetName()] = dr.GetName() - label[dr.GetNamespace()] = dr.GetNamespace() + label := setLabel(dr.GetNamespace(), dr.GetName(), dr.GetLabels()) for _, svc := range sr.Option.Cfg.Services { if svc.Name == dr.GetName() && svc.Namespace == dr.GetNamespace() { diff --git a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/util.go b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/util.go index 6296f16654..e22c42d450 100644 --- a/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/util.go +++ b/bcs-runtime/bcs-k8s/bcs-component/istio-policy-controller/controllers/util.go @@ -182,6 +182,20 @@ func mergeDrPolicy(dr *v1.DestinationRule, tp *v1alpha3.TrafficPolicy) { } } +// setLabel 设置 label +func setLabel(namespace, name string, labels map[string]string) map[string]string { + newLabels := make(map[string]string) + for k, v := range labels { + newLabels[k] = v + } + + newLabels[LabelKeyManagedBy] = ControllerName + newLabels[LabelKeyServiceNamespace] = namespace + newLabels[LabelKeyServiceName] = name + + return newLabels +} + // isEmptyStruct 判断任意结构体是否逻辑上为零(注意: 不能用于非结构体类型,如 chan、func、interface、array、map等) func isEmptyStruct(v interface{}) bool { if v == nil { From 2ca77a1b83b7b2be2ec4727d9611a56a0193ceab Mon Sep 17 00:00:00 2001 From: dove0012 Date: Mon, 2 Feb 2026 09:25:33 +0800 Subject: [PATCH 15/17] =?UTF-8?q?=E5=88=A0=E9=99=A4helm=E5=A4=9A=E4=BD=99?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../templates/NOTES.txt | 35 ----- .../templates/tests/test-connection.yaml | 16 -- .../helm/istio-policy-controller/values.yaml | 140 ------------------ 3 files changed, 191 deletions(-) delete mode 100644 install/helm/istio-policy-controller/templates/NOTES.txt delete mode 100644 install/helm/istio-policy-controller/templates/tests/test-connection.yaml diff --git a/install/helm/istio-policy-controller/templates/NOTES.txt b/install/helm/istio-policy-controller/templates/NOTES.txt deleted file mode 100644 index ff7a68202e..0000000000 --- a/install/helm/istio-policy-controller/templates/NOTES.txt +++ /dev/null @@ -1,35 +0,0 @@ -1. Get the application URL by running these commands: -{{- if .Values.httpRoute.enabled }} -{{- if .Values.httpRoute.hostnames }} - export APP_HOSTNAME={{ .Values.httpRoute.hostnames | first }} -{{- else }} - export APP_HOSTNAME=$(kubectl get --namespace {{(first .Values.httpRoute.parentRefs).namespace | default .Release.Namespace }} gateway/{{ (first .Values.httpRoute.parentRefs).name }} -o jsonpath="{.spec.listeners[0].hostname}") - {{- end }} -{{- if and .Values.httpRoute.rules (first .Values.httpRoute.rules).matches (first (first .Values.httpRoute.rules).matches).path.value }} - echo "Visit http://$APP_HOSTNAME{{ (first (first .Values.httpRoute.rules).matches).path.value }} to use your application" - - NOTE: Your HTTPRoute depends on the listener configuration of your gateway and your HTTPRoute rules. - The rules can be set for path, method, header and query parameters. - You can check the gateway configuration with 'kubectl get --namespace {{(first .Values.httpRoute.parentRefs).namespace | default .Release.Namespace }} gateway/{{ (first .Values.httpRoute.parentRefs).name }} -o yaml' -{{- end }} -{{- else if .Values.ingress.enabled }} -{{- range $host := .Values.ingress.hosts }} - {{- range .paths }} - http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }} - {{- end }} -{{- end }} -{{- else if contains "NodePort" .Values.service.type }} - export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "istio-policy-controller.fullname" . }}) - export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") - echo http://$NODE_IP:$NODE_PORT -{{- else if contains "LoadBalancer" .Values.service.type }} - NOTE: It may take a few minutes for the LoadBalancer IP to be available. - You can watch its status by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "istio-policy-controller.fullname" . }}' - export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "istio-policy-controller.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") - echo http://$SERVICE_IP:{{ .Values.service.port }} -{{- else if contains "ClusterIP" .Values.service.type }} - export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "istio-policy-controller.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") - export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") - echo "Visit http://127.0.0.1:8080 to use your application" - kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT -{{- end }} diff --git a/install/helm/istio-policy-controller/templates/tests/test-connection.yaml b/install/helm/istio-policy-controller/templates/tests/test-connection.yaml deleted file mode 100644 index 8718f99a7a..0000000000 --- a/install/helm/istio-policy-controller/templates/tests/test-connection.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: v1 -kind: Pod -metadata: - name: "{{ include "istio-policy-controller.fullname" . }}-test-connection" - namespace: {{ .Release.Namespace }} - labels: - {{- include "istio-policy-controller.labels" . | nindent 4 }} - annotations: - "helm.sh/hook": test -spec: - containers: - - name: wget - image: busybox - command: ['wget'] - args: ['{{ include "istio-policy-controller.fullname" . }}:{{ .Values.service.port }}'] - restartPolicy: Never diff --git a/install/helm/istio-policy-controller/values.yaml b/install/helm/istio-policy-controller/values.yaml index 203ef7deb7..5477d2b1a7 100644 --- a/install/helm/istio-policy-controller/values.yaml +++ b/install/helm/istio-policy-controller/values.yaml @@ -12,127 +12,6 @@ image: pullPolicy: Always # Overrides the image tag whose default is the chart appVersion. tag: "sit-cloud" - -# This is for the secrets for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ -imagePullSecrets: [] -# This is to override the chart name. -nameOverride: "" -fullnameOverride: "" - -# This section builds out the service account more information can be found here: https://kubernetes.io/docs/concepts/security/service-accounts/ -serviceAccount: - # Specifies whether a service account should be created. - create: true - # Automatically mount a ServiceAccount's API credentials? - automount: true - # Annotations to add to the service account. - annotations: {} - # The name of the service account to use. - # If not set and create is true, a name is generated using the fullname template. - name: "" - -# This is for setting Kubernetes Annotations to a Pod. -# For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ -podAnnotations: {} -# This is for setting Kubernetes Labels to a Pod. -# For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ -podLabels: {} - -podSecurityContext: {} - # fsGroup: 2000 - -securityContext: {} - # capabilities: - # drop: - # - ALL - # readOnlyRootFilesystem: true - # runAsNonRoot: true - # runAsUser: 1000 - -# This is for setting up a service more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/ -service: - # This sets the service type more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types - type: ClusterIP - # This sets the ports more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#field-spec-ports - port: 80 - -# This block is for setting up the ingress for more information can be found here: https://kubernetes.io/docs/concepts/services-networking/ingress/ -ingress: - enabled: false - className: "" - annotations: {} - # kubernetes.io/ingress.class: nginx - # kubernetes.io/tls-acme: "true" - hosts: - - host: chart-example.local - paths: - - path: / - pathType: ImplementationSpecific - tls: [] - # - secretName: chart-example-tls - # hosts: - # - chart-example.local - -# -- Expose the service via gateway-api HTTPRoute -# Requires Gateway API resources and suitable controller installed within the cluster -# (see: https://gateway-api.sigs.k8s.io/guides/) -httpRoute: - # HTTPRoute enabled. - enabled: false - # HTTPRoute annotations. - annotations: {} - # Which Gateways this Route is attached to. - parentRefs: - - name: gateway - sectionName: http - # namespace: default - # Hostnames matching HTTP header. - hostnames: - - chart-example.local - # List of rules and filters applied. - rules: - - matches: - - path: - type: PathPrefix - value: /headers - # filters: - # - type: RequestHeaderModifier - # requestHeaderModifier: - # set: - # - name: My-Overwrite-Header - # value: this-is-the-only-value - # remove: - # - User-Agent - # - matches: - # - path: - # type: PathPrefix - # value: /echo - # headers: - # - name: version - # value: v2 - -resources: {} - # We usually recommend not to specify default resources and to leave this as a conscious - # choice for the user. This also increases chances charts run on environments with little - # resources, such as Minikube. If you do want to specify resources, uncomment the following - # lines, adjust them as necessary, and remove the curly braces after 'resources:'. - # limits: - # cpu: 100m - # memory: 128Mi - # requests: - # cpu: 100m - # memory: 128Mi - -# This is to setup the liveness and readiness probes more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ -livenessProbe: - httpGet: - path: / - port: http -readinessProbe: - httpGet: - path: / - port: http - # This section is for setting up autoscaling more information can be found here: https://kubernetes.io/docs/concepts/workloads/autoscaling/ autoscaling: enabled: false @@ -140,22 +19,3 @@ autoscaling: maxReplicas: 100 targetCPUUtilizationPercentage: 80 # targetMemoryUtilizationPercentage: 80 - -# Additional volumes on the output Deployment definition. -volumes: [] - # - name: foo - # secret: - # secretName: mysecret - # optional: false - -# Additional volumeMounts on the output Deployment definition. -volumeMounts: [] - # - name: foo - # mountPath: "/etc/foo" - # readOnly: true - -nodeSelector: {} - -tolerations: [] - -affinity: {} From 30c90507d22c5112d1b272fb415cbeada9a15716 Mon Sep 17 00:00:00 2001 From: dove0012 Date: Mon, 2 Feb 2026 09:36:10 +0800 Subject: [PATCH 16/17] =?UTF-8?q?=E6=8A=8Aconfigmap=E7=9A=84=E5=80=BC?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E4=B8=BA=E5=8F=98=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../templates/configmap.yaml | 27 +---------------- .../helm/istio-policy-controller/values.yaml | 29 +++++++++++++++++++ 2 files changed, 30 insertions(+), 26 deletions(-) diff --git a/install/helm/istio-policy-controller/templates/configmap.yaml b/install/helm/istio-policy-controller/templates/configmap.yaml index 1cdf4a75c6..9adf89f643 100644 --- a/install/helm/istio-policy-controller/templates/configmap.yaml +++ b/install/helm/istio-policy-controller/templates/configmap.yaml @@ -10,30 +10,5 @@ metadata: meta.helm.sh/release-namespace: {{ .Release.Namespace }} data: config.yaml: | - global: - trafficPolicy: - connectionPool: {} - tunnel: {} - loadBalancer: - simple: RANDOM - localityLbSetting: - enabled: true - failover: - - from: gz - to: nj - setting: - mergeMode: override - deletePolicyOnServiceDelete: true - updateUnmanagedResources: true - autoGenerateVS: true - services: - - name: my-svc - namespace: bcs-system - trafficPolicy: - loadBalancer: - simple: RANDOM - setting: - mergeMode: override - deletePolicyOnServiceDelete: true - updateUnmanagedResources: true + {{- .Values.istioPolicyConfig | nindent 4 }} diff --git a/install/helm/istio-policy-controller/values.yaml b/install/helm/istio-policy-controller/values.yaml index 5477d2b1a7..a5532da1ce 100644 --- a/install/helm/istio-policy-controller/values.yaml +++ b/install/helm/istio-policy-controller/values.yaml @@ -19,3 +19,32 @@ autoscaling: maxReplicas: 100 targetCPUUtilizationPercentage: 80 # targetMemoryUtilizationPercentage: 80 + + +istioPolicyConfig: | + global: + trafficPolicy: + connectionPool: {} + tunnel: {} + loadBalancer: + simple: RANDOM + localityLbSetting: + enabled: true + failover: + - from: gz + to: nj + setting: + mergeMode: override + deletePolicyOnServiceDelete: true + updateUnmanagedResources: true + autoGenerateVS: true + services: + - name: my-svc + namespace: bcs-system + trafficPolicy: + loadBalancer: + simple: RANDOM + setting: + mergeMode: override + deletePolicyOnServiceDelete: true + updateUnmanagedResources: true \ No newline at end of file From 2ef031a4feadbb6f0d2d6c0d773ae1d820a79efe Mon Sep 17 00:00:00 2001 From: dove0012 Date: Mon, 2 Feb 2026 09:37:54 +0800 Subject: [PATCH 17/17] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- install/helm/istio-policy-controller/values.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/helm/istio-policy-controller/values.yaml b/install/helm/istio-policy-controller/values.yaml index a5532da1ce..2a4442be27 100644 --- a/install/helm/istio-policy-controller/values.yaml +++ b/install/helm/istio-policy-controller/values.yaml @@ -7,11 +7,11 @@ replicaCount: 1 # This sets the container image more information can be found here: https://kubernetes.io/docs/concepts/containers/images/ image: - repository: ccr.ccs.tencentyun.com/dove0012/istio-policy + repository: # This sets the pull policy for images. pullPolicy: Always # Overrides the image tag whose default is the chart appVersion. - tag: "sit-cloud" + tag: "" # This section is for setting up autoscaling more information can be found here: https://kubernetes.io/docs/concepts/workloads/autoscaling/ autoscaling: enabled: false