如何让两个Kubernetes服务相互交谈?

时间:2017-08-16 17:52:28

标签: kubernetes cluster-computing kubectl

目前,我在K8s服务中使用K8s API pod,该服务连接到K8s Redis服务,其中有K8s pod。问题是,我使用NodePort意味着BOTH暴露给公众。我只希望API可以访问公众。问题是,如果我不公开Redis服务,API就无法看到它。有没有办法连接两个服务而不向公众公开?

这是我的API服务yaml:

apiVersion: v1
kind: Service
metadata:
   name: app-api-svc
spec:
   selector:
     app: app-api
     tier: api
   ports:
     - protocol: TCP
       port: 5000
       nodePort: 30400
   type: NodePort

这是我的Redis服务yaml:

apiVersion: v1
kind: Service
metadata:
   name: app-api-redis-svc
spec:
   selector:
     app: app-api-redis
     tier: celery_broker
   ports:
     - protocol: TCP
       port: 6379
       nodePort: 30537
   type: NodePort

4 个答案:

答案 0 :(得分:5)

首先,将Redis服务配置为ClusterIP服务。它将是私有的,仅对其他服务可见。可以使用选项type删除该行。

apiVersion: v1
kind: Service
metadata:
   name: app-api-redis-svc
spec:
   selector:
     app: app-api-redis
     tier: celery_broker
   ports:
     - protocol: TCP
       port: 6379
       targetPort: [the port exposed by the Redis pod]

最后,当您配置API以访问Redis时,地址应为app-api-redis-svc:6379

这就是全部。我有很多服务以这种方式相互沟通。如果这对您不起作用,请在评论中告诉我。

答案 1 :(得分:3)

我将尝试从所有答案和我自己的研究中获取最佳效果并制作一份简短的指南,希望您能找到帮助:

1。测试连接性

连接到另一个广告连播,例如ruby pod:

kubectl exec -it some-pod-name -- /bin/sh

验证它是否可以ping到相关服务:

ping redis

可以连接到端口吗? (我发现telnet不能用于此)

nc -zv redis 6379

2。验证您的服务选择器是否正确

如果您的服务配置如下所示:

kind: Service
apiVersion: v1
metadata:
  name: redis
  labels:
    app: redis
    role: master
    tier: backend
spec:
  ports:
  - port: 6379
    targetPort: 6379
  selector:
    app: redis
    role: master
    tier: backend

验证你的pod上还设置了那些选择器吗?

get pods --selector=app=redis,role=master,tier=backend

运行以下命令确认您的服务与您的广告连接相关联:

$> describe service redis
Name:           redis
Namespace:      default
Labels:         app=redis
            role=master
            tier=backend
Annotations:        <none>
Selector:       app=redis,role=master,tier=backend
Type:           ClusterIP
IP:         10.47.250.121
Port:           <unset> 6379/TCP
Endpoints:      10.44.0.16:6379
Session Affinity:   None
Events:         <none>

检查Endpoints:字段并确认它不是空白

更多信息可在以下网址找到: https://kubernetes.io/docs/tasks/debug-application-cluster/debug-service/#my-service-is-missing-endpoints

答案 2 :(得分:1)

我不确定redis,但我有类似的应用程序。我有一个Java Web应用程序作为pod运行,通过nodePort暴露给外部世界。我有一个作为pod运行的mongodb容器。

在webapp部署规范中,我通过将服务名称作为参数将其映射到mongodb服务,我已粘贴下面的规范。您可以相应地进行修改。在Redis中应该有一个类似的映射参数,您必须使用服务名称,即&#34; mongoservice&#34;就我而言。

    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: empappdepl
      labels:
        name: empapp
    spec:
      replicas: 1
      template:
        metadata:
          labels:
            name: empapp
        spec:
          containers:
            -
              resources:
                limits:
                  cpu: 0.2
              image: registryip:5000/employee:1
              imagePullPolicy: IfNotPresent
              name: wsemp
              ports:
                - containerPort: 8080
                  name: wsemp
              command: ["java","-Dspring.data.mongodb.uri=mongodb://mongoservice/microservices", "-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
          imagePullSecrets:
           - name: myregistrykey
---
apiVersion: v1
kind: Service
metadata:
  labels:
    name: empwhatever
  name: empservice
spec:
  ports:
   - port: 8080
     targetPort: 8080
     protocol: TCP
     name: http
     nodePort: 30062
  type: NodePort
  selector:
    name: empapp
    ---
    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: mongodbdepl
      labels:
        name: mongodb
    spec:
      replicas: 1
      template:
        metadata:
          labels:
            name: mongodb
        spec:
          containers:
          - resources:
              limits:
                cpu: 0.3
            image: mongo
            imagePullPolicy: IfNotPresent
            name: mongodb
            ports:
                  - containerPort: 27017
    ---
    apiVersion: v1
    kind: Service
    metadata:
      labels:
        name: mongowhatever
      name: mongoservice
    spec:
      ports:
       - port: 27017
         targetPort: 27017
         protocol: TCP
      selector:
        name: mongodb

请注意,mongodb服务不需要作为NodePort公开。

答案 3 :(得分:1)

Kubernetes允许服务使用其服务名称与其他服务进行通信,从而实现服务间通信。

在您的方案中,应该可以从其他服务访问redis服务 http://app-api-redis-svc.default:6379。这里默认是运行服务的命名空间。

这会将您的请求内部路由到目标容器端口上运行的redis pod

查看此link以了解kubernetes提供的不同服务发现选项

希望有所帮助