使用 nginx-ingress 的裸机 k8s 入口
Bare-metal k8s ingress with nginx-ingress
我无法应用入口配置。
我需要通过 DNS 访问 jupyter-lab 服务
已部署到 3 节点裸机 k8s 集群
- node1.local(硕士)
- node2.local(工人)
- node3.local(工人)
Flannel 已安装为网络控制器
我已经像这样为裸机安装了 nginx ingress
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.44.0/deploy/static/provider/baremetal/deploy.yaml
部署后,jupyter-lab pod 在 node2 上,NodePort 服务从 http://node2.local:30004 正确响应(见下文)
我期待 ingress-nginx 控制器将通过其 DNS 名称公开 ClusterIP 服务......这就是我需要的,这是错误的吗?
这是 CIP 服务,用对称端口定义 8888
尽可能简单(错了吗?)
---
apiVersion: v1
kind: Service
metadata:
name: jupyter-lab-cip
namespace: default
spec:
type: ClusterIP
ports:
- port: 8888
targetPort: 8888
selector:
app: jupyter-lab
DNS名称jupyter-lab.local
解析到集群的ip地址范围,但超时无响应。 Failed to connect to jupyter-lab.local port 80: No route to host
firewall-cmd --list-all
说明每个节点都打开了80端口
这是端口 80 上集群(任何节点)的 http 入口定义。(错了吗?)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: jupyter-lab-ingress
annotations:
# nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io: /
spec:
rules:
- host: jupyter-lab.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: jupyter-lab-cip
port:
number: 80
这是部署
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: jupyter-lab-dpt
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: jupyter-lab
template:
metadata:
labels:
app: jupyter-lab
spec:
volumes:
- name: jupyter-lab-home
persistentVolumeClaim:
claimName: jupyter-lab-pvc
containers:
- name: jupyter-lab
image: docker.io/jupyter/tensorflow-notebook
ports:
- containerPort: 8888
volumeMounts:
- name: jupyter-lab-home
mountPath: /var/jupyter-lab_home
env:
- name: "JUPYTER_ENABLE_LAB"
value: "yes"
我可以通过其 NodePort http://node2:30004 成功访问 jupyter-lab,定义如下:
---
apiVersion: v1
kind: Service
metadata:
name: jupyter-lab-nodeport
namespace: default
spec:
type: NodePort
ports:
- port: 10003
targetPort: 8888
nodePort: 30004
selector:
app: jupyter-lab
如何进入我在 http://jupyter-lab.local 的 jupyter-lab ???
- 命令
kubectl get endpoints -n ingress-nginx ingress-nginx-controller-admission
returns :
ingress-nginx-controller-admission 10.244.2.4:8443 15m
我是否错误配置了端口?
我的“selector:appname”定义有误吗?
我是不是漏掉了一部分
我如何调试正在发生的事情?
其他详情
我在应用入口时收到此错误 kubectl apply -f default-ingress.yml
Error from server (InternalError): error when creating "minnimal-ingress.yml": Internal error occurred: failed calling webhook "validate.nginx.ingress.kubernetes.io": Post "https://ingress-nginx-contr
oller-admission.ingress-nginx.svc:443/networking/v1beta1/ingresses?timeout=10s": context deadline exceeded
这个命令kubectl delete validatingwebhookconfigurations --all-namespaces
删除了验证 webhook ...这样做是错误的吗?
我已经在集群中的每个节点上打开了端口 8443
入口无效,请尝试以下操作:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: jupyter-lab-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: jupyter-lab.local
http: # <- removed the -
paths:
- path: /
pathType: Prefix
backend:
service:
# name: jupyter-lab-cip
name: jupyter-lab-nodeport
port:
number: 8888
---
apiVersion: v1
kind: Service
metadata:
name: jupyter-lab-cip
namespace: default
spec:
type: ClusterIP
ports:
- port: 8888
targetPort: 8888
selector:
app: jupyter-lab
如果我没理解错的话,你正试图通过入口 nginx 代理公开 jupyternb 并使其可通过端口 80 访问。
运行 以下命令检查 nginx ingress 服务使用的节点端口:
$ kubectl get svc -n ingress-nginx ingress-nginx-controller
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller NodePort 10.96.240.73 <none> 80:30816/TCP,443:31475/TCP 3h30m
在我的例子中是端口 30816(对于 http)和 31475(对于 https)。
使用 NodePort 类型,您只能使用 30000-32767 范围内的端口(k8s 文档:https://kubernetes.io/docs/concepts/services-networking/service/#nodeport)。您可以使用 kube-apiserver 标志 --service-node-port-range
更改它,然后将其设置为例如80-32767
然后在你的 ingress-nginx-controller 服务中设置 nodePort: 80
apiVersion: v1
kind: Service
metadata:
annotations: {}
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/version: 0.44.0
helm.sh/chart: ingress-nginx-3.23.0
name: ingress-nginx-controller
namespace: ingress-nginx
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: http
nodePort: 80 # <- HERE
- name: https
port: 443
protocol: TCP
targetPort: https
nodePort: 443 # <- HERE
selector:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
type: NodePort
尽管通常不建议更改 service-node-port-range,因为如果您使用节点上已经打开的端口(例如,kubelet 在每个节点上打开的端口 10250),您可能会遇到一些问题。
更好的解决方案可能是使用 MetalLB.
编辑:
How can I get ingress to my jupyter-lab at http://jupyter-lab.local ???
假设您不需要容错解决方案,请下载 https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.44.0/deploy/static/provider/baremetal/deploy.yaml
文件并更改部署对象的 ports:
部分,如下所示:
ports:
- name: http
containerPort: 80
hostPort: 80 # <- add this line
protocol: TCP
- name: https
containerPort: 443
hostPort: 443 # <- add this line
protocol: TCP
- name: webhook
containerPort: 8443
protocol: TCP
并应用更改:
kubectl apply -f deploy.yaml
现在运行:
$ kubectl get po -n ingress-nginx ingress-nginx-controller-<HERE PLACE YOUR HASH> -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
ingress-nginx-controller-67897c9494-c7dwj 1/1 Running 0 97s 172.17.0.6 <node_name> <none> <none>
注意 NODE 列中的 。这是调度 Pod 的节点名称。现在获取此节点 IP 并将其添加到您的 /etc/hosts
文件中。
它现在应该可以工作了(去 http://jupyter-lab.local 检查它),但是这个解决方案很脆弱,如果 nginx ingress controller pod 被重新安排到其他节点,它将停止工作(并且它将保持这样直到您更改 /etc/hosts 文件中的 ip)。通常也不建议使用 hostPort:
字段,除非你有充分的理由这样做,所以不要滥用它。
如果您需要容错解决方案,请使用 MetalLB 并为 nginx 入口控制器创建 LoadBalancer 类型的服务。
我还没有测试过,但假设您正确配置了 MetalLB,以下应该可以完成工作:
kubectl delete svc -n ingress-nginx ingress-nginx-controller
kubectl expose deployment -n ingress-nginx ingress-nginx-controller --type LoadBalancer
我无法应用入口配置。
我需要通过 DNS 访问 jupyter-lab 服务
已部署到 3 节点裸机 k8s 集群
- node1.local(硕士)
- node2.local(工人)
- node3.local(工人)
Flannel 已安装为网络控制器
我已经像这样为裸机安装了 nginx ingress
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.44.0/deploy/static/provider/baremetal/deploy.yaml
部署后,jupyter-lab pod 在 node2 上,NodePort 服务从 http://node2.local:30004 正确响应(见下文)
我期待 ingress-nginx 控制器将通过其 DNS 名称公开 ClusterIP 服务......这就是我需要的,这是错误的吗?
这是 CIP 服务,用对称端口定义 8888
尽可能简单(错了吗?)
---
apiVersion: v1
kind: Service
metadata:
name: jupyter-lab-cip
namespace: default
spec:
type: ClusterIP
ports:
- port: 8888
targetPort: 8888
selector:
app: jupyter-lab
DNS名称
jupyter-lab.local
解析到集群的ip地址范围,但超时无响应。Failed to connect to jupyter-lab.local port 80: No route to host
firewall-cmd --list-all
说明每个节点都打开了80端口
这是端口 80 上集群(任何节点)的 http 入口定义。(错了吗?)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: jupyter-lab-ingress
annotations:
# nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io: /
spec:
rules:
- host: jupyter-lab.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: jupyter-lab-cip
port:
number: 80
这是部署
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: jupyter-lab-dpt
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: jupyter-lab
template:
metadata:
labels:
app: jupyter-lab
spec:
volumes:
- name: jupyter-lab-home
persistentVolumeClaim:
claimName: jupyter-lab-pvc
containers:
- name: jupyter-lab
image: docker.io/jupyter/tensorflow-notebook
ports:
- containerPort: 8888
volumeMounts:
- name: jupyter-lab-home
mountPath: /var/jupyter-lab_home
env:
- name: "JUPYTER_ENABLE_LAB"
value: "yes"
我可以通过其 NodePort http://node2:30004 成功访问 jupyter-lab,定义如下:
---
apiVersion: v1
kind: Service
metadata:
name: jupyter-lab-nodeport
namespace: default
spec:
type: NodePort
ports:
- port: 10003
targetPort: 8888
nodePort: 30004
selector:
app: jupyter-lab
如何进入我在 http://jupyter-lab.local 的 jupyter-lab ???
- 命令
kubectl get endpoints -n ingress-nginx ingress-nginx-controller-admission
returns :
ingress-nginx-controller-admission 10.244.2.4:8443 15m
我是否错误配置了端口?
我的“selector:appname”定义有误吗?
我是不是漏掉了一部分
我如何调试正在发生的事情?
其他详情
我在应用入口时收到此错误
kubectl apply -f default-ingress.yml
Error from server (InternalError): error when creating "minnimal-ingress.yml": Internal error occurred: failed calling webhook "validate.nginx.ingress.kubernetes.io": Post "https://ingress-nginx-contr oller-admission.ingress-nginx.svc:443/networking/v1beta1/ingresses?timeout=10s": context deadline exceeded
这个命令
kubectl delete validatingwebhookconfigurations --all-namespaces
删除了验证 webhook ...这样做是错误的吗?我已经在集群中的每个节点上打开了端口 8443
入口无效,请尝试以下操作:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: jupyter-lab-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: jupyter-lab.local
http: # <- removed the -
paths:
- path: /
pathType: Prefix
backend:
service:
# name: jupyter-lab-cip
name: jupyter-lab-nodeport
port:
number: 8888
---
apiVersion: v1
kind: Service
metadata:
name: jupyter-lab-cip
namespace: default
spec:
type: ClusterIP
ports:
- port: 8888
targetPort: 8888
selector:
app: jupyter-lab
如果我没理解错的话,你正试图通过入口 nginx 代理公开 jupyternb 并使其可通过端口 80 访问。
运行 以下命令检查 nginx ingress 服务使用的节点端口:
$ kubectl get svc -n ingress-nginx ingress-nginx-controller
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller NodePort 10.96.240.73 <none> 80:30816/TCP,443:31475/TCP 3h30m
在我的例子中是端口 30816(对于 http)和 31475(对于 https)。
使用 NodePort 类型,您只能使用 30000-32767 范围内的端口(k8s 文档:https://kubernetes.io/docs/concepts/services-networking/service/#nodeport)。您可以使用 kube-apiserver 标志 --service-node-port-range
更改它,然后将其设置为例如80-32767
然后在你的 ingress-nginx-controller 服务中设置 nodePort: 80
apiVersion: v1
kind: Service
metadata:
annotations: {}
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/version: 0.44.0
helm.sh/chart: ingress-nginx-3.23.0
name: ingress-nginx-controller
namespace: ingress-nginx
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: http
nodePort: 80 # <- HERE
- name: https
port: 443
protocol: TCP
targetPort: https
nodePort: 443 # <- HERE
selector:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
type: NodePort
尽管通常不建议更改 service-node-port-range,因为如果您使用节点上已经打开的端口(例如,kubelet 在每个节点上打开的端口 10250),您可能会遇到一些问题。
更好的解决方案可能是使用 MetalLB.
编辑:
How can I get ingress to my jupyter-lab at http://jupyter-lab.local ???
假设您不需要容错解决方案,请下载 https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.44.0/deploy/static/provider/baremetal/deploy.yaml
文件并更改部署对象的 ports:
部分,如下所示:
ports:
- name: http
containerPort: 80
hostPort: 80 # <- add this line
protocol: TCP
- name: https
containerPort: 443
hostPort: 443 # <- add this line
protocol: TCP
- name: webhook
containerPort: 8443
protocol: TCP
并应用更改:
kubectl apply -f deploy.yaml
现在运行:
$ kubectl get po -n ingress-nginx ingress-nginx-controller-<HERE PLACE YOUR HASH> -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
ingress-nginx-controller-67897c9494-c7dwj 1/1 Running 0 97s 172.17.0.6 <node_name> <none> <none>
注意 NODE 列中的 /etc/hosts
文件中。
它现在应该可以工作了(去 http://jupyter-lab.local 检查它),但是这个解决方案很脆弱,如果 nginx ingress controller pod 被重新安排到其他节点,它将停止工作(并且它将保持这样直到您更改 /etc/hosts 文件中的 ip)。通常也不建议使用 hostPort:
字段,除非你有充分的理由这样做,所以不要滥用它。
如果您需要容错解决方案,请使用 MetalLB 并为 nginx 入口控制器创建 LoadBalancer 类型的服务。
我还没有测试过,但假设您正确配置了 MetalLB,以下应该可以完成工作:
kubectl delete svc -n ingress-nginx ingress-nginx-controller
kubectl expose deployment -n ingress-nginx ingress-nginx-controller --type LoadBalancer