如何使用 istio sidecar 将 redis 暴露给外部?



我在k8s 1.15.0,istio 1.4.3中使用redis,它在网络内运行良好。

但是,当我尝试使用 istio 网关和 sidecar 将其暴露给外部网络时,它失败了。

然后我删除了 istio sidecar,只是在 k8s 中启动了 redis 服务器,它工作了。

搜索后,我将目的地规则添加到配置中,但没有帮助。

那么它有什么问题呢?感谢您的任何提示!

这是我的redis.yml

apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
spec:
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: docker.io/redis:5.0.5-alpine
imagePullPolicy: IfNotPresent
ports:
- containerPort: 16379
protocol: TCP
name: redis-port
volumeMounts:
- name: redis-data
mountPath: /data
- name: redis-conf
mountPath: /etc/redis
command:
- "redis-server"
args:
- "/etc/redis/redis.conf"
- "--protected-mode"
- "no"
volumes:
- name: redis-conf
configMap:
name: redis-conf
items:
- key: redis.conf
path: redis.conf
- name: redis-data
nfs:
path: /data/redis
server: 172.16.8.34
---
apiVersion: v1
kind: Service
metadata:
name: redis-svc
labels:
app: redis-svc
spec:
type: ClusterIP
ports:
- name: redis-port
port: 16379
protocol: TCP
selector:
app: redis
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: redis-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: tcp
protocol: TCP
hosts:
- "redis.basic.svc.cluster.local"
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: redis-svc
spec:
host: redis-svc
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: redis-vs
spec:
hosts:
- "redis.basic.svc.cluster.local"
gateways:
- redis-gateway
tcp:
- route:
- destination:
host: redis-svc.basic.svc.cluster.local
port:
number: 16379

更新:

这就是我的要求

[root]# redis-cli -h redis.basic.svc.cluster.local -p 80
redis.basic.svc.cluster.local:80> get Test
Error: Protocol error, got "H" as reply type byte

在使用 istio 公开 TCP 应用程序的情况下,几乎没有需要有所不同的事情。

  1. 需要"*"hosts:,因为TCP协议仅适用于IP:PORT。L4 中没有标头。

  2. 您的VirtualService需要TCP端口matchGateWay匹配。我建议以独特的方式命名它并匹配Deployment端口名称。

  3. 我建议避免使用端口80,因为它已经在默认入口配置中使用,并且可能导致端口冲突,因此我将其更改为11337

所以你的GateWay应该看起来像这样:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: redis-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 11337
name: redis-port
protocol: TCP
hosts:
- "*"

你的VirtualService是这样的:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: redis-vs
spec:
hosts:
- "*"
gateways:
- redis-gateway
tcp:
- match:
- port: 11337
route:
- destination:
host: redis-svc
port:
number: 16379

请注意,为了清楚起见,我删除了命名空间。

然后使用以下命令将自定义端口添加到默认入口网关:

kubectl edit svc istio-ingressgateway -n istio-system

并添加以下下一个其他端口定义:

- name: redis-port
nodePort: 31402
port: 11337
protocol: TCP
targetPort: 16379

要访问暴露的应用程序,请使用 istio 网关外部 IP 和端口,我们 刚刚设置。

要获取网关外部 IP,您可以使用:

export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
redis-cli -h $INGRESS_HOST -p 11337

如果您的istio-ingressgateway未分配外部 IP,请使用您的节点 IP 地址和端口31402之一。

希望这有帮助。

谢谢苏伦的回答。

但我认为redis.basic.svc.cluster.local在 DNS 主机之外,可以通过虚拟服务匹配,并且VirtualService.host是使用完整命名空间路径路由到服务redis-svc

也许不是因为这个原因。

最新更新