如何让两个 Kubernetes 服务相互对话?

How to make two Kubernetes Services talk to each other?

目前,我在连接到 K8s Redis 服务的 K8s 服务中使用 K8s API pods,K8s pods 是它自己的。问题是,我正在使用 NodePort,这意味着两者都暴露给 public。我只希望 API 可以访问 public。问题是,如果我让 Redis 服务不是 public,API 就看不到它。有没有一种方法可以在不将一个服务暴露给 public 的情况下连接两个服务?

这是我的 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

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

在 webapp 部署规范中,我通过服务名称作为参数将其映射到 mongodb 服务,我已将规范粘贴在下面。您可以修改 accordingly.There 应该是 Redis 中类似的映射参数,在我的例子中您还必须使用服务名称“mongoservice”。

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 公开。

首先,将 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

仅此而已。我有很多服务以这种方式相互通信。如果这对您不起作用,请在评论中告诉我。

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

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

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

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

希望对您有所帮助

我将尽力从所有答案和我自己的研究中汲取精华,并制作一个简短的指南,希望对您有所帮助:

1。测试连通性

连接到不同的 pod,例如 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

确认这些选择器也在您的 pods 上设置了吗?

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

通过 运行 确认您的服务与您的 pods 绑定:

$> 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