kubectl get pod信息/格式从何而来

2025-02-19  本文已影响0人  wwq2020

简单总结

kubectl侧根据开启了server print则添加table header信息
apiserver侧如果存在as table header则转换resp为table(以pod为例,格式和信息由printPod构建)

kubectl侧

如果开启了server print则添加table header信息

func NewCmdGet(parent string, f cmdutil.Factory, streams genericiooptions.IOStreams) *cobra.Command {
    ...
    构建命令
    cmd := &cobra.Command{
        ...
        Run: func(cmd *cobra.Command, args []string) {
            ...
            运行
            cmdutil.CheckErr(o.Run(f, args))
        },
        ...
    }
    ...
    添加server print column flag
    addServerPrintColumnFlags(cmd, o)
    ...
}

添加server print column flag
func addServerPrintColumnFlags(cmd *cobra.Command, opt *GetOptions) {
    cmd.Flags().BoolVar(&opt.ServerPrint, useServerPrintColumns, opt.ServerPrint, "If true, have the server return the appropriate table output. Supports extension APIs and CRDs.")
}



const (
    useServerPrintColumns = "server-print"
)

获取get options
func NewGetOptions(parent string, streams genericiooptions.IOStreams) *GetOptions {
    return &GetOptions{
        ...
        ServerPrint: true,
    }
}



func (o *GetOptions) Run(f cmdutil.Factory, args []string) error {
    ...
    r := f.NewBuilder().
        ...
        TransformRequests(o.transformRequests).
        Do()
    ...
}

转换http request
func (o *GetOptions) transformRequests(req *rest.Request) {
    if !o.ServerPrint || !o.IsHumanReadablePrinter {
        return
    }
    如果开启了server print则添加table header信息
    req.SetHeader("Accept", strings.Join([]string{
        fmt.Sprintf("application/json;as=Table;v=%s;g=%s", metav1.SchemeGroupVersion.Version, metav1.GroupName),
        fmt.Sprintf("application/json;as=Table;v=%s;g=%s", metav1beta1.SchemeGroupVersion.Version, metav1beta1.GroupName),
        "application/json",
    }, ","))

    // if sorting, ensure we receive the full object in order to introspect its fields via jsonpath
    if len(o.SortBy) > 0 {
        req.Param("includeObject", "Object")
    }
}

apiserver 侧

如果存在as table header则转换resp为table
staging/src/k8s.io/apiserver/pkg/endpoints/installer.go中

注册resource handler
func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storage, ws *restful.WebService) (*metav1.APIResource, *storageversion.ResourceInfo, error) {
    ...
    注册get handler
        switch action.Verb {
        case "GET": // Get a resource.
            var handler restful.RouteFunction
            if isGetterWithOptions {
                handler = restfulGetResourceWithOptions(getterWithOptions, reqScope, isSubresource)
            } else {
                handler = restfulGetResource(getter, reqScope)
            }
    ...
}

rest get resource handler
func restfulGetResource(r rest.Getter, scope handlers.RequestScope) restful.RouteFunction {
    return func(req *restful.Request, res *restful.Response) {
        handlers.GetResource(r, &scope)(res.ResponseWriter, req.Request)
    }
}

staging/src/k8s.io/apiserver/pkg/endpoints/handlers/get.go中

对外提供 get resource handler
func GetResource(r rest.Getter, scope *RequestScope) http.HandlerFunc {
    return getResourceHandler(scope,
        func(ctx context.Context, name string, req *http.Request) (runtime.Object, error) {
            ...
            get resource
            return r.Get(ctx, name, opts)
        })
}

get resource handler
func getResourceHandler(scope *RequestScope, getter getterFunc) http.HandlerFunc {
    ...
    转换resp object为各种格式
    transformResponseObject(ctx, scope, req, w, http.StatusOK, outputMediaType, result)
    ...
}
转换resp object为各种格式
func transformResponseObject(ctx context.Context, scope *RequestScope, req *http.Request, w http.ResponseWriter, statusCode int, mediaType negotiation.MediaTypeOptions, result runtime.Object) {
    do := func() {
        obj, err = doTransformObject(ctx, result, options, mediaType.Convert, scope)
    }
    endpointsrequest.TrackTransformResponseObjectLatency(ctx, do)

}

转换resp object为各种格式
func doTransformObject(ctx context.Context, obj runtime.Object, opts interface{}, target *schema.GroupVersionKind, scope *RequestScope) (runtime.Object, error) {
    ...
    case target.Kind == "Table":
        ...
        return asTable(ctx, obj, options, scope, target.GroupVersion())
    ...
}

转换为table
func asTable(ctx context.Context, result runtime.Object, opts *metav1.TableOptions, scope *RequestScope, groupVersion schema.GroupVersion) (runtime.Object, error) {
    ...
    obj, err := scope.TableConvertor.ConvertToTable(ctx, result, opts)
    ...
    table := (*metav1.Table)(obj)

}

pkg/registry/core/rest/storage_core.go中

构建rest storage
func (p *legacyProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, error) {
    ...
    构建pod rest storage
    podStorage, err := podstore.NewStorage(
        restOptionsGetter,
        nodeStorage.KubeletConnectionInfo,
        p.Proxy.Transport,
        podDisruptionClient,
    )
    ...
    添加rest storage
    if resource := "pods"; apiResourceConfigSource.ResourceEnabled(corev1.SchemeGroupVersion.WithResource(resource)) {
        添加pod rest storage
        storage[resource] = podStorage.Pod
        ...
    }
    ...
}
构建pod rest storage
func NewStorage(optsGetter generic.RESTOptionsGetter, k client.ConnectionInfoGetter, proxyTransport http.RoundTripper, podDisruptionBudgetClient policyclient.PodDisruptionBudgetsGetter) (PodStorage, error) {
    ...
    构建rest storage
    store := &genericregistry.Store{
        ...
        TableConvertor: printerstorage.TableConvertor{TableGenerator: printers.NewTableGenerator().With(printersinternal.AddHandlers)},
    }
    ...
    构建pod rest storage
    return PodStorage{
        Pod:                 &REST{store, proxyTransport},
        ...
    }, nil
}

pkg/printers/internalversion/printers.go

printer 处理方法
func AddHandlers(h printers.PrintHandler) {
    ...
    h.TableHandler(podColumnDefinitions, printPod)
    ...
}

pod printer
func printPod(pod *api.Pod, options printers.GenerateOptions) ([]metav1.TableRow, error) {
    ...
    return []metav1.TableRow{row}, nil
}
上一篇 下一篇

猜你喜欢

热点阅读