diff --git a/Documentation/CRDs/specification.md b/Documentation/CRDs/specification.md
index d22daa969..704d81947 100644
--- a/Documentation/CRDs/specification.md
+++ b/Documentation/CRDs/specification.md
@@ -4032,6 +4032,18 @@ int64
+
hostNetwork
bool
diff --git a/deploy/charts/rook-ceph/templates/resources.yaml b/deploy/charts/rook-ceph/templates/resources.yaml
index aac9a8ee8..a6ffe9f4c 100644
--- a/deploy/charts/rook-ceph/templates/resources.yaml
+++ b/deploy/charts/rook-ceph/templates/resources.yaml
@@ -2929,6 +2929,12 @@ spec:
description: Only performance counters greater than or equal to this option are fetched
format: int64
type: integer
+ port:
+ description: Port is the listening port of the ceph-exporter process. Defaults to 9926.
+ format: int32
+ maximum: 65535
+ minimum: 1
+ type: integer
statsPeriodSeconds:
default: 5
description: Time to wait before sending requests again to exporter server (seconds)
diff --git a/deploy/examples/crds.yaml b/deploy/examples/crds.yaml
index 42f56a6bd..53a745702 100644
--- a/deploy/examples/crds.yaml
+++ b/deploy/examples/crds.yaml
@@ -2927,6 +2927,12 @@ spec:
description: Only performance counters greater than or equal to this option are fetched
format: int64
type: integer
+ port:
+ description: Port is the listening port of the ceph-exporter process. Defaults to 9926.
+ format: int32
+ maximum: 65535
+ minimum: 1
+ type: integer
statsPeriodSeconds:
default: 5
description: Time to wait before sending requests again to exporter server (seconds)
diff --git a/pkg/apis/ceph.rook.io/v1/types.go b/pkg/apis/ceph.rook.io/v1/types.go
index affb98aa9..cd11d39c1 100755
--- a/pkg/apis/ceph.rook.io/v1/types.go
+++ b/pkg/apis/ceph.rook.io/v1/types.go
@@ -508,6 +508,12 @@ type CephExporterSpec struct {
// +kubebuilder:default=5
StatsPeriodSeconds int64 `json:"statsPeriodSeconds,omitempty"`
+ // Port is the listening port of the ceph-exporter process. Defaults to 9926.
+ // +kubebuilder:validation:Minimum=1
+ // +kubebuilder:validation:Maximum=65535
+ // +optional
+ Port int32 `json:"port,omitempty"`
+
// Whether host networking is enabled for CephExporter. If not set, the network settings from CephCluster.spec.networking will be applied.
// +nullable
// +optional
diff --git a/pkg/operator/ceph/cluster/nodedaemon/exporter.go b/pkg/operator/ceph/cluster/nodedaemon/exporter.go
index 62828b396..90d9c99a7 100644
--- a/pkg/operator/ceph/cluster/nodedaemon/exporter.go
+++ b/pkg/operator/ceph/cluster/nodedaemon/exporter.go
@@ -178,6 +178,13 @@ func getCephExporterChownInitContainer(cephCluster cephv1.CephCluster) corev1.Co
)
}
+func getExporterMetricsPort(cephCluster cephv1.CephCluster) int32 {
+ if cephCluster.Spec.Monitoring.Exporter != nil && cephCluster.Spec.Monitoring.Exporter.Port != 0 {
+ return cephCluster.Spec.Monitoring.Exporter.Port
+ }
+ return int32(DefaultMetricsPort)
+}
+
func getCephExporterDaemonContainer(cephCluster cephv1.CephCluster, cephVersion cephver.CephVersion) corev1.Container {
cephImage := cephCluster.Spec.CephVersion.Image
dataPathMap := config.NewDatalessDaemonDataPathMap(cephCluster.GetNamespace(), cephCluster.Spec.DataDirHostPath)
@@ -187,6 +194,7 @@ func getCephExporterDaemonContainer(cephCluster cephv1.CephCluster, cephVersion
exporterEnvVar := generateExporterEnvVar()
envVars := append(controller.DaemonEnvVars(&cephCluster.Spec), exporterEnvVar)
+ metricsPort := getExporterMetricsPort(cephCluster)
prioLimit, statsPeriod := defaultPrioLimit, defaultStatsPeriod
if cephCluster.Spec.Monitoring.Exporter != nil {
prioLimit = strconv.Itoa(int(cephCluster.Spec.Monitoring.Exporter.PerfCountersPrioLimit))
@@ -194,7 +202,7 @@ func getCephExporterDaemonContainer(cephCluster cephv1.CephCluster, cephVersion
}
args := []string{
"--sock-dir", sockDir,
- "--port", strconv.Itoa(int(DefaultMetricsPort)),
+ "--port", strconv.Itoa(int(metricsPort)),
"--prio-limit", prioLimit,
"--stats-period", statsPeriod,
}
@@ -206,7 +214,7 @@ func getCephExporterDaemonContainer(cephCluster cephv1.CephCluster, cephVersion
containerPort := corev1.ContainerPort{
Name: "http-metrics",
- ContainerPort: int32(DefaultMetricsPort),
+ ContainerPort: metricsPort,
Protocol: corev1.ProtocolTCP,
}
@@ -241,7 +249,7 @@ func MakeCephExporterMetricsService(cephCluster cephv1.CephCluster, servicePortM
Ports: []corev1.ServicePort{
{
Name: servicePortMetricName,
- Port: int32(DefaultMetricsPort),
+ Port: getExporterMetricsPort(cephCluster),
Protocol: corev1.ProtocolTCP,
},
},
@@ -304,7 +312,7 @@ func applyPrometheusAnnotations(cephCluster cephv1.CephCluster, objectMeta *meta
if len(cephv1.GetCephExporterAnnotations(cephCluster.Spec.Annotations)) == 0 {
t := cephv1.Annotations{
"prometheus.io/scrape": "true",
- "prometheus.io/port": strconv.Itoa(int(DefaultMetricsPort)),
+ "prometheus.io/port": strconv.Itoa(int(getExporterMetricsPort(cephCluster))),
}
t.ApplyToObjectMeta(objectMeta)
diff --git a/pkg/operator/ceph/cluster/nodedaemon/exporter_test.go b/pkg/operator/ceph/cluster/nodedaemon/exporter_test.go
index 5b81e4a7b..bc3ed4a5c 100644
--- a/pkg/operator/ceph/cluster/nodedaemon/exporter_test.go
+++ b/pkg/operator/ceph/cluster/nodedaemon/exporter_test.go
@@ -41,6 +41,10 @@ import (
)
func assertCephExporterArgs(t *testing.T, args []string, ipv6 bool) {
+ assertCephExporterArgsWithPort(t, args, ipv6, "9926")
+}
+
+func assertCephExporterArgsWithPort(t *testing.T, args []string, ipv6 bool, port string) {
var expectedArgsLen int
if ipv6 {
expectedArgsLen = 10
@@ -53,7 +57,7 @@ func assertCephExporterArgs(t *testing.T, args []string, ipv6 bool) {
assert.Equal(t, "--sock-dir", args[0])
assert.Equal(t, "/run/ceph", args[1])
assert.Equal(t, "--port", args[2])
- assert.Equal(t, "9926", args[3])
+ assert.Equal(t, port, args[3])
assert.Equal(t, "--prio-limit", args[4])
assert.Equal(t, "5", args[5])
assert.Equal(t, "--stats-period", args[6])
@@ -144,6 +148,25 @@ func TestCreateOrUpdateCephExporter(t *testing.T) {
assert.Equal(t, "--stats-period", args[6])
assert.Equal(t, "7", args[7])
})
+
+ t.Run("exporter custom port", func(t *testing.T) {
+ cephCluster.Spec.Monitoring.Exporter = &cephv1.CephExporterSpec{
+ PerfCountersPrioLimit: 5,
+ StatsPeriodSeconds: 5,
+ Port: 9927,
+ }
+ res, err := r.createOrUpdateCephExporter(node, tolerations, cephCluster, cephVersion)
+ assert.NoError(t, err)
+ assert.Equal(t, controllerutil.OperationResult("updated"), res)
+
+ err = r.client.Get(ctx, types.NamespacedName{Namespace: "rook-ceph", Name: name}, &deploy)
+ assert.NoError(t, err)
+
+ podSpec := deploy.Spec.Template
+ args := podSpec.Spec.Containers[0].Args
+ assertCephExporterArgsWithPort(t, args, false, "9927")
+ assert.Equal(t, int32(9927), podSpec.Spec.Containers[0].Ports[0].ContainerPort)
+ })
}
func TestCephExporterLogrotateContainer(t *testing.T) {
@@ -408,8 +431,17 @@ func TestServiceSpec(t *testing.T) {
assert.NotNil(t, s)
assert.Equal(t, "rook-ceph-exporter", s.Name)
assert.Equal(t, 1, len(s.Spec.Ports))
+ assert.Equal(t, int32(DefaultMetricsPort), s.Spec.Ports[0].Port)
assert.Equal(t, 2, len(s.Labels))
assert.Equal(t, 2, len(s.Spec.Selector))
+
+ t.Run("custom exporter port", func(t *testing.T) {
+ cephCluster.Spec.Monitoring.Exporter = &cephv1.CephExporterSpec{Port: 9927}
+ s, err := MakeCephExporterMetricsService(cephCluster, exporterServiceMetricName, scheme.Scheme)
+ assert.NoError(t, err)
+ assert.NotNil(t, s)
+ assert.Equal(t, int32(9927), s.Spec.Ports[0].Port)
+ })
}
func TestApplyCephExporterLabels(t *testing.T) {
|