我正在尝试学习有关 istio 的基础知识,所以我浏览了这里的官方文档以创建 80/20 金丝雀部署,我也遵循了 digitalocean 的本指南,它解释了一个简单的部署 https://www.digitalocean.com/community/tutorials/how-to-do-canary-deployments-with-istio-and-kubernetes 非常容易。
我在主页上创建了一个包含 2 条不同消息的简单应用程序,然后创建了虚拟服务、网关和目标规则。我(如指南中所述)获取带有kubectl -n istio-system get svc
的外部 ip,并尝试导航到该地址,但出现 503 错误。这看起来很简单,但我必须错过一些东西。这些是我的 3 个文件(据我了解没有更多必要的文件):
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
namespace: istio
name: flask-gateway
spec:
selector:
istio: ingressgateway
servers:
- hosts:
- "*"
port:
name: http
number: 80
protocol: HTTP
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: flask-app
namespace: istio
spec:
hosts:
- "*"
gateways:
- flask-gateway
http:
- route:
- destination:
host: flask-app
subset: v1
weight: 80
- destination:
host: flask-app
subset: v2
weight: 20
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: flask-app
namespace: istio
spec:
host: flask-app
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
下面是具有适用于 v1 和 v2 的部署和服务的 yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
version: v1
name: flask-deployment-v1
namespace: istio
spec:
replicas: 1
selector:
matchLabels:
app: flask-app
template:
metadata:
labels:
version: v1
app: flask-app
spec:
containers:
- name: flask-app
image: latalavera/flask-app:1.3
ports:
- containerPort: 5000
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 250m
memory: 256Mi
---
apiVersion: v1
kind: Service
metadata:
name: flask-service
namespace: istio
spec:
selector:
app: flask-app
ports:
- port: 5000
protocol: TCP
targetPort: 5000
type: ClusterIP
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
version: v2
name: flask-deployment-v2
namespace: istio
spec:
replicas: 1
selector:
matchLabels:
app: flask-app
template:
metadata:
labels:
app: flask-app
version: v2
spec:
containers:
- name: flask-app
image: latalavera/flask-app:2.0
ports:
- containerPort: 5000
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 250m
memory: 256Mi
---
apiVersion: v1
kind: Service
metadata:
name: flask-service2
namespace: istio
spec:
selector:
app: flask-app
ports:
- port: 5000
protocol: TCP
targetPort: 5000
type: ClusterIP
我已将标签version: v1
和version: v2
添加到我的部署中,并且我还使用了kubectl label ns istio istio-injection=enabled
命令,但它们无论如何都不起作用
您将服务命名为flask-service
并将VirtualService
中的host
设置为flask-app
。
host
字段不是选择器,而是要将流量路由到的服务FQDN
。所以它应该被称为flask-service
或更好的flask-service.istio.svc.cluster.local
:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: flask-app
namespace: istio
spec:
hosts:
- "*"
gateways:
- flask-gateway
http:
- route:
- destination:
host: flask-service.istio.svc.cluster.local
subset: v1
weight: 80
- destination:
host: flask-service.istio.svc.cluster.local
subset: v2
weight: 20
或者,您可以像Deployment
一样调用服务flask-app
。但无论如何都建议使用完整的FQDN
<service-name>.<namespace-name>.svc.cluster.local
。从文档中:
Kubernetes 用户注意:当使用短名称(例如"reviews"而不是"reviews.default.svc.cluster.local")时,Istio 将根据规则的命名空间而不是服务来解释短名称。"默认"命名空间中包含主机"reviews"的规则将被解释为"reviews.default.svc.cluster.local",而不考虑与评论服务关联的实际命名空间。为避免潜在的错误配置,建议始终使用完全限定的域名而不是短名称。
https://istio.io/latest/docs/reference/config/networking/virtual-service/#VirtualService ->主机
顺便说一句,您不需要 2 项服务,只需一项。服务具有用于app: flask-app
的selector
,因此它可以将流量路由到 v1 和 v2。流量的路由方式由VirtualService
和DestionationRule
定义。我会重新命令删除服务flask-service2
.如果需要在网格内路由流量,请在VirtualService
中添加mesh
作为gateways
,或者为网格内部流量创建一个新流量,以访问两个版本。有关该主题的更多信息:
https://istio.io/latest/docs/reference/config/networking/virtual-service/#VirtualService -> 网关