k8s集群内部服务发现的方式有两种: 1、通过变量发现 只能获取相同namespace里的变量 变量的获取有先后顺序,引用的变量必须要先创建 2、通过DNS的方式发现 在kube-system里有dns,可以自动发现所有命名空间里的服务的clusterIP 所以,在同一个命名空间里,一个服务访问另外一个服务的时候,可以直接通过服务名来访问 只要创建了一个服务(不管在哪个ns里创建的),都会自动向kube-system里的DNS注册 如果是不同的命名空间,可以通过 服务名.命名空间名 来访问

Service是一种抽象的对象,它定义了一组Pod的逻辑集合和一个用于访问它们的策略。 service主要实现集群内部通信,以及基于四层的内外通信(如端口)。 service用于为pod提供一个固定,统一的访问接口及负载均衡的能力,并借助新一代DNS的服务发现功能,解决客户端发现并访问容器化应用的难题。 service的地址是不会发生改变的,它通过标签选择器和后端的pod关联。 k8s集群中的3种ip: 1、Node IP:Node节点的IP地址 2、Pod IP: Pod的IP地址 3、Cluster IP: Service的IP地址,不能ping通

k8s集群中的service类型 $ kubectl explain svc.spec.type Defaults to ClusterIP. Valid options are ExternalName, ClusterIP, NodePort, and LoadBalancer. 不使用type字段的话,默认就是ClusterIP类型 1、ClusterIP:通过集群的内部 IP 暴露服务,选择该值,服务只能够在集群内部可以访问,这也是默认的ServiceType。 k8s集群内部流量走向: 内部客户端--service(ClussterIp:Port)--endpoint(ip和port列表)--应用pod(port) 2、NodePort:通过每个 Node 节点上的 IP 和静态端口(NodePort)暴露服务。NodePort 服务会路由到 ClusterIP 服务,这个 ClusterIP 服务会自动创建。通过请求 :,可以从集群的外部访问一个 NodePort 服务。 NodePort类型的service数据流向: 外部用户--外部LB--nodePort(集群入口)--service--endpoint--应用pod 3、LoadBalancer类型的service应用在公有云环境中 4、ExternalName类型的service用于实现集群内部pod访问集群外部的服务 数据流向:内部pod--service--外部服务 该类型的service没有serviceIP,没有nodeport,没有标签选择器,需要CNAME解析记录

完成内部流量转发工作的是各工作节点的kube-proxy proxy工作模式有3种: 1、userspace代理模式 2、iptables代理模式 3、ipvs代理模式 ipvs模式和iptables模式的区别仅仅是:请求流量的调度功能由ipvs完成,其他功能仍由iptables完成

创建service的两种方式: 1、使用kubectl expose命令 2、定义资源清单文件

$ kubectl explain svc.metadata FIELDS: labels name #svc的名字 namespace $ kubectl explain svc.spec FIELDS: clusterIP #svc的ip地址 ports selector type

$ kubectl explain svc.spec.clusterIP clusterIP is the IP address of the service and is usually assigned randomly by the master. Valid values are "None", empty string (""), or a valid IP address. "None" can be specified for headless services when proxying is not required. Only applies to types ClusterIP, NodePort, and LoadBalancer. Ignored if type is ExternalName. clusterIP表示svc的ip地址,一般自动获取,不用手动指定。如果不使用该字段或者指定其值为空,都表示自动获取ip地址。 如果指定其值为None,表示该svc是无头服务。 当svc的type是ExternalName时,不能使用该字段。

$ kubectl explain svc.spec.ports FIELDS: 1、port: 指该service暴露的端口,用yaml文件创建svc时是必选项,用命令创建时可以不指定,如果不指定,会继承pod中的containerPort。 2、nodePort: 指node节点端口(只有当type为NodePort或LoadBalancer时才需要该参数,一般自动生成),用于对外通信。 3、targetPort: 指后端pod暴露的端口,就是pod中的containerPort。 如果既不指定port又不指定targetPort,那么port和targetPort都会继承pod中的containerPort。 如果指定了port而没有指定targetPort,那么targetPort会继承port值,所以此时必须指定targetPort值为pod中的containerPort,不能随便指定端口号,除非port值和pod中的containerPort相同(这种情况可以不指定targetPort)。

当type为ClusterIP时,流量经过的端口走向是: svc端口(port)----pod端口(targetPort)----容器端口(containerPort) 当type为NodePort时,流量经过的端口走向是: 节点端口(NodePort)----svc端口(port)----pod端口(targetPort)----容器端口(containerPort)

使用命令创建svc(containerPort是8080) $ kubectl get deploy $ kubectl expose deploy deploy_name1 $ kubectl get svc $ kubectl delete svc svc_name $ kubectl expose deploy deploy_name2 --port=8080 $ kubectl expose deploy deploy_name3--port=80 --target-port=8080 $ kubectl expose deploy deploy_name4 --port=80 --target-port=8080 --type=NodePort $ kubectl get svc svc_name -o yaml

spec:
  clusterIP: 10.97.153.130
  externalTrafficPolicy: Cluster
  ports:
  - nodePort: 30693
    port: 80
    protocol: TCP
    targetPort: 8080

$ curl http://10.97.153.130 $ curl http://192.168.1.243:30693 #243是master地址 $ kubectl delete svc svc_name

用yaml文件创建svc

apiVersion: v1
kind: Service
metadata:
  labels:
    ame: mysvc
  name: mysvc
spec:
  ports:
  - port: 80
    targetPort: 8080
  selector:
    app: mysvc        #匹配标签为app: mysvc的后端pod
  type: NodePort

Headless无头类型的service: 该service没有IP,客户端不经过service,而是直接访问后端的pod 无头服务的type不能是NodePort。

kind: Service
spec:
  clusterIP: None    #(该参数设置为None即可成为无头service)

查看某个服务下有哪些pod: $ kubectl get svc $ kubectl get svc svc_name -o yaml $ kubectl describe svc svc_name Selector: run=nginx1 $ kubectl get pod -l run=nginx1

验证通过DNS发现服务 $ kubectl get pod -n kube-system |grep dns kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP
$ yum install bind-utils -y $ dig -t A svc_name.default.svc.cluster.local. @10.96.0.10 $ kubectl get svc svc_name -o yaml 在pod中验证dns服务发现 $ kubectl run busybox --rm -it --image=busybox sh / # cat /etc/resolv.conf nameserver 10.96.0.10 search default.svc.cluster.local svc.cluster.local cluster.local example.com