---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  labels:
    k8s-app: cilium
  name: cilium
  namespace: kube-system
spec:
  selector:
    matchLabels:
      k8s-app: cilium
  template:
    metadata:
      annotations:
{% if cilium_enable_prometheus %}
        prometheus.io/port: "9090"
        prometheus.io/scrape: "true"
{% endif %}
        scheduler.alpha.kubernetes.io/tolerations: '[{"key":"dedicated","operator":"Equal","value":"master","effect":"NoSchedule"}]'
      labels:
        k8s-app: cilium
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: k8s-app
                operator: In
                values:
                - cilium
            topologyKey: kubernetes.io/hostname
      containers:
      - args:
        - --config-dir=/tmp/cilium/config-map
{% if cilium_mtu != "" %}
        - --mtu={{ cilium_mtu }}
{% endif %}
{% if cilium_agent_custom_args is string %}
        - {{ cilium_agent_custom_args }}
{% else %}
{% for flag in cilium_agent_custom_args %}
        - {{ flag }}
{% endfor %}
{% endif %}
        command:
        - cilium-agent
        env:
        - name: K8S_NODE_NAME
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: spec.nodeName
        - name: CILIUM_K8S_NAMESPACE
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.namespace
        - name: CILIUM_CLUSTERMESH_CONFIG
          value: /var/lib/cilium/clustermesh/
{% if cilium_kube_proxy_replacement == 'strict' %}
        - name: KUBERNETES_SERVICE_HOST
          value: "{{ kube_apiserver_global_endpoint | urlsplit('hostname') }}"
        - name: KUBERNETES_SERVICE_PORT
          value: "{{ kube_apiserver_global_endpoint | urlsplit('port') }}"
{% endif %}
{% for env_var in cilium_agent_extra_env_vars %}
        - {{ env_var | to_nice_yaml(indent=2) | indent(10) }}
{% endfor %}
        image: "{{cilium_image_repo}}:{{cilium_image_tag}}"
        imagePullPolicy: {{ k8s_image_pull_policy }}
        resources:
          limits:
            cpu: {{ cilium_cpu_limit }}
            memory: {{ cilium_memory_limit }}
          requests:
            cpu: {{ cilium_cpu_requests }}
            memory: {{ cilium_memory_requests }}
        lifecycle:
          postStart:
            exec:
              command:
              - "/cni-install.sh"
{% if cilium_version | regex_replace('v') is version('1.10', '>=') %}
              - "--cni-exclusive={{ cilium_cni_exclusive }}"
{% endif %}
{% if cilium_version | regex_replace('v') is version('1.12', '>=') %}
              - "--log-file={{ cilium_cni_log_file }}"
{% endif %}
          preStop:
            exec:
              command:
              - /cni-uninstall.sh
        startupProbe:
          httpGet:
            host: '127.0.0.1'
            path: /healthz
            port: {{ cilium_agent_health_port }}
            scheme: HTTP
            httpHeaders:
            - name: "brief"
              value: "true"
          failureThreshold: 105
          periodSeconds: 2
          successThreshold: 1
        livenessProbe:
          httpGet:
            host: '127.0.0.1'
            path: /healthz
            port: {{ cilium_agent_health_port }}
            scheme: HTTP
            httpHeaders:
            - name: "brief"
              value: "true"
          failureThreshold: 10
          periodSeconds: 30
          successThreshold: 1
          timeoutSeconds: 5
        readinessProbe:
          httpGet:
            host: 127.0.0.1
            path: /healthz
            port: {{ cilium_agent_health_port }}
            scheme: HTTP
            httpHeaders:
            - name: "brief"
              value: "true"
          initialDelaySeconds: 5
          periodSeconds: 30
          successThreshold: 1
          failureThreshold: 3
          timeoutSeconds: 5
        name: cilium-agent
{% if cilium_enable_prometheus or cilium_enable_hubble_metrics %}
        ports:
{% endif %}
{% if cilium_enable_prometheus %}
        - containerPort: 9090
          hostPort: 9090
          name: prometheus
          protocol: TCP
{% endif %}
{% if cilium_enable_hubble_metrics %}
        - containerPort: 9091
          hostPort: 9091
          name: hubble-metrics
          protocol: TCP
{% endif %}
        securityContext:
          privileged: true
        volumeMounts:
        - mountPath: /sys/fs/bpf
          name: bpf-maps
          mountPropagation: Bidirectional
        - mountPath: /var/run/cilium
          name: cilium-run
        - mountPath: /host/opt/cni/bin
          name: cni-path
        - mountPath: /host/etc/cni/net.d
          name: etc-cni-netd
# pkg/workloads was depreca, removed in 1.7
# https://github.com/cilium/cilium/pull/9447
{% if cilium_version | regex_replace('v') is version('1.7', '<') %}
{% if container_manager == 'docker' %}
        - mountPath: /var/run/docker.sock
          name: docker-socket
          readOnly: true
{% else %}
        - name: "{{ container_manager }}-socket"
          mountPath: {{ cri_socket }}
          readOnly: true
{% endif %}
{% endif %}
{% if cilium_identity_allocation_mode == "kvstore" %}
        - mountPath: /var/lib/etcd-config
          name: etcd-config-path
          readOnly: true
        - mountPath: "{{cilium_cert_dir}}"
          name: etcd-secrets
          readOnly: true
{% endif %}
        - mountPath: /var/lib/cilium/clustermesh
          name: clustermesh-secrets
          readOnly: true
        - mountPath: /tmp/cilium/config-map
          name: cilium-config-path
          readOnly: true
{% if cilium_ip_masq_agent_enable %}
        - name: ip-masq-agent
          mountPath: /etc/config
          readOnly: true
{% endif %}
          # Needed to be able to load kernel modules
        - mountPath: /lib/modules
          name: lib-modules
          readOnly: true
        - mountPath: /run/xtables.lock
          name: xtables-lock
{% if cilium_encryption_enabled and cilium_encryption_type == "ipsec" %}
        - mountPath: /etc/ipsec
          name: cilium-ipsec-secrets
          readOnly: true
{% endif %}
{% if cilium_hubble_install %}
        - mountPath: /var/lib/cilium/tls/hubble
          name: hubble-tls
          readOnly: true
{% endif %}
{% for volume_mount in cilium_agent_extra_volume_mounts %}
        - {{ volume_mount | to_nice_yaml(indent=2) | indent(10) }}
{% endfor %}
# In managed etcd mode, Cilium must be able to resolve the DNS name of the etcd service
{% if cilium_identity_allocation_mode == "kvstore" %}
      dnsPolicy: ClusterFirstWithHostNet
{% endif %}
      hostNetwork: true
      initContainers:
{% if cilium_version | regex_replace('v') is version('1.11', '>=') and cilium_cgroup_auto_mount %}
      - name: mount-cgroup
        image: "{{cilium_image_repo}}:{{cilium_image_tag}}"
        imagePullPolicy: {{ k8s_image_pull_policy }}
        env:
        - name: CGROUP_ROOT
          value: {{ cilium_cgroup_host_root }}
        - name: BIN_PATH
          value: /opt/cni/bin
        command:
        - sh
        - -ec
        # The statically linked Go program binary is invoked to avoid any
        # dependency on utilities like sh and mount that can be missing on certain
        # distros installed on the underlying host. Copy the binary to the
        # same directory where we install cilium cni plugin so that exec permissions
        # are available.
        - |
          cp /usr/bin/cilium-mount /hostbin/cilium-mount;
          nsenter --cgroup=/hostproc/1/ns/cgroup --mount=/hostproc/1/ns/mnt "${BIN_PATH}/cilium-mount" $CGROUP_ROOT;
          rm /hostbin/cilium-mount
        volumeMounts:
        - name: hostproc
          mountPath: /hostproc
        - name: cni-path
          mountPath: /hostbin
        securityContext:
          privileged: true
{% endif %}
      - command:
        - /init-container.sh
        env:
        - name: CILIUM_ALL_STATE
          valueFrom:
            configMapKeyRef:
              key: clean-cilium-state
              name: cilium-config
              optional: true
        # CLEAN_CILIUM_BPF_STATE is deprecated in 1.6.
        # https://github.com/cilium/cilium/pull/7478
        - name: "{{ cilium_version | regex_replace('v') is version('1.6', '<')| ternary('CLEAN_CILIUM_BPF_STATE','CILIUM_BPF_STATE') }}"
          valueFrom:
            configMapKeyRef:
              key: clean-cilium-bpf-state
              name: cilium-config
              optional: true
# Removed in 1.11 and up.
# https://github.com/cilium/cilium/commit/f7a3f59fd74983c600bfce9cac364b76d20849d9
{% if cilium_version | regex_replace('v') is version('1.11', '<') %}
        - name: CILIUM_WAIT_BPF_MOUNT
          valueFrom:
            configMapKeyRef:
              key: wait-bpf-mount
              name: cilium-config
              optional: true
{% endif %}
{% if cilium_kube_proxy_replacement == 'strict' %}
        - name: KUBERNETES_SERVICE_HOST
          value: "{{ kube_apiserver_global_endpoint | urlsplit('hostname') }}"
        - name: KUBERNETES_SERVICE_PORT
          value: "{{ kube_apiserver_global_endpoint | urlsplit('port') }}"
{% endif %}
{% if cilium_version | regex_replace('v') is version('1.9', '<') %}
        image: "{{cilium_init_image_repo}}:{{cilium_init_image_tag}}"
{% else %}
        image: "{{cilium_image_repo}}:{{cilium_image_tag}}"
{% endif %}
        imagePullPolicy: {{ k8s_image_pull_policy }}
        name: clean-cilium-state
        securityContext:
          privileged: true
        volumeMounts:
        - mountPath: /sys/fs/bpf
          name: bpf-maps
{% if cilium_version | regex_replace('v') is version('1.11', '>=') %}
          # Required to mount cgroup filesystem from the host to cilium agent pod
        - name: cilium-cgroup
          mountPath: {{ cilium_cgroup_host_root }}
          mountPropagation: HostToContainer
{% endif %}
        - mountPath: /var/run/cilium
          name: cilium-run
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
      priorityClassName: system-node-critical
      restartPolicy: Always
      serviceAccount: cilium
      serviceAccountName: cilium
      terminationGracePeriodSeconds: 1
      hostNetwork: true
# In managed etcd mode, Cilium must be able to resolve the DNS name of the etcd service
{% if cilium_identity_allocation_mode == "kvstore" %}
      dnsPolicy: ClusterFirstWithHostNet
{% endif %}
      tolerations:
      - operator: Exists
      volumes:
        # To keep state between restarts / upgrades
      - hostPath:
          path: /var/run/cilium
          type: DirectoryOrCreate
        name: cilium-run
        # To keep state between restarts / upgrades for bpf maps
      - hostPath:
          path: /sys/fs/bpf
          type: DirectoryOrCreate
        name: bpf-maps
# pkg/workloads was deprecated in 1.6, removed in 1.7
# https://github.com/cilium/cilium/pull/9447
{% if cilium_version | regex_replace('v') is version('1.7', '<') %}
{% if container_manager == 'docker' %}
        # To read docker events from the node
      - hostPath:
          path: /var/run/docker.sock
          type: Socket
        name: docker-socket
{% else %}
        # To read crio events from the node
      - hostPath:
          path: {{ cri_socket }}
          type: Socket
        name: {{ container_manager }}-socket
{% endif %}
{% endif %}
{% if cilium_version | regex_replace('v') is version('1.11', '>=') %}
      # To mount cgroup2 filesystem on the host
      - name: hostproc
        hostPath:
          path: /proc
          type: Directory
      # To keep state between restarts / upgrades for cgroup2 filesystem
      - name: cilium-cgroup
        hostPath:
          path: {{ cilium_cgroup_host_root }}
          type: DirectoryOrCreate
{% endif %}
        # To install cilium cni plugin in the host
      - hostPath:
          path: /opt/cni/bin
          type: DirectoryOrCreate
        name: cni-path
        # To install cilium cni configuration in the host
      - hostPath:
          path: /etc/cni/net.d
          type: DirectoryOrCreate
        name: etc-cni-netd
        # To be able to load kernel modules
      - hostPath:
          path: /lib/modules
        name: lib-modules
        # To access iptables concurrently with other processes (e.g. kube-proxy)
      - hostPath:
          path: /run/xtables.lock
          type: FileOrCreate
        name: xtables-lock
{% if cilium_identity_allocation_mode == "kvstore" %}
        # To read the etcd config stored in config maps
      - configMap:
          # note: the leading zero means this number is in octal representation: do not remove it
          defaultMode: 0400
          items:
          - key: etcd-config
            path: etcd.config
          name: cilium-config
        name: etcd-config-path
        # To read the k8s etcd secrets in case the user might want to use TLS
      - name: etcd-secrets
        hostPath:
          path: "{{cilium_cert_dir}}"
{% endif %}
        # To read the clustermesh configuration
      - name: clustermesh-secrets
        secret:
          # note: the leading zero means this number is in octal representation: do not remove it
          defaultMode: 0400
          optional: true
          secretName: cilium-clustermesh
        # To read the configuration from the config map
      - configMap:
          name: cilium-config
        name: cilium-config-path
{% if cilium_ip_masq_agent_enable %}
      - configMap:
          name: ip-masq-agent
          items:
          - key: config
            path: ip-masq-agent
        name: ip-masq-agent
{% endif %}
{% if cilium_encryption_enabled and cilium_encryption_type == "ipsec" %}
      - name: cilium-ipsec-secrets
        secret:
          secretName: cilium-ipsec-keys
{% endif %}
{% if cilium_hubble_install %}
      - name: hubble-tls
        projected:
          # note: the leading zero means this number is in octal representation: do not remove it
          defaultMode: 0400
          sources:
          - secret:
              name: hubble-server-certs
              items:
                - key: tls.crt
                  path: server.crt
                - key: tls.key
                  path: server.key
              optional: true
          - configMap:
              name: hubble-ca-cert
              items:
                - key: ca.crt
                  path: client-ca.crt
              optional: true
{% endif %}
  updateStrategy:
    rollingUpdate:
      # Specifies the maximum number of Pods that can be unavailable during the update process.
      maxUnavailable: 2
    type: RollingUpdate
