How to Find the URL of a Service in Kubernetes – 如何在 Kubernetes 中查找服务的 URL

最后修改: 2024年 1月 26日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

Networking is an integral part of Kubernetes, with Service being one of its primitive networking objects. Kubernetes Service allows us to expose a network application to the external world. However, to access it, we must know its URL.

网络是Kubernetes不可分割的一部分,Service 是其最基本的网络对象之一。Kubernetes 服务允许我们向外部世界公开网络应用。但是,要访问它,我们必须知道它的 URL。

In this hands-on tutorial, we’ll discuss finding and using the Kubernetes service’s URL as a reliable network endpoint.

在本实践教程中,我们将讨论如何找到并使用 Kubernetes 服务的 URL 作为可靠的网络端点。

2. Setting up an Example

2.建立范例

We need to create a few Kubernetes objects to use as an example. To begin, let’s create Namespace objects.

我们需要创建几个 Kubernetes 对象作为示例。首先,让我们创建 Namespace 对象。

2.1. Creating Kubernetes Namespaces

2.1.创建 Kubernetes 命名空间

Kubernetes namespaces allow us to isolate the resources within the same cluster. So, let’s use the create command to create two namespaces – dev and stg:

Kubernetes 命名空间允许我们隔离同一集群内的资源。因此,让我们使用 create 命令创建两个命名空间–devstg

$ kubectl create ns dev
namespace/dev created

$ kubectl create ns stg
namespace/stg created

2.2. Creating Kubernetes Deployments

2.2.创建 Kubernetes 部署

In the previous step, we created two namespaces. Now, let’s deploy the Redis pod to those namespaces:

在上一步中,我们创建了两个命名空间。现在,让我们将 Redis pod 部署到这些命名空间:

$ kubectl create deploy redis-dev --image=redis:alpine -n dev
deployment.apps/redis-dev created

$ kubectl create deploy redis-stg --image=redis:alpine -n stg
deployment.apps/redis-stg created

Next, let’s verify that the pods have been created and that they’re in a healthy state:

接下来,让我们验证 pod 是否已创建,以及它们是否处于健康状态:

$ kubectl get pods -n dev
NAME                         READY   STATUS    RESTARTS   AGE
redis-dev-7b647c797c-c2mmg   1/1     Running   0          16s

$ kubectl get pods -n stg
NAME                        READY   STATUS    RESTARTS   AGE
redis-stg-d66978466-plfpv   1/1     Running   0          9s

Here, we can observe that the status of both pods is Running.

在这里,我们可以看到两个 pod 的状态都是Running

Now, the required setup is ready. In the upcoming sections, we’ll create a few Service objects to establish communication with these pods.

现在,所需的设置已准备就绪。在接下来的章节中,我们将创建一些 Service 对象,以便与这些 pod 建立通信。

3. Finding the URL of the ClusterIP Service

3.查找 ClusterIP 服务的 URL

In Kubernetes, the default service type is ClusterIP. For ClusterIP services, we can use the service name or its IP address as its URL. This allows us to limit communication only within the cluster. Let’s understand this with a simple example.

在 Kubernetes 中,默认服务类型是 ClusterIP对于 ClusterIP 服务,我们可以使用服务名称或其 IP 地址作为 URL。这样,我们就可以将通信限制在群集内部。让我们通过一个简单的例子来了解这一点。

3.1. Creating the ClusterIP Services

3.1.创建 ClusterIP 服务

First, let’s create ClusterIP Service objects in both namespaces:

首先,让我们在两个命名空间中创建 ClusterIP Service 对象:

$ kubectl expose deploy redis-dev --port 6379 --type ClusterIP -n dev
service/redis-dev exposed

$ kubectl expose deploy redis-stg --port 6379 --type ClusterIP -n stg
service/redis-stg exposed

In this example, we’ve used the expose command to create a Service object. The expose command uses the selectors of the Deployment object and creates a Service using the same selectors.

在本示例中,我们使用 expose 命令创建了一个 Service 对象。expose命令使用 Deployment 对象的选择器,并使用相同的选择器创建一个 Service 对象。

In the following sections, we’ll discuss how to find and use the names of these services as URLs.

在接下来的章节中,我们将讨论如何查找和使用这些服务的名称作为 URL。

3.2. Using the URL of the ClusterIP Service in the Same Namespace

3.2.在同一命名空间中使用 ClusterIP 服务的 URL

First, let’s use the get command to find the service name from the dev namespace:

首先,让我们使用 get 命令从 dev 命名空间中查找服务名称:

$ kubectl get svc -n dev
NAME        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
redis-dev   ClusterIP   10.100.18.154   <none>        6379/TCP   9s

In the output, the first column shows the service name. In our case, it’s redis-dev.

在输出结果中,第一列显示的是服务名称。在我们的例子中,它是 redis-dev

Now, let’s exec to the Redis pod that is deployed in the dev namespace, connect to the Redis server using redis-dev as a hostname, and execute the PING command:

现在,让我们执行到部署在 dev 命名空间中的 Redis pod,使用 redis-dev 作为主机名连接到 Redis 服务器,并执行 PING 命令:

$ kubectl exec -it redis-dev-7b647c797c-c2mmg -n dev -- sh
/data # redis-cli -h redis-dev PING
PONG
/data # exit

Here, we can see that the Redis server responds with the PONG message.

在这里,我们可以看到 Redis 服务器响应了 PONG 消息。

Finally, we execute the exit command to exit from the pod.

最后,我们执行 exit 命令退出 pod。

3.3. Using the URL of the ClusterIP Service From Another Namespace

3.3.从另一个命名空间使用 ClusterIP 服务的 URL

Let’s examine the format of a ClusterIP service URL:

让我们检查一下 ClusterIP 服务 URL 的格式:

<service-name>.<namespace>.<cluster-name>:<service-port>

We didn’t use the namespace and cluster-name in the previous example because we executed the command from the same namespace and cluster. In addition to that, we also skipped service-port because the Service was exposed using the default Redis port 6379.

在上一个示例中,我们没有使用 namespacecluster-name ,因为我们是在相同的命名空间和集群中执行命令的。除此之外,我们还跳过了 service-port,因为 Service 是使用默认 Redis 端口 6379 暴露的。

However, we need to specify a namespace name to use the ClusterIP service from another namespace. Let’s understand this with an example.

但是,我们需要指定一个命名空间名称,以便从另一个命名空间使用 ClusterIP 服务。让我们通过一个示例来理解这一点。

First, let’s find out the name of the service in the stg namespace:

首先,让我们找出 stg 命名空间中的服务名称:

$ kubectl get svc -n stg
NAME        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
redis-stg   ClusterIP   10.110.213.51   <none>        6379/TCP   9s

Now, let’s exec to the Redis pod that is deployed in the dev namespace, connect to the Redis server using redis-stg.stg as a hostname, and execute the PING command:

现在,让我们 exec 到部署在 dev 命名空间中的 Redis pod,使用 redis-stg.stg 作为主机名连接到 Redis 服务器,并执行 PING 命令:

$ kubectl exec -it redis-dev-7b647c797c-c2mmg -n dev -- sh
/data # redis-cli -h redis-stg.stg PING
PONG
/data # exit

In this example, we can see that the Redis server sends a PONG reply.

在这个示例中,我们可以看到 Redis 服务器发送了一个 PONG 回复。

An important thing to note is that we’ve used redis-stg.stg as a hostname, where redis-stg is the service name and stg is the namespace name in which the Service object was created.

需要注意的是,我们使用了 作为主机名的 redis-stg.stg,其中 redis-stg 是服务名称,stg 是创建 Service 对象的命名空间名称

3.4. Cleaning Up

3.4.清理

In the previous examples, we saw how to use the Service name as the URL.

在前面的示例中,我们看到了如何使用 Service 名称作为 URL。

Now, let’s use the delete command to clean up the services from the dev and stg namespaces:

现在,让我们使用 delete 命令来清理 devstg 命名空间中的服务:

$ kubectl delete svc redis-dev -n dev
service "redis-dev" deleted

$ kubectl delete svc redis-stg -n stg
service "redis-stg" deleted

4. Finding the URL of the NodePort Service

4.查找 NodePort 服务的 URL

The NodePort service allows external connectivity to the application using the IP address and port of the Kubernetes node. Let’s understand this by creating a NodePort service.

NodePort 服务允许使用 Kubernetes 节点的 IP 地址和端口与应用程序进行外部连接。让我们通过创建 NodePort 服务来了解这一点。

4.1. Creating the NodePort Service

4.1.创建 NodePort 服务

First, let’s use the expose command to create a Service with the type NodePort:

首先,让我们使用 expose 命令创建一个 Service 类型为 NodePort 的服务:

$ kubectl expose deploy redis-dev --port 6379 --type NodePort -n dev
service/redis-dev exposed

Next, let’s verify that the Service has been created:

接下来,让我们验证 Service 是否已创建:

$ kubectl get svc -n dev
NAME        TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
redis-dev   NodePort   10.111.147.176   <none>        6379:30243/TCP   2s

Here, we can see that the Service type is NodePort. In the second-to-last column, it shows that the Kubernetes node’s port 30243 is mapped to the pod’s port 6379.

在这里,我们可以看到 Service 类型是 NodePort。倒数第二列显示,Kubernetes 节点的端口 30243 被映射到 pod 的端口 6379

Now, we can use the IP address of the Kubernetes node and port 30243 from outside the cluster to access the Redis server. Let’s see this in action.

现在,我们可以使用 Kubernetes 节点的 IP 地址和端口 30243 从集群外部访问 Redis 服务器。让我们看看实际操作。

4.2. Using the URL of the NodePort Service

4.2.使用 NodePort 服务的 URL

First, let’s find the IP address of the Kubernetes node:

首先,让我们找到 Kubernetes 节点的 IP 地址:

$ kubectl get nodes -o wide
NAME       STATUS   ROLES           AGE   VERSION   INTERNAL-IP    EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
baeldung   Ready    control-plane   24h   v1.28.3   192.168.49.2   <none>        Ubuntu 22.04.3 LTS   5.15.0-41-generic   docker://24.0.7

Here, we’ve used the -o wide option with the Node objects to show the additional fields.

在这里,我们使用 -o wide 选项和 Node 对象来显示附加字段。

In the above output, the column with the header INTERNAL-IP shows the Kubernetes node’s IP address.

在上述输出中,标题为 INTERNAL-IP 的列显示 Kubernetes 节点的 IP 地址

Now, from the external machine, let’s connect to the Redis server using 192.168.49.2 as a hostname, 30243 as a port number, and execute the PING command:

现在,让我们从外部机器连接到 Redis 服务器,使用 192.168.49.2 作为主机名,30243 作为端口号,并执行 PING 命令:

$ redis-cli -h 192.168.49.2 -p 30243 PING
PONG

Here, we can see that the Redis server responds with a PONG message.

在这里,我们可以看到 Redis 服务器响应了一条 PONG 消息。

4.3. Cleaning Up

4.3.清理

In the next section, we’re going to see the usage of the LoadBalancer service. But before that, let’s do the cleanup of the NodePort service from the dev namespace:

在下一节中,我们将了解 LoadBalancer 服务的用法。但在此之前,我们先清理一下 dev 命名空间中的 NodePort 服务:

$ kubectl delete svc redis-dev -n dev
service "redis-dev" deleted

5. Finding the URL of the LoadBalancer Service

5.查找 LoadBalancer 服务的 URL

Just like the NodePort service, the LoadBalancer service also allows external connectivity to the application using the load balancer’s IP address. To understand this, let’s create a LoadBalancer service:

NodePort 服务一样,LoadBalancer 服务也允许使用负载平衡器的 IP 地址与应用程序进行外部连接。为了理解这一点,让我们创建一个 LoadBalancer 服务:

5.1. Creating the LoadBalancer Service

5.1.创建 LoadBalancer 服务

Let’s use the expose command to create a LoadBalancer service in the dev namespace:

让我们使用 expose 命令在 dev 命名空间中创建一个 LoadBalancer 服务:

$ kubectl expose deploy redis-dev --port 6379 --type LoadBalancer -n dev
service/redis-dev exposed

5.2. Using the URL of the LoadBalancer Service

5.2.使用 LoadBalancer 服务的 URL

Next, let’s use the get command to find the load balancer’s IP address:

接下来,让我们使用 get 命令来查找负载平衡器的 IP 地址:

$ kubectl get svc -n dev
NAME        TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)          AGE
redis-dev   LoadBalancer   10.111.167.249   192.168.49.10   6379:32637/TCP   7s

In this example, the column with the header EXTERNAL-IP represents the LoadBalancer service’s IP address.

在此示例中,带有页眉 EXTERNAL-IP 列表示 LoadBalancer 服务的 IP 地址

In our case, the load balancer’s IP address is 192.168.49.10.

在我们的例子中,负载平衡器的 IP 地址是 192.168.49.10

Now, from the external machine, let’s connect to the Redis server using 192.168.49.10 as a hostname and execute the PING command:

现在,让我们从外部计算机使用 192.168.49.10 作为主机名连接 Redis 服务器,并执行 PING 命令:

$ redis-cli -h 192.168.49.10 PING
PONG

In the output, we can see that the Redis server replies with a PONG message.

在输出中,我们可以看到 Redis 服务器回复了一条 PONG 消息。

6. Cleaning Up

6.清理

Deleting all unwanted objects to tidy up the cluster is a good practice. This helps us in lowering our costs by reducing hardware consumption.

删除所有不需要的对象以整理集群是一种很好的做法。这有助于我们通过减少硬件消耗来降低成本。

So, let’s use the delete command to remove the dev and stg namespaces:

因此,让我们使用 delete 命令来删除 devstg 命名空间:

$ kubectl delete ns dev
namespace "dev" deleted

$ kubectl delete ns stg
namespace "stg" deleted

This command deletes the namespace itself and all objects that are present in this namespace.

该命令将删除命名空间本身和命名空间中的所有对象。

Here, we deleted namespaces directly, as this is the test setup. However, we should be very careful while performing delete operations in the production environment.

在这里, 我们直接删除了命名空间,因为这是测试设置。但是,在生产环境中执行删除操作时,我们应该非常小心

7. Conclusion

7.结论

In this article, we discussed how to find and use the URL of a service in Kubernetes.

在本文中,我们讨论了如何在 Kubernetes 中查找和使用服务的 URL。

First, we saw how to use the ClusterIP service name as a URL from the same and another namespace. Then, we discussed how to find and use the URL of the NodePort service.

首先,我们了解了如何使用 ClusterIP 服务名称作为同一命名空间和另一命名空间的 URL。然后,我们讨论了如何查找和使用 NodePort 服务的 URL。

Finally, we discussed using the load balancer’s IP address as a service URL.

最后,我们讨论了使用负载平衡器的 IP 地址作为服务 URL 的问题。