发布一个k8s部署视频:https://edu.csdn.net/course/detail/26967
课程内容:各种k8s部署方式。包括minikube部署,kubeadm部署,kubeasz部署,rancher部署,k3s部署。包括开发测试环境部署k8s,和生产环境部署k8s。
腾讯课堂连接地址https://ke.qq.com/course/478827?taid=4373109931462251&tuin=ba64518
第二个视频发布 https://edu.csdn.net/course/detail/27109
腾讯课堂连接地址https://ke.qq.com/course/484107?tuin=ba64518
介绍主要的k8s资源的使用配置和命令。包括configmap,pod,service,replicaset,namespace,deployment,daemonset,ingress,pv,pvc,sc,role,rolebinding,clusterrole,clusterrolebinding,secret,serviceaccount,statefulset,job,cronjob,podDisruptionbudget,podSecurityPolicy,networkPolicy,resourceQuota,limitrange,endpoint,event,conponentstatus,node,apiservice,controllerRevision等。
第三个视频发布:https://edu.csdn.net/course/detail/27574
详细介绍helm命令,学习helm chart语法,编写helm chart。深入分析各项目源码,学习编写helm插件
第四个课程发布:https://edu.csdn.net/course/detail/28488
本课程将详细介绍k8s所有命令,以及命令的go源码分析,学习知其然,知其所以然
加qq群,请联系:
————————————————
type DeleteOptions struct {//delete结构体
resource.FilenameOptions
LabelSelector string
FieldSelector string
DeleteAll bool
DeleteAllNamespaces bool
IgnoreNotFound bool
Cascade bool
DeleteNow bool
ForceDeletion bool
WaitForDeletion bool
Quiet bool
WarnClusterScope bool
Raw string
GracePeriod int
Timeout time.Duration
Output string
DynamicClient dynamic.Interface
Mapper meta.RESTMapper
Result *resource.Result
genericclioptions.IOStreams
}
func NewCmdDelete(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
deleteFlags := NewDeleteCommandFlags("containing the resource to delete.")//初始化deleteflags
cmd := &cobra.Command{//cobra命令
Use: "delete ([-f FILENAME] | [-k DIRECTORY] | TYPE [(NAME | -l label | --all)])",
DisableFlagsInUseLine: true,
Short: i18n.T("Delete resources by filenames, stdin, resources and names, or by resources and label selector"),
Long: deleteLong,
Example: deleteExample,
Run: func(cmd *cobra.Command, args []string) {
o := deleteFlags.ToOptions(nil, streams)//deleteflag转deleteOption
cmdutil.CheckErr(o.Complete(f, args, cmd))//准备
cmdutil.CheckErr(o.Validate())//校验
cmdutil.CheckErr(o.RunDelete(f))//运行
},
SuggestFor: []string{"rm"},
}
deleteFlags.AddFlags(cmd)//设置选项
cmdutil.AddIncludeUninitializedFlag(cmd)
return cmd
}
//准备
func (o *DeleteOptions) Complete(f cmdutil.Factory, args []string, cmd *cobra.Command) error {
cmdNamespace, enforceNamespace, err := f.ToRawKubeConfigLoader().Namespace()//获取namespace和enforcenamespace
if err != nil {
return err
}
o.WarnClusterScope = enforceNamespace && !o.DeleteAllNamespaces//设置warnClusterScope
if o.DeleteAll || len(o.LabelSelector) > 0 || len(o.FieldSelector) > 0 {
if f := cmd.Flags().Lookup("ignore-not-found"); f != nil && !f.Changed {
// If the user didn't explicitly set the option, default to ignoring NotFound errors when used with --all, -l, or --field-selector
o.IgnoreNotFound = true//如果是deleteall,或指定selector或指定field-selector则ignor-not-found我true
}
}
if o.DeleteNow {//如果now为true
if o.GracePeriod != -1 {//grace-period不为默认值报错
return fmt.Errorf("--now and --grace-period cannot be specified together")
}
o.GracePeriod = 1//设置grace period为1
}
if o.GracePeriod == 0 && !o.ForceDeletion {//如果grace-period为0,并且不是force
// To preserve backwards compatibility, but prevent accidental data loss, we convert --grace-period=0
// into --grace-period=1. Users may provide --force to bypass this conversion.
o.GracePeriod = 1//grace-period设置为1
}
if len(o.Raw) == 0 {
r := f.NewBuilder().
Unstructured().
ContinueOnError().
NamespaceParam(cmdNamespace).DefaultNamespace().
FilenameParam(enforceNamespace, &o.FilenameOptions).
LabelSelectorParam(o.LabelSelector).
FieldSelectorParam(o.FieldSelector).
SelectAllParam(o.DeleteAll).
AllNamespaces(o.DeleteAllNamespaces).
ResourceTypeOrNameArgs(false, args...).RequireObject(false).
Flatten().
Do()//构造result对象
err = r.Err()
if err != nil {
return err
}
o.Result = r//设置result对象
o.Mapper, err = f.ToRESTMapper()//设置mapper
if err != nil {
return err
}
o.DynamicClient, err = f.DynamicClient()//设置client
if err != nil {
return err
}
}
return nil
}
//校验
func (o *DeleteOptions) Validate() error {
if o.Output != "" && o.Output != "name" {//output必须是空或name
return fmt.Errorf("unexpected -o output mode: %v. We only support '-o name'", o.Output)
}
if o.DeleteAll && len(o.LabelSelector) > 0 {//all和selector不能同时指定
return fmt.Errorf("cannot set --all and --selector at the same time")
}
if o.DeleteAll && len(o.FieldSelector) > 0 {//all和field-selector不能同时指定
return fmt.Errorf("cannot set --all and --field-selector at the same time")
}
switch {
case o.GracePeriod == 0 && o.ForceDeletion://如果是grace-period为0,并且是force,则输出告警
fmt.Fprintf(o.ErrOut, "warning: Immediate deletion does not wait for confirmation that the running resource has been terminated. The resource may continue to run on the cluster indefinitely.\n")
case o.ForceDeletion://如果grace-period不为0,force为0,则输出告警
fmt.Fprintf(o.ErrOut, "warning: --force is ignored because --grace-period is not 0.\n")
}
if len(o.Raw) > 0 {//raw大于0
if len(o.FilenameOptions.Filenames) > 1 {//不能指定多个文件
return fmt.Errorf("--raw can only use a single local file or stdin")
} else if len(o.FilenameOptions.Filenames) == 1 {
if strings.Index(o.FilenameOptions.Filenames[0], "http://") == 0 || strings.Index(o.FilenameOptions.Filenames[0], "https://") == 0 {//文件不能是url
return fmt.Errorf("--raw cannot read from a url")
}
}
if o.FilenameOptions.Recursive {//不能指定递归
return fmt.Errorf("--raw and --recursive are mutually exclusive")
}
if len(o.Output) > 0 {//不能指定output
return fmt.Errorf("--raw and --output are mutually exclusive")
}
if _, err := url.ParseRequestURI(o.Raw); err != nil {//url必须合法
return fmt.Errorf("--raw must be a valid URL path: %v", err)
}
}
return nil
}
//运行
func (o *DeleteOptions) RunDelete(f cmdutil.Factory) error {
if len(o.Raw) > 0 {//如果指定了raw,则调用http处理
restClient, err := f.RESTClient()
if err != nil {
return err
}
if len(o.Filenames) == 0 {
return rawhttp.RawDelete(restClient, o.IOStreams, o.Raw, "")
}
return rawhttp.RawDelete(restClient, o.IOStreams, o.Raw, o.Filenames[0])
}
return o.DeleteResult(o.Result)//如果没有指定raw,则处理删除
}
//删除逻辑
func (o *DeleteOptions) DeleteResult(r *resource.Result) error {
found := 0
if o.IgnoreNotFound {
r = r.IgnoreErrors(errors.IsNotFound)
}
warnClusterScope := o.WarnClusterScope
deletedInfos := []*resource.Info{}
uidMap := cmdwait.UIDMap{}
err := r.Visit(func(info *resource.Info, err error) error {//visit info对象
if err != nil {
return err
}
deletedInfos = append(deletedInfos, info)//追加deleteInfo
found++
options := &metav1.DeleteOptions{}//创建delete option
if o.GracePeriod >= 0 {
options = metav1.NewDeleteOptions(int64(o.GracePeriod))//创建delete option
}
policy := metav1.DeletePropagationBackground
if !o.Cascade {//如果cascade为false
policy = metav1.DeletePropagationOrphan
}
options.PropagationPolicy = &policy//设置级联策略
if warnClusterScope && info.Mapping.Scope.Name() == meta.RESTScopeNameRoot {//如果warnClusterScope为true,并且资源是集群资源则输出告警
fmt.Fprintf(o.ErrOut, "warning: deleting cluster-scoped resources, not scoped to the provided namespace\n")
warnClusterScope = false
}
response, err := o.deleteResource(info, options)//删除资源
if err != nil {
return err
}
resourceLocation := cmdwait.ResourceLocation{//创建资源位置
GroupResource: info.Mapping.Resource.GroupResource(),
Namespace: info.Namespace,
Name: info.Name,
}
if status, ok := response.(*metav1.Status); ok && status.Details != nil {
uidMap[resourceLocation] = status.Details.UID//设置uidMap
return nil
}
responseMetadata, err := meta.Accessor(response)
if err != nil {
// we don't have UID, but we didn't fail the delete, next best thing is just skipping the UID
klog.V(1).Info(err)
return nil
}
uidMap[resourceLocation] = responseMetadata.GetUID()//设置uidmap
return nil
})
if err != nil {
return err
}
if found == 0 {//资源没找到则打印没找到,并返回
fmt.Fprintf(o.Out, "No resources found\n")
return nil
}
if !o.WaitForDeletion {//不等待则返回
return nil
}
// if we don't have a dynamic client, we don't want to wait. Eventually when delete is cleaned up, this will likely
// drop out.
if o.DynamicClient == nil {//client为空,返回
return nil
}
effectiveTimeout := o.Timeout
if effectiveTimeout == 0 {
// if we requested to wait forever, set it to a week.
effectiveTimeout = 168 * time.Hour
}
waitOptions := cmdwait.WaitOptions{//创建等待选项
ResourceFinder: genericclioptions.ResourceFinderForResult(resource.InfoListVisitor(deletedInfos)),
UIDMap: uidMap,
DynamicClient: o.DynamicClient,
Timeout: effectiveTimeout,
Printer: printers.NewDiscardingPrinter(),
ConditionFn: cmdwait.IsDeleted,
IOStreams: o.IOStreams,
}
err = waitOptions.RunWait() //等待删除完成
if errors.IsForbidden(err) || errors.IsMethodNotSupported(err) {
// if we're forbidden from waiting, we shouldn't fail.
// if the resource doesn't support a verb we need, we shouldn't fail.
klog.V(1).Info(err)
return nil
}
return err
}
func (o *DeleteOptions) deleteResource(info *resource.Info, deleteOptions *metav1.DeleteOptions) (runtime.Object, error) {//删除资源
deleteResponse, err := resource.NewHelper(info.Client, info.Mapping).DeleteWithOptions(info.Namespace, info.Name, deleteOptions)//删除服务器资源
if err != nil {
return nil, cmdutil.AddSourceToErr("deleting", info.Source, err)
}
if !o.Quiet {//如果不为quiet,则打印结果
o.PrintObj(info)
}
return deleteResponse, nil
}