docker筆記25-k8s-service資源
service是要透過coreDNS來管理pod的。
kube-proxy始終監視著apiserver,獲取與service資源的變動狀態。一旦發現有service資源發生變動,kube-proxy都要把它轉變為當前節點之上的,能夠實現service資源排程,包括將客戶端資源排程到pod的規則(iptables或者ipvs)。
service工作模式有三種:userspace(k8s 1.1版本之前),iptables(k8s 1.10版本之前)和ipvs(k8s 1.11版本之後)
userspace模型:使用者空間模型。k8s 1.11版本用ipvs了,這個比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這個service千萬別刪,因為K8s都是透過10.96.0.1這個地址聯絡的。
[root@master ~]# kubectl explain svc
service型別:
a)、ExternalName:表示把叢集外部的服務引入到叢集內部中來,即實現了叢集內部pod和叢集外部的服務進行通訊;
b)、ClusterIP:只能在叢集內部通訊;
c)、NodePort:可以和叢集外部通訊;
d)、LoadBalancer:這個表示我們把k8s部署在虛擬機器上,自動在外部建立負載均衡器。比如在阿里雲上,底層是LBAAS。
ClusterIP
以前我們使用kubectl expose建立service,下面我們使用清單來建立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 #這個ip可以不指定,讓它自動分配 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
叢集預設字尾是svc.cluster.local
比如我們建立的redis預設名稱就是redis.defalut.svc.cluster.local
NodePort
訪問路徑: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 #這個ip可以不指定,讓他自動分配 type: NodePort ports: - port: 80 #service ip的埠 targetPort: 80 #容器ip的埠 nodePort: 30080 #node節點上埠,這個埠也可以不指定,會自動分配埠
[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 myapp-deploy-69b47bc96d-79fqh [root@master manifests]# curl myapp-deploy-69b47bc96d-tc54k
注意:172.16.1.101是Node節點的Ip,並且可以看到訪問是做了負載均衡的
下面我們再把來自同一個客戶端會話請求用sessionAffinity粘滯到一個固定的pod上,這樣就不會出現負載均衡現象了,相當於nginx的 ip_hash功能,如下:
[root@master manifests]# kubectl patch svc myapp -p '{"spec":{"sessionAffinity":"ClientIP"}}' service/myapp patched
上面打的補丁也可以直接用edit方法編輯。
[root@master manifests]# kubectl describe svc myapp Session Affinity: ClientIP
再改回負載均衡模式: [root@master manifests]# kubectl patch svc myapp -p '{"spec":{"sessionAffinity":"None"}}' service/myapp patched
無頭service
我們前面介紹的service是service name解析為cluster ip,然後cluster ip對應到後面的pod ip。
而無頭service是指service name 直接解析為後面的pod ip。
無頭就是沒有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。一個pod可以有多個service release: canary clusterIP: None #None表示是無頭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是空,這就是無頭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
上面看到無頭service name直接被解析到另個pod上的ip了。
ExternalName
我們可以用ExternalName對Service名稱和叢集外部服務地址做一個對映,使之訪問Service名稱就是訪問外部服務。例如下面的例子是將 svc1 和 xxx.xxx.xxx.xxx 做了對等關係。
kind: Service apiVersion: v1 metadata: name: svc1 namespace: default spec: type: ExternalName externalName: somedomain.org
不過,ExternalName 型別的服務適用於外部服務使用域名的方式,缺點是不能指定埠。
另外,要實現叢集內訪問叢集外服務的這個需求,也是非常簡單的。因為叢集內的Pod會繼承Node上的DNS解析規則。因此只要Node可以訪問的服務,Pod中也可以訪問到。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28916011/viewspace-2214745/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- docker筆記34-容器資源需求、資源限制及HeapSterDocker筆記
- docker筆記26-ingress資源和ingress controllerDocker筆記Controller
- 筆記資源整理筆記
- Docker筆記(八):資料管理Docker筆記
- docker 筆記Docker筆記
- 筆記:Docker筆記Docker
- Docker筆記Docker筆記
- docker筆記35-資源指標API及自定義指標APIDocker筆記指標API
- docker筆記22-k8s資源清單定義入門Docker筆記K8S
- docker 筆記2Docker筆記
- docker 筆記4Docker筆記
- Docker Stack 筆記Docker筆記
- docker筆記(一)Docker筆記
- docker使用筆記Docker筆記
- CORS(跨域資源共享)筆記CORS跨域筆記
- docker的資源控制(CPU、記憶體、IO)Docker記憶體
- Docker筆記之DockerfileDocker筆記
- docker簡單筆記Docker筆記
- Docker學習筆記Docker筆記
- Docker的使用筆記Docker筆記
- Docker 學習筆記Docker筆記
- Docker筆記之Docker初體驗Docker筆記
- Docker筆記(四):Docker映象管理Docker筆記
- Docker筆記(一):什麼是DockerDocker筆記
- docker筆記12-容器資料卷volumesDocker筆記
- Docker學習筆記:映象、容器、資料卷Docker筆記
- Effective C++ 筆記(3)資源管理C++筆記
- WPF筆記4——靜態資源(StaticResource)筆記
- 無線資源分配方法(筆記)筆記
- 【docker】Docker入門到實踐 筆記Docker筆記
- docker筆記3-docker的安裝Docker筆記
- Docker筆記(三):Docker安裝與配置Docker筆記
- ELK 搭建筆記--Docker 方式筆記Docker
- Ubuntu安裝docker筆記UbuntuDocker筆記
- Docker筆記之七:RegistryDocker筆記
- Docker筆記二之容器Docker筆記
- Docker筆記一之映象Docker筆記
- Docker筆記(六):容器管理Docker筆記