k8s-Services
簡(jiǎn)介:
Kubernetes 在設(shè)計(jì)之初就充分考慮了針對(duì)容器的服務(wù)發(fā)現(xiàn)與負(fù)載均衡機(jī)制,提供了 Service 資源冠胯,并通過 kube-proxy 配合 cloud provider 來(lái)適應(yīng)不同的應(yīng)用場(chǎng)景枕磁。隨著 kubernetes 用戶的激增,用戶場(chǎng)景的不斷豐富,又產(chǎn)生了一些新的負(fù)載均衡機(jī)制热某。目前,kubernetes 中的負(fù)載均衡大致可以分為以下幾種機(jī)制胳螟,每種機(jī)制都有其特定的應(yīng)用場(chǎng)景:
Service:直接用 Service 提供 cluster 內(nèi)部的負(fù)載均衡昔馋,并借助 cloud provider 提供的 LB 提供外部訪問
Ingress Controller:還是用 Service 提供 cluster 內(nèi)部的負(fù)載均衡,但是通過自定義 Ingress Controller 提供外部訪問
Service Load Balancer:把 load balancer 直接跑在容器中糖耸,實(shí)現(xiàn) Bare Metal 的 Service Load Balancer
Custom Load Balancer:自定義負(fù)載均衡秘遏,并替代 kube-proxy,一般在物理部署 Kubernetes 時(shí)使用嘉竟,方便接入公司已有的外部服務(wù)
Service 是對(duì)一組提供相同功能的 Pods 的抽象邦危,并為它們提供一個(gè)統(tǒng)一的入口。借助 Service舍扰,應(yīng)用可以方便的實(shí)現(xiàn)服務(wù)發(fā)現(xiàn)與負(fù)載均衡倦蚪,并實(shí)現(xiàn)應(yīng)用的零宕機(jī)升級(jí)。Service 通過標(biāo)簽來(lái)選取服務(wù)后端边苹,一般配合 Replication Controller 或者 Deployment 來(lái)保證后端容器的正常運(yùn)行陵且。這些匹配標(biāo)簽的 Pod IP 和端口列表組成 endpoints,由 kube-proxy 負(fù)責(zé)將服務(wù) IP 負(fù)載均衡到這些 endpoints 上勾给。
Service有四種類型:
ClusterIP:默認(rèn)類型滩报,自動(dòng)分配一個(gè)僅 cluster 內(nèi)部可以訪問的虛擬 IP
NodePort:在 ClusterIP 基礎(chǔ)上為 Service 在每臺(tái)機(jī)器上綁定一個(gè)端口,這樣就可以通過 <NodeIP>:NodePort 來(lái)訪問該服務(wù)播急。如果 kube-proxy 設(shè)置了 --nodeport-addresses=10.240.0.0/16(v1.10 支持)脓钾,那么僅該 NodePort 僅對(duì)設(shè)置在范圍內(nèi)的 IP 有效。
LoadBalancer:在 NodePort 的基礎(chǔ)上桩警,借助 cloud provider 創(chuàng)建一個(gè)外部的負(fù)載均衡器可训,并將請(qǐng)求轉(zhuǎn)發(fā)到 <NodeIP>:NodePort
ExternalName:將服務(wù)通過 DNS CNAME 記錄方式轉(zhuǎn)發(fā)到指定的域名(通過 spec.externlName 設(shè)定)。需要 kube-dns 版本在 1.7 以上。
另外握截,也可以將已有的服務(wù)以 Service 的形式加入到 Kubernetes 集群中來(lái)飞崖,只需要在創(chuàng)建 Service 的時(shí)候不指定 Label selector,而是在 Service 創(chuàng)建好后手動(dòng)為其添加 endpoint谨胞。
使用Cluster類型創(chuàng)建一個(gè)services
vim nginx.svc.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: default
spec:
selector:
app: nginx
clusterIP: 10.96.88.8
type: ClusterIP
ports:
- port: 80
targetPort: 80
查看service
[root@k8s-master daem]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 71d
nginx ClusterIP 10.96.88.8 <none> 80/TCP 5m38s
[root@k8s-master daem]# kubectl describe svc nginx
Name: nginx
Namespace: default
Labels: <none>
Annotations: <none>
Selector: app=nginx
Type: ClusterIP
IP: 10.96.88.8
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.1.104:80,10.244.1.108:80,10.244.2.66:80 + 1 more...
Session Affinity: None
Events: <none>
使用NodePort創(chuàng)建一個(gè)Service
vim myapp.svc.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: myapp
namespace: default
spec:
selector:
app: myapp
clusterIP: 10.96.99.99
type: NodePort
ports:
- port: 80
targetPort: 80
查看創(chuàng)建的svc和pod
root@master:~/k8s_yaml# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 2d5h
myapp NodePort 10.96.99.99 <none> 80:30107/TCP 19m
root@master:~/k8s_yaml# kubectl get pods
NAME READY STATUS RESTARTS AGE
myapp-5cbd66595b-2dghs 1/1 Running 0 15m
myapp-5cbd66595b-m5d6l 1/1 Running 0 21m
NodePort暴露端口在集群外部可以訪問