安装部署
安装部署
本文仅涉及将 istio 部署于 kubernetes .
按照目前的 kubernetes 服务部署方式,istio 可以通过一下几个方式部署:
- helm,这是 istio 的主要部署方式。
- istio operator,通过 kubernetes 的 operator 模式进行 istio 部署,这个方式使用起来最便捷。而实际上 operator 也是调用的 helm 进行部署和修改的。
- istioctl,istioctl 是 istio 的命令行工具,可以通过它控制 istio 上的各种配置。而实际上 istioctl 也是调用的 helm 进行部署的。
本文主要介绍使用 operator 方式部署。
建议直接看官方文档: istio/install
版本检查
istio 依赖 kubernetes 功能,需要按照当前的 k8s 版本选择适合的 istio 版本。参考 Support status of Istio releases
只要不是过于老旧的 k8s 集群,处于Supported versions内的都可以直接使用最新版本 istio
安装 istio operator
istio operator 可以通过两个方式安装
helm install
istioctl operator init
,后面也是 helm 调用。(推荐)
安装 istioctl
curl -L https://istio.io/downloadIstio | sh -
实际使用的脚本为istio/istio/downloadIstioCandidate.sh 可以选择安装 istioctl 并使用 istioctl 相关命令来配置 istio 部署,也可以使用在集群中安装 istio operator 的方式来配置 istio 部署。
istioctl operator init
对于 docker.io 拉取镜像失败的场景可以指定其他镜像仓库
istioctl operator init --hub example.com/istio
istioctl 还有许多可调参数
安装 istio
在安装完成 istio-operator 后可以通过 istio-operator CR 来安装 istio。 (推荐)在 istio-system 空间中安装 istio,因其为 istio 默认空间:
对于默认安装可以直接:
kubectl apply -f - <<EOF
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
namespace: istio-system
name: default-istiocontrolplane
spec:
profile: default
EOF
对于访问 docker.io 不方便的情况可以指定其他 OCI 仓库
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
namespace: istio-system
name: default-istiocontrolplane
spec:
profile: default
hub: example.com/istio # 第三方仓库(可选)
tag: 1.11.0 #指定tag(可选),若不指定,与operator版本相同。
可配置字段参考IstioOperatorSpec
不同 profile 的区别在于默认安装的组件不同,使用默认配置即可。参考 Installation Configuration Profiles
istio operator 以及 istioctl 均使用的 helm 方式安装 istio,所有配置均会发送至 helm ,详细的配置以及默认配置参考对应 chart 的 helm value.yaml.
不同的 profile 对应不同的 helm charts 中的默认 values,参考manifests/profiles
这些所有的组件 helm chart 都在 istio repo manifests/charts 中。
集成 jaeger tracing
istio 可以与 jaeger 集成,将服务网格内的 tracing 数据发送至 jaeger 服务。与 jaeger 集成就是让每个服务网格内的 sidecar(envoy) 被配置为开启追踪并发送追踪数据至 jaeger。
官方配置参见 : Configurability
jaeger 安装参考Operator for Kubernetes
istio 使用的 zipkin 协议,对于 jaeger zipkin 参考Migrating from Zipkin
这里有一个小坑:
1.25 版本的 jaeger 默认不开启 zipkin 端口(9411),虽然其设置了环境变量 “COLLECTOR_ZIPKIN_HTTP_PORT” 但似乎没有生效。所以需要手动设置 options: {“collector.zipkin.host-port”:”9411”},以便于 istio 使用。
apiVersion: jaegertracing.io/v1
kind: Jaeger
spec:
strategy: production
collector:
options:
collector.zipkin.host-port: "9411" #指定这一个选项以开启 zipkin 9411
在 istio 中开启 tracing,主要有几个配置:
- 开启 tracing
- 配置 tracing 服务器地址
- 配置采样方式
需要在 istio-operator CR 中更新设置几个配置:
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
meshConfig:
enableTracing: true # 开启tracing
defaultConfig:
tracing:
sampling: 1.0 # 默认采样率 1%
zipkin:
address: jaeger-collector.observability:9411 # tracing 收集器地址
如果是使用 jaeger gaent 的方式,可能需要更改 tracing 服务地址。
配置 istio gateway sidecar inject
istio 网关实例配置参考: deploying-a-gateway
默认的 istio operator 没有对 istio-gateway 设置开启注入,也就无法记录网关的追踪数据。默认将 gateway 安装在了 istio-system 空间,安全起见,推荐将其移动至独立的空间。
需要更改两个配置:
- Gateway 安装的目标空间。
- Gateway 设置注入方式为 gateway 方式(区别于 sidecar 模式)。
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
components:
ingressGateways:
- name: istio-ingress
namespace: istio-ingress # gateway namespace
values:
gateways:
istio-ingressgateway:
injectionTemplate: "gateway" # enable gateway injection
1.11 新增的针对 gateway 的注入方式,不再使用 sidecar。gateway-injection istio 对 gateway 的注入方式与常规不同,无法使用 sidecar 方式注入 gateway,需要指定 injectionTemplate 为 gateway。
此时从 jaeger 界面查询即可查询到从 gateway 开始的追踪数据了。
开启 istio cni
Install Istio with the Istio CNI plugin
istio cni 解决的问题是:
由于 istio 会向 pod 注入 sidecar 和一个 initContainer,initContainer 用于改变 iptables 规则将流量导至 sidecar,这就需要要求 pod 有 NET_ADMIN
能力。
如此的 Pod 权限,可能让网络存在安全风险或者有其他的不便。
istio cni 在 Pod 生命周期的创建网络阶段就进行了这个更改,在容器运行时就不再需要 NET_ADMIN 能力了
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
components:
cni:
enabled: true # enable cni
由于 cni 插件是链式执行的,istio cni 不会与其他 cni 冲突,安装 istio cni 也不会替换已存在的 cni 插件。calico cni 下启用 istio cni 后的 cni 配置类似如下:
{
"cniVersion": "0.3.1",
"name": "k8s-pod-network",
"plugins": [
{
"type": "calico"
...
},
...
{
"kubernetes": {
"cni_bin_dir": "/opt/cni/bin",
"exclude_namespaces": ["istio-system", "kube-system"],
"kubeconfig": "/etc/cni/net.d/ZZZ-istio-cni-kubeconfig"
},
"log_level": "info",
"log_uds_address": "/var/run/istio-cni/log.sock",
"name": "istio-cni",
"type": "istio-cni"
}
]
}
安装 kiali 进行可视化
kiali 是 mesh 的可视化工具,文档上推荐通过 istio addon 方式安装。
kiali-operator也有但是没有正式的易用的文档。
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.11/samples/addons/kiali.yaml
可以使用 istioctl 进行展示access_to_the_ui
istioctl dashboard kiali
使用 istioctl 是临时方案,若要持久化,kiali 在端口 20001 监听 webui 地址,可以访问其 service.
kiali 默认部署与 istio-system 空间下,使用了名称为 kiali 的 configmap 作为配置。
其文档上没有太多关于配置的说明,默认配置参考config.go#L407
我们的部署使用了外部的 promethus 以及 jaeger 等,需要修改配置才能使 kiali 正常生效。主要涉及如下配置:
# configmap kiali
external_services:
grafana:
in_cluster_url: http://grafana.grafana:3000
prometheus:
url: http://prometheus.monitoring:9090
tracing:
in_cluster_url: http://jaeger-query.observability:16685/jaeger
与 prometheus 集成
kiali 使用了 prometheus 数据来生成 kiali graph,为了能够正确的生成这些图,需要从 prometheus 获取 envoy sidecar 的指标。即需要保证 envoy 相关指标被 primetheus 采集到。
prometheus/#configuration 提供两种方式实现。
sidecar 在注入的时候存在配置 meshConfig.enablePrometheusMerge , 其控制了 sidecar 的注入行为,如果为 true 则会将原 pod 的 prometheus 注解更换为聚合的 prometheus 注解(如下)。
kind: Pod
metadata:
annotations:
prometheus.io/path: /stats/prometheus
prometheus.io/port: "15020"
prometheus.io/scrape: "true"
一般来说有几种配置方式:
- sidecar 会为 pod 增加
prometheus.io/scrape: "true"
注解,这个注解约定为存在该注解的 pod 会被 prometheus 发现并采集。也就能够被 kiali 所使用。(目前使用了 prometheus operator 关闭了该功能) -
如果配置上没有对上述注解响应,即即使指定了注解也无法被发现。则需要主动设置采集规则customized-scraping-configurations
- job_name: "istiod" kubernetes_sd_configs: - role: endpoints namespaces: names: - istio-system relabel_configs: - source_labels: [ __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name, ] action: keep regex: istiod;http-monitoring - job_name: "envoy-stats" metrics_path: /stats/prometheus kubernetes_sd_configs: - role: pod relabel_configs: - source_labels: [__meta_kubernetes_pod_container_port_name] action: keep regex: ".*-envoy-prom"
对于使用 prometheus operator 的可以将上述配置添加至 additional-scrape-configs secret 中。 参考additional-scrape-config.md
此外,还有一些 RecordRule 可以增加至 prometheus,参考using-prometheus-for-production-scale-monitoring
与 grafana 集成
istio 可以在 grafana 生成许多 dashboard 以观察整个 istio 上的状态。
istio 在 grafana 仓库中有 7639 11829 7636 7630 7645 等几个 dashboard 可以使用,可以通过 grafana ui 进行安装。
对于使用 grafana operator 的方式,需要自行生成对应 CR。
开启 istio dns proxy
在 kubernetes istio 中的 service 使用 coredns 解析 dns。这有个弱点,无法解析 serviceentry 的域名。
作为改进,可以为 mesh 启用 DNS 代理,若 dns 能够在其缓存中找到则直接响应而无需转发至上游 dns(coredns)。
一方面,istio dns 可以在这个阶段对 serviceentry 中的 dns 做响应,另一方面,可以减少对上游 dns 的请求。
参考:dns-proxy
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
meshConfig:
defaultConfig:
proxyMetadata:
# Enable basic DNS proxying
ISTIO_META_DNS_CAPTURE: "true"
# Enable automatic address allocation, optional
ISTIO_META_DNS_AUTO_ALLOCATE: "true"
增加 sidecar egress 限制
istio 默认安装下监听所有空间下的 service 以便于网格服务之间都能够互相通信。 在集群 workload 较多的情况下,istio sidecar 中会存在集群所有的服务配置,占用的内存甚至可高达 GB 级别。
如果能够将 sidecar 中存储的配置项目缩减则可显著降低内存使用。
istio 提供了 SideCar 资源可以针对命名空间级别对 sidecar 中的服务条目进行限制。让该空间下的 sidecar 仅能访问所配置的服务。
sidecar 支持通过 ingress/egress 项目和 workloadSelector 选择需要配置的服务。
更多参考官方文档: istio/sidecar
以 book-info 为例:
apiVersion: networking.istio.io/v1beta1
kind: Sidecar
metadata:
name: default
namespace: istio-demo
spec:
egress:
- hosts:
- "./*"
这个 sidecar 限制了服务发现的范围从整个集群到了当前 namespace。减少了内存占用,但是无法跨空间 mesh 通信。 如果需要跨空间通信则需要在 sidecar egress 上增加需要访问的空间。
hosts 中的条目以 namespace/dnsName 格式
调整前后内存占用对比:
$ kubectl -n istio-demo top pod
NAME CPU(cores) MEMORY(bytes)
details-v1-6f6bc76446-4bksd 10m 327Mi
productpage-v1-69d595976-c8qkj 56m 281Mi
ratings-v1-75475c49cd-cbbnn 7m 325Mi
reviews-v1-c5f75b9d4-ngst4 67m 381Mi
reviews-v2-65dffdf654-s7kt4 50m 375Mi
reviews-v3-755bf5cf76-52bxj 9m 457Mi
$ kubectl -n istio-demo top pod --use-protocol-buffers
NAME CPU(cores) MEMORY(bytes)
details-v1-6f6bc76446-vjkrw 8m 60Mi
productpage-v1-69d595976-sk8lc 56m 98Mi
ratings-v1-75475c49cd-bv6q6 10m 50Mi
reviews-v1-c5f75b9d4-2nk52 132m 150Mi
reviews-v2-65dffdf654-mdrbv 39m 189Mi
reviews-v3-755bf5cf76-lk829 140m 192Mi
常见问题
-
无法拉取镜像
建议更换镜像源,因默认从 docker.io 拉取;
apiVersion: install.istio.io/v1alpha1 kind: IstioOperator spec: hub: gcr.io/istio # 更换源
-
无法访问 jaeger.observability:9411
istio 使用 zipkin 协议进行 tracing 数据发送,jaeger 支持该协议,但是默认 jaeger 配置未开启该功端口。 参见collectors 此外 jaeger 将在 jaeger 的端口支持 zipkin 协议,参见backwards-compatibility-with-zipkin。
-
istio gateway 没有追踪数据发送 istio gateway 默认不发送追踪数据,需要为其配置 sidecar。并建议不要将其放置在 istio-system 空间