service用途:
service 为后端pod提供一组负载均衡代理
创建服务:
kubectl expose #快速创建服务
yaml创建服务:
apiVersion: v1
kind: Service
metadata:
name: kubia
spec:
ports:
- port: 80 #该服务对外端口
targetPort: 8080 #服务将连接转发到容器的端口
selector:
app: kubia #具有app=kubia标签的pod都属于该服务
将请求80端口的服务转发到pod标记为app=kubia的 8080 端口上。
kubuctl creatr -f kubia-svc.yaml #发布创建服务
kubctl get svc #查看服务资源
cluster-ip 显示集群IP,只能在集群内部可以被访问,服务的主要目标就是使集群内部的pod可以访问这组POD。
测试cluster-ip是否将请求转发到后端pod
kubectl exec kubia-7nog1(目标pod) -- curl -s http://10.111.249.153 (cluster ip)
-- 两个横杠之后的内容是指在pod内部需要执行的命令
如果希望请求每次都需要指向同一个pod,可以设置服务的sessionAffinity属性为ClientIP.默认值是None.
apiVersion: v1
kind: Service
apec:
sessionAffinity: ClinetIP
.......
这种方式会使代理将来自同一个client ip的所有请求转发至同一个pod 上。
k8s的服务不是在http层面上工作,服务处理TCP或者UDP包,所以不支持基于cookie的会话亲和性选项。
同一个服务暴露两个端口:
apiVersion: v1
kind: Service
metadata:
name: kubia
spec:
ports:
- name: http
port: 80
targetPort: 8080 #pod的8080端口映射成80端口
- name: https
port: 443
targetPort: 8443 #pod的8443端口映射成443
selector:
app: kubia
使用命名的端口:
有点: 即使更换端口号也无需更改服务spec.如果采用命名端口,仅需要改变spec pod中的端口号。
示例:
kind: pod
spec:
containers:
- name: kubia
ports:
- name: http
containerPort: 8080 #端口8080被命名为HTTP
-name: https
containerPort: 8443 #端口8443被命名为https
apiVersion: v1
kind: Service
spec:
ports:
- name: http
port: 80
targetPort: http #将80端口映射到容器中被称为HTTP
- name: https
port: 443
targetPort: https #将443端口映射到容器中被称为HTTPS
服务发现:
通过创建服务,可以通过一个稳定的IP访问到pod,在服务周期内这个IP保持不变,后端的pod删除重建或者数量增减,始终可以通过服务IP访问到这些pod
服务发现的两种方式:
1、通过环境变量发现:
在pod运行的时候,K8S会初始化一系列环境变量指向现在存在的服务,如果服务早于客户端pod的创建,pod上的进程可以根据环境变量活的服务的IP和端口。
kubectl exec kubia-3inly env
KUBIA_SERVICE_HOST=10.11.249.153 #这是服务集群的ip
KUBIA_SERVICE_PORT=80 #这是服务集群的端口
环境变量是获得服务端口和IP的一种方式。
2、通过DNS发现服务
pod是否使用内部DNS服务根据pod中的spec的dnsPolicy属性来决定
示例:FQDN
backend-database.default.svc.cluster.local #链接数据库的栗子
backend-database #对应的服务名称
default #表示服务在其中定义的名称空间
svc.cluster.local #后缀,可以省略。
在pod上可以使用FQDN去访问后端的数据库服务。
kubectl exec -it pod名称 bash #进入pod shell环境
curl http://backend-database.default.svc.cluster.local 或者 curl http://backend-database
注: 集群IP是虚拟IP,可以访问但无法PING通
链接集群外部服务:
1、服务endpoint
服务并不是和pod直接相连的,有一种资源介于两者之间,它就是endpoint。
通过 kubectl describe svc kubia 可以看到 Endpoints: pod的ip列表和端口。
endpoint 就是暴露pod的ip和端口资源。
kubectl get endpoints kubia(服务名称) #查看endpoints的详细信息
spec中定义了pod选择器,但在重定向传入链接时不会直接使用它。选择器用于构建ip列表和端口,并存储在
endpoint资源中,当客户端链接到服务时,服务代理选择这些IP和端口对中的一个,并将传入链接重定向到在该位置监听的服务器。
2、手动配置服务的endpoint
如果创建了不包含pod选择器的服务,K8S就不会创建endpoint资源,这样的话就需要手动配置endpoint资源。
示例:
(1)、创建一个不含pod选择器的服务:
apiVersion: v1
kind: Service
metadata:
name: external-service #服务的名字必须和endpoint对象的名字匹配
spec:
ports:
- port: 80 #服务中没有定义选择器,它将接受80端口的传入链接。
(2)手动创建endpoint资源
apiVersion: v1
kind: Endpoints
metadata:
name: external-service #Eendpoint名称必须与服务名称匹配
subsets:
- addresses:
- ip: 11.11.11.11 #服务将链接重定向到endpoint的IP地址
- ip: 22.22.22.22
ports:
- port: 80 #endpoint的目标端口