在前面系列文章中已经介绍了Istio及其各个核心组件,详述了如何利用阿里云Kubernetes容器服务,快速搭建一套用于连接、管理以及保护微服务的开放平台Istio,为应用引入和配置多个相关服务;并且通过一个官方示例演示了如何部署应用到上述Istio环境中,演示了如何设置智能路由、分布式追踪以及Istio 的遥测数据收集、查询及可视化等功能。
回顾这个系列文章请参考:
阿里云Kubernetes Service Mesh实践进行时(1): Istio初体验
阿里云Kubernetes Service Mesh实践进行时(2): 通过示例深入Istio
阿里云Kubernetes Service Mesh实践进行时(3): 智能路由
阿里云Kubernetes Service Mesh实践进行时(4): 分布式追踪
阿里云Kubernetes Service Mesh实践进行时(5): 遥测数据收集、查询及可视化
阿里云Kubernetes Service Mesh实践进行时(6): 故障诊断与检测工具Weave Scope
阿里云Kubernetes Service Mesh实践进行时(7): 可观测性分析服务Kiali
此外,阿里云Kubernetes容器服务已经提供了Istio与日志服务Log Service的集成能力,可以通过阿里云Kubernetes容器服务Istio实践之集成日志服务Log Service了解Istio与基于阿里云日志服务的分布式追踪系统的整合能力。
注意:在使用阿里云Kubernetes容器服务Istio 1.0的过程中,如果遇到类似CRD版本问题,请参考我们提供的问题分析。 我们会持续更新遇到的问题及其解决方法。
本文重点介绍在阿里云Kubernetes容器服务中如何启用或者禁用Sidecar自动注入,并分析自动注入Sidecar的原理机制。使用该自动注入能力,可以简化部署应用的逻辑。同时,阿里云Kubernetes容器服务也提供了可配置选型,让用户可以根据自己的需要配置是否启用该能力。
Admission是Kubernets中的一个术语,指的是Kubernets API Server资源请求过程中的一个阶段。如下图所示,在API Server接收到资源创建请求时,首先会对请求进行认证和鉴权,然后经过Admission处理,最后再保存到etcd。
从图中看到,Admission中有两个重要的阶段:Mutating
和Validating
,这两个阶段中执行的逻辑如下:
Kubernets 1.9版本开始引入了Admission Webhook扩展机制,通过Webhook回调功能,开发者可以非常灵活地对Kubernets API Server的功能进行扩展,在API Server创建资源时对资源进行验证或者修改。
使用Webhook的优势是不需要对API Server的源码进行修改和重新编译就可以扩展其功能。插入的逻辑实现为一个独立的进程,通过参数方式传入到Kubernets中,由Kubernets在进行自身逻辑处理时对扩展逻辑进行回调。
通过Admission webhook,可以加入Mutation和Validation两种类型的webhook插件:
当集群管理员需要强制对某些请求或者所有请求都进行校验或者修改的时候,就可以考虑使用ValidatingAdmissionWebhook或MutatingAdmissionWebhook。
在Kubernetes中,一些高级特性正常运行的前提条件是将相关的准入模块处于enable状态。对于Kubernetes APIServer来说,如果不恰当地配置了准入控制模块,它就不能正常工作或者某些功能也不会正常的生效。
在Kubernetes APIServer中有一个flag:--enable-admission-plugins
,其值为一串用逗号连接起、有序的准入模块列表,设置后就可在对象操作前执行一定顺序的准入模块调用。
--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota
阿里云Kubernetes容器服务默认创建的集群(版本1.10.4) kube-apiserver中已经启用了插件MutatingAdmissionWebhook与ValidatingAdmissionWebhook。通过如下命令可以查看kube-apiserver对应的POD启用参数:
kubectl describe po -l component=kube-apiserver -n kube-system
Command:
kube-apiserver
--apiserver-count=500
--runtime-config=admissionregistration.k8s.io/v1alpha1
......
--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota
......
Istio就是充分利用了Kubernets Webhook机制实现Envoy Proxy Sidecar的自动注入。
首先,创建Sidecar注入的配置项istio-sidecar-injector,如下所示:
kubectl describe configmap istio-sidecar-injector -n istio-system
Name: istio-sidecar-injector
Namespace: istio-system
Labels: app=ack-istio
chart=ack-istio-1.0.0
heritage=Tiller
istio=sidecar-injector
release=myistio
Annotations:
Data
====
config:
----
policy: enabled
template: |-
initContainers:
- name: istio-init
image: "registry.cn-hangzhou.aliyuncs.com/aliacs-app-catalog/proxy_init:1.0.0"
args:
......
imagePullPolicy: IfNotPresent
securityContext:
capabilities:
add:
- NET_ADMIN
privileged: true
restartPolicy: Always
containers:
- name: istio-proxy
image: [[ if (isset .ObjectMeta.Annotations "sidecar.istio.io/proxyImage") -]]
......
可以看到该ConfigMap 保存了默认注入策略(policy)和 sidecar 注入模板(template)。
策略(policy)
其次,部署Sidecar注入的Webhook,如下所示:
mutatingwebhook.yaml:
apiVersion: admissionregistration.k8s.io/v1beta1
kind: MutatingWebhookConfiguration
metadata:
name: istio-sidecar-injector
namespace: {{ .Release.Namespace }}
labels:
app: istio-sidecar-injector
chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
webhooks:
- name: sidecar-injector.istio.io
clientConfig:
service:
name: istio-sidecar-injector
namespace: {{ .Release.Namespace }}
path: "/inject"
caBundle: ""
rules:
- operations: [ "CREATE" ]
apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]
failurePolicy: Fail
namespaceSelector:
{{- if .Values.enableNamespacesByDefault }}
matchExpressions:
- key: istio-injection
operator: NotIn
values:
- disabled
{{- else }}
matchLabels:
istio-injection: enabled
{{- end }}
注意的是,如果enableNamespacesByDefault设置为true时,会根据命名空间选择器的匹配规则来决定是否默认启用Sidecar自动注入,即istio-injection不为disabled;反之,如果enableNamespacesByDefault设置为false时,只有命令空间中设置了标签istio-injection并且值为enabled,才会启用Sidecar自动注入。
可以查看部署好的istio-sidecar-injector容器:
其对应的deployment.yaml如下:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: istio-sidecar-injector
namespace: {{ .Release.Namespace }}
labels:
app: {{ template "sidecar-injector.name" . }}
chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
istio: sidecar-injector
spec:
replicas: {{ .Values.replicaCount }}
template:
metadata:
labels:
istio: sidecar-injector
spec:
serviceAccountName: istio-sidecar-injector-service-account
containers:
- name: sidecar-injector-webhook
image: "{{ .Values.global.hub }}/{{ .Values.image }}:{{ .Values.global.tag }}"
imagePullPolicy: {{ .Values.global.imagePullPolicy }}
args:
- --caCertFile=/etc/istio/certs/root-cert.pem
- --tlsCertFile=/etc/istio/certs/cert-chain.pem
- --tlsKeyFile=/etc/istio/certs/key.pem
- --injectConfig=/etc/istio/inject/config
- --meshConfig=/etc/istio/config/mesh
- --healthCheckInterval=2s
- --healthCheckFile=/health
根据上述的启用Sidecar自动注入规则,enableNamespacesByDefault设置为false时,命令空间中设置了标签istio-injection并且值为enabled,才会启用Sidecar自动注入。
执行以下命令可以为命令空间default增加标签istio-injection且值设为enabled。
kubectl label namespace default istio-injection=enabled
至此,命令空间default已经支持Sidecar自动注入,运行如下命令等同于前面文章中介绍的手工注入,系统会自动注入Envoy容器作为Sidecar。
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
本文重点介绍在阿里云Kubernetes容器服务中如何启用或者禁用Sidecar自动注入,并分析自动注入Sidecar的原理机制。使用该自动注入能力,可以简化部署应用的逻辑。同时,阿里云Kubernetes容器服务也提供了可配置选型,让用户可以根据自己的需要配置是否启用该能力。
欢迎大家使用阿里云上的容器服务,快速搭建微服务的开放治理平台Istio,比较简单地集成到自己项目的微服务开发中。