# Istio Helm Chart 详解 - Pilot

## 前言

Pilot 也是 Istio 的核心组件，负责以下任务：

1. 监听注册中心，例如 Kubernetes 中的服务信息变化。
1. 监听 Istio 的路由相关 CRD 资源。
1. 两项内容结合，生成 Envoy 可以理解的配置信息发送给 Envoy。

## values.yaml 中的全局变量

~~~yaml
  enabled: true
  replicaCount: 1
  autoscaleMin: 1
  autoscaleMax: 5
  image: pilot
  sidecar: true
  traceSampling: 1.0
  # Resources for a small pilot install
  resources:
    requests:
      cpu: 500m
      memory: 2048Mi
  env:
    PILOT_PUSH_THROTTLE_COUNT: 100
    GODEBUG: gctrace=2
  cpu:
    targetAverageUtilization: 80
~~~

`image` 字段使用的镜像名为 `pilot`。

老生常谈的 HPA 部分和其他组件区别不大，实例数量的上限为 5。

值得注意的是 Pilot 的资源设置，缺省 CPU 500m，内存 2G，比其它组件来说是比较大的。这里还特意注明，这是针对小负载情况的。

`sidecar` 参数看来可以启用或者关闭 Pilot 组件的 Sidecar 注入。

`traceSampling`、`PILOT_PUSH_THROTTLE_COUNT` 和 `GODEBUG`，目测都是性能向的参数。可以在后面的 Chart 中进行求证。

## RBAC 相关

授权部分，Pilot 的 ServiceAccount 为：`istio-pilot-service-account`，从 `clusterrole.yaml` 可以看到较多门类的权限：

|名称|权限|说明
|---|---|---|
|`config.istio.io/*`|`*`|Mixer 使用此配置对象将数据送入 Adapter。|
|`rbac.istio.io/*`|只读|RBAC 相关配置。|
|`networking.istio.io/*`|`*`|流量控制相关配置。|
|`authentication.istio.io`|`*`|认证策略相关配置。|
|`apiextensions.k8s.io/customresourcedefinitions`|`*`|Kubernetes CRD。|
|`extensions/thirdpartyresources`|`*`|Kubernetes TPR，1.8 以后已经弃用。|
|`extensions/thirdpartyresources.extensions`|`*`|TPR 的扩展资源。|
|`extensions/ingresses`|`*`|Kubernetes Ingress 资源。|
|`configmaps`|读写||
|`endpoints`, `pods`, `services`|`get`, `list`, `watch`||
`namespaces`, `nodes`, `secrets`|`get`, `list`, `watch`||

## gateway.yaml

这个文件中包含了三个 Gateway 对象，用于[网格扩展功能](https://istio.io/zh/docs/setup/kubernetes/mesh-expansion/)。

- `istio-autogenerated-k8s-ingress`：在 80 端口提供 http 边缘监听服务。
- `meshexpansion-gateway`：用于 MeshExpanshion，如果启用了 `global.meshExpansion`，则创建 Gateway，在边缘提供 15011 的 Pilot 访问，以及 8060 的 citadel 组件访问。
- `meshexpansion-ilb-gateway`：如果启用了 `global.meshExpansionILB`，则创建该对象，在内部网关中公开 Pilot 和 Citadel 的端口。

> `istio-autogenerated-k8s-ingress` 对象其实是个 Bug，它使用了 `global.k8sIngressSelector` 作为 Gateway 控制器，也就是说只有在 `global.ingress.enabled` 为 True 的情况下才有可用的 Gateway 提供服务，这部分应该使用条件判断确定是否包含。

## meshexpansion.yaml

这个文件很明显也是用于网格扩展的。事实上这一文件和 `gateway.yaml` 是一体的，今后可能会做合并。

如果启用了 `global.meshExpansion` 或者 `global.meshExpansionILB`，会为 `gateway.yaml` 中生成的 Gateway 创建 `VirtualService`：

- `meshexpansion-pilot`：从边缘进入的 Pilot 请求，访问 `pilot.istio-system` 主机时，如果端口为 15011，则指向 `istio-pilot.istio-system.svc.cluster.local`。
- `ilb-meshexpansion-pilot`：从内部网管进入的请求，访问主机为 `meshexpansionilb.istio-system`，将 `15011`、`15010` 以及 `5353` 端口分别转向到 `istio-pilot` 明文端口、`istio-pilot` mTLS 端口以及 DNS 服务的  53 端口。

## deployment.yaml

主进程为 [Pilot Discovery](https://istio.io/docs/reference/commands/pilot-discovery/)。注解部分要求不进行自动注入。

除了 Chart 和 Release 之外，Pilot 的 Deployment 模板还引用了几个其它的全局变量。

- `image`：和其它核心组件类似，Pilot 中对 `image` 的值如果包含了 `/`，则会忽略 `hub` 的内容，可以方便的替换为内网镜像。
- 模板 `istio.configmap.checksum`：来自 `templates/_helpers.tpl`，Istio chart 中的 `/templates/configmap.yaml` 文件的校验和。
- `global.priorityClassName`：[Pod 优先级](https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#pod-priority)。
- `global.imagePullPolicy`：镜像拉取策略。
- `global.oneNamespace`：如果启用了这一参数，则会在主进程参数中加入 `-a {{ .Release.Namespace }}`。
- `sidecar`：如果为 `True`，会进行如下操作：
    - 在 Pod 中注入 `istio-proxy` 容器，这一容器会根据 `global.controlPlaneSecurityEnabled` 设置，决定 `controlPlaneAuthPolicy` 的值为 `MUTUAL_TLS` 还是 `NONE`。
    - 注入容器的资源设置来自于 `global.proxy.resources` 或 `global.defaultResources`。
- `sidecar` 如果为 `False`，会进行如下操作：
    - 设置启动参数 `--secureGrpcAddr` 为 `15011`。
    - 开放容器端口 `15011`。
- `env`：如果设置了 `key: value` 类型的环境变量，此处会发送给 Pilot 进程。
- `traceSampling`：跟踪取样率，会被设置到 `PILOT_TRACE_SAMPLING` 环境变量中。
- `nodeaffinity` 模板：来自 `templates/_affinity.tpl`，用于设置节点亲和性。

## service.yaml

这里并无特殊设置，开放如下几个端口：

- 15010：gRPC 的 xDS 端口
- 15011：mTLS 的 xDS 端口
- 8080：传统 http 端口
- 9093：监控端口

## 总结

对 Pilot 的资源设置较大，同时 1.0.0 之后屡次出现 Pilot 内存消耗巨大的 Issue，其中的跟踪采样、GC 调试以及 Sidecar 注入方面应该都还有挖掘的潜力。但是很可惜 Pilot 的环境变量并无文档，须待日后进一步完善。
