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的目标端口

3、为外部服务创建别名
            除了收到配置服务的endpoint来代替公开的外部服务方法,另一种方法就是十一FQDN访问外部服务
            (1)创建ExternalName类型的服务
                 创建别名外部服务的服务时要将创建资源的一个type字段设置为ExternalName. 例如:api.xxx.com
                 示例:
                 apiVersion: v1
                 kind: Service
                 metadata:
                   name: external-service
                 spec:
                   type: ExternalName  #代码的type被设置成ExternalName
                   externalname: api.xxx.com  #实际服务的完全限定域名
                   ports:
                   - port: 80
            服务创建完成后pod可以通过external-service.default.svc.cluster.local域名(external-service)链接到外部服务,而不是使用服务的实际FQDN。ExternaName服务仅在DNS级别实施,为服务创建简单的CNAME dns记录。因此链接服务的客户端将直接链到外部服务,完全绕过代理服务,这些类型的服务不会获得集群的IP
            CNAME记录指向完全限定域名而不是数字IP地址。
 

Logo

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

更多推荐