外贸大型门户网站建设游戏代理平台哪个好
欢迎关注我的公众号:
目前刚开始写一个月,一共写了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 DiffOptions struct {//diff结构体FilenameOptions resource.FilenameOptionsServerSideApply boolForceConflicts boolOpenAPISchema openapi.ResourcesDiscoveryClient discovery.DiscoveryInterfaceDynamicClient dynamic.InterfaceDryRunVerifier *apply.DryRunVerifierCmdNamespace stringEnforceNamespace boolBuilder *resource.BuilderDiff *DiffProgram
}
func NewDiffOptions(ioStreams genericclioptions.IOStreams) *DiffOptions {return &DiffOptions{//创建diff结构体Diff: &DiffProgram{Exec: exec.New(),IOStreams: ioStreams,},}
}
//创建diff命令
func NewCmdDiff(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {options := NewDiffOptions(streams)//初始化结构体cmd := &cobra.Command{//创建cobra命令Use: "diff -f FILENAME",DisableFlagsInUseLine: true,Short: i18n.T("Diff live version against would-be applied version"),Long: diffLong,Example: diffExample,Run: func(cmd *cobra.Command, args []string) {cmdutil.CheckErr(options.Complete(f, cmd))//准备方法cmdutil.CheckErr(validateArgs(cmd, args))//校验cmdutil.CheckErr(options.Run())//运行},}usage := "contains the configuration to diff"cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, usage)//文件选项cmdutil.AddServerSideApplyFlags(cmd)//serverside选项return cmd
}
//准备
func (o *DiffOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error {var err errorerr = o.FilenameOptions.RequireFilenameOrKustomize()//文件选项是必须的if err != nil {return err}o.ServerSideApply = cmdutil.GetServerSideApplyFlag(cmd)//获取server-side选项o.ForceConflicts = cmdutil.GetForceConflictsFlag(cmd)//获取force-conflicts选项if o.ForceConflicts && !o.ServerSideApply {//如果指定force-conflicts选项则server-side选项为必须return fmt.Errorf("--force-conflicts only works with --server-side")}if !o.ServerSideApply {//如果没有设置server-side选项o.OpenAPISchema, err = f.OpenAPISchema()//获取OpenAPISchemaif err != nil {return err}}o.DiscoveryClient, err = f.ToDiscoveryClient()//设置DiscoveryClientif err != nil {return err}o.DynamicClient, err = f.DynamicClient()//设置DynamicClientif err != nil {return err}o.DryRunVerifier = &apply.DryRunVerifier{//设置干跑校验器Finder: cmdutil.NewCRDFinder(cmdutil.CRDFromDynamic(o.DynamicClient)),OpenAPIGetter: o.DiscoveryClient,}o.CmdNamespace, o.EnforceNamespace, err = f.ToRawKubeConfigLoader().Namespace()//设置namespace和enforceNamespaceif err != nil {return err}o.Builder = f.NewBuilder()//设置builderreturn nil
}
//校验
func validateArgs(cmd *cobra.Command, args []string) error {if len(args) != 0 {//参数必须是0个return cmdutil.UsageErrorf(cmd, "Unexpected args: %v", args)}return nil
}
//运行
func (o *DiffOptions) Run() error {differ, err := NewDiffer("LIVE", "MERGED")//构造differif err != nil {return err}defer differ.TearDown()//清理diffprinter := Printer{}//构造printerr := o.Builder.Unstructured().NamespaceParam(o.CmdNamespace).DefaultNamespace().FilenameParam(o.EnforceNamespace, &o.FilenameOptions).Flatten().Do()//构造result对象if err := r.Err(); err != nil {//result有错误返回return err}err = r.Visit(func(info *resource.Info, err error) error {//visit resultif err != nil {return err}if err := o.DryRunVerifier.HasSupport(info.Mapping.GroupVersionKind); err != nil {//校验是否支持干跑return err}local := info.Object.DeepCopyObject()//拷贝info.Objectfor i := 1; i <= maxRetries; i++ {//最大尝试次数maxRetries,循环if err = info.Get(); err != nil {//获取infoif !errors.IsNotFound(err) {//如果是非找到错误,返回return err}info.Object = nil//如果info没找到,info.Object设为空}force := i == maxRetries//如果尝试次数到达最大重试次数,则输出告警if force {klog.Warningf("Object (%v: %v) keeps changing, diffing without lock",info.Object.GetObjectKind().GroupVersionKind(),info.Name,)}obj := InfoObject{//构造InfoObject对象LocalObj: local,Info: info,Encoder: scheme.DefaultJSONEncoder(),OpenAPI: o.OpenAPISchema,Force: force,ServerSideApply: o.ServerSideApply,ForceConflicts: o.ForceConflicts,}err = differ.Diff(obj, printer)//准备diffif !isConflict(err) {//入股欧式非冲突错误,跳出循环break}}return err})if err != nil {return err}return differ.Run(o.Diff)//运行diff
}
type Differ struct {//differ 结构体From *DiffVersionTo *DiffVersion
}
func NewDiffer(from, to string) (*Differ, error) {//创建differdiffer := Differ{}//构造differ结构体var err errordiffer.From, err = NewDiffVersion(from)//创建fromif err != nil {return nil, err}differ.To, err = NewDiffVersion(to)//创建toif err != nil {differ.From.Dir.Delete()//删除fromreturn nil, err}return &differ, nil//返回
}
//准备diff
func (d *Differ) Diff(obj Object, printer Printer) error {if err := d.From.Print(obj, printer); err != nil {//把yaml文件输出到fromreturn err}if err := d.To.Print(obj, printer); err != nil {//把yaml文件输出到toreturn err}return nil
}// Run runs the diff program against both directories.
func (d *Differ) Run(diff *DiffProgram) error {//运行diffreturn diff.Run(d.From.Dir.Name, d.To.Dir.Name)
}// TearDown removes both temporary directories recursively.
func (d *Differ) TearDown() {//清理diffd.From.Dir.Delete() // Ignore error删除from目录d.To.Dir.Delete() // Ignore error删除to目录
}
type DiffVersion struct {//diffVersion结构体Dir *DirectoryName string
}// NewDiffVersion creates a new DiffVersion with the named version.
func NewDiffVersion(name string) (*DiffVersion, error) {//DiffVersiondir, err := CreateDirectory(name)//创建目录if err != nil {return nil, err}return &DiffVersion{//构造diffVersionDir: dir,Name: name,}, nil
}func (v *DiffVersion) getObject(obj Object) (runtime.Object, error) {//获取对象switch v.Name {case "LIVE"://获取live对象return obj.Live(), nilcase "MERGED"://获取merged对象return obj.Merged()}return nil, fmt.Errorf("Unknown version: %v", v.Name)
}// Print prints the object using the printer into a new file in the directory.
func (v *DiffVersion) Print(obj Object, printer Printer) error {//打印对象到文件vobj, err := v.getObject(obj)//获取对象if err != nil {return err}f, err := v.Dir.NewFile(obj.Name())//创建文件if err != nil {return err}defer f.Close()return printer.Print(vobj, f)//输出对象到文件
}
type Printer struct{}//printer结构体// Print the object inside the writer w.
func (p *Printer) Print(obj runtime.Object, w io.Writer) error {//打印对象到文件if obj == nil {return nil}data, err := yaml.Marshal(obj)//对象转yamlif err != nil {return err}_, err = w.Write(data)//输出到文件return err}
type DiffProgram struct {//diffProgram结构体Exec exec.Interfacegenericclioptions.IOStreams
}func (d *DiffProgram) getCommand(args ...string) exec.Cmd {//获取命令diff := ""if envDiff := os.Getenv("KUBECTL_EXTERNAL_DIFF"); envDiff != "" {//获取环境变量diff = envDiff} else {//环境变量不存在则用diffdiff = "diff"args = append([]string{"-u", "-N"}, args...)//设置参数}cmd := d.Exec.Command(diff, args...)//获取cmdcmd.SetStdout(d.Out)cmd.SetStderr(d.ErrOut)return cmd//返回cmd
}// Run runs the detected diff program. `from` and `to` are the directory to diff.
func (d *DiffProgram) Run(from, to string) error {//运行diffProgramreturn d.getCommand(from, to).Run()
}
type Directory struct {//directory结构体Name string
}// CreateDirectory does create the actual disk directory, and return a
// new representation of it.
func CreateDirectory(prefix string) (*Directory, error) {//创建临时目录name, err := ioutil.TempDir("", prefix+"-")//创建临时目录if err != nil {return nil, err}return &Directory{//返回目录Name: name,}, nil
}// NewFile creates a new file in the directory.
func (d *Directory) NewFile(name string) (*os.File, error) {//在目录下创建文件return os.OpenFile(filepath.Join(d.Name, name), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0700)
}// Delete removes the directory recursively.
func (d *Directory) Delete() error {//删除目录return os.RemoveAll(d.Name)
}
type Object interface {//Object接口Live() runtime.ObjectMerged() (runtime.Object, error)Name() string
}// InfoObject is an implementation of the Object interface. It gets all
// the information from the Info object.
type InfoObject struct {//InfoObject结构体LocalObj runtime.ObjectInfo *resource.InfoEncoder runtime.EncoderOpenAPI openapi.ResourcesForce boolServerSideApply boolForceConflicts bool
}var _ Object = &InfoObject{}// Returns the live version of the object
获取live对象
func (obj InfoObject) Live() runtime.Object {return obj.Info.Object
}// Returns the "merged" object, as it would look like if applied or
// created.
//获取merged对象
func (obj InfoObject) Merged() (runtime.Object, error) {if obj.ServerSideApply {//如果指定server-sidedata, err := runtime.Encode(unstructured.UnstructuredJSONScheme, obj.LocalObj)//把localObj编码为jsonif err != nil {return nil, err}options := metav1.PatchOptions{//设置patch选项Force: &obj.ForceConflicts,DryRun: []string{metav1.DryRunAll},}return resource.NewHelper(obj.Info.Client, obj.Info.Mapping).Patch(obj.Info.Namespace,obj.Info.Name,types.ApplyPatchType,data,&options,)//干跑patch到服务端,返回结果}// Build the patcher, and then apply the patch with dry-run, unless the object doesn't exist, in which case we need to create it.if obj.Live() == nil {//如果live为空// Dry-run create if the object doesn't exist.return resource.NewHelper(obj.Info.Client, obj.Info.Mapping).Create(obj.Info.Namespace,true,obj.LocalObj,&metav1.CreateOptions{DryRun: []string{metav1.DryRunAll}},)//干跑创建到服务端,返回结果}var resourceVersion *stringif !obj.Force {//如果force为true,获取resourceVersionaccessor, err := meta.Accessor(obj.Info.Object)if err != nil {return nil, err}str := accessor.GetResourceVersion()resourceVersion = &str}modified, err := util.GetModifiedConfiguration(obj.LocalObj, false, unstructured.UnstructuredJSONScheme)//获取yaml配置if err != nil {return nil, err}// This is using the patcher from apply, to keep the same behavior.// We plan on replacing this with server-side apply when it becomes available.patcher := &apply.Patcher{//创建patcherMapping: obj.Info.Mapping,Helper: resource.NewHelper(obj.Info.Client, obj.Info.Mapping),Overwrite: true,BackOff: clockwork.NewRealClock(),ServerDryRun: true,OpenapiSchema: obj.OpenAPI,ResourceVersion: resourceVersion,}_, result, err := patcher.Patch(obj.Info.Object, modified, obj.Info.Source, obj.Info.Namespace, obj.Info.Name, nil)//应用patch,返回结果return result, err
}func (obj InfoObject) Name() string {获取文件名称group := ""if obj.Info.Mapping.GroupVersionKind.Group != "" {设置groupgroup = fmt.Sprintf("%v.", obj.Info.Mapping.GroupVersionKind.Group)}return group + fmt.Sprintf("%v.%v.%v.%v",obj.Info.Mapping.GroupVersionKind.Version,obj.Info.Mapping.GroupVersionKind.Kind,obj.Info.Namespace,obj.Info.Name,)//返回拼接的名称
}