欢迎关注我的公众号:

 目前刚开始写一个月,一共写了18篇原创文章,文章目录如下:

istio多集群探秘,部署了50次多集群后我得出的结论

istio多集群链路追踪,附实操视频

istio防故障利器,你知道几个,istio新手不要读,太难!

istio业务权限控制,原来可以这么玩

istio实现非侵入压缩,微服务之间如何实现压缩

不懂envoyfilter也敢说精通istio系列-http-rbac-不要只会用AuthorizationPolicy配置权限

不懂envoyfilter也敢说精通istio系列-02-http-corsFilter-不要只会vs

不懂envoyfilter也敢说精通istio系列-03-http-csrf filter-再也不用再代码里写csrf逻辑了

不懂envoyfilter也敢说精通istio系列http-jwt_authn-不要只会RequestAuthorization

不懂envoyfilter也敢说精通istio系列-05-fault-filter-故障注入不止是vs

不懂envoyfilter也敢说精通istio系列-06-http-match-配置路由不只是vs

不懂envoyfilter也敢说精通istio系列-07-负载均衡配置不止是dr

不懂envoyfilter也敢说精通istio系列-08-连接池和断路器

不懂envoyfilter也敢说精通istio系列-09-http-route filter

不懂envoyfilter也敢说精通istio系列-network filter-redis proxy

不懂envoyfilter也敢说精通istio系列-network filter-HttpConnectionManager

不懂envoyfilter也敢说精通istio系列-ratelimit-istio ratelimit完全手册

 

————————————————

type ConvertOptions struct {//convert结构体
	PrintFlags *genericclioptions.PrintFlags
	Printer    printers.ResourcePrinter

	OutputVersion string
	Namespace     string

	builder   func() *resource.Builder
	local     bool
	validator func() (validation.Schema, error)

	resource.FilenameOptions
	genericclioptions.IOStreams
}
func NewConvertOptions(ioStreams genericclioptions.IOStreams) *ConvertOptions {
	return &ConvertOptions{//初始化convert结构体
		PrintFlags: genericclioptions.NewPrintFlags("converted").WithTypeSetter(scheme.Scheme).WithDefaultOutput("yaml"),
		local:      true,
		IOStreams:  ioStreams,
	}
}
//创建convert命令
func NewCmdConvert(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
	o := NewConvertOptions(ioStreams)//初始化结构体

	cmd := &cobra.Command{//创建cobra命令
		Use:                   "convert -f FILENAME",
		DisableFlagsInUseLine: true,
		Short:                 i18n.T("Convert config files between different API versions"),
		Long:                  convertLong,
		Example:               convertExample,
		Run: func(cmd *cobra.Command, args []string) {
			cmdutil.CheckErr(o.Complete(f, cmd))//准备
			cmdutil.CheckErr(o.RunConvert())//运行
		},
	}

	cmd.Flags().BoolVar(&o.local, "local", o.local, "If true, convert will NOT try to contact api-server but run locally.")//local选项
	cmd.Flags().StringVar(&o.OutputVersion, "output-version", o.OutputVersion, i18n.T("Output the formatted object with the given group version (for ex: 'extensions/v1beta1')."))//output-version选项
	o.PrintFlags.AddFlags(cmd)//打印选项

	cmdutil.AddValidateFlags(cmd)//校验选项
	cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, "to need to get converted.")//文件选项
	return cmd
}
//准备
func (o *ConvertOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) (err error) {
	err = o.FilenameOptions.RequireFilenameOrKustomize()//文件是必须的
	if err != nil {
		return err
	}
	o.builder = f.NewBuilder//设置builder

	o.Namespace, _, err = f.ToRawKubeConfigLoader().Namespace()//设置namespace
	if err != nil {
		return err
	}

	o.validator = func() (validation.Schema, error) {//设置schemaValidator
		return f.Validator(cmdutil.GetFlagBool(cmd, "validate"))
	}

	// build the printer
	o.Printer, err = o.PrintFlags.ToPrinter()//printflag转printer
	if err != nil {
		return err
	}
	return nil
}
//运行
func (o *ConvertOptions) RunConvert() error {

	// Convert must be removed from kubectl, since kubectl can not depend on
	// Kubernetes "internal" dependencies. These "internal" dependencies can
	// not be removed from convert. Another way to convert a resource is to
	// "kubectl apply" it to the cluster, then "kubectl get" at the desired version.
	// Another possible solution is to make convert a plugin.
	fmt.Fprintf(o.ErrOut, "kubectl convert is DEPRECATED and will be removed in a future version.\nIn order to convert, kubectl apply the object to the cluster, then kubectl get at the desired version.\n")//打印deprecated提示

	b := o.builder().
		WithScheme(scheme.Scheme).
		LocalParam(o.local)
	if !o.local {
		schema, err := o.validator()
		if err != nil {
			return err
		}
		b.Schema(schema)
	}

	r := b.NamespaceParam(o.Namespace).
		ContinueOnError().
		FilenameParam(false, &o.FilenameOptions).
		Flatten().
		Do()//用builder构造result对象

	err := r.Err()
	if err != nil {
		return err
	}

	singleItemImplied := false
	infos, err := r.IntoSingleItemImplied(&singleItemImplied).Infos()//获取infos
	if err != nil {
		return err
	}

	if len(infos) == 0 {//info为0个返回错误
		return fmt.Errorf("no objects passed to convert")
	}

	var specifiedOutputVersion schema.GroupVersion
	if len(o.OutputVersion) > 0 {//如果指定了output-version
		specifiedOutputVersion, err = schema.ParseGroupVersion(o.OutputVersion)//解析output-version
		if err != nil {
			return err
		}
	}

	internalEncoder := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)//获取codec
	internalVersionJSONEncoder := unstructured.JSONFallbackEncoder{Encoder: internalEncoder}//构造json encoder
	objects, err := asVersionedObject(infos, !singleItemImplied, specifiedOutputVersion, internalVersionJSONEncoder)//转换对象
	if err != nil {
		return err
	}

	return o.Printer.PrintObj(objects, o.Out)//打印结果
}
//转换对象
func asVersionedObject(infos []*resource.Info, forceList bool, specifiedOutputVersion schema.GroupVersion, encoder runtime.Encoder) (runtime.Object, error) {
	objects, err := asVersionedObjects(infos, specifiedOutputVersion, encoder)//转换对象
	if err != nil {
		return nil, err
	}

	var object runtime.Object
	if len(objects) == 1 && !forceList {//如果结果是1个对象,不是forceList
		object = objects[0]
	} else {
		object = &api.List{Items: objects}//把对象包装成list
		targetVersions := []schema.GroupVersion{}
		if !specifiedOutputVersion.Empty() {//specifiedOutputVersion非空
			targetVersions = append(targetVersions, specifiedOutputVersion)//append version
		}
		targetVersions = append(targetVersions, schema.GroupVersion{Group: "", Version: "v1"})//append version

		converted, err := tryConvert(scheme.Scheme, object, targetVersions...)//尝试转换
		if err != nil {
			return nil, err
		}
		object = converted
	}

	actualVersion := object.GetObjectKind().GroupVersionKind()//获取对象实际的version
	if actualVersion.Version != specifiedOutputVersion.Version {//如果对象实际version不等于指定的version
		defaultVersionInfo := ""
		if len(actualVersion.Version) > 0 {//实际version非空,设置打印消息
			defaultVersionInfo = fmt.Sprintf("Defaulting to %q", actualVersion.Version)
		}
		klog.V(1).Infof("info: the output version specified is invalid. %s\n", defaultVersionInfo)//输出klog日志
	}
	return object, nil//返回对象
}
//转换对象
func asVersionedObjects(infos []*resource.Info, specifiedOutputVersion schema.GroupVersion, encoder runtime.Encoder) ([]runtime.Object, error) {
	objects := []runtime.Object{}
	for _, info := range infos {//遍历infos
		if info.Object == nil {//info的object为空继续
			continue
		}

		targetVersions := []schema.GroupVersion{}//构造目标version slice
		// objects that are not part of api.Scheme must be converted to JSON
		// TODO: convert to map[string]interface{}, attach to runtime.Unknown?
		if !specifiedOutputVersion.Empty() {//指定的version非空
			if _, _, err := scheme.Scheme.ObjectKinds(info.Object); runtime.IsNotRegisteredError(err) {//获取对象kind,如果是IsNotRegisteredError错误
				// TODO: ideally this would encode to version, but we don't expose multiple codecs here.
				data, err := runtime.Encode(encoder, info.Object)//encode对象
				if err != nil {
					return nil, err
				}
				// TODO: Set ContentEncoding and ContentType.
				objects = append(objects, &runtime.Unknown{Raw: data})//追加objects,继续
				continue
			}
			targetVersions = append(targetVersions, specifiedOutputVersion)//追加目标vesions
		} else {//如果版本没指定
			gvks, _, err := scheme.Scheme.ObjectKinds(info.Object)//获取对象kinds
			if err == nil {
				for _, gvk := range gvks {
					targetVersions = append(targetVersions, scheme.Scheme.PrioritizedVersionsForGroup(gvk.Group)...)//追加目标versions
				}
			}
		}

		converted, err := tryConvert(scheme.Scheme, info.Object, targetVersions...)//尝试convert
		if err != nil {
			return nil, err
		}
		objects = append(objects, converted)//追加对象
	}
	return objects, nil//返回对象
}
//尝试转换
func tryConvert(converter runtime.ObjectConvertor, object runtime.Object, versions ...schema.GroupVersion) (runtime.Object, error) {
	var last error
	for _, version := range versions {//遍历目标版本
		if version.Empty() {//如果版本为空,直接返回对象
			return object, nil
		}
		obj, err := converter.ConvertToVersion(object, version)//转换对象到某个版本
		if err != nil {//有错误继续
			last = err
			continue
		}
		return obj, nil//返回对象
	}
	return nil, last//返回错误
}

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐