版權(quán) 本文為云錄原創(chuàng)文章,轉(zhuǎn)載無需和我聯(lián)系,但請(qǐng)注明來自云錄 https://www.yunzhuan.site
?? Service 的概念
Kubernetes Service 定義了這樣一種抽象:一個(gè) Pod 的邏輯分組,一種可以訪問它們的策略 —— 通常稱為微
服務(wù)。 這一組 Pod 能夠被 Service 訪問到,通常是通過 Label Selector
Service能夠提供負(fù)載均衡的能力,但是在使用上有以下限制:
只提供 4 層負(fù)載均衡能力,而沒有 7 層功能,但有時(shí)我們可能需要更多的匹配規(guī)則來轉(zhuǎn)發(fā)請(qǐng)求,這點(diǎn)上 4 層
負(fù)載均衡是不支持的
?? Service 類型
- ClusterIp:默認(rèn)類型,自動(dòng)分配一個(gè)僅 Cluster 內(nèi)部可以訪問的虛擬 IP
-
NodePort:在 ClusterIP 基礎(chǔ)上為 Service 在每臺(tái)機(jī)器上綁定一個(gè)端口,這樣就可以通過 : NodePort 來訪
問該服務(wù) -
LoadBalancer:在 NodePort 的基礎(chǔ)上,借助 cloud provider 創(chuàng)建一個(gè)外部負(fù)載均衡器,并將請(qǐng)求轉(zhuǎn)發(fā)
到: NodePort -
ExternalName:把集群外部的服務(wù)引入到集群內(nèi)部來,在集群內(nèi)部直接使用。沒有任何類型代理被創(chuàng)建,
這只有 kubernetes 1.7 或更高版本的 kube-dns 才支持
??VIP 和 Service 代理
在 Kubernetes 集群中,每個(gè) Node 運(yùn)行一個(gè) kube-proxy 進(jìn)程。 kube-proxy 負(fù)責(zé)為 Service 實(shí)現(xiàn)了一種
VIP(虛擬 IP)的形式,而不是 ExternalName 的形式。 在 Kubernetes v1.0 版本,代理完全在 userspace。在
Kubernetes v1.1 版本,新增了 iptables 代理,但并不是默認(rèn)的運(yùn)行模式。 從 Kubernetes v1.2 起,默認(rèn)就是
iptables 代理。 在 Kubernetes v1.8.0-beta.0 中,添加了 ipvs 代理
在 Kubernetes 1.14 版本開始默認(rèn)使用 ipvs 代理
在 Kubernetes v1.0 版本, Service 是 “4層”(TCP/UDP over IP)概念。 在 Kubernetes v1.1 版本,新增了
Ingress API(beta 版),用來表示 “7層”(HTTP)服務(wù)
??ipvs 代理模式
這種模式,kube-proxy 會(huì)監(jiān)視 Kubernetes Service 對(duì)象和 Endpoints ,調(diào)用 netlink 接口以相應(yīng)地創(chuàng)建
ipvs 規(guī)則并定期與 Kubernetes Service 對(duì)象和 Endpoints 對(duì)象同步 ipvs 規(guī)則,以確保 ipvs 狀態(tài)與期望一
致。訪問服務(wù)時(shí),流量將被重定向到其中一個(gè)后端 Pod
與 iptables 類似,ipvs 于 netfilter 的 hook 功能,但使用哈希表作為底層數(shù)據(jù)結(jié)構(gòu)并在內(nèi)核空間中工作。這意
味著 ipvs 可以更快地重定向流量,并且在同步代理規(guī)則時(shí)具有更好的性能。此外,ipvs 為負(fù)載均衡算法提供了更
多選項(xiàng),例如:
rr :輪詢調(diào)度
lc :最小連接數(shù)
dh :目標(biāo)哈希
sh :源哈希
sed :最短期望延遲
nq : 不排隊(duì)調(diào)度
?? ClusterIP
clusterIP 主要在每個(gè) node 節(jié)點(diǎn)使用 iptables,將發(fā)向 clusterIP 對(duì)應(yīng)端口的數(shù)據(jù),轉(zhuǎn)發(fā)到 kube-proxy 中。然
后 kube-proxy 自己內(nèi)部實(shí)現(xiàn)有負(fù)載均衡的方法,并可以查詢到這個(gè) service 下對(duì)應(yīng) pod 的地址和端口,進(jìn)而把
數(shù)據(jù)轉(zhuǎn)發(fā)給對(duì)應(yīng)的 pod 的地址和端口
apiserver 用戶通過kubectl命令向apiserver發(fā)送創(chuàng)建service的命令,apiserver接收到請(qǐng)求后將數(shù)據(jù)存儲(chǔ)
到etcd中
kube-proxy kubernetes的每個(gè)節(jié)點(diǎn)中都有一個(gè)叫做kube-porxy的進(jìn)程,這個(gè)進(jìn)程負(fù)責(zé)感知service,pod
的變化,并將變化的信息寫入本地的iptables規(guī)則中文章來源:http://www.zghlxwxcb.cn/news/detail-818558.html
iptables 使用NAT等技術(shù)將virtualIP的流量轉(zhuǎn)至endpoint中文章來源地址http://www.zghlxwxcb.cn/news/detail-818558.html
創(chuàng)建 SvcClusterIP.yaml 文件
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deploy
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: myapp
release: stabel
template:
metadata:
labels:
app: myapp
release: stabel
env: test
spec:
containers:
- name: myapp
image: nginx:latest
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
---
# svc
apiVersion: v1
kind: Service
metadata:
name: myapp
namespace: default
spec:
type: ClusterIP
selector:
app: myapp
release: stabel
ports:
- name: http
port: 80
targetPort: 80
[root@k8s-master01 k8sservice]# kubectl apply -f SvcClusterIP.yaml
deployment.apps/myapp-deploy created
service/myapp created
[root@k8s-master01 k8sservice]# kubectl get po
NAME READY STATUS RESTARTS AGE
myapp-deploy-547fddf58-sf566 1/1 Running 0 4s
myapp-deploy-547fddf58-skrw2 1/1 Running 0 4s
myapp-deploy-547fddf58-vtkzz 1/1 Running 0 4s
nfs-client-provisioner-876986df-vlrmv 1/1 Running 0 31h
[root@k8s-master01 k8sservice]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 10d
myapp ClusterIP 10.98.113.5 <none> 80/TCP 41s
[root@k8s-master01 k8sservice]# curl 10.98.113.5
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
?? Headless Service (無頭服務(wù))
有時(shí)不需要或不想要負(fù)載均衡,以及單獨(dú)的 Service IP 。遇到這種情況,可以通過指定 Cluster
IP(spec.clusterIP) 的值為 “None” 來創(chuàng)建 Headless Service 。這類 Service 并不會(huì)分配 Cluster IP, kube-
proxy 不會(huì)處理它們,而且平臺(tái)也不會(huì)為它們進(jìn)行負(fù)載均衡和路由
第一種:自主選擇權(quán),有時(shí)候client想自己決定使用哪個(gè)Real Server,可以通過查詢DNS來獲取Real Server的信息
第二種:headless service關(guān)聯(lián)的每個(gè)endpoint(也就是Pod),都會(huì)有對(duì)應(yīng)的DNS域名;這樣Pod之間就可以互相訪問
headless services一般結(jié)合StatefulSet來部署有狀態(tài)的應(yīng)用,比如kafka集群,mysql集群,zk集群等
創(chuàng)建 SvcHeadless.yaml文件
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deploy
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: myapp
release: stabel
template:
metadata:
labels:
app: myapp
release: stabel
env: test
spec:
containers:
- name: myapp
image: nginx:latest
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
---
# svc
apiVersion: v1
kind: Service
metadata:
name: myapp
namespace: default
spec:
selector:
app: myapp
release: stabel
clusterIP: "None"
ports:
- name: http
port: 80
targetPort: 80
[root@k8s-master01 k8sservice]# kubectl apply -f SvcHeadless.yaml
deployment.apps/myapp-deploy created
service/myapp created
[root@k8s-master01 k8sservice]# kubectl get po
NAME READY STATUS RESTARTS AGE
myapp-deploy-547fddf58-clmhn 1/1 Running 0 4s
myapp-deploy-547fddf58-hwqm9 1/1 Running 0 4s
myapp-deploy-547fddf58-xkzfg 1/1 Running 0 4s
nfs-client-provisioner-876986df-vlrmv 1/1 Running 0 31h
[root@k8s-master01 k8sservice]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 10d
myapp ClusterIP None <none> 80/TCP 8s
?? NodePort
nodePort 的原理在于在 node 上開了一個(gè)端口,將向該端口的流量導(dǎo)入到 kube-proxy,然后由 kube-proxy 進(jìn)
一步到給對(duì)應(yīng)的 pod
創(chuàng)建SvcNodeport.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deploy
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: myapp
release: stabel
template:
metadata:
labels:
app: myapp
release: stabel
env: test
spec:
containers:
- name: myapp
image: nginx:latest
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
---
# svc
apiVersion: v1
kind: Service
metadata:
name: myapp
namespace: default
spec:
type: NodePort
selector:
app: myapp
release: stabel
ports:
- name: http
port: 80
targetPort: 80
nodePort: 30001
[root@k8s-master01 k8sservice]# kubectl apply -f SvcNodeport.yaml
deployment.apps/myapp-deploy created
service/myapp created
[root@k8s-master01 k8sservice]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 10d
myapp NodePort 10.109.139.103 <none> 80:30001/TCP 7s
?? LoadBalancer
loadBalancer 和 nodePort 其實(shí)是同一種方式。區(qū)別在于 loadBalancer 比 nodePort 多了一步,就是可以調(diào)用
cloud provider 去創(chuàng)建 LB 來向節(jié)點(diǎn)導(dǎo)流
??ExternalName
把集群外部的服務(wù)引入到集群內(nèi)部來,在集群內(nèi)部直接使用。沒有任何類型代理被創(chuàng)建,這只有 Kubernetes 1.7或更高版本的kube-dns才支持。
這種類型的 Service 通過返回 CNAME 和它的值,可以將服務(wù)映射到 externalName 字段的內(nèi)容。
ExternalName Service 是 Service 的特例,它沒有 selector,也沒有定義任何的端口和Endpoint。
相反的,對(duì)于運(yùn)行在集群外部的服務(wù),它通過返回該外部服務(wù)的別名這種方式來提供服務(wù)
kind: Service
apiVersion: v1
metadata:
name: my-service
namespace: default
spec:
type: ExternalName
externalName: yunzhuan.site
當(dāng)查詢主機(jī) my-service.defalut.svc.cluster.local ( SVC_NAME.NAMESPACE.svc.cluster.local )時(shí),集群的
DNS 服務(wù)將返回一個(gè)值 yunzhuan.site 的 CNAME 記錄。訪問這個(gè)服務(wù)的工作方式和其他的相
同,唯一不同的是重定向發(fā)生在 DNS 層,而且不會(huì)進(jìn)行代理或轉(zhuǎn)發(fā)
版權(quán) 本文為云錄原創(chuàng)文章,轉(zhuǎn)載無需和我聯(lián)系,但請(qǐng)注明來自云錄 https://www.yunzhuan.site
到了這里,關(guān)于【云原生 | Kubernetes 系列】—K8s-Service 的概念的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!