使用 microk8s 从主机简单进入?
Simple ingress from host with microk8s?
我想用 MicroK8s 做两件事:
- 将主机(Ubuntu 18.04)端口 80/443 路由到 Microk8s
- 使用类似于 kubernetes.io 文档中定义的简单入口的东西
我的最终目标是创建一个位于 Ubuntu 主机上的单节点 Kubernetes 集群,然后使用入口将不同的域路由到服务内部各自的 pods。
过去几天我一直在尝试用 Microk8s 来做这件事,但我无法理解它。
到目前为止我得到的最好的方法是使用 MetalLB 创建负载平衡器。但这要求我使用本地网络上可用的免费 IP 地址,而不是主机 IP 地址。
我还启用了 default-http-backend
并尝试导出和编辑这些配置文件但没有成功。
作为示例,一旦启用入口加载项,这将在 Minikube
上运行,此示例显示群集 IP 上端口 80 的基本 Nginx 服务器映像:
# ingress-service.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-service
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
# - host: nginx.ioo
- http:
paths:
- path: /
backend:
serviceName: nginx-cluster-ip-service
servicePort: 80
# nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 1
selector:
matchLabels:
component: nginx
template:
metadata:
labels:
component: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
# nginx-cluster-ip-service
apiVersion: v1
kind: Service
metadata:
name: nginx-cluster-ip-service
spec:
type: ClusterIP
selector:
component: nginx
ports:
- port: 80
targetPort: 80
如果我对您的理解正确,您可能会看到几种方法。
一个是你已经提到的MetalLB。
MetalLB provides a network load-balancer implementation for Kubernetes clusters that do not run on a supported cloud provider, effectively allowing the usage of LoadBalancer Services within any cluster.
你可以阅读详细实现A pure software solution: MetalLB
另一种方式是Over a NodePort Service
This approach has a few other limitations one ought to be aware of:
- Source IP address
Services of type NodePort perform source address translation by default. This means the source IP of a HTTP request is always the IP address of the Kubernetes node that received the requestfrom the perspective of NGINX.
你也可以使用host network
In a setup where there is no external load balancer available but using NodePorts is not an option, one can configure ingress-nginx
Pods to use the network of the host they run on instead of a dedicated network namespace. The benefit of this approach is that the NGINX Ingress controller can bind ports 80 and 443 directly to Kubernetes nodes' network interfaces, without the extra network translation imposed by NodePort Services.
你还要记住,如果你在POD
里面编辑配置,如果Pod重启或者崩溃,它就会消失。
我希望这可以帮助您确定采用哪种方式来实现您的想法。
当使用 LoadBalancer(又名 metallb)时,几乎所有文档中都缺少一个重要步骤:
ingress-controller 需要暴露给 metallb LoadBalancer。
kubectl expose deploy nginx-deployment --port 80 --type LoadBalancer
这也可以通过 yaml 来完成,但使用 cli 更容易。
经过几天的谷歌搜索,我终于看到了这个让我大开眼界的教程视频。
语句“到目前为止我得到的最好的是使用 MetalLB 创建负载平衡器。”是错的。您必须使用入口层进行主机流量路由。
在裸机环境中,您需要配置 MetalLB 以允许从主机到 k8s 的传入连接。
首先我们需要一个测试:
curl -H "Host: nginx.ioo" http://HOST_IP
结果如何?
- 网络错误
- 错误 404 或 503
- 有效!!
如果网络错误,那么你需要 MetalLB
microk8s.enable metallb:$(curl ipinfo.io/ip)-$(curl ipinfo.io/ip)
运行再次测试
如果网络错误,那么你有问题。检查主机连接。
如果错误 404(有时是 503),那么您需要一个入口规则。
# ingress-service.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-service
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: nginx.ioo
- http:
paths:
- path: /
backend:
serviceName: nginx-cluster-ip-service
servicePort: 80
上次测试。它应该有效。
现在您可以使用入口将不同的域路由到服务内部各自的 pods。
如果您需要通过 HTTPS 和身份验证 public 公开服务,这可能会变得相当复杂,因为您需要配置 a) 入口,b) TLS 证书服务 - 即使用 Lets Encrypt,c) 身份验证代理,d) 在您的应用中实施用户授权。
如果您的 K8S 集群 运行 在没有 public IP 的服务器上,这会带来额外的复杂性,因为您需要穿透 NAT。
https://github.com/gwrun/tutorials/tree/main/k8s/pod 演示了如何使用 Kubernetes 在没有 public IP 的 microk8s 集群上安全地公开 k8s 服务 运行 作为 public 具有 OAuth 身份验证和授权的可访问 HTTPS仪表板作为示例服务。
TLDR
更新注释为kubernetes.io/ingress.class: public
为什么
对于 MicroK8s v1.21,运行
microk8s enable ingress
将在 ingress
命名空间中创建一个名为 nginx-ingress-microk8s-controller
的 DaemonSet
。
如果你检查一下,有一个标志来设置入口 class:
- args:
... omitted ...
- --ingress-class=public
... omitted ...
因此,为了在线处理大多数示例,您需要
- 删除
--ingress-class=public
参数,使其默认为 nginx
- 更新注释 将
kubernetes.io/ingress.class: nginx
设为 kubernetes.io/ingress.class: public
将 ingress.class
从 nginx
更改为 public
建议 并设置 DNS 条目(使用我的外部提供商的控制台)从 *
到我的 public IP(不是主机名)是复制 Openshift 风格 route
(又名“基于名称的虚拟主机”)的两个充分条件 microk8s
安装在金属上。
- 更多信息
尽管没有安装 MetalLB,但所有 pod 副本之间的负载平衡工作正常(从 gcr.io/google-samples/hello-app
的输出中可以看出)。由于入口控制器自动生成的自签名证书,即使 HTTPS 也可以开箱即用。
使用 Microk8s 1.21+ 时,Ingress 配置在 运行 microk8s enable ingress
:
之后应该是这样的
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: frontend-ingress
spec:
rules:
- host: staging.resplendentdata.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend-service
port:
number: 80
ingressClassName: public
要安装 nginx 使其与 ingressClass=nginx
一起使用,请使用:
#https://kubernetes.github.io/ingress-nginx/deploy/
helm upgrade --install ingress-nginx ingress-nginx \
--repo https://kubernetes.github.io/ingress-nginx \
--namespace ingress-nginx --create-namespace
我想用 MicroK8s 做两件事:
- 将主机(Ubuntu 18.04)端口 80/443 路由到 Microk8s
- 使用类似于 kubernetes.io 文档中定义的简单入口的东西
我的最终目标是创建一个位于 Ubuntu 主机上的单节点 Kubernetes 集群,然后使用入口将不同的域路由到服务内部各自的 pods。
过去几天我一直在尝试用 Microk8s 来做这件事,但我无法理解它。
到目前为止我得到的最好的方法是使用 MetalLB 创建负载平衡器。但这要求我使用本地网络上可用的免费 IP 地址,而不是主机 IP 地址。
我还启用了
default-http-backend
并尝试导出和编辑这些配置文件但没有成功。
作为示例,一旦启用入口加载项,这将在 Minikube
上运行,此示例显示群集 IP 上端口 80 的基本 Nginx 服务器映像:
# ingress-service.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-service
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
# - host: nginx.ioo
- http:
paths:
- path: /
backend:
serviceName: nginx-cluster-ip-service
servicePort: 80
# nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 1
selector:
matchLabels:
component: nginx
template:
metadata:
labels:
component: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
# nginx-cluster-ip-service
apiVersion: v1
kind: Service
metadata:
name: nginx-cluster-ip-service
spec:
type: ClusterIP
selector:
component: nginx
ports:
- port: 80
targetPort: 80
如果我对您的理解正确,您可能会看到几种方法。
一个是你已经提到的MetalLB。
MetalLB provides a network load-balancer implementation for Kubernetes clusters that do not run on a supported cloud provider, effectively allowing the usage of LoadBalancer Services within any cluster.
你可以阅读详细实现A pure software solution: MetalLB
另一种方式是Over a NodePort Service
This approach has a few other limitations one ought to be aware of:
- Source IP address
Services of type NodePort perform source address translation by default. This means the source IP of a HTTP request is always the IP address of the Kubernetes node that received the requestfrom the perspective of NGINX.
你也可以使用host network
In a setup where there is no external load balancer available but using NodePorts is not an option, one can configure
ingress-nginx
Pods to use the network of the host they run on instead of a dedicated network namespace. The benefit of this approach is that the NGINX Ingress controller can bind ports 80 and 443 directly to Kubernetes nodes' network interfaces, without the extra network translation imposed by NodePort Services.
你还要记住,如果你在POD
里面编辑配置,如果Pod重启或者崩溃,它就会消失。
我希望这可以帮助您确定采用哪种方式来实现您的想法。
当使用 LoadBalancer(又名 metallb)时,几乎所有文档中都缺少一个重要步骤:
ingress-controller 需要暴露给 metallb LoadBalancer。
kubectl expose deploy nginx-deployment --port 80 --type LoadBalancer
这也可以通过 yaml 来完成,但使用 cli 更容易。
经过几天的谷歌搜索,我终于看到了这个让我大开眼界的教程视频。
语句“到目前为止我得到的最好的是使用 MetalLB 创建负载平衡器。”是错的。您必须使用入口层进行主机流量路由。
在裸机环境中,您需要配置 MetalLB 以允许从主机到 k8s 的传入连接。
首先我们需要一个测试:
curl -H "Host: nginx.ioo" http://HOST_IP
结果如何?
- 网络错误
- 错误 404 或 503
- 有效!!
如果网络错误,那么你需要 MetalLB
microk8s.enable metallb:$(curl ipinfo.io/ip)-$(curl ipinfo.io/ip)
运行再次测试
如果网络错误,那么你有问题。检查主机连接。
如果错误 404(有时是 503),那么您需要一个入口规则。
# ingress-service.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-service
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: nginx.ioo
- http:
paths:
- path: /
backend:
serviceName: nginx-cluster-ip-service
servicePort: 80
上次测试。它应该有效。
现在您可以使用入口将不同的域路由到服务内部各自的 pods。
如果您需要通过 HTTPS 和身份验证 public 公开服务,这可能会变得相当复杂,因为您需要配置 a) 入口,b) TLS 证书服务 - 即使用 Lets Encrypt,c) 身份验证代理,d) 在您的应用中实施用户授权。
如果您的 K8S 集群 运行 在没有 public IP 的服务器上,这会带来额外的复杂性,因为您需要穿透 NAT。
https://github.com/gwrun/tutorials/tree/main/k8s/pod 演示了如何使用 Kubernetes 在没有 public IP 的 microk8s 集群上安全地公开 k8s 服务 运行 作为 public 具有 OAuth 身份验证和授权的可访问 HTTPS仪表板作为示例服务。
TLDR
更新注释为kubernetes.io/ingress.class: public
为什么
对于 MicroK8s v1.21,运行
microk8s enable ingress
将在 ingress
命名空间中创建一个名为 nginx-ingress-microk8s-controller
的 DaemonSet
。
如果你检查一下,有一个标志来设置入口 class:
- args:
... omitted ...
- --ingress-class=public
... omitted ...
因此,为了在线处理大多数示例,您需要
- 删除
--ingress-class=public
参数,使其默认为nginx
- 更新注释 将
kubernetes.io/ingress.class: nginx
设为kubernetes.io/ingress.class: public
将 ingress.class
从 nginx
更改为 public
建议 *
到我的 public IP(不是主机名)是复制 Openshift 风格 route
(又名“基于名称的虚拟主机”)的两个充分条件 microk8s
安装在金属上。
- 更多信息
尽管没有安装 MetalLB,但所有 pod 副本之间的负载平衡工作正常(从 gcr.io/google-samples/hello-app
的输出中可以看出)。由于入口控制器自动生成的自签名证书,即使 HTTPS 也可以开箱即用。
使用 Microk8s 1.21+ 时,Ingress 配置在 运行 microk8s enable ingress
:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: frontend-ingress
spec:
rules:
- host: staging.resplendentdata.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend-service
port:
number: 80
ingressClassName: public
要安装 nginx 使其与 ingressClass=nginx
一起使用,请使用:
#https://kubernetes.github.io/ingress-nginx/deploy/
helm upgrade --install ingress-nginx ingress-nginx \
--repo https://kubernetes.github.io/ingress-nginx \
--namespace ingress-nginx --create-namespace