【问题标题】:How do I expose ingress to my local machine? (minikube on windows)如何向本地计算机公开入口? (Windows 上的 minikube)
【发布时间】:2020-05-16 13:45:56
【问题描述】:

我有两个部署

部署 1

apiVersion: v1
kind: Service
metadata:
  name: first-service
spec:
  selector:
    key: app1
  ports:
    - port: 81
      targetPort: 5050

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: first-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      run: app1
  template:
    metadata:
      labels:
        run: app1
    spec:
      containers:
      - name: ocr
        image: ocr_app
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 5050

部署 2

apiVersion: v1
kind: Service
metadata:
  name: second-service
spec:
  selector:
    key: app2
  ports:
    - port: 82
      targetPort: 5000

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: second-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      run: app2
  template:
    metadata:
      labels:
        run: app2
    spec:
      containers:
      - name: ner
        image: ner_app
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 5000

在 minikube 上启用入口后,我应用了 ingess

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress
spec:
  rules:
  - host: demo.local
    http:
      paths:
      - path: /ocr
        backend:
          serviceName: first-service
          servicePort: 81
      - path: /ner
        backend:
          serviceName: second-service
          servicePort: 82

在我的主机文件中,我有

192.168.177.71  demo.local

192.168.177.71 是我当前的 minikube ip

然后我运行了这个命令

kubectl port-forward nginx-ingress-controller-6fc5bcc8c9-p6mvj 3000:80 --namespace kube-system

在控制台中是输出

Forwarding from 127.0.0.1:3000 -> 80
Forwarding from [::1]:3000 -> 80

但是当我使用邮递员向demo.local:3000/ocr 发出请求时,没有响应

无法得到任何响应连接到时出错 demo.local:3000.

编辑:使用minikube service first-service 给出此输出

PS D:\docker> minikube service first-service
|-----------|---------------|-------------|--------------|
| NAMESPACE |     NAME      | TARGET PORT |     URL      |
|-----------|---------------|-------------|--------------|
| default   | first-service |             | No node port |
|-----------|---------------|-------------|--------------|
* service default/first-service has no node port

【问题讨论】:

  • 只是为了清除一些想法。您正在使用 Kubernetes 1.16+。您是否在 minikube minikube addons enable ingress 中启用了入口?您只有/ocr/ner 有问题?
  • @PjoterS 是启用入口,两条路径上的问题相同

标签: kubernetes minikube


【解决方案1】:

@erotavlas 作为 Mafor 提供的答案,可以帮助您解决问题,请接受他的回答。

我正在发布可能对其他人有帮助的扩展答案。

此问题的根本原因是 selector/labels

first-service 中,spec.selector 设置为key: app1,但在部署中spec.selector.matchLabels 设置为run: app1

要正常工作,您需要使用相同的选择器。因此,您需要将服务、spec.selector 更改为run: app1 或将部署spec.selector.matchLabels 更改为key: app1second-servicesecond-deployment 的情况相同。更多详情请见here

我已尝试基于 official docs 和您的 YAML 在 Minikube 上使用 Ingress。

另外,要在Minikube 上使用Ingress,必须启用Ingress addon

$ minikube addons list | grep ingress
- ingress: disabled

如果它被禁用,你必须启用它。

$ minikube addons enable ingress
✅  ingress was successfully enabled

targetPort: 是容器接受流量的端口/应用程序在 pod 内运行的端口
port: 是抽象的Service 端口,它可以是其他 pod 用来访问服务的任何端口。

OP 使用自己的映像,其中应用程序在端口 50505000 上运行,在此示例中,我将在端口 8080 上使用 GCP hello world。 Labels/matchLabels 已更改为在部署和服务中具有 sam 值。

首次服务

apiVersion: v1
kind: Service
metadata:
  name: first-service
spec:
  selector:
    key: app1
  ports:
    - port: 81
      targetPort: 8080

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: first-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      key: app1
  template:
    metadata:
      labels:
        key: app1
    spec:
      containers:
      - name: hello1
        image: gcr.io/google-samples/hello-app:1.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080

service/first-service created
deployment.apps/first-deployment created

二次服务

apiVersion: v1
kind: Service
metadata:
  name: second-service
spec:
  selector:
    key: app2
  ports:
    - port: 82
      targetPort: 8080

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: second-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      key: app2
  template:
    metadata:
      labels:
        key: app2
    spec:
      containers:
      - name: hello2
        image: gcr.io/google-samples/hello-app:2.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080

service/second-service created
deployment.apps/second-deployment created

它将服务创建为ClusterIP 类型。如果需要,您可以使用NodePort,但这不是必需的。

应用入口

提供的入口足以进行测试。

official docs 中所述。您应该将 minikube ip 添加到主机文件。

注意:如果您在本地运行 Minikube,请使用 minikube ip 获取外部 IP。入口列表中显示的 IP 地址将是内部 IP。

在 Ubuntu 操作系统中为 /etc/hosts(需要使用 sudo 进行编辑)。 Windows操作系统请查看this article

对于我的集群(使用 GCE):

$ minikube ip
10.132.15.208

添加到hosts文件值:

10.132.15.208 demo.local

以下回复。

$ curl demo.local/ocr
Hello, world!
Version: 1.0.0
Hostname: first-deployment-85b75bf4f9-qlzrp
$ curl demo.local/ner
Hello, world!
Version: 2.0.0
Hostname: second-deployment-5b5bbb7f4-9sbqr

但是,Mafor 提供的带有rewrite 的版本更加通用。

此外,您还可以考虑在Minikube 上使用LoadBalancer。 更多信息可以在Minikube docs找到。

【讨论】:

    【解决方案2】:

    首先,您不需要kubectl port-forward。 Ingress 暴露在您的 minikube ip 端口 80 上。

    其次,可能您需要在入口配置中进行一些重写规则。默认情况下,入口“按原样”转发请求,即 demo.local:3000/ocr 被转发到 first-service:81/ocr。可能这不是您想要的,除非将 first-service 部署到 /ocr 上下文。

    我猜,你需要这样的东西:

    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      name: ingress
      annotations:
        nginx.ingress.kubernetes.io/rewrite-target: /$2
    spec:
      rules:
      - host: demo.local
        http:
          paths:
          - path: /ocr(/|$)(.*)
            backend:
              serviceName: first-service
              servicePort: 81
          - path: /ner(/|$)(.*)
            backend:
              serviceName: second-service
              servicePort: 82
    

    https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#rewrite

    【讨论】:

    • 我不明白您所说的“除非将第一服务部署到 /ocr 上下文”是什么意思。为了清楚起见,我试图公开两条单独的路由,一条向一个服务发送请求,另一个向另一个服务发送请求。例如,第一个部署是一个带有烧瓶 rest api 的容器,我将要调用的路由指定为“/ocr”
    • 我的意思是:flask api 本身是否包含/ocr 路由,还是应该用/ 调用它?
    • Flask 应用包含这个@app.route("/ocr", methods=['POST'])
    • 好吧,比忽略我的回答,我会删除它。但是关于kubectl port-forward 的部分仍然有效。并检查您是否没有尝试连接 https。
    • OMG 现在可以工作了,我删除了 rewrite ` annotations: nginx.ingress.kubernetes.io/rewrite-target: /$1` 并修复了两个服务的选择器以匹配部署中的标签。感谢您的帮助:) 不妨包括我在您的答案中找到的内容
    猜你喜欢
    • 2021-04-03
    • 2020-12-18
    • 1970-01-01
    • 2021-12-10
    • 1970-01-01
    • 1970-01-01
    • 2019-04-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多