Service介紹
按照官方文檔的說法失乾,在K8S中勇边,Service是將運行在集群中的一組Pod的應(yīng)用公開為網(wǎng)絡(luò)服務(wù)的抽象方法寇蚊,是K8S的核心概念之一峭判,Service的主要作用是使客戶端發(fā)現(xiàn)Pod并與之通信开缎。
簡單理解起來就是,由Service提供統(tǒng)一的入口地址林螃,然后將請求負(fù)載分發(fā)到后端Pod的容器應(yīng)用奕删。
為什么有Service
集群中部署了Pod,應(yīng)用是成功的部署起來了疗认,但是只是至此的話完残,Pod提供服務(wù)訪問存在以下一些問題伏钠。
- Pod是短暫的,可能會被銷毀或重新調(diào)度谨设,這使得Pod的IP是隨時變動和更新的熟掂;
- 部署多個Pod的伸縮問題,流量分配問題扎拣;
- 集群外部客戶端無法直接訪問Pod打掘。
這時候就需要Service,Pod作為Service的后端提供服務(wù)鹏秋。所以我們可以想象尊蚁,Service需要完成的事情:
- 服務(wù)發(fā)現(xiàn),通過Pod的lable查找目標(biāo)Pod侣夷,將查找的Pod的注冊到自己的后端列表横朋,Pod的IP信息發(fā)生更改,后端列表也同步更新百拓;
- 負(fù)載均衡琴锭,請求到達(dá)Service之后,將請求均衡轉(zhuǎn)發(fā)的后端列表衙传;
- 服務(wù)暴露:對外提供統(tǒng)一的請求地址决帖。
創(chuàng)建Service
在創(chuàng)建Sercvice之前我們首先創(chuàng)建service代理的Pod,nginx-pod.yaml:
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
先給到一個簡單的Service定義實例nginx-service.yaml:
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
type: LoadBalancer
spec.ports.port是Service對外提供服務(wù)的端口蓖捶,spec.ports.targetPort是轉(zhuǎn)發(fā)到Pod內(nèi)的訪問端口地回;
通過spec.selector發(fā)現(xiàn)同一命名空間下帶有app=nginx的label的Pod作為后端。
創(chuàng)建命令:
kubectl apply -f nginx-service.yaml
Service作為Pod的負(fù)載均衡器俊鱼,使用service.spec.selector
字段去匹配Pod刻像,上面示例中,nginx Service將通過app: nginx
的label查找Pod作為后端并闲。
創(chuàng)建Service之后细睡,查看Service的后端:
kubectl get svc -o wide
kubectl describe svc nginx
在創(chuàng)建Sercvice之前,我已經(jīng)創(chuàng)建了一個帶有app: nginx
label的Pod帝火,所以可以看到Service的EndPoints中已經(jīng)有了一個后端(10.244.1.25)了溜徙,Endpoint也是一種K8S資源,可以使用kubectl get ep
命令查看犀填。
除了以上使用yaml定義Service之外蠢壹,還可以使用以下命令創(chuàng)建Service:
# 暴露Pod
kubectl expose pod nginx --name=nginx --port=80 --target-port=80 --protocol=TCP --type=NodePort
# 或者Deployment管理的Pod
kubectl expose deploy nginx --name=nginx --port=80 --target-port=80 --protocol=TCP --type=LoadBalancer
Service類型
通過Service.spec.type
定義,最常用的三種:ClusterIP(默認(rèn))宏浩,NodePort知残、LoadBalancer。
CLusterIP
指定type為ClusterIP時,它將被分配一個集群內(nèi)部的IP求妹,在集群內(nèi)部通過訪問它來訪問后端Pod乏盐,這種Service一般只供集群內(nèi)部訪問。
NodePort
指定type為NodePort時制恍,會在所有節(jié)點分配一個端口(默認(rèn)從30000-32767)作為service的入口父能,訪問方式:<protocol>://<node-ip>:<port>,使用NodePort類型時净神,也會默認(rèn)分配一個ClusterIP何吝,除非使用ClusterIP: None免除分配。
特點:
- 所有節(jié)點都是同一個端口鹃唯;
- 端口是有限的爱榕,30000-32767范圍內(nèi)分配,也可以使用service.spec.ports.nodePort指定端口坡慌,但指定的端口必須在范圍內(nèi)且尚未被占用黔酥;
- 外部訪問需要使用到Node的IP。
LoadBalancer
隨機分配一個LoadBalancer作為Service的入口洪橘,一般需要云提供商的支持跪者。請求到達(dá)LoadBalancer地址后,均衡負(fù)載到后端Pod熄求,使用LoadBalancer類型時渣玲,也會默認(rèn)分配一個ClusterIP,并且也會分配一個NodePort端口弟晚,實際上來說忘衍,LoadBalancer是基于NodePort實現(xiàn)的。
特點:
- 外部網(wǎng)絡(luò)可以通過LoadBalancer的地址和端口訪問到集群內(nèi)Service服務(wù)指巡。
訪問Service
- 通過ClusterIP訪問淑履,限集群內(nèi)部訪問隶垮;
- 通過Service Name訪問:如果在同一命名空間藻雪,可以直接使用服務(wù)名稱(<service-name>)訪問,如果不在同一命名空間狸吞,使用服務(wù)名稱和命名空間名稱(<service-name>.<namespace-name>)訪問勉耀,集群外可訪問;
- 通過ExternalIP(一般是LoadBalancer的host和ip)訪問蹋偏,集群外可訪問便斥。