无法从Postman的k8s-Skaffold中获得Express API的响应

时间:2019-10-08 03:34:21

标签: docker kubernetes dockerfile minikube skaffold

尝试做一些应该非常简单的事情:启动Express吊舱并获取localhost:5000/,它应该以{{1​​}}作为响应。

  • 我已经为Docker for Macminikube安装了Hello World!
    • 必填ingress-nginx
    • 适用于Mac的Docker kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml
    • minikube kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/cloud-generic.yaml
  • 我运行minikube addons enable ingress
  • 它会打印出skaffold dev --tail,因此显然正在运行
  • 导航到Example app listening on port 5000localhost并收到“无法获得任何响应”错误
  • 还尝试了localhost:5000的{​​{1}},并获得了相同的结果

不太确定我在做什么错。代码和配置如下。有建议吗?


index.js

minikube ip

skaffold.yaml

192.168.99.100

ingress-service.yaml

// Import dependencies
const express = require('express');

// Set the ExpressJS application
const app = express();

// Set the listening port
// Web front-end is running on port 3000
const port = 5000;

// Set root route
app.get('/', (req, res) => res.send('Hello World!'));

// Listen on the port
app.listen(port, () => console.log(`Example app listening on port ${port}`));

server-deployment.yaml

apiVersion: skaffold/v1beta15
kind: Config
build:
  local:
    push: false
  artifacts:
    - image: sockpuppet/server
      context: server
      docker:
        dockerfile: Dockerfile.dev
      sync:
        manual:
        - src: '**/*.js'
          dest: .
deploy:
  kubectl:
    manifests:
      - k8s/ingress-service.yaml
      - k8s/server-deployment.yaml
      - k8s/server-cluster-ip-service.yaml

server-cluster-ip-service.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-service
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  rules:
    - http:
        paths:
          - path: /?(.*)
            backend:
              serviceName: server-cluster-ip-service
              servicePort: 5000

Dockerfile.dev

apiVersion: apps/v1
kind: Deployment
metadata:
  name: server-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      component: server
  template:
    metadata:
      labels:
        component: server
    spec:
      containers:
        - name: server
          image: sockpuppet/server
          ports:
            - containerPort: 5000

apiVersion: v1 kind: Service metadata: name: server-cluster-ip-service spec: type: ClusterIP selector: component: server ports: - port: 5000 targetPort: 5000 的输出

FROM node:12.10-alpine
EXPOSE 5000

WORKDIR "/app"
COPY ./package.json ./
RUN npm install
COPY . .

CMD ["npm", "run", "dev"]

describe的输出

$ kubectl describe ingress ingress-service     
Name:             ingress-service
Namespace:        default
Address:          
Default backend:  default-http-backend:80 (<none>)
Rules:
  Host       Path  Backends
  ----       ----  --------
  localhost  
             /   server-cluster-ip-service:5000 (172.17.0.7:5000,172.17.0.8:5000,172.17.0.9:5000)
Annotations:
  kubectl.kubernetes.io/last-applied-configuration:  {"apiVersion":"extensions/v1beta1","kind":"Ingress","metadata":{"annotations":{"kubernetes.io/ingress.class":"nginx"},"name":"ingress-service","namespace":"default"},"spec":{"rules":[{"host":"localhost","http":{"paths":[{"backend":{"serviceName":"server-cluster-ip-service","servicePort":5000},"path":"/"}]}}]}}

  kubernetes.io/ingress.class:  nginx
Events:
  Type    Reason  Age   From                      Message
  ----    ------  ----  ----                      -------
  Normal  CREATE  16h   nginx-ingress-controller  Ingress default/ingress-service
  Normal  CREATE  21s   nginx-ingress-controller  Ingress default/ingress-service

来自kubectl get po -l component=server 的输出:注意$ kubectl get po -l component=server NAME READY STATUS RESTARTS AGE server-deployment-cf6dd5744-2rnh9 1/1 Running 0 11s server-deployment-cf6dd5744-j9qvn 1/1 Running 0 11s server-deployment-cf6dd5744-nz4nj 1/1 Running 0 11s 。可能是问题吗?

kubectl describe pods server-deployment

1 个答案:

答案 0 :(得分:1)

好的,现在解决这个问题。

可以归结为所使用的服务类型:ClusterIP

  

ClusterIP:在群集内部IP上公开服务。选择此值将使服务仅可从群集内访问。这是默认的ServiceType。

如果我想直接从集群外部(例如Postman,pgAdmin等)连接到Pod或Deployment,并且想要使用Service进行连接,我应该使用NodePort

  

NodePort:在静态端口(NodePort)上公开每个节点IP上的服务。将自动创建NodePort服务将路由到的ClusterIP服务。您可以通过请求<NodeIP><NodePort>从集群外部联系NodePort服务。

因此,就我而言,如果我想继续使用服务,请将服务清单更改为:

apiVersion: v1
kind: Service
metadata:
  name: server-cluster-ip-service
spec:
  type: NodePort
  selector:
    component: server
  ports:
    - port: 5000
      targetPort: 5000
      nodePort: 31515

请确保手动设置nodePort: <port>,否则这是随机的,使用起来很麻烦。

然后我将使用minikube获得minikube ip IP,并使用192.168.99.100:31515连接到Pod。

到那时,一切都按预期进行。

但是,这意味着分别具有开发(NodePort)和生产(ClusterIP)集,这可能完全没问题。但我希望我的清单与生产版本保持一致(即ClusterIP)。

有几种解决方法:

  1. 使用类似Kustomize之类的方法,您可以在其中设置base.yaml,然后为每个环境覆盖,在该环境中,它只需更改相关信息即可避免大部分重复的清单。
  2. 使用kubectl port-forward。我认为这是我要走的路。这样,我可以保留一组生产清单,但是当我想使用pgAdmin对Postgres进行质量检查时,我可以这样做:

    kubectl port-forward services/postgres-cluster-ip-service 5432:5432

    或者对于后端和邮递员:

    kubectl port-forward services/server-cluster-ip-service 5000:5000

我正在使用ingress-service.yaml通过nginx-ingress来执行此操作,但是还没有工作。会在我更新时更新。但是对我来说,port-forward似乎是路要走,因为我可以拥有一组我不需要更改的生产清单。

Skaffold端口转发

这对我来说更好。将其附加到skaffold.yaml的底部,基本上与kubectl port-forward相同,而无需占用一两个终端:

portForward:
  - resourceType: service
    resourceName: server-cluster-ip-service
    port: 5000
    localPort: 5000
  - resourceType: service
    resourceName: postgres-cluster-ip-service
    port: 5432
    localPort: 5432

然后运行skaffold dev --port-forward