Service 作用和原理
作用:Service 的作用次要是用来做负载平衡,dns 解析以及对外裸露端口。所有的 pod IP 和端口都会通过 label 匹配到,而后通过 coredns 解析实现了服务发现
原理:Service 通过 iptables 或者 ipvs 对拜访的指标地址进行批改转发数据
Service 的类型
- Cluster
- NodePort
- LoadBalancer
- ExternalName
Cluster 类型
$ cat myapp-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deploy
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:v1
ports:
- containerPort: 80
name: http
$ cat myapp-svc.yaml
kind: Service
apiVersion: v1
metadata:
name: myapp-svc
spec:
selector:
app: myapp
ports:
- protocol: TCP
port: 80
targetPort: 80
$ kubectl apply -f myapp-deploy.yaml
deployment.apps/myapp-deploy created
$ kubectl apply -f myapp-svc.yaml
service/myapp-svc created
$ kubectl get deploy,svc,endpoints
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/myapp-deploy 3/3 3 3 28s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 5d21h
service/myapp-svc ClusterIP 10.105.225.171 <none> 80/TCP 22s
NAME ENDPOINTS AGE
endpoints/kubernetes 172.16.56.133:8443 5d21h
endpoints/myapp-svc 172.17.0.6:80,172.17.0.7:80,172.17.0.8:80 22s
$ kubectl run cirros-$RANDOM --rm -ti --image=cirros -- sh
/ # curl http://10.105.225.171
<h3>Hello World!</h3><b>Hostname:</b> myapp-deploy-ccc8b4bb5-f829g<br/><b>Visits:</b> <i>cannot connect to Redis, counter disabled</i>/
NodePort 类型
$ cat myapp-svc.yaml
kind: Service
apiVersion: v1
metadata:
name: myapp-svc
spec:
type: NodePort
selector:
app: myapp
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 32223
$ kubectl apply -f myapp-svc.yaml
service/myapp-svc configured
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 5d21h
myapp-svc NodePort 10.105.225.171 <none> 80:32223/TCP 9m46s
$ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
myapp-deploy-ccc8b4bb5-dn4lb 1/1 Running 0 10m 172.17.0.6 minikube <none> <none>
myapp-deploy-ccc8b4bb5-ds542 1/1 Running 0 10m 172.17.0.7 minikube <none> <none>
myapp-deploy-ccc8b4bb5-f829g 1/1 Running 0 10m 172.17.0.8 minikube <none> <none>
如果你尝试刷新页面,会发现失去不同的主机名,这是正确的
ExternalName 类型
$ cat external-redis-svc.yaml
kind: Service
apiVersion: v1
metadata:
name: external-redis-svc
namespace: default
spec:
type: ExternalName
externalName: www.baidu.com
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 0
selector: {}
$ kubectl create -f external-redis-svc.yaml
service/external-redis-svc created
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
external-redis-svc ExternalName <none> www.baidu.com 80/TCP 5s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 5d21h
myapp-svc NodePort 10.105.225.171 <none> 80:32223/TCP 17m
$ kubectl run -ti --rm busybox --image=busybox -- sh
/ # nslookup external-redis-svc.default.svc.cluster.local.
Server: 10.96.0.10
Address: 10.96.0.10:53
external-redis-svc.default.svc.cluster.local canonical name = www.baidu.com
www.baidu.com canonical name = www.a.shifen.com
Name: www.a.shifen.com
Address: 163.177.151.109
Name: www.a.shifen.com
Address: 163.177.151.110
*** Can't find external-redis-svc.default.svc.cluster.local.: No answer
/ # exit
- 如果内部服务没有域名,为了进步服务的兼容性能够采纳 service+ 手动 endponit,自定义一个域名
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9376
apiVersion: v1
kind: Endpoints
metadata:
name: my-service
subsets:
- addresses:
- ip: 192.0.2.42
ports:
- port: 9376