Skip to content

SDN-5072: Deploy FRR-K8s - #2450

Merged
openshift-merge-bot[bot] merged 2 commits into
openshift:masterfrom
jcaamano:frr-k8s
Aug 9, 2024
Merged

SDN-5072: Deploy FRR-K8s#2450
openshift-merge-bot[bot] merged 2 commits into
openshift:masterfrom
jcaamano:frr-k8s

Conversation

@jcaamano

@jcaamano jcaamano commented Jul 29, 2024

Copy link
Copy Markdown
Contributor

Deploys FRR-K8s if enabled both if enabled both in the API and the feature gate

I used the helm chart (at this time HEAD of release-4.17 branch):
https://github.com/openshift/metallb-operator/blob/6de2375a6350e62c0e34a9ebdd392b0832b76b86/bindata/deployment/helm/frr-k8s

with equivalent values of what metallb operator would use on default :

frrk8s:
  logLevel: info
  image:
    repository: quay.io/metallb/frr-k8s
    tag: v0.0.14
  serviceAccount:
    create: false
    name: frr-k8s-daemon
  disableCertRotation: true
  frr:
    image:
      repository: quay.io/frrouting/frr
      tag: 9.1.0
    metricsBindAddress: 127.0.0.1
    metricsPort: 7573
    secureMetricsPort: 9141
prometheus:
  metricsPort: 7572
  secureMetricsPort: 9140
  metricsTLSSecret: frr-k8s-certs-secret
  serviceAccount: foo
  namespace: bar
  rbacProxy:
    repository: gcr.io/kubebuilder/kube-rbac-proxy
    tag: v0.11.0
  serviceMonitor:
    enabled: true
    tlsConfig:
      caFile: /etc/prometheus/configmaps/serving-certs-ca-bundle/service-ca.crt
      certFile: /etc/prometheus/secrets/metrics-client-certs/tls.crt
      insecureSkipVerify: false
      keyFile: /etc/prometheus/secrets/metrics-client-certs/tls.key
      serverName: frr-k8s-monitor-service.metallb-system.svc
    metricRelabelings:
    - regex: frrk8s_bgp_(.*)
      replacement: metallb_bgp_$1
      sourceLabels: [__name__]
      targetLabel: __name__
    - regex: frrk8s_bfd_(.*)
      replacement: metallb_bfd_$1
      sourceLabels: [__name__]
      targetLabel: __name__

This does not generate the CRDs or RBAC though.

CRDs were picked from
https://github.com/openshift/metallb-operator/tree/6de2375a6350e62c0e34a9ebdd392b0832b76b86/bundle/manifests

RBAC was picked from
https://github.com/openshift/metallb-operator/blob/6de2375a6350e62c0e34a9ebdd392b0832b76b86/config/metallb_rbac/metallb.yaml

Then I applied the same changes metallb operator applies programatically changes from
https://github.com/openshift/metallb-operator/blob/6de2375a6350e62c0e34a9ebdd392b0832b76b86/pkg/helm/frrk8s.go#L79

The resulting configuration was used as source. On top of that, changes following CNO and OCP managemenet conventions were applied, plus minor edits from me, and this is the resulting diff vs source:

❯ diff -u10 upstream.yaml cno.yaml       
--- upstream.yaml	2024-08-07 17:10:10.893991403 +0000
+++ cno.yaml	2024-08-07 17:09:09.327710107 +0000
@@ -1,10 +1,24 @@
+apiVersion: v1
+kind: Namespace
+metadata:
+  labels:
+    openshift.io/cluster-monitoring: "true"
+    pod-security.kubernetes.io/audit: privileged
+    pod-security.kubernetes.io/enforce: privileged
+    pod-security.kubernetes.io/warn: privileged
+  name: openshift-frr-k8s
+  annotations:
+    openshift.io/node-selector: ""
+    openshift.io/description: "FRR-K8s components"
+    workload.openshift.io/allowed: "management"
+---
 apiVersion: apiextensions.k8s.io/v1
 kind: CustomResourceDefinition
 metadata:
   annotations:
     controller-gen.kubebuilder.io/version: v0.14.0
   name: frrconfigurations.frrk8s.metallb.io
 spec:
   group: frrk8s.metallb.io
   names:
     kind: FRRConfiguration
@@ -521,52 +535,43 @@
             type: object
         type: object
     served: true
     storage: true
     subresources:
       status: {}
 ---
 apiVersion: v1
 kind: ServiceAccount
 metadata:
-  labels:
-    app.kubernetes.io/component: rbac
-    app.kubernetes.io/created-by: frr-k8s
-    app.kubernetes.io/instance: frr-k8s-sa
-    app.kubernetes.io/managed-by: kustomize
-    app.kubernetes.io/name: serviceaccount
-    app.kubernetes.io/part-of: frr-k8s
   name: frr-k8s-daemon
-  namespace: metallb-system
+  namespace: openshift-frr-k8s
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
 metadata:
-  labels:
-    app: frr-k8s
-  name: frr-k8s-daemon-role
-  namespace: metallb-system
+  name: openshift-frr-k8s
+  namespace: openshift-frr-k8s
 rules:
 - apiGroups:
   - ""
   resources:
   - secrets
   verbs:
   - get
   - list
   - watch
   - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRole
 metadata:
-  name: frr-k8s-daemon-role
+  name: openshift-frr-k8s
 rules:
 - apiGroups:
   - ""
   resources:
   - nodes
   verbs:
   - get
   - list
   - watch
 - apiGroups:
@@ -624,118 +629,79 @@
   - update
   - watch
 - apiGroups:
   - frrk8s.metallb.io
   resources:
   - frrnodestates/status
   verbs:
   - get
   - patch
   - update
----
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRole
-metadata:
-  labels:
-    app.kubernetes.io/component: kube-rbac-proxy
-    app.kubernetes.io/created-by: frr-k8s
-    app.kubernetes.io/instance: proxy-role
-    app.kubernetes.io/managed-by: kustomize
-    app.kubernetes.io/name: clusterrole
-    app.kubernetes.io/part-of: frr-k8s
-  name: frr-k8s-proxy-role
-rules:
 - apiGroups:
   - authentication.k8s.io
   resources:
   - tokenreviews
   verbs:
   - create
 - apiGroups:
   - authorization.k8s.io
   resources:
   - subjectaccessreviews
   verbs:
   - create
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: RoleBinding
 metadata:
-  labels:
-    app.kubernetes.io/component: rbac
-    app.kubernetes.io/created-by: frr-k8s
-    app.kubernetes.io/instance: frr-k8s-rolebinding
-    app.kubernetes.io/managed-by: kustomize
-    app.kubernetes.io/name: rolebinding
-    app.kubernetes.io/part-of: frr-k8s
-  name: frr-k8s-daemon-rolebinding
-  namespace: metallb-system
+  name: openshift-frr-k8s
+  namespace: openshift-frr-k8s
 roleRef:
   apiGroup: rbac.authorization.k8s.io
   kind: Role
-  name: frr-k8s-daemon-role
+  name: openshift-frr-k8s
 subjects:
 - kind: ServiceAccount
   name: frr-k8s-daemon
-  namespace: metallb-system
+  namespace: openshift-frr-k8s
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
 metadata:
-  labels:
-    app.kubernetes.io/component: rbac
-    app.kubernetes.io/created-by: frr-k8s
-    app.kubernetes.io/instance: frr-k8s-rolebinding
-    app.kubernetes.io/managed-by: kustomize
-    app.kubernetes.io/name: clusterrolebinding
-    app.kubernetes.io/part-of: frr-k8s
-  name: frr-k8s-daemon-rolebinding
+  name: openshift-frr-k8s
 roleRef:
   apiGroup: rbac.authorization.k8s.io
   kind: ClusterRole
-  name: frr-k8s-daemon-role
+  name: openshift-frr-k8s
 subjects:
 - kind: ServiceAccount
   name: frr-k8s-daemon
-  namespace: metallb-system
+  namespace: openshift-frr-k8s
 ---
 apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRoleBinding
+kind: RoleBinding
 metadata:
-  labels:
-    app.kubernetes.io/component: kube-rbac-proxy
-    app.kubernetes.io/created-by: frr-k8s
-    app.kubernetes.io/instance: proxy-rolebinding
-    app.kubernetes.io/managed-by: kustomize
-    app.kubernetes.io/name: clusterrolebinding
-    app.kubernetes.io/part-of: frr-k8s
-  name: frr-k8s-proxy-rolebinding
+  name: system:openshift:scc:privileged
+  namespace: openshift-frr-k8s
 roleRef:
   apiGroup: rbac.authorization.k8s.io
   kind: ClusterRole
-  name: frr-k8s-proxy-role
+  name: system:openshift:scc:privileged
 subjects:
 - kind: ServiceAccount
   name: frr-k8s-daemon
-  namespace: metallb-system
+  namespace: openshift-frr-k8s
 ---
 apiVersion: v1
 kind: ConfigMap
 metadata:
   name: frr-startup
-  namespace: "openshift-frr-k8s"
-  labels:
-    helm.sh/chart: frr-k8s-0.0.14
-    app: frr-k8s
-    app.kubernetes.io/version: "v0.0.14"
-    app.kubernetes.io/managed-by: Helm
-    component: frr-k8s
+  namespace: openshift-frr-k8s
 data:
   daemons: |
     # This file tells the frr package which daemons to start.
     #
     # Sample configurations for these daemons can be found in
     # /usr/share/doc/frr/examples/.
     #
     # ATTENTION:
     #
     # When activating a daemon for the first time, a config file, even if it is
@@ -818,116 +784,127 @@
     ! So anything configured here is only temporary.
     frr version 8.0
     frr defaults traditional
     hostname Router
     line vty
     log file /etc/frr/frr.log informational
 ---
 apiVersion: apps/v1
 kind: DaemonSet
 metadata:
-  name: frrk8s-frr-k8s
-  namespace: "openshift-frr-k8s"
+  name: frr-k8s
+  namespace: openshift-frr-k8s
   labels:
-    helm.sh/chart: frr-k8s-0.0.14
     app: frr-k8s
-    app.kubernetes.io/version: "v0.0.14"
-    app.kubernetes.io/managed-by: Helm
     component: frr-k8s
-    app: "frr-k8s"
+  annotations:
+    release.openshift.io/version: "{{.ReleaseVersion}}"
 spec:
   updateStrategy:
     type: RollingUpdate
+    rollingUpdate:
+      maxUnavailable: 10%
   selector:
     matchLabels:
       app: frr-k8s
       component: frr-k8s
   template:
     metadata:
       labels:
         app: frr-k8s
         component: frr-k8s
-        app: "frr-k8s"
+      annotations:
+        target.workload.openshift.io/management: '{"effect": "PreferredDuringScheduling"}'
+        openshift.io/required-scc: privileged
     spec:
       serviceAccountName: frr-k8s-daemon
+      priorityClassName: system-node-critical
       terminationGracePeriodSeconds: 0
       hostNetwork: true
       volumes:
       - name: frr-sockets
         emptyDir: {}
       - name: frr-startup
         configMap:
           name: frr-startup
       - name: frr-conf
         emptyDir: {}
       - name: reloader
         emptyDir: {}
       - name: metrics
         emptyDir: {}
       - name: metrics-certs
         secret:
           secretName: frr-k8s-certs-secret
       initContainers:
       # Copies the initial config files with the right permissions to the shared volume.
       - name: cp-frr-files
-        image: quay.io/frrouting/frr:9.1.0
+        image: {{.FRRK8sImage}}
         securityContext:
           runAsUser: 100
           runAsGroup: 101
         command: ["/bin/sh", "-c", "cp -rLf /tmp/frr/* /etc/frr/"]
+        terminationMessagePolicy: FallbackToLogsOnError
         volumeMounts:
         - name: frr-startup
           mountPath: /tmp/frr
         - name: frr-conf
           mountPath: /etc/frr
       # Copies the reloader to the shared volume between the speaker and reloader.
       - name: cp-reloader
-        image: quay.io/metallb/frr-k8s:v0.0.14
+        image: {{.FRRK8sImage}}
         command: ["/bin/sh", "-c", "cp -f /frr-reloader.sh /etc/frr_reloader/"]
+        terminationMessagePolicy: FallbackToLogsOnError
         volumeMounts:
         - name: reloader
           mountPath: /etc/frr_reloader
       # Copies the metrics exporter
       - name: cp-metrics
-        image: quay.io/metallb/frr-k8s:v0.0.14
+        image: {{.FRRK8sImage}}
         command: ["/bin/sh", "-c", "cp -f /frr-metrics /etc/frr_metrics/"]
+        terminationMessagePolicy: FallbackToLogsOnError
         volumeMounts:
         - name: metrics
           mountPath: /etc/frr_metrics
       shareProcessNamespace: true
       containers:
       - name: controller
-        image: quay.io/metallb/frr-k8s:v0.0.14
+        image: {{.FRRK8sImage}}
         command:
         - /frr-k8s
         args:
-        - "--node-name=$(NODE_NAME)"
-        - "--namespace=$(NAMESPACE)"
-        - "--metrics-bind-address=127.0.0.1:7572"
+        - --node-name=$(NODE_NAME)
+        - --namespace=$(NAMESPACE)
+        - --metrics-bind-address=127.0.0.1:7572
         - --log-level=info
         - --health-probe-bind-address=127.0.0.1:8081
         env:
         - name: FRR_CONFIG_FILE
           value: /etc/frr_reloader/frr.conf
         - name: FRR_RELOADER_PID_FILE
           value: /etc/frr_reloader/reloader.pid
         - name: NODE_NAME
           valueFrom:
             fieldRef:
               fieldPath: spec.nodeName
         - name: NAMESPACE
           valueFrom:
             fieldRef:
               fieldPath: metadata.namespace
         ports:
         - containerPort: 7572
           name: monitoring
+        resources:
+          requests:
+            cpu: 100m
+            memory: 200Mi
+        terminationMessagePolicy: FallbackToLogsOnError
         livenessProbe:
           httpGet:
             path: /healthz
             port: 8081
             host: 127.0.0.1
           initialDelaySeconds: 10
           periodSeconds: 10
           timeoutSeconds: 1
           successThreshold: 1
           failureThreshold: 3
@@ -953,21 +930,21 @@
           - name: reloader
             mountPath: /etc/frr_reloader
       - name: frr
         securityContext:
           capabilities:
             add:
             - NET_ADMIN
             - NET_RAW
             - SYS_ADMIN
             - NET_BIND_SERVICE
-        image: quay.io/frrouting/frr:9.1.0
+        image: {{.FRRK8sImage}}
         env:
         - name: TINI_SUBREAPER
           value: "true"
         volumeMounts:
         - name: frr-sockets
           mountPath: /var/run/frr
         - name: frr-conf
           mountPath: /etc/frr
         # The command is FRR's default entrypoint & waiting for the log file to appear and tailing it.
         # If the log file isn't created in 60 seconds the tail fails and the container is restarted.
@@ -976,217 +953,208 @@
         - /bin/sh
         - -c
         - |
           /sbin/tini -- /usr/lib/frr/docker-start &
           attempts=0
           until [[ -f /etc/frr/frr.log || $attempts -eq 60 ]]; do
             sleep 1
             attempts=$(( $attempts + 1 ))
           done
           tail -f /etc/frr/frr.log
+        resources:
+          requests:
+            cpu: 100m
+            memory: 200Mi
+        terminationMessagePolicy: FallbackToLogsOnError
         livenessProbe:
           httpGet:
             path: /livez
             port: 7573
             host: 127.0.0.1
           periodSeconds: 10
           failureThreshold: 3
         startupProbe:
           httpGet:
             path: /livez
             port: 7573
             host: 127.0.0.1
           failureThreshold: 30
           periodSeconds: 5
       - name: reloader
-        image: quay.io/frrouting/frr:9.1.0
+        image: {{.FRRK8sImage}}
         command: ["/etc/frr_reloader/frr-reloader.sh"]
+        resources:
+          requests:
+            cpu: 10m
+            memory: 20Mi
+        terminationMessagePolicy: FallbackToLogsOnError
         volumeMounts:
         - name: frr-sockets
           mountPath: /var/run/frr
         - name: frr-conf
           mountPath: /etc/frr
         - name: reloader
           mountPath: /etc/frr_reloader
       - name: frr-metrics
-        image: quay.io/frrouting/frr:9.1.0
+        image: {{.FRRK8sImage}}
         command: ["/etc/frr_metrics/frr-metrics"]
         args:
         - --metrics-port=7573
         - --metrics-bind-address=127.0.0.1
         ports:
         - containerPort: 7573
           name: monitoring
+        resources:
+          requests:
+            cpu: 10m
+            memory: 20Mi
+        terminationMessagePolicy: FallbackToLogsOnError
         volumeMounts:
         - name: frr-sockets
           mountPath: /var/run/frr
         - name: frr-conf
           mountPath: /etc/frr
         - name: metrics
           mountPath: /etc/frr_metrics
       - name: kube-rbac-proxy
-        image: gcr.io/kubebuilder/kube-rbac-proxy:v0.11.0
-        imagePullPolicy: 
+        image: {{.KubeRBACProxyImage}}
         args:
         - --logtostderr
         - --secure-listen-address=:9140
         - --upstream=http://127.0.0.1:7572/
-        - --tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
+        - --tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
         - --tls-private-key-file=/etc/metrics/tls.key
         - --tls-cert-file=/etc/metrics/tls.crt
         ports:
         - containerPort: 9140
           name: metricshttps
         resources:
           requests:
             cpu: 10m
             memory: 20Mi
         terminationMessagePolicy: FallbackToLogsOnError
         volumeMounts:
         - name: metrics-certs
           mountPath: /etc/metrics
           readOnly: true
       - name: kube-rbac-proxy-frr
-        image: gcr.io/kubebuilder/kube-rbac-proxy:v0.11.0
-        imagePullPolicy: 
+        image: {{.KubeRBACProxyImage}}
         args:
         - --logtostderr
         - --secure-listen-address=:9141
-        - --tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
+        - --tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
         - --upstream=http://127.0.0.1:7573/
         - --tls-private-key-file=/etc/metrics/tls.key
         - --tls-cert-file=/etc/metrics/tls.crt
         ports:
         - containerPort: 9141
           name: metricshttps
         resources:
           requests:
             cpu: 10m
             memory: 20Mi
         terminationMessagePolicy: FallbackToLogsOnError
         volumeMounts:
         - name: metrics-certs
           mountPath: /etc/metrics
           readOnly: true
       nodeSelector:
-        "kubernetes.io/os": linux
+        kubernetes.io/os: linux
       tolerations:
       - key: node-role.kubernetes.io/master
         effect: NoSchedule
         operator: Exists
       - key: node-role.kubernetes.io/control-plane
         effect: NoSchedule
         operator: Exists
 ---
 apiVersion: v1
 kind: Service
 metadata:
-  annotations:
-    prometheus.io/scrape: "true"
+  name: frr-k8s-monitor-service
+  namespace: openshift-frr-k8s
   labels:
     name: frr-k8s-monitor-service
-  name: frr-k8s-monitor-service
-  namespace: "openshift-frr-k8s"
+  annotations:
+    prometheus.io/scrape: "true"
+    service.beta.openshift.io/serving-cert-secret-name: frr-k8s-certs-secret
 spec:
   selector:
     app: frr-k8s
     component: frr-k8s
   clusterIP: None
   ports:
-  - name: "metricshttps"
+  - name: metricshttps
     port: 9140
-    targetPort: 9140
+    targetPort: metricshttps
   - name: frrmetricshttps
     port: 9141
-    targetPort: 9141
+    targetPort: frrmetricshttps
   sessionAffinity: None
   type: ClusterIP
 ---
 apiVersion: monitoring.coreos.com/v1
 kind: ServiceMonitor
 metadata:
   name: frr-k8s-monitor
-  namespace: "openshift-frr-k8s"
+  namespace: openshift-frr-k8s
   labels:
-    helm.sh/chart: frr-k8s-0.0.14
     app: frr-k8s
-    app.kubernetes.io/version: "v0.0.14"
-    app.kubernetes.io/managed-by: Helm
     component: frr-k8s
+  annotations:
+    networkoperator.openshift.io/ignore-errors: ""
 spec:
   endpoints:
-  - port: "metricshttps"
-    honorLabels: true
-    metricRelabelings:
-    - regex: frrk8s_bgp_(.*)
-      replacement: metallb_bgp_$1
-      sourceLabels:
-      - __name__
-      targetLabel: __name__
-    - regex: frrk8s_bfd_(.*)
-      replacement: metallb_bfd_$1
-      sourceLabels:
-      - __name__
-      targetLabel: __name__
-    bearerTokenFile: "/var/run/secrets/kubernetes.io/serviceaccount/token"
-    scheme: "https"
-    tlsConfig:
-      caFile: /etc/prometheus/configmaps/serving-certs-ca-bundle/service-ca.crt
-      certFile: /etc/prometheus/secrets/metrics-client-certs/tls.crt
-      insecureSkipVerify: false
-      keyFile: /etc/prometheus/secrets/metrics-client-certs/tls.key
-      serverName: frr-k8s-monitor-service.metallb-system.svc
-  - port: "frrmetricshttps"
-    honorLabels: true
-    metricRelabelings:
-    - regex: frrk8s_bgp_(.*)
-      replacement: metallb_bgp_$1
-      sourceLabels:
-      - __name__
-      targetLabel: __name__
-    - regex: frrk8s_bfd_(.*)
-      replacement: metallb_bfd_$1
-      sourceLabels:
-      - __name__
-      targetLabel: __name__
-    bearerTokenFile: "/var/run/secrets/kubernetes.io/serviceaccount/token"
-    scheme: "https"
-    tlsConfig:
-      caFile: /etc/prometheus/configmaps/serving-certs-ca-bundle/service-ca.crt
-      certFile: /etc/prometheus/secrets/metrics-client-certs/tls.crt
-      insecureSkipVerify: false
-      keyFile: /etc/prometheus/secrets/metrics-client-certs/tls.key
-      serverName: frr-k8s-monitor-service.metallb-system.svc
-  jobLabel: "app.kubernetes.io/name"
+    - port: metricshttps
+      honorLabels: true
+      bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
+      scheme: https
+      tlsConfig:
+        caFile: /etc/prometheus/configmaps/prometheus.io/scrape/service-ca.crt
+        serverName: openshift-frr-k8s-metrics-service.openshift-frr-k8s.svc
+        insecureSkipVerify: false
+    - port: frrmetricshttps
+      honorLabels: true
+      bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
+      scheme: https
+      tlsConfig:
+        caFile: /etc/prometheus/configmaps/serving-certs-ca-bundle/service-ca.crt
+        serverName: openshift-frr-k8s-metrics-service.openshift-frr-k8s.svc
+        insecureSkipVerify: false
+  jobLabel: app
   namespaceSelector:
     matchNames:
     - openshift-frr-k8s
   selector:
     matchLabels:
       name: frr-k8s-monitor-service
 ---
 apiVersion: v1
 kind: Service
 metadata:
   name: frr-k8s-webhook-service
-  namespace: "openshift-frr-k8s"
+  namespace: openshift-frr-k8s
+  annotations:
+    service.beta.openshift.io/serving-cert-secret-name: frr-k8s-webhook-server-cert
 spec:
   ports:
   - port: 443
     targetPort: 9443
   selector:
     component: frr-k8s-webhook-server
 ---
 apiVersion: admissionregistration.k8s.io/v1
 kind: ValidatingWebhookConfiguration
 metadata:
   name: frr-k8s-validating-webhook-configuration
+  annotations:
+    service.beta.openshift.io/inject-cabundle: "true"
 webhooks:
 - admissionReviewVersions:
   - v1
   clientConfig:
     service:
       name: frr-k8s-webhook-service
       namespace: openshift-frr-k8s
       path: /validate-frrk8s-metallb-io-v1beta1-frrconfiguration
   failurePolicy: Fail
   name: frrconfigurationsvalidationwebhook.metallb.io
@@ -1199,61 +1167,61 @@
     - CREATE
     - UPDATE
     resources:
     - frrconfigurations
   sideEffects: None
 ---
 apiVersion: apps/v1
 kind: Deployment
 metadata:
   name: frr-k8s-webhook-server
-  namespace: "openshift-frr-k8s"
+  namespace: openshift-frr-k8s
   labels:
-    helm.sh/chart: frr-k8s-0.0.14
     app: frr-k8s
-    app.kubernetes.io/version: "v0.0.14"
-    app.kubernetes.io/managed-by: Helm
     component: frr-k8s-webhook-server
-    app: "frr-k8s"
+  annotations:
+    release.openshift.io/version: "{{.ReleaseVersion}}"
 spec:
   selector:
     matchLabels:
       component: frr-k8s-webhook-server
   template:
     metadata:
-      annotations:
-        kubectl.kubernetes.io/default-container: frr-k8s-webhook-server
       labels:
         component: frr-k8s-webhook-server
+      annotations:
+        target.workload.openshift.io/management: '{"effect": "PreferredDuringScheduling"}'
+        openshift.io/required-scc: restricted-v2
     spec:
       containers:
       - command:
         - /frr-k8s
         args:
         - --log-level=info
-        - "--webhook-mode=onlywebhook"
-        - "--disable-cert-rotation=true"
-        - "--namespace=$(NAMESPACE)"
+        - --webhook-mode=onlywebhook
+        - --disable-cert-rotation=true
+        - --namespace=$(NAMESPACE)
         - --health-probe-bind-address=:8081
         env:
         - name: NAMESPACE
           valueFrom:
             fieldRef:
               fieldPath: metadata.namespace
-        image: quay.io/metallb/frr-k8s:v0.0.14
+        image: {{.FRRK8sImage}}
         name: frr-k8s-webhook-server
         securityContext:
-          allowPrivilegeEscalation: false
-          capabilities:
-            drop:
-              - ALL
-          readOnlyRootFilesystem: true
+         runAsNonRoot: true
+        resources:
+          requests:
+            cpu: 10m
+            memory: 50Mi
+        terminationMessagePolicy: FallbackToLogsOnError
         livenessProbe:
           httpGet:
             path: /healthz
             port: 8081
           initialDelaySeconds: 10
           periodSeconds: 10
           failureThreshold: 3
         readinessProbe:
           httpGet:
             path: /readyz
@@ -1271,11 +1239,12 @@
         operator: Exists
       - key: node-role.kubernetes.io/control-plane
         effect: NoSchedule
         operator: Exists
       volumes:
       - name: cert
         secret:
           defaultMode: 420
           secretName: frr-k8s-webhook-server-cert
       serviceAccountName: frr-k8s-daemon
+      priorityClassName: system-cluster-critical
       terminationGracePeriodSeconds: 10

I am sure this will need further adjustments but aiming for a good starting point.

This is a diff

@openshift-ci openshift-ci Bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jul 29, 2024
@openshift-ci

openshift-ci Bot commented Jul 29, 2024

Copy link
Copy Markdown
Contributor

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jul 29, 2024
@jcaamano

Copy link
Copy Markdown
Contributor Author

/test images
/test e2e-gcp-ovn

@jcaamano

Copy link
Copy Markdown
Contributor Author

/test images

@jcaamano

Copy link
Copy Markdown
Contributor Author

/test e2e-gcp-ovn

@jcaamano

Copy link
Copy Markdown
Contributor Author

/test images
/test e2e-gcp-ovn

@jcaamano

Copy link
Copy Markdown
Contributor Author

/test images

@jcaamano

Copy link
Copy Markdown
Contributor Author

/test images
/test e2e-metal-ipi-ovn

@jcaamano

Copy link
Copy Markdown
Contributor Author

/test ?

@openshift-ci

openshift-ci Bot commented Jul 30, 2024

Copy link
Copy Markdown
Contributor

@jcaamano: The following commands are available to trigger required jobs:

  • /test 4.17-upgrade-from-stable-4.16-images
  • /test e2e-aws-ovn-hypershift-conformance
  • /test e2e-aws-ovn-upgrade
  • /test e2e-aws-ovn-windows
  • /test e2e-azure-ovn-upgrade
  • /test e2e-gcp-ovn
  • /test e2e-gcp-ovn-upgrade
  • /test e2e-metal-ipi-ovn-ipv6
  • /test images
  • /test lint
  • /test okd-scos-images
  • /test unit
  • /test verify

The following commands are available to trigger optional jobs:

  • /test 4.17-upgrade-from-stable-4.16-e2e-aws-ovn-upgrade
  • /test 4.17-upgrade-from-stable-4.16-e2e-azure-ovn-upgrade
  • /test 4.17-upgrade-from-stable-4.16-e2e-gcp-ovn-upgrade
  • /test e2e-aws-hypershift-ovn-kubevirt
  • /test e2e-aws-ovn-ipsec-serial
  • /test e2e-aws-ovn-ipsec-upgrade
  • /test e2e-aws-ovn-local-to-shared-gateway-mode-migration
  • /test e2e-aws-ovn-serial
  • /test e2e-aws-ovn-shared-to-local-gateway-mode-migration
  • /test e2e-aws-ovn-single-node
  • /test e2e-aws-ovn-techpreview-serial
  • /test e2e-azure-ovn
  • /test e2e-azure-ovn-dualstack
  • /test e2e-azure-ovn-manual-oidc
  • /test e2e-gcp-ovn-techpreview
  • /test e2e-metal-ipi-ovn-ipv6-ipsec
  • /test e2e-network-mtu-migration-ovn-ipv4
  • /test e2e-network-mtu-migration-ovn-ipv6
  • /test e2e-openstack-ovn
  • /test e2e-ovn-hybrid-step-registry
  • /test e2e-ovn-ipsec-step-registry
  • /test e2e-ovn-step-registry
  • /test e2e-vsphere-ovn
  • /test e2e-vsphere-ovn-dualstack
  • /test e2e-vsphere-ovn-dualstack-primaryv6
  • /test e2e-vsphere-ovn-windows
  • /test qe-perfscale-aws-ovn-medium-cluster-density
  • /test qe-perfscale-aws-ovn-medium-node-density-cni
  • /test qe-perfscale-aws-ovn-small-cluster-density
  • /test qe-perfscale-aws-ovn-small-node-density-cni
  • /test security

Use /test all to run the following jobs that were automatically triggered:

  • pull-ci-openshift-cluster-network-operator-master-4.17-upgrade-from-stable-4.16-e2e-aws-ovn-upgrade
  • pull-ci-openshift-cluster-network-operator-master-4.17-upgrade-from-stable-4.16-e2e-azure-ovn-upgrade
  • pull-ci-openshift-cluster-network-operator-master-4.17-upgrade-from-stable-4.16-e2e-gcp-ovn-upgrade
  • pull-ci-openshift-cluster-network-operator-master-4.17-upgrade-from-stable-4.16-images
  • pull-ci-openshift-cluster-network-operator-master-e2e-aws-hypershift-ovn-kubevirt
  • pull-ci-openshift-cluster-network-operator-master-e2e-aws-ovn-hypershift-conformance
  • pull-ci-openshift-cluster-network-operator-master-e2e-aws-ovn-local-to-shared-gateway-mode-migration
  • pull-ci-openshift-cluster-network-operator-master-e2e-aws-ovn-serial
  • pull-ci-openshift-cluster-network-operator-master-e2e-aws-ovn-shared-to-local-gateway-mode-migration
  • pull-ci-openshift-cluster-network-operator-master-e2e-aws-ovn-single-node
  • pull-ci-openshift-cluster-network-operator-master-e2e-aws-ovn-upgrade
  • pull-ci-openshift-cluster-network-operator-master-e2e-aws-ovn-windows
  • pull-ci-openshift-cluster-network-operator-master-e2e-azure-ovn
  • pull-ci-openshift-cluster-network-operator-master-e2e-azure-ovn-upgrade
  • pull-ci-openshift-cluster-network-operator-master-e2e-gcp-ovn
  • pull-ci-openshift-cluster-network-operator-master-e2e-gcp-ovn-upgrade
  • pull-ci-openshift-cluster-network-operator-master-e2e-metal-ipi-ovn-ipv6
  • pull-ci-openshift-cluster-network-operator-master-e2e-metal-ipi-ovn-ipv6-ipsec
  • pull-ci-openshift-cluster-network-operator-master-e2e-network-mtu-migration-ovn-ipv4
  • pull-ci-openshift-cluster-network-operator-master-e2e-network-mtu-migration-ovn-ipv6
  • pull-ci-openshift-cluster-network-operator-master-e2e-openstack-ovn
  • pull-ci-openshift-cluster-network-operator-master-e2e-ovn-hybrid-step-registry
  • pull-ci-openshift-cluster-network-operator-master-e2e-ovn-ipsec-step-registry
  • pull-ci-openshift-cluster-network-operator-master-e2e-ovn-step-registry
  • pull-ci-openshift-cluster-network-operator-master-e2e-vsphere-ovn
  • pull-ci-openshift-cluster-network-operator-master-e2e-vsphere-ovn-dualstack
  • pull-ci-openshift-cluster-network-operator-master-e2e-vsphere-ovn-dualstack-primaryv6
  • pull-ci-openshift-cluster-network-operator-master-images
  • pull-ci-openshift-cluster-network-operator-master-lint
  • pull-ci-openshift-cluster-network-operator-master-okd-scos-images
  • pull-ci-openshift-cluster-network-operator-master-security
  • pull-ci-openshift-cluster-network-operator-master-unit
  • pull-ci-openshift-cluster-network-operator-master-verify
Details

In response to this:

/test ?

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@jcaamano

Copy link
Copy Markdown
Contributor Author

/test e2e-metal-ipi-ovn-ipv6

1 similar comment
@jcaamano

Copy link
Copy Markdown
Contributor Author

/test e2e-metal-ipi-ovn-ipv6

@jcaamano

Copy link
Copy Markdown
Contributor Author

/test images
/test e2e-metal-ipi-ovn

@jcaamano

Copy link
Copy Markdown
Contributor Author

/test e2e-metal-ipi-ovn-ipv6

@jcaamano

Copy link
Copy Markdown
Contributor Author

/test images
/test e2e-metal-ipi-ovn-ipv6

@jcaamano

Copy link
Copy Markdown
Contributor Author

/test images
/test e2e-metal-ipi-ovn-ipv6

1 similar comment
@jcaamano

Copy link
Copy Markdown
Contributor Author

/test images
/test e2e-metal-ipi-ovn-ipv6

@jcaamano

jcaamano commented Aug 5, 2024

Copy link
Copy Markdown
Contributor Author

/test images
/test e2e-metal-ipi-ovn-ipv6

@jcaamano

jcaamano commented Aug 5, 2024

Copy link
Copy Markdown
Contributor Author

/test images
/test e2e-metal-ipi-ovn-ipv6

@jcaamano

jcaamano commented Aug 5, 2024

Copy link
Copy Markdown
Contributor Author

/test images

@jcaamano

jcaamano commented Aug 7, 2024

Copy link
Copy Markdown
Contributor Author

/hold

we need frr-k8s image in the payload first

@openshift-ci openshift-ci Bot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Aug 7, 2024
@jcaamano jcaamano changed the title Deploy FRR-K8s SDN-5072: Deploy FRR-K8s Aug 7, 2024
@openshift-ci-robot

openshift-ci-robot commented Aug 7, 2024

Copy link
Copy Markdown
Contributor

@jcaamano: This pull request references SDN-5072 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.17.0" version, but no target version was set.

Details

In response to this:

Deploys FRR-K8s if enabled both if enabled both in the API and the feature gate

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Aug 7, 2024
@openshift-ci-robot

openshift-ci-robot commented Aug 7, 2024

Copy link
Copy Markdown
Contributor

@jcaamano: This pull request references SDN-5072 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.17.0" version, but no target version was set.

Details

In response to this:

Deploys FRR-K8s if enabled both if enabled both in the API and the feature gate

I used the helm chart (at this time HEAD of release-4.17 branch):
https://github.com/openshift/metallb-operator/blob/6de2375a6350e62c0e34a9ebdd392b0832b76b86/bindata/deployment/helm/frr-k8s

with equivalent values of what metallb operator would use on default :

frrk8s:
 logLevel: info
 image:
   repository: quay.io/metallb/frr-k8s
   tag: v0.0.14
 serviceAccount:
   create: false
   name: frr-k8s-daemon
 disableCertRotation: true
 frr:
   image:
     repository: quay.io/frrouting/frr
     tag: 9.1.0
   metricsBindAddress: 127.0.0.1
   metricsPort: 7573
   secureMetricsPort: 9141
prometheus:
 metricsPort: 7572
 secureMetricsPort: 9140
 metricsTLSSecret: frr-k8s-certs-secret
 serviceAccount: foo
 namespace: bar
 rbacProxy:
   repository: gcr.io/kubebuilder/kube-rbac-proxy
   tag: v0.11.0
 serviceMonitor:
   enabled: true
   tlsConfig:
     caFile: /etc/prometheus/configmaps/serving-certs-ca-bundle/service-ca.crt
     certFile: /etc/prometheus/secrets/metrics-client-certs/tls.crt
     insecureSkipVerify: false
     keyFile: /etc/prometheus/secrets/metrics-client-certs/tls.key
     serverName: frr-k8s-monitor-service.metallb-system.svc
   metricRelabelings:
   - regex: frrk8s_bgp_(.*)
     replacement: metallb_bgp_$1
     sourceLabels: [__name__]
     targetLabel: __name__
   - regex: frrk8s_bfd_(.*)
     replacement: metallb_bfd_$1
     sourceLabels: [__name__]
     targetLabel: __name__

This does not generate the CRDs or RBAC though.

CRDs were picked from
https://github.com/openshift/metallb-operator/tree/6de2375a6350e62c0e34a9ebdd392b0832b76b86/bundle/manifests

RBAC was picked from
https://github.com/openshift/metallb-operator/blob/6de2375a6350e62c0e34a9ebdd392b0832b76b86/config/metallb_rbac/metallb.yaml

Then I applied the same changes metallb operator applies programatically changes from
https://github.com/openshift/metallb-operator/blob/6de2375a6350e62c0e34a9ebdd392b0832b76b86/pkg/helm/frrk8s.go#L79

The resulting configuration was used as source. On top of that, changes following CNO and OCP managemenet conventions wre applied and this is the resulting diff vs source:

❯ diff -u10 upstream.yaml cno.yaml       
--- upstream.yaml	2024-08-07 17:10:10.893991403 +0000
+++ cno.yaml	2024-08-07 17:09:09.327710107 +0000
@@ -1,10 +1,24 @@
+apiVersion: v1
+kind: Namespace
+metadata:
+  labels:
+    openshift.io/cluster-monitoring: "true"
+    pod-security.kubernetes.io/audit: privileged
+    pod-security.kubernetes.io/enforce: privileged
+    pod-security.kubernetes.io/warn: privileged
+  name: openshift-frr-k8s
+  annotations:
+    openshift.io/node-selector: ""
+    openshift.io/description: "FRR-K8s components"
+    workload.openshift.io/allowed: "management"
+---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  annotations:
    controller-gen.kubebuilder.io/version: v0.14.0
  name: frrconfigurations.frrk8s.metallb.io
spec:
  group: frrk8s.metallb.io
  names:
    kind: FRRConfiguration
@@ -521,52 +535,43 @@
            type: object
        type: object
    served: true
    storage: true
    subresources:
      status: {}
---
apiVersion: v1
kind: ServiceAccount
metadata:
-  labels:
-    app.kubernetes.io/component: rbac
-    app.kubernetes.io/created-by: frr-k8s
-    app.kubernetes.io/instance: frr-k8s-sa
-    app.kubernetes.io/managed-by: kustomize
-    app.kubernetes.io/name: serviceaccount
-    app.kubernetes.io/part-of: frr-k8s
  name: frr-k8s-daemon
-  namespace: metallb-system
+  namespace: openshift-frr-k8s
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
-  labels:
-    app: frr-k8s
-  name: frr-k8s-daemon-role
-  namespace: metallb-system
+  name: openshift-frr-k8s
+  namespace: openshift-frr-k8s
rules:
- apiGroups:
  - ""
  resources:
  - secrets
  verbs:
  - get
  - list
  - watch
  - update
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
-  name: frr-k8s-daemon-role
+  name: openshift-frr-k8s
rules:
- apiGroups:
  - ""
  resources:
  - nodes
  verbs:
  - get
  - list
  - watch
- apiGroups:
@@ -624,118 +629,79 @@
  - update
  - watch
- apiGroups:
  - frrk8s.metallb.io
  resources:
  - frrnodestates/status
  verbs:
  - get
  - patch
  - update
----
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRole
-metadata:
-  labels:
-    app.kubernetes.io/component: kube-rbac-proxy
-    app.kubernetes.io/created-by: frr-k8s
-    app.kubernetes.io/instance: proxy-role
-    app.kubernetes.io/managed-by: kustomize
-    app.kubernetes.io/name: clusterrole
-    app.kubernetes.io/part-of: frr-k8s
-  name: frr-k8s-proxy-role
-rules:
- apiGroups:
  - authentication.k8s.io
  resources:
  - tokenreviews
  verbs:
  - create
- apiGroups:
  - authorization.k8s.io
  resources:
  - subjectaccessreviews
  verbs:
  - create
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
-  labels:
-    app.kubernetes.io/component: rbac
-    app.kubernetes.io/created-by: frr-k8s
-    app.kubernetes.io/instance: frr-k8s-rolebinding
-    app.kubernetes.io/managed-by: kustomize
-    app.kubernetes.io/name: rolebinding
-    app.kubernetes.io/part-of: frr-k8s
-  name: frr-k8s-daemon-rolebinding
-  namespace: metallb-system
+  name: openshift-frr-k8s
+  namespace: openshift-frr-k8s
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
-  name: frr-k8s-daemon-role
+  name: openshift-frr-k8s
subjects:
- kind: ServiceAccount
  name: frr-k8s-daemon
-  namespace: metallb-system
+  namespace: openshift-frr-k8s
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
-  labels:
-    app.kubernetes.io/component: rbac
-    app.kubernetes.io/created-by: frr-k8s
-    app.kubernetes.io/instance: frr-k8s-rolebinding
-    app.kubernetes.io/managed-by: kustomize
-    app.kubernetes.io/name: clusterrolebinding
-    app.kubernetes.io/part-of: frr-k8s
-  name: frr-k8s-daemon-rolebinding
+  name: openshift-frr-k8s
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
-  name: frr-k8s-daemon-role
+  name: openshift-frr-k8s
subjects:
- kind: ServiceAccount
  name: frr-k8s-daemon
-  namespace: metallb-system
+  namespace: openshift-frr-k8s
---
apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRoleBinding
+kind: RoleBinding
metadata:
-  labels:
-    app.kubernetes.io/component: kube-rbac-proxy
-    app.kubernetes.io/created-by: frr-k8s
-    app.kubernetes.io/instance: proxy-rolebinding
-    app.kubernetes.io/managed-by: kustomize
-    app.kubernetes.io/name: clusterrolebinding
-    app.kubernetes.io/part-of: frr-k8s
-  name: frr-k8s-proxy-rolebinding
+  name: system:openshift:scc:privileged
+  namespace: openshift-frr-k8s
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
-  name: frr-k8s-proxy-role
+  name: system:openshift:scc:privileged
subjects:
- kind: ServiceAccount
  name: frr-k8s-daemon
-  namespace: metallb-system
+  namespace: openshift-frr-k8s
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: frr-startup
-  namespace: "openshift-frr-k8s"
-  labels:
-    helm.sh/chart: frr-k8s-0.0.14
-    app: frr-k8s
-    app.kubernetes.io/version: "v0.0.14"
-    app.kubernetes.io/managed-by: Helm
-    component: frr-k8s
+  namespace: openshift-frr-k8s
data:
  daemons: |
    # This file tells the frr package which daemons to start.
    #
    # Sample configurations for these daemons can be found in
    # /usr/share/doc/frr/examples/.
    #
    # ATTENTION:
    #
    # When activating a daemon for the first time, a config file, even if it is
@@ -818,116 +784,127 @@
    ! So anything configured here is only temporary.
    frr version 8.0
    frr defaults traditional
    hostname Router
    line vty
    log file /etc/frr/frr.log informational
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
-  name: frrk8s-frr-k8s
-  namespace: "openshift-frr-k8s"
+  name: frr-k8s
+  namespace: openshift-frr-k8s
  labels:
-    helm.sh/chart: frr-k8s-0.0.14
    app: frr-k8s
-    app.kubernetes.io/version: "v0.0.14"
-    app.kubernetes.io/managed-by: Helm
    component: frr-k8s
-    app: "frr-k8s"
+  annotations:
+    release.openshift.io/version: "{{.ReleaseVersion}}"
spec:
  updateStrategy:
    type: RollingUpdate
+    rollingUpdate:
+      maxUnavailable: 10%
  selector:
    matchLabels:
      app: frr-k8s
      component: frr-k8s
  template:
    metadata:
      labels:
        app: frr-k8s
        component: frr-k8s
-        app: "frr-k8s"
+      annotations:
+        target.workload.openshift.io/management: '{"effect": "PreferredDuringScheduling"}'
+        openshift.io/required-scc: privileged
    spec:
      serviceAccountName: frr-k8s-daemon
+      priorityClassName: system-node-critical
      terminationGracePeriodSeconds: 0
      hostNetwork: true
      volumes:
      - name: frr-sockets
        emptyDir: {}
      - name: frr-startup
        configMap:
          name: frr-startup
      - name: frr-conf
        emptyDir: {}
      - name: reloader
        emptyDir: {}
      - name: metrics
        emptyDir: {}
      - name: metrics-certs
        secret:
          secretName: frr-k8s-certs-secret
      initContainers:
      # Copies the initial config files with the right permissions to the shared volume.
      - name: cp-frr-files
-        image: quay.io/frrouting/frr:9.1.0
+        image: {{.FRRK8sImage}}
        securityContext:
          runAsUser: 100
          runAsGroup: 101
        command: ["/bin/sh", "-c", "cp -rLf /tmp/frr/* /etc/frr/"]
+        terminationMessagePolicy: FallbackToLogsOnError
        volumeMounts:
        - name: frr-startup
          mountPath: /tmp/frr
        - name: frr-conf
          mountPath: /etc/frr
      # Copies the reloader to the shared volume between the speaker and reloader.
      - name: cp-reloader
-        image: quay.io/metallb/frr-k8s:v0.0.14
+        image: {{.FRRK8sImage}}
        command: ["/bin/sh", "-c", "cp -f /frr-reloader.sh /etc/frr_reloader/"]
+        terminationMessagePolicy: FallbackToLogsOnError
        volumeMounts:
        - name: reloader
          mountPath: /etc/frr_reloader
      # Copies the metrics exporter
      - name: cp-metrics
-        image: quay.io/metallb/frr-k8s:v0.0.14
+        image: {{.FRRK8sImage}}
        command: ["/bin/sh", "-c", "cp -f /frr-metrics /etc/frr_metrics/"]
+        terminationMessagePolicy: FallbackToLogsOnError
        volumeMounts:
        - name: metrics
          mountPath: /etc/frr_metrics
      shareProcessNamespace: true
      containers:
      - name: controller
-        image: quay.io/metallb/frr-k8s:v0.0.14
+        image: {{.FRRK8sImage}}
        command:
        - /frr-k8s
        args:
-        - "--node-name=$(NODE_NAME)"
-        - "--namespace=$(NAMESPACE)"
-        - "--metrics-bind-address=127.0.0.1:7572"
+        - --node-name=$(NODE_NAME)
+        - --namespace=$(NAMESPACE)
+        - --metrics-bind-address=127.0.0.1:7572
        - --log-level=info
        - --health-probe-bind-address=127.0.0.1:8081
        env:
        - name: FRR_CONFIG_FILE
          value: /etc/frr_reloader/frr.conf
        - name: FRR_RELOADER_PID_FILE
          value: /etc/frr_reloader/reloader.pid
        - name: NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        - name: NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        ports:
        - containerPort: 7572
          name: monitoring
+        resources:
+          requests:
+            cpu: 100m
+            memory: 200Mi
+        terminationMessagePolicy: FallbackToLogsOnError
        livenessProbe:
          httpGet:
            path: /healthz
            port: 8081
            host: 127.0.0.1
          initialDelaySeconds: 10
          periodSeconds: 10
          timeoutSeconds: 1
          successThreshold: 1
          failureThreshold: 3
@@ -953,21 +930,21 @@
          - name: reloader
            mountPath: /etc/frr_reloader
      - name: frr
        securityContext:
          capabilities:
            add:
            - NET_ADMIN
            - NET_RAW
            - SYS_ADMIN
            - NET_BIND_SERVICE
-        image: quay.io/frrouting/frr:9.1.0
+        image: {{.FRRK8sImage}}
        env:
        - name: TINI_SUBREAPER
          value: "true"
        volumeMounts:
        - name: frr-sockets
          mountPath: /var/run/frr
        - name: frr-conf
          mountPath: /etc/frr
        # The command is FRR's default entrypoint & waiting for the log file to appear and tailing it.
        # If the log file isn't created in 60 seconds the tail fails and the container is restarted.
@@ -976,217 +953,208 @@
        - /bin/sh
        - -c
        - |
          /sbin/tini -- /usr/lib/frr/docker-start &
          attempts=0
          until [[ -f /etc/frr/frr.log || $attempts -eq 60 ]]; do
            sleep 1
            attempts=$(( $attempts + 1 ))
          done
          tail -f /etc/frr/frr.log
+        resources:
+          requests:
+            cpu: 100m
+            memory: 200Mi
+        terminationMessagePolicy: FallbackToLogsOnError
        livenessProbe:
          httpGet:
            path: /livez
            port: 7573
            host: 127.0.0.1
          periodSeconds: 10
          failureThreshold: 3
        startupProbe:
          httpGet:
            path: /livez
            port: 7573
            host: 127.0.0.1
          failureThreshold: 30
          periodSeconds: 5
      - name: reloader
-        image: quay.io/frrouting/frr:9.1.0
+        image: {{.FRRK8sImage}}
        command: ["/etc/frr_reloader/frr-reloader.sh"]
+        resources:
+          requests:
+            cpu: 10m
+            memory: 20Mi
+        terminationMessagePolicy: FallbackToLogsOnError
        volumeMounts:
        - name: frr-sockets
          mountPath: /var/run/frr
        - name: frr-conf
          mountPath: /etc/frr
        - name: reloader
          mountPath: /etc/frr_reloader
      - name: frr-metrics
-        image: quay.io/frrouting/frr:9.1.0
+        image: {{.FRRK8sImage}}
        command: ["/etc/frr_metrics/frr-metrics"]
        args:
        - --metrics-port=7573
        - --metrics-bind-address=127.0.0.1
        ports:
        - containerPort: 7573
          name: monitoring
+        resources:
+          requests:
+            cpu: 10m
+            memory: 20Mi
+        terminationMessagePolicy: FallbackToLogsOnError
        volumeMounts:
        - name: frr-sockets
          mountPath: /var/run/frr
        - name: frr-conf
          mountPath: /etc/frr
        - name: metrics
          mountPath: /etc/frr_metrics
      - name: kube-rbac-proxy
-        image: gcr.io/kubebuilder/kube-rbac-proxy:v0.11.0
-        imagePullPolicy: 
+        image: {{.KubeRBACProxyImage}}
        args:
        - --logtostderr
        - --secure-listen-address=:9140
        - --upstream=http://127.0.0.1:7572/
-        - --tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
+        - --tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
        - --tls-private-key-file=/etc/metrics/tls.key
        - --tls-cert-file=/etc/metrics/tls.crt
        ports:
        - containerPort: 9140
          name: metricshttps
        resources:
          requests:
            cpu: 10m
            memory: 20Mi
        terminationMessagePolicy: FallbackToLogsOnError
        volumeMounts:
        - name: metrics-certs
          mountPath: /etc/metrics
          readOnly: true
      - name: kube-rbac-proxy-frr
-        image: gcr.io/kubebuilder/kube-rbac-proxy:v0.11.0
-        imagePullPolicy: 
+        image: {{.KubeRBACProxyImage}}
        args:
        - --logtostderr
        - --secure-listen-address=:9141
-        - --tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
+        - --tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
        - --upstream=http://127.0.0.1:7573/
        - --tls-private-key-file=/etc/metrics/tls.key
        - --tls-cert-file=/etc/metrics/tls.crt
        ports:
        - containerPort: 9141
          name: metricshttps
        resources:
          requests:
            cpu: 10m
            memory: 20Mi
        terminationMessagePolicy: FallbackToLogsOnError
        volumeMounts:
        - name: metrics-certs
          mountPath: /etc/metrics
          readOnly: true
      nodeSelector:
-        "kubernetes.io/os": linux
+        kubernetes.io/os: linux
      tolerations:
      - key: node-role.kubernetes.io/master
        effect: NoSchedule
        operator: Exists
      - key: node-role.kubernetes.io/control-plane
        effect: NoSchedule
        operator: Exists
---
apiVersion: v1
kind: Service
metadata:
-  annotations:
-    prometheus.io/scrape: "true"
+  name: frr-k8s-monitor-service
+  namespace: openshift-frr-k8s
  labels:
    name: frr-k8s-monitor-service
-  name: frr-k8s-monitor-service
-  namespace: "openshift-frr-k8s"
+  annotations:
+    prometheus.io/scrape: "true"
+    service.beta.openshift.io/serving-cert-secret-name: frr-k8s-certs-secret
spec:
  selector:
    app: frr-k8s
    component: frr-k8s
  clusterIP: None
  ports:
-  - name: "metricshttps"
+  - name: metricshttps
    port: 9140
-    targetPort: 9140
+    targetPort: metricshttps
  - name: frrmetricshttps
    port: 9141
-    targetPort: 9141
+    targetPort: frrmetricshttps
  sessionAffinity: None
  type: ClusterIP
---
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: frr-k8s-monitor
-  namespace: "openshift-frr-k8s"
+  namespace: openshift-frr-k8s
  labels:
-    helm.sh/chart: frr-k8s-0.0.14
    app: frr-k8s
-    app.kubernetes.io/version: "v0.0.14"
-    app.kubernetes.io/managed-by: Helm
    component: frr-k8s
+  annotations:
+    networkoperator.openshift.io/ignore-errors: ""
spec:
  endpoints:
-  - port: "metricshttps"
-    honorLabels: true
-    metricRelabelings:
-    - regex: frrk8s_bgp_(.*)
-      replacement: metallb_bgp_$1
-      sourceLabels:
-      - __name__
-      targetLabel: __name__
-    - regex: frrk8s_bfd_(.*)
-      replacement: metallb_bfd_$1
-      sourceLabels:
-      - __name__
-      targetLabel: __name__
-    bearerTokenFile: "/var/run/secrets/kubernetes.io/serviceaccount/token"
-    scheme: "https"
-    tlsConfig:
-      caFile: /etc/prometheus/configmaps/serving-certs-ca-bundle/service-ca.crt
-      certFile: /etc/prometheus/secrets/metrics-client-certs/tls.crt
-      insecureSkipVerify: false
-      keyFile: /etc/prometheus/secrets/metrics-client-certs/tls.key
-      serverName: frr-k8s-monitor-service.metallb-system.svc
-  - port: "frrmetricshttps"
-    honorLabels: true
-    metricRelabelings:
-    - regex: frrk8s_bgp_(.*)
-      replacement: metallb_bgp_$1
-      sourceLabels:
-      - __name__
-      targetLabel: __name__
-    - regex: frrk8s_bfd_(.*)
-      replacement: metallb_bfd_$1
-      sourceLabels:
-      - __name__
-      targetLabel: __name__
-    bearerTokenFile: "/var/run/secrets/kubernetes.io/serviceaccount/token"
-    scheme: "https"
-    tlsConfig:
-      caFile: /etc/prometheus/configmaps/serving-certs-ca-bundle/service-ca.crt
-      certFile: /etc/prometheus/secrets/metrics-client-certs/tls.crt
-      insecureSkipVerify: false
-      keyFile: /etc/prometheus/secrets/metrics-client-certs/tls.key
-      serverName: frr-k8s-monitor-service.metallb-system.svc
-  jobLabel: "app.kubernetes.io/name"
+    - port: metricshttps
+      honorLabels: true
+      bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
+      scheme: https
+      tlsConfig:
+        caFile: /etc/prometheus/configmaps/prometheus.io/scrape/service-ca.crt
+        serverName: openshift-frr-k8s-metrics-service.openshift-frr-k8s.svc
+        insecureSkipVerify: false
+    - port: frrmetricshttps
+      honorLabels: true
+      bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
+      scheme: https
+      tlsConfig:
+        caFile: /etc/prometheus/configmaps/serving-certs-ca-bundle/service-ca.crt
+        serverName: openshift-frr-k8s-metrics-service.openshift-frr-k8s.svc
+        insecureSkipVerify: false
+  jobLabel: app
  namespaceSelector:
    matchNames:
    - openshift-frr-k8s
  selector:
    matchLabels:
      name: frr-k8s-monitor-service
---
apiVersion: v1
kind: Service
metadata:
  name: frr-k8s-webhook-service
-  namespace: "openshift-frr-k8s"
+  namespace: openshift-frr-k8s
+  annotations:
+    service.beta.openshift.io/serving-cert-secret-name: frr-k8s-webhook-server-cert
spec:
  ports:
  - port: 443
    targetPort: 9443
  selector:
    component: frr-k8s-webhook-server
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
  name: frr-k8s-validating-webhook-configuration
+  annotations:
+    service.beta.openshift.io/inject-cabundle: "true"
webhooks:
- admissionReviewVersions:
  - v1
  clientConfig:
    service:
      name: frr-k8s-webhook-service
      namespace: openshift-frr-k8s
      path: /validate-frrk8s-metallb-io-v1beta1-frrconfiguration
  failurePolicy: Fail
  name: frrconfigurationsvalidationwebhook.metallb.io
@@ -1199,61 +1167,61 @@
    - CREATE
    - UPDATE
    resources:
    - frrconfigurations
  sideEffects: None
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: frr-k8s-webhook-server
-  namespace: "openshift-frr-k8s"
+  namespace: openshift-frr-k8s
  labels:
-    helm.sh/chart: frr-k8s-0.0.14
    app: frr-k8s
-    app.kubernetes.io/version: "v0.0.14"
-    app.kubernetes.io/managed-by: Helm
    component: frr-k8s-webhook-server
-    app: "frr-k8s"
+  annotations:
+    release.openshift.io/version: "{{.ReleaseVersion}}"
spec:
  selector:
    matchLabels:
      component: frr-k8s-webhook-server
  template:
    metadata:
-      annotations:
-        kubectl.kubernetes.io/default-container: frr-k8s-webhook-server
      labels:
        component: frr-k8s-webhook-server
+      annotations:
+        target.workload.openshift.io/management: '{"effect": "PreferredDuringScheduling"}'
+        openshift.io/required-scc: restricted-v2
    spec:
      containers:
      - command:
        - /frr-k8s
        args:
        - --log-level=info
-        - "--webhook-mode=onlywebhook"
-        - "--disable-cert-rotation=true"
-        - "--namespace=$(NAMESPACE)"
+        - --webhook-mode=onlywebhook
+        - --disable-cert-rotation=true
+        - --namespace=$(NAMESPACE)
        - --health-probe-bind-address=:8081
        env:
        - name: NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
-        image: quay.io/metallb/frr-k8s:v0.0.14
+        image: {{.FRRK8sImage}}
        name: frr-k8s-webhook-server
        securityContext:
-          allowPrivilegeEscalation: false
-          capabilities:
-            drop:
-              - ALL
-          readOnlyRootFilesystem: true
+         runAsNonRoot: true
+        resources:
+          requests:
+            cpu: 10m
+            memory: 50Mi
+        terminationMessagePolicy: FallbackToLogsOnError
        livenessProbe:
          httpGet:
            path: /healthz
            port: 8081
          initialDelaySeconds: 10
          periodSeconds: 10
          failureThreshold: 3
        readinessProbe:
          httpGet:
            path: /readyz
@@ -1271,11 +1239,12 @@
        operator: Exists
      - key: node-role.kubernetes.io/control-plane
        effect: NoSchedule
        operator: Exists
      volumes:
      - name: cert
        secret:
          defaultMode: 420
          secretName: frr-k8s-webhook-server-cert
      serviceAccountName: frr-k8s-daemon
+      priorityClassName: system-cluster-critical
      terminationGracePeriodSeconds: 10

I am sure this will need further adjustments but aiming for a good starting point.

This is a diff

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci-robot

openshift-ci-robot commented Aug 7, 2024

Copy link
Copy Markdown
Contributor

@jcaamano: This pull request references SDN-5072 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.17.0" version, but no target version was set.

Details

In response to this:

Deploys FRR-K8s if enabled both if enabled both in the API and the feature gate

I used the helm chart (at this time HEAD of release-4.17 branch):
https://github.com/openshift/metallb-operator/blob/6de2375a6350e62c0e34a9ebdd392b0832b76b86/bindata/deployment/helm/frr-k8s

with equivalent values of what metallb operator would use on default :

frrk8s:
 logLevel: info
 image:
   repository: quay.io/metallb/frr-k8s
   tag: v0.0.14
 serviceAccount:
   create: false
   name: frr-k8s-daemon
 disableCertRotation: true
 frr:
   image:
     repository: quay.io/frrouting/frr
     tag: 9.1.0
   metricsBindAddress: 127.0.0.1
   metricsPort: 7573
   secureMetricsPort: 9141
prometheus:
 metricsPort: 7572
 secureMetricsPort: 9140
 metricsTLSSecret: frr-k8s-certs-secret
 serviceAccount: foo
 namespace: bar
 rbacProxy:
   repository: gcr.io/kubebuilder/kube-rbac-proxy
   tag: v0.11.0
 serviceMonitor:
   enabled: true
   tlsConfig:
     caFile: /etc/prometheus/configmaps/serving-certs-ca-bundle/service-ca.crt
     certFile: /etc/prometheus/secrets/metrics-client-certs/tls.crt
     insecureSkipVerify: false
     keyFile: /etc/prometheus/secrets/metrics-client-certs/tls.key
     serverName: frr-k8s-monitor-service.metallb-system.svc
   metricRelabelings:
   - regex: frrk8s_bgp_(.*)
     replacement: metallb_bgp_$1
     sourceLabels: [__name__]
     targetLabel: __name__
   - regex: frrk8s_bfd_(.*)
     replacement: metallb_bfd_$1
     sourceLabels: [__name__]
     targetLabel: __name__

This does not generate the CRDs or RBAC though.

CRDs were picked from
https://github.com/openshift/metallb-operator/tree/6de2375a6350e62c0e34a9ebdd392b0832b76b86/bundle/manifests

RBAC was picked from
https://github.com/openshift/metallb-operator/blob/6de2375a6350e62c0e34a9ebdd392b0832b76b86/config/metallb_rbac/metallb.yaml

Then I applied the same changes metallb operator applies programatically changes from
https://github.com/openshift/metallb-operator/blob/6de2375a6350e62c0e34a9ebdd392b0832b76b86/pkg/helm/frrk8s.go#L79

The resulting configuration was used as source. On top of that, changes following CNO and OCP managemenet conventions were applied, plus minor edits from me, and this is the resulting diff vs source:

❯ diff -u10 upstream.yaml cno.yaml       
--- upstream.yaml	2024-08-07 17:10:10.893991403 +0000
+++ cno.yaml	2024-08-07 17:09:09.327710107 +0000
@@ -1,10 +1,24 @@
+apiVersion: v1
+kind: Namespace
+metadata:
+  labels:
+    openshift.io/cluster-monitoring: "true"
+    pod-security.kubernetes.io/audit: privileged
+    pod-security.kubernetes.io/enforce: privileged
+    pod-security.kubernetes.io/warn: privileged
+  name: openshift-frr-k8s
+  annotations:
+    openshift.io/node-selector: ""
+    openshift.io/description: "FRR-K8s components"
+    workload.openshift.io/allowed: "management"
+---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  annotations:
    controller-gen.kubebuilder.io/version: v0.14.0
  name: frrconfigurations.frrk8s.metallb.io
spec:
  group: frrk8s.metallb.io
  names:
    kind: FRRConfiguration
@@ -521,52 +535,43 @@
            type: object
        type: object
    served: true
    storage: true
    subresources:
      status: {}
---
apiVersion: v1
kind: ServiceAccount
metadata:
-  labels:
-    app.kubernetes.io/component: rbac
-    app.kubernetes.io/created-by: frr-k8s
-    app.kubernetes.io/instance: frr-k8s-sa
-    app.kubernetes.io/managed-by: kustomize
-    app.kubernetes.io/name: serviceaccount
-    app.kubernetes.io/part-of: frr-k8s
  name: frr-k8s-daemon
-  namespace: metallb-system
+  namespace: openshift-frr-k8s
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
-  labels:
-    app: frr-k8s
-  name: frr-k8s-daemon-role
-  namespace: metallb-system
+  name: openshift-frr-k8s
+  namespace: openshift-frr-k8s
rules:
- apiGroups:
  - ""
  resources:
  - secrets
  verbs:
  - get
  - list
  - watch
  - update
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
-  name: frr-k8s-daemon-role
+  name: openshift-frr-k8s
rules:
- apiGroups:
  - ""
  resources:
  - nodes
  verbs:
  - get
  - list
  - watch
- apiGroups:
@@ -624,118 +629,79 @@
  - update
  - watch
- apiGroups:
  - frrk8s.metallb.io
  resources:
  - frrnodestates/status
  verbs:
  - get
  - patch
  - update
----
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRole
-metadata:
-  labels:
-    app.kubernetes.io/component: kube-rbac-proxy
-    app.kubernetes.io/created-by: frr-k8s
-    app.kubernetes.io/instance: proxy-role
-    app.kubernetes.io/managed-by: kustomize
-    app.kubernetes.io/name: clusterrole
-    app.kubernetes.io/part-of: frr-k8s
-  name: frr-k8s-proxy-role
-rules:
- apiGroups:
  - authentication.k8s.io
  resources:
  - tokenreviews
  verbs:
  - create
- apiGroups:
  - authorization.k8s.io
  resources:
  - subjectaccessreviews
  verbs:
  - create
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
-  labels:
-    app.kubernetes.io/component: rbac
-    app.kubernetes.io/created-by: frr-k8s
-    app.kubernetes.io/instance: frr-k8s-rolebinding
-    app.kubernetes.io/managed-by: kustomize
-    app.kubernetes.io/name: rolebinding
-    app.kubernetes.io/part-of: frr-k8s
-  name: frr-k8s-daemon-rolebinding
-  namespace: metallb-system
+  name: openshift-frr-k8s
+  namespace: openshift-frr-k8s
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
-  name: frr-k8s-daemon-role
+  name: openshift-frr-k8s
subjects:
- kind: ServiceAccount
  name: frr-k8s-daemon
-  namespace: metallb-system
+  namespace: openshift-frr-k8s
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
-  labels:
-    app.kubernetes.io/component: rbac
-    app.kubernetes.io/created-by: frr-k8s
-    app.kubernetes.io/instance: frr-k8s-rolebinding
-    app.kubernetes.io/managed-by: kustomize
-    app.kubernetes.io/name: clusterrolebinding
-    app.kubernetes.io/part-of: frr-k8s
-  name: frr-k8s-daemon-rolebinding
+  name: openshift-frr-k8s
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
-  name: frr-k8s-daemon-role
+  name: openshift-frr-k8s
subjects:
- kind: ServiceAccount
  name: frr-k8s-daemon
-  namespace: metallb-system
+  namespace: openshift-frr-k8s
---
apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRoleBinding
+kind: RoleBinding
metadata:
-  labels:
-    app.kubernetes.io/component: kube-rbac-proxy
-    app.kubernetes.io/created-by: frr-k8s
-    app.kubernetes.io/instance: proxy-rolebinding
-    app.kubernetes.io/managed-by: kustomize
-    app.kubernetes.io/name: clusterrolebinding
-    app.kubernetes.io/part-of: frr-k8s
-  name: frr-k8s-proxy-rolebinding
+  name: system:openshift:scc:privileged
+  namespace: openshift-frr-k8s
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
-  name: frr-k8s-proxy-role
+  name: system:openshift:scc:privileged
subjects:
- kind: ServiceAccount
  name: frr-k8s-daemon
-  namespace: metallb-system
+  namespace: openshift-frr-k8s
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: frr-startup
-  namespace: "openshift-frr-k8s"
-  labels:
-    helm.sh/chart: frr-k8s-0.0.14
-    app: frr-k8s
-    app.kubernetes.io/version: "v0.0.14"
-    app.kubernetes.io/managed-by: Helm
-    component: frr-k8s
+  namespace: openshift-frr-k8s
data:
  daemons: |
    # This file tells the frr package which daemons to start.
    #
    # Sample configurations for these daemons can be found in
    # /usr/share/doc/frr/examples/.
    #
    # ATTENTION:
    #
    # When activating a daemon for the first time, a config file, even if it is
@@ -818,116 +784,127 @@
    ! So anything configured here is only temporary.
    frr version 8.0
    frr defaults traditional
    hostname Router
    line vty
    log file /etc/frr/frr.log informational
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
-  name: frrk8s-frr-k8s
-  namespace: "openshift-frr-k8s"
+  name: frr-k8s
+  namespace: openshift-frr-k8s
  labels:
-    helm.sh/chart: frr-k8s-0.0.14
    app: frr-k8s
-    app.kubernetes.io/version: "v0.0.14"
-    app.kubernetes.io/managed-by: Helm
    component: frr-k8s
-    app: "frr-k8s"
+  annotations:
+    release.openshift.io/version: "{{.ReleaseVersion}}"
spec:
  updateStrategy:
    type: RollingUpdate
+    rollingUpdate:
+      maxUnavailable: 10%
  selector:
    matchLabels:
      app: frr-k8s
      component: frr-k8s
  template:
    metadata:
      labels:
        app: frr-k8s
        component: frr-k8s
-        app: "frr-k8s"
+      annotations:
+        target.workload.openshift.io/management: '{"effect": "PreferredDuringScheduling"}'
+        openshift.io/required-scc: privileged
    spec:
      serviceAccountName: frr-k8s-daemon
+      priorityClassName: system-node-critical
      terminationGracePeriodSeconds: 0
      hostNetwork: true
      volumes:
      - name: frr-sockets
        emptyDir: {}
      - name: frr-startup
        configMap:
          name: frr-startup
      - name: frr-conf
        emptyDir: {}
      - name: reloader
        emptyDir: {}
      - name: metrics
        emptyDir: {}
      - name: metrics-certs
        secret:
          secretName: frr-k8s-certs-secret
      initContainers:
      # Copies the initial config files with the right permissions to the shared volume.
      - name: cp-frr-files
-        image: quay.io/frrouting/frr:9.1.0
+        image: {{.FRRK8sImage}}
        securityContext:
          runAsUser: 100
          runAsGroup: 101
        command: ["/bin/sh", "-c", "cp -rLf /tmp/frr/* /etc/frr/"]
+        terminationMessagePolicy: FallbackToLogsOnError
        volumeMounts:
        - name: frr-startup
          mountPath: /tmp/frr
        - name: frr-conf
          mountPath: /etc/frr
      # Copies the reloader to the shared volume between the speaker and reloader.
      - name: cp-reloader
-        image: quay.io/metallb/frr-k8s:v0.0.14
+        image: {{.FRRK8sImage}}
        command: ["/bin/sh", "-c", "cp -f /frr-reloader.sh /etc/frr_reloader/"]
+        terminationMessagePolicy: FallbackToLogsOnError
        volumeMounts:
        - name: reloader
          mountPath: /etc/frr_reloader
      # Copies the metrics exporter
      - name: cp-metrics
-        image: quay.io/metallb/frr-k8s:v0.0.14
+        image: {{.FRRK8sImage}}
        command: ["/bin/sh", "-c", "cp -f /frr-metrics /etc/frr_metrics/"]
+        terminationMessagePolicy: FallbackToLogsOnError
        volumeMounts:
        - name: metrics
          mountPath: /etc/frr_metrics
      shareProcessNamespace: true
      containers:
      - name: controller
-        image: quay.io/metallb/frr-k8s:v0.0.14
+        image: {{.FRRK8sImage}}
        command:
        - /frr-k8s
        args:
-        - "--node-name=$(NODE_NAME)"
-        - "--namespace=$(NAMESPACE)"
-        - "--metrics-bind-address=127.0.0.1:7572"
+        - --node-name=$(NODE_NAME)
+        - --namespace=$(NAMESPACE)
+        - --metrics-bind-address=127.0.0.1:7572
        - --log-level=info
        - --health-probe-bind-address=127.0.0.1:8081
        env:
        - name: FRR_CONFIG_FILE
          value: /etc/frr_reloader/frr.conf
        - name: FRR_RELOADER_PID_FILE
          value: /etc/frr_reloader/reloader.pid
        - name: NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        - name: NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        ports:
        - containerPort: 7572
          name: monitoring
+        resources:
+          requests:
+            cpu: 100m
+            memory: 200Mi
+        terminationMessagePolicy: FallbackToLogsOnError
        livenessProbe:
          httpGet:
            path: /healthz
            port: 8081
            host: 127.0.0.1
          initialDelaySeconds: 10
          periodSeconds: 10
          timeoutSeconds: 1
          successThreshold: 1
          failureThreshold: 3
@@ -953,21 +930,21 @@
          - name: reloader
            mountPath: /etc/frr_reloader
      - name: frr
        securityContext:
          capabilities:
            add:
            - NET_ADMIN
            - NET_RAW
            - SYS_ADMIN
            - NET_BIND_SERVICE
-        image: quay.io/frrouting/frr:9.1.0
+        image: {{.FRRK8sImage}}
        env:
        - name: TINI_SUBREAPER
          value: "true"
        volumeMounts:
        - name: frr-sockets
          mountPath: /var/run/frr
        - name: frr-conf
          mountPath: /etc/frr
        # The command is FRR's default entrypoint & waiting for the log file to appear and tailing it.
        # If the log file isn't created in 60 seconds the tail fails and the container is restarted.
@@ -976,217 +953,208 @@
        - /bin/sh
        - -c
        - |
          /sbin/tini -- /usr/lib/frr/docker-start &
          attempts=0
          until [[ -f /etc/frr/frr.log || $attempts -eq 60 ]]; do
            sleep 1
            attempts=$(( $attempts + 1 ))
          done
          tail -f /etc/frr/frr.log
+        resources:
+          requests:
+            cpu: 100m
+            memory: 200Mi
+        terminationMessagePolicy: FallbackToLogsOnError
        livenessProbe:
          httpGet:
            path: /livez
            port: 7573
            host: 127.0.0.1
          periodSeconds: 10
          failureThreshold: 3
        startupProbe:
          httpGet:
            path: /livez
            port: 7573
            host: 127.0.0.1
          failureThreshold: 30
          periodSeconds: 5
      - name: reloader
-        image: quay.io/frrouting/frr:9.1.0
+        image: {{.FRRK8sImage}}
        command: ["/etc/frr_reloader/frr-reloader.sh"]
+        resources:
+          requests:
+            cpu: 10m
+            memory: 20Mi
+        terminationMessagePolicy: FallbackToLogsOnError
        volumeMounts:
        - name: frr-sockets
          mountPath: /var/run/frr
        - name: frr-conf
          mountPath: /etc/frr
        - name: reloader
          mountPath: /etc/frr_reloader
      - name: frr-metrics
-        image: quay.io/frrouting/frr:9.1.0
+        image: {{.FRRK8sImage}}
        command: ["/etc/frr_metrics/frr-metrics"]
        args:
        - --metrics-port=7573
        - --metrics-bind-address=127.0.0.1
        ports:
        - containerPort: 7573
          name: monitoring
+        resources:
+          requests:
+            cpu: 10m
+            memory: 20Mi
+        terminationMessagePolicy: FallbackToLogsOnError
        volumeMounts:
        - name: frr-sockets
          mountPath: /var/run/frr
        - name: frr-conf
          mountPath: /etc/frr
        - name: metrics
          mountPath: /etc/frr_metrics
      - name: kube-rbac-proxy
-        image: gcr.io/kubebuilder/kube-rbac-proxy:v0.11.0
-        imagePullPolicy: 
+        image: {{.KubeRBACProxyImage}}
        args:
        - --logtostderr
        - --secure-listen-address=:9140
        - --upstream=http://127.0.0.1:7572/
-        - --tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
+        - --tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
        - --tls-private-key-file=/etc/metrics/tls.key
        - --tls-cert-file=/etc/metrics/tls.crt
        ports:
        - containerPort: 9140
          name: metricshttps
        resources:
          requests:
            cpu: 10m
            memory: 20Mi
        terminationMessagePolicy: FallbackToLogsOnError
        volumeMounts:
        - name: metrics-certs
          mountPath: /etc/metrics
          readOnly: true
      - name: kube-rbac-proxy-frr
-        image: gcr.io/kubebuilder/kube-rbac-proxy:v0.11.0
-        imagePullPolicy: 
+        image: {{.KubeRBACProxyImage}}
        args:
        - --logtostderr
        - --secure-listen-address=:9141
-        - --tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
+        - --tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
        - --upstream=http://127.0.0.1:7573/
        - --tls-private-key-file=/etc/metrics/tls.key
        - --tls-cert-file=/etc/metrics/tls.crt
        ports:
        - containerPort: 9141
          name: metricshttps
        resources:
          requests:
            cpu: 10m
            memory: 20Mi
        terminationMessagePolicy: FallbackToLogsOnError
        volumeMounts:
        - name: metrics-certs
          mountPath: /etc/metrics
          readOnly: true
      nodeSelector:
-        "kubernetes.io/os": linux
+        kubernetes.io/os: linux
      tolerations:
      - key: node-role.kubernetes.io/master
        effect: NoSchedule
        operator: Exists
      - key: node-role.kubernetes.io/control-plane
        effect: NoSchedule
        operator: Exists
---
apiVersion: v1
kind: Service
metadata:
-  annotations:
-    prometheus.io/scrape: "true"
+  name: frr-k8s-monitor-service
+  namespace: openshift-frr-k8s
  labels:
    name: frr-k8s-monitor-service
-  name: frr-k8s-monitor-service
-  namespace: "openshift-frr-k8s"
+  annotations:
+    prometheus.io/scrape: "true"
+    service.beta.openshift.io/serving-cert-secret-name: frr-k8s-certs-secret
spec:
  selector:
    app: frr-k8s
    component: frr-k8s
  clusterIP: None
  ports:
-  - name: "metricshttps"
+  - name: metricshttps
    port: 9140
-    targetPort: 9140
+    targetPort: metricshttps
  - name: frrmetricshttps
    port: 9141
-    targetPort: 9141
+    targetPort: frrmetricshttps
  sessionAffinity: None
  type: ClusterIP
---
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: frr-k8s-monitor
-  namespace: "openshift-frr-k8s"
+  namespace: openshift-frr-k8s
  labels:
-    helm.sh/chart: frr-k8s-0.0.14
    app: frr-k8s
-    app.kubernetes.io/version: "v0.0.14"
-    app.kubernetes.io/managed-by: Helm
    component: frr-k8s
+  annotations:
+    networkoperator.openshift.io/ignore-errors: ""
spec:
  endpoints:
-  - port: "metricshttps"
-    honorLabels: true
-    metricRelabelings:
-    - regex: frrk8s_bgp_(.*)
-      replacement: metallb_bgp_$1
-      sourceLabels:
-      - __name__
-      targetLabel: __name__
-    - regex: frrk8s_bfd_(.*)
-      replacement: metallb_bfd_$1
-      sourceLabels:
-      - __name__
-      targetLabel: __name__
-    bearerTokenFile: "/var/run/secrets/kubernetes.io/serviceaccount/token"
-    scheme: "https"
-    tlsConfig:
-      caFile: /etc/prometheus/configmaps/serving-certs-ca-bundle/service-ca.crt
-      certFile: /etc/prometheus/secrets/metrics-client-certs/tls.crt
-      insecureSkipVerify: false
-      keyFile: /etc/prometheus/secrets/metrics-client-certs/tls.key
-      serverName: frr-k8s-monitor-service.metallb-system.svc
-  - port: "frrmetricshttps"
-    honorLabels: true
-    metricRelabelings:
-    - regex: frrk8s_bgp_(.*)
-      replacement: metallb_bgp_$1
-      sourceLabels:
-      - __name__
-      targetLabel: __name__
-    - regex: frrk8s_bfd_(.*)
-      replacement: metallb_bfd_$1
-      sourceLabels:
-      - __name__
-      targetLabel: __name__
-    bearerTokenFile: "/var/run/secrets/kubernetes.io/serviceaccount/token"
-    scheme: "https"
-    tlsConfig:
-      caFile: /etc/prometheus/configmaps/serving-certs-ca-bundle/service-ca.crt
-      certFile: /etc/prometheus/secrets/metrics-client-certs/tls.crt
-      insecureSkipVerify: false
-      keyFile: /etc/prometheus/secrets/metrics-client-certs/tls.key
-      serverName: frr-k8s-monitor-service.metallb-system.svc
-  jobLabel: "app.kubernetes.io/name"
+    - port: metricshttps
+      honorLabels: true
+      bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
+      scheme: https
+      tlsConfig:
+        caFile: /etc/prometheus/configmaps/prometheus.io/scrape/service-ca.crt
+        serverName: openshift-frr-k8s-metrics-service.openshift-frr-k8s.svc
+        insecureSkipVerify: false
+    - port: frrmetricshttps
+      honorLabels: true
+      bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
+      scheme: https
+      tlsConfig:
+        caFile: /etc/prometheus/configmaps/serving-certs-ca-bundle/service-ca.crt
+        serverName: openshift-frr-k8s-metrics-service.openshift-frr-k8s.svc
+        insecureSkipVerify: false
+  jobLabel: app
  namespaceSelector:
    matchNames:
    - openshift-frr-k8s
  selector:
    matchLabels:
      name: frr-k8s-monitor-service
---
apiVersion: v1
kind: Service
metadata:
  name: frr-k8s-webhook-service
-  namespace: "openshift-frr-k8s"
+  namespace: openshift-frr-k8s
+  annotations:
+    service.beta.openshift.io/serving-cert-secret-name: frr-k8s-webhook-server-cert
spec:
  ports:
  - port: 443
    targetPort: 9443
  selector:
    component: frr-k8s-webhook-server
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
  name: frr-k8s-validating-webhook-configuration
+  annotations:
+    service.beta.openshift.io/inject-cabundle: "true"
webhooks:
- admissionReviewVersions:
  - v1
  clientConfig:
    service:
      name: frr-k8s-webhook-service
      namespace: openshift-frr-k8s
      path: /validate-frrk8s-metallb-io-v1beta1-frrconfiguration
  failurePolicy: Fail
  name: frrconfigurationsvalidationwebhook.metallb.io
@@ -1199,61 +1167,61 @@
    - CREATE
    - UPDATE
    resources:
    - frrconfigurations
  sideEffects: None
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: frr-k8s-webhook-server
-  namespace: "openshift-frr-k8s"
+  namespace: openshift-frr-k8s
  labels:
-    helm.sh/chart: frr-k8s-0.0.14
    app: frr-k8s
-    app.kubernetes.io/version: "v0.0.14"
-    app.kubernetes.io/managed-by: Helm
    component: frr-k8s-webhook-server
-    app: "frr-k8s"
+  annotations:
+    release.openshift.io/version: "{{.ReleaseVersion}}"
spec:
  selector:
    matchLabels:
      component: frr-k8s-webhook-server
  template:
    metadata:
-      annotations:
-        kubectl.kubernetes.io/default-container: frr-k8s-webhook-server
      labels:
        component: frr-k8s-webhook-server
+      annotations:
+        target.workload.openshift.io/management: '{"effect": "PreferredDuringScheduling"}'
+        openshift.io/required-scc: restricted-v2
    spec:
      containers:
      - command:
        - /frr-k8s
        args:
        - --log-level=info
-        - "--webhook-mode=onlywebhook"
-        - "--disable-cert-rotation=true"
-        - "--namespace=$(NAMESPACE)"
+        - --webhook-mode=onlywebhook
+        - --disable-cert-rotation=true
+        - --namespace=$(NAMESPACE)
        - --health-probe-bind-address=:8081
        env:
        - name: NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
-        image: quay.io/metallb/frr-k8s:v0.0.14
+        image: {{.FRRK8sImage}}
        name: frr-k8s-webhook-server
        securityContext:
-          allowPrivilegeEscalation: false
-          capabilities:
-            drop:
-              - ALL
-          readOnlyRootFilesystem: true
+         runAsNonRoot: true
+        resources:
+          requests:
+            cpu: 10m
+            memory: 50Mi
+        terminationMessagePolicy: FallbackToLogsOnError
        livenessProbe:
          httpGet:
            path: /healthz
            port: 8081
          initialDelaySeconds: 10
          periodSeconds: 10
          failureThreshold: 3
        readinessProbe:
          httpGet:
            path: /readyz
@@ -1271,11 +1239,12 @@
        operator: Exists
      - key: node-role.kubernetes.io/control-plane
        effect: NoSchedule
        operator: Exists
      volumes:
      - name: cert
        secret:
          defaultMode: 420
          secretName: frr-k8s-webhook-server-cert
      serviceAccountName: frr-k8s-daemon
+      priorityClassName: system-cluster-critical
      terminationGracePeriodSeconds: 10

I am sure this will need further adjustments but aiming for a good starting point.

This is a diff

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

from:
kind: DockerImage
name: quay.io/openshift/origin-cli:latest
- name: metallb-frr

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kyrtapz

kyrtapz commented Aug 8, 2024

Copy link
Copy Markdown
Contributor

/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Aug 8, 2024
go get github.com/openshift/api
go mod vendor
go mod tidy

Signed-off-by: Jaime Caamaño Ruiz <jcaamano@redhat.com>
@openshift-ci openshift-ci Bot removed the lgtm Indicates that a PR is ready to be merged. label Aug 8, 2024
Signed-off-by: Jaime Caamaño Ruiz <jcaamano@redhat.com>
@kyrtapz

kyrtapz commented Aug 8, 2024

Copy link
Copy Markdown
Contributor

/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Aug 8, 2024
@openshift-ci

openshift-ci Bot commented Aug 8, 2024

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: jcaamano, kyrtapz

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@jcaamano

jcaamano commented Aug 8, 2024

Copy link
Copy Markdown
Contributor Author

/test e2e-metal-ipi-ovn-ipv6

@jcaamano

jcaamano commented Aug 8, 2024

Copy link
Copy Markdown
Contributor Author

/hold cancel

openshift-eng/ocp-build-data#5209 merged

@openshift-ci openshift-ci Bot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Aug 8, 2024
@openshift-merge-bot
openshift-merge-bot Bot merged commit 1381d25 into openshift:master Aug 9, 2024
@openshift-ci

openshift-ci Bot commented Aug 9, 2024

Copy link
Copy Markdown
Contributor

@jcaamano: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/security 37c6518 link false /test security
ci/prow/e2e-aws-hypershift-ovn-kubevirt 37c6518 link false /test e2e-aws-hypershift-ovn-kubevirt
ci/prow/e2e-metal-ipi-ovn-ipv6-ipsec 37c6518 link false /test e2e-metal-ipi-ovn-ipv6-ipsec
ci/prow/e2e-vsphere-ovn-dualstack-primaryv6 37c6518 link false /test e2e-vsphere-ovn-dualstack-primaryv6
ci/prow/e2e-vsphere-ovn-dualstack 37c6518 link false /test e2e-vsphere-ovn-dualstack

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. lgtm Indicates that a PR is ready to be merged.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants