美文网首页K8S容器编排最佳实践
K8S容器编排之Headless浅谈

K8S容器编排之Headless浅谈

作者: 云爬虫技术研究笔记 | 来源:发表于2018-12-26 23:02 被阅读16274次

      前言: 最近在基于K8S开发平台的过程中遇到了有个问题没有弄懂,就是CoreDNS的作用,就好像在Docker Swarm里面,我们可以通过Service name来访问一组容器,在K8S里,我们想要通过name来访问服务的方式就是在Deployment上面添加一层Service,这样我们就可以通过Service name来访问服务了,那其中的原理就是和CoreDNS有关,它将Service name解析成Cluster IP,这样我们访问Cluster IP的时候就通过Cluster IP作负载均衡,把流量分布到各个POD上面。我想的问题是CoreDNS是否会直接解析PODname,在Service的服务里,是不可以的,因为ServiceCluster IP,直接被CoreDNS解析了,那怎么才能让它解析POD呢,有大牛提出了可以使用Headless Service,所以我们就来探究一下什么是Headless Service

      Headless Service也是一种Service,但不同的是会定义spec:clusterIP: None,也就是不需要Cluster IPService
      我们首先想想ServiceCluster IP的工作原理:一个Service可能对应多个EndPoint(Pod)client访问的是Cluster IP,通过iptables规则转到Real Server,从而达到负载均衡的效果。具体操作如下所示:

    kubectl get svc
    NAME                      CLUSTER-IP       EXTERNAL-IP       PORT(S)           AGE
    nginx-service             10.107.124.218   192.168.128.158   80/TCP,443/TCP    1d
    kubectl describe  svc nginx-service    
    Name:                   nginx-service
    Namespace:              default
    Labels:                 
    Selector:               component=nginx
    Type:                   ClusterIP
    IP:                     10.107.124.218
    External IPs:           192.168.128.158
    Port:                   nginx-http      80/TCP
    Endpoints:              10.244.2.9:80
    Port:                   nginx-https     443/TCP
    Endpoints:              10.244.2.9:443
    Session Affinity:       None
    No events.
    nslookup nginx-service.default.svc.cluster.local  10.96.0.10
    Server:         10.96.0.10
    Address:        10.96.0.10#53
    
    Name:   nginx-service.default.svc.cluster.local
    Address: 10.107.124.218
    

      从上面的结果中我们可以看到虽然Service有2个endpoint,但是dns查询时只会返回Service的地址。具体client访问的是哪个Real Server,是由iptables来决定的。
      那么我们再来看看Headless Service的效果呢?

    kubectl get service
    NAME                      CLUSTER-IP       EXTERNAL-IP       PORT(S)    AGE
    nginx                     None                         80/TCP     1h
    kubectl describe  service nginx
    Name:                   nginx
    Namespace:              default
    Labels:                 app=nginx
    Selector:               app=nginx
    Type:                   ClusterIP
    IP:                     None
    Port:                   web     80/TCP
    Endpoints:              10.244.2.17:80,10.244.2.18:80
    Session Affinity:       None
    No events.
    nslookup nginx.default.svc.cluster.local 10.96.0.10
    Server:         10.96.0.10
    Address:        10.96.0.10#53
    
    Name:   nginx.default.svc.cluster.local
    Address: 10.244.2.17
    Name:   nginx.default.svc.cluster.local
    Address: 10.244.2.18
    

      根据结果得知dns查询会如实的返回2个真实的endpoint

      所以,顾名思义,Headless Service就是没头的Service。有什么使用场景呢?

    • 第一种:自主选择权,有时候client想自己来决定使用哪个Real Server,可以通过查询DNS来获取Real Server的信息。

    • 第二种:Headless Services还有一个用处(PS:也就是我们需要的那个特性)。Headless Service的对应的每一个Endpoints,即每一个Pod,都会有对应的DNS域名;这样Pod之间就可以互相访问。我们还是看上面的这个例子。

    kubectl get statefulsets web
    NAME      DESIRED   CURRENT   AGE
    web       2         2         1h
    kubectl get pods
    web-0                       1/1       Running   0          1h
    web-1                       1/1       Running   0          1h
    nslookup nginx.default.svc.cluster.local 10.96.0.10
    Server:         10.96.0.10
    Address:        10.96.0.10#53
    
    Name:   nginx.default.svc.cluster.local
    Address: 10.244.2.17
    Name:   nginx.default.svc.cluster.local
    Address: 10.244.2.18
    
    nslookup web-1.nginx.default.svc.cluster.local 10.96.0.10
    Server:         10.96.0.10
    Address:        10.96.0.10#53
    
    Name:   web-1.nginx.default.svc.cluster.local
    Address: 10.244.2.18
    
    nslookup web-0.nginx.default.svc.cluster.local 10.96.0.10
    Server:         10.96.0.10
    Address:        10.96.0.10#53
    
    Name:   web-0.nginx.default.svc.cluster.local
    Address: 10.244.2.17
    

      如上,web为我们创建的StatefulSets,对应的pod的域名为web-0web-1,他们之间可以互相访问,这样对于一些集群类型的应用就可以解决互相之间身份识别的问题了。

      完整示例:

    apiVersion: v1
    kind: Service
    metadata:
      name: nginx
      labels:
        app: nginx
    spec:
      ports:
      - port: 80
        name: web
      clusterIP: None
      selector:
        app: nginx
    ---
    apiVersion: apps/v1beta1
    kind: StatefulSet
    metadata:
      name: web
    spec:
      serviceName: "nginx"
      replicas: 1
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx:1.11
            ports:
            - containerPort: 80
              name: web
            volumeMounts:
            - name: www
              mountPath: /usr/share/nginx/html
          nodeSelector:
            node: kube-node3
          volumes:
            - name: www
              hostPath:
                path: /mydir
    

    相关文章

      网友评论

        本文标题:K8S容器编排之Headless浅谈

        本文链接:https://www.haomeiwen.com/subject/cmfllqtx.html