1、概述
在kubernetes中,pod是应用程序的载体,我们可以通过pod的ip来访问应用程序,但是pod的ip地址不是固定的,这也就意味着不方便直接采用pod的ip对服务进行访问。
为了解决这个问题,kubernetes提供了Service资源,Service会对提供同一个服务的多个pod进行聚合,并且提供一个统一的入口地址。通过访问Service的入口地址就能访问到后面的pod服务。
2、Service详解
2.1、Service的资源清单文件
kind: Service # 资源类型
apiVersion: v1 # 资源版本
metadata: # 元数据
name: service # 资源名称
namespace: dev # 命名空间
spec: # 描述
selector: # 标签选择器,用于确定当前service代理哪些pod
app: nginx
type: # Service类型,指定service的访问方式
clusterIP: # 虚拟服务的ip地址
sessionAffinity: # session亲和性,支持ClientIP、None两个选项
ports: # 端口信息
- protocol: TCP
port: 3017 # service端口
targetPort: 5003 # pod端口
nodePort: 31122 # 主机端口
2.2、Service类型
-
ClusterIP:默认值,它是Kubernetes系统自动分配的虚拟IP,只能在集群内部访问
-
NodePort:将Service通过指定的Node上的端口暴露给外部,通过此方法,就可以在集群外部访问服务
-
LoadBalancer:使用外接负载均衡器完成到服务的负载分发,注意此模式需要外部云环境支持
-
ExternalName: 把集群外部的服务引入集群内部,直接使用
3、Service实例
3.1、创建deploy
在使用service之前,首先利用deploy创建出3个pod,注意要为pod设置app=nginx-pod
的标签
创建deployment.yaml,内容如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: pc-deployment
namespace: dev
spec:
replicas: 3
selector:
matchLabels:
app: nginx-pod
template:
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
# 创建deploy
[root@k8s-master ~]# kubectl apply -f deployment.yaml
deployment.apps/pc-deployment created
# 查看pod详情
[root@k8s-master ~]# kubectl get pod -n dev -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pc-deployment-69cbb4f6b6-45fmg 1/1 Running 0 63s 172.17.36.99 k8s-node1 <none> <none>
pc-deployment-69cbb4f6b6-78dz5 1/1 Running 0 63s 172.17.169.169 k8s-node2 <none> <none>
pc-deployment-69cbb4f6b6-s8x2h 1/1 Running 0 63s 172.17.169.166 k8s-node2 <none> <none>
#为了方便测试我们将三个 nginx欢迎页内容分别改为所在容器IP以示区分
[root@k8s-master ~]# kubectl exec -it pc-deployment-69cbb4f6b6-45fmg -n dev /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@pc-deployment-69cbb4f6b6-45fmg:/# echo 172.17.36.99 > /usr/share/nginx/html/index.html
[root@k8s-master ~]# kubectl exec -it pc-deployment-69cbb4f6b6-78dz5 -n dev /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@pc-deployment-69cbb4f6b6-78dz5:/# echo 172.17.169.169 > /usr/share/nginx/html/index.html
[root@k8s-master ~]# kubectl exec -it pc-deployment-69cbb4f6b6-s8x2h -n dev /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@pc-deployment-69cbb4f6b6-s8x2h:/# echo 172.17.169.166 > /usr/share/nginx/html/index.html
# 分别访问三个nginx 可以看出改后效果
[root@k8s-master ~]# curl 172.17.36.99
172.17.36.99
[root@k8s-master ~]# curl 172.17.169.169
172.17.169.169
[root@k8s-master ~]# curl 172.17.169.166
172.17.169.166
3.2、ClusterIP类型的Service
创建service-clusterip.yaml文件
apiVersion: v1
kind: Service
metadata:
name: service-clusterip
namespace: dev
spec:
selector:
app: nginx-pod
type: ClusterIP
ports:
- port: 80 # Service端口
targetPort: 80 # pod端口
# 创建service
[root@k8s-master ~]# kubectl apply -f service-clusterip.yaml
service/service-clusterip created
[root@k8s-master ~]#
[root@k8s-master ~]#
# 查看service 信息
[root@k8s-master ~]# kubectl get svc -n dev -owide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service-clusterip ClusterIP 10.8.192.195 <none> 80/TCP 7s app=nginx-pod
[root@k8s-master ~]#
[root@k8s-master ~]#
# 查看service的详细信息
# 在这里有一个Endpoints列表,里面就是当前service可以负载到的服务入口 即为上面我们创建的pod的ip+nginx端口
[root@k8s-master ~]# kubectl describe svc service-clusterip -n dev
Name: service-clusterip
Namespace: dev
Labels: <none>
Annotations: <none>
Selector: app=nginx-pod
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.8.192.195
IPs: 10.8.192.195
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 172.17.169.166:80,172.17.169.169:80,172.17.36.99:80
Session Affinity: None
Events: <none>
# 查看ipvs 的映射规则 也可以看出调用service 的地址,被已轮询方式转发到相应的pod上,这个规则即为kube-proxy生成的
[root@k8s-master ~]# ipvsadm -Ln
TCP 10.8.192.195:80 rr
-> 172.17.36.99:80 Masq 1 0 0
-> 172.17.169.166:80 Masq 1 0 0
-> 172.17.169.169:80 Masq 1 0 0
# 访问 10.8.192.195 也可以看出这三个ip是以轮询方式被访问
[root@k8s-master ~]# curl 10.8.192.195
172.17.169.169
[root@k8s-master ~]# curl 10.8.192.195
172.17.169.166
[root@k8s-master ~]# curl 10.8.192.195
172.17.36.99
[root@k8s-master ~]# curl 10.8.192.195
172.17.169.169
[root@k8s-master ~]# curl 10.8.192.195
172.17.169.166
[root@k8s-master ~]# curl 10.8.192.195
172.17.36.99
[root@k8s-master ~]# curl 10.8.192.195
172.17.169.169
[root@k8s-master ~]#