# This manifest installs the Istio install-cni container, as well # as the Istio CNI plugin and config on # each master and worker node in a Kubernetes cluster. {{- $defaultBinDir := (.Capabilities.KubeVersion.GitVersion | contains "-gke") | ternary "/home/kubernetes/bin" "/opt/cni/bin" }} kind: DaemonSet apiVersion: apps/v1 metadata: name: {{ template "name" . }}-node namespace: {{ .Release.Namespace }} labels: k8s-app: {{ template "name" . }}-node release: {{ .Release.Name }} istio.io/rev: {{ .Values.revision | default "default" }} install.operator.istio.io/owning-resource: {{ .Values.ownerName | default "unknown" }} operator.istio.io/component: "Cni" spec: selector: matchLabels: k8s-app: {{ template "name" . }}-node updateStrategy: type: RollingUpdate rollingUpdate: maxUnavailable: {{ .Values.cni.rollingMaxUnavailable }} template: metadata: labels: k8s-app: {{ template "name" . }}-node sidecar.istio.io/inject: "false" istio.io/dataplane-mode: none annotations: sidecar.istio.io/inject: "false" # Add Prometheus Scrape annotations prometheus.io/scrape: 'true' prometheus.io/port: "15014" prometheus.io/path: '/metrics' # Custom annotations {{- if .Values.cni.podAnnotations }} {{ toYaml .Values.cni.podAnnotations | indent 8 }} {{- end }} spec: {{if .Values.cni.ambient.enabled }}hostNetwork: true{{ end }} nodeSelector: kubernetes.io/os: linux # Can be configured to allow for excluding istio-cni from being scheduled on specified nodes {{- with .Values.cni.affinity }} affinity: {{- toYaml . | nindent 8 }} {{- end }} tolerations: # Make sure istio-cni-node gets scheduled on all nodes. - effect: NoSchedule operator: Exists # Mark the pod as a critical add-on for rescheduling. - key: CriticalAddonsOnly operator: Exists - effect: NoExecute operator: Exists priorityClassName: system-node-critical serviceAccountName: {{ template "name" . }} # Minimize downtime during a rolling upgrade or deletion; tell Kubernetes to do a "force # deletion": https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods. terminationGracePeriodSeconds: 5 containers: # This container installs the Istio CNI binaries # and CNI network config file on each node. - name: install-cni {{- if contains "/" .Values.cni.image }} image: "{{ .Values.cni.image }}" {{- else }} image: "{{ .Values.cni.hub | default .Values.global.hub }}/{{ .Values.cni.image | default "install-cni" }}:{{ template "istio-tag" . }}" {{- end }} {{- if or .Values.cni.pullPolicy .Values.global.imagePullPolicy }} imagePullPolicy: {{ .Values.cni.pullPolicy | default .Values.global.imagePullPolicy }} {{- end }} readinessProbe: httpGet: path: /readyz port: 8000 securityContext: privileged: true # always requires privilege to be useful (install node plugin, etc) runAsGroup: 0 runAsUser: 0 runAsNonRoot: false # Both ambient and sidecar repair mode require elevated node privileges to function. # But we don't need _everything_ in `privileged`, so drop+readd capabilities based on feature. # privileged is redundant with CAP_SYS_ADMIN # since it's redundant, hardcode it to `true`, then manually drop ALL + readd granular # capabilities we actually require capabilities: drop: - ALL add: # CAP_NET_ADMIN is required to allow ipset and route table access - NET_ADMIN # CAP_NET_RAW is required to allow iptables mutation of the `nat` table - NET_RAW # CAP_SYS_ADMIN is required for both ambient and repair, in order to open # network namespaces in `/proc` to obtain descriptors for entering pod netnamespaces. # There does not appear to be a more granular capability for this. - SYS_ADMIN {{- if .Values.cni.seccompProfile }} seccompProfile: {{ toYaml .Values.cni.seccompProfile | trim | indent 14 }} {{- end }} command: ["install-cni"] args: {{- if or .Values.cni.logging.level .Values.global.logging.level }} - --log_output_level={{ coalesce .Values.cni.logging.level .Values.global.logging.level }} {{- end}} {{- if .Values.global.logAsJson }} - --log_as_json {{- end}} envFrom: - configMapRef: name: {{ template "name" . }}-config env: - name: REPAIR_NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName - name: REPAIR_RUN_AS_DAEMON value: "true" - name: REPAIR_SIDECAR_ANNOTATION value: "sidecar.istio.io/status" - name: NODE_NAME valueFrom: fieldRef: apiVersion: v1 fieldPath: spec.nodeName - name: GOMEMLIMIT valueFrom: resourceFieldRef: resource: limits.memory - name: GOMAXPROCS valueFrom: resourceFieldRef: resource: limits.cpu - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace volumeMounts: - mountPath: /host/opt/cni/bin name: cni-bin-dir {{- if or .Values.cni.repair.repairPods .Values.cni.ambient.enabled }} - mountPath: /host/proc name: cni-host-procfs readOnly: true {{- end }} - mountPath: /host/etc/cni/net.d name: cni-net-dir - mountPath: /var/run/istio-cni name: cni-socket-dir {{- if .Values.cni.ambient.enabled }} - mountPath: /host/var/run/netns mountPropagation: HostToContainer name: cni-netns-dir - mountPath: /var/run/ztunnel name: cni-ztunnel-sock-dir {{ end }} resources: {{- if .Values.cni.resources }} {{ toYaml .Values.cni.resources | trim | indent 12 }} {{- else }} {{ toYaml .Values.global.defaultResources | trim | indent 12 }} {{- end }} volumes: # Used to install CNI. - name: cni-bin-dir hostPath: path: {{ .Values.cni.cniBinDir | default $defaultBinDir }} {{- if or .Values.cni.repair.repairPods .Values.cni.ambient.enabled }} - name: cni-host-procfs hostPath: path: /proc type: Directory {{- end }} {{- if .Values.cni.ambient.enabled }} - name: cni-ztunnel-sock-dir hostPath: path: /var/run/ztunnel type: DirectoryOrCreate {{- end }} - name: cni-net-dir hostPath: path: {{ default "/etc/cni/net.d" .Values.cni.cniConfDir }} # Used for UDS sockets for logging, ambient eventing - name: cni-socket-dir hostPath: path: /var/run/istio-cni - name: cni-netns-dir hostPath: path: {{ .Values.cni.cniNetnsDir | default "/var/run/netns" }} type: DirectoryOrCreate # DirectoryOrCreate instead of Directory for the following reason - CNI may not bind mount this until a non-hostnetwork pod is scheduled on the node, # and we don't want to block CNI agent pod creation on waiting for the first non-hostnetwork pod. # Once the CNI does mount this, it will get populated and we're good.