背景
当通过执行kubectl label namespace sample istio-injection=enabled
此命令后(为sample命名命名空间开启自动注入Sidecar),在sample命名空间进行部署应用时,会发现每个Pod都会自动注入Sidecar,是不是很神奇,接下来我们一步一步分析一下!
什么是 Admission
Admission是Kubernetes中的一个术语,指的是Kubernetes API Server资源请求过程中的一个阶段。它会在请求通过认证和授权之后、对象被持久化之前拦截到达 API 服务器的请求,然后经过Admission处理( 根据 API 中的配置,分别执行变更和验证准入控制 webhook,最后再保存到etcd。
从上图看出,Admission有两个重要的阶段:Mutating和Validating,这两个阶段中执行的逻辑如下:
- Mutating,从字面上可以知道,在Mutating阶段可以对请求内容进行修改。
- Validating,指在该阶段不允许修改请求内容,但可以根据请求的内容判断是继续执行该请求还是拒绝该请求。
Kubernetes 1.9版本开始引入了Admission Webhook扩展机制,通过Webhook回调功能,开发者可以非常灵活地对Kubernetes API Server的功能进行扩展,在API Server创建资源时对资源进行验证或者修改。
使用Webhook的优势是不需要对API Server的源码进行修改和重新编译就可以扩展其功能。插入的逻辑实现为一个独立的进程,通过参数方式传入到Kubernetes中,由Kubernetes在进行自身逻辑处理时对扩展逻辑进行回调。
通过Admission Webhook,可以加入Mutation和Validation两种类型的Webhook插件:
-
MutatingAdmissionWebhook允许你在Webhook中对资源对象进行修改。
-
ValidatingAdmissionWebhook执行一些检查操作,可以拒绝用户的请求来增加额外的准入策略。
当集群管理员需要强制对某些请求(或所有请求)都进行校验(或者修改)的时候,就可以考虑使用ValidatingAdmissionWebhook或MutatingAdmissionWebhook。
启用 Webhook
WebHook 是一种 HTTP 回调:某些条件下触发的 HTTP POST 请求;通过 HTTP POST 发送的简单事件通知。一个基于 web 应用实现的 WebHook 会在特定事件发生时把消息发送给特定的 URL。
在Kubernetes API Server种的有个配置参数:--enable-admission-plugins,其值为一串用逗号连接的有序的准入模块列表,设置后就可在对象操作前执行一定顺序的准入模块调用。
# 修改api server的启动参数即可
--enable-admission-plugins=NodeRestriction CertificateApproval, CertificateSigning, CertificateSubjectRestriction, DefaultIngressClass, DefaultStorageClass, DefaultTolerationSeconds, LimitRanger, MutatingAdmissionWebhook, NamespaceLifecycle, PersistentVolumeClaimResize, Priority, ResourceQuota, RuntimeClass, ServiceAccount, StorageObjectInUseProtection, TaintNodesByCondition, ValidatingAdmissionWebhook
Webhook自动注入Sidecar
Istio是利用了Kubernets Webook机制来实现Envoy Proxy Sidecar的自动注入。
分析注入配置
首先,创建Sidecar注入的配置文件istio-sidecar-injector:
# kubectl get cm -n istio-system istio-sidecar-injector -o yaml
apiVersion: v1
data:
config: |-
defaultTemplates: [sidecar]
policy: enabled
alwaysInjectSelector:
.....
templates:
sidecar: |
{{- $containers := list }}
{{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}}
metadata:
labels:
security.istio.io/tlsMode: {{ index .ObjectMeta.Labels `security.istio.io/tlsMode` | default "istio" | quote }}
service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }}
service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }}
istio.io/rev: {{ .Revision | default "default" | quote }}
annotations: {
{{- if eq (len $containers) 1 }}
kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}",
kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}",
{{ end }}
{{- if .Values.istio_cni.enabled }}
{{- if not .Values.istio_cni.chained }}
k8s.v1.cni.cncf.io/networks: '{{ appendMultusNetwork (index .ObjectMeta.Annotations `k8s.v1.cni.cncf.io/networks`) `istio-cni` }}',
{{- end }}
sidecar.istio.io/interceptionMode: "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}",
{{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}traffic.sidecar.istio.io/includeOutboundIPRanges: "{{.}}",{{ end }}
{{ with annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}traffic.sidecar.istio.io/excludeOutboundIPRanges: "{{.}}",{{ end }}
traffic.sidecar.istio.io/includeInboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` `*` }}",
traffic.sidecar.istio.io/excludeInboundPorts: "{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}",
{{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") }}
traffic.sidecar.istio.io/includeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}",
{{- end }}
{{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne .Values.global.proxy.excludeOutboundPorts "") }}
traffic.sidecar.istio.io/excludeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}",
{{- end }}
{{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}traffic.sidecar.istio.io/kubevirtInterfaces: "{{.}}",{{ end }}
{{- end }}
}
可以看出该configmap保存了默认的注册策略和Sidecar注入模板
策略参数:
- disabled:Sidecar注入器默认不会注入pod中。pod模板定义中的注解sidecar.istio.io/inject值为true,会启用注入功能。
- enabled:Sidecar注入器默认会注入pod中。pod模板定义中的注解sidecar.istio.io/inject值为false,会禁止注入功能。
分析注入的Webhook
# kubectl get MutatingWebhookConfiguration -n istio-system -o yaml
apiVersion: v1
items:
- apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
generation: 2
labels:
app: sidecar-injector
install.operator.istio.io/owning-resource: unknown
install.operator.istio.io/owning-resource-namespace: istio-system
istio.io/rev: default
operator.istio.io/component: Pilot
operator.istio.io/managed: Reconcile
operator.istio.io/version: 1.10.6
release: istio
manager: istio-operator
operation: Apply
time: "2021-12-31T03:27:02Z"
manager: pilot-discovery
operation: Update
time: "2021-12-31T03:27:32Z"
name: istio-sidecar-injector
resourceVersion: "3291680"
selfLink: /apis/admissionregistration.k8s.io/v1/mutatingwebhookconfigurations/istio-sidecar-injector
uid: 89d137e5-fc47-4069-b9ba-a8f71e4d1cc6
webhooks:
- admissionReviewVersions:
- v1beta1
- v1
clientConfig: # webhook指定连接信息
caBundle: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMvVENDQWVXZ0F3SUJBZ0lSQUtlRksvQmphOGVWR3VSelAzcTdXODh3RFFZSktvWklodmNOQVFFTEJRQXcKR0RFV01CUUdBMVVFQ2hNTlkyeDFjM1JsY2k1c2IyTmhiREFlRncweU1URXlNekV3TXpJM016RmFGdzB6TVRFeQpNamt3TXpJM016RmFNQmd4RmpBVUJnTlZCQW9URFdOc2RYTjBaWEl1Ykc5allXd3dnZ0VpTUEwR0NTcUdTSWIzCkRRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRRFp0SmxBMkhqQURBamVlNGpUTjlOK0FjRFJybmxjT2k2SmZqOWEKQWdUSFBxcmo1MGo1aUQ5SERUbXlOOXlkeS8yR2pUUStQaFB3UkxyUG9UUjV3Q1ZVTk5JbGdUelZpSE03d3JOWQo2V2N6bVpRQ0Zxd1hEbHBnZkRFUFhjUjQ5OUwzUXp1c3phczE4S2pEckFVTFdkT3NOL2k1SS9tbGJOdVlKSnpPCnFDQ0swRnFiemtBUU9oaGduZHdQMVdoUHZHSWVXTy96d3BOQUluVXpFck5LcW8ya2tQbHZwRmQydGhlWVY2cU8KRFBtZE9LQVRwb0xqR3dVSnIraWUyWlJXbjlSeUp4ZW4wTlhKcWZRMmg1WGp3MThCaXBNUVQ2WGhTVGtkUktibApDOHk0Z0tJY2xmc2lSckUwTER5dnVtSUhDMEFucTl2eDZ2VHo3elVFMFdPcEFZVVBBZ01CQUFHalFqQkFNQTRHCkExVWREd0VCL3dRRUF3SUNCREFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQjBHQTFVZERnUVdCQlFDYko3VkZOK3QKTWZCa0t4K2NVNXZObnhqNDFEQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUF6cDdmTGR0S20vTzRwTGNNWWd3aApKZFJHSGlVOEU4bmJzWU1HamU3bEFockl0R2JoWURhT3NTRGMrc2NrUkVScDF4dDM1NnJsU1ZINGo4S2NWNnJZClRIUFM2NWdrNm1uMmEyT1A1aFQxUDdiYk8wVTQyaFM4WUpUR0IvTzRreThsYnRZWFBhRTFCbTQrOUw1eHlQMHkKSllJaDFqTVFKQ1UrOTdzS002V2xOZzh1NzMvZ2xhamJrOUNFRmJkUUVGRmVCVEJlVS9IOTY4SWFDL0txNlQ0SAo4VTBEc3hqQnZyN0gxRnpTY3lKQk8zSEdBTkhzWkRtdm9vMDk5WFdteElvSHRDb3dDdExjWFQ0cktPbmt2SERHCjZlalhuNzBjbUp5dFIrVzFJazc2VldjMXUwM2ZQZVB5WE4wOC85THFkS0J3L2dFQndTamkwanYwTVJSczZnWnUKOXc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
service:
name: istiod
namespace: istio-system
path: /inject
port: 443
failurePolicy: Fail
matchPolicy: Equivalent
name: rev.namespace.sidecar-injector.istio.io
namespaceSelector:
matchExpressions:
- key: istio.io/rev
operator: In
values:
- default
- key: istio-injection
operator: DoesNotExist
objectSelector:
matchExpressions:
- key: sidecar.istio.io/inject
operator: NotIn
values:
- "false"
reinvocationPolicy: Never
rules:
- apiGroups:
- ""
apiVersions:
- v1
operations:
- CREATE
resources:
- pods
scope: '*'
sideEffects: None
timeoutSeconds: 10
- admissionReviewVersions:
- v1beta1
- v1
clientConfig:
caBundle: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMvVENDQWVXZ0F3SUJBZ0lSQUtlRksvQmphOGVWR3VSelAzcTdXODh3RFFZSktvWklodmNOQVFFTEJRQXcKR0RFV01CUUdBMVVFQ2hNTlkyeDFjM1JsY2k1c2IyTmhiREFlRncweU1URXlNekV3TXpJM016RmFGdzB6TVRFeQpNamt3TXpJM016RmFNQmd4RmpBVUJnTlZCQW9URFdOc2RYTjBaWEl1Ykc5allXd3dnZ0VpTUEwR0NTcUdTSWIzCkRRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRRFp0SmxBMkhqQURBamVlNGpUTjlOK0FjRFJybmxjT2k2SmZqOWEKQWdUSFBxcmo1MGo1aUQ5SERUbXlOOXlkeS8yR2pUUStQaFB3UkxyUG9UUjV3Q1ZVTk5JbGdUelZpSE03d3JOWQo2V2N6bVpRQ0Zxd1hEbHBnZkRFUFhjUjQ5OUwzUXp1c3phczE4S2pEckFVTFdkT3NOL2k1SS9tbGJOdVlKSnpPCnFDQ0swRnFiemtBUU9oaGduZHdQMVdoUHZHSWVXTy96d3BOQUluVXpFck5LcW8ya2tQbHZwRmQydGhlWVY2cU8KRFBtZE9LQVRwb0xqR3dVSnIraWUyWlJXbjlSeUp4ZW4wTlhKcWZRMmg1WGp3MThCaXBNUVQ2WGhTVGtkUktibApDOHk0Z0tJY2xmc2lSckUwTER5dnVtSUhDMEFucTl2eDZ2VHo3elVFMFdPcEFZVVBBZ01CQUFHalFqQkFNQTRHCkExVWREd0VCL3dRRUF3SUNCREFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQjBHQTFVZERnUVdCQlFDYko3VkZOK3QKTWZCa0t4K2NVNXZObnhqNDFEQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUF6cDdmTGR0S20vTzRwTGNNWWd3aApKZFJHSGlVOEU4bmJzWU1HamU3bEFockl0R2JoWURhT3NTRGMrc2NrUkVScDF4dDM1NnJsU1ZINGo4S2NWNnJZClRIUFM2NWdrNm1uMmEyT1A1aFQxUDdiYk8wVTQyaFM4WUpUR0IvTzRreThsYnRZWFBhRTFCbTQrOUw1eHlQMHkKSllJaDFqTVFKQ1UrOTdzS002V2xOZzh1NzMvZ2xhamJrOUNFRmJkUUVGRmVCVEJlVS9IOTY4SWFDL0txNlQ0SAo4VTBEc3hqQnZyN0gxRnpTY3lKQk8zSEdBTkhzWkRtdm9vMDk5WFdteElvSHRDb3dDdExjWFQ0cktPbmt2SERHCjZlalhuNzBjbUp5dFIrVzFJazc2VldjMXUwM2ZQZVB5WE4wOC85THFkS0J3L2dFQndTamkwanYwTVJSczZnWnUKOXc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
service:
name: istiod
namespace: istio-system
path: /inject
port: 443
failurePolicy: Fail
matchPolicy: Equivalent
name: rev.object.sidecar-injector.istio.io
namespaceSelector:
matchExpressions:
- key: istio.io/rev
operator: DoesNotExist
- key: istio-injection
operator: DoesNotExist
objectSelector:
matchExpressions:
- key: sidecar.istio.io/inject
operator: NotIn
values:
- "false"
- key: istio.io/rev
operator: In
values:
- default
reinvocationPolicy: Never
rules:
- apiGroups:
- ""
apiVersions:
- v1
operations:
- CREATE
resources:
- pods
scope: '*'
sideEffects: None
timeoutSeconds: 10
- admissionReviewVersions:
- v1beta1
- v1
clientConfig:
caBundle: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMvVENDQWVXZ0F3SUJBZ0lSQUtlRksvQmphOGVWR3VSelAzcTdXODh3RFFZSktvWklodmNOQVFFTEJRQXcKR0RFV01CUUdBMVVFQ2hNTlkyeDFjM1JsY2k1c2IyTmhiREFlRncweU1URXlNekV3TXpJM016RmFGdzB6TVRFeQpNamt3TXpJM016RmFNQmd4RmpBVUJnTlZCQW9URFdOc2RYTjBaWEl1Ykc5allXd3dnZ0VpTUEwR0NTcUdTSWIzCkRRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRRFp0SmxBMkhqQURBamVlNGpUTjlOK0FjRFJybmxjT2k2SmZqOWEKQWdUSFBxcmo1MGo1aUQ5SERUbXlOOXlkeS8yR2pUUStQaFB3UkxyUG9UUjV3Q1ZVTk5JbGdUelZpSE03d3JOWQo2V2N6bVpRQ0Zxd1hEbHBnZkRFUFhjUjQ5OUwzUXp1c3phczE4S2pEckFVTFdkT3NOL2k1SS9tbGJOdVlKSnpPCnFDQ0swRnFiemtBUU9oaGduZHdQMVdoUHZHSWVXTy96d3BOQUluVXpFck5LcW8ya2tQbHZwRmQydGhlWVY2cU8KRFBtZE9LQVRwb0xqR3dVSnIraWUyWlJXbjlSeUp4ZW4wTlhKcWZRMmg1WGp3MThCaXBNUVQ2WGhTVGtkUktibApDOHk0Z0tJY2xmc2lSckUwTER5dnVtSUhDMEFucTl2eDZ2VHo3elVFMFdPcEFZVVBBZ01CQUFHalFqQkFNQTRHCkExVWREd0VCL3dRRUF3SUNCREFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQjBHQTFVZERnUVdCQlFDYko3VkZOK3QKTWZCa0t4K2NVNXZObnhqNDFEQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUF6cDdmTGR0S20vTzRwTGNNWWd3aApKZFJHSGlVOEU4bmJzWU1HamU3bEFockl0R2JoWURhT3NTRGMrc2NrUkVScDF4dDM1NnJsU1ZINGo4S2NWNnJZClRIUFM2NWdrNm1uMmEyT1A1aFQxUDdiYk8wVTQyaFM4WUpUR0IvTzRreThsYnRZWFBhRTFCbTQrOUw1eHlQMHkKSllJaDFqTVFKQ1UrOTdzS002V2xOZzh1NzMvZ2xhamJrOUNFRmJkUUVGRmVCVEJlVS9IOTY4SWFDL0txNlQ0SAo4VTBEc3hqQnZyN0gxRnpTY3lKQk8zSEdBTkhzWkRtdm9vMDk5WFdteElvSHRDb3dDdExjWFQ0cktPbmt2SERHCjZlalhuNzBjbUp5dFIrVzFJazc2VldjMXUwM2ZQZVB5WE4wOC85THFkS0J3L2dFQndTamkwanYwTVJSczZnWnUKOXc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
service:
name: istiod
namespace: istio-system
path: /inject
port: 443
failurePolicy: Fail
matchPolicy: Equivalent
name: namespace.sidecar-injector.istio.io
namespaceSelector:
matchExpressions:
- key: istio-injection
operator: In
values:
- enabled
objectSelector:
matchExpressions:
- key: sidecar.istio.io/inject
operator: NotIn
values:
- "false"
reinvocationPolicy: Never
rules:
- apiGroups:
- ""
apiVersions:
- v1
operations:
- CREATE
resources:
- pods
scope: '*'
sideEffects: None
timeoutSeconds: 10
- admissionReviewVersions:
- v1beta1
- v1
clientConfig:
caBundle: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMvVENDQWVXZ0F3SUJBZ0lSQUtlRksvQmphOGVWR3VSelAzcTdXODh3RFFZSktvWklodmNOQVFFTEJRQXcKR0RFV01CUUdBMVVFQ2hNTlkyeDFjM1JsY2k1c2IyTmhiREFlRncweU1URXlNekV3TXpJM016RmFGdzB6TVRFeQpNamt3TXpJM016RmFNQmd4RmpBVUJnTlZCQW9URFdOc2RYTjBaWEl1Ykc5allXd3dnZ0VpTUEwR0NTcUdTSWIzCkRRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRRFp0SmxBMkhqQURBamVlNGpUTjlOK0FjRFJybmxjT2k2SmZqOWEKQWdUSFBxcmo1MGo1aUQ5SERUbXlOOXlkeS8yR2pUUStQaFB3UkxyUG9UUjV3Q1ZVTk5JbGdUelZpSE03d3JOWQo2V2N6bVpRQ0Zxd1hEbHBnZkRFUFhjUjQ5OUwzUXp1c3phczE4S2pEckFVTFdkT3NOL2k1SS9tbGJOdVlKSnpPCnFDQ0swRnFiemtBUU9oaGduZHdQMVdoUHZHSWVXTy96d3BOQUluVXpFck5LcW8ya2tQbHZwRmQydGhlWVY2cU8KRFBtZE9LQVRwb0xqR3dVSnIraWUyWlJXbjlSeUp4ZW4wTlhKcWZRMmg1WGp3MThCaXBNUVQ2WGhTVGtkUktibApDOHk0Z0tJY2xmc2lSckUwTER5dnVtSUhDMEFucTl2eDZ2VHo3elVFMFdPcEFZVVBBZ01CQUFHalFqQkFNQTRHCkExVWREd0VCL3dRRUF3SUNCREFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQjBHQTFVZERnUVdCQlFDYko3VkZOK3QKTWZCa0t4K2NVNXZObnhqNDFEQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUF6cDdmTGR0S20vTzRwTGNNWWd3aApKZFJHSGlVOEU4bmJzWU1HamU3bEFockl0R2JoWURhT3NTRGMrc2NrUkVScDF4dDM1NnJsU1ZINGo4S2NWNnJZClRIUFM2NWdrNm1uMmEyT1A1aFQxUDdiYk8wVTQyaFM4WUpUR0IvTzRreThsYnRZWFBhRTFCbTQrOUw1eHlQMHkKSllJaDFqTVFKQ1UrOTdzS002V2xOZzh1NzMvZ2xhamJrOUNFRmJkUUVGRmVCVEJlVS9IOTY4SWFDL0txNlQ0SAo4VTBEc3hqQnZyN0gxRnpTY3lKQk8zSEdBTkhzWkRtdm9vMDk5WFdteElvSHRDb3dDdExjWFQ0cktPbmt2SERHCjZlalhuNzBjbUp5dFIrVzFJazc2VldjMXUwM2ZQZVB5WE4wOC85THFkS0J3L2dFQndTamkwanYwTVJSczZnWnUKOXc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
service:
name: istiod
namespace: istio-system
path: /inject
port: 443
failurePolicy: Fail
matchPolicy: Equivalent
name: object.sidecar-injector.istio.io
namespaceSelector:
matchExpressions:
- key: istio-injection
operator: DoesNotExist
- key: istio.io/rev
operator: DoesNotExist
objectSelector:
matchExpressions:
- key: sidecar.istio.io/inject
operator: In
values:
- "true"
- key: istio.io/rev
operator: DoesNotExist
reinvocationPolicy: Never
rules:
- apiGroups:
- ""
apiVersions:
- v1
operations:
- CREATE
resources:
- pods
scope: '*'
sideEffects: None
timeoutSeconds: 10
kind: List
metadata:
resourceVersion: ""
selfLink: ""
如果enableNamespacesByDefault设置为true时,会根据命名空间选择器的匹配规则来决定是否默认启用Sidecar自动注入,即istio-injection不为disabled;反之,如果enableNamespacesByDefault设置为false时,只有命令空间中设置了标签istio-injection并且值为enabled,才会启用Sidecar自动注入。
匹配请求-规则
operations
列出一个或多个要匹配的操作。 可以是CREATE
、UPDATE
、DELETE
、CONNECT
或*
以匹配所有内容。apiGroups
列出了一个或多个要匹配的 API 组。""
是核心 API 组。"*"
匹配所有 API 组。apiVersions
列出了一个或多个要匹配的 API 版本。"*"
匹配所有 API 版本。resources
列出了一个或多个要匹配的资源。
"*"
匹配所有资源,但不包括子资源。"*/*"
匹配所有资源,包括子资源。"pods/*"
匹配 pod 的所有子资源。"*/status"
匹配所有 status 子资源。
scope
指定要匹配的范围。有效值为"Cluster"
、"Namespaced"
和"*"
。 子资源匹配其父资源的范围。在 Kubernetes v1.14+ 版本中才被支持。 默认值为"*"
,对应 1.14 版本之前的行为。
"Cluster"
表示只有集群作用域的资源才能匹配此规则(API 对象 Namespace 是集群作用域的)。"Namespaced"
意味着仅具有名字空间的资源才符合此规则。"*"
表示没有范围限制。
注入条件
- Webhook的namespaceSelector机制。
- 默认策略。
- 每个pod的可覆盖注解。
案例
Sidecar自动注入的规则,enableNamespacesByDefault设置为false时,命名空间中设置了标签istio-injection并且值为enabled,才会启用Sidecar自动注入。
# 为命名空间default增加标签istio-injection且值设为enabled
$ kubectl label namespaces default istio-injection=enabled
namespace/default labeled
$ cat nginx-deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
$ kubectl apply -f nginx-deployment.yml
deployment.apps/nginx-deployment created
# 通过查看pod详情可以发现sidecar已注入
$ kubectl describe pods nginx-deployment-66b6c48dd5-swz7j
Name: nginx-deployment-66b6c48dd5-swz7j
Namespace: default
Priority: 0
Node: k8s-node02/192.168.1.105
Start Time: Thu, 20 Jan 2022 16:37:28 +0800
Labels: app=nginx
istio.io/rev=default
pod-template-hash=66b6c48dd5
security.istio.io/tlsMode=istio
service.istio.io/canonical-name=nginx
service.istio.io/canonical-revision=latest
Annotations: cni.projectcalico.org/podIP: 100.125.152.31/32
cni.projectcalico.org/podIPs: 100.125.152.31/32
kubectl.kubernetes.io/default-container: nginx
kubectl.kubernetes.io/default-logs-container: nginx
prometheus.io/path: /stats/prometheus
prometheus.io/port: 15020
prometheus.io/scrape: true
sidecar.istio.io/status:
{"initContainers":["istio-init"],"containers":["istio-proxy"],"volumes":["istio-envoy","istio-data","istio-podinfo","istiod-ca-cert"],"ima...
Status: Running
IP: 100.125.152.31
IPs:
IP: 100.125.152.31
Controlled By: ReplicaSet/nginx-deployment-66b6c48dd5
Init Containers:
istio-init:
Container ID: docker://3d1d8f5c7840df4e680b222a44d5597c2f1363aeddf75337c84a5d31349fece5
Image: docker.io/istio/proxyv2:1.10.6
Image ID: docker-pullable://istio/proxyv2@sha256:c26d5a662ffb9e931b71198c1c5647466e0423e5408a37acb92d97dadcf00f2c
Port: <none>
Host Port: <none>
Args:
istio-iptables
-p
15001
-z
15006
-u
1337
-m
REDIRECT
-i
*
-x
-b
*
-d
15090,15021,15020
State: Terminated
Reason: Completed
Exit Code: 0
Started: Thu, 20 Jan 2022 16:37:29 +0800
Finished: Thu, 20 Jan 2022 16:37:29 +0800
Ready: True
Restart Count: 0
Limits:
cpu: 2
memory: 1Gi
Requests:
cpu: 100m
memory: 128Mi
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-xr52f (ro)
Containers:
nginx:
Container ID: docker://4deec4c4a8573445fc086275ae8665e75778e1c615e33fa12e9014eb5f721db0
Image: nginx:1.14.2
Image ID: docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d
Port: 80/TCP
Host Port: 0/TCP
State: Running
Started: Thu, 20 Jan 2022 16:37:30 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-xr52f (ro)
istio-proxy:
Container ID: docker://9b183d318f0b73ec8d42bf69abc7cf41ff2290f59ed9e2cca6e513e1a85ac775
Image: docker.io/istio/proxyv2:1.10.6
Image ID: docker-pullable://istio/proxyv2@sha256:c26d5a662ffb9e931b71198c1c5647466e0423e5408a37acb92d97dadcf00f2c
Port: 15090/TCP
Host Port: 0/TCP
Args:
proxy
sidecar
--domain
$(POD_NAMESPACE).svc.cluster.local
--serviceCluster
nginx.$(POD_NAMESPACE)
--proxyLogLevel=warning
--proxyComponentLogLevel=misc:error
--log_output_level=default:info
--concurrency
2
State: Running
Started: Thu, 20 Jan 2022 16:37:30 +0800
Ready: True
Restart Count: 0
Limits:
cpu: 2
memory: 1Gi
Requests:
cpu: 100m
memory: 128Mi
Readiness: http-get http://:15021/healthz/ready delay=1s timeout=3s period=2s #success=1 #failure=30
Environment:
JWT_POLICY: first-party-jwt
PILOT_CERT_PROVIDER: istiod
CA_ADDR: istiod.istio-system.svc:15012
POD_NAME: nginx-deployment-66b6c48dd5-swz7j (v1:metadata.name)
POD_NAMESPACE: default (v1:metadata.namespace)
INSTANCE_IP: (v1:status.podIP)
SERVICE_ACCOUNT: (v1:spec.serviceAccountName)
HOST_IP: (v1:status.hostIP)
CANONICAL_SERVICE: (v1:metadata.labels['service.istio.io/canonical-name'])
CANONICAL_REVISION: (v1:metadata.labels['service.istio.io/canonical-revision'])
PROXY_CONFIG: {}
ISTIO_META_POD_PORTS: [
{"containerPort":80,"protocol":"TCP"}
]
ISTIO_META_APP_CONTAINERS: nginx
ISTIO_META_CLUSTER_ID: Kubernetes
ISTIO_META_INTERCEPTION_MODE: REDIRECT
ISTIO_META_WORKLOAD_NAME: nginx-deployment
ISTIO_META_OWNER: kubernetes://apis/apps/v1/namespaces/default/deployments/nginx-deployment
ISTIO_META_MESH_ID: cluster.local
TRUST_DOMAIN: cluster.local
Mounts:
/etc/istio/pod from istio-podinfo (rw)
/etc/istio/proxy from istio-envoy (rw)
/var/lib/istio/data from istio-data (rw)
/var/run/secrets/istio from istiod-ca-cert (rw)
/var/run/secrets/kubernetes.io/serviceaccount from default-token-xr52f (ro
小结
Istio 自动注入Sidecar是根据kubernets Apiserver准入Webook实现。当请求通过认证和授权后, 对象被持久化之前拦截到达 API 服务器的请求,会根据Api sever中的配置,分配去执行变更和验证准入的Webhook。这时istio-sidecar-injector Webhook会根据注入条件进行更改Pod模板达到目的。
评论区