2017-08-16 76 views
3

目前,我已经在K8s服务中使用K8s API Pod来连接到K8s Redis服务,并使用它自己的K8s Pod。问题是,我使用的是NodePort,这意味着BOTH暴露给公众。我只希望API能够访问公众。问题是,如果我使Redis服务不公开,则API无法看到它。有没有办法连接两个服务而不向公众公开?如何让两个Kubernetes服务互相交谈?

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

回答

2

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

最后,当你配置达到了Redis的API,地址应app-api-redis-svc:6379

而这一切。我有很多以这种方式相互沟通的服务。如果这不适合你,请在评论中告诉我。

+0

我确实需要一个服务才能成为NodePort,这样公众或不同计算机上的某个人就可以打到它。那它是如何工作的?当涉及到网络时,我的速度很慢 –

+1

如果您希望Redis服务是私有的,那么Redis服务应该是ClusterIP。 API可以是NodePort或LoadBalancer,没关系。 –

+0

该应用如何解析“app-api-redis-svc”到集群IP? – kaizenCoder

1

我不知道Redis的,但我有一个类似的应用。我有一个Java web应用程序作为通过nodePort向外部世界公开的pod运行。我有一个mongodb容器作为一个容器运行。

在webapp部署规范中,我通过传递服务名称作为参数将其映射到mongodb服务的名称,我粘贴了下面的规范。您可以相应地进行修改。在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公开。

+0

这个例子中你没有暴露过mongo服务吗?该服务正在抓取'mongodb',并且它是带有NodePort的服务。我说得对吗? –

+1

是的,mongo服务是暴露的,这就是为什么我提到作为一个笔记,它不需要公开为节点端口。我没有使用它,但没有打扰从我的poc中删除它。流程就是这样。来自外部世界的请求 - > emp web服务 - >在内部连接到mongodb并存储数据。 – Vikram

+0

外部世界如何能够击中互联网服务?现在不是'ClusterIP'吗? –

1

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

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

您的要求提供给您的Redis吊舱的目标容器端口上运行

结帐这个内部路由,该link通过kubernetes

提供的服务发现选择不同的模式希望它可以帮助

0

我试图从所有的答案和我自己的研究中获得最好的结果,并做一个简短的指南,我希望你能找到帮助:

1。测试连通

连接到不同的吊舱,如红宝石荚:

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

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

ping redis 

它可以连接到端口? (我发现远程登录并没有对这项工作)

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 

核实这些选择也设置在你的豆荚上?

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