Kubernetes 为不同命名空间中的两个部署部署单个 NodePort

时间:2021-04-13 12:23:32

标签: kubernetes kubernetes-service kubernetes-deployment

我必须在我的 kubernetes 集群上部署两个使用相同服务进行通信的部署,但是这两个部署位于两个不同的命名空间中:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app1
  namespace: namespace1
  labels:
    app: app1
spec:
  replicas: 2
  selector:
    matchLabels:
      app: app1
  template:
    metadata:
      labels:
        app: app1
    spec:
      containers:
        - name: app1
          image: eu.gcr.io/direct-variety-20998876/test1:dev
          resources:
            requests:
              cpu: "100m"
              memory: "128Mi"
          ports:
            - containerPort: 8000
          imagePullPolicy: Always
          env:
              ...

和同一秒,但在另一个空间:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app2
  namespace: namespace2
  labels:
    app: app2
spec:
  replicas: 2
  selector:
    matchLabels:
      app: app2
  template:
    metadata:
      labels:
        app: app2
    spec:
      containers:
        - name: app2
          image: eu.gcr.io/direct-variety-20998876/test1:prod
          resources:
            requests:
              cpu: "100m"
              memory: "128Mi"
          ports:
            - containerPort: 8000
          imagePullPolicy: Always
          env:
              ...

所以我必须为在两个命名空间上运行的机器人部署创建一个公共服务: 我试试:

kind: Service
apiVersion: v1
metadata:
  name: apps-service
  namespace: ???
spec:
  selector:
    app: ???
  ports:
  - protocol: TCP
    port: 8000
    targetPort: 8000
  type: NodePort

到目前为止,我为特定命名空间中的任何应用程序创建了一个服务,但有一种方法可以创建一个服务来管理这两个部署(然后关联一个唯一的入口)?

非常感谢

1 个答案:

答案 0 :(得分:1)

首先,我想提供一些一般性的解释。 正如我们在 Ingress documentation 中看到的:

<块引用>

你必须有一个 Ingress 控制器才能满足一个 Ingress。仅创建 Ingress 资源无效。

Ingress Controller 可以部署在任何命名空间中,并且通常部署在与应用命名空间分开的命名空间中。

Ingress resource(入口规则)应部署在与它们指向的服务相同的命名空间中。

多个入口资源可以有一个入口控制器。

在与其指向的 Ingress 相同的命名空间中部署 Services 资源是最常见的方法(我推荐这种方法)。 但是,可以使用 externalName 服务在一个命名空间中使用 Ingress,在另一个命名空间中使用 Services


我将创建一个示例来说明它是如何工作的。

假设,我在两个不同的 Deployments (app1, app2) 中部署了两个 Namespaces (namespace1, namespace2):< /p>

$ cat app1.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: app1
  name: app1
  namespace: namespace1
spec:
  selector:
    matchLabels:
      app: app1
  template:
    metadata:
      labels:
        app: app1
    spec:
      containers:
      - image: nginx
        name: nginx
    
$ cat app2.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: app2
  name: app2
  namespace: namespace2
spec:
  selector:
    matchLabels:
      app: app2
  template:
    metadata:
      labels:
        app: app2
    spec:
      containers:
      - image: nginx
        name: nginx
    

我用 Deployments ClusterIP 暴露了这些 Services

$ cat svc-app1.yml
apiVersion: v1
kind: Service
metadata:
  labels:
    app: app1
  name: app1
  namespace: namespace1
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: app1
    
$ cat svc-app2.yml
apiVersion: v1
kind: Service
metadata:
  labels:
    app: app2
  name: app2
  namespace: namespace2
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: app2

我们希望在单独的 Ingress (Namespace) 中拥有单个 default 资源。 首先,我们需要部署类型为 ExternalName 的服务,将服务映射到 DNS 名称。

$ cat external-app1.yml
kind: Service
apiVersion: v1
metadata:
  name: external-app1
spec:
  type: ExternalName
  externalName: app1.namespace1.svc
  
$ cat external-app2.yml
kind: Service
apiVersion: v1
metadata:
  name: external-app2
spec:
  type: ExternalName
  externalName: app2.namespace2.svc

然后我们就可以部署 Ingress 资源了:

$ cat ingress.yml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /
  name: app-ingress
spec:
  rules:
    - http:
        paths:
          - path: /app1
            backend:
              serviceName: external-app1
              servicePort: 80
          - path: /app2
            backend:
              serviceName: external-app2
              servicePort: 80
              
$ kubectl apply -f ingress.yml
ingress.networking.k8s.io/app-ingress created
          

最后,我们可以检查它是否按预期工作:

$ curl 34.118.X.207/app1
app1
$ curl 34.118.X.207/app2
app2

注意:这是一种解决方法,对于不同的入口控制器可能会有不同的工作方式。通常在不同的命名空间中拥有两个或多个 Ingress 资源会更好。