您好,登錄后才能下訂單哦!
service是要通過(guò)coreDNS來(lái)管理pod的。
kube-proxy始終監(jiān)視著apiserver,獲取與service資源的變動(dòng)狀態(tài)。一旦發(fā)現(xiàn)有service資源發(fā)生變動(dòng),kube-proxy都要把它轉(zhuǎn)變?yōu)楫?dāng)前節(jié)點(diǎn)之上的,能夠?qū)崿F(xiàn)service資源調(diào)度,包括將客戶端資源調(diào)度到pod的規(guī)則(iptables或者ipvs)。
service工作模式有三種:userspace(k8s 1.1版本之前),iptables(k8s 1.10版本之前)和ipvs(k8s 1.11版本之后)
userspace模型:用戶空間模型。k8s 1.11版本用ipvs了,這個(gè)比iptables效率高。
[root@master ~]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 16d redis ClusterIP 10.106.138.181 <none> 6379/TCP 23h
[root@master ~]# kubectl delete svc redis service "redis" deleted
注意kubernetes這個(gè)service千萬(wàn)別刪,因?yàn)镵8s都是通過(guò)10.96.0.1這個(gè)地址聯(lián)系的。
[root@master ~]# kubectl explain svc
service類(lèi)型:
a)、ExternalName:表示把集群外部的服務(wù)引入到集群內(nèi)部中來(lái),即實(shí)現(xiàn)了集群內(nèi)部pod和集群外部的服務(wù)進(jìn)行通信;
b)、ClusterIP:只能在集群內(nèi)部通訊;
c)、NodePort:可以和集群外部通訊;
d)、LoadBalancer:這個(gè)表示我們把k8s部署在虛擬機(jī)上,自動(dòng)在外部創(chuàng)建負(fù)載均衡器。比如在阿里云上,底層是LBAAS。
以前我們使用kubectl expose創(chuàng)建service,下面我們使用清單來(lái)創(chuàng)建service。
[root@master manifests]# cat redis-svc.yaml apiVersion: v1 kind: Service metadata: name: redis namespace: default spec: selector: app: redis role: logstor clusterIP: 10.97.97.97 #這個(gè)ip可以不指定,讓它自動(dòng)分配 type: ClusterIP ports: - port: 6379 #service ip中的端口 targetPort: 6379 #容器ip中的端口
[root@master manifests]# kubectl apply -f redis-svc.yaml service/redis created
[root@master manifests]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 16d redis ClusterIP 10.97.97.97 <none> 6379/TCP 1m
[root@master manifests]# kubectl describe svc redis Name: redis Namespace: default Labels: <none> Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"redis","namespace":"default"},"spec":{"clusterIP":"10.97.97.97","ports":[{"por... Selector: app=redis,role=logstor Type: ClusterIP IP: 10.97.97.97 Port: <unset> 6379/TCP TargetPort: 6379/TCP Endpoints: 10.244.2.65:6379 ##這是pod的ip Session Affinity: None Events: <none>
資源記錄:SVC_NAME.NAMESPACE_NAME.DOMAIN.LTD
集群默認(rèn)后綴是svc.cluster.local
比如我們創(chuàng)建的redis默認(rèn)名稱就是redis.defalut.svc.cluster.local
訪問(wèn)路徑:client---->NodeIP:NodePoint----->ClusterIP:ServerPort---->PodIP:containerPort
[root@master manifests]# cat myapp-svc.yaml apiVersion: v1 kind: Service metadata: name: myapp namespace: default spec: selector: app: myapp release: canary clusterIP: 10.99.99.99 #這個(gè)ip可以不指定,讓他自動(dòng)分配 type: NodePort ports: - port: 80 #service ip的端口 targetPort: 80 #容器ip的端口 nodePort: 30080 #node節(jié)點(diǎn)上端口,這個(gè)端口也可以不指定,會(huì)自動(dòng)分配端口
[root@master manifests]# kubectl apply -f myapp-svc.yaml service/myapp created
[root@master manifests]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 16d myapp NodePort 10.99.99.99 <none> 80:30080/TCP 44s redis ClusterIP 10.97.97.97 <none> 6379/TCP 15m
[root@master manifests]# curl http://172.16.1.101:30080/hostname.html myapp-deploy-69b47bc96d-79fqh [root@master manifests]# curl http://172.16.1.101:30080/hostname.html myapp-deploy-69b47bc96d-tc54k
注意:172.16.1.101是Node節(jié)點(diǎn)的Ip,并且可以看到訪問(wèn)是做了負(fù)載均衡的
下面我們?cè)侔褋?lái)自同一個(gè)客戶端會(huì)話請(qǐng)求用sessionAffinity粘滯到一個(gè)固定的pod上,這樣就不會(huì)出現(xiàn)負(fù)載均衡現(xiàn)象了,相當(dāng)于nginx的 ip_hash功能,如下:
[root@master manifests]# kubectl patch svc myapp -p '{"spec":{"sessionAffinity":"ClientIP"}}' service/myapp patched
上面打的補(bǔ)丁也可以直接用edit方法編輯。
[root@master manifests]# kubectl describe svc myapp Session Affinity: ClientIP
再改回負(fù)載均衡模式: [root@master manifests]# kubectl patch svc myapp -p '{"spec":{"sessionAffinity":"None"}}' service/myapp patched
我們前面介紹的service是service name解析為cluster ip,然后cluster ip對(duì)應(yīng)到后面的pod ip。
而無(wú)頭service是指service name 直接解析為后面的pod ip。
無(wú)頭就是沒(méi)有cluster ip牽頭了。
[root@master manifests]# cat myapp-svc-headless.yaml apiVersion: v1 kind: Service metadata: name: myapp-svc namespace: default spec: selector: app: myapp #挑選的pod還是myapp。一個(gè)pod可以有多個(gè)service release: canary clusterIP: None #None表示是無(wú)頭service ports: - port: 80 #service ip中的端口 targetPort: 80 #容器ip中的端口
[root@master manifests]# kubectl apply -f myapp-svc-headless.yaml service/myapp-svc created
[root@master manifests]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 16d myapp NodePort 10.99.99.99 <none> 80:30080/TCP 1h myapp-svc ClusterIP None <none> 80/TCP 28s redis ClusterIP 10.97.97.97 <none> 6379/TCP 1h
看到上面myapp-svc的cluster-ip是空,這就是無(wú)頭service。
[root@master manifests]# kubectl get svc -n kube-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP 16d
可以看到coreDNS的地址是10.96.0.10
[root@master manifests]# dig -t A myapp-svc.default.svc.cluster.local. @10.96.0.10 ; <<>> DiG 9.9.4-RedHat-9.9.4-61.el7_5.1 <<>> -t A myapp-svc.default.svc.cluster.local. @10.96.0.10 ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 10702 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;myapp-svc.default.svc.cluster.local. INA ;; ANSWER SECTION: myapp-svc.default.svc.cluster.local. 5 IN A10.244.1.63 myapp-svc.default.svc.cluster.local. 5 IN A10.244.2.51 ;; Query time: 0 msec ;; SERVER: 10.96.0.10#53(10.96.0.10) ;; WHEN: Mon Sep 24 00:22:07 EDT 2018 ;; MSG SIZE rcvd: 166
[root@master manifests]# kubectl get pods -o wide -l app=myapp NAME READY STATUS RESTARTS AGE IP NODE myapp-deploy-69b47bc96d-79fqh 1/1 Running 0 1d 10.244.1.63 node1 myapp-deploy-69b47bc96d-tc54k 1/1 Running 0 1d 10.244.2.51 node2
上面看到無(wú)頭service name直接被解析到另個(gè)pod上的ip了。
我們可以用ExternalName對(duì)Service名稱和集群外部服務(wù)地址做一個(gè)映射,使之訪問(wèn)Service名稱就是訪問(wèn)外部服務(wù)。例如下面的例子是將 svc1 和 xxx.xxx.xxx.xxx 做了對(duì)等關(guān)系。
kind: Service apiVersion: v1 metadata: name: svc1 namespace: default spec: type: ExternalName externalName: somedomain.org
不過(guò),ExternalName 類(lèi)型的服務(wù)適用于外部服務(wù)使用域名的方式,缺點(diǎn)是不能指定端口。
另外,要實(shí)現(xiàn)集群內(nèi)訪問(wèn)集群外服務(wù)的這個(gè)需求,也是非常簡(jiǎn)單的。因?yàn)榧簝?nèi)的Pod會(huì)繼承Node上的DNS解析規(guī)則。因此只要Node可以訪問(wèn)的服務(wù),Pod中也可以訪問(wèn)到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。