dmz社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 427|回复: 0

[Html/Css] 025.掌握Service-SVC基础使用

[复制链接]
  • TA的每日心情

    2024-2-20 11:15
  • 签到天数: 11 天

    [LV.3]偶尔看看II

    878

    主题

    4343

    帖子

    3987

    积分

    终身会员[A]

    Rank: 7Rank: 7Rank: 7

    积分
    3987

    发表于 2020-4-12 08:00:01 | 显示全部楼层 |阅读模式

    本站资源全部免费,回复即可查看下载地址!

    您需要 登录 才可以下载或查看,没有帐号?立即注册

    x
    目录


    一        Service简介1.1        Service概念
    Service是Kubernetes的核心概念,通过创建Service,可以为一组具有相同功能的容器应用提供一个统一的入口地址,并且将请求负载分发到后端的各个容器应用上。
    1.2        Service定义详解
    [HTML] 纯文本查看 复制代码
    apiVersion: v1		#必须,api版本
    kind: Service		#必须,类型为Service
    metadata:			#必须,元数据
      name: string		#必须,Service名称
      namespace: string		#必须,命名空间,默认为default
      labels:			#自定义标签属性列表
        - name: string
      annotations:		#自定义注解属性列表
        - name: string
    spec:			#必须,详细描述
      selector: []		#必须,Label Selector配置
      type: ClusterIP		#必须,Serice类型,详见如下
      sessionAffinity: string	#虚拟服务IP地址,当选择type=ClusterIP时,若不指定,则系统进行自动分配;当type=LoadBalancer时,需要指定
      ports:			#Service需要暴露的端口列表
      - name: string		#端口名称
        protocol:		#端口协议,支持TCP和UDP,默认为TCP
        port: int		#服务监听的端口号
        targetPort: 8080	#需要转发到后端Pod的端口号
        nodePort: int		#当spec.type=NodePort时,指定映射到物理机的端口号
    status:			#当spec.type=LoadBalancer时,设置外部负载均衡的地址,用于公有云
      loadBalancer:		#外部负载均衡器
        ingress:		#外部负载均衡器
          ip: string		#外部负载均衡器的IP地址
          hostname: string	#外部负载均衡器的主机名



    spec.type:Service的类型,指定Service的访问方式,默认为ClusterIP。
    • ClusterIP:虚拟的服务IP地址,该地址用于Kubernetes集群内部的Pod访问,在Node上kube-proxy通过设置的iptables规则进行转发;
    • NodePort:使用宿主机的端口,使能够访问各Node的外部客户端通过Node的IP地址和端口号就能访问服务;
    • LoadBalancer:使用外接负载均衡器完成到服务的负载分发,需要在spec.status.loadBalancer字段指定外部负载均衡器的IP地址,并同时定义nodePort和clusterIP,用于公有云。






    二        Service基本使用2.1        Service的基本用法
    一般来说,对外提供服务的应用程序需要通过某种机制来实现,对于容器应用最简便的方式就是通过TCP/IP机制及监听IP和端口号来实现。
    示例:定义一个提供Web服务的RC,由两个Tomcat容器副本组成,每个容器都通过containerPort设置提供服务的端口号为8080。
    [root@k8smaster01 study]# cat webapp-rc.yaml


    [HTML] 纯文本查看 复制代码
    apiVersion: v1
    kind: ReplicationController
    metadata:
      name: webapp
    spec:
      replicas: 2
      template:
        metadata:
          name: webapp
          labels:
            app: webapp
        spec:
          containers:
          - name: webapp
            image: tomcat
            ports:
            - containerPort: 8080





    [root@k8smaster01 study]# kubectl create -f webapp-rc.yaml
    [root@k8smaster01 study]# kubectl get pods -l app=webapp -o yaml | grep podIP
        podIP: 172.24.9.88
        podIP: 172.24.9.199
    [root@k8smaster01 study]# curl 172.24.9.88:8080




    直接通过Pod的IP地址和端口号可以访问到容器应用内的服务,但是Pod的IP地址是不可靠的,例如当Pod所在的Node发生故障时,Pod将被Kubernetes重新调度到另一个Node,Pod的IP地址将发生变化。
    如果容器应用本身是分布式的部署方式,通过多个实例共同提供服务,就需要在这些实例的前端设置一个负载均衡器来实现请求的分发。Kubernetes中的Service就是用于解决这些问题的核心组件。
    Service示例:以如上webapp应用为例,为了让客户端应用访问到两个Tomcat Pod实例,可以创建一个Service来提供服务。Kubernetes提供了一种快速的方法,即通过kubectl expose命令来创建Service。
    [root@k8smaster01 study]# kubectl expose rc webapp
    [root@k8smaster01 study]# kubectl get svc | grep -E 'NAME|webapp'
    NAME                       TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
    webapp                     ClusterIP   10.10.10.51    <none>        8080/TCP   45s
    [root@k8smaster01 study]# curl 10.10.10.51:8080                #测试访问

    提示:如上Service地址10.10.10.51:8080的访问被自动负载分发到后端两个Pod。
    Service示例2:通过Service配置文件暴露服务。
    [root@k8smaster01 study]# vi webappsvc.yaml

    [HTML] 纯文本查看 复制代码
    apiVersion: v1
    kind: Service
    metadata:
      name: webappservice
    spec:
      ports:
      - port: 8081
        targetPort: 8080
      selector:
        app: webapp


    [root@k8smaster01 study]# kubectl create -f webappsvc.yaml
    [root@k8smaster01 study]# kubectl get svc | grep -E 'NAME|webappser'
    NAME                       TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
    webappservice              ClusterIP   10.10.10.83    <none>        8081/TCP   22s
    提示:如上Service定义中的关键字段是ports和selector。本例中ports定义部分指定了Service所需的虚拟端口号为8081,由于与Pod容器端口号8080不一样,所以需要再通过targetPort来指定后端Pod的端口号。selector定义部分设置的是后端Pod所拥有的label:app=webapp。
    [root@k8smaster01 study]# curl 10.10.10.83:8081                #访问测试
    • Service负载分发策略:RoundRobin和SessionAffinity

    • RoundRobin:轮询模式,即轮询将请求转发到后端的各个Pod上。
    • SessionAffinity:基于客户端IP地址进行会话保持的模式,即第1次将某个客户端发起的请求转发到后端的某个Pod上,之后从相同的客户端发起的请求都将被转发到后端相同的Pod上。

    在默认情况下,Kubernetes采用RoundRobin模式对客户端请求进行负载分发,同时可以通过设置service.spec.sessionAffinity=ClientIP来启用SessionAffinity策略。这样,同一个客户端IP发来的请求就会被转发到后端固定的某个Pod上了。
    通过Service的定义,Kubernetes实现了一种分布式应用统一入口的定义和负载均衡机制。Service还可以进行其他类型的设置,例如设置多个端口号、直接设置为集群外部服务,或实现为Headless Service(无头服务)模式。
    2.2        多端口Service
    有时一个容器应用也可能提供多个端口的服务,那么在Service的定义中也可以相应地设置为将多个端口对应到多个应用服务。
    示例1:如下,Service设置了两个端口号,并且为每个端口号都进行了命名。
    [root@k8smaster01 study]# vi twoportservice.yaml


    [HTML] 纯文本查看 复制代码
    apiVersion: v1
    kind: Service
    metadata:
      name: webapp[/align][align=left]spec:
      ports:
      - port: 8080
        targetPort: 8080
        name: web
      - port: 8005
        targetPort: 8005
        name: management
      selector:
        app: webapp

    [root@k8smaster01 study]# vi kubednsservice.yaml


    [HTML] 纯文本查看 复制代码
    apiVersion: v1
    kind: Service
    metadata:
      name: kube-dns
      namespace: kube-system
      labels:
        k8s-app: kube-dns
        kubernetes.io/cluster-service: "true"
        kubernetes.io/name: "KubeDNS"
    spec:
      selector:
        k8s-app: kube-dns
      clusterIP: 169.169.0.100
      ports:
      - name: dns
        port: 53
        protocol: UDP
    
      - name: dns-tcp
        port: 53
        protocol: TCP

    2.3        外部服务Service
    在某些环境中,应用系统需要将一个外部数据库、另一个集群或Namespace中的服务作为服务的后端,则可通过创建一个无Label Selector的Service来实现。
    [root@k8smaster01 study]# vi noselectorservice.yaml


    [HTML] 纯文本查看 复制代码
    apiVersion: v1
    kind: Service
    metadata:
      name: my-service
    spec:
      ports:
      - protocol: TCP
        port: 80
        targetPort: 80


    [root@k8smaster01 study]# kubectl create -f noselectorservice.yaml
    如上定义创建的是一个不带标签选择器的Service,即无法选择后端的Pod,系统不会自动创建Endpoint,因此需要手动创建一个和该Service对应的Endpoint,用于指向实际的后端访问地址。
    如下所示的Endpoint的定义文件:
    [root@k8smaster01 study]# vi noselectorendpoint.yaml


    [HTML] 纯文本查看 复制代码
    apiVersion: v1
    kind: Endpoints
    metadata:
      name: my-service
    subsets:
    - addresses:
      - IP: 47.96.145.131
      ports:
      - port: 80


    [root@k8smaster01 study]# kubectl create -f noselectorendpoint.yaml
    [root@k8smaster01 study]# kubectl get svc | grep -E 'NAME|my-service'
    NAME                       TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
    my-service                 ClusterIP   10.10.10.211   <none>        80/TCP     3s
    [root@k8smaster01 study]# curl 10.10.10.211


    提示:如上所示,访问没有标签选择器的Service和带有标签选择器的Service一样,请求将会被路由到由用户手动定义的后端Endpoint上。

    三        Headless Service3.1        无头服务简介
    在某些应用场景中,若需要人为指定负载均衡器,不使用Service提供的默认负载均衡的功能,或者应用程序希望知道属于同组服务的其他实例。Kubernetes提供了Headless Service来实现这种功能,即不为Service设置ClusterIP(入口IP地址),仅通过Label Selector将后端的Pod列表返回给调用的客户端。
    此场景中,Service就不再具有一个特定的ClusterIP地址,对其进行访问将获得包含Label“app=nginx”的全部Pod列表,然后客户端程序自行决定如何处理这个Pod列表。
    例如,StatefulSet就是使用Headless Service为客户端返回多个服务地址的。
    对于“去中心化”类的应用集群,Headless Service非常适合。
    3.2        Nginx场景实验
    通过对Headless Service搭建Nginx集群,从而自动实现应用集群的创建。
    [root@k8smaster01 study]# vi nginx-service.yaml        #创建Service


    [HTML] 纯文本查看 复制代码
    apiVersion: v1
    kind: Service
    metadata:
      labels:
        name: nginx-svc
      name: nginx-svc
    spec:
      ports:
      - protocol: TCP
        port: 80
        targetPort: 80
      selector:
        name: nginx-demo			#定义selector
      clusterIP: None

    [root@k8smaster01 study]# kubectl create -f nginx-service.yaml
    [root@k8smaster01 study]# vi nginx-deployment.yaml

    [HTML] 纯文本查看 复制代码
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        name: nginx-demo
      name: nginx-demo
    spec:
      replicas: 2
      selector:
        matchLabels:
          name: nginx-demo
      template:
        metadata:
          labels:
            name: nginx-demo
        spec:
          containers:
          - name: nginx
            image: nginx:1.7.9
            ports:
            - containerPort: 80
              name: web


    [root@k8smaster01 study]# kubectl create -f nginx-deployment.yaml
    [root@k8smaster01 study]# kubectl create -f nginx-service.yaml
    [root@k8smaster01 study]# kubectl get svc -o wide
    [root@k8smaster01 study]# kubectl get pods -o wide   
    [root@k8smaster01 study]# nslookup nginx-svc.default.svc.cluster.local 10.10.190.170



    提示:由上可知,通过解析SVC的地址,直接解析出来的为Pod的IP。






    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|Archiver|小黑屋|本站代理|dmz社区

    GMT+8, 2024-4-26 06:55 , Processed in 0.198401 second(s), 33 queries .

    Powered by Discuz! X3.4 Licensed

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表