K8s/kubectl resource object

4/6/2019

My interest is in exploring how K8s resource objects are created from specs submitted by client-API; and how they are communicated across kube master services and pods.

I have started exploring the K8s source code and reached certain depth. For this exploration I am using kubectl create -f <path to yaml> and tracking how this command is handled in source code. here is brief summary

  1. https://github.com/kubernetes/kubernetes/blob/v1.14.0/pkg/kubectl/cmd/create/create.go#L96 I started with this function and followed on function trail (thanks to this blog); and gradually reached to
  2. https://github.com/kubernetes/kubernetes/blob/v1.14.0/staging/src/k8s.io/client-go/rest/request.go#L708 - http request is formed here
  3. https://github.com/kubernetes/kubernetes/blob/v1.14.0/staging/src/k8s.io/client-go/rest/request.go#L395 - the body of the request is formed here.
  4. https://github.com/kubernetes/kubernetes/blob/v1.14.0/staging/src/k8s.io/client-go/rest/request.go#L732 - this functions send http request and gets response back for processing, here I have addedklog.Infof("custom log sizeofdata:%T$$,%d$$,%s$$,%#v",*req,unsafe.Sizeof(*req),*req,*req) to find size of the request being sent.

My hypothesis is; this request size in bytes should change as the change in specs submitted by the user (yaml file passed with kubectl create -f)

Now I tried to feed two different resource spec(with kubectl create -f ) and see how the HTTP request and request body changes (its size).

Yaml 1 - nginx sample https://raw.githubusercontent.com/kubernetes/website/master/content/en/examples/application/deployment.yaml

Yaml 2 - centos sample

apiVersion: v1
kind: Pod
metadata:
  name: cent-os-test
spec:
  containers:
  - name: centos-test-container
    image: centos
    command: ["sleep"]
    args: ["100"]
  restartPolicy: Never

Surprisingly both times output of the logging line above was same Byte size (248 Bytes)

for log requested by klog.Infof("custom log sizeofdata:%T$$,%d$$,%s$$,%#v",*req,unsafe.Sizeof(*req),*req,*req)

I have used $$ as field separator while printing.

Following are log entries in case of both of yamls

for Yaml 2 centos ---

I0405 22:22:37.285666  360723 request.go:745] custom_log size of data : http.Request $$, 248 $$, {POST https://10.xxx.xxx.xxx:6443/api/v1/namespaces/default/pods HTTP/1.1 %!s(int=1) %!s(int=1) map[Accept:[application/json] Content-Type:[application/json]] {%!s(*bytes.Reader=&{[123 34 97 112 105 86 101 114 115 105 111 110 34 58 34 118 49 34 44 34 107 105 110 100 34 58 34 80 111 100 34 44 34 109 101 116 97 100 97 116 97 34 58 123 34 110 97 109 101 34 58 34 99 101 110 116 45 111 115 45 116 101 115 116 34 44 34 110 97 109 101 115 112 97 99 101 34 58 34 100 101 102 97 117 108 116 34 125 44 34 115 112 101 99 34 58 123 34 99 111 110 116 97 105 110 101 114 115 34 58 91 123 34 97 114 103 115 34 58 91 34 49 48 48 34 93 44 34 99 111 109 109 97 110 100 34 58 91 34 115 108 101 101 112 34 93 44 34 105 109 97 103 101 34 58 34 99 101 110 116 111 115 34 44 34 110 97 109 101 34 58 34 99 101 110 116 111 115 45 116 101 115 116 45 99 111 110 116 97 105 110 101 114 34 125 93 44 34 114 101 115 116 97 114 116 80 111 108 105 99 121 34 58 34 78 101 118 101 114 34 125 125 10] 0 -1})} %!s(func() (io.ReadCloser, error)=0x8087b0) %!s(int64=223) [] %!s(bool=false) 10.xxx.xxx.xxx:6443 map[] map[] %!s(*multipart.Form=<nil>) map[]   %!s(*tls.ConnectionState=<nil>) %!s(<-chan struct {}=<nil>) %!s(*http.Response=<nil>) <nil>} $$, http.Request{Method:"POST", URL:(*url.URL)(0xc001dc6880), Proto:"HTTP/1.1", ProtoMajor:1, ProtoMinor:1, Header:http.Header{"Accept":[]string{"application/json"}, "Content-Type":[]string{"application/json"}}, Body:ioutil.nopCloser{Reader:(*bytes.Reader)(0xc000886f60)}, GetBody:(func() (io.ReadCloser, error))(0x8087b0), ContentLength:223, TransferEncoding:[]string(nil), Close:false, Host:"10.xxx.xxx.xxx:6443", Form:url.Values(nil), PostForm:url.Values(nil), MultipartForm:(*multipart.Form)(nil), Trailer:http.Header(nil), RemoteAddr:"", RequestURI:"", TLS:(*tls.ConnectionState)(nil), Cancel:(<-chan struct {})(nil), Response:(*http.Response)(nil), ctx:context.Context(nil)} 

for Yaml 1 nginx ---

I0406 00:07:19.873854  410863 request.go:745] custom_log size of data : http.Request $$, 248 $$, {POST https://10.xxx.xxx.xxx:6443/apis/apps/v1/namespaces/default/deployments HTTP/1.1 %!s(int=1) %!s(int=1) map[Accept:[application/json] Content-Type:[application/json]] {%!s(*bytes.Reader=&{[123 34 97 112 105 86 101 114 115 105 111 110 34 58 34 97 112 112 115 47 118 49 34 44 34 107 105 110 100 34 58 34 68 101 112 108 111 121 109 101 110 116 34 44 34 109 101 116 97 100 97 116 97 34 58 123 34 110 97 109 101 34 58 34 110 103 105 110 120 45 100 101 112 108 111 121 109 101 110 116 34 44 34 110 97 109 101 115 112 97 99 101 34 58 34 100 101 102 97 117 108 116 34 125 44 34 115 112 101 99 34 58 123 34 114 101 112 108 105 99 97 115 34 58 50 44 34 115 101 108 101 99 116 111 114 34 58 123 34 109 97 116 99 104 76 97 98 101 108 115 34 58 123 34 97 112 112 34 58 34 110 103 105 110 120 34 125 125 44 34 116 101 109 112 108 97 116 101 34 58 123 34 109 101 116 97 100 97 116 97 34 58 123 34 108 97 98 101 108 115 34 58 123 34 97 112 112 34 58 34 110 103 105 110 120 34 125 125 44 34 115 112 101 99 34 58 123 34 99 111 110 116 97 105 110 101 114 115 34 58 91 123 34 105 109 97 103 101 34 58 34 110 103 105 110 120 58 49 46 55 46 57 34 44 34 110 97 109 101 34 58 34 110 103 105 110 120 34 44 34 112 111 114 116 115 34 58 91 123 34 99 111 110 116 97 105 110 101 114 80 111 114 116 34 58 56 48 125 93 125 93 125 125 125 125 10] 0 -1})} %!s(func() (io.ReadCloser, error)=0x8087b0) %!s(int64=316) [] %!s(bool=false) 10.xxx.xxx.xxx:6443 map[] map[] %!s(*multipart.Form=<nil>) map[]   %!s(*tls.ConnectionState=<nil>) %!s(<-chan struct {}=<nil>) %!s(*http.Response=<nil>) <nil>} $$, http.Request{Method:"POST", URL:(*url.URL)(0xc000a96380), Proto:"HTTP/1.1", ProtoMajor:1, ProtoMinor:1, Header:http.Header{"Accept":[]string{"application/json"}, "Content-Type":[]string{"application/json"}}, Body:ioutil.nopCloser{Reader:(*bytes.Reader)(0xc0008abb90)}, GetBody:(func() (io.ReadCloser, error))(0x8087b0), ContentLength:316, TransferEncoding:[]string(nil), Close:false, Host:"10.xxx.xxx.xxx:6443", Form:url.Values(nil), PostForm:url.Values(nil), MultipartForm:(*multipart.Form)(nil), Trailer:http.Header(nil), RemoteAddr:"", RequestURI:"", TLS:(*tls.ConnectionState)(nil), Cancel:(<-chan struct {})(nil), Response:(*http.Response)(nil), ctx:context.Context(nil)}

Why both of times the HTTP request size is 248 bytes? Shouldn’t it increase in case of the nginx yaml since it passes more lines of spec information?

-- ankit patel
kubectl
kubernetes

1 Answer

4/11/2019

Would you refer to the length of the *req variable rather then it's size

klog.Infof("custom log sizeofdata:%T$$$$,%d$$$$,%s$$$$,%#v",*req,len(*req),*req,*req)

Similar to the below snippet illustrating that size of a variable of type string is always 8 but the length of a string that a variable references can vary:

package main

import "fmt"
import "unsafe"

func main() {
    s1 := "foo"
    s2 := "foobar"

    fmt.Printf("s1 size: %T, %d\n", s1, unsafe.Sizeof(s1))
    fmt.Printf("s2 size: %T, %d\n", s2, unsafe.Sizeof(s2))
    fmt.Printf("s1 len: %T, %d\n", s1, len(s1))
    fmt.Printf("s2 len: %T, %d\n", s2, len(s2))
}

Result:

s1 size: string, 8
s2 size: string, 8
s1 len: string, 3
s2 len: string, 6
-- A_Suh
Source: StackOverflow