将本地执行的服务(minikube)集成到 Kubernetes 集群中
Integrate locally executed service (minikube) into Kubernetes cluster
我目前正在为现有设置设计一个 Kubernetes 集群,其中包括大约十个服务。之前,我已经使用 minikube 在本地开发和测试了这些服务,后来我在不同的物理机器(我们称之为暂存系统)上发布了一个自托管的 Kubernetes 实例。其中一些部署的服务需要访问同一网络中其他机器上的资源。这意味着我的开发环境 (minikube) 也需要访问这些外部资源。这是此集群中一个进程的简短 "mockup"。
+-----------+
| External |
| Service X |
+-----------+
^
|
+-----------+ +-----------+
| Service A | <-- | Service B |
+-----------+ +-----------+
由于某些网络更改,我无法再访问这些远程资源,这意味着无法再从我的本地计算机访问外部服务 X。我知道问是否有可能在我的本地机器上托管服务 B,但 "connect" 它到我的远程集群。是否有可能将 minikube 用作现有 Kubernetes 实例的简单节点?我严重依赖 CoreDNS 的服务发现,这意味着我想找到基础架构级别的解决方案而不是应用程序级别的方法。如果登台系统甚至不知道我的服务 B 不是本地托管的,那将是理想的。如果这可能是一个愚蠢的问题,我很抱歉,但目前看来我对 Kubernetes 的了解有点不足。
如果你有两个独立的 kubernetes 集群 例如Minikube 和其他一些 远程 kubernetes 集群 的本地实例,并且您希望它们能够相互交互,您可以为此目的使用称为 Services without selectors.
您可以将您的远程 kubernetes 集群 视为任何其他外部资源(例如数据库服务器 运行 在一个单独的 machine/vm 上)并且您可以公开它在您的集群内部。通常我们在 k8s 集群 上向外部公开一些 运行 的东西,但在这种情况下,我们希望在内部向我们的集群公开一个外部资源,就好像它是另一个内部资源一样。从 Pods
的角度来看,它实际上看起来像一个内部资源,在其本地集群域下可用,其方式与内部资源完全相同,由简单的 ClusterIP
服务公开。
让我们快速了解一下如何实现它。在官方 kubernetes 文档的 this section 中对此有很好的解释:
Services most commonly abstract access to Kubernetes Pods, but they
can also abstract other kinds of backends. For example:
- You want to have an external database cluster in production, but in your test environment you use your own databases.
- You want to point your Service to a Service in a different Namespace
or on another cluster.
- You are migrating a workload to Kubernetes. Whilst evaluating the approach, you run only a proportion of your backends in Kubernetes.
In any of these scenarios you can define a Service without a Pod
selector. For example:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9376
Because this Service has no selector, the corresponding Endpoint
object is not created automatically. You can manually map the Service
to the network address and port where it’s running, by adding an
Endpoint object manually:
apiVersion: v1
kind: Endpoints
metadata:
name: my-service
subsets:
- addresses:
- ip: 192.0.2.42
ports:
- port: 9376
如果提到的 dev 和 staging 环境之间只有网络连接,您可以使用没有选择器的 Services 。如果你需要你的 Minikube 集群能够连接到你的 staging 集群在 192.0.2.42:9376
上公开的东西,你只需要使用此 IP 在您的 Endpoints 对象定义中。服务被定义为监听 por 80
所以它最终会在这个标准端口下在内部暴露给你 Minikube Pods
.
这种解决方案的最大优点是,这种 Service
使特定的外部资源在您本地 k8s 集群 上的 Pods
中运行的应用程序内部可用,并且他们可以使用它的 DNS 名称 来引用它,即在同一个 namespace
中的 service-name
或通过来自任何 namespace
集群的 FQDN <my-service-name>.<namespace>.svc.cluster.local
-宽。
如果您的外部资源在域名下可用,您也可以考虑使用ExternalName,这是一个特殊的没有选择器的服务类型,在这种情况下,您不必手动配置任何Endpoints
对象。它的定义可能如下所示:
apiVersion: v1
kind: Service
metadata:
name: my-service
namespace: prod
spec:
type: ExternalName
externalName: my.database.example.com
我目前正在为现有设置设计一个 Kubernetes 集群,其中包括大约十个服务。之前,我已经使用 minikube 在本地开发和测试了这些服务,后来我在不同的物理机器(我们称之为暂存系统)上发布了一个自托管的 Kubernetes 实例。其中一些部署的服务需要访问同一网络中其他机器上的资源。这意味着我的开发环境 (minikube) 也需要访问这些外部资源。这是此集群中一个进程的简短 "mockup"。
+-----------+
| External |
| Service X |
+-----------+
^
|
+-----------+ +-----------+
| Service A | <-- | Service B |
+-----------+ +-----------+
由于某些网络更改,我无法再访问这些远程资源,这意味着无法再从我的本地计算机访问外部服务 X。我知道问是否有可能在我的本地机器上托管服务 B,但 "connect" 它到我的远程集群。是否有可能将 minikube 用作现有 Kubernetes 实例的简单节点?我严重依赖 CoreDNS 的服务发现,这意味着我想找到基础架构级别的解决方案而不是应用程序级别的方法。如果登台系统甚至不知道我的服务 B 不是本地托管的,那将是理想的。如果这可能是一个愚蠢的问题,我很抱歉,但目前看来我对 Kubernetes 的了解有点不足。
如果你有两个独立的 kubernetes 集群 例如Minikube 和其他一些 远程 kubernetes 集群 的本地实例,并且您希望它们能够相互交互,您可以为此目的使用称为 Services without selectors.
您可以将您的远程 kubernetes 集群 视为任何其他外部资源(例如数据库服务器 运行 在一个单独的 machine/vm 上)并且您可以公开它在您的集群内部。通常我们在 k8s 集群 上向外部公开一些 运行 的东西,但在这种情况下,我们希望在内部向我们的集群公开一个外部资源,就好像它是另一个内部资源一样。从 Pods
的角度来看,它实际上看起来像一个内部资源,在其本地集群域下可用,其方式与内部资源完全相同,由简单的 ClusterIP
服务公开。
让我们快速了解一下如何实现它。在官方 kubernetes 文档的 this section 中对此有很好的解释:
Services most commonly abstract access to Kubernetes Pods, but they can also abstract other kinds of backends. For example:
- You want to have an external database cluster in production, but in your test environment you use your own databases.
- You want to point your Service to a Service in a different Namespace or on another cluster.
- You are migrating a workload to Kubernetes. Whilst evaluating the approach, you run only a proportion of your backends in Kubernetes.
In any of these scenarios you can define a Service without a Pod selector. For example:
apiVersion: v1 kind: Service metadata: name: my-service spec: ports: - protocol: TCP port: 80 targetPort: 9376
Because this Service has no selector, the corresponding Endpoint object is not created automatically. You can manually map the Service to the network address and port where it’s running, by adding an Endpoint object manually:
apiVersion: v1 kind: Endpoints metadata: name: my-service subsets: - addresses: - ip: 192.0.2.42 ports: - port: 9376
如果提到的 dev 和 staging 环境之间只有网络连接,您可以使用没有选择器的 Services 。如果你需要你的 Minikube 集群能够连接到你的 staging 集群在 192.0.2.42:9376
上公开的东西,你只需要使用此 IP 在您的 Endpoints 对象定义中。服务被定义为监听 por 80
所以它最终会在这个标准端口下在内部暴露给你 Minikube Pods
.
这种解决方案的最大优点是,这种 Service
使特定的外部资源在您本地 k8s 集群 上的 Pods
中运行的应用程序内部可用,并且他们可以使用它的 DNS 名称 来引用它,即在同一个 namespace
中的 service-name
或通过来自任何 namespace
集群的 FQDN <my-service-name>.<namespace>.svc.cluster.local
-宽。
如果您的外部资源在域名下可用,您也可以考虑使用ExternalName,这是一个特殊的没有选择器的服务类型,在这种情况下,您不必手动配置任何Endpoints
对象。它的定义可能如下所示:
apiVersion: v1 kind: Service metadata: name: my-service namespace: prod spec: type: ExternalName externalName: my.database.example.com