持续更新中…
Cobra提供了很多构建命令行接口的特性。基本的Cobra功能说明可以在 https://blog.gopheracademy.com/advent-2014/introducing-cobra/ 找到。基本示例如下
package main
import (
"fmt"
"github.com/spf13/cobra"
"math/rand"
"os"
"time"
)
func main() {
rand.Seed(time.Now().UnixNano())
command := NewCommand()
if err := command.Execute(); err != nil {
os.Exit(1)
}
}
func NewCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "Test Cobra command",
Short: "Shot description",
Long: "Long description",
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("Test Run")
for {
}
},
}
return cmd
}
编译运行后就会执行command的Run方法
kubernetes中所有的组件都是一个cobra.Command应用
kube-apiserver启动核心代码如下
(cmd/kube-apiserver/apiserver.go)
func main() {
rand.Seed(time.Now().UnixNano())
command := app.NewAPIServerCommand()
if err := command.Execute(); err != nil {
os.Exit(1)
}
}
app.NewAPIServerCommand()返回的就是一个cobra.Command指针对象
(cmd/kube-apiserver/app/server.go)
// NewAPIServerCommand creates a *cobra.Command object with default parameters
func NewAPIServerCommand() *cobra.Command {
s := options.NewServerRunOptions()
cmd := &cobra.Command{
......
RunE: func(cmd *cobra.Command, args []string) error {
......
// set default options
completedOptions, err := Complete(s)
......
return Run(completedOptions, genericapiserver.SetupSignalHandler())
},
}
kube-apiserver编译后的二进制文件启动就是执行的RunE方法
其他的kube-controllermanager,kube-proxy等都是使用cobra.Command启动的
kube-apiserver使用的是cobra.Command启动,但是启动的时候会携带很多参数
kube-apiserver --address=192.168.133.16 --allow-privileged=true ...
这些参数的解析是通过flag完成的
package main
import (
"flag"
"fmt"
)
//声明变量用于接收命令行传入的参数值
var (
name string
age int
address *string
id *int
)
func init() {
//通过传入变量地址的方式,绑定命令行参数到string变量
flag.StringVar(
&name, //第一个参数:存放值的参数地址
"name", //第二个参数:命令行参数的名称
"匿名", //第三个参数:命令行不输入时的默认值
"您的姓名" //第四个参数:该参数的描述信息,help命令时会显示
)
//通过传入变量地址的方式,绑定命令行参数到int变量
flag.IntVar(&age, "age", -1, "您的年龄")
//和前面两个变量的获取方式不同,这个api没有传入变量地址,而是把命令行参数值的地址返回了
address = flag.String("address", "未知", "您的住址")
id = flag.Int("id", -1, "身份ID")
}
func main() {
//处理入参
flag.Parse()
//入参已经被赋值给各个变量,可以使用了
fmt.Printf("%s您好, 您的年龄:%d, 您的住址:%s, 您的ID:%d\n\n", name, age, *address, *id)
fmt.Println("---遍历有输入的参数(开始)---")
//Visit方法会遍历有输入的参数,flag.Flag可以将参数的名称、值、默认值、描述等内容取到
flag.Visit(func(f *flag.Flag) {
fmt.Printf("参数名[%s], 参数值[%s], 默认值[%s], 描述信息[%s]\n", f.Name, f.Value, f.DefValue, f.Usage)
})
fmt.Println("---遍历有输入的参数(结束)---\n")
fmt.Println("---遍历所有的参数(开始)---")
//VisitAll方法会遍历所有定义的参数(包括没有在命令行输入的),flag.Flag可以将参数的名称、值、默认值、描述等内容取到
flag.VisitAll(func(f *flag.Flag) {
fmt.Printf("参数名[%s], 参数值[%s], 默认值[%s], 描述信息[%s]\n", f.Name, f.Value, f.DefValue, f.Usage)
})
fmt.Println("---遍历所有的参数(结束)---\n")
}
运行的时候使用可以通过-name,-age等传入参数
go run flag.go --name test --age 30 --address=wuhan -id 101
运行help显示如下
[root@admin ]# go run flag.go --help
-address string
您的住址 (default "未知")
-age int
您的年龄 (default -1)
-id int
身份ID (default -1)
-name string
您的姓名 (default "匿名")
kubernetes中所有的组件启动所携带的参数都是通过flag进行解析,运行kube-apiserver --help
[root@k8s-node1 ~]# kube-apiserver --help
The Kubernetes API server validates and configures data
for the api objects which include pods, services, replicationcontrollers, and
others. The API Server services REST operations and provides the frontend to the
cluster's shared state through which all other components interact.
Usage:
kube-apiserver [flags]
Generic flags:
--advertise-address ip
The IP address on which to advertise the apiserver to members of the cluster. This address must be reachable by the rest of the
cluster. If blank, the --bind-address will be used. If --bind-address is unspecified, the host's default interface will be used.
--cloud-provider-gce-lb-src-cidrs cidrs
CIDRs opened in GCE firewall for LB traffic proxy & health checks (default
130.211.0.0/22,209.85.152.0/22,209.85.204.0/22,35.191.0.0/16)
......