Mau*_*cio 8 nginx google-kubernetes-engine nginx-ingress google-cloud-armor gke-networking
我有一个 GKE 集群,它使用 Nginx Ingress Controller 作为其入口引擎。目前,当我设置 Nginx Ingress Controller 时,我定义了一项服务kind: LoadBalancer并将其指向先前在 GCP 上保留的外部静态 IP。问题是它只绑定到区域静态 IP 地址(如果我没记错的话,是 L4 负载均衡器)。我想要一个全局负载均衡器。
我知道我可以通过使用 GKE 入口控制器而不是 Nginx 入口控制器来实现这一点。但我仍然想使用 Nginx Ingress,因为它具有强大的注释功能,例如根据条件重写标头等;GKE Ingress 注释不可用的内容。
最后,有没有办法将全局负载均衡器与 nginx 入口控制器结合起来,或者将全局负载均衡器放在 Nginx 创建的 L4 负载均衡器前面?
我们需要有全局负载均衡器才能受到 Cloud Armor 的保护。
我终于成功地让 Nginx Ingress Controller 和 L7 HTTP(S) 负载均衡器一起工作。
根据@rrob 的回复和他自己的问题,我设法让它发挥作用。唯一的区别是他的解决方案将安装经典的 HTTP(S) LoadBalancer,而不是新版本,并且我还介绍了 IP 地址的创建、自签名证书以及从 HTTP 到 HTTPS 的 HTTP 代理重定向。我将在这里列出对我有用的详细步骤。
此步骤假设我们已经创建了一个VPC-native traffic routing启用的集群。
在需要HTTP(S) LoadBalancer之前,我只需应用 Nginx DOCS 页面提供的清单来安装 Nginx Ingress Controller,它将创建一个类型的服务LoadBalancer,然后自动创建一个区域 L4 LoadBalancer 。
但现在我需要有Cloud Armor和WAF,L4负载均衡器不支持它。Cloud Armor 需要 HTTPS(S) 负载均衡器才能正常工作。
为了让Nginx Ingress 控制器与新的HTTPS(S) LoadBalancer一起工作,我们需要将Nginx Ingress Controller服务type: LoadBalancer上的 改为,并向其添加NEG注释。通过此网络注释,GCP 将自动创建一个网络端点组,该组将指向在 GKE 中运行的 Nginx Ingress Controller 服务。该网络端点组将作为我们的 HTTPS 负载均衡器的后端。ClusterIPcloud.google.com/neg: '{"exposed_ports": {"80":{"name": "ingress-nginx-80-neg"}}}'
注意:使用cloud.google.com/neg注释时,GCP 将为包含带有Nginx Ingress Controller pod的节点的每个区域创建一个网络端点组。例如,如果您将 NodePool 设置为分布在us-central1-a、us-central1-b和us-central1-f上,并且每个节点中都有一个入口控制器副本,则 GCP 将创建三个网络端点组。因此,当您设置负载均衡器的后端时,您需要将它们全部添加为后端,如步骤 5 中所述。
apiVersion: v1
kind: Service
metadata:
annotations:
labels:
helm.sh/chart: ingress-nginx-4.0.15
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 1.1.1
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: controller
name: ingress-nginx-controller
namespace: ingress-nginx
annotations:
cloud.google.com/neg: '{"exposed_ports": {"80":{"name": "ingress-nginx-80-neg"}}}'
spec:
type: ClusterIP
ipFamilyPolicy: SingleStack
ipFamilies:
- IPv4
ports:
- name: http
port: 80
protocol: TCP
targetPort: http
appProtocol: http
- name: https
port: 443
protocol: TCP
targetPort: https
appProtocol: https
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/component: controller
Run Code Online (Sandbox Code Playgroud)
如果您使用 HELM 安装 Nginx Ingress Controller,则需要覆盖配置以将 NEG 注释添加到服务中。所以
values.yaml看起来像这样:
controller:
service:
type: ClusterIP
annotations:
cloud.google.com/neg: '{"exposed_ports": {"80":{"name": "ingress-nginx-80-neg"}}}'
Run Code Online (Sandbox Code Playgroud)
要安装它,请将 ingress-nginx 添加到 helm 存储库:
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
Run Code Online (Sandbox Code Playgroud)
然后安装它:
helm install -f values.yaml ingress-nginx ingress-nginx/ingress-nginx
Run Code Online (Sandbox Code Playgroud)
PROJECT_ID=<project-id>
ZONE=us-central1-a
CLUSTER_NAME=<cluster-name>
HEALTH_CHECK_NAME=nginx-ingress-controller-health-check
NETWORK_NAME=<network-name>
CERTIFICATE_NAME=self-managed-exp-<day>-<month>-<year>
GKE_NODE_METADATA=$(kubectl get nodes -o jsonpath='{.items[0].metadata}')
GKE_SAMPLE_NODE_NAME=$(echo $GKE_NODE_METADATA | jq -r .name)
GKE_SAMPLE_NODE_ZONE=$(echo $GKE_NODE_METADATA | jq -r .labels | jq -r '."topology.kubernetes.io/zone"')
NETWORK_TAGS=$(gcloud compute instances describe \
$GKE_SAMPLE_NODE_NAME --project $PROJECT_ID \
--zone=$GKE_SAMPLE_NODE_ZONE --format="value(tags.items[0])")
Run Code Online (Sandbox Code Playgroud)
必须是高级级别和全球级别
gcloud compute addresses create ${CLUSTER_NAME}-loadbalancer-ip \
--global \
--ip-version IPV4
Run Code Online (Sandbox Code Playgroud)
gcloud compute firewall-rules create ${CLUSTER_NAME}-allow-tcp-loadbalancer \
--allow tcp:80 \
--source-ranges 130.211.0.0/22,35.191.0.0/16 \
--target-tags $NETWORK_TAGS \
--network $NETWORK_NAME
Run Code Online (Sandbox Code Playgroud)
gcloud compute health-checks create http ${CLUSTER_NAME}-nginx-health-check \
--port 80 \
--check-interval 60 \
--unhealthy-threshold 3 \
--healthy-threshold 1 \
--timeout 5 \
--request-path /healthz
Run Code Online (Sandbox Code Playgroud)
gcloud compute backend-services create ${CLUSTER_NAME}-backend-service \
--load-balancing-scheme=EXTERNAL \
--protocol=HTTP \
--port-name=http \
--health-checks=${CLUSTER_NAME}-nginx-health-check \
--global
Run Code Online (Sandbox Code Playgroud)
如前所述,将为包含 Nginx Ingress Controller Pod 的每个区域创建一个网络端点组。所以我的设置的当前布局是:
a. **Node Pool** configured to span across **us-central1-a** and **us-central1-c**.
b. **Nginx Ingress Controller** configured to have 4 replicas.
c. **Node 1** in **us-central1-a** will have 2 replicas.
d. **Node 2** in **us-central1-c** will have 2 replicas.
e. GCP generated two Network Endpoint Groups. One for **us-central1-a** and other for **us-central1-c**.
Run Code Online (Sandbox Code Playgroud)
因此,对于下面的示例,我为每个区域绑定两个 NEG,作为负载均衡器的后端服务。
# us-central1-a
gcloud compute backend-services add-backend ${CLUSTER_NAME}-backend-service \
--network-endpoint-group=ingress-nginx-80-neg \
--network-endpoint-group-zone=us-central1-a \
--balancing-mode=RATE \
--capacity-scaler=1.0 \
--max-rate-per-endpoint=100 \
--global
# us-central1-c
gcloud compute backend-services add-backend ${CLUSTER_NAME}-backend-service \
--network-endpoint-group=ingress-nginx-80-neg \
--network-endpoint-group-zone=us-central1-c \
--balancing-mode=RATE \
--capacity-scaler=1.0 \
--max-rate-per-endpoint=100 \
--global
Run Code Online (Sandbox Code Playgroud)
gcloud compute url-maps create ${CLUSTER_NAME}-loadbalancer \
--default-service ${CLUSTER_NAME}-backend-service
Run Code Online (Sandbox Code Playgroud)
gcloud compute ssl-certificates create $CERTIFICATE_NAME \
--certificate=my-cert.pem \
--private-key=my-privkey.pem \
--global
Run Code Online (Sandbox Code Playgroud)
要创建 LoadBalancer 前端,请在控制台上输入 Loadbalancer,然后单击“编辑”。
前端配置选项卡将不完整。去那里
点击“添加前端IP和端口”
为其命名并在“协议”字段中选择“HTTPS” 。
将IP 地址从临时 IP更改为之前分配的静态 IP
选择您的证书并标记启用 HTTP 到 HTTPS 重定向(如果需要)。(我做到了)
保存负载均衡器。进入 LoadBalancer 页面时,我们应该看到我们的 nginx 实例健康且绿色。就我而言,我已将 Nginx Ingress Controller 设置为具有 4 个副本:

最后,我们只需将我们的域指向 LoadBalancer IP 并创建我们的 Ingress 文件。
注意:Ingress 现在不会处理证书。该证书现在将由 LoadBalancer 在外部进行管理。所以 Ingress 不会有tls定义:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/upstream-fail-timeout: "1200"
nginx.ingress.kubernetes.io/configuration-snippet: |
set $http_origin "${scheme}://${host}";
more_set_headers "server: hide";
more_set_headers "X-Content-Type-Options: nosniff";
more_set_headers "Referrer-Policy: strict-origin";
name: ingress-nginx
namespace: prod
spec:
rules:
- host: app.mydomain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend
port:
number: 80
Run Code Online (Sandbox Code Playgroud)