diff --git a/.chloggen/ipv6_support.yaml b/.chloggen/ipv6_support.yaml new file mode 100755 index 000000000..97540a58d --- /dev/null +++ b/.chloggen/ipv6_support.yaml @@ -0,0 +1,16 @@ +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the component, or a single word describing the area of concern, (e.g. operator, github action) +component: operator + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Add .spec.hashRing.memberlist.enableIPv6 option to enable IPv6 support + +# One or more tracking issues related to the change +issues: [704] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: diff --git a/apis/tempo/v1alpha1/tempostack_types.go b/apis/tempo/v1alpha1/tempostack_types.go index fd61d8bbf..2e70d382b 100644 --- a/apis/tempo/v1alpha1/tempostack_types.go +++ b/apis/tempo/v1alpha1/tempostack_types.go @@ -90,6 +90,13 @@ type TempoStackSpec struct { // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Search configuration options" SearchSpec SearchSpec `json:"search,omitempty"` + // HashRing defines the spec for the distributed hash ring configuration. + // + // +optional + // +kubebuilder:validation:Optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors="urn:alm:descriptor:com.tectonic.ui:advanced",displayName="Hash Ring" + HashRing HashRingSpec `json:"hashRing,omitempty"` + // Template defines requirements for a set of tempo components. // // +optional @@ -412,6 +419,26 @@ type ObjectStorageTLSSpec struct { CA string `json:"caName,omitempty"` } +// MemberListSpec defines the configuration for the memberlist based hash ring. +type MemberListSpec struct { + // EnableIPv6 enables IPv6 support for the memberlist based hash ring. + // + // +optional + // +kubebuilder:validation:Optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors="urn:alm:descriptor:com.tectonic.ui:booleanSwitch",displayName="Enable IPv6" + EnableIPv6 *bool `json:"enableIPv6,omitempty"` +} + +// HashRingSpec defines the hash ring configuration. +type HashRingSpec struct { + // MemberList configuration spec + // + // +optional + // +kubebuilder:validation:Optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Memberlist Config" + MemberList MemberListSpec `json:"memberlist,omitempty"` +} + // ReceiversTLSSpec is the TLS configuration for the receivers. type ReceiversTLSSpec struct { Enabled bool `json:"enabled"` diff --git a/apis/tempo/v1alpha1/tempostack_webhook.go b/apis/tempo/v1alpha1/tempostack_webhook.go index dfeb843a2..36d78aa96 100644 --- a/apis/tempo/v1alpha1/tempostack_webhook.go +++ b/apis/tempo/v1alpha1/tempostack_webhook.go @@ -21,6 +21,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/webhook/admission" "github.com/grafana/tempo-operator/apis/config/v1alpha1" + "github.com/grafana/tempo-operator/internal/autodetect" "github.com/grafana/tempo-operator/internal/manifests/naming" ) @@ -123,6 +124,13 @@ func (d *Defaulter) Default(ctx context.Context, obj runtime.Object) error { r.Spec.Template.QueryFrontend.JaegerQuery.Ingress.Route.Termination = defaultUITLSTermination } + // Enable IPv6 if the operator pod (and therefore most likely all other pods) only have IPv6 addresses assigned + if r.Spec.HashRing.MemberList.EnableIPv6 == nil { + if autodetect.DetectIPv6Only([]string{"eth0", "en0"}) { + r.Spec.HashRing.MemberList.EnableIPv6 = ptr.To(true) + } + } + return nil } diff --git a/apis/tempo/v1alpha1/zz_generated.deepcopy.go b/apis/tempo/v1alpha1/zz_generated.deepcopy.go index 1c43f274d..c6870d8e1 100644 --- a/apis/tempo/v1alpha1/zz_generated.deepcopy.go +++ b/apis/tempo/v1alpha1/zz_generated.deepcopy.go @@ -197,6 +197,22 @@ func (in *GrafanaConfigSpec) DeepCopy() *GrafanaConfigSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HashRingSpec) DeepCopyInto(out *HashRingSpec) { + *out = *in + in.MemberList.DeepCopyInto(&out.MemberList) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HashRingSpec. +func (in *HashRingSpec) DeepCopy() *HashRingSpec { + if in == nil { + return nil + } + out := new(HashRingSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *IngestionLimitSpec) DeepCopyInto(out *IngestionLimitSpec) { *out = *in @@ -315,6 +331,26 @@ func (in *LimitSpec) DeepCopy() *LimitSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MemberListSpec) DeepCopyInto(out *MemberListSpec) { + *out = *in + if in.EnableIPv6 != nil { + in, out := &in.EnableIPv6, &out.EnableIPv6 + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MemberListSpec. +func (in *MemberListSpec) DeepCopy() *MemberListSpec { + if in == nil { + return nil + } + out := new(MemberListSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *MetricsConfigSpec) DeepCopyInto(out *MetricsConfigSpec) { *out = *in @@ -826,6 +862,7 @@ func (in *TempoStackSpec) DeepCopyInto(out *TempoStackSpec) { out.Storage = in.Storage in.Retention.DeepCopyInto(&out.Retention) in.SearchSpec.DeepCopyInto(&out.SearchSpec) + in.HashRing.DeepCopyInto(&out.HashRing) in.Template.DeepCopyInto(&out.Template) if in.Tenants != nil { in, out := &in.Tenants, &out.Tenants diff --git a/bundle/community/manifests/tempo-operator.clusterserviceversion.yaml b/bundle/community/manifests/tempo-operator.clusterserviceversion.yaml index 7c1e623a2..ec116d436 100644 --- a/bundle/community/manifests/tempo-operator.clusterserviceversion.yaml +++ b/bundle/community/manifests/tempo-operator.clusterserviceversion.yaml @@ -42,7 +42,7 @@ metadata: capabilities: Deep Insights categories: Logging & Tracing,Monitoring containerImage: ghcr.io/grafana/tempo-operator/tempo-operator - createdAt: "2023-12-07T18:57:13Z" + createdAt: "2023-12-07T19:15:22Z" description: Create and manage deployments of Tempo, a high-scale distributed tracing backend. operatorframework.io/cluster-monitoring: "true" @@ -87,6 +87,20 @@ spec: name: "" version: v1 specDescriptors: + - description: HashRing defines the spec for the distributed hash ring configuration. + displayName: Hash Ring + path: hashRing + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: MemberList configuration spec + displayName: Memberlist Config + path: hashRing.memberlist + - description: EnableIPv6 enables IPv6 support for the memberlist based hash + ring. + displayName: Enable IPv6 + path: hashRing.memberlist.enableIPv6 + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - description: Images defines the image for each container. displayName: Container Images path: images diff --git a/bundle/community/manifests/tempo.grafana.com_tempostacks.yaml b/bundle/community/manifests/tempo.grafana.com_tempostacks.yaml index 65268a8f6..f220ce08c 100644 --- a/bundle/community/manifests/tempo.grafana.com_tempostacks.yaml +++ b/bundle/community/manifests/tempo.grafana.com_tempostacks.yaml @@ -53,6 +53,19 @@ spec: spec: description: TempoStackSpec defines the desired state of TempoStack. properties: + hashRing: + description: HashRing defines the spec for the distributed hash ring + configuration. + properties: + memberlist: + description: MemberList configuration spec + properties: + enableIPv6: + description: EnableIPv6 enables IPv6 support for the memberlist + based hash ring. + type: boolean + type: object + type: object images: description: Images defines the image for each container. properties: diff --git a/bundle/openshift/manifests/tempo-operator.clusterserviceversion.yaml b/bundle/openshift/manifests/tempo-operator.clusterserviceversion.yaml index c72ff7b77..7823c12df 100644 --- a/bundle/openshift/manifests/tempo-operator.clusterserviceversion.yaml +++ b/bundle/openshift/manifests/tempo-operator.clusterserviceversion.yaml @@ -42,7 +42,7 @@ metadata: capabilities: Deep Insights categories: Logging & Tracing,Monitoring containerImage: ghcr.io/grafana/tempo-operator/tempo-operator - createdAt: "2023-12-07T18:32:18Z" + createdAt: "2023-12-07T19:15:21Z" description: Create and manage deployments of Tempo, a high-scale distributed tracing backend. operatorframework.io/cluster-monitoring: "true" @@ -87,6 +87,20 @@ spec: name: "" version: v1 specDescriptors: + - description: HashRing defines the spec for the distributed hash ring configuration. + displayName: Hash Ring + path: hashRing + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: MemberList configuration spec + displayName: Memberlist Config + path: hashRing.memberlist + - description: EnableIPv6 enables IPv6 support for the memberlist based hash + ring. + displayName: Enable IPv6 + path: hashRing.memberlist.enableIPv6 + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - description: Images defines the image for each container. displayName: Container Images path: images diff --git a/bundle/openshift/manifests/tempo.grafana.com_tempostacks.yaml b/bundle/openshift/manifests/tempo.grafana.com_tempostacks.yaml index 65268a8f6..f220ce08c 100644 --- a/bundle/openshift/manifests/tempo.grafana.com_tempostacks.yaml +++ b/bundle/openshift/manifests/tempo.grafana.com_tempostacks.yaml @@ -53,6 +53,19 @@ spec: spec: description: TempoStackSpec defines the desired state of TempoStack. properties: + hashRing: + description: HashRing defines the spec for the distributed hash ring + configuration. + properties: + memberlist: + description: MemberList configuration spec + properties: + enableIPv6: + description: EnableIPv6 enables IPv6 support for the memberlist + based hash ring. + type: boolean + type: object + type: object images: description: Images defines the image for each container. properties: diff --git a/config/crd/bases/tempo.grafana.com_tempostacks.yaml b/config/crd/bases/tempo.grafana.com_tempostacks.yaml index 95d817acd..f1c62b73b 100644 --- a/config/crd/bases/tempo.grafana.com_tempostacks.yaml +++ b/config/crd/bases/tempo.grafana.com_tempostacks.yaml @@ -50,6 +50,19 @@ spec: spec: description: TempoStackSpec defines the desired state of TempoStack. properties: + hashRing: + description: HashRing defines the spec for the distributed hash ring + configuration. + properties: + memberlist: + description: MemberList configuration spec + properties: + enableIPv6: + description: EnableIPv6 enables IPv6 support for the memberlist + based hash ring. + type: boolean + type: object + type: object images: description: Images defines the image for each container. properties: diff --git a/config/manifests/community/bases/tempo-operator.clusterserviceversion.yaml b/config/manifests/community/bases/tempo-operator.clusterserviceversion.yaml index 1758e4ef3..1c3e00cd5 100644 --- a/config/manifests/community/bases/tempo-operator.clusterserviceversion.yaml +++ b/config/manifests/community/bases/tempo-operator.clusterserviceversion.yaml @@ -48,6 +48,20 @@ spec: name: "" version: v1 specDescriptors: + - description: HashRing defines the spec for the distributed hash ring configuration. + displayName: Hash Ring + path: hashRing + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: MemberList configuration spec + displayName: Memberlist Config + path: hashRing.memberlist + - description: EnableIPv6 enables IPv6 support for the memberlist based hash + ring. + displayName: Enable IPv6 + path: hashRing.memberlist.enableIPv6 + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - description: Images defines the image for each container. displayName: Container Images path: images diff --git a/config/manifests/openshift/bases/tempo-operator.clusterserviceversion.yaml b/config/manifests/openshift/bases/tempo-operator.clusterserviceversion.yaml index 1758e4ef3..1c3e00cd5 100644 --- a/config/manifests/openshift/bases/tempo-operator.clusterserviceversion.yaml +++ b/config/manifests/openshift/bases/tempo-operator.clusterserviceversion.yaml @@ -48,6 +48,20 @@ spec: name: "" version: v1 specDescriptors: + - description: HashRing defines the spec for the distributed hash ring configuration. + displayName: Hash Ring + path: hashRing + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:advanced + - description: MemberList configuration spec + displayName: Memberlist Config + path: hashRing.memberlist + - description: EnableIPv6 enables IPv6 support for the memberlist based hash + ring. + displayName: Enable IPv6 + path: hashRing.memberlist.enableIPv6 + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - description: Images defines the image for each container. displayName: Container Images path: images diff --git a/docs/operator/api.md b/docs/operator/api.md index 97c8a532f..c98cb5645 100644 --- a/docs/operator/api.md +++ b/docs/operator/api.md @@ -651,6 +651,66 @@ Kubernetes meta/v1.LabelSelector +## HashRingSpec { #tempo-grafana-com-v1alpha1-HashRingSpec } + +

+ +(Appears on:TempoStackSpec) + +

+ +
+ +

HashRingSpec defines the hash ring configuration.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+ +memberlist
+ + + + + +MemberListSpec + + + + + +
+ +(Optional) + +

MemberList configuration spec

+ +
+ ## IngestionLimitSpec { #tempo-grafana-com-v1alpha1-IngestionLimitSpec }

@@ -1310,6 +1370,62 @@ reconciled by the operator.

+## MemberListSpec { #tempo-grafana-com-v1alpha1-MemberListSpec } + +

+ +(Appears on:HashRingSpec) + +

+ +
+ +

MemberListSpec defines the configuration for the memberlist based hash ring.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+ +enableIPv6
+ + + +bool + + + +
+ +(Optional) + +

EnableIPv6 enables IPv6 support for the memberlist based hash ring.

+ +
+ ## MetricsConfigSpec { #tempo-grafana-com-v1alpha1-MetricsConfigSpec }

@@ -3903,6 +4019,33 @@ SearchSpec +hashRing
+ + + + + +HashRingSpec + + + + + + + + + +(Optional) + +

HashRing defines the spec for the distributed hash ring configuration.

+ + + + + + + + template
diff --git a/internal/autodetect/network.go b/internal/autodetect/network.go new file mode 100644 index 000000000..6cfc2fbeb --- /dev/null +++ b/internal/autodetect/network.go @@ -0,0 +1,39 @@ +package autodetect + +import ( + "net" + "net/netip" +) + +// DetectIPv6Only detects if the pod has only IPv6 addresses assigned and no IPv4 addresses. +func DetectIPv6Only(interfaces []string) bool { + foundIPv4 := false + foundIPv6 := false + + for _, name := range interfaces { + inf, err := net.InterfaceByName(name) + if err != nil { + continue + } + + addrs, err := inf.Addrs() + if err != nil { + continue + } + + for _, a := range addrs { + prefix, err := netip.ParsePrefix(a.String()) + if err != nil { + continue + } + + if prefix.Addr().Is4() { + foundIPv4 = true + } else if prefix.Addr().Is6() { + foundIPv6 = true + } + } + } + + return foundIPv6 && !foundIPv4 +} diff --git a/internal/manifests/config/build.go b/internal/manifests/config/build.go index 45f78009e..f0359ba19 100644 --- a/internal/manifests/config/build.go +++ b/internal/manifests/config/build.go @@ -7,6 +7,8 @@ import ( "html/template" "io" + "k8s.io/utils/ptr" + "github.com/grafana/tempo-operator/apis/tempo/v1alpha1" "github.com/grafana/tempo-operator/internal/manifests/manifestutils" "github.com/grafana/tempo-operator/internal/manifests/naming" @@ -69,8 +71,9 @@ func buildConfiguration(params manifestutils.Params) ([]byte, error) { StorageType: string(tempo.Spec.Storage.Secret.Type), StorageParams: params.StorageParams, GlobalRetention: tempo.Spec.Retention.Global.Traces.Duration.String(), - MemberList: []string{ - naming.Name("gossip-ring", tempo.Name), + MemberList: memberlistOptions{ + JoinMembers: []string{naming.Name("gossip-ring", tempo.Name)}, + EnableIPv6: ptr.Deref(tempo.Spec.HashRing.MemberList.EnableIPv6, false), }, QueryFrontendDiscovery: fmt.Sprintf("%s:%d", naming.Name("query-frontend-discovery", tempo.Name), manifestutils.PortGRPCServer), GlobalRateLimits: fromRateLimitSpecToRateLimitOptions(tempo.Spec.LimitSpec.Global), diff --git a/internal/manifests/config/build_test.go b/internal/manifests/config/build_test.go index 86bd37587..4056064e9 100644 --- a/internal/manifests/config/build_test.go +++ b/internal/manifests/config/build_test.go @@ -7,6 +7,7 @@ import ( openshiftconfigv1 "github.com/openshift/api/config/v1" "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/utils/ptr" configv1alpha1 "github.com/grafana/tempo-operator/apis/config/v1alpha1" "github.com/grafana/tempo-operator/apis/tempo/v1alpha1" @@ -2173,3 +2174,216 @@ query_frontend: } } + +func TestBuildConfigurationIPv6(t *testing.T) { + testCases := []struct { + name string + ipv6 *bool + expect string + }{ + { + name: "ipv6 disabled", + ipv6: ptr.To(false), + expect: ` +--- +compactor: + compaction: + block_retention: 48h0m0s + ring: + kvstore: + store: memberlist +distributor: + receivers: + jaeger: + protocols: + thrift_http: + endpoint: 0.0.0.0:14268 + thrift_binary: + endpoint: 0.0.0.0:6832 + thrift_compact: + endpoint: 0.0.0.0:6831 + grpc: + endpoint: 0.0.0.0:14250 + zipkin: + otlp: + protocols: + grpc: + endpoint: "0.0.0.0:4317" + http: + endpoint: "0.0.0.0:4318" + ring: + kvstore: + store: memberlist +ingester: + lifecycler: + ring: + kvstore: + store: memberlist + replication_factor: 1 + tokens_file_path: /var/tempo/tokens.json + max_block_duration: 10m +memberlist: + abort_if_cluster_join_fails: false + join_members: + - tempo-test-gossip-ring +multitenancy_enabled: false +querier: + max_concurrent_queries: 20 + search: + external_hedge_requests_at: 8s + external_hedge_requests_up_to: 2 + frontend_worker: + frontend_address: "tempo-test-query-frontend-discovery:9095" +server: + grpc_server_max_recv_msg_size: 4194304 + grpc_server_max_send_msg_size: 4194304 + http_listen_port: 3200 + http_server_read_timeout: 3m + http_server_write_timeout: 3m + log_format: logfmt +storage: + trace: + backend: s3 + blocklist_poll: 5m + cache: none + local: + path: /var/tempo/traces + s3: + bucket: tempo + endpoint: "minio:9000" + insecure: true + wal: + path: /var/tempo/wal +usage_report: + reporting_enabled: false +query_frontend: + search: + concurrent_jobs: 2000 + max_duration: 0s +`, + }, + { + name: "ipv6 enabled", + ipv6: ptr.To(true), + expect: ` +--- +compactor: + compaction: + block_retention: 48h0m0s + ring: + kvstore: + store: memberlist + enable_inet6: true +distributor: + receivers: + jaeger: + protocols: + thrift_http: + endpoint: 0.0.0.0:14268 + thrift_binary: + endpoint: 0.0.0.0:6832 + thrift_compact: + endpoint: 0.0.0.0:6831 + grpc: + endpoint: 0.0.0.0:14250 + zipkin: + otlp: + protocols: + grpc: + endpoint: "0.0.0.0:4317" + http: + endpoint: "0.0.0.0:4318" + ring: + kvstore: + store: memberlist +ingester: + lifecycler: + ring: + kvstore: + store: memberlist + replication_factor: 1 + tokens_file_path: /var/tempo/tokens.json + enable_inet6: true + max_block_duration: 10m +memberlist: + abort_if_cluster_join_fails: false + join_members: + - tempo-test-gossip-ring +multitenancy_enabled: false +querier: + max_concurrent_queries: 20 + search: + external_hedge_requests_at: 8s + external_hedge_requests_up_to: 2 + frontend_worker: + frontend_address: "tempo-test-query-frontend-discovery:9095" +server: + grpc_server_max_recv_msg_size: 4194304 + grpc_server_max_send_msg_size: 4194304 + http_listen_port: 3200 + http_server_read_timeout: 3m + http_server_write_timeout: 3m + log_format: logfmt +storage: + trace: + backend: s3 + blocklist_poll: 5m + cache: none + local: + path: /var/tempo/traces + s3: + bucket: tempo + endpoint: "minio:9000" + insecure: true + wal: + path: /var/tempo/wal +usage_report: + reporting_enabled: false +query_frontend: + search: + concurrent_jobs: 2000 + max_duration: 0s +`, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + cfg, err := buildConfiguration(manifestutils.Params{ + Tempo: v1alpha1.TempoStack{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + }, + Spec: v1alpha1.TempoStackSpec{ + Storage: v1alpha1.ObjectStorageSpec{ + Secret: v1alpha1.ObjectStorageSecretSpec{ + Type: v1alpha1.ObjectStorageSecretS3, + }, + }, + ReplicationFactor: 1, + Retention: v1alpha1.RetentionSpec{ + Global: v1alpha1.RetentionConfig{ + Traces: metav1.Duration{Duration: 48 * time.Hour}, + }, + }, + HashRing: v1alpha1.HashRingSpec{ + MemberList: v1alpha1.MemberListSpec{ + EnableIPv6: tc.ipv6, + }, + }, + }, + }, + StorageParams: manifestutils.StorageParams{ + S3: &manifestutils.S3{ + Endpoint: "minio:9000", + Bucket: "tempo", + Insecure: true, + }, + }, + }) + require.NoError(t, err) + require.YAMLEq(t, tc.expect, string(cfg)) + }) + } + +} diff --git a/internal/manifests/config/options.go b/internal/manifests/config/options.go index ae740bd53..18fe1ee92 100644 --- a/internal/manifests/config/options.go +++ b/internal/manifests/config/options.go @@ -11,7 +11,7 @@ type options struct { GlobalRateLimits rateLimitsOptions TenantRateLimitsPath string TLS tlsOptions - MemberList []string + MemberList memberlistOptions Search searchOptions ReplicationFactor int Multitenancy bool @@ -65,6 +65,11 @@ type tlsOptions struct { Profile tlsProfileOptions } +type memberlistOptions struct { + JoinMembers []string + EnableIPv6 bool +} + type receiverTLSOptions struct { Enabled bool ClientCAEnabled bool diff --git a/internal/manifests/config/tempo-config.yaml b/internal/manifests/config/tempo-config.yaml index 72317a40e..44cb14852 100644 --- a/internal/manifests/config/tempo-config.yaml +++ b/internal/manifests/config/tempo-config.yaml @@ -4,6 +4,9 @@ compactor: ring: kvstore: store: memberlist + {{- if .MemberList.EnableIPv6 }} + enable_inet6: true + {{- end}} distributor: receivers: {{- if not .Gateway }} @@ -89,11 +92,14 @@ ingester: store: memberlist replication_factor: {{ .ReplicationFactor }} tokens_file_path: /var/tempo/tokens.json + {{- if .MemberList.EnableIPv6 }} + enable_inet6: true + {{- end}} max_block_duration: 10m memberlist: abort_if_cluster_join_fails: false join_members: - {{- range .MemberList }} + {{- range .MemberList.JoinMembers }} - {{ . }} {{- end }} multitenancy_enabled: {{ .Multitenancy }}