Exposing containers
在 Kubernetes 中,当我们需要让 Pod 对外部可访问时,可以通过创建服务(Service)来实现。服务为 Pod 提供了一个稳定的地址,使得其他服务或者用户可以通过它来访问 Pod。以下是如何使用 kubectl expose
命令来创建服务的步骤:
创建服务:
-
命令示例
bash$ kubectl expose deployment pingpong --type=ClusterIP --port=8080
-
解释 :
- 这个命令会为名为
pingpong
的部署创建一个服务。这个服务允许内部网络中的其他组件通过一个固定的 IP 地址来访问这个部署的 Pods。
- 这个命令会为名为
-
服务解析:
- 一旦服务被创建,CoreDNS(Kubernetes 的内置 DNS 服务器)将能够通过服务的名称来解析它的地址。例如,如果创建了名为
hello
的服务,通过 DNS 查询hello
将能解析到这个服务的 IP 地址。
- 一旦服务被创建,CoreDNS(Kubernetes 的内置 DNS 服务器)将能够通过服务的名称来解析它的地址。例如,如果创建了名为
-
服务的类型:
- ClusterIP: 默认类型,分配一个内部 IP 供集群内部通讯使用,外部无法直接访问。
- NodePort: 在每个节点上打开一个端口,使得服务可以从集群外部访问。它通常用于开发和测试环境。
- LoadBalancer: 使用云服务提供商的负载均衡器将外部流量转发到服务。这是在生产环境中经常使用的类型,以实现高可用性。
- ExternalName: 允许通过 DNS 名称返回一个任意字符串,通常用于服务发现机制内部的资源。
-
通俗解释:
可以将服务想象为一个电话交换机,它为一个或多个工作中的电话(Pods)提供了一个电话号码(服务地址)。不管这些电话具体在哪个房间(节点),打电话的人(其他服务或用户)只需要拨打这个号码,交换机就会自动连接到正确的电话。不同的服务类型就像是不同种类的电话服务,有的仅限于内部拨打(ClusterIP),有的可以接收外部来电(NodePort 和 LoadBalancer),而 ExternalName 则像是一个电话转接服务。
基本服务类型
在 Kubernetes 中,服务(Service)是定义如何访问一组特定的 Pods 的抽象方式。下面是两种常见服务类型的详细说明:
*
#### **ClusterIP(默认类型)**:
* **虚拟 IP 地址**: 为服务分配一个内部的、私有的虚拟 IP 地址,这个地址仅在集群内部(节点和 Pods)可达。
* **连接方式**: 我们的代码可以使用原始的端口号连接到服务。这意味着不需要任何特殊的网络配置就可以访问服务。
#### **NodePort**:
* **端口分配**: 为服务分配一个端口(默认范围是 30000-32768),这个端口在集群的所有节点上都可用,任何人都可以通过这个端口连接到服务。
* **代码修改**: 我们的代码必须改为连接到这个新的端口号。这是因为外部流量需要通过一个特定的节点端口来访问集群内部的服务。
-
这些服务是通过在每个节点上运行的
kube-proxy
组件来实现的。kube-proxy
使用用户空间的代理和一组 iptables 规则来处理进入节点的流量,确保它被正确地转发到对应的服务端口。-
ClusterIP 就像是一个内部电话系统,只能在公司内部使用。每个服务都有一个内部号码,公司内的员工(集群内的 Pods)可以直接拨打这个号码来相互连接。
-
NodePort 类似于给公司的每个入口安装一个电话,这个电话有一个特定的公共号码。任何人(包括公司外部的人)都可以拨打这个号码来联系公司内部的人。
-
-
节点(Node):
- 节点是 Kubernetes 集群中的一个工作机,可以是物理机或虚拟机。每个节点都能运行应用程序的容器,包括 Pods。
- 集群中的节点分为两种类型:主节点(Master Node) 和 工作节点(Worker Node)。主节点管理集群的整体运行,而工作节点则是实际运行 Pods 的地方。
-
Pods:
- Pod 是 Kubernetes 中的基本运行单元,每个 Pod 包含一个或多个容器(例如,Docker 容器)。Pod 内的容器共享网络和存储资源。
- Pod 被设计为临时的或易失的资源,这意味着当 Pod 因某些原因停止运行时,Kubernetes 可以快速地在任何工作节点上重建它们。
-
内部与外部:
- 内部:通常指的是 Kubernetes 集群的内部网络环境。只有集群内的其他服务或 Pods 可以访问部署在内部的资源。例如,使用 ClusterIP 类型的服务创建的内部 IP 地址只能被集群内的其他 Pods 或服务访问。
- 外部:指的是集群外部的环境,也就是除了 Kubernetes 集群之外的网络环境。如果希望让外部用户或服务访问集群内的应用,需要使用特定类型的服务(如 NodePort 或 LoadBalancer)来暴露相应的端口或接口。
- 运行带有开放端口的容器:
- 由于 ping 没有连接对象,我们必须运行其他东西。 我们将使用 jpetazzo/httpenv,这是一个用 Go 编写的小型 HTTP 服务器。 jpetazzo/httpenv 监听端口 8888。
- 它以 JSON 格式提供其环境变量。 环境变量将包括 HOSTNAME,这将是 pod 名称(因此,每个后端将有所不同)。
如何在 Kubernetes 中部署 jpetazzo/httpenv
容器
-
Docker 镜像:
- 镜像说明 :
jpetazzo/httpenv
是一个包含用 Go 语言编写的微型 HTTP 服务器的 Docker 镜像。这个服务器配置为监听 8888 端口。 - 功能特点 :
- 监听端口:服务器监听 8888 端口,这意味着容器将在此端口接收进来的请求。
- 输出内容:它会以 JSON 格式输出所有容器可访问的环境变量。这包括 Kubernetes 设置的变量以及你定义的任何自定义变量。
- 动态 HOSTNAME :JSON 输出包括
HOSTNAME
变量,Kubernetes 会自动将其设置为 Pod 的名称。由于每个 Pod 都有唯一的名称,所以HOSTNAME
将在不同的后端中有所不同,提供了识别响应 Pod 的方式。
- 镜像说明 :
-
在 Kubernetes 中部署容器:
-
你可以在 Kubernetes 中部署这个容器,并通常通过服务来使其可访问。下面是一个设置示例:
bashapiVersion: apps/v1 kind: Deployment metadata: name: httpenv-deployment spec: replicas: 2 selector: matchLabels: app: httpenv template: metadata: labels: app: httpenv spec: containers: - name: httpenv image: jpetazzo/httpenv ports: - containerPort: 8888 --- apiVersion: v1 kind: Service metadata: name: httpenv-service spec: type: ClusterIP selector: app: httpenv ports: - port: 8888 targetPort: 8888
解释:
-
-
部署 :此 YAML 文件创建名为
httpenv-deployment
的部署。它指定了 2 个副本,意味着 Kubernetes 将确保始终运行两个容器实例。 -
Pod 配置 :每个运行
httpenv
容器的 Pod 将暴露 8888 端口。 -
服务 :
httpenv-service
是一种ClusterIP
类型的服务,意味着它仅在集群内部可访问。它将流量路由到标有app: httpenv
标签的任一 Pod 的 8888 端口。
部署和访问服务
- 部署 YAML :使用
kubectl apply -f <filename>.yaml
命令创建 YAML 文件中定义的资源。 - 访问服务 :在集群内部,可以在
httpenv-service:8888
地址访问服务,它将响应 JSON 格式的环境变量。
监控 Pod 的创建
在 Kubernetes 中操作时,通常我们希望实时监控资源状态的变化。为此,我们可以开启一个命令窗口来实时监控 Pod 的状态:
bash
$ kubectl get pods -w
解释:
kubectl get pods -w
命令会列出所有的 Pod 并持续观察它们的状态变化。这里的-w
参数表示 watch(监视)模式,使你能实时看到 Pod 的创建和状态更新。
创建部署
为了运行 jpetazzo/httpenv
这个轻量级 HTTP 服务器,我们需要创建一个 Kubernetes 部署:
bash
$ kubectl create deployment httpenv --image=jpetazzo/httpenv
解释:
- 这个命令创建了一个名为
httpenv
的部署。 --image=jpetazzo/httpenv
指定使用jpetazzo/httpenv
镜像,这是一个基于 Go 语言编写的简单 HTTP 服务器,能显示出环境变量的 JSON 数据。
扩展部署
一旦部署创建完成,你可能需要根据负载来增加服务器的副本数。我们可以通过以下命令将部署扩展到 10 个副本:
bash
$ kubectl scale deployment httpenv --replicas=10
解释:
kubectl scale deployment httpenv --replicas=10
命令会将httpenv
部署的副本数设置为 10。- 这意味着 Kubernetes 将确保总共有 10 个
httpenv
Pod 在运行,以处理更多的网络请求。
总结
通过这些步骤,你已经成功地在 Kubernetes 集群中部署了一个轻量级的 HTTP 服务器,并根据需要扩展了其服务能力。这样的设置不仅能够处理更多的并发请求,也提高了应用的可用性和容错能力。这些操作展示了 Kubernetes 强大的容器编排和扩展能力。
以下是在 Kubernetes 中创建一个默认的 ClusterIP 服务以及如何暴露你的 HTTP 服务器端口的具体步骤,包括命令的翻译和操作的解释:
查看初始服务
在创建新的服务之前,我们可以先查看当前 Kubernetes 集群中已有的服务:
bash
$ kubectl get service
解释:
kubectl get service
命令会列出当前集群中所有的服务。这可以帮助你了解哪些服务已经在运行,以及它们的状态。
暴露 HTTP 服务器的端口
为了使外部可以访问我们的 HTTP 服务器,我们需要创建一个服务来暴露相应的端口。这里我们使用的是 Kubernetes 的 expose
命令:
bash
$ kubectl expose deployment httpenv --port 8888
解释:
kubectl expose deployment httpenv --port 8888
命令创建一个新的服务,并将httpenv
部署的 8888 端口暴露出来。- 默认情况下,此命令创建的服务类型是 ClusterIP,这意味着这个服务只能在集群内部访问。
查看分配的 IP 地址
创建服务后,你可能想知道这个服务被分配了哪个 IP 地址。可以通过以下命令查看:
bash
$ kubectl get service
解释:
- 再次执行
kubectl get service
命令会显示所有服务,包括刚刚创建的httpenv
服务。输出中将包括服务的 ClusterIP,这是服务在集群内部通信使用的 IP 地址。
总结
通过这些步骤,你已经成功地为你的 HTTP 服务器创建了一个内部服务,并暴露了必要的端口,使得集群内的其他应用或服务能够访问它。这个 ClusterIP 服务确保了服务的稳定访问,而且是在集群内部网络中进行,保证了通信的安全性和隔离性。
Testing our service
要从本地机器访问部署在 Kubernetes 集群中的服务,你可以使用端口转发功能。这使得本地端口直接连接到集群中的服务。以下是详细的步骤和命令解释:
端口转发
使用 kubectl port-forward
命令,可以将集群内部服务的端口转发到本地机器的端口。这对于开发和测试非常有用,因为你可以直接从你的开发机器访问服务。
bash
$ kubectl port-forward service/httpenv 8888:8888
解释:
kubectl port-forward service/httpenv 8888:8888
命令将本地机器的 8888 端口连接到通过httpenv
服务暴露的 8888 端口。- 这意味着在本地机器上访问
localhost:8888
时,请求将被转发到集群中的httpenv
服务。
发送请求
你可以使用 curl
命令从本地机器发送请求到通过端口转发设置的服务:
bash
curl http://localhost:8888/
这条命令将向你的 HTTP 服务器发送一个请求,并显示服务器返回的所有环境变量的 JSON 格式数据。
过滤输出
如果输出太多,你可以使用 jq
工具来过滤并只显示特定的数据。例如,只查看 HOSTNAME
环境变量:
bash
curl -s http://localhost:8888/ | jq .HOSTNAME
解释:
curl -s http://localhost:8888/
发送请求到服务器并抑制curl
的进度输出。| jq .HOSTNAME
将curl
的输出通过管道传递给jq
,jq
是一个处理 JSON 的命令行工具,这里它被用来从 JSON 数据中提取HOSTNAME
字段的值。
总结
通过以上步骤,你可以轻松地从本地机器访问和测试运行在 Kubernetes 集群中的服务。端口转发是一种便捷的方法,可以帮助开发者直接与集群中的服务交互,而无需配置复杂的网络或暴露服务到外部网络。这对于开发和调试应用程序是非常有帮助的。
在 Kubernetes 中,服务(Service)通过"端点(Endpoints)"连接到后端的 Pods,确保服务能够平稳运行。下面,我将详细说明如何查看 Kubernetes 服务相关联的端点,并解决当端点众多时,显示命令可能截断列表的问题。
• A service has a number of "endpoints" that are maintained and updated automatically by Kubernetes
• Each endpoint is a host + port where the service is available
查看服务的端点
要查看 httpenv
服务相关联的端点,你可以使用 kubectl describe
命令,这将提供服务的详细描述,包括端点信息:
bash
$ kubectl describe service httpenv
解释:
- 运行该命令后,输出结果中将有一行以"Endpoints:"开头,这一行列出了服务可用的一系列地址,格式为 host。
- 这些地址代表了能够处理该服务请求的具体 Pods 的 IP 地址和它们的端口。
处理端点列表截断问题
如果服务关联了很多端点,kubectl describe
命令显示的信息可能会被截断。为了查看完整的端点列表,可以使用 kubectl get endpoints
命令:
bash
$ kubectl get endpoints
解释:
-
kubectl get endpoints
命令会列出所有服务的端点,通常以一种更简洁的格式显示。 -
为了获取特定服务的详细端点信息,你可以特别指定服务名称:
bash$ kubectl get endpoints httpenv
-
这个命令将只显示
httpenv
服务的端点,无论其数量多少,都不会截断信息。
总结
通过上述步骤,你可以有效地查看和管理 Kubernetes 中的服务端点。理解服务与端点的关系及其动态更新机制对于管理和调试 Kubernetes 中的网络流量至关重要。这些端点的正确配置和监控可以确保服务的高可用性和网络性能。