我有一个k3s(轻量级k8s)集群运行在我的树莓派上。所以,我没有使用任何云托管集群,而是在我的树莓派上使用了bear metal集群。
我已经使用此清单部署了一个应用程序:
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-world
namespace: myapp
spec:
replicas: 3
selector:
matchLabels:
app: hello-world
template:
metadata:
labels:
app: hello-world
spec:
containers:
- name: hello-world
image: bashofmann/rancher-demo:1.0.0
imagePullPolicy: Always
resources:
requests:
cpu: 200m
ports:
- containerPort: 8080
name: web
protocol: TCP
我还创建了一个服务来将流量转发到应用程序pod。
apiVersion: v1
kind: Service
metadata:
name: demo-app-svc
namespace: myapp
spec:
selector:
app: hello-world
ports:
- name: web
protocol: TCP
port: 31113
targetPort: 8080
然后,我为路由规则创建了一个入口:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-ing
namespace: myapp
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: myapp.com
http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: demo-app-svc
port:
number: 31113
我成功地将上面的应用程序pod、服务和入口部署到我的k3s集群中。就像清单显示的那样,它们位于命名空间myapp
下。
接下来我想做的是部署Kubernetes Nginx Ingress Controller,以便集群外的客户端能够访问部署的应用程序。
因此,我通过以下方式部署它:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.2/deploy/static/provider/cloud/deploy.yaml
上述命令成功地将入口控制器部署在名称空间ingress-nginx
下,并使用命令k get all -n ingress-nginx
部署其他对象,如下所示:
如上图所示,LoadBalancer
类型service
的外部IP的值为<pending>
,因此,集群外的客户端仍然无法访问应用程序pod。
为什么会这样?在bear metal机器上部署Nginx入口控制器会错过什么?目标是有一个外部IP,可以用于从外部集群访问应用程序Pod,我该如何实现?
1条答案
按热度按时间vdgimpew1#
我不是K3SMaven,但我想我找到了一份文档,可以解决您的问题。
看一看:
服务负载平衡器
任何服务负载平衡器(LB)都可以在K3s群集中使用。默认情况下,K3s提供使用可用主机端口的负载平衡器ServiceLB(以前称为Klipper Load Balancer)。
上游Kubernetes允许创建LoadBalancer类型的服务,但不包括默认负载平衡器实现,因此在安装负载平衡器之前,这些服务将保持
pending
。许多托管服务需要云提供商(如Amazon EC2或Microsoft Azure)来提供外部负载平衡器实现。相比之下,K3s ServiceLB使您可以在没有云提供商或任何其他配置的情况下使用LoadBalancer服务。服务LB的工作原理
ServiceLB控制器监视Kubernetes Services,并将
spec.type
字段设置为LoadBalancer
。对于每个LoadBalancer服务,将在
kube-system
命名空间中创建DaemonSet。此DaemonSet进而在每个节点上创建前缀为svc-
的Pod。这些Pod使用iptables将流量从Pod的NodePort转发到服务的ClusterIP地址和端口。如果ServiceLB Pod在配置了外部IP的节点上运行,则节点的外部IP将填充到服务的
status.loadBalancer.ingress
地址列表中。否则,将使用节点的内部IP。如果创建了多个LoadBalancer服务,则会为每个服务创建单独的DaemonSet。
可以在同一节点上公开多个服务,只要它们使用不同的端口。
如果您尝试创建侦听端口80的LoadBalancer Service,则ServiceLB将尝试在群集中为端口80查找空闲主机。如果没有具有该端口的主机可用,则LB将保持Pending状态。
作为一种可能的解决方案,我建议使用
Traefik
,因为它是K3S
中的默认Ingress
控制器。LoadBalancer
上的Pending
状态很可能是由该端口(Traefik
)上使用的另一个服务引起的。如果您希望继续使用
NGINX
,同一文档页解释了如何禁用Traefik
。