kubectl源码分析之rollout status
发布一个k8s部署视频:https://edu.csdn.net/course/detail/26967课程内容:各种k8s部署方式。包括minikube部署,kubeadm部署,kubeasz部署,rancher部署,k3s部署。包括开发测试环境部署k8s,和生产环境部署k8s。腾讯课堂连接地址https://ke.qq.com/course/478827?taid=43731099314622
欢迎关注我的公众号:
目前刚开始写一个月,一共写了18篇原创文章,文章目录如下:
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完全手册
加qq群,请联系:
————————————————
type RolloutStatusOptions struct {//status结构体
PrintFlags *genericclioptions.PrintFlags
Namespace string
EnforceNamespace bool
BuilderArgs []string
Watch bool
Revision int64
Timeout time.Duration
StatusViewerFn func(*meta.RESTMapping) (polymorphichelpers.StatusViewer, error)
Builder func() *resource.Builder
DynamicClient dynamic.Interface
FilenameOptions *resource.FilenameOptions
genericclioptions.IOStreams
}
func NewRolloutStatusOptions(streams genericclioptions.IOStreams) *RolloutStatusOptions {
return &RolloutStatusOptions{//初始化结构体
PrintFlags: genericclioptions.NewPrintFlags("").WithTypeSetter(scheme.Scheme),
FilenameOptions: &resource.FilenameOptions{},
IOStreams: streams,
Watch: true,
Timeout: 0,
}
}
//创建status命令
func NewCmdRolloutStatus(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
o := NewRolloutStatusOptions(streams)//初始化结构体
validArgs := []string{"deployment", "daemonset", "statefulset"}
cmd := &cobra.Command{//创建cobra命令
Use: "status (TYPE NAME | TYPE/NAME) [flags]",
DisableFlagsInUseLine: true,
Short: i18n.T("Show the status of the rollout"),
Long: statusLong,
Example: statusExample,
Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Complete(f, args))//准备
cmdutil.CheckErr(o.Validate())//校验
cmdutil.CheckErr(o.Run())//运行
},
ValidArgs: validArgs,//有效参数
}
usage := "identifying the resource to get from a server."
cmdutil.AddFilenameOptionFlags(cmd, o.FilenameOptions, usage)//文件选项
cmd.Flags().BoolVarP(&o.Watch, "watch", "w", o.Watch, "Watch the status of the rollout until it's done.")//watch选项
cmd.Flags().Int64Var(&o.Revision, "revision", o.Revision, "Pin to a specific revision for showing its status. Defaults to 0 (last revision).")//revision选项
cmd.Flags().DurationVar(&o.Timeout, "timeout", o.Timeout, "The length of time to wait before ending watch, zero means never. Any other values should contain a corresponding time unit (e.g. 1s, 2m, 3h).")//timeout选项
return cmd
}
//准备函数
func (o *RolloutStatusOptions) Complete(f cmdutil.Factory, args []string) error {
o.Builder = f.NewBuilder//设置Builder
var err error
o.Namespace, o.EnforceNamespace, err = f.ToRawKubeConfigLoader().Namespace()//设置Namespace和Enforcenamespace
if err != nil {
return err
}
o.BuilderArgs = args//设置资源
o.StatusViewerFn = polymorphichelpers.StatusViewerFn//设置获取viewer函数
clientConfig, err := f.ToRESTConfig()//获取config
if err != nil {
return err
}
o.DynamicClient, err = dynamic.NewForConfig(clientConfig)//设置client
if err != nil {
return err
}
return nil
}
//校验函数
// Validate makes sure all the provided values for command-line options are valid
func (o *RolloutStatusOptions) Validate() error {
if len(o.BuilderArgs) == 0 && cmdutil.IsFilenameSliceEmpty(o.FilenameOptions.Filenames, o.FilenameOptions.Kustomize) {//资源和文件必须有一个
return fmt.Errorf("required resource not specified")
}
if o.Revision < 0 {//版本不能小于0
return fmt.Errorf("revision must be a positive integer: %v", o.Revision)
}
return nil
}
//运行
func (o *RolloutStatusOptions) Run() error {
r := o.Builder().
WithScheme(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...).
NamespaceParam(o.Namespace).DefaultNamespace().
FilenameParam(o.EnforceNamespace, o.FilenameOptions).
ResourceTypeOrNameArgs(true, o.BuilderArgs...).
SingleResourceType().
Latest().
Do()//构造result对象
err := r.Err()
if err != nil {
return err
}
infos, err := r.Infos()//获取info对象
if err != nil {
return err
}
if len(infos) != 1 {//info不等于1个,报错
return fmt.Errorf("rollout status is only supported on individual resources and resource collections - %d resources were found", len(infos))
}
info := infos[0]
mapping := info.ResourceMapping()
statusViewer, err := o.StatusViewerFn(mapping)//获取viewer
if err != nil {
return err
}
fieldSelector := fields.OneTermEqualSelector("metadata.name", info.Name).String()//设置字段选择器
lw := &cache.ListWatch{//设置watch func
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
options.FieldSelector = fieldSelector
return o.DynamicClient.Resource(info.Mapping.Resource).Namespace(info.Namespace).List(options)
},
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
options.FieldSelector = fieldSelector
return o.DynamicClient.Resource(info.Mapping.Resource).Namespace(info.Namespace).Watch(options)
},
}
preconditionFunc := func(store cache.Store) (bool, error) {//设置条件函数
_, exists, err := store.Get(&metav1.ObjectMeta{Namespace: info.Namespace, Name: info.Name})
if err != nil {
return true, err
}
if !exists {
// We need to make sure we see the object in the cache before we start waiting for events
// or we would be waiting for the timeout if such object didn't exist.
return true, apierrors.NewNotFound(mapping.Resource.GroupResource(), info.Name)
}
return false, nil
}
// if the rollout isn't done yet, keep watching deployment status
ctx, cancel := watchtools.ContextWithOptionalTimeout(context.Background(), o.Timeout)
intr := interrupt.New(nil, cancel)//构造interrupt
return intr.Run(func() error {//运行interrupt
_, err = watchtools.UntilWithSync(ctx, lw, &unstructured.Unstructured{}, preconditionFunc, func(e watch.Event) (bool, error) {//监控
switch t := e.Type; t {//判断事件
case watch.Added, watch.Modified://如果是Added,Modified事件
status, done, err := statusViewer.Status(e.Object.(runtime.Unstructured), o.Revision)//通过viewer获取状态信息
if err != nil {
return false, err
}
fmt.Fprintf(o.Out, "%s", status)//打印状态信息
// Quit waiting if the rollout is done
if done {//如果done为true,结束监控
return true, nil
}
shouldWatch := o.Watch
if !shouldWatch {//如果--watch为false,结束监控
return true, nil
}
return false, nil//否则return false,继续监控
case watch.Deleted://如果事件为Deleted
// We need to abort to avoid cases of recreation and not to silently watch the wrong (new) object
return true, fmt.Errorf("object has been deleted")//结束监控,返回错误
default:
return true, fmt.Errorf("internal error: unexpected event %#v", e)
}
})
return err
})
}
更多推荐
所有评论(0)