본문 바로가기

kubernetes

도대체 service라는 녀석은 뭘까?

0단계 - 왜 하는겨?

  • 도대체 쿠버네티스트에서 서비스란 녀석...참 신기한것 같다.
  • 서비스란 녀석을 통해 파드(콘테이너)안으로 들어간다. 
    • 정확한 표현은 아니다..암튼..
  • 서비스란 녀석은 그렇다고 파드처럼 콘테이너도 아닌다...
  • 그러다면 서비스란 녀석의 실체(?)는 뭘까?

도대체 서비스는 뭘까???

 

1단계 - 그냥 디버깅 해버리겠어~

  • 그냥 직접  k3s를 디버깅해버리겠습니다 .
  • 서비스가 만들어진 시점에 브레이크를 걸어보면 되는것 아니겠습니까!!!!!!!

1.1 단계 - 서비스를 만들어야지~~

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app.kubernetes.io/name: MyApp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376
  • MyApp이라는 파드가 없어도 서비는 잘 만들어지는 군요..
test@test:~/k3s_test/svc$ kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
my-service   ClusterIP   10.43.156.169   <none>        80/TCP    84s
  • 자..그러면 이제 브레이크를 걸어봅시다요!!!!아자 아자 아자!!!
$ kubectl create service clusterip testsvc --tcp=123
service/testsvc created
  • 명령으로도 만들 수 있다!!!

그런데 어떻게 걸수 있을까???

 

[root@k3sdbg bin]# ./kubectl api-resources
NAME                              SHORTNAMES   APIVERSION                             NAMESPACED   KIND
services                          svc          v1                                     true         Service
 

Introduction to Kubernetes API - the way to understand the concept of Kubernetes Operators.

To understand the concept of Kubernetes Operators you have to better understand the Kubernetes API itself. I want to show you where you…

michalswi.medium.com

 

드디어 걸렸습니다. 

#go/pkg/mod/github.com/k3s-io/kubernetes@v1.25.1-k3s1/pkg/proxy/config/config.go
func (c *ServiceConfig) handleAddService(obj interface{}) {
	service, ok := obj.(*v1.Service)
	if !ok {
		utilruntime.HandleError(fmt.Errorf("unexpected object type: %v", obj))
		return
	}
	for i := range c.eventHandlers {
		klog.V(4).InfoS("Calling handler.OnServiceAdd")
		c.eventHandlers[i].OnServiceAdd(service)
	}
}
// OnServiceAdd is called whenever creation of new service object is observed.
func (proxier *metaProxier) OnServiceAdd(service *v1.Service) {
	proxier.ipv4Proxier.OnServiceAdd(service)
	proxier.ipv6Proxier.OnServiceAdd(service)
}
// OnServiceAdd is called whenever creation of new service object
// is observed.
func (proxier *Proxier) OnServiceAdd(service *v1.Service) {
	proxier.OnServiceUpdate(nil, service)
}
// OnServiceUpdate is called whenever modification of an existing
// service object is observed.
func (proxier *Proxier) OnServiceUpdate(oldService, service *v1.Service) {
	if proxier.serviceChanges.Update(oldService, service) && proxier.isInitialized() {
		proxier.Sync()
	}
}
// Update updates given service's change map based on the <previous, current> service pair.  It returns true if items changed,
// otherwise return false.  Update can be used to add/update/delete items of ServiceChangeMap.  For example,
// Add item
//   - pass <nil, service> as the <previous, current> pair.
//
// Update item
//   - pass <oldService, service> as the <previous, current> pair.
//
// Delete item
//   - pass <service, nil> as the <previous, current> pair.
func (sct *ServiceChangeTracker) Update(previous, current *v1.Service) bool {
	svc := current
	if svc == nil {
		svc = previous
	}
	// previous == nil && current == nil is unexpected, we should return false directly.
	if svc == nil {
		return false
	}
	metrics.ServiceChangesTotal.Inc()
	namespacedName := types.NamespacedName{Namespace: svc.Namespace, Name: svc.Name}

	sct.lock.Lock()
	defer sct.lock.Unlock()

	change, exists := sct.items[namespacedName]
	if !exists {
		change = &serviceChange{}
		change.previous = sct.serviceToServiceMap(previous)
		sct.items[namespacedName] = change
	}
	change.current = sct.serviceToServiceMap(current)
	// if change.previous equal to change.current, it means no change
	if reflect.DeepEqual(change.previous, change.current) {
		delete(sct.items, namespacedName)
	} else {
		klog.V(2).InfoS("Service updated ports", "service", klog.KObj(svc), "portCount", len(change.current))
	}
	metrics.ServiceChangesPending.Set(float64(len(sct.items)))
	return len(sct.items) > 0
}
// serviceToServiceMap translates a single Service object to a ServiceMap.
//
// NOTE: service object should NOT be modified.
func (sct *ServiceChangeTracker) serviceToServiceMap(service *v1.Service) ServiceMap {
	if service == nil {
		return nil
	}

	if utilproxy.ShouldSkipService(service) {
		return nil
	}

	clusterIP := utilproxy.GetClusterIPByFamily(sct.ipFamily, service)
	if clusterIP == "" {
		return nil
	}

	serviceMap := make(ServiceMap)
	svcName := types.NamespacedName{Namespace: service.Namespace, Name: service.Name}
	for i := range service.Spec.Ports {
		servicePort := &service.Spec.Ports[i]
		svcPortName := ServicePortName{NamespacedName: svcName, Port: servicePort.Name, Protocol: servicePort.Protocol}
		baseSvcInfo := sct.newBaseServiceInfo(servicePort, service)
		if sct.makeServiceInfo != nil {
			serviceMap[svcPortName] = sct.makeServiceInfo(servicePort, service, baseSvcInfo)
		} else {
			serviceMap[svcPortName] = baseSvcInfo
		}
	}
	return serviceMap
}

  • 프락시에서 서비스를 생성하는 거였나???

https://blog.csdn.net/liu_weiliang10405/article/details/123855762
https://blog.csdn.net/liu_weiliang10405/article/details/123855762
https://github.com/DavadDi/go_study/blob/master/kube-proxy.md
https://zhuanlan.zhihu.com/p/342111922
https://zhuanlan.zhihu.com/p/342111922
https://zhuanlan.zhihu.com/p/342111922
https://developer.aliyun.com/article/745431

https://rootdeep.github.io/posts/kube-proxy-code-analysis/

 

kube-proxy 源码分析

功能概述 kube-proxy是管理service的访问入口,包括集群内Pod到Service的访问和集群外访问service。当用户创建 service 的

rootdeep.github.io

 

'kubernetes' 카테고리의 다른 글

allow-privileged=true  (0) 2022.11.15
pod packet capture  (0) 2022.09.26
nginx service LB로 올리기  (0) 2022.09.21
Ubuntu 22.04에 k3s설치하기  (0) 2022.09.08
왜? pod에 한개의 VSCode만 attach되는 거여?  (0) 2022.07.20