Think Deep,Work Lean

k8s之几个特殊的service

Posted on By zack

前言

在写这篇blog之前先回想一下对service的了解:

  1. NodePort ClusterIP LoadBalance
  2. headless service 与 statefulSet结合使用,sts的pod名字后面数字依次递增,启动顺序跟这个一致
  3. headless的 service 的clusterIP为none
  4. service yaml中的 matchLable 和 selector
  5. ipvsadm -Sn grep clusterIP
  6. kubelet service/etcd service 与 kube-scheduler-svc / kube-apiservice/ kube-controller-manager-service
  7. service与endpoint如何关联?如果headless service中没有slector这个headlessService是否有意义,如果该headless service 没有selector如何让其拥有endpoints?如果该service既没有selector也没有endpoint,那么这个headless service有什么意义?

本案例全部基于ks-installer的环境讲解。

环境

root@ks-allinone:/root # kubectl -n kube-system get svc
NAME                          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                        AGE
coredns                       ClusterIP   10.233.0.3      <none>        53/UDP,53/TCP,9153/TCP         8h
etcd                          ClusterIP   None            <none>        2379/TCP                       3h27m
kube-controller-manager-svc   ClusterIP   None            <none>        10252/TCP                      7h43m
kube-scheduler-svc            ClusterIP   None            <none>        10251/TCP                      7h43m
kubelet                       ClusterIP   None            <none>        10250/TCP,10255/TCP,4194/TCP   7h41m
metrics-server                ClusterIP   10.233.23.232   <none>        443/TCP                        3h32m

kubelet service

首先要明白,在k8s中分两种角色,workermaster。对于用systemd安装的服务有:

master:  kubelet  docker etcd
worker: kubelet docker 

如果系统有问题,首先想到的粗暴方法是把这几个服务强行重启。(当然前提是先检查服务,查看日志,对症下药) 对于systemctl 看日志的方法: journectl -xe -u <serviceName> 如果是想看某段时间的日志,可以使用如下格式

journalctl -u kubelet.service --since="2020-07-08 17:20" --until="2020-07-08 17:30"

kubelet服务:

root@ks-allinone:/root # kubectl -n kube-system get svc kubelet -o yaml
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: "2020-07-31T02:41:57Z"
  labels:
    k8s-app: kubelet
  name: kubelet
  namespace: kube-system
  resourceVersion: "12343"
  selfLink: /api/v1/namespaces/kube-system/services/kubelet
  uid: 385745e7-42b0-4841-b032-b15316598b43
spec:
  clusterIP: None
  ports:
  - name: https-metrics
    port: 10250
    protocol: TCP
    targetPort: 10250
  - name: http-metrics
    port: 10255
    protocol: TCP
    targetPort: 10255
  - name: cadvisor
    port: 4194
    protocol: TCP
    targetPort: 4194
  sessionAffinity: None
  type: ClusterIP
status:
  loadBalancer: {}

刚看到这个服务的时候,发现这个服务有点奇怪,没有selector、ClusterIP也是None,说明该服务是Headless Service

describe svc看下这个服务是否有endpoints:

root@ks-allinone:/root # kubectl -n kube-system describe svc kubelet
Name:              kubelet
Namespace:         kube-system
Labels:            k8s-app=kubelet
Annotations:       <none>
Selector:          <none>
Type:              ClusterIP
IP:                None
Port:              https-metrics  10250/TCP
TargetPort:        10250/TCP
Endpoints:         10.160.15.40:10250
Port:              http-metrics  10255/TCP
TargetPort:        10255/TCP
Endpoints:         10.160.15.40:10255
Port:              cadvisor  4194/TCP
TargetPort:        4194/TCP
Endpoints:         10.160.15.40:4194
Session Affinity:  None
Events:            <none>

发现这个服务是有endpoints的,而且还有不少的endpoints

单从service的yaml文件来看其实看不出所以然。

那么问题来了: 什么时候会在没有后端pod(无selector)的情况下给service加上endpoints的呢?

此时可以手动添加endpointsservice关联。 现在看下kubelet的endpoints

Name:         kubelet
Namespace:    kube-system
Labels:       k8s-app=kubelet
Annotations:  <none>
Subsets:
  Addresses:          192.168.11.10,192.168.11.100,192.168.11.101,192.168.11.102,192.168.11.103,192.168.11.104,192.168.11.105,192.168.11.106,192.168.11.107,192.168.11.108,192.168.11.109,192.168.11.11,192.168.11.110,192.168.11.111,192.168.11.112,192.168.11.113,192.168.11.114,192.168.11.115,192.168.11.116,192.168.11.117,192.168.11.118,192.168.11.119,192.168.11.12,192.168.11.120,192.168.11.121,192.168.11.122,192.168.11.123,192.168.11.124,192.168.11.125,192.168.11.126,192.168.11.127,192.168.11.128,192.168.11.129,192.168.11.13,192.168.11.130,192.168.11.131,192.168.11.132,192.168.11.133,192.1...
    1.93,192.168.11.94,192.168.11.95,192.168.11.96,192.168.11.97,192.168.11.98,192.168.11.99
    NotReadyAddresses:  <none>
    Ports:
        Name           Port   Protocol
        ----           ----   --------
        http-metrics   10255  TCP
        cadvisor       4194   TCP
        https-metrics  10250  TCP

    Events:  <none>

因为我的环境是个大集群,因此会显示出很多IP来,这个subnet就是将servcie与endpoint关联。address就是对应endpoints的地址。 其中还有三个端口,分别提供metrics的http(s)访问端口。另外还看到有个cadvisor的容器端口,那么这里扩展下cadvisor是什么用的呢?其实是google提供的一款可示化监控工具,作用跟prometheus类似。

至此我们明白了。。。。

<待补充>