diff --git a/assets/optional/metrics-server/00-namespace.yaml b/assets/optional/metrics-server/00-namespace.yaml new file mode 100644 index 0000000000..17f727565a --- /dev/null +++ b/assets/optional/metrics-server/00-namespace.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: openshift-monitoring + labels: + name: openshift-monitoring + pod-security.kubernetes.io/enforce: privileged + pod-security.kubernetes.io/audit: privileged + pod-security.kubernetes.io/warn: privileged diff --git a/assets/optional/metrics-server/01-cluster-role-binding-auth-delegator.yaml b/assets/optional/metrics-server/01-cluster-role-binding-auth-delegator.yaml new file mode 100644 index 0000000000..fad58afef1 --- /dev/null +++ b/assets/optional/metrics-server/01-cluster-role-binding-auth-delegator.yaml @@ -0,0 +1,17 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/component: metrics-server + app.kubernetes.io/managed-by: cluster-monitoring-operator + app.kubernetes.io/name: auth-delegator + app.kubernetes.io/part-of: openshift-monitoring + name: metrics-server:system:auth-delegator +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:auth-delegator +subjects: +- kind: ServiceAccount + name: metrics-server + namespace: openshift-monitoring diff --git a/assets/optional/metrics-server/01-cluster-role-binding.yaml b/assets/optional/metrics-server/01-cluster-role-binding.yaml new file mode 100644 index 0000000000..8a32b85158 --- /dev/null +++ b/assets/optional/metrics-server/01-cluster-role-binding.yaml @@ -0,0 +1,18 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/managed-by: cluster-monitoring-operator + app.kubernetes.io/name: metrics-server + app.kubernetes.io/part-of: openshift-monitoring + name: system:metrics-server +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:metrics-server +subjects: +- kind: ServiceAccount + name: metrics-server + namespace: openshift-monitoring +- kind: User + name: system:metrics-server diff --git a/assets/optional/metrics-server/01-cluster-role.yaml b/assets/optional/metrics-server/01-cluster-role.yaml new file mode 100644 index 0000000000..19be5ca4b0 --- /dev/null +++ b/assets/optional/metrics-server/01-cluster-role.yaml @@ -0,0 +1,25 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: metrics-server + app.kubernetes.io/managed-by: cluster-monitoring-operator + app.kubernetes.io/name: metrics-server + app.kubernetes.io/part-of: openshift-monitoring + name: system:metrics-server +rules: +- apiGroups: + - "" + resources: + - nodes/metrics + verbs: + - get +- apiGroups: + - "" + resources: + - pods + - nodes + verbs: + - get + - list + - watch diff --git a/assets/optional/metrics-server/01-role-binding-auth-reader.yaml b/assets/optional/metrics-server/01-role-binding-auth-reader.yaml new file mode 100644 index 0000000000..6b11a238ce --- /dev/null +++ b/assets/optional/metrics-server/01-role-binding-auth-reader.yaml @@ -0,0 +1,18 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: metrics-server + app.kubernetes.io/managed-by: cluster-monitoring-operator + app.kubernetes.io/name: metrics-server-auth-reader + app.kubernetes.io/part-of: openshift-monitoring + name: metrics-server-auth-reader + namespace: kube-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: extension-apiserver-authentication-reader +subjects: +- kind: ServiceAccount + name: metrics-server + namespace: openshift-monitoring diff --git a/assets/optional/metrics-server/01-service-account.yaml b/assets/optional/metrics-server/01-service-account.yaml new file mode 100644 index 0000000000..310685e790 --- /dev/null +++ b/assets/optional/metrics-server/01-service-account.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: metrics-server + app.kubernetes.io/managed-by: cluster-monitoring-operator + app.kubernetes.io/name: metrics-server + app.kubernetes.io/part-of: openshift-monitoring + name: metrics-server + namespace: openshift-monitoring diff --git a/assets/optional/metrics-server/02-configmap-audit-profiles.yaml b/assets/optional/metrics-server/02-configmap-audit-profiles.yaml new file mode 100644 index 0000000000..1cff598a6d --- /dev/null +++ b/assets/optional/metrics-server/02-configmap-audit-profiles.yaml @@ -0,0 +1,45 @@ +apiVersion: v1 +data: + metadata-profile.yaml: |- + "apiVersion": "audit.k8s.io/v1" + "kind": "Policy" + "metadata": + "name": "Metadata" + "omitStages": + - "RequestReceived" + "rules": + - "level": "Metadata" + none-profile.yaml: |- + "apiVersion": "audit.k8s.io/v1" + "kind": "Policy" + "metadata": + "name": "None" + "omitStages": + - "RequestReceived" + "rules": + - "level": "None" + request-profile.yaml: |- + "apiVersion": "audit.k8s.io/v1" + "kind": "Policy" + "metadata": + "name": "Request" + "omitStages": + - "RequestReceived" + "rules": + - "level": "Request" + requestresponse-profile.yaml: |- + "apiVersion": "audit.k8s.io/v1" + "kind": "Policy" + "metadata": + "name": "RequestResponse" + "omitStages": + - "RequestReceived" + "rules": + - "level": "RequestResponse" +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/managed-by: cluster-monitoring-operator + app.kubernetes.io/part-of: openshift-monitoring + name: metrics-server-audit-profiles + namespace: openshift-monitoring diff --git a/assets/optional/metrics-server/03-deployment.yaml b/assets/optional/metrics-server/03-deployment.yaml new file mode 100644 index 0000000000..23cdafb3e1 --- /dev/null +++ b/assets/optional/metrics-server/03-deployment.yaml @@ -0,0 +1,114 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: metrics-server + app.kubernetes.io/managed-by: cluster-monitoring-operator + app.kubernetes.io/name: metrics-server + app.kubernetes.io/part-of: openshift-monitoring + name: metrics-server + namespace: openshift-monitoring +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/component: metrics-server + app.kubernetes.io/name: metrics-server + app.kubernetes.io/part-of: openshift-monitoring + strategy: + type: Recreate + template: + metadata: + annotations: + openshift.io/required-scc: restricted-v2 + target.workload.openshift.io/management: '{"effect": "PreferredDuringScheduling"}' + labels: + app.kubernetes.io/component: metrics-server + app.kubernetes.io/name: metrics-server + app.kubernetes.io/part-of: openshift-monitoring + spec: + containers: + - args: + - --secure-port=10250 + - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname + - --kubelet-use-node-status-port + - --metric-resolution=15s + - --kubelet-certificate-authority=/etc/tls/kubelet-serving-ca-bundle/ca-bundle.crt + - --kubelet-client-certificate=/etc/tls/metrics-server-client-certs/tls.crt + - --kubelet-client-key=/etc/tls/metrics-server-client-certs/tls.key + - --tls-cert-file=/etc/tls/private/tls.crt + - --tls-private-key-file=/etc/tls/private/tls.key + - --tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 + - --shutdown-send-retry-after=true + - --shutdown-delay-duration=150s + - --disable-http2-serving=true + image: quay.io/openshift/kube-metrics-server + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: /livez + port: https + scheme: HTTPS + periodSeconds: 10 + name: metrics-server + ports: + - containerPort: 10250 + name: https + protocol: TCP + readinessProbe: + failureThreshold: 6 + httpGet: + path: /readyz + port: https + scheme: HTTPS + initialDelaySeconds: 20 + periodSeconds: 20 + resources: + requests: + cpu: 1m + memory: 40Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - mountPath: /etc/tls/private + name: secret-metrics-server-tls + - mountPath: /etc/tls/metrics-server-client-certs + name: secret-metrics-server-client-certs + - mountPath: /etc/tls/kubelet-serving-ca-bundle + name: configmap-kubelet-serving-ca-bundle + - mountPath: /etc/audit + name: metrics-server-audit-profiles + readOnly: true + - mountPath: /var/log/metrics-server + name: audit-log + readOnly: false + nodeSelector: + kubernetes.io/os: linux + priorityClassName: system-cluster-critical + serviceAccountName: metrics-server + terminationGracePeriodSeconds: 170 + tolerations: + - effect: NoSchedule + key: node-role.kubernetes.io/master + volumes: + - name: secret-metrics-server-client-certs + secret: + secretName: metrics-server-client-certs + - name: secret-metrics-server-tls + secret: + secretName: metrics-server-tls + - configMap: + name: kubelet-serving-ca-bundle + name: configmap-kubelet-serving-ca-bundle + - emptyDir: {} + name: audit-log + - configMap: + name: metrics-server-audit-profiles + name: metrics-server-audit-profiles diff --git a/assets/optional/metrics-server/04-api-service.yaml b/assets/optional/metrics-server/04-api-service.yaml new file mode 100644 index 0000000000..54303f0d9d --- /dev/null +++ b/assets/optional/metrics-server/04-api-service.yaml @@ -0,0 +1,21 @@ +apiVersion: apiregistration.k8s.io/v1 +kind: APIService +metadata: + annotations: + service.beta.openshift.io/inject-cabundle: "true" + labels: + app.kubernetes.io/component: metrics-server + app.kubernetes.io/managed-by: cluster-monitoring-operator + app.kubernetes.io/name: metrics-server + app.kubernetes.io/part-of: openshift-monitoring + name: v1beta1.metrics.k8s.io +spec: + group: metrics.k8s.io + groupPriorityMinimum: 100 + insecureSkipTLSVerify: false + service: + name: metrics-server + namespace: openshift-monitoring + port: 443 + version: v1beta1 + versionPriority: 100 diff --git a/assets/optional/metrics-server/04-service.yaml b/assets/optional/metrics-server/04-service.yaml new file mode 100644 index 0000000000..3a485b2dad --- /dev/null +++ b/assets/optional/metrics-server/04-service.yaml @@ -0,0 +1,22 @@ +apiVersion: v1 +kind: Service +metadata: + annotations: + openshift.io/description: Expose the metrics-server web server on port 443. This port is for internal use, and no other usage is guaranteed. + service.beta.openshift.io/serving-cert-secret-name: metrics-server-tls + labels: + app.kubernetes.io/component: metrics-server + app.kubernetes.io/managed-by: cluster-monitoring-operator + app.kubernetes.io/name: metrics-server + app.kubernetes.io/part-of: openshift-monitoring + name: metrics-server + namespace: openshift-monitoring +spec: + ports: + - name: https + port: 443 + protocol: TCP + targetPort: https + selector: + app.kubernetes.io/name: metrics-server + app.kubernetes.io/part-of: openshift-monitoring diff --git a/assets/optional/metrics-server/kustomization.aarch64.yaml b/assets/optional/metrics-server/kustomization.aarch64.yaml new file mode 100644 index 0000000000..e80886329f --- /dev/null +++ b/assets/optional/metrics-server/kustomization.aarch64.yaml @@ -0,0 +1,4 @@ +images: + - name: quay.io/openshift/kube-metrics-server + newName: quay.io/openshift-release-dev/ocp-v5.0-art-dev + digest: sha256:35daed97a2d279f2543334cfb209f81be440e423042cc7dae6784985d71f2f8d diff --git a/assets/optional/metrics-server/kustomization.x86_64.yaml b/assets/optional/metrics-server/kustomization.x86_64.yaml new file mode 100644 index 0000000000..831caab705 --- /dev/null +++ b/assets/optional/metrics-server/kustomization.x86_64.yaml @@ -0,0 +1,4 @@ +images: + - name: quay.io/openshift/kube-metrics-server + newName: quay.io/openshift-release-dev/ocp-v5.0-art-dev + digest: sha256:cb84656c5b900f21b7984f917ac0473cf7b5e58cd1ec7d782b01fbe99d39bee7 diff --git a/assets/optional/metrics-server/kustomization.yaml b/assets/optional/metrics-server/kustomization.yaml new file mode 100644 index 0000000000..ca034994ff --- /dev/null +++ b/assets/optional/metrics-server/kustomization.yaml @@ -0,0 +1,13 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - 00-namespace.yaml + - 01-service-account.yaml + - 01-cluster-role.yaml + - 01-cluster-role-binding.yaml + - 01-cluster-role-binding-auth-delegator.yaml + - 01-role-binding-auth-reader.yaml + - 02-configmap-audit-profiles.yaml + - 03-deployment.yaml + - 04-service.yaml + - 04-api-service.yaml diff --git a/assets/optional/metrics-server/release-metrics-server-aarch64.json b/assets/optional/metrics-server/release-metrics-server-aarch64.json new file mode 100644 index 0000000000..c748ed629d --- /dev/null +++ b/assets/optional/metrics-server/release-metrics-server-aarch64.json @@ -0,0 +1,8 @@ +{ + "release": { + "base": "placeholder" + }, + "images": { + "metrics_server": "quay.io/openshift-release-dev/ocp-v5.0-art-dev@sha256:35daed97a2d279f2543334cfb209f81be440e423042cc7dae6784985d71f2f8d" + } +} diff --git a/assets/optional/metrics-server/release-metrics-server-x86_64.json b/assets/optional/metrics-server/release-metrics-server-x86_64.json new file mode 100644 index 0000000000..1a15957d8c --- /dev/null +++ b/assets/optional/metrics-server/release-metrics-server-x86_64.json @@ -0,0 +1,8 @@ +{ + "release": { + "base": "placeholder" + }, + "images": { + "metrics_server": "quay.io/openshift-release-dev/ocp-v5.0-art-dev@sha256:cb84656c5b900f21b7984f917ac0473cf7b5e58cd1ec7d782b01fbe99d39bee7" + } +} diff --git a/etcd/vendor/github.com/openshift/microshift/pkg/config/config.go b/etcd/vendor/github.com/openshift/microshift/pkg/config/config.go index 28cd90d5e0..c4902cae86 100644 --- a/etcd/vendor/github.com/openshift/microshift/pkg/config/config.go +++ b/etcd/vendor/github.com/openshift/microshift/pkg/config/config.go @@ -445,6 +445,24 @@ func (c *Config) incorporateUserSettings(u *Config) { c.DNS.Hosts.File = u.DNS.Hosts.File } } + + // DNS resource configuration - merge key-by-key to preserve defaults + if u.DNS.Resources.Requests != nil { + if c.DNS.Resources.Requests == nil { + c.DNS.Resources.Requests = make(map[string]string) + } + for k, v := range u.DNS.Resources.Requests { + c.DNS.Resources.Requests[k] = v + } + } + if u.DNS.Resources.Limits != nil { + if c.DNS.Resources.Limits == nil { + c.DNS.Resources.Limits = make(map[string]string) + } + for k, v := range u.DNS.Resources.Limits { + c.DNS.Resources.Limits[k] = v + } + } if u.ApiServer.FeatureGates.FeatureSet != "" { c.ApiServer.FeatureGates.FeatureSet = u.ApiServer.FeatureGates.FeatureSet } diff --git a/etcd/vendor/github.com/openshift/microshift/pkg/config/dns.go b/etcd/vendor/github.com/openshift/microshift/pkg/config/dns.go index b567cbbc08..cbd5372b46 100644 --- a/etcd/vendor/github.com/openshift/microshift/pkg/config/dns.go +++ b/etcd/vendor/github.com/openshift/microshift/pkg/config/dns.go @@ -4,6 +4,8 @@ import ( "fmt" "os" "path/filepath" + + "k8s.io/apimachinery/pkg/api/resource" ) const ( @@ -13,6 +15,20 @@ const ( type HostsStatusEnum string +// DNSResources configures the CPU and memory resources for the dns container +// in the dns-default DaemonSet. +type DNSResources struct { + // Requests specifies the minimum resources required for the dns container. + // Valid keys are "cpu" and "memory". Values must be valid Kubernetes resource quantities. + // When not set, defaults to cpu=50m, memory=70Mi. + Requests map[string]string `json:"requests,omitempty"` + + // Limits specifies the maximum resources the dns container can use. + // Valid keys are "cpu" and "memory". Values must be valid Kubernetes resource quantities. + // When not set, no limits are applied. + Limits map[string]string `json:"limits,omitempty"` +} + type DNS struct { // baseDomain is the base domain of the cluster. All managed DNS records will // be sub-domains of this base. @@ -38,6 +54,9 @@ type DNS struct { // Hosts contains configuration for the hosts file. Hosts HostsConfig `json:"hosts,omitempty"` + + // Resources configures the CPU and memory resources for the dns container. + Resources DNSResources `json:"resources,omitempty"` } // HostsConfig contains configuration for the hosts file . @@ -64,6 +83,12 @@ func dnsDefaults() DNS { File: "/etc/hosts", Status: HostsStatusDisabled, }, + Resources: DNSResources{ + Requests: map[string]string{ + "cpu": "50m", + "memory": "70Mi", + }, + }, } } @@ -76,7 +101,10 @@ func (t *DNS) validate() error { return err } - return t.validateHosts() + if err := t.validateHosts(); err != nil { + return err + } + return t.validateResources() } func (t *DNS) validateConfigFile() error { @@ -90,7 +118,7 @@ func (t *DNS) validateHosts() error { switch t.Hosts.Status { case HostsStatusEnabled: if t.Hosts.File == "" { - break + return nil } return validateFilePath(t.Hosts.File, "hosts file") case HostsStatusDisabled: @@ -98,6 +126,54 @@ func (t *DNS) validateHosts() error { default: return fmt.Errorf("invalid hosts status: %s", t.Hosts.Status) } +} + +func dnsMinimumRequests() map[string]resource.Quantity { + defaults := dnsDefaults() + mins := make(map[string]resource.Quantity, len(defaults.Resources.Requests)) + for k, v := range defaults.Resources.Requests { + mins[k] = resource.MustParse(v) + } + return mins +} + +func (t *DNS) validateResources() error { + allowed := map[string]struct{}{ + "cpu": {}, + "memory": {}, + } + mins := dnsMinimumRequests() + for key, val := range t.Resources.Requests { + if _, ok := allowed[key]; !ok { + return fmt.Errorf("unsupported dns resource request key %q: allowed keys are cpu, memory", key) + } + qty, err := resource.ParseQuantity(val) + if err != nil { + return fmt.Errorf("invalid dns resource request %s=%q: %v", key, val, err) + } + if minQty, ok := mins[key]; ok && qty.Cmp(minQty) < 0 { + return fmt.Errorf("dns resource request %s=%q is below minimum %s", key, val, minQty.String()) + } + } + for key, val := range t.Resources.Limits { + if _, ok := allowed[key]; !ok { + return fmt.Errorf("unsupported dns resource limit key %q: allowed keys are cpu, memory", key) + } + if _, err := resource.ParseQuantity(val); err != nil { + return fmt.Errorf("invalid dns resource limit %s=%q: %v", key, val, err) + } + } + for key, limitVal := range t.Resources.Limits { + reqVal, ok := t.Resources.Requests[key] + if !ok { + continue + } + limit := resource.MustParse(limitVal) + req := resource.MustParse(reqVal) + if limit.Cmp(req) < 0 { + return fmt.Errorf("dns resource limit %s=%q must be greater than or equal to request %s=%q", key, limitVal, key, reqVal) + } + } return nil } diff --git a/etcd/vendor/github.com/openshift/microshift/pkg/util/cryptomaterial/certinfo.go b/etcd/vendor/github.com/openshift/microshift/pkg/util/cryptomaterial/certinfo.go index aed383b9fa..4e8c50989e 100644 --- a/etcd/vendor/github.com/openshift/microshift/pkg/util/cryptomaterial/certinfo.go +++ b/etcd/vendor/github.com/openshift/microshift/pkg/util/cryptomaterial/certinfo.go @@ -74,6 +74,10 @@ func AdminKubeconfigClientCertDir(certsDir string) string { return filepath.Join(AdminKubeconfigSignerDir(certsDir), "admin-kubeconfig-client") } +func MetricsServerKubeletClientCertDir(certsDir string) string { + return filepath.Join(KubeAPIServerToKubeletSignerCertDir(certsDir), "metrics-server-kubelet-client") +} + // KubeletCSRSignerSignerCertDir returns path to the signer that signs kubelet CSRs // and the signer that signs CSRs of the CSR API func KubeletCSRSignerSignerCertDir(certsDir string) string { diff --git a/packaging/observability/microshift-observability.service b/packaging/observability/microshift-observability.service index 2fc2e984dc..826c2f86db 100644 --- a/packaging/observability/microshift-observability.service +++ b/packaging/observability/microshift-observability.service @@ -8,7 +8,7 @@ ConditionPathExists=/var/lib/microshift/resources/observability-client/kubeconfi Environment=KUBECONFIG=/var/lib/microshift/resources/observability-client/kubeconfig Environment=K8S_NODE_NAME="%l" ExecStartPre=/usr/bin/mkdir -p /var/lib/microshift-observability -ExecStart=/usr/bin/opentelemetry-collector --config=/etc/microshift/observability/opentelemetry-collector.yaml +ExecStart=/bin/bash -c 'ARGS="--config=file:/etc/microshift/observability/opentelemetry-collector.yaml"; for f in /etc/microshift/observability/otelcol.d/*.yaml; do [ -f "$$f" ] && ARGS="$$ARGS --config=file:$$f"; done; exec /usr/bin/opentelemetry-collector $$ARGS' Restart=always User=root diff --git a/packaging/observability/otelcol.d/microshift-metrics-server.yaml b/packaging/observability/otelcol.d/microshift-metrics-server.yaml new file mode 100644 index 0000000000..e18788969f --- /dev/null +++ b/packaging/observability/otelcol.d/microshift-metrics-server.yaml @@ -0,0 +1,26 @@ +receivers: + prometheus/metrics_server: + config: + scrape_configs: + - job_name: metrics-server + scrape_interval: 30s + scheme: https + tls_config: + ca_file: /var/lib/microshift/certs/service-ca/ca.crt + server_name: metrics-server.openshift-monitoring.svc + kubernetes_sd_configs: + - kubeconfig_file: /var/lib/microshift/resources/observability-client/kubeconfig + role: endpoints + namespaces: + names: [openshift-monitoring] + relabel_configs: + - source_labels: [__meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name] + action: keep + regex: metrics-server;https + +service: + pipelines: + metrics/metrics_server: + receivers: [prometheus/metrics_server] + processors: [batch] + exporters: [otlp] diff --git a/packaging/rpm/microshift.spec b/packaging/rpm/microshift.spec index 6362e4f552..e47fac2ca9 100644 --- a/packaging/rpm/microshift.spec +++ b/packaging/rpm/microshift.spec @@ -236,6 +236,7 @@ and can be used to embed those images into osbuilder blueprints or bootc contain Summary: OpenTelemetry-Collector configured for MicroShift BuildArch: noarch Requires: microshift = %{version} +Requires: microshift-metrics-server = %{version} Requires: opentelemetry-collector %description observability @@ -261,6 +262,25 @@ The microshift-cert-manager-release-info package provides release information fi release. These files contain the list of container image references used by Cert Manager and can be used to embed those images into osbuilder blueprints or bootc containerfiles. +%package metrics-server +Summary: Kubernetes metrics-server for MicroShift +ExclusiveArch: x86_64 aarch64 +Requires: microshift = %{version} + +%description metrics-server +The microshift-metrics-server package provides the metrics-server for MicroShift. +Install this package to enable kubectl top and resource metrics via the Metrics API. + +%package metrics-server-release-info +Summary: Release information for metrics-server for MicroShift +BuildArch: noarch +Requires: microshift-release-info = %{version} + +%description metrics-server-release-info +The microshift-metrics-server-release-info package provides release information files for this +release. These files contain the list of container image references used by the metrics-server +and can be used to embed those images into osbuilder blueprints or bootc containerfiles. + %package sriov Summary: SR-IOV Network Operator for MicroShift ExclusiveArch: x86_64 aarch64 @@ -562,7 +582,9 @@ install -p -m644 assets/optional/ai-model-serving/release-ai-model-serving-x86_6 # observability install -d -m755 %{buildroot}/%{_sysconfdir}/microshift/observability +install -d -m755 %{buildroot}/%{_sysconfdir}/microshift/observability/otelcol.d install -p -m644 packaging/observability/*.yaml -D %{buildroot}%{_sysconfdir}/microshift/observability/ +install -p -m644 packaging/observability/otelcol.d/microshift-metrics-server.yaml %{buildroot}%{_sysconfdir}/microshift/observability/otelcol.d/ # Explicit copy of large config as default. Not using symlink to avoid accidental package upgrade overwriting user config if the user edits the config without copying (i.e. edits the target of symlink). install -p -m644 packaging/observability/opentelemetry-collector-large.yaml -D %{buildroot}%{_sysconfdir}/microshift/observability/opentelemetry-collector.yaml install -p -m644 packaging/observability/microshift-observability.service %{buildroot}%{_unitdir}/ @@ -599,6 +621,31 @@ cat assets/optional/cert-manager/manager/images-x86_64.yaml >> %{buildroot}/%{_p mkdir -p -m755 %{buildroot}%{_datadir}/microshift/release install -p -m644 assets/optional/cert-manager/release-cert-manager-{x86_64,aarch64}.json %{buildroot}%{_datadir}/microshift/release/ +# metrics-server +install -d -m755 %{buildroot}/%{_prefix}/lib/microshift/manifests.d/080-microshift-metrics-server +install -p -m644 assets/optional/metrics-server/00-namespace.yaml %{buildroot}/%{_prefix}/lib/microshift/manifests.d/080-microshift-metrics-server +install -p -m644 assets/optional/metrics-server/01-service-account.yaml %{buildroot}/%{_prefix}/lib/microshift/manifests.d/080-microshift-metrics-server +install -p -m644 assets/optional/metrics-server/01-cluster-role.yaml %{buildroot}/%{_prefix}/lib/microshift/manifests.d/080-microshift-metrics-server +install -p -m644 assets/optional/metrics-server/01-cluster-role-binding.yaml %{buildroot}/%{_prefix}/lib/microshift/manifests.d/080-microshift-metrics-server +install -p -m644 assets/optional/metrics-server/01-cluster-role-binding-auth-delegator.yaml %{buildroot}/%{_prefix}/lib/microshift/manifests.d/080-microshift-metrics-server +install -p -m644 assets/optional/metrics-server/01-role-binding-auth-reader.yaml %{buildroot}/%{_prefix}/lib/microshift/manifests.d/080-microshift-metrics-server +install -p -m644 assets/optional/metrics-server/02-configmap-audit-profiles.yaml %{buildroot}/%{_prefix}/lib/microshift/manifests.d/080-microshift-metrics-server +install -p -m644 assets/optional/metrics-server/03-deployment.yaml %{buildroot}/%{_prefix}/lib/microshift/manifests.d/080-microshift-metrics-server +install -p -m644 assets/optional/metrics-server/04-service.yaml %{buildroot}/%{_prefix}/lib/microshift/manifests.d/080-microshift-metrics-server +install -p -m644 assets/optional/metrics-server/04-api-service.yaml %{buildroot}/%{_prefix}/lib/microshift/manifests.d/080-microshift-metrics-server +install -p -m644 assets/optional/metrics-server/kustomization.yaml %{buildroot}/%{_prefix}/lib/microshift/manifests.d/080-microshift-metrics-server + +%ifarch %{arm} aarch64 +cat assets/optional/metrics-server/kustomization.aarch64.yaml >> %{buildroot}/%{_prefix}/lib/microshift/manifests.d/080-microshift-metrics-server/kustomization.yaml +%endif +%ifarch x86_64 +cat assets/optional/metrics-server/kustomization.x86_64.yaml >> %{buildroot}/%{_prefix}/lib/microshift/manifests.d/080-microshift-metrics-server/kustomization.yaml +%endif + +# metrics-server-release-info +mkdir -p -m755 %{buildroot}%{_datadir}/microshift/release +install -p -m644 assets/optional/metrics-server/release-metrics-server-{x86_64,aarch64}.json %{buildroot}%{_datadir}/microshift/release/ + # sriov install -d -m755 %{buildroot}/%{_prefix}/lib/microshift/manifests.d/070-microshift-sriov install -d -m755 %{buildroot}/%{_prefix}/lib/microshift/manifests.d/070-microshift-sriov/crd @@ -790,10 +837,12 @@ fi %files observability %dir %{_prefix}/lib/microshift/manifests.d/003-microshift-observability %dir %{_sysconfdir}/microshift/observability/ +%dir %{_sysconfdir}/microshift/observability/otelcol.d %{_unitdir}/microshift-observability.service %config(noreplace) %{_sysconfdir}/microshift/observability/opentelemetry-collector.yaml %{_sysconfdir}/microshift/observability/opentelemetry-collector-*.yaml %{_prefix}/lib/microshift/manifests.d/003-microshift-observability/* +%config(noreplace) %{_sysconfdir}/microshift/observability/otelcol.d/microshift-metrics-server.yaml %files cert-manager %dir %{_prefix}/lib/microshift/manifests.d/060-microshift-cert-manager @@ -802,6 +851,13 @@ fi %files cert-manager-release-info %{_datadir}/microshift/release/release-cert-manager-{x86_64,aarch64}.json +%files metrics-server +%dir %{_prefix}/lib/microshift/manifests.d/080-microshift-metrics-server +%{_prefix}/lib/microshift/manifests.d/080-microshift-metrics-server/* + +%files metrics-server-release-info +%{_datadir}/microshift/release/release-metrics-server-{x86_64,aarch64}.json + %files sriov %dir %{_prefix}/lib/microshift/manifests.d/070-microshift-sriov %dir %{_prefix}/lib/microshift/manifests.d/070-microshift-sriov/crd diff --git a/pkg/cmd/init.go b/pkg/cmd/init.go index 50851ed33e..de2e2a40a3 100644 --- a/pkg/cmd/init.go +++ b/pkg/cmd/init.go @@ -155,6 +155,13 @@ func certSetup(cfg *config.Config) (*certchains.CertificateChains, error) { Validity: alignValidity(cryptomaterial.ShortLivedCertificateValidity), }, UserInfo: &user.DefaultInfo{Name: "system:kube-apiserver", Groups: []string{"kube-master"}}, + }).WithClientCertificates( + &certchains.ClientCertificateSigningRequestInfo{ + CSRMeta: certchains.CSRMeta{ + Name: "metrics-server-kubelet-client", + Validity: alignValidity(cryptomaterial.ShortLivedCertificateValidity), + }, + UserInfo: &user.DefaultInfo{Name: "system:metrics-server"}, }), // admin-kubeconfig-signer @@ -175,7 +182,7 @@ func certSetup(cfg *config.Config) (*certchains.CertificateChains, error) { Name: "openshift-observability-client", Validity: alignValidity(cryptomaterial.ShortLivedCertificateValidity), }, - UserInfo: &user.DefaultInfo{Name: "openshift-observability-client", Groups: []string{""}}, + UserInfo: &user.DefaultInfo{Name: "openshift-observability-client"}, }, ), diff --git a/pkg/cmd/metrics.go b/pkg/cmd/metrics.go new file mode 100644 index 0000000000..2e1bb08fbd --- /dev/null +++ b/pkg/cmd/metrics.go @@ -0,0 +1,120 @@ +package cmd + +import ( + "context" + "fmt" + "os" + "time" + + "github.com/openshift/microshift/pkg/config" + "github.com/openshift/microshift/pkg/util" + "github.com/openshift/microshift/pkg/util/cryptomaterial" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/tools/clientcmd" + "k8s.io/klog/v2" +) + +const metricsServerManifestPath = "/usr/lib/microshift/manifests.d/080-microshift-metrics-server" + +func provisionMetricsServerCerts(ctx context.Context, cfg *config.Config) error { + exists, err := util.PathExists(metricsServerManifestPath) + if err != nil { + return err + } + if !exists { + klog.V(2).Infof("Metrics-server manifests not found at %s, skipping cert provisioning", metricsServerManifestPath) + return nil + } + + kubeconfigPath := cfg.KubeConfigPath(config.KubeAdmin) + + restCfg, err := clientcmd.BuildConfigFromFlags("", kubeconfigPath) + if err != nil { + return fmt.Errorf("building kubeconfig: %w", err) + } + clientset, err := kubernetes.NewForConfig(restCfg) + if err != nil { + return fmt.Errorf("creating clientset: %w", err) + } + const ns = "openshift-monitoring" + err = wait.PollUntilContextTimeout(ctx, 2*time.Second, 5*time.Minute, true, func(ctx context.Context) (bool, error) { + _, err := clientset.CoreV1().Namespaces().Get(ctx, ns, metav1.GetOptions{}) + if err == nil { + return true, nil + } + if !apierrors.IsNotFound(err) { + return false, fmt.Errorf("getting namespace %s: %w", ns, err) + } + klog.V(2).Infof("Waiting for namespace %s to be created by kustomize", ns) + return false, nil + }) + if err != nil { + return fmt.Errorf("waiting for namespace %s: %w", ns, err) + } + + certsDir := cryptomaterial.CertsDirectory(config.DataDir) + + certDir := cryptomaterial.MetricsServerKubeletClientCertDir(certsDir) + certPEM, err := os.ReadFile(cryptomaterial.ClientCertPath(certDir)) + if err != nil { + return err + } + keyPEM, err := os.ReadFile(cryptomaterial.ClientKeyPath(certDir)) + if err != nil { + return err + } + + secret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "metrics-server-client-certs", + Namespace: ns, + Annotations: map[string]string{ + "openshift.io/owning-component": "metrics-server", + }, + }, + Type: corev1.SecretTypeTLS, + Data: map[string][]byte{ + "tls.crt": certPEM, + "tls.key": keyPEM, + }, + } + _, err = clientset.CoreV1().Secrets(ns).Create(ctx, secret, metav1.CreateOptions{}) + if apierrors.IsAlreadyExists(err) { + _, err = clientset.CoreV1().Secrets(ns).Update(ctx, secret, metav1.UpdateOptions{}) + } + if err != nil { + return fmt.Errorf("applying metrics-server client cert secret: %w", err) + } + + caPEM, err := os.ReadFile(cryptomaterial.KubeletClientCAPath(certsDir)) + if err != nil { + return err + } + + cm := &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: "kubelet-serving-ca-bundle", + Namespace: ns, + Annotations: map[string]string{ + "openshift.io/owning-component": "metrics-server", + }, + }, + Data: map[string]string{ + "ca-bundle.crt": string(caPEM), + }, + } + _, err = clientset.CoreV1().ConfigMaps(ns).Create(ctx, cm, metav1.CreateOptions{}) + if apierrors.IsAlreadyExists(err) { + _, err = clientset.CoreV1().ConfigMaps(ns).Update(ctx, cm, metav1.UpdateOptions{}) + } + if err != nil { + return fmt.Errorf("applying kubelet serving CA configmap: %w", err) + } + + klog.Infof("Provisioned metrics-server kubelet client cert and CA bundle") + return nil +} diff --git a/pkg/cmd/run.go b/pkg/cmd/run.go index 94c2fbd8f6..a48a7320b3 100644 --- a/pkg/cmd/run.go +++ b/pkg/cmd/run.go @@ -303,6 +303,18 @@ func RunMicroshift(cfg *config.Config) error { // After MicroShift's core becomes ready, run the kustomizer (delete and/or apply manifests). kustomize.NewKustomizer(cfg).RunStandalone(runCtx) + // Provision certs for optional components after kustomize creates their namespaces. + go func() { + defer func() { + if r := recover(); r != nil { + klog.Errorf("Panic in metrics-server cert provisioning: %v", r) + } + }() + if err := provisionMetricsServerCerts(runCtx, cfg); err != nil { + klog.Errorf("Failed to provision metrics-server certs: %v", err) + } + }() + // Watch for SIGTERM or service error to exit, now that we are ready. select { case <-sigTerm: diff --git a/pkg/healthcheck/microshift_optional_workloads.go b/pkg/healthcheck/microshift_optional_workloads.go index 80e2d9a3b0..22e68dbcc2 100644 --- a/pkg/healthcheck/microshift_optional_workloads.go +++ b/pkg/healthcheck/microshift_optional_workloads.go @@ -38,6 +38,21 @@ var optionalWorkloadPaths = map[string]optionalWorkloads{ Namespace: "sriov-network-operator", Workloads: NamespaceWorkloads{Deployments: []string{"sriov-network-operator"}}, }, + + "/usr/lib/microshift/manifests.d/080-microshift-metrics-server": { + Namespace: "openshift-monitoring", + Workloads: NamespaceWorkloads{Deployments: []string{"metrics-server"}}, + }, +} + +// mergeWorkloads merges two NamespaceWorkloads, returning a new NamespaceWorkloads. This is helpful for cases +// where components from multiple sources are deployed to the same namespace. +func mergeWorkloads(existing, incoming NamespaceWorkloads) NamespaceWorkloads { + return NamespaceWorkloads{ + Deployments: append(existing.Deployments, incoming.Deployments...), + DaemonSets: append(existing.DaemonSets, incoming.DaemonSets...), + StatefulSets: append(existing.StatefulSets, incoming.StatefulSets...), + } } // fillOptionalMicroShiftWorkloads assembles list of optional MicroShift workloads @@ -73,7 +88,7 @@ func fillOptionalMicroShiftWorkloads(workloadsToCheck map[string]NamespaceWorklo } klog.Infof("Optional component path exists and is configured: %s - expecting %v in namespace %q", path, ow.Workloads.String(), ow.Namespace) - workloadsToCheck[ow.Namespace] = ow.Workloads + workloadsToCheck[ow.Namespace] = mergeWorkloads(workloadsToCheck[ow.Namespace], ow.Workloads) } return nil } diff --git a/pkg/util/cryptomaterial/certinfo.go b/pkg/util/cryptomaterial/certinfo.go index aed383b9fa..4e8c50989e 100644 --- a/pkg/util/cryptomaterial/certinfo.go +++ b/pkg/util/cryptomaterial/certinfo.go @@ -74,6 +74,10 @@ func AdminKubeconfigClientCertDir(certsDir string) string { return filepath.Join(AdminKubeconfigSignerDir(certsDir), "admin-kubeconfig-client") } +func MetricsServerKubeletClientCertDir(certsDir string) string { + return filepath.Join(KubeAPIServerToKubeletSignerCertDir(certsDir), "metrics-server-kubelet-client") +} + // KubeletCSRSignerSignerCertDir returns path to the signer that signs kubelet CSRs // and the signer that signs CSRs of the CSR API func KubeletCSRSignerSignerCertDir(certsDir string) string { diff --git a/scripts/auto-rebase/assets.yaml b/scripts/auto-rebase/assets.yaml index b4f34d3f6c..4a55700927 100644 --- a/scripts/auto-rebase/assets.yaml +++ b/scripts/auto-rebase/assets.yaml @@ -301,6 +301,29 @@ assets: - file: service.yaml - file: serviceaccount.yaml + - dir: optional/metrics-server/ + ignore: "MicroShift-specific metrics-server manifests sourced from CMO" + files: + - file: 00-namespace.yaml + - file: 01-cluster-role-binding-auth-delegator.yaml + - file: 01-cluster-role-binding.yaml + - file: 01-cluster-role.yaml + - file: 01-role-binding-auth-reader.yaml + - file: 01-service-account.yaml + - file: 02-configmap-audit-profiles.yaml + - file: 03-deployment.yaml + - file: 04-api-service.yaml + - file: 04-service.yaml + - file: kustomization.yaml + - file: kustomization.x86_64.yaml + ignore: "gets generated during image rebase" + - file: kustomization.aarch64.yaml + ignore: "gets generated during image rebase" + - file: release-metrics-server-x86_64.json + ignore: "gets generated during image rebase" + - file: release-metrics-server-aarch64.json + ignore: "gets generated during image rebase" + - dir: optional/observability/ ignore: "they don't exist in upstream repository - only in microshift" files: diff --git a/scripts/auto-rebase/assets_metrics.yaml b/scripts/auto-rebase/assets_metrics.yaml new file mode 100644 index 0000000000..0afaa7279b --- /dev/null +++ b/scripts/auto-rebase/assets_metrics.yaml @@ -0,0 +1,88 @@ +assets: + - dir: optional/metrics-server/ + no_clean: True + src: cluster-monitoring-operator/assets/metrics-server/ + files: + - file: 00-namespace.yaml + ignore: "Provided by MicroShift" + - file: 01-service-account.yaml + ignore: "Provided by MicroShift" + - file: 01-cluster-role.yaml + ignore: "Provided by MicroShift" + - file: clusterrole-aggregated-metrics-reader.yaml + ignore: "Provided by MicroShift" + - file: 01-cluster-role-binding.yaml + ignore: "MicroShift adds User: system:metrics-server subject for dedicated kubelet client cert" + - file: 01-cluster-role-binding-auth-delegator.yaml + ignore: "Provided by MicroShift" + - file: 01-role-binding-auth-reader.yaml + ignore: "Provided by MicroShift" + - file: 02-configmap-audit-profiles.yaml + ignore: "Provided by MicroShift" + - file: 03-deployment.yaml + ignore: "MicroShift customizes replicas, strategy, image placeholder, and cert volumes" + - file: 04-service.yaml + ignore: "MicroShift uses service-ca annotation for serving cert" + - file: 04-api-service.yaml + ignore: "Provided by MicroShift" + - file: kustomization.yaml + ignore: "Provided by MicroShift" + - file: kustomization.x86_64.yaml + ignore: "Provided by MicroShift" + - file: kustomization.aarch64.yaml + ignore: "Provided by MicroShift" + - file: release-metrics-server-aarch64.json + ignore: "Provided by MicroShift" + - file: release-metrics-server-x86_64.json + ignore: "Provided by MicroShift" + + - dir: optional/node-exporter/ + no_clean: True + src: cluster-monitoring-operator/assets/node-exporter/ + files: + - file: 01-service-account.yaml + ignore: "Provided by MicroShift" + - file: 01-cluster-role.yaml + ignore: "Provided by MicroShift" + - file: 01-cluster-role-binding.yaml + ignore: "Provided by MicroShift" + - file: 01-security-context-constraints.yaml + ignore: "Provided by MicroShift" + - file: 02-kube-rbac-proxy-secret.yaml + ignore: "Provided by MicroShift" + - file: 02-accelerators-collector-configmap.yaml + ignore: "Provided by MicroShift" + - file: 03-daemonset.yaml + ignore: "MicroShift removes metrics-client-ca volume/mount/arg (populated by CMO at runtime)" + - file: 04-service.yaml + ignore: "Provided by MicroShift" + - file: kustomization.yaml + ignore: "Provided by MicroShift" + - file: kustomization.x86_64.yaml + ignore: "Provided by MicroShift" + - file: kustomization.aarch64.yaml + ignore: "Provided by MicroShift" + + - dir: optional/kube-state-metrics/ + no_clean: True + src: cluster-monitoring-operator/assets/kube-state-metrics/ + files: + - file: 01-service-account.yaml + ignore: "Provided by MicroShift" + - file: 01-cluster-role.yaml + ignore: "Provided by MicroShift" + - file: 01-cluster-role-binding.yaml + ignore: "Provided by MicroShift" + - file: 02-kube-rbac-proxy-secret.yaml + ignore: "Provided by MicroShift" + - file: 02-custom-resource-state-configmap.yaml + - file: 03-deployment.yaml + ignore: "MicroShift overrides: Recreate strategy, removes metrics-client-ca, image placeholders" + - file: 04-service.yaml + ignore: "Provided by MicroShift" + - file: kustomization.yaml + ignore: "Provided by MicroShift" + - file: kustomization.x86_64.yaml + ignore: "Provided by MicroShift" + - file: kustomization.aarch64.yaml + ignore: "Provided by MicroShift" diff --git a/scripts/auto-rebase/rebase.sh b/scripts/auto-rebase/rebase.sh index 1bcdb6cae5..f7ab20f106 100755 --- a/scripts/auto-rebase/rebase.sh +++ b/scripts/auto-rebase/rebase.sh @@ -38,6 +38,7 @@ REBASE_USE_SSH="${REBASE_USE_SSH:-false}" EMBEDDED_COMPONENTS="route-controller-manager cluster-policy-controller hyperkube etcd kube-storage-version-migrator cluster-config-api" EMBEDDED_COMPONENT_OPERATORS="cluster-kube-apiserver-operator cluster-kube-controller-manager-operator cluster-openshift-controller-manager-operator cluster-kube-scheduler-operator machine-config-operator operator-lifecycle-manager" LOADED_COMPONENTS="cluster-dns-operator cluster-ingress-operator service-ca-operator cluster-network-operator cluster-csi-snapshot-controller-operator" +OPTIONAL_COMPONENTS="cluster-monitoring-operator" declare -a ARCHS=("amd64" "arm64") declare -A GOARCH_TO_UNAME_MAP=( ["amd64"]="x86_64" ["arm64"]="aarch64" ) @@ -200,7 +201,7 @@ download_release() { component=$(echo "${line}" | cut -d ' ' -f 1) repo=$(echo "${line}" | cut -d ' ' -f 2) commit=$(echo "${line}" | cut -d ' ' -f 3) - if [[ "${EMBEDDED_COMPONENTS}" == *"${component}"* ]] || [[ "${LOADED_COMPONENTS}" == *"${component}"* ]] || [[ "${EMBEDDED_COMPONENT_OPERATORS}" == *"${component}"* ]]; then + if [[ "${EMBEDDED_COMPONENTS}" == *"${component}"* ]] || [[ "${LOADED_COMPONENTS}" == *"${component}"* ]] || [[ "${EMBEDDED_COMPONENT_OPERATORS}" == *"${component}"* ]] || [[ "${OPTIONAL_COMPONENTS}" == *"${component}"* ]]; then clone_repo "${repo}" "${commit}" "." echo "${repo} embedded-component ${commit}" >> "${new_commits_file}" echo @@ -663,7 +664,6 @@ copy_manifests() { "$REPOROOT/scripts/auto-rebase/handle_assets.py" "./scripts/auto-rebase/assets.yaml" } - # Updates embedded component manifests by gathering these from various places # in the staged repos and copying them into the asset directory. update_openshift_manifests() { @@ -921,6 +921,7 @@ EOF update_olm_images update_multus_images + update_metrics_images popd >/dev/null } @@ -1111,6 +1112,93 @@ EOF done # for goarch } +update_metrics_images() { + title "Rebasing metrics component images" + + # Maps kustomization image name -> OCP release tag name + declare -A METRICS_IMAGE_MAP=( + ["quay.io/openshift/kube-metrics-server"]="kube-metrics-server" + ["quay.io/openshift/kube-state-metrics"]="kube-state-metrics" + ["quay.io/openshift/node-exporter"]="prometheus-node-exporter" + ["quay.io/openshift/kube-rbac-proxy"]="kube-rbac-proxy" + ) + + # Maps component dir -> release JSON key -> OCP release tag name + declare -A METRICS_COMPONENT_JSON_KEY=( + ["metrics-server"]="metrics_server" + ["kube-state-metrics"]="kube_state_metrics" + ["node-exporter"]="node_exporter" + ) + + # Maps release JSON key -> OCP release tag name + declare -A METRICS_EXPORTER_JSON_MAP=( + ["metrics_server"]="kube-metrics-server" + ["kube_state_metrics"]="kube-state-metrics" + ["node_exporter"]="prometheus-node-exporter" + ) + + for goarch in amd64 arm64; do + arch=${GOARCH_TO_UNAME_MAP["${goarch}"]:-noarch} + + local release_file="${STAGING_DIR}/release_${goarch}.json" + + local base_release + base_release=$(jq -r ".metadata.version" "${release_file}") + + # Generate per-component release JSON and kustomization files + for component_dir in metrics-server kube-state-metrics node-exporter; do + [[ -d "${REPOROOT}/assets/optional/${component_dir}" ]] || continue + + # Generate per-component release JSON + local json_key="${METRICS_COMPONENT_JSON_KEY[$component_dir]}" + local release_tag="${METRICS_EXPORTER_JSON_MAP[$json_key]}" + local new_image + new_image=$(jq -r ".references.spec.tags[] | select(.name == \"${release_tag}\") | .from.name" "${release_file}") + if [[ -z "${new_image}" || "${new_image}" == "null" ]]; then + >&2 echo "ERROR: Release tag '${release_tag}' not found in payload for ${component_dir}" + return 1 + fi + local component_release_json="${REPOROOT}/assets/optional/${component_dir}/release-${component_dir}-${arch}.json" + jq -n --arg base "$base_release" --arg img "${new_image}" \ + "{\"release\": {\"base\": \$base}, \"images\": {\"${json_key}\": \$img}}" > "${component_release_json}" + + local kustomization_arch_file="${REPOROOT}/assets/optional/${component_dir}/kustomization.${arch}.yaml" + + cat < "${kustomization_arch_file}" +images: +EOF + + # Read image names from the base kustomization and deployment/daemonset + local image_names + image_names=$(grep -h 'image:' "${REPOROOT}/assets/optional/${component_dir}/"*.yaml 2>/dev/null \ + | sed 's/.*image: *//; s/:.*//; s/@.*//' | sort -u) + + for orig_image in ${image_names}; do + local release_tag="${METRICS_IMAGE_MAP[$orig_image]:-}" + if [[ -z "${release_tag}" ]]; then + >&2 echo "ERROR: Unknown metrics image '${orig_image}' in ${component_dir}" + return 1 + fi + + local new_image + new_image=$(jq -r ".references.spec.tags[] | select(.name == \"${release_tag}\") | .from.name" "${release_file}") + if [[ -z "${new_image}" || "${new_image}" == "null" ]]; then + >&2 echo "ERROR: Image for release tag '${release_tag}' not found in payload for ${component_dir}" + return 1 + fi + local new_image_name="${new_image%@*}" + local new_image_digest="${new_image#*@}" + + cat <> "${kustomization_arch_file}" + - name: ${orig_image} + newName: ${new_image_name} + digest: ${new_image_digest} +EOF + done + done + done +} + update_olm_images() { title "Rebasing operator-lifecycle-manager manifests" diff --git a/test/bin/common.sh b/test/bin/common.sh index ef682a676f..8b092354b8 100644 --- a/test/bin/common.sh +++ b/test/bin/common.sh @@ -388,6 +388,8 @@ MICROSHIFT_Y2_OPTIONAL_RPMS_LIST=( microshift-cert-manager-release-info microshift-sriov microshift-sriov-release-info + microshift-metrics-server + microshift-metrics-server-release-info ) MICROSHIFT_Y1_OPTIONAL_RPMS_LIST=( "${MICROSHIFT_Y2_OPTIONAL_RPMS_LIST[@]}"