问题描述
我在 Centos7 上运行 kubernetes 1-21-0。我已经设置了一个 keycloak 服务来测试我的入口控制器,并且能够使用 myurl.com:30872
这样的 keycloak 端口访问主机 URL 上的 keycloak。这些是我正在运行的服务:
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default keycloak NodePort 10.96.11.164 <none> 8080:30872/TCP 21h
default kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 11d
ingress-Nginx ingress-Nginx-controller NodePort 10.102.201.24 <none> 80:31110/TCP,443:30566/TCP 9m45s
ingress-Nginx ingress-Nginx-controller-admission ClusterIP 10.107.90.207 <none> 80/TCP,443/TCP 9m45s
kube-system kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 11d
我已经部署了以下 nginx ingress controller。
# Source: ingress-Nginx/templates/controller-service-webhook.yaml
apiVersion: v1
kind: Service
Metadata:
labels:
helm.sh/chart: ingress-Nginx-3.23.0
app.kubernetes.io/name: ingress-Nginx
app.kubernetes.io/instance: ingress-Nginx
app.kubernetes.io/version: 0.44.0
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: controller
name: ingress-Nginx-controller-admission
namespace: ingress-Nginx
spec:
type: ClusterIP
ports:
- name: http-webhook
port: 80
targetPort: webhook
- name: https-webhook
port: 443
targetPort: webhook
selector:
app.kubernetes.io/name: ingress-Nginx
app.kubernetes.io/instance: ingress-Nginx
app.kubernetes.io/component: controller
有了这个入口:
apiVersion: networking.k8s.io/v1
kind: Ingress
Metadata:
name: keycloak
annotations:
kubernetes.io/ingress.class: Nginx
Nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /keycloak
pathType: Prefix
backend:
service:
name: keycloak
port:
number: 8080
现在,当我尝试通过入口连接到 keycloak 服务时,我转到 myurl.com/keycloak
但它无法连接并尝试从我的控制节点内卷曲它显示连接被拒绝:
# curl -I http://127.0.0.1/keycloak
curl: (7) Failed connect to 127.0.0.1:80; Connection refused
有人能看到我遗漏了什么吗?
编辑:
我意识到入口控制器确实可以工作,但我还需要指定它的端口才能像这样访问它:
curl -I http://127.0.0.1:31110/keycloak
我想避免的。
解决方法
您必须指定 31110
端口,因为您的 nginx 入口设置为 NodePort
,这意味着 kubernetes 侦听此端口,并且所有流向此处的流量都重定向到 nginx-ingress-controller
pod。
根据您的设置和目标,这可以以不同的方式实现。
选项 1 - 仅用于测试目的,不更改设置。仅适用于 nginx-ingress-controller
pod 正在运行的控制平面
可以将流量从外部端口 80 转发到 nginx-ingress-controller
pod 直接端口 80。您可以运行此命令(在后台):
sudo kubectl port-forward ingress-nginx-controller-xxxxxxxx-yyyyy 80:80 -n ingress-nginx &
卷曲测试表明它正在工作:
curl -I localhost/keycloak
Handling connection for 80
HTTP/1.1 200 OK
Date: Wed,16 Jun 2021 13:19:23 GMT
Curl 可以在不同的实例上运行,在这种情况下,命令看起来像这样,无需指定任何端口:
curl -I public_ip/keycloak
选项 2 - 这一个有点困难,但提供了更好的结果。
可以在集群外部公开 pod。功能称为 hostPort
- 它允许在主机 IP 上公开单个容器端口。要在不同的工作节点上进行这项工作,ingress-nginx-controller
应部署为 DaemonSet
。
我更正的 ingress-nginx helm chart values.yaml
中的以下部分:
hostPort -> 启用 -> true
## Use host ports 80 and 443
## Disabled by default
##
hostPort:
enabled: true
ports:
http: 80
https: 443
kind -> DaemonSet
## DaemonSet or Deployment
##
kind: DaemonSet
然后从此图表安装 ingress-nginx-controller。
它的作用是默认 ingress-nginx-controller
pod 将侦听 80 和 443 端口上的流量。
这通过简单的测试证实:
curl -I localhost/keycloak
HTTP/1.1 200 OK
Date: Wed,16 Jun 2021 13:31:25 GMT
选项 3 - 如果 ingress-nginx 安装了 LoadBalancer 类型,也可以考虑。
使用 metallb
- 专为裸机集群设计的软件负载均衡器。 How to install metallb 和 configure
完成并部署 ingress-nginx 后,ingress-nginx 将获得外部 IP:
kubectl get svc --all-namespaces
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx ingress-nginx-controller LoadBalancer 10.102.135.146 192.168.1.240 80:32400/TCP,443:32206/TCP 43s
用 curl
再次测试:
curl -I 192.168.1.240/keycloak
HTTP/1.1 200 OK
Date: Wed,16 Jun 2021 13:55:34 GMT
有关上述主题的更多信息: