体验 Istio (三):使用 demo 配置部署 Istio

这篇章博客作为前奏,展示k8s+istio的神奇之处以及如何使用istio,相比官方文档:1.有更多关于k8s的细节;2.引入了轻量的k8s管理工具kuboard;3.排除了部署istio后关于grafana和loki的问题;4.更加详细得介绍了istio的UI kiali。

部署istio、demo和插件

参考Getting Started文档即可,可以在文档的最下方切换为中文。虽然不想罗列太多的细节,但为了有更流畅的体验,不免产生一些与官方文档重复的内容。

部署文档中的curl命令仅仅是根据运行环境下载并解压最新的发布包,与releases页下载后手动解压一致,这里部署istio-1.20.1,能够兼容前篇博客部署的k8s-1.28,部署指定版本的命令为:

mkdir $HOME/opt
cd $HOME/opt
curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.20.1 TARGET_ARCH=x86_64 sh -

对关键目录的说明如下:

├── bin             # 包含istioctl可执行文件
├── manifests       # 部署istio时使用的chart包
│   ├── charts
│   ├── examples
│   └── profiles    # 可选的部署配置
├── samples         # demo应用和插件相关的manifest文件
└── tools           # 命令行自动补全和证书相关的makefile

可以编辑~/.bashrc文件,将其中的bin目录加入PATH中,便于使用istioctl命令。部署用到的镜像全部在docker.io仓库中,本系列第一篇中已经配置了mirror,执行安装命令:

# 在k8s中安装
istioctl install --set profile=demo -y
# 为default namespace中的pod启用自动注入,会自动注入sidecar容器作为代理
kubectl label namespace default istio-injection=enabled
# 可以看到客户端、控制平面、数据平面的版本
istioctl version

# 查看部署的deploymen
kubectl -n istio-system get deployments
# NAME                   READY   UP-TO-DATE   AVAILABLE   AGE
# istio-egressgateway    1/1     1            1           10m
# istio-ingressgateway   1/1     1            1           10m
# istiod                 1/1     1            1           11m

官方文档建议使用demo配置以进行测试,在$HOME/opt/istio-1.20.1/manifests/profiles/demo.yaml中可以看到暴露给用户的配置,不同部署配置间的差异参考Installation Configuration Profiles

然后部署demo应用:

cd $HOME/opt/istio-1.20.1
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml

# 查看pod
kubectl get pods -o wide
# NAME                             READY   STATUS    RESTARTS   AGE     IP            NODE                 NOMINATED NODE   READINESS GATES
# details-v1-698d88b-nh2tw         2/2     Running   0          2m55s   10.244.1.11   ubuntu-dev60-k8sw1   <none>           <none>
# productpage-v1-675fc69cf-qhh7c   2/2     Running   0          2m54s   10.244.1.16   ubuntu-dev60-k8sw1   <none>           <none>
# ratings-v1-6484c4d9bb-6j7m2      2/2     Running   0          2m55s   10.244.1.13   ubuntu-dev60-k8sw1   <none>           <none>
# reviews-v1-5b5d6494f4-5hfrw      2/2     Running   0          2m55s   10.244.1.12   ubuntu-dev60-k8sw1   <none>           <none>
# reviews-v2-5b667bcbf8-4jzgz      2/2     Running   0          2m54s   10.244.1.15   ubuntu-dev60-k8sw1   <none>           <none>
# reviews-v3-5b9bd44f4-tjdkk       2/2     Running   0          2m54s   10.244.1.14   ubuntu-dev60-k8sw1   <none>           <none>

当所有default namespace中的应用都处于running状态时,就完成了拥有4个服务共6个实例的微服务应用bookinfo的部署,多少有点神奇的意味。这只是一个简单的演示,所以并没有设计使用数据库来保存状态,因为有状态服务在k8s中是单独的一个概念,比无状态服务更加复杂。因为bookinfo的所有service都是cluster ip类型,所以无法被外部访问,这是正确的设计,暂且不讨论它。

打开kuboard可以很直观的看到一个业务pod中包含三个容器,除了init容器外,istio-proxy容器拦截了业务容器的流量,以实现流量治理,是istio中的数据平面组件:

在这里插入图片描述
虽然无法被外部访问,但是可以通过进入容器从而进入到k8s网络内部进行测试(首先根据标签获得容器名称,然后进入容器执行curl命令):

kubectl exec "$(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}')" -c ratings -- curl -sS productpage:9080/productpage | grep -o "<title>.*</title>"

不过kuboard中还有一个更加简单的办法,那就是直接代理容器的端口实现浏览器访问:

在这里插入图片描述
以上两种方式都只是临时手段,接下来需要使用正式的方法istio-ingressgateway来暴露服务:

kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml

这个操作并没有创建任何新的进程,它只是会把进入service istio-ingressgateway的符合指定七层特征的流量转发至productpage:9080,这些条件也是在此时创建的,可以查看以上文件的内容。现在,向外部暴露book-info应用的问题转换成了暴露istio-ingressgateway,它将作为流量进入k8s的统一入口,service istio-ingressgateway的类型为loadbalancer,这意味着它将以nodeport的方式监听主机的随机端口并映射到ingress pod端口,这里也不讨论loadbalancer类型的细节,只需要知道满足条件的情况下是可以得到一个确定的流量入口的,现在只好手动找出这个随机端口:

kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}'

现在以31449来代指得到的随机端口,针对这个端口需要注意:

  • 目前k8s有两个节点,istio和book-info的pod都工作在worker节点,但是以http://<node ip>:31449/productpage方式套用任何节点的ip都是可以访问应用的
  • netstat命令看不到31449端口,它是被iptables转发的,可以执行命令sudo iptables-save | grep 31449查看,在本系列第一篇提到过这个问题
  • 31449端口是随机的,在创建service时分配,也就是说只要没有重建这个service,下次启动集群这个端口不变

现在,多刷新几次http://<node ip>:31449/productpage链接,你会发现能够看到三种不同样式的页面,因为你的请求被随机发往了不同版本的实例。

如果以上步骤遇到问题,可以执行istioctl analyze命令做一个验证,来发现类似忘记设置自动注入sidecar之类的配置问题,具体参考使用 Istioctl Analyze 诊断配置

一切正常之后,需要安装以下插件:

  • grafana,用于可视化
  • jaeger,用于链路追踪,这是一个多合一的镜像,包含了agent、collector、query和ui,参考Quick Start - Deploying the AllInOne image
  • kiali,作为istio控制台,参考kiali
  • loki,用于日志聚合,以statefulset的方式部署,参考loki
  • prometheus-server,由于检控指标收集、聚合、查询

这里将samples/addons/prometheus.yaml 中的--storage.tsdb.retention.time值从15d修改为1d以减少存储空间占用。

执行命令kubectl apply -f samples/addons完成安装,这里如此简单就完成了可观测系统的搭建。紧接着执行命令istioctl dashboard kiali --address 0.0.0.0 --browser=false就可以完成对控制台流量的转发,从而可以通过宿主机的浏览器访问控制台:

在这里插入图片描述
这里有两个问题:

第一个问题是kiali消息报告“Could not fetch Grafana info. Turning off links to Grafana.”,执行命令kubectl -n istio-system edit configmap kiali编辑kiali的配置,在external_services:下加入:

      grafana:
        url: "http://grafana.istio-system:3000"

然后删除kiali pod,k8s自动拉起的新pod将使用更新后的配置。

第二个问题是workloads界面的loki异常,执行kubectl get pods命令可以看到loki-0处于pending状态,执行命令kubectl describe pod loki-0可以看到是因为无法绑定pvc而调度失败,执行命令kubectl get pvc可以看到对应的pvc处于pending状态,在前面提到loki是有状态应用,使用statefulset对象进行描述,这意味着loki实例调度到其他节点时必须能够访问之前存储的数据,因此这类数据不能与节点绑定,而应该是可以在不同节点访问的,现在这里的问题就是无法找到可共享的持久化数据的提供者,使用kuboard可以更加直接的看到前面提到的情况,这里也通过在kuboard界面的操作来解决这个问题。

首先在两个k8s节点上创建nfs,server位于master节点,列出基于ubuntu的搭建过程(kuboard文档搭建NFS Server是基于centos的):

# 在master节点的操作

# 安装nfs server
sudo apt install -y nfs-kernel-server
# 添加共享配置
cat <<EOF | sudo tee -a /etc/exports
/root/nfs/share0 *(insecure,rw,sync,no_root_squash,no_subtree_check)
EOF
# 启用配置
sudo mkdir -p /root/nfs/share0
sudo exportfs -r
# 验证
sudo exportfs
# /root/nfs/share0
# 在worker节点操作

# 安装nfs client
sudo apt install -y nfs-common
# 验证,查看nfs server上的共享目录,任意master网卡的ip均可
showmount -e 10.0.2.51
# 验证,client端创建的文件在server端可见
sudo mkdir -p /root/nfs/share0mount
sudo mount -t nfs 10.0.2.51:/root/nfs/share0 /root/nfs/share0mount
echo "hello nfs server" | sudo tee /root/nfs/share0mount/test.txt

nfs搭建成功后,在kuboard的集群管理-存储类-创建存储类菜单中创建nfs类型的存储类:

在这里插入图片描述
点击保存,根据页面指引即可完成安装,必须清楚这一步背后执行的操作,点击已创建条目上的“查看”按钮,在弹出窗口的最下方点击“YAML”按按钮就可以看到,一共创建了四类资源:

  • StorageClass,负责自动为pvc创建pv,pvc中必须指定sc的名字,是存储的管理方
  • Deployment,部署provisioner作为存储提供方
  • PersistentVolume,忽略,由kuboard创建,为避免某些问题
  • PersistentVolumeClaim,忽略,由kuboard创建,为避免某些问题

要删除他们时,在界面的存储条目中执行删除将删除所有资源。

有了可用的storageclass后,在存储页中编辑处于pending状态的pvc storage-loki-0的yaml文件,在spec部分添加storageClassName: share0(因为风险,k8s不建议直接更新statefulset loki中的pvc模板,但是可以根据情况删除后重新部署):

在这里插入图片描述
确定并应用之后storage-loki-0 很快就变更为bound状态,稍等loki将进入running状态,到此就解决了这个问题,再回到集群配置的存储卷页面,会发现已经自动创建了一个绑定至storage-loki-0 的pv。

此时worker节点的系统负载小于4(w节点cpu数量),kiali访问流畅,可见本系列第二篇提到的docker in docker方式具有很大的性能损耗。

istio addons部分包含的组件带有web界面,可以这样访问:

# grafana
# 访问地址:http://<node ip>:3000
# 将service中名为service的端口代理到本地的3000端口
kubectl -n istio-system port-forward --address 0.0.0.0 service/grafana 3000:service

# prometheus
# 访问地址:http://<node ip>:9090
kubectl -n istio-system port-forward --address 0.0.0.0 service/prometheus 9090:http

# jaeger
# 访问地址:http://<node ip>:5050
kubectl -n istio-system port-forward --address 0.0.0.0 service/tracing 5050:http-query

认识kiali

最后,需要认识下kiali,首先构造一些请求:

for i in $(seq 1 100); do curl -s -o /dev/null "http://127.0.0.1:31449/productpage"; done

然后就可以在graph页面下看到从trace数据得来的位于default namespace的book-info应用拓扑,可以通过选项定制拓扑:

在这里插入图片描述
也可以切换namespace查看,点击istio-ingressgateway-点击右侧traces-点击任何一条trace记录,即可显示流量路径:

在这里插入图片描述
左侧的applications(实际上是具备app、version标签的workloads)、workloads、services提供了不同的视角,显示的信息类型也有所差异,能从graph中点击相应的对象进入,以applications productpage为例:

在这里插入图片描述
在预览页中可以看到与此应用相关的workload和service,其他table:

  • traffic,显示看入站和出站流量
  • inbound metrics,显示了入站流量的关键指标,能够根据标签定制仪表盘,也能够附加追踪和趋势信息
  • outbound metrics,显示了出站流量的关键指标,与入站一致
  • traces,显示了追踪信息,在transaction和span级别通过百分位线清晰的显示了耗时水平

应用可以有多个实例,从workloads进入productpage-v1,tables中会多出:

  • log,显示了对应pod中容器的日志,能够附加span信息、搜索、更改代理的日志级别
  • envoy,显示了流量代理envoy的状态、配置、指标等

配置istio的入口在istio config,这里会显示istio相关的对象,虚拟服务、gateway等,完全通过yaml配置:

在这里插入图片描述

总结

从部署和修复问题的过程中可以看出,整套技术栈具备非常高的复杂度,而这些复杂度又成就了那些神奇的事情,到这里仅仅是完成了环境的搭建,更重要的是基于这套环境了解book-info应用部署和运行的细节以及istio如何工作,下一节将暂时抛开istio,会比较详细地介绍下book-info应用如何在k8s中部署和运行,先剥去一些istio的神秘面纱。

  • 44
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值