介绍服务
kubernetes中服务是一种为一组相同功能的pod提供一个单一不变的接入点的资源。可以将一组提供相同服务的pod给定一个不变的接入资源。
创建服务
服务的后端可以不止有一个pod,服务连接所有的后端指定的pod,服务对后端的pod是负载均衡的。
服务是如何区分哪些pod属于服务,哪些pod不属于服务?
服务根据标签来选择pod。
也就是说,控制器根据标签控制pod,服务根据标签判断是否属于本服务。
通过yaml文件创建服务
apiVersion: v1
kind: Service
metadata:
name: tservice
spec:
#标签选择器
selector:
app: kubia-rc
ports:
#映射在主机上的端口
- port: 80
#容器内的端口
targetPort: 8080
使用命令创建服务,并查看服务
#在该文件目录下执行,创建服务
kubectl create -f test.yaml
#查看服务
kubectl get svc
#或者
kubectl get service
刚才创建了一个服务,现在使用控制器创建一些pod,通过刚才创建的服务绑定
apiVersion: v1
kind: ReplicationController
metadata:
name: kubia-rc
spec:
replicas: 3
selector:
#监测的标签
app: kubia-rc
template:
metadata:
name: kubia-rc
#控制器创建的pod携带的标签
labels:
app: kubia-rc
spec:
containers:
- name: kubia-rc
image: luksa/kubia
ports:
- containerPort: 8080
protocol: TCP
这样pod就会和服务绑定,此时,服务并没有对外暴露,我们可以在节点中查看
#查看服务的ip
kubectl get services
#在使用minikube的情况下
minikube ssh
#进入到节点之后
curl -s http://ip地址:端口号
还可以在服务中指定多个端口
apiVersion: v1
kind: Service
metadata:
name: tservice
spec:
selector:
app: kubia-rc
ports:
- port: 80
targetPort: 8080
- port: 8081
targetPort: 8081
服务发现
创建服务之后,我们还要在其它pod中能够发现服务,并调用服务,这也是服务的一个作用。
通过环境变量发现服务
我们可以进入一个pod,在pod中查看环境变量来发现服务
#进入一个pod
kubectl exec -it podname bash
env
此时我们可以发现之前创建的服务的环境变量。
通过DNS发现服务
进入到pod中后,我们可以通过服务名称命名空间发现服务。
#例如服务名为kubia-rc
#进入到pod中
curl -s http://kubia-rc.default.svc.cluster.local
连接集群外部的服务
我们创建的服务,服务并不是和pod直接相连,而是通过服务和pod中间的endpoints层进行请求分发,我们既然想连接集群外部的服务,也就是说,将endpoints层的ip地址写外部的ip地址,这样请求分发时,就会分发到集群外部服务。
我们要创建没有节点选择器的服务,(如果有节点选择器,就会在本地集群中找目标pod)
apiVersion: v1
kind: Service
metadata:
name: tend
spec:
ports:
- port: 8081
单独创建endpoints层
apiVersion: v1
kind: Endpoints
metadata:
name: tend#注意,endpoints层的name要和service的name相同,否则不匹配
subsets:
- addresses: #外部服务地址
- ip: 150.158.178.239
ports: #端口号
- port: 80
这样创建service和endpoints就会自动找到外部服务
#创建service和endpoints
kubectl create -f service.yaml
kubectl create -f endpoints.yaml
#端口暴露端口
minikube service tend
将服务暴露给外部服务
有几种方式可以在外部访问服务:
- 使用NodePort,每个集群节点都会在节点上打开一个端口,将接收到的服务重定向到基础服务
- 使用LoadBalance,有一个专用的负载均衡器,将流量重定向到节点端口。
- Ingress资源,通过一个地址公开多个服务。
使用NodePort类型服务
创建NodePort服务
apiVersion: v1
kind: Service
metadata:
name: myapp
spec:
type: NodePorts
selector:
#通过标签选择器确定pod
app: myapps
ports:
- port: 80#映射出的端口
targetPort: 8080#容器内的端口
#使用命令创建服务
kubectl create -f test.yaml
#暴露端口
minikube service myapp
#这时流量会自动转发到某一个pod
注意:我们使用NodePort类型时,当有流量访问时,会先到某一个节点,从某一个节点到服务控制器,进行流量转发。这就导致,如果客户端访问的某一个节点出现错误,就导致该请求不能正常响应
使用LoadBalance类型
apiVersion: v1
kind: Service
metadata:
name: myapp
spec:
type: LoadBalancer
selector:
app: myapp
ports:
- port: 80
targetPort: 8080
与上一个不同的是,在这种类型下,负载均衡会有一个独立的地址,不会因为某一个节点的失效,导致部分请求无响应。
通过Ingress暴露服务
首先确保ingress服务打开,
列出ingress类型的地址
kubectl get ingresses
我们还要在本地的DNS列表中增加一项,映射到ip地址
ingress工作机里
在地址栏中输入url,通过本地的DNS映射到ip地址,ip地址找到Ingress,从ingress中决定访问哪个服务,进入到服务之后,通过Endpoints决定进哪些pod,将请求发送给其中一个pod。