k8s–基础–17–Service–服务类型


1、 环境准备

1.1、需要使用到的命令

# 启动
kubectl apply -f /root/test/deployment_nginx.yaml

# 查看pod
kubectl get pods -l nginx_pod=nginx_pod_la  -o wide


# 启动
kubectl apply -f /root/test/service_nginx.yaml
# 查看service
kubectl get svc service-nginx
# 查看service明细
kubectl describe svc service-nginx


# 创建命名空间dev
kubectl create ns  dev
# 查看dev空间的所有资源
kubectl get all -n dev

1.1、通过deployment创建pod

  1. 具体看 k8s–基础–14–deployment
  2. 该pod是为了给service代理使用

1.1.1、配置文件

vim /root/test/deployment_nginx.yaml  

内容

apiVersion: apps/v1
kind: Deployment
metadata:
  # Deployment 的名称
  name: deployment-nginx
  # Deployment 的标签
  labels:
    k1: k1_la
    k2: k2_la
spec:
  # 副本数目
  replicas: 3
  # 选择器
  selector:
    # 选择器匹配的标签
    matchLabels:
      nginx_pod: nginx_pod_la
  # Pod 模板
  template: 
    metadata:
      # Pod的标签
      labels:
        nginx_pod: nginx_pod_la
    spec:
      containers:
        # 容器名称
      - name: nginx
        # 镜像
        image: nginx
        # 镜像策略
        imagePullPolicy: IfNotPresent
		# 容器端口
        ports:
        - containerPort: 80

1.2、创建Service

vim /root/test/service_nginx.yaml

内容

apiVersion: v1
kind: Service
metadata:
  # Service 的名称
  name: service-nginx
  labels:
  # Service 的标签
    service_k1: k1_la
spec:
  ports:
  # 端口
  - port: 80
  # 协议
    protocol: TCP
  # 标签选择器,选择Deployment 的标签
  selector:
    nginx_pod: nginx_pod_la

2、 服务类型

  1. 对一些应用(如 Frontend)的某些部分,可能希望通过外部(Kubernetes 集群外部)IP地址暴露Service服务。
  2. Kubernetes Service Types允许指定一个需要的类型的Service,默认是ClusterIP类型。
  3. 服务类型有
    1. ClusterIP
    2. nodePort
    3. LoadBalancer
    4. ExternalName

3、ClusterIP

Service.spec.type:ClusterIP
 
  1. service服务,只可以被k8s集群中的节点或者pod所访问
  2. service服务,不能被k8s集群之外的机器或者浏览器访问。
  3. 原理:通过集群的内部IP暴露service服务
  4. 是默认配置

在这里插入图片描述

4、nodePort

Service.spec.type:nodePort
 
  1. service服务,可以被k8s之外的主机或者浏览器访问
    1. 通过每个Node上的IP和静态端口(NodePort)暴露service服务。
  2. 通过请求:,可以从集群的外部访问一个Service服务。
  3. 底层实现是kube-proxy

4.1、数据流量走向

访问物理节点(master节点或者node节点)ip:宿主机映射的端口
	映射到--->service ip:service的端口
		映射到----->pod ip:container port

4.2、分配端口

  1. service服务暴露到Node的端口范围
    1. 30000-32767
  2. 每个Node将从该端口(每个Node上的同一端口)代理到Service
  3. 端口将通过Service的spec.ports[*].nodePort字段被指定。

4.3、测试

4.3.1、编辑配置文件

在这里插入图片描述

4.3.2、访问

http://192.168.187.154:30771/

在这里插入图片描述

5、ExternalName

Service.spec.type:ExternalName
 
  1. 是Service的特例
  2. k8s集群从内到外的访问
  3. 它没有selector,也没有定义任何的端口和Endpoint。
  4. 对于运行在集群外部的服务,它通过返回该外部服务的别名这种方式来提供服务。
    1. 通过返回CNAME和它的值,可以将服务映射到externalName字段的内容
  5. 没有任何类型代理被创建
  6. Kubernetes 1.7+ 的kube-dns才支持。

5.1、案例

5.1.1、配置文件


apiVersion: v1
kind: Service
metadata:
  # Service 的名称
  name: service-nginx
  # 命名空间
  namespace: dev
spec:
  type: ExternalName
  externalName: hd.db.com
  

在这里插入图片描述

5.1.2、说明

  1. 访问名称:
    1. 规则:ServiceName.namespace.sve.cluster.local
    2. 对应:service-nginx.dev.svc.cluster.local
  2. 当k8s 查询主机 service-nginx.dev.svc.cluster.local 时,集群的DNS服务将返回一个值为hd.db.com的CNAME记录。
    1. 总结:访问service-nginx.dev.svc.cluster.local会被代理到hd.db.com
  3. 访问这个服务的工作方式与其它的相同,唯一不同的是重定向发生在DNS层,而且不会进行代理或转发。

6、LoadBalancer

Service.spec.type:LoadBalancer
 
  1. 使用云提供商的负载局衡器,将为Service提供负载均衡器。
  2. 可以向外部暴露服务。
  3. 负载均衡器是异步创建的
  4. 外部的负载均衡器可以路由到NodePort服务和ClusterIP服务。
  5. 负载均衡器的信息将会通过Service的status.loadBalancer字段被发布出去。

6.1、案例

6.1.1、配置文件

kind: Service
apiVersion: v1
metadata:
  # Service 的名称
  name: service-nginx
spec:
  selector:
    # 标签选择器,选择 k1-nginx: v1 标签
    k1-nginx: v1
  ports:
	# TCP 协议
    - protocol: TCP
	  # service 端口
      port: 80
	  # 目标端口
      targetPort: 9376
	  # 节点端口
      nodePort: 30061
  # 集群IP
  clusterIP: 10.0.171.239
  # 负载IP
  loadBalancerIP: 78.11.24.19
  # 服务类型
  type: LoadBalancer
status:
  loadBalancer:
    ingress:
      - ip: 146.148.47.155

6.1.2、说明

  1. 来自外部负载均衡器的请求将直接打到 backend Pod 上,在这些情况下,将根据用户设置的loadBalancerIP来创建负载均衡器。
  2. 某些云提供商允许设置loadBalancerIP。
    1. 如果没有设置loadBalancerIP:将会给负载均衡器指派一个临时IP。
    2. 如果设置了loadBalancerIP:但云提供商并不支持这种特性,那么设置的loadBalancerIP值将会被忽略掉。
  3. k8s集群内容或者集群节点 请求10.0.171.239会被代理到78.11.24.19

7、其他

7.1、Headless Service

  1. 就是没有Service IP的Service
  2. 通过spec.clusterIP:'None’来实现

7.1.1、场景

  1. 不需要负载均衡
  2. 不需要单独的Service IP

7.1.2、好处

  1. 允许开发人员自由寻找他们自己的方式,降低与Kubernetes系统的耦合性。
  2. 应用仍然可以使用一种自注册的模式和适配器,对其它需要发现机制的系统能够很容易地基于这个API来构建。

7.1.3、注意

  1. 这类Service并不会分配Cluster IP,kube-proxy 不会处理它们,而且平台也不会为它们进行负载均衡和路由。
  2. DNS如何实现自动配置,依赖于Service是否定义了selector

7.1.4、Headless Service是否配置了Selector

  1. 是:Endpoint控制器在API中创建了Endpoints记录,并且修改DNS配置返回 记录(地址),通过这个地址直接到达Service的后端Pod上
  2. 否:Endpoint 控制器不会创建Endpoints记录。

7.1.5、操作1–有配置Selector

apiVersion: v1
kind: Service
metadata:
  # Service 的名称
  name: service-nginx
  labels:
  # Service 的标签
    service_k1: k1_la
spec:
  clusterIP: 'None'
  ports:
  # 端口
  - port: 80
  # 协议
    protocol: TCP
  # 标签选择器,选择Deployment 的标签
  selector:
    nginx_pod: nginx_pod_la

在这里插入图片描述

Endpoint控制器在API中创建了Endpoints记录,并且修改DNS配置返回记录(地址),通过这个地址直接到达Service的后端Pod上

7.1.6、操作2–没有配置Selector

先要执行删除动作,再启动


kubectl delete -f /root/test/service_nginx.yaml
kubectl apply -f /root/test/service_nginx.yaml

配置内容

apiVersion: v1
kind: Service
metadata:
  # Service 的名称
  name: service-nginx
  labels:
  # Service 的标签
    service_k1: k1_la
spec:
  clusterIP: 'None'
  ports:
  # 端口
  - port: 80
  # 协议
    protocol: TCP

在这里插入图片描述

Endpoint 控制器不会创建Endpoints记录。

7.2、AWS 内部负载均衡器

7.2.1、场景

在混合云环境中,从虚拟私有云(VPC)环境中的服务 路由流量

7.2.2、说明

在 Service 中增加 annotation 来实现,如下所示:

[...]
metadata: 
    name: my-service
    annotations: 
        service.beta.kubernetes.io/aws-load-balancer-internal: 0.0.0.0/0
[...]

在水平分割的DNS环境中,需要两个Service来将外部和内部的流量路由到Endpoint 上。

7.3、AWS SSL 支持

对运行在AWS上部分支持SSL的集群,从1.3版本开始,可以为LoadBalancer类型的Service增加两个annotation.

7.3.1、第1个annotation

metadata:
      name: my-service
      annotations:
        service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012
  1. 指定了使用的证书。
  2. 证书可以是第三方发行商发行的证书,这个证书或者被上传到IAM或者由AWS的证书管理器创建

7.3.1、第2个annotation

metadata:
      name: my-service
      annotations:
         service.beta.kubernetes.io/aws-load-balancer-backend-protocol: (https|http|ssl|tcp)
  1. 指定了pod使用的协议。
  2. 对于HTTPS和SSL,ELB将期望该pod基于加密的连接来认证自身。
    1. HTTP和HTTPS将选择7层代理:
      1. ELB将中断与用户的连接,当转发请求时,会解析Header信息并添加上用户的IP地址(pod只能在连接的另一端看到该IP地址)。
    2. TCP和SSL将选择4层代理:
      1. ELB将转发流量,并不修改Header信息。

7.4、外部 IP

7.4.1、场景

  1. 通过外部的IP路由到集群中一个或多个Node上
  2. 通过外部IP(作为目的IP地址)进入到集群,转到Service的端口上的流量,将会被路由到Service的Endpoint上。

7.4.2、说明

  1. 通过指定spec.externalIPs来暴露
  2. externalIPs可以同任意的的一个ServiceType来一起指定

7.4.3、案例

kind: Service
apiVersion: v1
metadata:
  name: my-service
spec:
  selector:
    app: MyApp
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 3306
  externalIPs: 
- 80.11.12.10

在上面的例子中,my-service可以在80.11.12.10:80(外部IP:端口)上被客户端访问。

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐