kind: DaemonSet
apiVersion: apps/v1
metadata:
  name: ovnkube-node
  namespace: openshift-ovn-kubernetes
  annotations:
    kubernetes.io/description: |
      This daemonset launches the ovn-kubernetes per node networking components.
    release.openshift.io/version: "{{.ReleaseVersion}}"
spec:
  selector:
    matchLabels:
      app: ovnkube-node
  updateStrategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: ovnkube-node
        component: network
        type: infra
        openshift.io/component: network
        kubernetes.io/os: "linux"
    spec:
      serviceAccountName: ovn-kubernetes-node
      hostNetwork: true
      hostPID: true
      priorityClassName: "system-node-critical"
      # volumes in all containers:
      # (container) -> (host)
      # /etc/openvswitch -> /var/lib/openvswitch/etc - ovsdb system id
      # /var/lib/openvswitch -> /var/lib/openvswitch/data - ovsdb data
      # /run/openvswitch -> tmpfs - ovsdb sockets
      # /env -> configmap env-overrides - debug overrides
      containers:
      # ovn-controller: programs the vswitch with flows from the sbdb
      - name: ovn-controller
        image: "{{.OvnImage}}"
        command:
        - /bin/bash
        - -c
        - |
          set -e
          if [[ -f "/env/${K8S_NODE}" ]]; then
            set -o allexport
            source "/env/${K8S_NODE}"
            set +o allexport
          fi
          echo "$(date -Iseconds) - starting ovn-controller"
          exec ovn-controller unix:/var/run/openvswitch/db.sock -vfile:off \
            --no-chdir --pidfile=/var/run/ovn/ovn-controller.pid \
            -p /ovn-cert/tls.key -c /ovn-cert/tls.crt -C /ovn-ca/ca-bundle.crt \
            -vconsole:"${OVN_LOG_LEVEL}"
        securityContext:
          privileged: true
        env:
        - name: OVN_LOG_LEVEL
          value: info
        - name: K8S_NODE
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        volumeMounts:
        - mountPath: /run/openvswitch
          name: run-openvswitch
        - mountPath: /run/ovn/
          name: run-ovn
        - mountPath: /etc/openvswitch
          name: etc-openvswitch
        - mountPath: /etc/ovn/
          name: etc-openvswitch
        - mountPath: /var/lib/openvswitch
          name: var-lib-openvswitch
        - mountPath: /env
          name: env-overrides
        - mountPath: /ovn-cert
          name: ovn-cert
        - mountPath: /ovn-ca
          name: ovn-ca
        terminationMessagePolicy: FallbackToLogsOnError
        resources:
          requests:
            cpu: 10m
            memory: 300Mi

      # ovnkube-node: does node-level bookkeeping and configuration
      - name: ovnkube-node
        image: "{{.OvnImage}}"
        command:
        - /bin/bash
        - -c
        - |
          set -xe
          if [[ -f "/env/${K8S_NODE}" ]]; then
            set -o allexport
            source "/env/${K8S_NODE}"
            set +o allexport
          fi
          echo "I$(date "+%m%d %H:%M:%S.%N") - waiting for db_ip addresses"
          cp -f /usr/libexec/cni/ovn-k8s-cni-overlay /cni-bin-dir/
          ovn_config_namespace=openshift-ovn-kubernetes
          echo "I$(date "+%m%d %H:%M:%S.%N") - disable conntrack on geneve port"
          iptables -t raw -A PREROUTING -p udp --dport {{.GenevePort}} -j NOTRACK
          iptables -t raw -A OUTPUT -p udp --dport {{.GenevePort}} -j NOTRACK
          retries=0
          while true; do
            db_ip=$(kubectl get ep -n ${ovn_config_namespace} ovnkube-db -o jsonpath='{.subsets[0].addresses[0].ip}')
            if [[ -n "${db_ip}" ]]; then
              break
            fi
            (( retries += 1 ))
            if [[ "${retries}" -gt 40 ]]; then
              echo "E$(date "+%m%d %H:%M:%S.%N") - db endpoint never came up"
              exit 1
            fi
            echo "I$(date "+%m%d %H:%M:%S.%N") - waiting for db endpoint"
            sleep 5
          done

          echo "I$(date "+%m%d %H:%M:%S.%N") - starting ovnkube-node db_ip ${db_ip}"
          hybrid_overlay_flags=
          if [[ -n "{{.OVNHybridOverlayEnable}}" ]]; then
            hybrid_overlay_flags="--enable-hybrid-overlay --no-hostsubnet-nodes=kubernetes.io/os=windows"
            if [[ -n "{{.OVNHybridOverlayNetCIDR}}" ]]; then
              hybrid_overlay_flags="${hybrid_overlay_flags} --hybrid-overlay-cluster-subnets={{.OVNHybridOverlayNetCIDR}}"
            fi
          fi
          
          exec /usr/bin/ovnkube --init-node "${K8S_NODE}" \
            --nb-address "{{.OVN_NB_DB_LIST}}" \
            --sb-address "{{.OVN_SB_DB_LIST}}" \
            --nb-client-privkey /ovn-cert/tls.key \
            --nb-client-cert /ovn-cert/tls.crt \
            --nb-client-cacert /ovn-ca/ca-bundle.crt \
            --sb-client-privkey /ovn-cert/tls.key \
            --sb-client-cert /ovn-cert/tls.crt \
            --sb-client-cacert /ovn-ca/ca-bundle.crt \
            --config-file=/run/ovnkube-config/ovnkube.conf \
            --loglevel "${OVN_KUBE_LOG_LEVEL}" \
            --inactivity-probe="${OVN_CONTROLLER_INACTIVITY_PROBE}" \
            ${hybrid_overlay_flags} \
            --metrics-bind-address "0.0.0.0:9103"
        env:
        # for kubectl
        - name: KUBERNETES_SERVICE_PORT
          value: "{{.KUBERNETES_SERVICE_PORT}}"
        - name: KUBERNETES_SERVICE_HOST
          value: "{{.KUBERNETES_SERVICE_HOST}}"
        - name: OVN_CONTROLLER_INACTIVITY_PROBE
          value: "{{.OVN_CONTROLLER_INACTIVITY_PROBE}}"
        - name: OVN_KUBE_LOG_LEVEL
          value: "4"
        - name: K8S_NODE
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        ports:
        - name: metrics-port
          containerPort: 9103
        securityContext:
          privileged: true
        terminationMessagePolicy: FallbackToLogsOnError
        volumeMounts:
        # for the iptables wrapper
        - mountPath: /host
          name: host-slash
          readOnly: true
          mountPropagation: HostToContainer
        # for the CNI server socket
        - mountPath: /run/ovn-kubernetes/
          name: host-run-ovn-kubernetes
        # accessing bind-mounted net namespaces
        - mountPath: /run/netns
          name: host-run-netns
          readOnly: true
          mountPropagation: HostToContainer
        # for installing the CNI plugin binary
        - mountPath: /cni-bin-dir
          name: host-cni-bin
        # for installing the CNI configuration file
        - mountPath: /etc/cni/net.d
          name: host-cni-netd
        # Where we store IP allocations
        - mountPath: /var/lib/cni/networks/ovn-k8s-cni-overlay
          name: host-var-lib-cni-networks-ovn-kubernetes
        - mountPath: /run/openvswitch
          name: run-openvswitch
        - mountPath: /run/ovn/
          name: run-ovn
        - mountPath: /etc/openvswitch
          name: etc-openvswitch
        - mountPath: /etc/ovn/
          name: etc-openvswitch
        - mountPath: /var/lib/openvswitch
          name: var-lib-openvswitch
        - mountPath: /run/ovnkube-config/
          name: ovnkube-config
        - mountPath: /env
          name: env-overrides
        - mountPath: /ovn-cert
          name: ovn-cert
        - mountPath: /ovn-ca
          name: ovn-ca
        resources:
          requests:
            cpu: 10m
            memory: 300Mi
        lifecycle:
          preStop:
            exec:
              command: ["rm","-f","/etc/cni/net.d/10-ovn-kubernetes.conf"]
        readinessProbe:
          exec:
            command: ["test", "-f", "/etc/cni/net.d/10-ovn-kubernetes.conf"]
          initialDelaySeconds: 5
          periodSeconds: 5
      nodeSelector:
        beta.kubernetes.io/os: "linux"
      volumes:
      # used for iptables wrapper scripts
      - name: host-slash
        hostPath:
          path: /
      - name: host-run-netns
        hostPath:
          path: /run/netns
      - name: var-lib-openvswitch
        hostPath:
          path: /var/lib/openvswitch/data
      - name: etc-openvswitch
        hostPath:
          path: /var/lib/openvswitch/etc
      - name: run-openvswitch
        hostPath:
          path: /var/run/openvswitch
      - name: run-ovn
        hostPath:
          path: /var/run/ovn
      # For CNI server
      - name: host-run-ovn-kubernetes
        hostPath:
          path: /run/ovn-kubernetes
      - name: host-cni-bin
        hostPath:
          path: "{{.CNIBinDir}}"
      - name: host-cni-netd
        hostPath:
          path: "{{.CNIConfDir}}"
      - name: host-var-lib-cni-networks-ovn-kubernetes
        hostPath:
          path: /var/lib/cni/networks/ovn-k8s-cni-overlay
      - name: ovnkube-config
        configMap:
          name: ovnkube-config
      - name: env-overrides
        configMap:
          name: env-overrides
          optional: true
      - name: ovn-ca
        configMap:
          name: ovn-ca
      - name: ovn-cert
        secret:
          secretName: ovn-cert
      tolerations:
      - operator: "Exists"
