您如何使用 Kubernetes 设置两个相互通信的微服务,一个是 public,一个是私有的?

how do you set up two microservices that communicate with each other, one being public and one private, using Kubernetes?

我认为您可以在 -service.yaml 中进行配置。例如,我有一个前端和一个后端。前端应该是 public,我的后端应该是私有的。那么如何使用 Kubernetes 设置两个相互通信的微服务,一个是 public,一个是私有的?

前端-service.yaml

apiVersion: v1
kind: Service
metadata:
  creationTimestamp: null
  labels:
    app: frontend
  name: frontend
spec:
  ports:
  - port: 8081
    protocol: TCP
    targetPort: 8081
  selector:
    app: frontend
  type: LoadBalancer
status:
  loadBalancer: {}

后端-service.yaml

apiVersion: v1
kind: Service
metadata:
  creationTimestamp: null
  labels:
    app: backend
  name: backend
spec:
  ports:
  - port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    app: backend
  type: LoadBalancer
status:
  loadBalancer: {}

我试过的

kubectl apply -f frontend-deploy.yaml
kubectl get pods
kubectl apply -f frontend-service.yaml
kubectl get service
kubectl apply -f backend-deploy.yaml
kubectl get pods
kubectl apply -f backend-service.yaml
kubectl get service
kubectl expose deployment frontend --type=LoadBalancer --name=frontend-service.yaml

您应该将 ClusterIP type 用于私有/内部服务,这将使您的应用程序仅在集群内可用:

  • ClusterIP: Exposes the Service on a cluster-internal IP. Choosing this value makes the Service only reachable from within the cluster. This is the default ServiceType

...和 ​​LoadBalancer type 用于 public 服务,这些服务旨在接收来自集群外部的请求:

  • LoadBalancer: Exposes the Service externally using a cloud provider's load balancer. NodePort and ClusterIP Services, to which the external load balancer routes, are automatically created.

示例:

假设我已经创建了前端和后端部署 - 8081 端口上的前端和 8080 端口上的后端。服务 yaml 与您的类似(我在前端使用 LoadBalancer,在后端使用 ClusterIP)。前端服务在80端口,后端在8080:

apiVersion: v1
kind: Service
metadata:
  labels:
    app: frontend
  name: frontend
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 8081
  selector:
    app: frontend
  type: LoadBalancer
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: backend
  name: backend
spec:
  ports:
  - port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    app: backend
  type: ClusterIP

让我们检查一下服务:

$ kubectl get svc
NAME                                TYPE           CLUSTER-IP     EXTERNAL-IP      PORT(S)        AGE
backend                             ClusterIP      10.36.9.41     <none>           8080/TCP       19m
frontend                            LoadBalancer   10.36.4.172    xx.xxx.xxx.xxx   80:32126/TCP   19m

可以看出,两个服务都有 ClusterIP(用于集群内部通信),前端服务有一个具有 public IP 的 LoadBalancer。

让我们exec into a pod只使用服务名称向前端和后端发送请求:

root@my-nginx-deployment-5bbb68bb8f-jgvrk:/# curl backend:8080
"hello world backend"
root@my-nginx-deployment-5bbb68bb8f-jgvrk:/# curl frontend:80
"hello world frontend"

它工作正常,因为我执行到的 pod 位于同一命名空间(默认)。对于不同命名空间之间的通信,你 should use <service-name>.<namespace>.svc.cluster.local or ClusterIP:

root@my-nginx-deployment-5bbb68bb8f-jgvrk:/# curl backend.default.svc.cluster.local:8080
"hello world backend"
root@my-nginx-deployment-5bbb68bb8f-jgvrk:/# curl 10.36.9.41:8080
"hello world backend"

这就是 Kubernetes 中集群内部通信的工作方式

集群外的请求使用LoadBalancer IP(kubectl get svc命令中的EXTERNAL-IP):

user@shell-outside-the-cluster:~$ curl xx.xxx.xxx.xxx
"hello world frontend"

当您有多个应用程序并希望 public 公开时,请考虑使用 Ingress

同时检查这些: