在没有负载均衡器的情况下在 Digital Ocean 的托管 Kubernetes 上公开端口 80
Expose port 80 on Digital Ocean's managed Kubernetes without a load balancer
我想在不使用 Digital Ocean 的负载均衡器的情况下在端口 80 上公开我的 Kubernetes Managed Digital Ocean(单节点)集群的服务。这可能吗?我该怎么做?
这本质上是一个业余爱好项目(我是从 Kubernetes 开始的),只是想保持非常低的成本。
一个NodePort Service可以为所欲为。像这样:
kind: Service
apiVersion: v1
metadata:
name: my-service
spec:
type: NodePort
selector:
app: MyApp
ports:
- protocol: TCP
nodePort: 80
targetPort: 80
这会将传入流量从节点的端口 80 重定向到您的 pod 的端口 80。在 DNS 中发布节点 IP,您就设置好了。
一般来说像这样向外界公开服务是一个非常非常糟糕的主意,因为通过所有流量到服务的单个节点都将接收到负载不平衡并成为单点故障。但是,这种考虑不适用于单节点集群,因此需要注意的是 LoadBalancer 和 Ingress 是执行您正在寻找的容错方法,NodePort 最适合这种极其特殊的情况。
您可以部署配置为使用主机网络和端口 80/443 的 Ingress。
DO 的集群防火墙默认没有打开 80/443 入站。
如果您编辑自动创建的防火墙规则 will eventually reset themselves。解决方案是创建一个单独的防火墙也指向相同的 Kubernetes 工作节点:
$ doctl compute firewall create \
--inbound-rules="protocol:tcp,ports:80,address:0.0.0.0/0,address:::/0 protocol:tcp,ports:443,address:0.0.0.0/0,address:::/0" \
--tag-names=k8s:CLUSTER_UUID \
--name=k8s-extra-mycluster
(从仪表板获取 CLUSTER_UUID
值或从 doctl kubernetes cluster list
获取 ID 列)
- 在下面创建 nginx ingress using the host network. I've included the helm chart 配置,但您也可以通过直接安装过程完成。
编辑:上面 link 中的 Helm 图表已被弃用,因此安装图表的正确方法是(as per the new docs):
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
添加和更新此存储库后
# For Helm 2
$ helm install stable/nginx-ingress --name=myingress -f myingress.values.yml
# For Helm 3
$ helm install myingress stable/nginx-ingress -f myingress.values.yml
#EDIT: The New way to install in helm 3
helm install myingress ingress-nginx/ingress-nginx -f myingress.values.yaml
myingress.values.yml
图表:
---
controller:
kind: DaemonSet
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet
daemonset:
useHostPort: true
service:
type: ClusterIP
rbac:
create: true
您应该能够通过任何工作节点 IP 访问 :80 和 :443 上的集群,它会将流量路由到您的入口。
由于节点 IP 可以并且确实会发生变化,请考虑部署 external-dns 来管理 DNS 条目以指向您的工作节点。同样,使用 helm chart 并假设您的 DNS 域由 DigitalOcean 托管(尽管任何受支持的 DNS 提供商都可以工作):
# For Helm 2
$ helm install --name=mydns -f mydns.values.yml stable/external-dns
# For Helm 3
$ helm install mydns stable/external-dns -f mydns.values.yml
mydns.values.yml
图表:
---
provider: digitalocean
digitalocean:
# create the API token at https://cloud.digitalocean.com/account/api/tokens
# needs read + write
apiToken: "DIGITALOCEAN_API_TOKEN"
domainFilters:
# domains you want external-dns to be able to edit
- example.com
rbac:
create: true
- 创建 Kubernetes Ingress resource 以将请求路由到现有的 Kubernetes 服务:
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: testing123-ingress
annotations:
kubernetes.io/ingress.class: nginx
spec:
rules:
- host: testing123.example.com # the domain you want associated
http:
paths:
- path: /
backend:
serviceName: testing123-service # existing service
servicePort: 8000 # existing service port
- 大约一分钟后,您应该会看到 DNS 记录出现并且可以解析:
$ dig testing123.example.com # should return worker IP address
$ curl -v http://testing123.example.com # should send the request through the Ingress to your backend service
(编辑:编辑自动创建的防火墙规则最终会失效,改为添加单独的防火墙)。
我想在不使用 Digital Ocean 的负载均衡器的情况下在端口 80 上公开我的 Kubernetes Managed Digital Ocean(单节点)集群的服务。这可能吗?我该怎么做?
这本质上是一个业余爱好项目(我是从 Kubernetes 开始的),只是想保持非常低的成本。
一个NodePort Service可以为所欲为。像这样:
kind: Service
apiVersion: v1
metadata:
name: my-service
spec:
type: NodePort
selector:
app: MyApp
ports:
- protocol: TCP
nodePort: 80
targetPort: 80
这会将传入流量从节点的端口 80 重定向到您的 pod 的端口 80。在 DNS 中发布节点 IP,您就设置好了。
一般来说像这样向外界公开服务是一个非常非常糟糕的主意,因为通过所有流量到服务的单个节点都将接收到负载不平衡并成为单点故障。但是,这种考虑不适用于单节点集群,因此需要注意的是 LoadBalancer 和 Ingress 是执行您正在寻找的容错方法,NodePort 最适合这种极其特殊的情况。
您可以部署配置为使用主机网络和端口 80/443 的 Ingress。
DO 的集群防火墙默认没有打开 80/443 入站。
如果您编辑自动创建的防火墙规则 will eventually reset themselves。解决方案是创建一个单独的防火墙也指向相同的 Kubernetes 工作节点:
$ doctl compute firewall create \
--inbound-rules="protocol:tcp,ports:80,address:0.0.0.0/0,address:::/0 protocol:tcp,ports:443,address:0.0.0.0/0,address:::/0" \
--tag-names=k8s:CLUSTER_UUID \
--name=k8s-extra-mycluster
(从仪表板获取 CLUSTER_UUID
值或从 doctl kubernetes cluster list
获取 ID 列)
- 在下面创建 nginx ingress using the host network. I've included the helm chart 配置,但您也可以通过直接安装过程完成。
编辑:上面 link 中的 Helm 图表已被弃用,因此安装图表的正确方法是(as per the new docs):
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
添加和更新此存储库后
# For Helm 2
$ helm install stable/nginx-ingress --name=myingress -f myingress.values.yml
# For Helm 3
$ helm install myingress stable/nginx-ingress -f myingress.values.yml
#EDIT: The New way to install in helm 3
helm install myingress ingress-nginx/ingress-nginx -f myingress.values.yaml
myingress.values.yml
图表:
---
controller:
kind: DaemonSet
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet
daemonset:
useHostPort: true
service:
type: ClusterIP
rbac:
create: true
您应该能够通过任何工作节点 IP 访问 :80 和 :443 上的集群,它会将流量路由到您的入口。
由于节点 IP 可以并且确实会发生变化,请考虑部署 external-dns 来管理 DNS 条目以指向您的工作节点。同样,使用 helm chart 并假设您的 DNS 域由 DigitalOcean 托管(尽管任何受支持的 DNS 提供商都可以工作):
# For Helm 2
$ helm install --name=mydns -f mydns.values.yml stable/external-dns
# For Helm 3
$ helm install mydns stable/external-dns -f mydns.values.yml
mydns.values.yml
图表:
---
provider: digitalocean
digitalocean:
# create the API token at https://cloud.digitalocean.com/account/api/tokens
# needs read + write
apiToken: "DIGITALOCEAN_API_TOKEN"
domainFilters:
# domains you want external-dns to be able to edit
- example.com
rbac:
create: true
- 创建 Kubernetes Ingress resource 以将请求路由到现有的 Kubernetes 服务:
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: testing123-ingress
annotations:
kubernetes.io/ingress.class: nginx
spec:
rules:
- host: testing123.example.com # the domain you want associated
http:
paths:
- path: /
backend:
serviceName: testing123-service # existing service
servicePort: 8000 # existing service port
- 大约一分钟后,您应该会看到 DNS 记录出现并且可以解析:
$ dig testing123.example.com # should return worker IP address
$ curl -v http://testing123.example.com # should send the request through the Ingress to your backend service
(编辑:编辑自动创建的防火墙规则最终会失效,改为添加单独的防火墙)。