K8S 之 Service
摘要
-
本文介绍 K8S 的 Service ,本文以 CentOS 8 为例。
Service 介绍
-
Service(缩写为 svc)是一个抽象层,它定义了一组Pod的逻辑集,并为这些Pod支持外部流量暴露、负载均衡和服务发现。
-
尽管每个Pod 都有一个唯一的IP地址,但是如果没有Service,这些IP不会暴露在群集外部。
-
Service允许您的应用程序接收流量。
-
Service也可以用在ServiceSpec标记type的方式暴露,type类型如下:
- ClusterIP(默认):在集群的内部IP上公开Service。这种类型使得Service只能从集群内访问。
- NodePort:使用NAT在集群中每个选定Node的相同端口上公开Service。使用
: 从集群外部访问Service。是ClusterIP的超集。 - LoadBalancer:在当前云中创建一个外部负载均衡器(如果支持的话),并为Service分配一个固定的外部IP。是NodePort的超集。
- ExternalName:通过返回带有该名称的CNAME记录,使用任意名称(由spec中的externalName指定)公开Service。不使用代理。
创建Service
ClusterIP
-
只能在集群内部访问
1 | # 先创建deployment,此时会为每个pod添加一个label app=nginx |
NodePort
-
暴露宿主机的端口,供外部访问
1 | # 创建service,将deployment的pod暴露出来,暴露类型为NodePort |
yaml文件创建service
-
yaml文件格式
1 | apiVersion: v1 # api版本 |
-
这里有个问题需要注意,service 默认是通过
标签
来匹配pod的,所以创建service的时候,一定要保证pod的标签是存在的,否则service无法匹配pod,另外虽然我们通过命令行创建service时是通过kubectl expose deployment nginx --type=NodePort --port=80
创建的,但也并不表示service只会匹配这个deployment创建的pod,而是会匹配所有具有指定标签的pod(app=nginx)。
1 | # 获取service的 selector |
ExternalName
-
可以将其它 namespace 的 service 别名到 当前 namespace,这样访问 service 时就不需要加上命名空间名称了
-
ExternalName Service 是纯 DNS CNAME 映射,我们不经可以映射集群内容服务,也可以映射集群外部服务。
-
原先的 service 访问方式:
1 | # 在不同命名空间下创建service |
-
ExternalName 访问
1 | # 在 ns1 中创建 externalName 类型的 service,--external-name 指定 ns2 中的 nginx-service |
-
也可以通过 yaml 创建
1 | apiVersion: v1 |
-
查看 service
1 | $ k get svc -n ns1 |
-
此时再次进入 ns1 中的 pod 访问 ns2 中的 nginx-service 服务
1 | kubectl exec -it -n ns1 alpine-demo-66895487c8-sk4t4 -- /bin/sh |
LoadBalancer
-
LoadBalancer 是 Kubernetes Service 的一种类型,用于自动申请一个云厂商的负载均衡器(如 AWS ELB、GCP LB、阿里云 SLB),将外部流量转发到 Kubernetes 集群内部的 Pod 上。
安装 MetallB
-
如果您在IPVS模式下使用kube代理,从Kubernetes v1.14.2开始,您必须启用严格的ARP模式。请注意,如果您使用kube-router作为服务代理,则不需要这个,因为它默认启用了严格的ARP。
1 | # 查看将要产生的变更,如果有变更则返回非零状态码 |
-
安装MetalLB
1 | export METLB_VERSION=v0.15.2 |
-
查看MetalLB资源
1 | $ k get all -n metallb-system -owide |
-
配置地址池:metallb-pool.yaml
1 | apiVersion: metallb.io/v1beta1 |
1 | kubectl apply -f metallb-pool.yaml |
-
配置地址池的二级公告:metallb-advertisement.yaml
1 | apiVersion: metallb.io/v1beta1 |
1 | kubectl apply -f metallb-advertisement.yaml |
创建 LoadBalancer 类型的 service
-
metallb-service.yaml
1 | apiVersion: apps/v1 # 指定使用的 API 版本,这里是 apps/v1,适用于 Deployment 资源 |
1 | $ k apply -f metallb-service.yaml |
-
查看service
1 | # 可以看到 service 的类型为 LoadBalancer,并分配了 EXTERNAL-IP,这里还开放了nodePort 30613 |
-
访问service
1 | # 通过 service 的 port 访问,这里是 80 |
访问service,轮询pod
1 | ## 在集群内 |
管理service
-
查看service
1 | # 查看service |
-
编辑service,保存(:wq)后生效,不需要额外 apply 或 restart
1 | kubectl edit svc nginx |
-
删除service
1 | kubectl delete svc nginx |