共计 11507 个字符,预计需要花费 29 分钟才能阅读完成。
前言
为了不便用户装置 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.yaml
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
profile: minimal
hub: docker.io/istio
tag: 1.1.4
components:
pilot:
enabled: true
# test1.yaml
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
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.yaml
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
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 configuration
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
components:
base:
enabled: false
pilot:
enabled: false
ingressGateways:
- name: istio-ingressgateway
enabled: false
#default yaml
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
namespace: istio-system
spec:
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.yaml
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
namespace: istio-system
spec:
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 configuration
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
components:
base:
enabled: false
pilot:
enabled: false
ingressGateways:
- name: istio-ingressgateway
enabled: false
# final.yaml
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
creationTimestamp: null
namespace: istio-system
spec:
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 交互并创立资源,因而不再赘述。