目前刚开始写一个月,一共写了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完全手册
加qq群,请联系:
————————————————
type TopPodOptions struct {//top pod结构体
ResourceName string
Namespace string
Selector string
SortBy string
AllNamespaces bool
PrintContainers bool
NoHeaders bool
PodClient corev1client.PodsGetter
HeapsterOptions HeapsterTopOptions
Client *metricsutil.HeapsterMetricsClient
Printer *metricsutil.TopCmdPrinter
DiscoveryClient discovery.DiscoveryInterface
MetricsClient metricsclientset.Interface
genericclioptions.IOStreams
}
//创建top pod命令
func NewCmdTopPod(f cmdutil.Factory, o *TopPodOptions, streams genericclioptions.IOStreams) *cobra.Command {
if o == nil {
o = &TopPodOptions{//初始化结构体
IOStreams: streams,
}
}
cmd := &cobra.Command{//创建cobra命令
Use: "pod [NAME | -l label]",
DisableFlagsInUseLine: true,
Short: i18n.T("Display Resource (CPU/Memory/Storage) usage of pods"),
Long: topPodLong,
Example: topPodExample,
Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Complete(f, cmd, args))//准备
cmdutil.CheckErr(o.Validate())//校验
cmdutil.CheckErr(o.RunTopPod())//运行
},
Aliases: []string{"pods", "po"},//别名
}
cmd.Flags().StringVarP(&o.Selector, "selector", "l", o.Selector, "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)")//selector选项
cmd.Flags().StringVar(&o.SortBy, "sort-by", o.Selector, "If non-empty, sort pods list using specified field. The field can be either 'cpu' or 'memory'.")//sort-by选项
cmd.Flags().BoolVar(&o.PrintContainers, "containers", o.PrintContainers, "If present, print usage of containers within a pod.")//containers选项
cmd.Flags().BoolVarP(&o.AllNamespaces, "all-namespaces", "A", o.AllNamespaces, "If present, list the requested object(s) across all namespaces. Namespace in current context is ignored even if specified with --namespace.")//所有名称空间选项
cmd.Flags().BoolVar(&o.NoHeaders, "no-headers", o.NoHeaders, "If present, print output without headers.")//no-headers选项
o.HeapsterOptions.Bind(cmd.Flags())//绑定heapster选项
return cmd
}
//准备函数
func (o *TopPodOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
var err error
if len(args) == 1 {//如果参数是1个,则把参数赋值给资源
o.ResourceName = args[0]
} else if len(args) > 1 {//参数大于1个报错
return cmdutil.UsageErrorf(cmd, "%s", cmd.Use)
}
o.Namespace, _, err = f.ToRawKubeConfigLoader().Namespace()//设置namespace
if err != nil {
return err
}
clientset, err := f.KubernetesClientSet()//获取clientset
if err != nil {
return err
}
o.DiscoveryClient = clientset.DiscoveryClient//从clientset获取discoveryClient
config, err := f.ToRESTConfig()//获取restconfig
if err != nil {
return err
}
o.MetricsClient, err = metricsclientset.NewForConfig(config)//通过restConfig获取MetrixClient
if err != nil {
return err
}
o.PodClient = clientset.CoreV1()//通过clientset获取PodClient
o.Client = metricsutil.NewHeapsterMetricsClient(clientset.CoreV1(), o.HeapsterOptions.Namespace, o.HeapsterOptions.Scheme, o.HeapsterOptions.Service, o.HeapsterOptions.Port)//设置heapersterclient
o.Printer = metricsutil.NewTopCmdPrinter(o.Out)//设置打印对象
return nil
}
//校验
func (o *TopPodOptions) Validate() error {
if len(o.SortBy) > 0 {//如果sort-by有值,则值必须为memory或cpu
if o.SortBy != sortByCPU && o.SortBy != sortByMemory {
return errors.New("--sort-by accepts only cpu or memory")
}
}
if len(o.ResourceName) > 0 && len(o.Selector) > 0 {//资源名称和selector不能同时指定
return errors.New("only one of NAME or --selector can be provided")
}
return nil
}
//运行
func (o TopPodOptions) RunTopPod() error {
var err error
selector := labels.Everything()//设置标签选择器为所有
if len(o.Selector) > 0 {//如果--selector不为空,设置标签选择器为解析后的值
selector, err = labels.Parse(o.Selector)
if err != nil {
return err
}
}
apiGroups, err := o.DiscoveryClient.ServerGroups()//从discoveryClient获取apiGroup
if err != nil {
return err
}
metricsAPIAvailable := SupportedMetricsAPIVersionAvailable(apiGroups)//判断metrics是否支持apiGroup
metrics := &metricsapi.PodMetricsList{}//创建PodMetricsList对象
if metricsAPIAvailable {//如果metrics支持apiGroup
metrics, err = getMetricsFromMetricsAPI(o.MetricsClient, o.Namespace, o.ResourceName, o.AllNamespaces, selector)//获取metrics
if err != nil {
return err
}
} else {
metrics, err = o.Client.GetPodMetrics(o.Namespace, o.ResourceName, o.AllNamespaces, selector)//通过client获取metrics
if err != nil {
return err
}
}
// TODO: Refactor this once Heapster becomes the API server.
// First we check why no metrics have been received.
if len(metrics.Items) == 0 {//如果metrics为空
// If the API server query is successful but all the pods are newly created,
// the metrics are probably not ready yet, so we return the error here in the first place.
e := verifyEmptyMetrics(o, selector)//验证空metrics
if e != nil {
return e
}
}
if err != nil {
return err
}
return o.Printer.PrintPodMetrics(metrics.Items, o.PrintContainers, o.AllNamespaces, o.NoHeaders, o.SortBy)//打印metrics
}
//通过metrics api获取metrics
func getMetricsFromMetricsAPI(metricsClient metricsclientset.Interface, namespace, resourceName string, allNamespaces bool, selector labels.Selector) (*metricsapi.PodMetricsList, error) {
var err error
ns := metav1.NamespaceAll//名称空间为所有
if !allNamespaces {//如果没有指定all-namespaces,名称空间为特定值
ns = namespace
}
versionedMetrics := &metricsv1beta1api.PodMetricsList{}//构造PodMetricsList对象
if resourceName != "" {//如果资源名称不为空
m, err := metricsClient.MetricsV1beta1().PodMetricses(ns).Get(resourceName, metav1.GetOptions{})//获取指定资源名称的metrics
if err != nil {
return nil, err
}
versionedMetrics.Items = []metricsv1beta1api.PodMetrics{*m}//包装
} else {
versionedMetrics, err = metricsClient.MetricsV1beta1().PodMetricses(ns).List(metav1.ListOptions{LabelSelector: selector.String()})//通过labelselector获取metrics
if err != nil {
return nil, err
}
}
metrics := &metricsapi.PodMetricsList{}//构造podMetricsList对象
err = metricsv1beta1api.Convert_v1beta1_PodMetricsList_To_metrics_PodMetricsList(versionedMetrics, metrics, nil)//把metrics转为PodMetricsList
if err != nil {
return nil, err
}
return metrics, nil//返回结果
}
//验证空metrics
func verifyEmptyMetrics(o TopPodOptions, selector labels.Selector) error {
if len(o.ResourceName) > 0 {//如果资源名称不控
pod, err := o.PodClient.Pods(o.Namespace).Get(o.ResourceName, metav1.GetOptions{})//获取pod
if err != nil {
return err
}
if err := checkPodAge(pod); err != nil {//检查年龄
return err
}
} else {
pods, err := o.PodClient.Pods(o.Namespace).List(metav1.ListOptions{//获取符合selector的所有pod
LabelSelector: selector.String(),
})
if err != nil {
return err
}
if len(pods.Items) == 0 {
return nil
}
for _, pod := range pods.Items {//遍历pods检查年龄
if err := checkPodAge(&pod); err != nil {
return err
}
}
}
return errors.New("metrics not available yet")
}
func checkPodAge(pod *v1.Pod) error {
age := time.Since(pod.CreationTimestamp.Time)//获取pod从创建到现在的时间
if age > metricsCreationDelay {//如果pod存在时间大于特定时间
message := fmt.Sprintf("Metrics not available for pod %s/%s, age: %s", pod.Namespace, pod.Name, age.String())
klog.Warningf(message)//输出klog警告
return errors.New(message)//返回错误
} else {
klog.V(2).Infof("Metrics not yet available for pod %s/%s, age: %s", pod.Namespace, pod.Name, age.String())//输出info
return nil//返回nil
}
}
// 打印pod metrics
func (printer *TopCmdPrinter) PrintPodMetrics(metrics []metricsapi.PodMetrics, printContainers bool, withNamespace bool, noHeaders bool, sortBy string) error {
if len(metrics) == 0 {//如果metrics为空返回
return nil
}
w := printers.GetNewTabWriter(printer.out)//把out包装为tabWriter
defer w.Flush()//defer flush
if !noHeaders {//如果没有指定noHeaders
if withNamespace {//如果withnamespace
printValue(w, NamespaceColumn)//打印namespace列
}
if printContainers {//如果打印容器为真
printValue(w, PodColumn)//打印pod列
}
printColumnNames(w, PodColumns)//打印其他列
}
p, err := NewPodMetricsSorter(metrics, printContainers, withNamespace, sortBy)//排序器
if err != nil {
return err
}
sort.Sort(p)//执行排序
for _, m := range metrics {// 遍历metrics
err := printSinglePodMetrics(w, &m, printContainers, withNamespace)//打印单行
if err != nil {
return err
}
}
return nil
}