获取 Kubernetes Ingress 的端点/ IP 地址

23
Base OS : CentOS (1 master 2 minions)
K8S version : 1.9.5 (deployed using KubeSpray)

我刚接触Kubernetes Ingress,正在设置两个不同的服务,每个服务都可以通过自己的路径访问。

我已经创建了2个部署:

kubectl run nginx --image=nginx --port=80
kubectl run echoserver --image=gcr.io/google_containers/echoserver:1.4 --port=8080

我还创建了它们相应的服务:

kubectl expose deployment nginx --target-port=80 --type=NodePort
kubectl expose deployment echoserver --target-port=8080 --type=NodePort

我的svc是:

[root@node1 kubernetes]# kubectl get svc
NAME         TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
echoserver   NodePort   10.233.48.121   <none>        8080:31250/TCP   47m
nginx        NodePort   10.233.44.54    <none>        80:32018/TCP     1h

我的NodeIP地址是172.16.16.2,我可以使用它访问两个Pod。

http://172.16.16.2:31250 &
http://172.16.16.2:32018

现在除此之外,我想部署一个Ingress,以便我能够使用不同的路径访问两个pod,而不是使用2个IP和2个不同的端口,而是1个IP地址。

所以我的Ingress文件是:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: fanout-nginx-ingress
spec:
  rules:
  - http:
      paths:
      - path: /nginx
        backend:
          serviceName: nginx
          servicePort: 80
      - path: /echo
        backend:
          serviceName: echoserver
          servicePort: 8080

这将产生:

[root@node1 kubernetes]# kubectl describe  ing fanout-nginx-ingress
Name:             fanout-nginx-ingress
Namespace:        development
Address:          
Default backend:  default-http-backend:80 (<none>)
Rules:
  Host  Path  Backends
  ----  ----  --------
  *     
        /nginx   nginx:80 (<none>)
        /echo    echoserver:8080 (<none>)
Annotations:
Events:  <none>

现在,当我尝试使用 NodeIP 地址(172.16.16.2)访问 Pods 时,什么也没有。

http://172.16.16.2/echo
http://172.16.16.2/nginx

我的配置文件中是否有我遗漏的东西?


2
我是一个 Kubernetes 新手,所以请谨慎对待我的建议。我注意到 Ingress 缺少“地址”信息。这可能是问题的原因吗? - thebitguru
你是对的。它确实缺失了。 - user4889345
4
你是如何解决缺失地址的问题的?我也遇到了同样的问题。控制器和应用程序在同一个命名空间中,但我无法访问它们。 - Piotr Kula
5个回答

20

在我的裸机安装中出现了类似问题 - 或者更接近于这个问题(Kubernetes虚拟集群 - 一组通过Host-Only-Adapter连接的虚拟机)。这里是我的kubernetes虚拟实验室链接。

首先确保您已安装Ingress Controller。目前有两个值得尝试的Ingress Controller,分别是kubernetes nginx ingress controllernginx kubernetes ingress controller - 我安装了第一个。

安装

前往安装说明并执行第一步。

# prerequisite-generic-deployment-command
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/mandatory.yaml

接下来获取集群节点的IP地址。

$ kubectl get nodes -o wide
NAME     STATUS   ROLES    ...   INTERNAL-IP    
master   Ready    master   ...   192.168.121.110
node01   Ready    <none>   ...   192.168.121.111
node02   Ready    <none>   ...   192.168.121.112

此外,创建类型为LoadBalanceringress-nginx服务。我通过从安装教程中下载NodePort模板服务,并在svc-ingress-nginx-lb.yaml文件中进行以下调整来完成此操作。

$ curl https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/provider/baremetal/service-nodeport.yaml > svc-ingress-nginx-lb.yaml

# my changes svc-ingress-nginx-lb.yaml
type: LoadBalancer
externalIPs:
  - 192.168.121.110
  - 192.168.121.111
  - 192.168.121.112
externalTrafficPolicy: Local

# create ingress- service
$ kubectl apply -f svc-ingress-nginx-lb.yaml

验证

检查是否已创建ingress-nginx服务。

$ kubectl get svc -n ingress-nginx
NAME            TYPE           CLUSTER-IP     EXTERNAL-IP                                                       PORT(S)                      AGE
ingress-nginx   LoadBalancer   10.110.127.9   192.168.121.110,192.168.121.111,192.168.121.112   80:30284/TCP,443:31684/TCP   70m

检查是否创建了nginx-ingress-controller部署。

$ kubectl get deploy -n ingress-nginx
NAME                       DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx-ingress-controller   1         1         1            1           73m

检查是否运行 nginx-ingress Pod。

$ kubectl get pods --all-namespaces -l 

app.kubernetes.io/name=ingress-nginx
NAMESPACE       NAME                                        READY   STATUS    RESTARTS   AGE
ingress-nginx   nginx-ingress-controller-5cd796c58c-lg6d4   1/1     Running   0          75m

最后,检查Ingress Controller版本。不要忘记更改Pod名称!

$ kubectl exec -it nginx-ingress-controller-5cd796c58c-lg6d4 -n ingress-nginx -- /nginx-ingress-controller --version
-------------------------------------------------------------------------------
NGINX Ingress controller
  Release:    0.21.0
  Build:      git-b65b85cd9
  Repository: https://github.com/aledbf/ingress-nginx
-------------------------------------------------------------------------------

测试

通过执行此教程中的步骤来测试Ingress控制器是否正常工作,当然,您将省略minikube 部分。

成功执行所有步骤将创建类似于此的Ingress控制器资源。

$ kubectl get ing
NAME               HOSTS                                ADDRESS                                          PORTS    AGE
ingress-tutorial   myminikube.info,cheeses.all          192.168.121.110,192.168.121.111,192.168.121.112   80      91m

而且还有长这样的豆荚。

$ kubectl get pods 
NAME                              READY   STATUS             RESTARTS   AGE
cheddar-cheese-6f94c9dbfd-cll4z   1/1     Running            0          110m
echoserver-55dcfbf8c6-dwl6s       1/1     Running            0          104m
stilton-cheese-5f6bbdd7dd-8s8bf   1/1     Running            0          110m

最后,测试通过Ingress负载均衡器传播到myminikube.info的请求。

$ curl myminikube.info
CLIENT VALUES:
client_address=10.44.0.7
command=GET
real path=/
query=nil
request_version=1.1
request_uri=http://myminikube.info:8080/

SERVER VALUES:
server_version=nginx: 1.10.0 - lua: 10001

HEADERS RECEIVED:
accept=*/*
host=myminikube.info
user-agent=curl/7.29.0
x-forwarded-for=10.32.0.1
x-forwarded-host=myminikube.info
x-forwarded-port=80
x-forwarded-proto=http
x-original-uri=/
x-real-ip=10.32.0.1
x-request-id=b2fb3ee219507bfa12472c7d481d4b72
x-scheme=http
BODY:

在裸金属环境中使ingress运作需要一段漫长的旅程。因此,我将包括帮助我的相关链接。


我已经通过更新svc-ingress-nginx-lb.yaml文件使其正常工作。但是,主机网络中的机器只能访问其中一个EXTERNAL-IP。您介意解释一下它是如何工作的吗? - vc25
忘了提到我没有为入口设置主机名,因此它是直接通过 EXTERNAL-IP 访问的。 - vc25

2

检查您的集群中是否有一个入口控制器:

$ kubectl get po --all-namespaces

你应该看到类似于:
kube-system nginx-ingress-controller-gwts0   1/1  Running   0    18d

只有在Ingress所在的命名空间中才能创建用于访问服务的Ingress。 由于安全原因,不支持跨命名空间的Ingress。


谢谢。那就是问题所在(我是Ingress新手)。我使用以下步骤(https://github.com/kubernetes/ingress-nginx/tree/master/deploy)部署了Ingress控制器。我只有一个问题。Ingress控制器和我想要由Ingress控制器控制的应用程序必须在同一个命名空间中吗? - user4889345
1
我在我的回答中添加了对你问题的回复。 - Nicola Ben

1
似乎您的集群缺少Ingress控制器。
一般来说,Ingress控制器的工作方式如下: 1. 在集群中搜索某种类型的对象(ingress,“nginx”)。 2. 解析该对象并为特定的ingress pod创建配置部分。 3. 更新该pod对象(使用更新后的配置重新启动它)。
该特定pod负责将流量从入站端口(通常是节点上的几个专用端口)处理到集群中配置的流量目标。
您可以从两个受支持且维护的控制器中进行选择 - NginxGCE
Ingress控制器由安装期间创建的几个组件组成。 以下是Nginx Ingress文档中的安装部分。
curl https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/namespace.yaml              | kubectl apply -f -
curl https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/default-backend.yaml        | kubectl apply -f -
curl https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/configmap.yaml              | kubectl apply -f -
curl https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/tcp-services-configmap.yaml | kubectl apply -f -
curl https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/udp-services-configmap.yaml | kubectl apply -f -

如果您的集群中已配置 RBAC 授权:
curl https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/rbac.yaml      | kubectl apply -f -
curl https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/with-rbac.yaml | kubectl apply -f -

如果没有配置RBAC:
curl https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/without-rbac.yaml | kubectl apply -f -

如果您从头开始创建集群:

curl https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/provider/baremetal/service-nodeport.yaml | kubectl apply -f -

验证您的安装:

kubectl get pods --all-namespaces -l app=ingress-nginx --watch

你应该看到类似于以下内容:
NAMESPACE       NAME                                       READY     STATUS    RESTARTS   AGE
ingress-nginx   nginx-ingress-controller-699cdf846-nj2rw   1/1       Running   0          1h

检查可用的服务及其参数:

kubectl get services --all-namespaces

如果您正在使用自定义服务提供程序部署(minikube、AWS、Azure、GKE),请参考Nginx Ingress文档获取安装详细信息。
有关Ingress的详细信息,请参阅官方Kubernetes Ingress文档

谢谢。这正是我现在所做的,我在 ingress-nginx 命名空间中拥有一个 Ingress 控制器。但是我将我的应用程序和其服务部署在不同的命名空间中。结果发现我不能这样做。因此,我现在将重新部署其服务和 Pod 到命名空间 ingress-nginx 中,并观察情况如何。 - user4889345
1
您不必将所有服务放在ingress-controller命名空间中。您只需要将Ingress对象与所提到的服务放在同一个命名空间中即可。Ingress对象可以位于任何命名空间中,ingress-controller具有从任何命名空间读取此类对象的权限。 - VAS

1

我正在使用microk8s默认的nginx Ingress控制器在一个较新版本的k8s(> 1.18)上,我注意到这个特定的注释给我带来了问题:

kubernetes.io/ingress.class: "nginx"

它出现在许多旧文档和示例中,但显然已被弃用(请参见https://kubernetes.io/docs/concepts/services-networking/ingress/)。我还使用了更新的注释定义了一个名为“public”的ingressClassName。我不确定是两者之间的冲突导致了问题,但一旦我删除了已弃用的注释,我的地址就出现了。

0
对于使用您的入口资源(扇出-nginx-ingress),您需要首先部署默认情况下不在本地Kubernetes集群中的Ingress控制器。您需要自己部署它。 有许多解决方案可供选择,您可以使用其中任何一个,但Nginx Ingress控制器很好。 有关详细信息,请参考Mumshad Mannambeth在此处提供的关于Ingress的优秀视频: https://www.youtube.com/watch?v=GhZi4DxaxxE

3
最好将视频内容进行总结,而不是指向可能会在未来无法访问的视频。 - webofmars

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接