Skip to main content

Command Palette

Search for a command to run...

Istio 小入门 —— ServiceEntry 的对外通信

Updated
3 min read

上一篇讲了一些入口流量的事情,在实际项目运行中,还有另外一类边界流量,就是出口流量,也常被称为 egress 流量。这一篇结合一点实际需求,设计一些常用场景,讲讲服务网格中对外部服务的调用过程。

这里我们需要几个服务定义,首先是用于模拟客户端服务的工作负载,这里继续使用 dustise/sleep 镜像。外部我们使用两个网站作为我们的外部服务演示,分别代表 httphttps 两种:http://httpbin.orghttps://api.jd.com/

开始之前

根据安装文档的说明完成 Istio 的部署,这里建议使用 Helm 方式。

使用的 dustise/sleep 镜像生成两个负载,使用 version 标签将负载拆分为 v1v2 两个版本。源码见文末。

$ istioctl kube-inject -f sleep.dual.yaml | kubectl apply -f -
service/sleep created
deployment.extensions/sleep-v1 created
deployment.extensions/sleep-v2 created

然后使用环境变量保存新建 Pod 名称:

export SLEEP_V1=$(kubectl get pod -l app=sleep,version=v1 -o jsonpath={.items..metadata.name})
export SLEEP_V2=$(kubectl get pod -l app=sleep,version=v2 -o jsonpath={.items..metadata.name})

创建 ServiceEntry

首先创建一个 ServiceEntry,指向 httpbin.org

apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: httpbin-ext
spec:
  hosts:
  - httpbin.org
  ports:
  - number: 80
    name: http
    protocol: HTTP
  resolution: DNS

然后给 api.jd.com 创建一个 ServiceEntry:

apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: jd-api
spec:
  hosts:
  - api.jd.com
  ports:
  - number: 443
    name: https
    protocol: HTTPS
  resolution: DNS

发起外部访问

$ kubectl exec -it $SLEEP_V1 -c sleep sh
/ # curl http://httpbin.org/ip
{
  "origin": "168.63.251.242"
}
/ # curl https://api.jd.com
<html>
...
</html>
/ # curl -v http://api.jd.com
...
< HTTP/1.1 404 Not Found
...
* Connection #0 to host api.jd.com left intact

可以看到,已经注册了的主机,可以通过对应的协议来进行访问了,但是如果协议不匹配,也会返回 404 代码。后面的内容,会选择几个常见场景进行演示。

服务质量监控

Istio 提供了很多的指标数据,对于外部服务来说,其服务端并不受控,但是还是可以从客户端获取一定的指标,来判断服务的状态。例如用下面的命令生成负载之后:

kubectl exec -it $SLEEP_V2 -c sleep -- wrk -d 10m http://httpbin.org/

可以在 Grafana 中看到如下的图形:

设置超时限制

外部应用的服务质量通常是不受调用方管理的,为了防止意外超时拖累整体应用,我们可以给外部服务设置一个超时限制,超过这一规则的调用直接中断。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: httpbin-service
spec:
  hosts:
  - httpbin.org
  http:
  - timeout: 3s
    route:
    - destination:
        host: httpbin.org

应用之后,再次进入 Pod 执行指令访问 http://httpbin.org

$ kubectl apply -f httpbin-timeout.yaml
virtualservice.networking.istio.io/httpbin-service created
$ kubectl exec -it $SLEEP_V1 -c sleep sh
/ # time curl -sSL http://httpbin.org/delay/2 >> /dev/null
real    0m 2.51s
user    0m 0.00s
sys     0m 0.00s
/ # time curl -sSL http://httpbin.org/delay/5
upstream request timeout
real    0m 3.01s
user    0m 0.00s
sys     0m 0.00s

上面的测试可以看出,第二次的延迟五秒调用已经返回了超时的结果,并且是在我们的三秒限制之内完成了调用。

使用 kubectl delete -f httpbin-timeout.yaml 删除这一定义,进行下一步。

仅允许指定源头访问

设想我们的网格中,仅有部分应用可以访问一些外部服务,这里我们借用 Istio 的故障注入功能,定义一个 abort 的注入,只允许 sleep:v2 访问 http://httpbin.org,其他服务的访问尝试会失败。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: httpbin-service
spec:
  hosts:
  - httpbin.org
  http:
  - match:
    - sourceLabels:
        app: sleep
        version: v2
    route:
    - destination:
        host: httpbin.org
  - route:
    - destination:
        host: httpbin.org
    fault:
      abort:
        percent: 100
        httpStatus: 403

上面的定义中,我们首先让 sleep:v2 的筛选条件的请求,转发给 httpbin.org;而其余流量,则会被注入一个 403 错误。

我们分别从 sleep:v1sleep:v2 服务发起对 httpbin.org 的访问:

$ kubectl exec  $SLEEP_V2 -c sleep -- curl -s http://httpbin.org/ip
{
  "origin": "168.63.251.242"
}
$ kubectl exec  $SLEEP_V1 -c sleep -- curl -s -v http://httpbin.org/ip
*   Trying 52.72.80.190...
...
< HTTP/1.1 403 Forbidden
< content-length: 18
< content-type: text/plain
< date: Wed, 22 Aug 2018 06:20:04 GMT
< server: envoy
<
{ [18 bytes data]
* Connection #0 to host httpbin.org left intact
fault filter abort%

可以看到,结果和我们的预测是一致的。

To be continued

上面所述,只是针对 ServiceEntry 的一些粗浅应用,Istio 还提供了 Egress Gateway 这样的高级组件。可以提供更多管理能力,敬请期待。

相关链接

  1. 安装文档https://istio.io/zh/docs/setup/kubernetes/

  2. RBAChttps://istio.io/zh/docs/tasks/security/role-based-access-control/

  3. 基于 Mixer Adaptor 的访问控制https://istio.io/zh/docs/tasks/policy-enforcement/denial-and-list/

部分源码

sleep.yaml

apiVersion: v1
kind: Service
metadata:
  name: sleep
  labels:
    app: sleep
spec:
  selector:
    app: sleep
  ports:
    - name: ssh
      port: 80
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: sleep-v1
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: sleep
        version: v1
    spec:
      containers:
      - name: sleep
        image: dustise/sleep:v0.5
        imagePullPolicy: IfNotPresent
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: sleep-v2
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: sleep
        version: v2
    spec:
      containers:
      - name: sleep
        image: dustise/sleep:v0.5
        imagePullPolicy: IfNotPresent

More from this blog

龙虾恐慌:AIOps 又要改名了?

ChatGPT 开始,把 AI 拉近到普罗大众的面前,让无数人感受到 AI 的亲民魅力。而龙虾,则把大模型驱动的自动化能力,突然间变得水灵灵、活泼泼地走进千家万户。它不只是“风口上的猪”,而是风口本身。热度高到让 Mac mini 一度断货,不知道这在不在库克的预料之内。 每代人都有每代人的鸡蛋,春节期间,我就领了我的鸡蛋。翻出古老的 MacBook Air M1,充值各种大模型。当然了,这个工具

Mar 9, 20261 min read

再见 2025

我猜不少人以为这个号废了吧?并没有,只是今年变化有点大,一直有种抄起键盘,无从说起的感觉,所以一直偷懒到今天,2025 的最后一天。 今年是我的第四个本命年,去年末一期播客里,大内说本命年不是灾年,是变化年,有危也有机。可是讲真啊,只看到危,没看到机。 各种因缘际会,从鹅厂跳槽到前东家,已经接近四年,第一个合同期已经进入尾声。除了前两年还在云原生领域嗷嗷叫,后两年基本都是些鸡零狗碎的东西了,用老东家的术语说是——偏离主航道,可谓是前景暗淡了。 一旦确定要滚蛋,反倒心思轻松起来,每天骑着我的小红车...

Jan 5, 20261 min read

辅助编程?dora 说:我知道你很急可是请你别急

从 OpenGPT 把大模型的火烧旺了之后,这三年来,相信很多组织或摩拳擦掌、或躬身入局,希望借助聪明能干的大模型,或想偿还技术宅,或想降本增效,或想弯道超车。一时间,沉寂许久的 AIxx 又活过来了,LLM Ops、Vibe Coding、中医大模型、GPT 算命等等,全都老树发新芽,焕发了勃勃生机。那么视角拉回从业者最关注的饭碗相关的领域之一——AI 辅助开发,产生了什么触动,应该如何拥抱呢? DORA 的年度报告中给出了很有意思的结论——强者恒强。 执行摘要部分总结了几个有趣的点: 问题...

Oct 6, 20251 min read

[译]dora:ai 辅助软件开发状态报告

执行摘要 在 2025 年,科技领导者面临的核心问题已不再是“是否要采用 AI”,而是“如何实现其价值”。 DORA 的研究基于超过 100 小时的定性访谈和来自全球近 5,000 名技术专业人士的问卷调查。研究揭示了一个关键事实:AI 在软件开发中的主要角色是“放大器”。它会放大高效能组织的优势,也会凸显组织的缺陷。 关键结论:AI 是放大器 AI 投资的最大回报并非来自工具本身,而是来自组织底层系统的战略性建设: 高质量的内部平台 清晰的工作流 团队的协同能力 缺少这些基础,AI ...

Oct 2, 202514 min read

僭越了,有人在用 Rust 写 Kubernetes

一个新语言问世,最爱做的事情之一,就是重写存量软件了。 云原生喝酒 SIG 重点扶持项目——rk8s(https://github.com/rk8s-dev/rk8s) 也可以归在这个范畴里,只不过这个项目重写的东西比较大,是 Kubernetes。 从 2025 年 1 月第一个 Commit 开始,到现在有了 200 多次 Commit,十几万行代码。当然距离 Kubernetes 的几百万行代码还差得远——老马就是喜欢整这种大无畏项目。 另外该项目也是国内第一个脱离 Cargo 转向使用 ...

Sep 27, 20253 min read

【伪】架构师

342 posts