前言
为了不便用户装置istio和操作相应的manifest,社区将本来的纯helm装置模式演变成现在的cli和operator模式(https://docs.google.com/docum...)。同时为了保障后向兼容和良好的代码复用,cli复用operator提供的命令行api,operator命令行基于helm的chart渲染进行实现。根本的模式构造如下图所示:
因而,本文从istioctl提供的install和manifest指令登程,依照istioctl->operator->helm的方向进行剖析,重点形容operator中cmd的实现流程。
Install
istioctl
命令行参数与实例
此节可参考https://istio.io/latest/docs/...官网文档。
代码入口
istioctl实质上是利用cobra编写的命令行程序,在/istio/istioctl/cmd/root.go中将InstallCmd退出RootCmd中,而InstallCmd由operator实现。
installCmd := mesh.InstallCmd(loggingOptions)hideInheritedFlags(installCmd, FlagNamespace, FlagIstioNamespace, FlagCharts)rootCmd.AddCommand(installCmd)
operator
代码流程与重要函数
整体构造如下图所示。
接下来,以istioctl install --set installPackagePath=/istio/manifests --set profile=empty -f test0.yaml -f test1.yaml为例,剖析各个函数。其中test0.yaml和test1.yaml的内容如下图所示。
# test0.yamlapiVersion: install.istio.io/v1alpha1kind: IstioOperatorspec: profile: minimal hub: docker.io/istio tag: 1.1.4 components: pilot: enabled: true
# test1.yamlapiVersion: install.istio.io/v1alpha1kind: IstioOperatorspec: hub: docker.io/istio tag: 1.1.5 components: pilot: enabled: true
ParseYAMLFiles
ParseYAMLFiles从左到右读取并笼罩-f标记所传入的IstioOperator yaml,并提取出其中的profile字段。因而提取出的profile为minimal,test0.yaml和test1.yaml的初步处理结果temp0.yaml如下所示。
# temp0.yamlapiVersion: install.istio.io/v1alpha1kind: IstioOperatorspec: profile: minimal hub: docker.io/istio tag: 1.1.5 components: pilot: enabled: true
ReadYaml(And)Profile
ReadYamlProfile依据--set profile=empty对ParseYAMLFiles返回的profile后果进行笼罩,因而最终的profile为empty。
GetProfileYAML
GetProfileYAML从--set installPackagePath=/istio/manifests指定的目录读取empty yaml,因为istio所提供的所有内置profile都基于default profile,因而利用empty yaml去笼罩default profile,最终失去temp1.yaml。
#empty yaml# The empty profile has everything disabled# This is useful as a base for custom user configurationapiVersion: install.istio.io/v1alpha1kind: IstioOperatorspec: components: base: enabled: false pilot: enabled: false ingressGateways: - name: istio-ingressgateway enabled: false
#default yamlapiVersion: install.istio.io/v1alpha1kind: IstioOperatormetadata: namespace: istio-systemspec: hub: gcr.io/istio-testing tag: latest # You may override parts of meshconfig by uncommenting the following lines. meshConfig: defaultConfig: proxyMetadata: {} enablePrometheusMerge: true # Opt-out of global http2 upgrades. # Destination rule is used to opt-in. # h2_upgrade_policy: DO_NOT_UPGRADE # Traffic management feature components: base: enabled: true pilot: enabled: true # Istio Gateway feature ingressGateways: - name: istio-ingressgateway enabled: true egressGateways: - name: istio-egressgateway enabled: false # Istio CNI feature cni: enabled: false # Remote and config cluster configuration for an external istiod istiodRemote: enabled: false # Global values passed through to helm global.yaml. # Please keep this in sync with manifests/charts/global.yaml values: defaultRevision: "" global: istioNamespace: istio-system istiod: enableAnalysis: false logging: level: "default:info" logAsJson: false pilotCertProvider: istiod jwtPolicy: third-party-jwt proxy: image: proxyv2 clusterDomain: "cluster.local" resources: requests: cpu: 100m memory: 128Mi limits: cpu: 2000m memory: 1024Mi logLevel: warning componentLogLevel: "misc:error" privileged: false enableCoreDump: false statusPort: 15020 readinessInitialDelaySeconds: 1 readinessPeriodSeconds: 2 readinessFailureThreshold: 30 includeIPRanges: "*" excludeIPRanges: "" excludeOutboundPorts: "" excludeInboundPorts: "" autoInject: enabled tracer: "zipkin" proxy_init: image: proxyv2 resources: limits: cpu: 2000m memory: 1024Mi requests: cpu: 10m memory: 10Mi # Specify image pull policy if default behavior isn't desired. # Default behavior: latest images will be Always else IfNotPresent. imagePullPolicy: "" operatorManageWebhooks: false tracer: lightstep: {} zipkin: {} datadog: {} stackdriver: {} imagePullSecrets: [] oneNamespace: false defaultNodeSelector: {} configValidation: true multiCluster: enabled: false clusterName: "" omitSidecarInjectorConfigMap: false network: "" defaultResources: requests: cpu: 10m defaultPodDisruptionBudget: enabled: true priorityClassName: "" useMCP: false sds: token: aud: istio-ca sts: servicePort: 0 meshNetworks: {} mountMtlsCerts: false base: enableCRDTemplates: false validationURL: "" pilot: autoscaleEnabled: true autoscaleMin: 1 autoscaleMax: 5 replicaCount: 1 image: pilot traceSampling: 1.0 env: {} cpu: targetAverageUtilization: 80 nodeSelector: {} keepaliveMaxServerConnectionAge: 30m enableProtocolSniffingForOutbound: true enableProtocolSniffingForInbound: true deploymentLabels: podLabels: {} configMap: true telemetry: enabled: true v2: enabled: true metadataExchange: wasmEnabled: false prometheus: wasmEnabled: false enabled: true stackdriver: enabled: false logging: false monitoring: false topology: false configOverride: {} istiodRemote: injectionURL: "" gateways: istio-egressgateway: env: {} autoscaleEnabled: true type: ClusterIP name: istio-egressgateway secretVolumes: - name: egressgateway-certs secretName: istio-egressgateway-certs mountPath: /etc/istio/egressgateway-certs - name: egressgateway-ca-certs secretName: istio-egressgateway-ca-certs mountPath: /etc/istio/egressgateway-ca-certs istio-ingressgateway: autoscaleEnabled: true type: LoadBalancer name: istio-ingressgateway env: {} secretVolumes: - name: ingressgateway-certs secretName: istio-ingressgateway-certs mountPath: /etc/istio/ingressgateway-certs - name: ingressgateway-ca-certs secretName: istio-ingressgateway-ca-certs mountPath: /etc/istio/ingressgateway-ca-certs
#temp1.yamlapiVersion: install.istio.io/v1alpha1kind: IstioOperatormetadata: namespace: istio-systemspec: components: base: enabled: false cni: enabled: false egressGateways: - enabled: false name: istio-egressgateway ingressGateways: - enabled: false name: istio-ingressgateway istiodRemote: enabled: false pilot: enabled: false hub: gcr.io/istio-testing meshConfig: defaultConfig: proxyMetadata: {} enablePrometheusMerge: true tag: latest values: base: enableCRDTemplates: false validationURL: "" defaultRevision: "" gateways: istio-egressgateway: autoscaleEnabled: true env: {} name: istio-egressgateway secretVolumes: - mountPath: /etc/istio/egressgateway-certs name: egressgateway-certs secretName: istio-egressgateway-certs - mountPath: /etc/istio/egressgateway-ca-certs name: egressgateway-ca-certs secretName: istio-egressgateway-ca-certs type: ClusterIP istio-ingressgateway: autoscaleEnabled: true env: {} name: istio-ingressgateway secretVolumes: - mountPath: /etc/istio/ingressgateway-certs name: ingressgateway-certs secretName: istio-ingressgateway-certs - mountPath: /etc/istio/ingressgateway-ca-certs name: ingressgateway-ca-certs secretName: istio-ingressgateway-ca-certs type: LoadBalancer global: configValidation: true defaultNodeSelector: {} defaultPodDisruptionBudget: enabled: true defaultResources: requests: cpu: 10m imagePullPolicy: "" imagePullSecrets: [] istioNamespace: istio-system istiod: enableAnalysis: false jwtPolicy: third-party-jwt logAsJson: false logging: level: default:info meshNetworks: {} mountMtlsCerts: false multiCluster: clusterName: "" enabled: false network: "" omitSidecarInjectorConfigMap: false oneNamespace: false operatorManageWebhooks: false pilotCertProvider: istiod priorityClassName: "" proxy: autoInject: enabled clusterDomain: cluster.local componentLogLevel: misc:error enableCoreDump: false excludeIPRanges: "" excludeInboundPorts: "" excludeOutboundPorts: "" image: proxyv2 includeIPRanges: '*' logLevel: warning privileged: false readinessFailureThreshold: 30 readinessInitialDelaySeconds: 1 readinessPeriodSeconds: 2 resources: limits: cpu: 2000m memory: 1024Mi requests: cpu: 100m memory: 128Mi statusPort: 15020 tracer: zipkin proxy_init: image: proxyv2 resources: limits: cpu: 2000m memory: 1024Mi requests: cpu: 10m memory: 10Mi sds: token: aud: istio-ca sts: servicePort: 0 tracer: datadog: {} lightstep: {} stackdriver: {} zipkin: {} useMCP: false istiodRemote: injectionURL: "" pilot: autoscaleEnabled: true autoscaleMax: 5 autoscaleMin: 1 configMap: true cpu: targetAverageUtilization: 80 deploymentLabels: null enableProtocolSniffingForInbound: true enableProtocolSniffingForOutbound: true env: {} image: pilot keepaliveMaxServerConnectionAge: 30m nodeSelector: {} podLabels: {} replicaCount: 1 traceSampling: 1 telemetry: enabled: true v2: enabled: true metadataExchange: wasmEnabled: false prometheus: enabled: true wasmEnabled: false stackdriver: configOverride: {} enabled: false logging: false monitoring: false topology: false
OverlayIOP
OverlayIOP将ReadYaml(And)Profile所失去的temp0.yaml笼罩于temp1.yaml之上,失去final.yaml
#empty yaml# The empty profile has everything disabled# This is useful as a base for custom user configurationapiVersion: install.istio.io/v1alpha1kind: IstioOperatorspec: components: base: enabled: false pilot: enabled: false ingressGateways: - name: istio-ingressgateway enabled: false
# final.yamlapiVersion: install.istio.io/v1alpha1kind: IstioOperatormetadata: creationTimestamp: null namespace: istio-systemspec: components: base: enabled: false cni: enabled: false egressGateways: - enabled: false name: istio-egressgateway ingressGateways: - enabled: false name: istio-ingressgateway istiodRemote: enabled: false pilot: enabled: true hub: docker.io/istio installPackagePath: /istio/manifests meshConfig: defaultConfig: proxyMetadata: {} enablePrometheusMerge: true profile: empty tag: 1.1.5 values: base: enableCRDTemplates: false validationURL: "" defaultRevision: "" gateways: istio-egressgateway: autoscaleEnabled: true env: {} name: istio-egressgateway secretVolumes: - mountPath: /etc/istio/egressgateway-certs name: egressgateway-certs secretName: istio-egressgateway-certs - mountPath: /etc/istio/egressgateway-ca-certs name: egressgateway-ca-certs secretName: istio-egressgateway-ca-certs type: ClusterIP istio-ingressgateway: autoscaleEnabled: true env: {} name: istio-ingressgateway secretVolumes: - mountPath: /etc/istio/ingressgateway-certs name: ingressgateway-certs secretName: istio-ingressgateway-certs - mountPath: /etc/istio/ingressgateway-ca-certs name: ingressgateway-ca-certs secretName: istio-ingressgateway-ca-certs type: LoadBalancer global: configValidation: true defaultNodeSelector: {} defaultPodDisruptionBudget: enabled: true defaultResources: requests: cpu: 10m imagePullPolicy: "" imagePullSecrets: [] istioNamespace: istio-system istiod: enableAnalysis: false jwtPolicy: third-party-jwt logAsJson: false logging: level: default:info meshNetworks: {} mountMtlsCerts: false multiCluster: clusterName: "" enabled: false network: "" omitSidecarInjectorConfigMap: false oneNamespace: false operatorManageWebhooks: false pilotCertProvider: istiod priorityClassName: "" proxy: autoInject: enabled clusterDomain: cluster.local componentLogLevel: misc:error enableCoreDump: false excludeIPRanges: "" excludeInboundPorts: "" excludeOutboundPorts: "" image: proxyv2 includeIPRanges: '*' logLevel: warning privileged: false readinessFailureThreshold: 30 readinessInitialDelaySeconds: 1 readinessPeriodSeconds: 2 resources: limits: cpu: 2000m memory: 1024Mi requests: cpu: 100m memory: 128Mi statusPort: 15020 tracer: zipkin proxy_init: image: proxyv2 resources: limits: cpu: 2000m memory: 1024Mi requests: cpu: 10m memory: 10Mi sds: token: aud: istio-ca sts: servicePort: 0 tracer: datadog: {} lightstep: {} stackdriver: {} zipkin: {} useMCP: false istiodRemote: injectionURL: "" pilot: autoscaleEnabled: true autoscaleMax: 5 autoscaleMin: 1 configMap: true cpu: targetAverageUtilization: 80 deploymentLabels: null enableProtocolSniffingForInbound: true enableProtocolSniffingForOutbound: true env: {} image: pilot keepaliveMaxServerConnectionAge: 30m nodeSelector: {} podLabels: {} replicaCount: 1 traceSampling: 1 telemetry: enabled: true v2: enabled: true metadataExchange: wasmEnabled: false prometheus: enabled: true wasmEnabled: false stackdriver: configOverride: {} enabled: false logging: false monitoring: false topology: false
GenerateConfig
配置局部总结如下,operator将绝大部分面向用户的配置复杂度都暗藏在了内置profile中,其中base profile是根底演变项,演变过程为base profile -> select profile -> user config -> set flag,越往后优先级越高。在具体实际中,内置profile能满足大多数需要,若有额定需要则应用user config解决,set flag不便于管理。
RenderCharts
后面提到,operator要应用helm的chart rendering,因而通过GenerateConfig生成的final.yaml能够映射到helm的values.yaml。并且,为了便于用户了解与保护helm chart,istio管制面的每一个组件都有一个chart与之对应,final.yaml中各个组件的配置最终映射到各个chart的values.yaml进行渲染。charts目录如下所示。
processRecursive
每个组件的chart渲染胜利后生成所需的manifest,并利用k8s的api与apiserver进行交互,最初胜利创立或更新istio失常运行所需的所有资源。
Manifest
Manifest命令根本与Install命令的流程相似,只是通过helm渲染后不须要与apiserver交互并创立资源,因而不再赘述。