Deployment
对象部署完应用还需要向外界暴露入口才能通过HTTP访问到K8S集群里的应用Pod。Service就是做这件事情的,为什么还需要一个这样的API对象,一个方面是因为Pod的IP不是固定的,另外一个方面是因为一组Pod实例需要Service提供复杂均衡功能。所以Service是在逻辑抽象层上定义了一组Pod ,为他们提供一个统一的固定IP和访问这组Pod的负载均衡策略
Service是K8S中非常重要的概念,主要发挥的作用有:
endpoint
**。当Pods发生变化(例如,扩容、缩容、重新调度等)时,Service会自动更新Endpoints资源以反映最新的Pods信息。这样,应用程序可以从Service的虚拟IP地址或DNS名称中访问这些Pods,而无需关注它们具体在哪些节点上。当Service创建时,K8S会自动为该Service分配一个DNS名称,并将该名称与Service关联起来。关联的完整格式为:
Servcie名称.命名空间.svc.集群域名后缀
这个DNS名称很长,有些情况下可以使用简写来替代。同一命名空间中的Pods访问可以省略命名空间,直接使用Service名称
就可以访问。如果是在默认的命名空间下,也可以省略,直接使用service名称
对一些应用的某些部分,可能只需要集群内部网路访问,而有些部分(如前端)可能需要其公开外部IP地址,也就是可以从集群外部访问某个地址,所以在创建Service可以指定所需要的Service类型。可用的type有:
这是默认的Service类型,会将Service对象通过一个内部IP暴露给集群内部,这种类型的Service只能够在集群内部使用和访问,不对外暴露
会在每个宿主节点的一个指定固定端口号上暴露Service,与此同时还会自动创建一个ClusterIP类型的Service,NodePort类型的Service会将集群外部的请求路由给NodePort类型的Service。当类型设置为 NodePort 后,可以在 ports 配置中增加 nodePort 配置指定端口,需要在下方的端口范围内,如果不指定会随机指定端口,端口范围:30000~32767
也可以修改端口范围配置,在文件 /usr/lib/systemd/system/kube-apiserver.servic
调整
适用于公有云上的Kubernetes
服务,使用LoadBalancer类型的Service,同时会自动创建NodePort和ClusterIP类型的Service,LoadBalancer会把请求路由到NodePort和ClusterIP类型的Service上。
ExternalName 类型的 Service,是在 kube-dns 里添加了一条 CNAME 记录。这个CNAME记录是在Service的spec.externalName里指定的,
以上四种类型除了ExternalName
,Kubernetes
的kube-proxy
组件都会为Service
提供VIP(虚拟IP)
nginx-service-ClusterIP.yaml
文件,内容如下:apiVersion: v1
kind: Service
metadata:
name: nginx-svc-cluster # Service名称
labels:
app: nginx-svc-cluster # Service标签
spec:
type: ClusterIP # service类型
selector: #匹配哪些pod会被Serivce代理
app: nginx-deploy
ports: #端口映射
- name: http #为这个端口映射起一个名字
# 端口绑定的协议,支持 TCP、UDP、SCTP,默认为 TCP
protocol: TCP
# svc 自己的端口,虚拟
port: 80
# 目标 pod 的端口
targetPort: 90
查看service创建情况
kubectl get svc
-------------------------------------------------
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 20d
nginx-svc-cluster ClusterIP 10.110.228.98 <none> 80/TCP 16m
访问
前面说过ClusterIP类型只能供集群内网访问,所以我们只能先创建一个pod,进去这个pod,再来访问这个地址
# 创建busyboxpod
kubectl run busybox-pod --image=busybox --restart=Always
#进进入容器
kubectl exec -it busybox-pod -- sh
访问
wget 10.110.228.98
或者
wget nginx-svc-cluster
apiVersion: v1
kind: Service
metadata:
name: nginx-svc-nodeport
labels:
app: nginx-svc-nodeport
spec:
type: NodePort
selector: #匹配哪些pod会被Serivce代理
app: nginx-deploy
ports: #端口映射
- name: http #为这个端口映射起一个名字
# 端口绑定的协议,支持 TCP、UDP、SCTP,默认为 TCP
protocol: TCP
# nodePort是svc占用宿主机的一个端口
# nodePort: 30080
# svc 自己的端口,虚拟
port: 80
# 目标 pod 的端口
targetPort: 90
- name: http2
port: 81
targetPort: 91
查看service创建情况
kubectl get svc
-------------------------------------------------
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 20d
nginx-svc-nodeport NodePort 10.98.195.178 <none> 80:31216/TCP,81:30517/TCP 39h
这里创建一个名叫nginx-svc
类型为NodePort的service,并且绑定了两个端口号,如果绑定两个端口号则访问的时候加上对应的端口号,如:
# 这样就能访问到pod的90端口号
wget nginx-svc-nodePort:80
# 这样就能访问到pod的91端口号
wget nginx-svc-nodePort:81
--不需要再容器中使用
# 这样就能访问到pod的90端口号
wget 192.168.31.100:31216
apiVersion: v1
kind: Service
metadata:
name: nginx-svc-externalname # Service名称
labels:
app: nginx-svc-externalname # Service标签
spec:
type: ExternalName
externalName: www.baidu.com
进去容器测试
# 进入容器
kubectl exec -it busybox-pod -- sh
#测试
ping nginx-svc-externalnam