Service 类型
- 1.NodePort
- 2.ClusterlP
- 3.LoadBalance
- 4.ExternalName
在《Service 概念与实战》一文中,Service 的发布使用的是 NodePort 类型。除此之外,Service 的发布还支持 ClusterlP、LoadBalancer 和 ExternalName 这 3 种类型。
1.NodePort
在把 Service 的 type
字段设置为 NodePort 时,Kubernetes 将在每个节点上随机分配一个端口作为外部用户访问的入口(该端口号的默认范围是 30000
- 32767
)。该端口允许外部用户访问集群内部的 Pod 应用。如果用户想指定 30000
- 32767
内某个具体的端口,则需要增加一个 nodePort
字段。
在以下 YAML 文件中,使用 nodePort
字段指定了一个自定义的端口号 31234
。
apiVersion: v1
kind: Service
metadata:
name: service-demo2
namespace: default
spec:
# 这里使用 NodePort 类型的 Service 将应用程序暴露给外部
type: NodePort
ports:
- name: http
# 为方便起见,一般将 targetport 字段的值设置为与 port 字段相同的值
port: 80
targetPort: 80
# 可选字段,自定义端口号
nodePort: 31234
protocol: TCP
# 定义标签选择器,将服务 Service 与匹配便签的一组 Pod 关联起来
selector:
app: nginx
端口类型 |
|
---|---|
nodePort | 外部机器可访问的端口,一般为 node 机器上开放的端口。nodePort 是 kubernetes 提供给集群外部客户访问 Service 入口的一种方式。 |
port | Kubernetes 中的服务之间访问的端口,是提供给集群内部客户访问 Service 的入口。例如,尽管 MySQL 容器暴露了 3306 端口,但是集群内其他容器需要通过 3306 端口访问该服务,外部机器不能访问 MySQL 服务,因为没有配置 nodePort 类型。 |
targetPort | targetPort 是 Pod 上的端口,容器的端口(最根本的端口入口),与制作容器时暴露的端口一致(DockerFile 中 EXPOSE),例如 docker.io 官方的 nginx 暴露的是 80 端口。从 port 和 nodePort 上到来的数据最终经过 kube-proxy 流入到后端 Pod 的 targetPort 上进入容器。 |
containerPort | containerPort 是在 Pod 控制器中定义的、Pod 中的容器需要暴露的端口。targetPort 和 containerPort 必须一致。 |
2.ClusterlP
这是 Service 默认的发布类型。它将在集群内部分配一个可以访问的虚拟 IP 地址,通过该地址暴露服务。因此,这种类型的 Service 只能够实现 同一个集群内部应用之间的相互访问。
下面来演示 ClusterIP 的使用。
通过 Deployment 创建应用的部署描述文件 service-clusterip1.yaml
,并在其中输入以下内容。
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: service-clusterip
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
使用 kubectl apply
命令创建 Deployment。
kubectl apply -f service-clusterip1.yaml
创建 Service 的描述文件 service-clusterip2.yaml
,并在其中输入以下内容。
apiVersion: v1
kind: Service
metadata:
name: service-clusterip
namespace: default
spec:
ports:
- name: http
port: 1234
protocol: TCP
targetPort: 80
selector:
app: nginx
这里没有指定 Service 的发布类型,默认就是 ClusterIP。同时这里将容器中的 80
端口暴露成了 1234
端口。
🚀 也可以使用
kubectl expose deployment my-deployment --port=1234 --target-port=80 --name=my-service
命令暴露应用。在这个例子中,my-deployment
是 Deployment 的名称,my-service
是 Service 的名称,--port=1234
是 Service 的端口,--target-port=80
是 Deployment 内部容器的端口。
使用 kubectl apply
命令创建 Service。
kubectl apply -f service-clusterip2.yaml
查看 Pod、Service 和 Endpoint 的详细信息。
kubectl get pod,svc,ep -o wide
输出的信息如下:
通过 Cluster IP 地址访问应用,将返回 Nginx 的首页。
curl 10.96.206.202:1234
3.LoadBalance
如果要使用外部的负载均衡器来访问应用(如 Google Cloud、AWS 和 OpenStack 等),则可以通过使用 LoadBalancer 类型的 Service 将 Kubernetes 集群中的 IP 地址和端口号自动加入公有云的 LoadBalancer 中,从而异步地实现负载均衡。
在以下 YAML 示例文件中,使用阿里云作为 Kubernetes 集群的外部负载均衡器。
apiVersion: v1
kind: Service
metadata:
name: service-loadbalancer
labels:
app: service-loadbalancer
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
name: main-port
selector:
app: service-loadbalancer
type: LoadBalancer
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: alicloud-controller-manager
spec:
replicas: 1
template:
metadata:
labels:
app: alicloud-controller-manager
spec:
containers:
- image: collenzhao/alicloud-controller-manager
name: alicloud-controller-manager
env:
- name: ACCESS_KEY_ID
value: 你的阿里云 ACCESS_KEY_ID
- name: ACCESS_KEY_SECRET
value: 你的阿里云ACCESS_KEY_SECRET
4.ExternalName
ExternalName 类型的 Service 可以将一个已经存在的 Service 映射到外部的 DNS 服务,而达到通过使用外部 DNS 服务解析服务应用的目的。
下面是 Kubernetes 官方提供的一个示例。
apiVersion: v1
kind: Service
metadata:
name: my-service
namespace: prod
spec:
type: ExternalName
externalName: my.database.example.com
🚀 在查找主机
my-service.prod.svc.cluster.local
时,Kubernetes 集群的 DNS 服务将返回my.database.example.com
。