这篇分析下kube-apiserver CLI的参数初始化。每个kubernetes主节点上,都可以在以下目录发现kube-apiserver的启动配置文件:
[root@kubemaster ~]# cat /etc/kubernetes/manifests/kube-apiserver.yaml
apiVersion: v1
kind: Pod
metadata:
annotations:
kubeadm.kubernetes.io/kube-apiserver.advertise-address.endpoint: xx.xx.xx.xx:6443
creationTimestamp: null
labels:
component: kube-apiserver
tier: control-plane
name: kube-apiserver
namespace: kube-system
spec:
containers:
- command:
# kube-apiserver CLI的参数
- kube-apiserver
- --advertise-address=xx.xx.xx.xx
- --allow-privileged=true
- --authorization-mode=Node,RBAC
- --client-ca-file=/etc/kubernetes/pki/ca.crt
- --enable-admission-plugins=NodeRestriction
- --enable-bootstrap-token-auth=true
- --etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt
- --etcd-certfile=/etc/kubernetes/pki/apiserver-etcd-client.crt
- --etcd-keyfile=/etc/kubernetes/pki/apiserver-etcd-client.key
那这些参数是源码中怎样初始化的?
Code
启动点:
func main() {
// -> 从这里启动
command := app.NewAPIServerCommand()
code := cli.Run(command)
os.Exit(code)
}
// NewAPIServerCommand creates a *cobra.Command object with default parameters
func NewAPIServerCommand() *cobra.Command {
s := options.NewServerRunOptions()
cmd := &cobra.Command{
Use: "kube-apiserver",
Long: `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.`,
// ...
}
// 1. 初始化flag
fs := cmd.Flags()
// 2. 添加flag
namedFlagSets := s.Flags()
verflag.AddFlags(namedFlagSets.FlagSet("global"))
// ...
return cmd
}
flag在其中按照功能分成了几组,也有全局的flag单独注册。比如etcd相关的配置项会被分成一组。
// Flags returns flags for a specific APIServer by section name
func (s *ServerRunOptions) Flags() (fss cliflag.NamedFlagSets) {
// 分组flag
s.GenericServerRunOptions.AddUniversalFlags(fss.FlagSet("generic"))
// etcd相关的配置项
s.Etcd.AddFlags(fss.FlagSet("etcd"))
s.SecureServing.AddFlags(fss.FlagSet("secure serving"))
s.Audit.AddFlags(fss.FlagSet("auditing"))
s.Features.AddFlags(fss.FlagSet("features"))
s.Authentication.AddFlags(fss.FlagSet("authentication"))
// ...
// 全局flag
fs.BoolVar(&s.AllowPrivileged, "allow-privileged", s.AllowPrivileged,
"If true, allow privileged containers. [default=false]")
// ...
}
比如etcd分组中的flag, 在调用s.Etcd.AddFlags时添加。
- k8s.io/apiserver/pkg/server/options/etcd.go
// AddEtcdFlags adds flags related to etcd storage for a specific APIServer to the specified FlagSet
func (s *EtcdOptions) AddFlags(fs *pflag.FlagSet) {
if s == nil {
return
}
fs.StringSliceVar(&s.EtcdServersOverrides, "etcd-servers-overrides", s.EtcdServersOverrides, ""+
"Per-resource etcd servers overrides, comma separated. The individual override "+
"format: group/resource#servers, where servers are URLs, semicolon separated. "+
"Note that this applies only to resources compiled into this server binary. ")
fs.StringVar(&s.DefaultStorageMediaType, "storage-media-type", s.DefaultStorageMediaType, ""+
"The media type to use to store objects in storage. "+
"Some resources or storage backends may only support a specific media type and will ignore this setting.")
fs.IntVar(&s.DeleteCollectionWorkers, "delete-collection-workers", s.DeleteCollectionWorkers,
"Number of workers spawned for DeleteCollection call. These are used to speed up namespace cleanup.")
// ...
}
NamedFlagSets
NamedFlagSets负责存储所有配置分组,每个子package 调用FlagSet方法,初始化自身配置。
// NamedFlagSets stores named flag sets in the order of calling FlagSet.
type NamedFlagSets struct {
// Order is an ordered list of flag set names.
Order []string
// FlagSets stores the flag sets by name.
FlagSets map[string]*pflag.FlagSet
// NormalizeNameFunc is the normalize function which used to initialize FlagSets created by NamedFlagSets.
NormalizeNameFunc func(f *pflag.FlagSet, name string) pflag.NormalizedName
}
// FlagSet returns the flag set with the given name and adds it to the
// ordered name list if it is not in there yet.
func (nfs *NamedFlagSets) FlagSet(name string) *pflag.FlagSet {
if nfs.FlagSets == nil {
nfs.FlagSets = map[string]*pflag.FlagSet{}
}
if _, ok := nfs.FlagSets[name]; !ok {
flagSet := pflag.NewFlagSet(name, pflag.ExitOnError)
flagSet.SetNormalizeFunc(pflag.CommandLine.GetNormalizeFunc())
if nfs.NormalizeNameFunc != nil {
flagSet.SetNormalizeFunc(nfs.NormalizeNameFunc)
}
nfs.FlagSets[name] = flagSet
nfs.Order = append(nfs.Order, name)
}
return nfs.FlagSets[name]
}