diff --git a/Dockerfile.combined b/Dockerfile.combined index 32c9604d1..535cdc82d 100644 --- a/Dockerfile.combined +++ b/Dockerfile.combined @@ -19,12 +19,15 @@ COPY pkg/ pkg/ # Build RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o manager main.go RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o vgmanager cmd/vgmanager/main.go +RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o metricsexporter cmd/metricsexporter/exporter.go # vgmanager needs 'nsenter' and other basic linux utils to correctly function FROM centos:8 WORKDIR / COPY --from=builder /workspace/manager . COPY --from=builder /workspace/vgmanager . +COPY --from=builder /workspace/metricsexporter . +EXPOSE 23532 USER 65532:65532 # '/manager' is lvm-operator entrypoint diff --git a/cmd/metricsexporter/exporter.go b/cmd/metricsexporter/exporter.go new file mode 100644 index 000000000..8bf6e311e --- /dev/null +++ b/cmd/metricsexporter/exporter.go @@ -0,0 +1,96 @@ +/* +Copyright 2021. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +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 main + +import ( + "flag" + "net" + "net/http" + "os" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" + "github.com/prometheus/client_golang/prometheus/promhttp" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +var ( + exporterNamespace string + exporterAddress string + kubeconfigPath string + kubeAPIServerURL string +) + +type lvmCollector struct{} + +func (lc *lvmCollector) Describe(c chan<- *prometheus.Desc) {} +func (lc *lvmCollector) Collect(c chan<- prometheus.Metric) {} + +func main() { + lvmExpFlags := flag.NewFlagSet("lvm-metrics-exporter", flag.ExitOnError) + lvmExpFlags.StringVar(&exporterNamespace, "namespace", "lvm-exporter", + "set the namespace of the lvm metric exporter") + lvmExpFlags.StringVar(&exporterAddress, "address", ":23532", + "address on which the metrics exporter should run") + lvmExpFlags.StringVar(&kubeconfigPath, "kubeconfig", "", "Path to kubeconfig file") + lvmExpFlags.StringVar(&kubeAPIServerURL, "apiserver", "", "API server URL") + + zapOptions := &zap.Options{} + zapOptions.BindFlags(lvmExpFlags) + + _ = lvmExpFlags.Parse(os.Args[1:]) + + zapOpts := zap.UseFlagOptions(zapOptions) + newLogger := zap.New(zapOpts).WithName("lvm-metric-exporter") + newLogger.Info("Commandline: ", "args", os.Args[1:]) + newLogger.Info("Exporter set values: ", "namespace", exporterNamespace, "address", exporterAddress) + + prometheus.MustRegister(&lvmCollector{}) + + // prometheus http handler + http.Handle("/metrics", promhttp.Handler()) + http.HandleFunc("/", func(rw http.ResponseWriter, r *http.Request) { + _, err := rw.Write([]byte(` + LVM Metric Exporter + +

LVM Metric Exporter

+

Metrics

+ + `)) + if err != nil { + newLogger.Error(err, "error while writing into http.ResponseWriter") + return + } + }) + + // prometheus metrics + _ = promauto.NewGauge(prometheus.GaugeOpts{ + Name: "lvmoptest", + Help: "this is a test gauge metrics", + }) + + // runtime loop + newLogger.Info("Starting lvm metric exporter at ", "address", exporterAddress) + ln, err := net.Listen("tcp", exporterAddress) + if err != nil { + newLogger.Error(err, "Error creating the listener") + } + err = http.Serve(ln, nil) + if err != nil { + newLogger.Error(err, "Error while serving requests") + } +} diff --git a/config/default/kustomization.yaml b/config/default/kustomization.yaml index 2f0ed842e..727f702a7 100644 --- a/config/default/kustomization.yaml +++ b/config/default/kustomization.yaml @@ -17,8 +17,6 @@ namespace: lvm-operator-system #- ../webhook # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required. #- ../certmanager -# [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. -#- ../prometheus # Protect the /metrics endpoint by putting it behind auth. # If you want your controller-manager to expose the /metrics @@ -46,6 +44,7 @@ resources: - ../crd - ../rbac - ../manager +- ../prometheus images: - name: rbac-proxy newName: gcr.io/kubebuilder/kube-rbac-proxy diff --git a/config/manager/manager.yaml b/config/manager/manager.yaml index d5d882d17..937caa7ef 100644 --- a/config/manager/manager.yaml +++ b/config/manager/manager.yaml @@ -21,6 +21,7 @@ spec: metadata: labels: control-plane: controller-manager + exporter: lvm-operator spec: securityContext: runAsNonRoot: true @@ -66,5 +67,9 @@ spec: envFrom: - configMapRef: name: lvm-operator-manager-config + - command: + - /metricsexporter + image: controller:latest + name: metricsexporter serviceAccountName: controller-manager terminationGracePeriodSeconds: 10 diff --git a/config/prometheus/monitor.yaml b/config/prometheus/monitor.yaml index d19136ae7..4d0c74c3e 100644 --- a/config/prometheus/monitor.yaml +++ b/config/prometheus/monitor.yaml @@ -5,16 +5,22 @@ kind: ServiceMonitor metadata: labels: control-plane: controller-manager - name: controller-manager-metrics-monitor + name: lvm-operator-controller-manager-metrics-monitor namespace: system spec: endpoints: - path: /metrics - port: https - scheme: https + port: topolvm-metrics + scheme: http + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + tlsConfig: + insecureSkipVerify: true + - path: /metrics + port: lvm-metrics + scheme: http bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token tlsConfig: insecureSkipVerify: true selector: matchLabels: - control-plane: controller-manager + app.kubernetes.io/compose: metrics diff --git a/config/rbac/kustomization.yaml b/config/rbac/kustomization.yaml index 3f85e52f4..580e6919b 100644 --- a/config/rbac/kustomization.yaml +++ b/config/rbac/kustomization.yaml @@ -13,7 +13,12 @@ resources: - topolvm_controller_service_account.yaml - topolvm_controller_role.yaml - topolvm_controller_role_bindings.yaml -# topolvm-node rbac +# lvm-node metric rbac +- lvm_metric_service_config.yaml +- lvm_node_role_n_rolebindings.yaml +# topolvm-node metric rbac +- topolvm_metric_service_config.yaml +- topolvm_node_role_n_rolebindings.yaml - topolvm_node_service_account.yaml - topolvm_node_role.yaml - topolvm_node_role_bindings.yaml diff --git a/config/rbac/lvm_metric_service_config.yaml b/config/rbac/lvm_metric_service_config.yaml new file mode 100644 index 000000000..0dd9b8e3a --- /dev/null +++ b/config/rbac/lvm_metric_service_config.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: lvm-node-metrics + namespace: system + labels: + app.kubernetes.io/compose: metrics +spec: + selector: + exporter: lvm-operator + ports: + - name: lvm-metrics + protocol: TCP + port: 23532 + targetPort: 23532 diff --git a/config/rbac/lvm_node_role_n_rolebindings.yaml b/config/rbac/lvm_node_role_n_rolebindings.yaml new file mode 100644 index 000000000..8c3a9fc15 --- /dev/null +++ b/config/rbac/lvm_node_role_n_rolebindings.yaml @@ -0,0 +1,31 @@ +--- +kind: Role +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: lvm-metrics + namespace: system +rules: + - apiGroups: + - "" + resources: + - services + - endpoints + - pods + verbs: + - get + - list + - watch +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: lvm-metrics + namespace: system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: lvm-metrics +subjects: +- kind: ServiceAccount + name: prometheus-k8s + namespace: openshift-monitoring diff --git a/config/rbac/topolvm_metric_service_config.yaml b/config/rbac/topolvm_metric_service_config.yaml new file mode 100644 index 000000000..15b16bf52 --- /dev/null +++ b/config/rbac/topolvm_metric_service_config.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: topolvm-node-metrics + namespace: system + labels: + app.kubernetes.io/compose: metrics +spec: + selector: + app: topolvm-node + ports: + - name: topolvm-metrics + protocol: TCP + port: 8080 + targetPort: 8080 diff --git a/config/rbac/topolvm_node_role_n_rolebindings.yaml b/config/rbac/topolvm_node_role_n_rolebindings.yaml new file mode 100644 index 000000000..c6c70907c --- /dev/null +++ b/config/rbac/topolvm_node_role_n_rolebindings.yaml @@ -0,0 +1,31 @@ +--- +kind: Role +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: topolvm-metrics + namespace: system +rules: + - apiGroups: + - "" + resources: + - services + - endpoints + - pods + verbs: + - get + - list + - watch +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: topolvm-metrics + namespace: system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: topolvm-metrics +subjects: +- kind: ServiceAccount + name: prometheus-k8s + namespace: openshift-monitoring diff --git a/go.mod b/go.mod index d3d8f5c4e..aad02ed4c 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/onsi/gomega v1.15.0 github.com/openshift/api v0.0.0-20211028023115-7224b732cc14 github.com/openshift/client-go v0.0.0-20210831095141-e19a065e79f7 + github.com/prometheus/client_golang v1.11.0 github.com/stretchr/testify v1.7.0 github.com/topolvm/topolvm v0.10.3 gotest.tools/v3 v3.0.3