4、Ingress 入口流量
Ingress 入口流量
我们知道在 Kubernetes 中我们会使用 Ingress
来暴露 HTTP 流量的入口,在 Istio 中我们是通过 Gateway
来暴露流量入口的,那么我们是否可以使用 Ingress
对象来支持 Istio 的流量入口呢?答案是肯定的,但是我们还是建议使用 Gateway
而不是 Ingress
来使用 Istio 提供的完整功能集,例如丰富的流量管理和安全功能。
k8s gateway api。
目录
[toc]
本节实战
实战名称 |
---|
🚩 实战:Kubernetes Ingress-2023.11.15(测试成功) |
🚩 实战:Ingress Gateway-2023.11.15(测试成功) |
🚩 实战:istio安全网关-2023.11.16(测试成功) |
🚩 实战:TLS 透传-2023.11.16(测试成功) |
Kubernetes Ingress
==🚩 实战:Kubernetes Ingress-2023.11.15(测试成功)==
实验环境:
k8sv1.27.6(containerd:[root@master1 ~]#istioctl versionclientversion:1.19.3controlplaneversion:1.19.3dataplaneversion:1.19.3(8 proxies)
实验软件:
链接:https:A[实战步骤] -->B(1、 部署服务端测试应用)A[实战步骤] -->C(2、 创建ingress)A[实战步骤] -->D(3、 测试)
下面我们来使用 Ingress 资源配置 Istio 的入口网关,使用 Kubernetes Ingress 可以暴露从集群外到集群内服务的 HTTP 和 HTTPS 路由。
- 这里我们部署一个
httpbin
应用,用来测试:
kubectlapply-fsamples/httpbin/httpbin.yaml
查看:
[root@master1 istio-1.19.3]#kubectl get po -l app=httpbinNAMEREADYSTATUSRESTARTSAGEhttpbin-86869bccff-7lpjx2/2Running02d14h[root@master1 istio-1.19.3]#kubectl get svcNAMETYPECLUSTER-IPEXTERNAL-IPPORT(S) AGEhttpbinClusterIP10.111.57.195<none>8000/TCP2d14h……
- 创建后我们就可以创建一个
Ingress
对象来暴露httpbin
服务了:
⚠️ ==特别注意:==
#httpbin-ingress.yamlapiVersion:networking.k8s.io/v1kind:Ingressmetadata:annotations:kubernetes.io/ingress.class:istioname:httpbinspec:rules:- host:httpbin.k8s.localhttp:paths:- path:/statuspathType:Prefixbackend:service:name:httpbinport:number:8000
可以看到这个 Ingress 对象和我们在 Kubernetes 中的使用方法没有什么区别,唯一不同的是我们这里使用了一个 kubernetes.io/ingress.class
注解来告知 Istio Ingress Gateway 它应该处理该 Ingress,否则它将被忽略。
我们应用上面的资源清单:
[root@master1 istio-1.19.3]#kubectl apply -f httpbin-ingress.yamlingress.networking.k8s.io/httpbincreatedWarning:annotation"kubernetes.io/ingress.class"isdeprecated,pleaseuse'spec.ingressClassName'instead
- 我们可以通过
kubectl get ingress
命令来查看下 Ingress 对象的状态:
$kubectlgetingressNAMECLASSHOSTSADDRESSPORTSAGEhttpbin<none>httpbin.k8s.local806s
- 然后我们可以使用
curl
来访问httpbin
服务:
# 获取 Ingress Gateway 的地址和端口exportINGRESS_PORT=$(kubectl-nistio-systemgetserviceistio-ingressgateway-ojsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')exportINGRESS_HOST=$(kubectlgetpod-listio=ingressgateway-nistio-system-ojsonpath='{.items[0].status.hostIP}')echo$INGRESS_PORTecho$INGRESS_HOST# 访问 httpbin 服务$curl-s-I-HHost:httpbin.k8s.local"http:HTTP/1.1200OKserver:istio-envoydate:Mon,13Nov202306:10:13GMTcontent-type:text/html;charset=utf-8# .......
注意使用 -H
标志将 Host
的 HTTP 头设置为 httpbin.k8s.local
, 因为 Ingress 中已经配置为处理访问该域名的请求,但是在测试环境中,该域名并没有相应的 DNS 绑定,当然我们也可以直接在 /etc/hosts
中添加一个映射(当然是istio-ingressgateway-9c8b9b586-vj44l
pod所在node节点了)。
- 访问未指定的其他 URL 时,将返回 HTTP 404 错误:
$curl-s-I-HHost:httpbin.k8s.local"http:HTTP/1.1404NotFound#......
- 注意下:自己当前istio环境
[root@master1 istio-1.19.3]#export INGRESS_PORT=$(kubectl-nistio-systemgetserviceistio-ingressgateway-ojsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')[root@master1 istio-1.19.3]#export INGRESS_HOST=$(kubectlgetpod-listio=ingressgateway-nistio-system-ojsonpath='{.items[0].status.hostIP}')[root@master1 istio-1.19.3]#echo $INGRESS_PORT31666[root@master1 istio-1.19.3]#echo $INGRESS_HOST172.29.9.63[root@master1 istio-1.19.3]#kubectl get po -owide -l istio=ingressgateway-nistio-systemNAMEREADYSTATUSRESTARTSAGEIPNODENOMINATEDNODEREADINESSGATESistio-ingressgateway-9c8b9b586-vj44l1/1Running03d6h10.244.2.15node2<none><none>[root@master1 istio-1.19.3]#kubectl get svc -nistio-systemNAMETYPECLUSTER-IPEXTERNAL-IPPORT(S) AGEistio-egressgatewayClusterIP10.109.85.119<none>80/TCP,443/TCP8distio-ingressgatewayLoadBalancer10.105.233.167<pending>15021:31410/TCP,80:31666/TCP,443:32213/TCP,31400:30291/TCP,15443:31787/TCP8distiodClusterIP10.109.185.251<none>15010/TCP,15012/TCP,443/TCP,15014/TCP8d
- 在 Kubernetes 1.18 中,添加了新资源
IngressClass
,以替换 Ingress 资源上的kubernetes.io/ingress.class
注解,我们也可以使用该资源来替换注解的方式,需要将controller
字段设置为istio.io/ingress-controller
,如下所示:
#httpbin-ingress2.yamlapiVersion:networking.k8s.io/v1kind:IngressClassmetadata:name:istiospec:controller:istio.io/ingress-controller# 指定 Ingress Controller 为 istio---apiVersion:networking.k8s.io/v1kind:Ingressmetadata:name:httpbinspec:ingressClassName:istio# 指定 IngressClass 为 istiorules:- host:httpbin.k8s.localhttp:paths:- path:/pathType:Prefixbackend:service:name:httpbinport:number:8000
上面这种方式更加简洁,而且可以避免使用注解的方式,但是需要注意的是,该资源对象只能在 Kubernetes 1.18 及以上版本中使用。
- 应用上面ingress对象
#先删除旧的ingress对象[root@master1 istio-1.19.3]#kubectl delete -f httpbin-ingress.yaml ingress.networking.k8s.io"httpbin"deleted[root@master1 istio-1.19.3]#kubectl apply -f httpbin-ingress2.yaml ingressclass.networking.k8s.io/istiocreatedingress.networking.k8s.io/ingresscreated#查看[root@master1 istio-1.19.3]#kubectl get ingressclassNAMECONTROLLERPARAMETERSAGEistioistio.io/ingress-controller<none>27s[root@master1 istio-1.19.3]#kubectl get ingressNAMECLASSHOSTSADDRESSPORTSAGEingressistiohttpbin.k8s.local8035s
- 再次测试
[root@master1 istio-1.19.3]#curl -s -I -HHost:httpbin.k8s.local "http:HTTP/1.1200OKserver:istio-envoydate:Wed,15Nov202312:51:24GMTcontent-type:text/html;charset=utf-8access-control-allow-origin:*access-control-allow-credentials:truecontent-length:0x-envoy-upstream-service-time:6[root@master1 istio-1.19.3]#curl -s -I -HHost:httpbin.k8s.local "http:HTTP/1.1200OKserver:istio-envoydate:Wed,15Nov202312:51:29GMTcontent-type:application/jsoncontent-length:597access-control-allow-origin:*access-control-allow-credentials:truex-envoy-upstream-service-time:12
符合预期,测试结束。😘
- 记得回收掉刚才创建的资源
[root@master1 istio-1.19.3]#kubectl delete -f httpbin-ingress2.yaml ingressclass.networking.k8s.io"istio"deletedingress.networking.k8s.io"ingress"deleted
此外 Ingress 还可以进行 TLS 设置,Istio 支持此功能,但是引用的 Secret 必须存在于 istio-ingressgateway
部署的命名空间(通常是 istio-system
)中。
通过 Kubernetes Ingress 我们可以将流量导入到 Istio 中,但是对于一些高级的流量管理功能,比如路由、熔断、限流等就很难实现了,所以我们还是建议使用 Istio 的 Gateway
资源来暴露流量入口。
Ingress Gateway
前面我们都是通过 Istio 提供的 Gateway
资源来暴露流量入口,与 Ingress 相比,Gateway 提供了更广泛的自定义和灵活性,并允许将 Istio 功能(例如监控和路由规则)应用于进入集群的流量。
Ingress Gateway
==🚩 实战:Ingress Gateway-2023.11.15(测试成功)==
实验环境:
k8sv1.27.6(containerd:[root@master1 ~]#istioctl versionclientversion:1.19.3controlplaneversion:1.19.3dataplaneversion:1.19.3(8 proxies)
实验软件:
链接:https:A[实战步骤] -->B(1、 部署服务端测试应用)A[实战步骤] -->C(2、 创建ingress)A[实战步骤] -->D(3、 测试)
Ingress Gateway 描述在网格边界运作的负载均衡器,用于接收传入的 HTTP/TCP 连接。它会配置暴露的端口、协议等,但与 Kubernetes Ingress 资源不同,Gateway
对象不会包括任何流量路由配置,和路由规则相关的配置需要使用 VirtualService
和 DestinationRule
资源来实现。
- 比如上面的
httpbin
应用,如果通过Gateway
对象来暴露流量入口,那么我们需要创建一个Gateway
对象,然后再创建一个VirtualService
对象来配置流量路由,内容如下所示:
#ingress-gateway.yamlapiVersion:networking.istio.io/v1alpha3kind:Gatewaymetadata:name:httpbin-gatewayspec:selector:istio:ingressgatewayservers:- port:number:80name:httpprotocol:HTTPhosts:- "httpbin.k8s.local"---apiVersion:networking.istio.io/v1alpha3kind:VirtualServicemetadata:name:httpbinspec:hosts:- "httpbin.k8s.local"gateways:- httpbin-gatewayhttp:- match:- uri:prefix:/status- uri:prefix:/delayroute:- destination:port:number:8000host:httpbin
上面的资源清单我们就通过 Gateway
对象暴露了 HTTP 流量的入口,然后通过 VirtualService
对象来配置流量路由,一共配置了两个路由规则,允许流量流向路径 /status
和 /delay
。gateways
列表指定了哪些请求允许通 httpbin-gateway
网关,所有其他外部请求均被拒绝并返回 404 响应。
- 直接应用上面的资源清单
kubectlapply-fingress-gateway.yaml
- 然后我们可以通过
curl
来访问httpbin
服务:
# 获取 Ingress Gateway 的地址和端口exportINGRESS_PORT=$(kubectl-nistio-systemgetserviceistio-ingressgateway-ojsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')exportINGRESS_HOST=$(kubectlgetpod-listio=ingressgateway-nistio-system-ojsonpath='{.items[0].status.hostIP}')# 访问 httpbin 服务$curl-s-I-HHost:httpbin.k8s.local"http:HTTP/1.1200OKserver:istio-envoydate:Mon,13Nov202306:32:58GMTcontent-type:text/html;charset=utf-8# .......$curl-s-I-HHost:httpbin.k8s.local"http:HTTP/1.1404NotFound...
测试结束。😘
- 回收刚才创建的资源
kubectldelete-fingress-gateway.yaml
当然除了这最基本的功能之外,Gateway
还支持很多其他高级功能,比如 TLS、SNI等。
安全网关
我们已经了解了如何使用 Gateway
对象来对外暴露 HTTP 服务,那么我们如何使用 TLS 或 mTLS 来暴露安全的 HTTPS 服务呢?
==🚩 实战:istio安全网关-2023.11.16(测试成功)==
实验环境:
k8sv1.27.6(containerd:[root@master1 ~]#istioctl versionclientversion:1.19.3controlplaneversion:1.19.3dataplaneversion:1.19.3(8 proxies)
实验软件: