目前,我在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
答案 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)
我将尝试从所有答案和我自己的研究中获取最佳效果并制作一份简短的指南,希望您能找到帮助:
连接到另一个广告连播,例如ruby pod:
kubectl exec -it some-pod-name -- /bin/sh
验证它是否可以ping到相关服务:
ping redis
可以连接到端口吗? (我发现telnet不能用于此)
nc -zv redis 6379
如果您的服务配置如下所示:
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提供的不同服务发现选项
希望有所帮助