当我在 GKE 中将 NodePort 服务指定为 Ingress 后端时,我得到了两个后端
When I specify NodePort service as Ingress backend in GKE, I get two backends
--概览
我在 GKE 上自定义安装了 istio (type=nodeport)。安装命令如下
istioctl install --set profile=default --set values.gateways.istio-ingressgateway.type=NodePort
我正在构建 Ingress 并将 NodePort 服务指定为后端。我发现即使我指定了 NodePort,GCP 也将另一个后端指定为默认设置。因此,我无法通过 TCP/IP 连接到 GCP LoadBalancer。如果我将相同的端口设置为 pod 的 readinessprobe 入口等,健康检查也会在那里。
有什么办法可以解决吗?
--详情
- 具有两个后端的 LB 的详细视图(顶部后端服务是 GCP 中的默认配置)
Detail view of LB
- 节点端口配置
# This is a value that is automatically set by istio
$ k get svc istio-ingressgateway -n istio-system -o yaml
ports:
- name: status-port
nodePort: 32476
port: 15021
protocol: TCP
targetPort: 15021
- name: http2
nodePort: 32241
port: 80
protocol: TCP
targetPort: 8080
- name: https
nodePort: 31739
port: 443
protocol: TCP
targetPort: 8443
- name: tcp-istiod
nodePort: 32488
port: 15012
protocol: TCP
targetPort: 15012
- name: tls
nodePort: 32741
port: 15443
protocol: TCP
targetPort: 15443
- istio-ingressgateway(pod) 就绪设置
$ k get po istio-ingressgateway-6f8bbbbd8c-qmkln -n istio-system -o yaml
:
readinessProbe:
failureThreshold: 30
httpGet:
path: /healthz/ready
port: 15021
scheme: HTTP
initialDelaySeconds: 1
periodSeconds: 2
successThreshold: 1
timeoutSeconds: 1
- 入口设置
#
spec:
rules:
- host: www.custom.com
http:
paths:
- backend:
serviceName: istio-ingressgateway
servicePort: 80
- backend:
serviceName: istio-ingressgateway
servicePort: 15021
kubectl get svc
的结果
istio-system istio-ingressgateway NodePort 10.47.13.185 <none> 15021:31761/TCP,80:31561/TCP,443:31257/TCP,15012:31841/TCP,15443:32172/TCP 9h
我把这个答案分为几部分:
- 使用
GKE
创建 Ingress
资源时的两个后端。
- 问题中的入口定义。
- 将
Cloud
装甲与 Istio
整合。
使用 GKE
创建 Ingress
资源时的两个后端
这是按预期工作的,因为使用 GKE
创建的 Ingress
将有 2 个后端:
YAML
清单中指定的。
- 默认后端:
default-http-backend
。
例如,您可以按照以下步骤操作:
$ kubectl create deployment nginx --image=nginx
$ kubectl expose deployment nginx --port=80 --type=NodePort
- 为
nginx
创建一个 Ingress
资源,但具有 hello
路径(用于示例目的)
之后您应该会看到类似的设置:
第一个后端服务正在使用实例组将请求发送到与 Ingress
资源不匹配的默认后端。
第二个后端服务正在使用 NEG(网络端点组)发送与 Ingress
资源匹配的请求(在本例中为 nginx
Deployment
)。
我已将红色方块标记为将其与 Kubernetes 资源“连接”(查看端口):
$ kubectl get svc nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx NodePort 10.20.6.229 <none> 80:32612/TCP 51m
$ kubectl get svc -n kube-system default-http-backend
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default-http-backend NodePort 10.20.15.39 <none> 80:30603/TCP 121m
问题中的入口定义
问题 is/was 中包含的 Ingress
定义部分以引用具有 2 个不同后端的相同路径的方式创建:
http:
paths:
- backend:
serviceName: istio-ingressgateway
servicePort: 80
- backend:
serviceName: istio-ingressgateway
servicePort: 15021
上面的例子:
- 有 2 个不同的后端。
- 配置为2个不同的后端共享相同的路径。
- 请求(如我所复制的那样)进入“
15021
”后端,仅用于健康检查。
要解决这个问题,您需要删除 15021
后端并使用 backendConfig
资源来配置健康检查和安全策略(稍后会详细介绍)。
A side note!
The YAML
manifest is using and old and soon to be deprecated way to describe Ingress
. Please refer to this documentation for more reference:
将 Cloud Armor 与 Istio 集成
您可以通过以下方式将 Cloud Armor 与 Istio 结合使用:
- 创建安全策略。
- 创建
backendConfig
作为 Istio Service
的先决条件。
- 安装 Istio 并修改其
Service
。
- 创建
Ingress
资源以指向 istio-ingressgateway
。
- 用例子测试。
创建安全策略
出于示例目的,可以创建仅阻止单个 IP 地址的安全策略。可以通过 gcloud
或 Cloud Console
(Web UI):
让我们假设创建了名为 deny-single
的安全策略来阻止单个 IP 地址。
创建 backendConfig
作为 Istio Service
的先决条件。
您将需要创建一个 backendConfig
来配置运行状况检查并强制执行安全策略:
apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
name: ingress-backendconfig
namespace: istio-system
spec:
healthCheck:
requestPath: /healthz/ready
port: 15021
type: HTTP
securityPolicy:
name: deny-single # <-- IMPORTANT
安装 Istio 并修改其 Service
您需要在 istio-ingressgateway
的 Service
中添加以下注释 :
cloud.google.com/backend-config: '{"default": "ingress-backendconfig"}'
cloud.google.com/neg: '{"ingress":true}'
此注释将通知 GCP
要应用的安全策略以及将流量传递到 istio-ingressgateway
所需的健康检查。
创建一个 Ingress
资源指向 istio-ingressgateway
将请求从 HTTP(S) Load Balancer
发送到 istio-ingressgateway
的基本 Ingress
定义如下:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: istio-ingress
namespace: istio-system
spec:
rules:
- http:
paths:
- path: /*
pathType: ImplementationSpecific
backend:
service:
name: istio-ingressgateway
port:
number: 80
用例子测试
要检查设置是否正常工作,您可以生成 Bookinfo Application。
使用 2 个不同的 IP 地址进行测试:
$ curl ifconfig.me
217.AAA.BBB.CCC
$ curl 34.XXX.YYY.ZZZ/productpage
<!doctype html><meta charset="utf-8"><meta name=viewport content="width=device-width, initial-scale=1"><title>403</title>403 Forbidden%
$ curl ifconfig.me
94.EEE.FFF.GGG
$ curl 34.XXX.YYY.ZZZ/productpage
<html>
<head>
<title>Simple Bookstore App</title>
<-- REDACTED -->
A side note!
The "closed port" that you've received could be related to the fact that istio-ingressgateway
was configured to listen on specific path like /productpage
and not /
. (if the request was specifically targeted to port 80
instead of 15021
)
其他资源:
--概览
我在 GKE 上自定义安装了 istio (type=nodeport)。安装命令如下
istioctl install --set profile=default --set values.gateways.istio-ingressgateway.type=NodePort
我正在构建 Ingress 并将 NodePort 服务指定为后端。我发现即使我指定了 NodePort,GCP 也将另一个后端指定为默认设置。因此,我无法通过 TCP/IP 连接到 GCP LoadBalancer。如果我将相同的端口设置为 pod 的 readinessprobe 入口等,健康检查也会在那里。 有什么办法可以解决吗?
--详情
- 具有两个后端的 LB 的详细视图(顶部后端服务是 GCP 中的默认配置)
Detail view of LB
- 节点端口配置
# This is a value that is automatically set by istio
$ k get svc istio-ingressgateway -n istio-system -o yaml
ports:
- name: status-port
nodePort: 32476
port: 15021
protocol: TCP
targetPort: 15021
- name: http2
nodePort: 32241
port: 80
protocol: TCP
targetPort: 8080
- name: https
nodePort: 31739
port: 443
protocol: TCP
targetPort: 8443
- name: tcp-istiod
nodePort: 32488
port: 15012
protocol: TCP
targetPort: 15012
- name: tls
nodePort: 32741
port: 15443
protocol: TCP
targetPort: 15443
- istio-ingressgateway(pod) 就绪设置
$ k get po istio-ingressgateway-6f8bbbbd8c-qmkln -n istio-system -o yaml
:
readinessProbe:
failureThreshold: 30
httpGet:
path: /healthz/ready
port: 15021
scheme: HTTP
initialDelaySeconds: 1
periodSeconds: 2
successThreshold: 1
timeoutSeconds: 1
- 入口设置
#
spec:
rules:
- host: www.custom.com
http:
paths:
- backend:
serviceName: istio-ingressgateway
servicePort: 80
- backend:
serviceName: istio-ingressgateway
servicePort: 15021
kubectl get svc
的结果
istio-system istio-ingressgateway NodePort 10.47.13.185 <none> 15021:31761/TCP,80:31561/TCP,443:31257/TCP,15012:31841/TCP,15443:32172/TCP 9h
我把这个答案分为几部分:
- 使用
GKE
创建Ingress
资源时的两个后端。 - 问题中的入口定义。
- 将
Cloud
装甲与Istio
整合。
使用 GKE
创建 Ingress
资源时的两个后端
这是按预期工作的,因为使用 GKE
创建的 Ingress
将有 2 个后端:
YAML
清单中指定的。- 默认后端:
default-http-backend
。
例如,您可以按照以下步骤操作:
$ kubectl create deployment nginx --image=nginx
$ kubectl expose deployment nginx --port=80 --type=NodePort
- 为
nginx
创建一个Ingress
资源,但具有hello
路径(用于示例目的)
之后您应该会看到类似的设置:
第一个后端服务正在使用实例组将请求发送到与 Ingress
资源不匹配的默认后端。
第二个后端服务正在使用 NEG(网络端点组)发送与 Ingress
资源匹配的请求(在本例中为 nginx
Deployment
)。
我已将红色方块标记为将其与 Kubernetes 资源“连接”(查看端口):
$ kubectl get svc nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx NodePort 10.20.6.229 <none> 80:32612/TCP 51m
$ kubectl get svc -n kube-system default-http-backend
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default-http-backend NodePort 10.20.15.39 <none> 80:30603/TCP 121m
问题中的入口定义
问题 is/was 中包含的 Ingress
定义部分以引用具有 2 个不同后端的相同路径的方式创建:
http:
paths:
- backend:
serviceName: istio-ingressgateway
servicePort: 80
- backend:
serviceName: istio-ingressgateway
servicePort: 15021
上面的例子:
- 有 2 个不同的后端。
- 配置为2个不同的后端共享相同的路径。
- 请求(如我所复制的那样)进入“
15021
”后端,仅用于健康检查。
要解决这个问题,您需要删除 15021
后端并使用 backendConfig
资源来配置健康检查和安全策略(稍后会详细介绍)。
A side note!
The
YAML
manifest is using and old and soon to be deprecated way to describeIngress
. Please refer to this documentation for more reference:
将 Cloud Armor 与 Istio 集成
您可以通过以下方式将 Cloud Armor 与 Istio 结合使用:
- 创建安全策略。
- 创建
backendConfig
作为 IstioService
的先决条件。 - 安装 Istio 并修改其
Service
。 - 创建
Ingress
资源以指向istio-ingressgateway
。 - 用例子测试。
创建安全策略
出于示例目的,可以创建仅阻止单个 IP 地址的安全策略。可以通过 gcloud
或 Cloud Console
(Web UI):
让我们假设创建了名为 deny-single
的安全策略来阻止单个 IP 地址。
创建 backendConfig
作为 Istio Service
的先决条件。
您将需要创建一个 backendConfig
来配置运行状况检查并强制执行安全策略:
apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
name: ingress-backendconfig
namespace: istio-system
spec:
healthCheck:
requestPath: /healthz/ready
port: 15021
type: HTTP
securityPolicy:
name: deny-single # <-- IMPORTANT
安装 Istio 并修改其 Service
您需要在 istio-ingressgateway
的 Service
中添加以下注释 :
cloud.google.com/backend-config: '{"default": "ingress-backendconfig"}'
cloud.google.com/neg: '{"ingress":true}'
此注释将通知 GCP
要应用的安全策略以及将流量传递到 istio-ingressgateway
所需的健康检查。
创建一个 Ingress
资源指向 istio-ingressgateway
将请求从 HTTP(S) Load Balancer
发送到 istio-ingressgateway
的基本 Ingress
定义如下:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: istio-ingress
namespace: istio-system
spec:
rules:
- http:
paths:
- path: /*
pathType: ImplementationSpecific
backend:
service:
name: istio-ingressgateway
port:
number: 80
用例子测试
要检查设置是否正常工作,您可以生成 Bookinfo Application。
使用 2 个不同的 IP 地址进行测试:
$ curl ifconfig.me
217.AAA.BBB.CCC
$ curl 34.XXX.YYY.ZZZ/productpage
<!doctype html><meta charset="utf-8"><meta name=viewport content="width=device-width, initial-scale=1"><title>403</title>403 Forbidden%
$ curl ifconfig.me
94.EEE.FFF.GGG
$ curl 34.XXX.YYY.ZZZ/productpage
<html>
<head>
<title>Simple Bookstore App</title>
<-- REDACTED -->
A side note!
The "closed port" that you've received could be related to the fact that
istio-ingressgateway
was configured to listen on specific path like/productpage
and not/
. (if the request was specifically targeted to port80
instead of15021
)
其他资源: