istio.io/istio@v0.0.0-20240520182934-d79c90f27776/architecture/environments/operator.md (about)

     1  # Istio operator code overview
     2  
     3  ## Introduction
     4  
     5  This document covers primarily the code, with some background on how the design maps to it.
     6  See the
     7  [design doc](https://docs.google.com/document/d/11j9ZtYWNWnxQYnZy8ayZav1FMwTH6F6z6fkDYZ7V298/edit#heading=h.qex63c29z2to)
     8  for a more complete design description. The operator code is divided roughly into five areas:
     9  
    10  1. [IstioOperatorSpec API](#istiooperatorspec-api) and related infrastructure, which is expressed as a
    11  [proto](https://github.com/istio/api/blob/master/operator/v1alpha1/operator.proto) and
    12  compiled to [Go
    13  structs](https://github.com/istio/api/blob/master/operator/v1alpha1/operator.pb.go).
    14  `IstioOperatorSpec` has pass-through fields to the Helm values.yaml API, but these are additionally validated through
    15  a [schema](../operator/pkg/apis/istio/v1alpha1/values_types.proto).
    16  1. [Controller](#k8s-controller) code. The code comprises the K8s listener, webhook and logic for reconciling the cluster
    17  to an `IstioOperatorSpec` CR.
    18  1. [Manifest creation](#manifest-creation) code. User settings are overlaid on top of the
    19  selected profile values and passed to a renderer in the Helm library to create manifests. Further customization on the
    20  created manifests can be done through overlays.
    21  1. [CLI](#cli) code. CLI code shares the `IstioOperatorSpec` API with
    22  the controller, but allows manifests to be generated and optionally applied from the command line without the need to
    23  run a privileged controller in the cluster.
    24  1. [Migration tools](#migration-tools). The migration tools are intended to
    25  automate configuration migration from Helm to the operator.
    26  
    27  The operator code uses the new Helm charts in the [istio/manifests/charts](../manifests/charts/istio-operator). It is not
    28  compatible with the older charts in [istio/istio](https://github.com/istio/istio/tree/1.4.7/install/kubernetes/helm).
    29  See `istio/manifests/charts` for details about the new charts and why they were created. Briefly, the new charts
    30  are intended to support production ready deployments of Istio that follow best practices like canarying for upgrade.
    31  
    32  ## Terminology
    33  
    34  Throughout the document, the following terms are used:
    35  
    36  - `IstioOperatorSpec`: The API directly defined in the
    37  [IstioOperatorSpec proto](https://github.com/istio/api/blob/master/operator/v1alpha1/operator.proto),
    38  including feature and component groupings, namespaces and enablement, and per-component K8s settings.
    39  - Helm values.yaml API, implicitly defined through the various values.yaml files in the
    40  [istio/manifests/charts](../manifests/charts/istio-operator) and schematized in the operator through
    41  [values_types.proto](../operator/pkg/apis/istio/v1alpha1/values_types.proto).
    42  
    43  ## IstioOperatorSpec API
    44  
    45  The `IstioOperatorSpec` API is intended to replace the installation and K8s parts of Helm values.yaml.
    46  
    47  ### Features and components
    48  
    49  The operator has a very similar structure to istio/installer: components are grouped into features.
    50  `IstioOperatorSpec` defines functional settings at the feature level. Functional settings are those that performs some
    51  function in the Istio control plane without necessarily being tied to any one component that runs in a Deployment.
    52  Component settings are those that necessarily refer to a particular Deployment or Service. For example, the number
    53  of Pilot replicas is a component setting, because it refers to a component which is a Deployment in the
    54  cluster. Most K8s platform settings are necessarily component settings.
    55  The available features and the components that comprise each feature are as follows:
    56  
    57  | Feature | Components |
    58  |---------|------------|
    59  CRDs, and other cluster wide configs | Base
    60  Traffic Management | Pilot
    61  Security | Pilot
    62  Configuration management | Pilot
    63  AutoInjection | Pilot
    64  Gateways | Ingress gateway
    65  Gateways | Egress gateway
    66  Policy | Policy (deprecated)
    67  Telemetry | Telemetry (deprecated)
    68  
    69  Features and components are defined in the
    70  [name](https://github.com/istio/operator/blob/e9097258cb4fbe59648e7da663cdad6f16927b8f/pkg/name/name.go#L44) package.
    71  
    72  Note: Besides the features and the components listed in the table above, some addon features and components are as follows:
    73  
    74  | Feature | Components |
    75  |---------|------------|
    76  Telemetry | Prometheus
    77  Telemetry | Prometheus Operator
    78  Telemetry | Grafana
    79  Telemetry | Kiali
    80  Telemetry | Tracing
    81  ThirdParty | CNI
    82  
    83  ### Namespaces
    84  
    85  The `IstioOperatorSpec` API and underlying new Helm charts offer a lot of flexibility in which namespaces features and
    86  components are installed into. Namespace definitions can be defined and specialized at the global, feature and component
    87  level, with each lower level overriding the setting of the higher parent level. For example, if the global default
    88  namespace is defined as:
    89  
    90  ```yaml
    91  defaultNamespace: istio-system
    92  ```
    93  
    94  and namespaces are specialized for the gateway feature and its components:
    95  
    96  ```yaml
    97  apiVersion: install.istio.io/v1alpha1
    98  kind: IstioOperator
    99  metadata:
   100    namespace: istio-operator
   101  spec:
   102    components:
   103      ingressGateways:
   104      - name: istio-ingressgateway
   105        enabled: true
   106        namespace: istio-gateways
   107  ```
   108  
   109  the resulting namespaces will be:
   110  
   111  | Component | Namespace |
   112  | --------- | :-------- |
   113  ingressGateways | istio-gateways
   114  
   115  These rules are expressed in code in the
   116  [name](https://github.com/istio/operator/blob/e9097258cb4fbe59648e7da663cdad6f16927b8f/pkg/name/name.go#L246) package.
   117  
   118  ### Enablement
   119  
   120  Features and components can be individually or collectively enabled or disabled. If a feature is disabled, all of its
   121  components are disabled, regardless of their component-level enablement. If a feature is enabled, all of its components
   122  are enabled, unless they are individually disabled. For example:
   123  
   124  ```yaml
   125      telemetry:
   126        enabled: true
   127        v2:
   128          enabled: false
   129  ```
   130  
   131  These rules are expressed in code in the
   132  [name](https://github.com/istio/operator/blob/e9097258cb4fbe59648e7da663cdad6f16927b8f/pkg/name/name.go#L131) package.
   133  
   134  ### K8s settings
   135  
   136  Rather than defining selective mappings from parameters to fields in K8s resources, the `IstioOperatorSpec` API
   137  contains a consistent K8s block for each Istio component. The available K8s settings are defined in
   138  [KubernetesResourcesSpec](https://github.com/istio/api/blob/7791470ecc4c5e123589ff2b781f47b1bcae6ddd/mesh/v1alpha1/component.proto#L103):
   139  
   140  | Field name | K8s API reference |
   141  | :--------- | :---------------- |
   142  resources | [resources](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/#resource-requests-and-limits-of-pod-and-container)
   143  readinessProbe | [readiness probes](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/)
   144  replicaCount | [replica count](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/)
   145  hpaSpec | [HorizontalPodAutoscaler](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/)
   146  podDisruptionBudget | [PodDisruptionBudget](https://kubernetes.io/docs/concepts/workloads/pods/disruptions/#how-disruption-budgets-work)
   147  podAnnotations | [pod annotations](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/)
   148  env | [container environment variables](https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/)
   149  imagePullPolicy| [ImagePullPolicy](https://kubernetes.io/docs/concepts/containers/images/)
   150  priorityClassName | [priority class name](https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#priorityclass)
   151  nodeSelector| [node selector](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector)
   152  affinity | [affinity and anti-affinity](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity)
   153  serviceAnnotations | [service annotations](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/)
   154  securityContext | [security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod)
   155  
   156  These K8s setting are available for each component under the `k8s` field, for example:
   157  
   158  ```yaml
   159  trafficManagement:
   160    components:
   161      pilot:
   162        k8s:
   163          hpaSpec:
   164            # HPA spec, as defined in K8s API
   165  ```
   166  
   167  ### Translations
   168  
   169  API translations are version specific and are expressed as a
   170  [table of Translators](https://github.com/istio/operator/blob/e9097258cb4fbe59648e7da663cdad6f16927b8f/pkg/translate/translate.go#L110)
   171  indexed by minor [version](../operator/pkg/version/version.go). This is because
   172  mapping rules are only allowed to change between minor (not patch) versions.
   173  
   174  The `IstioOperatorSpec` API fields are translated to the output manifest in two ways:
   175  
   176  1. The `IstioOperatorSpec` API fields are mapped to the Helm values.yaml schema using the
   177  [APIMapping](https://github.com/istio/operator/blob/e9097258cb4fbe59648e7da663cdad6f16927b8f/pkg/translate/translate.go#L112)
   178  field of the [Translator](https://github.com/istio/operator/blob/e9097258cb4fbe59648e7da663cdad6f16927b8f/pkg/translate/translate.go#L52)
   179  struct.
   180  1. The K8s settings are applied to resources in the output manifest using the
   181  [KubernetesMapping](https://github.com/istio/operator/blob/e9097258cb4fbe59648e7da663cdad6f16927b8f/pkg/translate/translate.go#L132)
   182  field in the [Translator](https://github.com/istio/operator/blob/e9097258cb4fbe59648e7da663cdad6f16927b8f/pkg/translate/translate.go#L52)
   183  struct.
   184  
   185  Other per-component mappings to Helm values.yaml are expressed in the
   186  [ComponentMaps](https://github.com/istio/operator/blob/e9097258cb4fbe59648e7da663cdad6f16927b8f/pkg/translate/translate.go#L83)
   187  struct.
   188  
   189  ### Validations
   190  
   191  Both the `IstioOperatorSpec` and Helm APIs are validated. The `IstioOperatorSpec` API is validated through a
   192  table of validation rules in
   193  [pkg/validate/validate.go](pkg/validate/validate.go). These rules
   194  refer to the Go struct path schema and hence have names with a capitalized first letter.
   195  The Helm values.yaml API is validated in
   196  [validate_values.go](pkg/validate/validate_values.go)
   197  and refer to the values.yaml data paths. Hence, these rules have names with a lower case first letter.
   198  Apart from validating the correctness of individual fields, the operator ensure that relationships between values in
   199  different parts of the configuration tree are correct. For example, it's an error to enable a component while its
   200  parent feature is disabled.
   201  
   202  ## K8s controller
   203  
   204  TODO(rcernich).
   205  
   206  ## Manifest creation
   207  
   208  Manifest rendering is a multi-step process, shown in the figure below. ![rendering
   209  process](images/operator_render_flow.svg) The example in the figure shows the rendering being triggered by a CLI `mesh`
   210  command with a `IstioOperatorSpec` CR passed to it from a file; however, the same rendering steps would occur when an
   211  in-cluster CR is updated and the controller acts upon it to generate a new manifest to apply to the cluster. Note that
   212  both the charts and configuration profiles can come from three different sources: compiled-in, local filesystem.
   213  The source may be selected independently for the charts and profiles. The different steps in creating the manifest are
   214  as follows:
   215  
   216  1. The user CR (my_custom.yaml) selects a configuration profile. If no profile is selected, the
   217  [default profile](../manifests/profiles/default.yaml) is used. Each profile is defined as a
   218  set of defaults for `IstioOperatorSpec`, for both the restructured fields (K8s settings, namespaces and enablement)
   219  and the Helm values (Istio behavior configuration).
   220  
   221  1. The fields defined in the user CR override any values defined in the configuration profile CR.  The
   222  resulting CR is converted to Helm values.yaml format and passed to the next step.
   223  1. Part of the configuration profile contains settings in the Helm values.yaml schema format. User overrides of
   224  these fields are applied and merged with the output of this step. The result of this step is a merge of configuration
   225  profile defaults and user overlays, all expressed in Helm values.yaml format. This final values.yaml configuration
   226  is passed to the Helm rendering library and used to render the charts. The rendered manifests are passed to the next
   227  step.
   228  1. Overlays in the user CR are applied to the rendered manifests. No values are ever defined in configuration profile
   229  CRs at this layer, so no merge is performed in this step.
   230  
   231  ## CLI
   232  
   233  The CLI `mesh` command is implemented in the [cmd/mesh](../operator/cmd/mesh/)
   234  subdirectory as a Cobra command with the following subcommands:
   235  
   236  - [manifest](../operator/cmd/mesh/manifest.go): the manifest subcommand is used to generate, install, diff or migrate Istio manifests, it has the following subcommands:
   237      - [install](../operator/cmd/mesh/install.go): the install subcommand is used to generate an Istio install manifest and apply it to a cluster.
   238      - [diff](../operator/cmd/mesh/manifest-diff.go): the diff subcommand is used to compare manifest from two files or directories.
   239      - [generate](../operator/cmd/mesh/manifest-generate.go): the generate subcommand is used to generate an Istio install manifest.
   240  - [profile](../operator/cmd/mesh/profile.go): dumps the default values for a selected profile, it has the following subcommands:
   241      - [diff](../operator/cmd/mesh/profile-diff.go): the diff subcommand is used to display the difference between two Istio configuration profiles.
   242      - [dump](../operator/cmd/mesh/profile-dump.go): the dump subcommand is used to dump the values in an Istio configuration profile.
   243      - [list](../operator/cmd/mesh/profile-list.go): the list subcommand is used to list available Istio configuration profiles.
   244  - [upgrade](../operator/cmd/mesh/upgrade.go): performs an in-place upgrade of the Istio control plane with eligibility checks.
   245  
   246  ## Migration tools
   247  
   248  TODO(richardwxn).