什么是service
官方的解释是:
k8s中最小的管理单元是pod;而service是 将运行在一个或一组 Pod 上的网络应用程序公开为网络服务的方法;
Kubernetes 中 Service 的一个关键目标是让你无需修改现有应用以使用某种服务发现机制。 你可以在 Pod 集合中运行代码,无论该代码是为云原生环境设计的,还是被容器化的老应用。 你可以使用 Service 让一组 Pod 可在网络上访问,这样客户端就能与之交互。
Service API 是 Kubernetes 的组成部分,它是一种抽象,帮助你将 Pod 集合在网络上公开出去。 每个 Service 对象定义一组端点的逻辑集合(通常这些端点就是 Pod)以及如何访问到这些 Pod 的策略
例如,有一个无状态的后端应用,其中运行 3 个副本(Replicas)。 这些副本是可互换的 —— 前端不需要关心它们调用的是哪个后端。 即便构成后端集合的实际 Pod 可能会发生变化,前端客户端不应该也没必要知道这些, 而且它们也不必亲自跟踪后端的状态变化。
通俗一点讲就是将一组pod抽离成一个服务,和这组pods交互的其他组件不需要知道这组pod内发生了什么事情,里面的某些pod是否健康,每一个pod的ip是多少,我只知道这组pod抽离成的service是什么就行了
sevice有哪些类型
1、ClusterIP:默认的类型值,通过集群的内部 IP 公开 Service,选择该值时 Service 只能够在集群内部访问。 这也是你没有为服务显式指定 type 时使用的默认值。 你可以使用 Ingress 或者 Gateway API 向公共互联网公开服务。
2、NodePort:通过每个节点上的 IP 和静态端口(NodePort)公开 Service。此类型可通过节点IP和端口进行访问,对外暴露了集群内部服务;
3、LoadBalancer:使用云平台的负载均衡器向外部公开 Service。Kubernetes 不直接提供负载均衡组件; 你必须提供一个,或者将你的 Kubernetes 集群与某个云平台集成。
案例练习
我新建一个服务,指定ClusterIP类型,并通过集群内部进行访问;
1、先创建一个nginx 的yaml文件,再执行kubectl apply -f nginx-demo,创建好应用;
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx-demo
name: nginx-demo
spec:
replicas: 2
selector:
matchLabels:
app: nginx-demo
template:
metadata:
labels:
app: nginx-demo
spec:
containers:
- image: nginx
name: nginx
查看启动情况:
2、创建service资源
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx-demo
name: nginx-demo
spec:
selector:
app: nginx-demo
ports:
- port: 8000
protocol: TCP
targetPort: 80
执行kubectl命令,并查看启动情况:
可以看到资源已经启动好了,进入集群访问资源,可以看到已分配了集群的内部ip是:10.96.185.237,使用8000端口
可以看到成功访问了service 资源;
案例2:使用nodeport类型的service,在浏览器内访问集群内部应用,也就是暴露集群的应用,实现在集群外部访问
我们这里就已经部署好的k8s-dashboard为例,看一下service的yaml文件
kind: Service
apiVersion: v1
metadata:
name: kubernetes-dashboard
namespace: kubernetes-dashboard
uid: 0626588b-9fc3-4bf7-aa54-779a223ba3f8
resourceVersion: '11657'
creationTimestamp: '2023-08-04T11:59:45Z'
labels:
k8s-app: kubernetes-dashboard
annotations:
kubectl.kubernetes.io/last-applied-configuration: >
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"k8s-app":"kubernetes-dashboard"},"name":"kubernetes-dashboard","namespace":"kubernetes-dashboard"},"spec":{"ports":[{"nodePort":32232,"port":443,"targetPort":8443}],"selector":{"k8s-app":"kubernetes-dashboard"},"type":"NodePort"}}
managedFields:
- manager: kubectl-client-side-apply
operation: Update
apiVersion: v1
time: '2023-08-04T11:59:45Z'
fieldsType: FieldsV1
fieldsV1:
f:metadata:
f:annotations:
.: {}
f:kubectl.kubernetes.io/last-applied-configuration: {}
f:labels:
.: {}
f:k8s-app: {}
f:spec:
f:externalTrafficPolicy: {}
f:ports:
.: {}
k:{"port":443,"protocol":"TCP"}:
.: {}
f:nodePort: {}
f:port: {}
f:protocol: {}
f:targetPort: {}
f:selector:
.: {}
f:k8s-app: {}
f:sessionAffinity: {}
f:type: {}
spec:
ports:
- protocol: TCP
port: 443
targetPort: 8443
nodePort: 32232 #对外暴露的端口
selector:
k8s-app: kubernetes-dashboard
clusterIP: 10.96.27.42
clusterIPs:
- 10.96.27.42
type: NodePort #nodeport类型
sessionAffinity: None
externalTrafficPolicy: Cluster
status:
loadBalancer: {}
可以看到文件中的服务类型为NodePort ,https协议访问的端口为32232,那在浏览器内就通过任一集群节点ip的方式访问
可以看到已经对外暴露成功!