在没有GCP负载均衡器的情况下创建kubernetes nginx ingress

时间:2017-04-03 16:12:51

标签: node.js nginx go kubernetes

所以我正在使用Kubernetes进行侧面项目,这很棒。运行一个像我正在进行的小项目更便宜(一个3-5个实例的小集群基本上给了我所需的一切,每月约30美元的GCP)。

我正在努力的唯一领域是尝试使用kubernetes Ingress资源映射到群集并扇出到我的微服务(它们是小Go或Node后端)。我有入口的配置设置映射到不同的服务,那里没有问题。

据我所知,在创建入口资源时,您可以轻松地让GCP启动LoadBalancer。这很好,但它也代表另外20美元/月,这增加了项目的成本。一旦/如果这个东西得到一些牵引力,那可以被忽略,但是现在并且为了更好地理解Kubernetes,我想做以下事情:

  • 从GCP获取静态IP,
  • 使用入口资源
  • 在同一群集中托管负载均衡器(使用nginx负载均衡器)
  • 避免支付外部负载均衡器

有没有办法甚至可以使用Kubernetes和入口资源来完成?

谢谢!

4 个答案:

答案 0 :(得分:3)

是的,这是可能的。部署入口控制器,并使用NodePort服务进行部署。例如:

---
apiVersion: v1
kind: Service
metadata:
  name: nginx-ingress-controller
  namespace: kube-system
  labels:
    k8s-app: nginx-ingress-controller
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 80
    nodePort: 32080
    protocol: TCP
    name: http
  - port: 443
    targetPort: 443
    nodePort: 32443
    protocol: TCP
    name: https
  selector:
    k8s-app: nginx-ingress-controller

现在,创建一个带有DNS条目的入口:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-ingress
spec:
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /
        backend:
          serviceName: my-app-service #obviously point this to a valid service + port
          servicePort: 80

现在,假设您的静态IP附加到运行kube-proxy的任何kubernetes节点,更新DNS以指向静态IP,您应该能够访问myapp.example.com:32080并且入口会将您映射回你的应用。

其他一些事情:

如果您想使用低于32080的端口,请记住,如果您正在使用CNI网络,you'll have trouble with hostport。它建议让负载均衡器监听端口80,我想你可能只是设置了nginx进行代理传递,但它变得很困难。这就是推荐使用云提供商的负载均衡器的原因:)

答案 1 :(得分:0)

你也可以创建一个nginx-ingress图表,让它拉出一个短暂的IP,然后将其升级为静态。这将为您留下L7单区负载均衡器。

本指南介绍了它。如果你使用kube-lego,你可以忽略TLS的东西,它与nginx-ingress一样好用

https://github.com/kubernetes/ingress-nginx/tree/master/docs/examples/static-ip

答案 2 :(得分:0)

TLDR:如果您想在3000以下的端口上提供网站/网络服务,那么不可能,这是不可能的。如果有人找到了解决方法,我很想知道

我尝试在3000以下的端口上使用时使用的两种主要方法包括:

  • 安装nginx-ingress类型为NodePort的控制器服务,侦听端口80和443。但是,这导致以下错误:
    Error: UPGRADE FAILED: Service "nginx-ingress-controller" is invalid:
    spec.ports[0].nodePort: Invalid value: 80: provided port is not in the
    valid range. The range of valid ports is 30000-32767
    
    解决此错误的方法是更改​​启动--service-node-port-range时使用的kube-apiserver标志。但是,无法在GCP上访问此配置。如果您想尝试一下,可以在这里查看说明:Kubernetes service node port range
  • 按照线程Expose port 80 and 443 on Google Container Engine without load balancer中的步骤进行操作。这依赖于使用附加到externalIP的{​​{1}}的{​​{1}}属性。乍一看,这似乎是一个理想的解决方案。但是,service属性的工作方式存在一个错误。它不接受外部静态IP,而接受内部临时IP。如果您在type: ClusterIP字段中对内部临时IP进行硬编码,然后通过GCP控制台将外部静态IP附加到群集中的一个节点,则请求将被成功路由。但是,这不是一个可行的解决方案,因为您现在已经在externalIP定义中对临时IP进行了硬编码,因此,随着节点内部IP的更改,您的网站将不可避免地离线。

如果可以在3000以上的端口上使用,请参见下面的说明。


如何卸下LoadBalancer(仅允许在端口> 3000上使用)

我尝试删除LoadBalancer,这是我能想到的最佳解决方案。它具有以下缺陷:

  • 用于访问网页的端口不是通常的80和443,因为从节点公开这些端口并非易事。我会在以后解决的。

还有以下好处:

  • 没有LoadBalancer。
  • 网站/网络服务的IP是静态的。
  • 这取决于流行的externalIP舵图。
  • 它使用service,可以根据请求的路径完全控制如何将请求路由到您的nginx-ingress

1。安装入口服务和控制器

假设您已经安装了Helm(如果您不遵循此处的步骤:Installing Helm on GKE),请创建一个ingressservices的{​​{1}}。

nginx-ingress

2。创建入口资源

为您的路由创建入口定义。

type

然后使用

安装
NodePort

3。创建防火墙规则

找到集群的标签。

helm install \
  --name nginx-ingress \
  stable/nginx-ingress \
  --set rbac.create=true \
  --set controller.publishService.enabled=true \
  --set controller.service.type=NodePort \
  --set controller.service.nodePorts.http=30080 \
  --set controller.service.nodePorts.https=30443

如果您的集群实例的名称类似于

# my-ingress-resource.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: reverse-proxy
  namespace: production # Namespace must be the same as that of target services below.
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/ssl-redirect: "false" # Set to true once SSL is set up.
spec:
  rules:
  - http:
      paths:
      - path: /api
        backend:
          serviceName: backend
          servicePort: 3000
      - path: /
        backend:
          serviceName: frontend
          servicePort: 80

然后您的群集标记为kubectl apply -f my-ingress-resource.yaml

转到the GCP firewall page验证您是否在导航栏中选择了正确的项目。

单击“创建防火墙规则”。给规则起一个体面的名字。您可以将大多数设置保留为默认设置,但是将群集标记保留在“目标标记”下。将源IP范围设置为gcloud compute instances list 。在“协议和端口”下,将“允许所有”更改为“指定的协议和端口”。选中“ TCP”框,然后在输入字段中输入gke-cluster-1-pool-1-fee097a3-n6c8 gke-cluster-1-pool-1-fee097a3-zssz 。点击“创建”。

4。创建一个静态IP

转到https://console.cloud.google.com/networking/addresses/并单击“保留静态地址”。给它起一个描述性的名称,然后选择正确的区域。选择正确的区域后,您应该能够单击“附​​加到”下拉列表,然后选择一个Kubernetes节点。点击“保留”。

5。测试配置

保留静态IP后,通过查看External IP Address list找出授予了哪个静态IP。

将其复制到浏览器中,然后添加端口(对于HTTP,gke-cluster-1-pool-1-fee097a3,对于HTTPS,0.0.0.0/0)。您应该会看到您的网页。

答案 3 :(得分:0)

original source,但它包含我从未使用过的 Digital Ocean 详细信息。老实说,它救了我一命,并且可以使用 3000 以下的端口,但老实说,我不确定它是如何工作的。

我的设置是使用这个 Nginx ingress controller. 使用 helm 安装它,并为其提供一个配置文件:

$ helm install my-nginx ingress-nginx/ingress-nginx -f config.yaml

配置文件应包含:

controller:
  kind: DaemonSet
  hostNetwork: true
  dnsPolicy: ClusterFirstWithHostNet
  daemonset:
    useHostPort: true
  service:
    type: ClusterIP
rbac:
  create: true

您可以找到默认值 here,但我不知道如何理解该配置。

之后你可以创建你的入口 yaml:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: web-app
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/proxy-body-size: "100m"
    cert-manager.io/cluster-issuer: "letsencrypt"
    nginx.ingress.kubernetes.io/server-alias: "example.com"
  labels:
    app: web-app
spec:
  tls:
    - hosts:
      - example.com
      secretName: prod-certs
  rules:
    - host: example.com
      http: 
        paths:
        - backend:
            serviceName: myservice
            servicePort: 443

这是我的,可能对你不起作用,但试试吧!

它指向的服务入口规则是NodePort类型:

apiVersion: v1
kind: Service
metadata:
  name: myservice
  labels:
    app: myservice
spec:
  type: NodePort
  ports:
  - port: 443
    targetPort: 80

但我相信 ClusterIP 也可以。

除此之外,其中一个 VM 具有公共静态 IP,我们将该 IP 用于我们的域名。

所以我相信这个过程是。域名转换为该静态 IP。然后流量到达入口控制器,我不知道这是如何工作的,但是在那里您的流量与某个规则匹配,并被重定向到服务。端口是在 Ingress 中定义的,因此您也可以使用 3000 个以下的端口,但我不知道这个“解决方案”在性能方面是如何工作的,而且我也不知道 Ingress 控制器如何接受未公开的流量。

设置 Ingress 可能是我经历过的最糟糕的经历之一,我实际上采用了这种混乱的方法,因为使用 LoadBalancer 服务类型更糟糕。祝你好运!

相关问题