hello云胜

技术与生活

0%

上一篇文章写了通过配置kubeconfig文件,使用kubectl连接多个k8s集群的操作。

配置kubectl连接多个k8s集群 (qq.com)

然后有小伙伴告知有个开源项目kubecm就是做这个事情的。

我赶紧去了解并使用了一下,确实不错。比我手动一个个添加kubeconfig方便多了。

这个工具就是把我之前手动的操作全部自动化了,棒啊,

给作者点赞。sunny0826/kubecm: Manage your kubeconfig more easily. (github.com)

也感谢小伙伴的指教。

安装就不说了,很简单。我希望以后直接在自己电脑上操作,省的ssh到服务器上怪麻烦。

所以安装了windows版本。

添加环境

从服务器上把kubeconfig文件拿下来,就是下面命令中的sit.yaml

1
.\kubecm.exe add --context-name=sit -f sit.yaml

image-20231205181709459

会让你选择是否覆盖掉用户目录下的config文件

选否,会在当前目录生成一个新文件kubecm.config。可以先检查下,没问题再覆盖

image-20231205181421070

查看

1
.\kubecm.exe list

image-20231205182101302

重命名

看到我现在默认的这个环境的名字是当时部署时自动生成的,很不好。可以改名

1
kubecm.exe  rename

image-20231205182456276

rename命令没有什么参数可传,是一种交互式的操作。

选择要改名的context,改就行了,很方便。

image-20231205182557536

image-20231205182757832

切换环境

现在默认的时我的mytest环境

image-20231206092139447

想要将默认环境切换为sit也很简单

1
kubecm.exe  switch

image-20231206092308310

交互式选择需要的环境即可

image-20231206094146076

现在kubectl直接就是sit环境的信息了

删除

1
kubecm.exe  delete

image-20231206092956845

一样的交互式选择

kubebuilder(六)webhook

operator中的webhook也是很重要的一块功能。也是相对比较独立的模块,所以放在后面讲。

webhook是一个callback,注册到k8s的api-server上。当某个特定的时间发生时,api server就会查询注册的webhook,并根据一些逻辑确认转发消息给某个webhook

在k8s中,有3类webhook,admission webhook, authorization webhookCRD conversion webhook.

在kubebuilder的底层controller-runtime框架里,支持admission webhooks and CRD conversion webhooks。

这篇笔记讲的是admission webhook。(以下的webhook就是指admission webhook)。 CRD conversion webhooks用于多版本api转换时,目前入门阶段先不讨论这个话题。

admission webhook又可以分成2类。

一种是校验类的webhook,只读取信息,做校验判断,不会改变消息,称为validating类型。这里的校验就可以写复杂的业务了,前面的代码里我们也配置过简单的validation校验。

1
2
// +kubebuilder:validation:Required
Image string `json:"image,omitempty"`

另一种就是可修改对象的webhook,比如设置默认值功能,称为mutating类型。

执行顺序

先执行mutating webhook,后执行validating webhook

就是说先设置,后校验。不需要担心,校验完了之后,另一个webhook又修改了值。

工作流

1

  1. 用户创建一个CRD的实例
  2. k8s api-server将这个请求转发给对应的webhook
  3. webhook完成默认的参数配置操作,并进行一些参数校验操作。成功之后将cr返回给api-server。api-server进行落库
  4. 我们编写的controller的在后台监控cr,拉取cr内容,并执行我们编写的逻辑
  5. cr的执行结果同步回api-server

创建webhook

和创建api一样,webhook也由kubebuilder创建脚手架代码。

我们在之前的代码框架上继续操作。

1
kubebuilder create webhook --group tutorial --version v1 --kind Demo --defaulting --programmatic-validation 

–defaulting 是会创建配置默认值的webhook

–programmatic-validation 创建有校验功能的webhook

kubebuilder的参数

1
2
3
4
5
6
7
8
9
10
Flags:
--conversion if set, scaffold the conversion webhook
--defaulting if set, scaffold the defaulting webhook
--force attempt to create resource even if it already exists
--group string resource Group
-h, --help help for webhook
--kind string resource Kind
--plural string resource irregular plural form
--programmatic-validation if set, scaffold the validating webhook
--version string resource Version

–conversion 就是创建CRD conversion webhooks。用于多版本api转换时,现在先不用管。

执行完之后,看看生成的代码

image-20240318145925949

查看main.go

image-20240318151327123

作用就是在manager中注册了我们的webhook

业务代码

更重要的文件是生成的这个webhook文件,我们的业务代码是写在这里的

image-20240318152519441

image-20240318154234686

我们的Demo实现了webhook.Defaulter接口。即拥有了配置crd的默认值的能力。

稍后我们在这个Default()方法里编写配置默认值的操作。

image-20240318154438377

我们的Demo实现了webhook.Validator接口,在crd进行增删改时可以进行验证操作

简单实现几个方法

1
2
3
4
5
6
7
8
9
10
func (r *Demo) Default() {
demolog.Info("default", "name", r.Name)

// TODO(user): fill in your defaulting logic.
if r.Spec.Replicas == nil {
r.Spec.Replicas = new(int32)
*r.Spec.Replicas = 1
demolog.Info("配置默认值", "replicas", *r.Spec.Replicas)
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// 创建和更新调一下validate方法
func (r *Demo) ValidateCreate() error {
demolog.Info("validate create", "name", r.Name)

// TODO(user): fill in your validation logic upon object creation.
// 调用 r.validate() 方法,来验证对象的合法性。
return r.validate()
}

func (r *Demo) validate() error {
var allErrs field.ErrorList
if *r.Spec.Replicas > 10 {
err := field.Invalid(field.NewPath("spec").Child("replicas"),
*r.Spec.Replicas,
"副本数不能大于10")

allErrs = append(allErrs, err)
}

if len(allErrs) == 0 {
demolog.Info("参数合法")
return nil
}

return apierrors.NewInvalid(schema.GroupKind{
Group: "tutorial",
Kind: "Demo"},
r.Name, allErrs)
}

在部署webhook前,还需要修改下配置

在config/default/kustomization.yaml中

image-20240318173558821

注释全都放开

在config/crd/kustomization.yaml中

image-20240318173642764

注释放开

部署前准备

安装cert-manager

因为api-server是通过https调用webhook,所以需要部署cert-manager来自动管理证书。

这也是kubebuilder官方建议的方案

1
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.7.3/cert-manager.yaml

image-20240320171742770

因为我的测试环境是1.18的k8s,所以选择1.7版本的cert manager。

image-20240320171848151

清理环境

先把之前测试的资源全部删除

删除测试demo

1
kubectl delete -f config/samples/tutorial_v1_demo.yaml

删除operator

1
kubectl delete -f demo-operator.yaml

删除crd

1
make uninstall

部署

1
make install
1
make docker-build docker-push IMG=harbor-test.xxx.net/paas/demo-operator:2.0
1
make deploy IMG=harbor-test.xxx.net/paas/demo-operator:2.0

image-20240320173017108

测试

测试默认值功能

修改一下之前的yaml,去掉replicas字段

1
2
3
4
5
6
7
8
apiVersion: tutorial.demo.com/v1
kind: Demo
metadata:
namespace: demo
name: demo-sample
spec:
image: nginx:1.22
svcName: demo-ng

查看manager的日志

image-20240320173733830

调用了配置默认值的代码

测试参数校验功能

将yaml中的replicas字段设置为15,超过我们的最大值

1
2
[root@paas-m-k8s-master-1 demo-operator]# kubectl apply -f config/samples/tutorial_v1_demo.yaml
The Demo "demo-sample" is invalid: spec.replicas: Invalid value: 15: 副本数不能大于10

直接报错

查看日志

image-20240320174235546

进行了校验

kubebuilder(五)operator运行逻辑

前面我们先简单介绍了operator的项目结构,现在来深入聊聊operator的运行逻辑

Controller 的架构图

img

这是kubebuilder生成的operator项目架构图

img

operator项目的启动逻辑

1.在main.go启动函数中,实例化一个Manager对象。

1
2
3
4
5
6
7
8
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
Scheme: scheme,
MetricsBindAddress: metricsAddr,
Port: 9443,
HealthProbeBindAddress: probeAddr,
LeaderElection: enableLeaderElection,
LeaderElectionID: "f6f7ca38.demo.com",
})

注意看ctrl.Options,默认是监听所有namespace。

1
2
3
4
5
ctrl.Options{
Scheme: scheme,
Namespace: xxnamespace,
MetricsBindAddress: metricsAddr,
}

可以监听指定的namespace。

想要监听多个namespace,可以使用MultiNamespacedCacheBuilder

1
2
3
4
5
ctrl.Options{
Scheme: scheme,
NewCache: cache.MultiNamespacedCacheBuilder([]string{"default", "demo"}),
MetricsBindAddress: metricsAddr,
}

在修改了Operator作用域后,需同时修改RBAC(config/rbac/… 路径下相关yaml文件),以授权Operator操作该namespace下的资源。

2.通过SetUpWithManager()方法,注册资源对象的controller到Manager对象中。

1
2
3
4
5
6
7
if err = (&controllers.DemoReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "Demo")
os.Exit(1)
}

作用就是把我们的DemoReconciler控制器绑定到Manager上

主要的代码逻辑在SetUpWithManager()方法里

1
2
3
4
5
6
// SetupWithManager sets up the controller with the Manager.
func (r *DemoReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
For(&tutorialv1.Demo{}).
Complete(r)
}

ctrl.NewControllerManagedBy(mgr)返回一个controller的构造器builder,然后通过For方法进行设置,这里就是设置为我们编写的自定义资源tutorialv1.Demo,表示要监听这个资源。监听了之后,干什么呢?就是Complete()方法,你看Complete的参数就是r,这个r就是我们写的DemoReconciler。所以,SetupWithManager方法就是说监听我们的crd资源,有任何变化都去执行他的Reconcile()方法。

继续往下追,Complete()方法会调用Builder.Build()进行构造。

Builder.Build()里又包含doController()和doWatch()这两个重要方法。

doController通过资源对象的 GVK 来获取 Controller 的名称,最后通过一个 newController 函数来实例化Controller。

DoWatch就是调用controller.watch来注册EventHandler事件。

启动controllerManager,也就是启动我们编写的crd对象的controller

1
2
3
4
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
setupLog.Error(err, "problem running manager")
os.Exit(1)
}

主要的代码逻辑在mgr.Start()方法里

kubebuilder(二)创建项目及初始化

一个demo项目来了解kubebuilder的项目结构

初始化项目

1
2
3
mkdir demo-operator
cd demo-operator
kubebuilder init --domain demo.com --repo demo.com/tutorial

这一步创建了 Go module 工程基本的模板文件,引入了必要的依赖

如果不用–repo参数,也可以先

1
go mod init demo.com/tutorial

手动初始化一个go module工程

打印的日志

1
2
3
4
5
6
7
8
Writing kustomize manifests for you to edit...
Writing scaffold for you to edit...
Get controller runtime:
$ go get sigs.k8s.io/controller-runtime@v0.10.0
Update dependencies:
$ go mod tidy
Next: define a resource with:
$ kubebuilder create api

可以看到我这里使用的controller-runtime是0.10.0版本。

查看

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
[root@paas-m-k8s-master-1 demo-operator]# tree
.
├── config
│   ├── default
│   │   ├── kustomization.yaml
│   │   ├── manager_auth_proxy_patch.yaml
│   │   └── manager_config_patch.yaml
│   ├── manager
│   │   ├── controller_manager_config.yaml
│   │   ├── kustomization.yaml
│   │   └── manager.yaml
│   ├── prometheus
│   │   ├── kustomization.yaml
│   │   └── monitor.yaml
│   └── rbac
│   ├── auth_proxy_client_clusterrole.yaml
│   ├── auth_proxy_role_binding.yaml
│   ├── auth_proxy_role.yaml
│   ├── auth_proxy_service.yaml
│   ├── kustomization.yaml
│   ├── leader_election_role_binding.yaml
│   ├── leader_election_role.yaml
│   ├── role_binding.yaml
│   └── service_account.yaml
├── Dockerfile
├── go.mod
├── go.sum
├── hack
│   └── boilerplate.go.txt
├── main.go
├── Makefile
└── PROJECT

6 directories, 24 files

就是一个标准的go module项目

一些重要的文件

  1. Makefile:非常重要的工具,以后编译构建、部署、运行都会用到;
  2. PROJECT:kubebuilder工程的元数据,在生成各种API的时候会用到这里面的信息;
  3. config/default:基于kustomize制作的配置文件,为controller提供标准配置,也可以按需要去修改调整;
  4. config/manager:一些和manager有关的细节配置,例如镜像的资源限制;
  5. config/rbac:如果需要限制operator在kubernetes中的操作权限,就要通过rbac来做精细的权限配置了

main.go是程序的入口,初始化了Manager,由manager来管理api和controller

img

我们现在捋一下,k8s接收crd资源描述,crd被我们将要编写的controllrt控制。那么manager是什么

manager是用来管理controller的控制器,代码的主要功能就是启动controller,并使多个controller共存

下面我们继续创建crd文件和对应的controller代码

创建crd文件和controller

创建api的命令如下:但先别急着执行

1
kubebuilder create api --group tutorial --version v1 --kind Demo
1
2
3
4
5
也就是常说的GVK
1)group参数表示组的概念
2)version定义版本
3)kind定义自定义资源类型
4)以上参数组成了自定义资源的yaml 的 apiVersion和kind

如果直接执行,你可能会遇到这个错误

image-20240129164353991

原因是

在执行过程中,会根据Makefile来执行操作。

其中有一步是使用controller-gen来生成代码

image-20240129164517895

这里寻找controller-gen的路径是$(shell pwd)/bin/controller-gen

并不是我之前安装的controller-gen路径,所以需要修改以下。

否则找不到,就会去下载,但是我当前工作目录下并没有bin目录。会失败

改成

1
CONTROLLER_GEN = controller-gen

因为我上一篇准备工作,已经放到全局可执行了。

同理,把kustomize也顺手改掉,后面的make会用到

image-20240129164933847

1
KUSTOMIZE = kustomize

现在执行一下创建命令

image-20240129165802014

执行成功之后,查看下目录

image-20240129165924556

可以看到,kubebuilder自动为我们创建了几个关键的目录和文件

  • api/v1 :对应于创建时指定的version v1。 名字demo对应我们创建时指定的Kind
  • config/crd
  • controllers

我们查看几个重要的文件

  1. 在PROJECT文件中新增了API资源声明

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    domain: demo.com
    layout:
    - go.kubebuilder.io/v3
    projectName: demo-operator
    repo: demo.com/tutorial
    resources:
    - api:
    crdVersion: v1
    namespaced: true
    controller: true
    domain: demo.com
    group: tutorial
    kind: Demo
    path: demo.com/tutorial/api/v1
    version: v1
    version: "3"

  2. 新增了api目录,包含crd的类型定义

  3. 新增了crd目录,是crd的描述文件

  4. 在rbac目录中新增了对应的role文件

  5. 新增controller目录,包含controller文件

  6. 还有一个不容易发现的修改点是main.go文件

    1
    2
    3
    4
    5
    6
    7
    if err = (&controllers.DemoReconciler{
    Client: mgr.GetClient(),
    Scheme: mgr.GetScheme(),
    }).SetupWithManager(mgr); err != nil {
    setupLog.Error(err, "unable to create controller", "controller", "Demo")
    os.Exit(1)
    }

    注册了我们的controller

一些不重要的文件

可以看到在api下还有两个文件

  • groupversion_info.go
  • zz_generated.deepcopy.go

这两个文件都不需要去修改。groupversion_info是一些group和version信息,zz_generated.deepcopy.go是会自动生成的。

kubebuilder(三)实现operator

在前面的文章我们已经了解了operator项目的基本结构。现在我们来写一点简单的代码,然后把我们的crd和operator部署到k8s集群中。

需求

这是一个真实的需求,只不过做了简化。

在开发公司自己的paas平台,有一个需求是,用户在发版的时候,只需要在页面上填几个字段,我们在k8s中自动拉起service和deployment等资源,屏蔽k8s的底层技术对上层用户的困扰。

我们这里只要让用户填一下 业务名,镜像地址和副本数。

定义API

修改api目录下的demo_types.go文件,这个文件定义了我们的CRD中spec可用的字段。

注意: json 标签是必需的。为了能够序列化字段,任何你添加的新的字段一定有json标签。

image-20240129171326962

1
2
3
4
5
6
7
8
type DemoSpec struct {
// +kubebuilder:validation:Required
Image string `json:"image,omitempty"`
// +kubebuilder:validation:Required
SvcName string `json:"svcName,omitempty"`
// +kubebuilder:validation:Required
Replicas *int32 `json:"replicas,omitempty"`
}

然后定义下资源的status

1
2
3
type DemoStatus struct {
Replicas *int32 `json:"replicas,omitempty"`
}

每次修改API定义后,需要执行命令自动重新生成CRD定义代码

1
# make manifests

image-20240130112827332

可以看到生成了我们的crd

实现controller

kubebuilder已经很贴心的告诉了我们代码应该写在哪

image-20240129172302802

代码流程

根据crd资源创建service和deployment

如果修改ctd中的replicas,同样触发deployment的变更

代码比较长,放在github上了

https://github.com/jedyang/demo/tree/master/kubebuilder

这里先不开发代码也是可以的,先打几行日志,把流程跑通

默认情况下,Reconcile方法返回错误就会触发再次循环。

配置监听

我们写完了Reconcile(),那么什么时候这个Reconcile会得到执行呢?

这就要看SetupWithManager()方法

SetupWithManager方法,就是用于添加我们关心哪些资源的变动。

默认生成的是这样的

1
2
3
4
5
func (r *DemoReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
For(&tutorialv1.Demo{}).
Complete(r)
}

表示监听我们自定义的这个tutorialv1.Demo资源。也就是我们在k8s中只要这个crd的变动,就会触发我们的Reconcile()方法

如果修改为

1
2
3
4
5
6
7
8
9
10
11
12
13
import (
...
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
)
func (r *DemoReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
For(&tutorialv1.Demo{}).
Owns(&corev1.Pod{}).
Owns(&corev1.Service{}).
Owns(&appsv1.Deployment{}).
Complete(r)
}

就是对任何tutorialv1.Demo或Service、Deployment、Pod的变化,我们的Controller都会监听到,并生成事件,触发Reconcile()方法。

开发参考资源

kubebuilder官方手册:https://book.kubebuilder.io/introduction.html

kubenetes api文档:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.21/

https://kubernetes.io/docs/reference/kubernetes-api/

make manifests 用于生成yaml资源文件

make generate 用于生成代码相关的

image-20240321141542423

kubebuilder(一)开发环境搭建

开发一个k8s operator,当然可以在官方原生的controller-runtime 项目上从头构建,但是比较复杂。现在一般基于operator脚手架进行开发。目前最流行的的脚手架是Kubebuilder 或 OperatorSDK。Kubebuilder 或 OperatorSDK都是对controller-runtime 项目进行了上层的封装,使开发者可以专注于业务逻辑的实现。这里讲解kubebuilder的使用步骤。

首选需要一个可用的K8S集群。然后有一台linux服务器,能部署kubebuilder

image-20221221155300941

kubectl的配置

下载

1
curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl

给文件可执行权限;

1
chmod +x ./kubectl

将kubectl移动到可以全局执行的目录下:

1
mv ./kubectl /usr/local/bin/kubectl

kubectl要想连接k8s集群,还需要一个k8s的config文件。就在k8s集群的/root/.kube/目录下。复制到我们的kubebuilder服务器上同样目录下。

现在我们在kubebuilder服务器上也可以操作k8s了。

部署kubebuilder

各个组件的版本

go 1.18.5

docker 19.03.0

安装go

安装一些必要的工具

1
yum install unzip tree wget gcc gcc-c++ kernel-devel -y

安装go

安装官网安装的https://golang.google.cn/doc/install

额外执行以下命令

1
2
$ go env -w GO111MODULE=on
$ go env -w GOPROXY=https://goproxy.cn,direct

安装docker

安装kustomize

后面的操作中需要使用kustomize去做配置管理。

kustomize允许用户将不同环境所共享的配置放在一个文件目录下,而将其他不同的配置放在另外的目录下。这样用户就可以很容易的区分那些值是当前环境所特有的,从而在修改的时候会额外关注。

官方给出的安装方式,因为网络问题安装失败

基于模板生成YAML文件,下载kustomize二进制压缩包:https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize/v3.8.1/kustomize_v3.8.1_linux_amd64.tar.gz

1
2
3
4
5
6
# 解压并安装
$ tar zxvf kustomize_v3.8.1_linux_amd64.tar.gz
$ chmod +x kustomize
$ mv kustomize /usr/local/bin/
$ kustomize version
{Version:kustomize/v3.8.1 GitCommit:0b359d0ef0272e6545eda0e99aacd63aef99c4d0 BuildDate:2020-07-16T00:58:46Z GoOs:linux GoArch:amd64}

安装controller-gen

下载源码,编译安装

1
2
3
4
5
6
7
wget https://github.com/kubernetes-sigs/controller-tools/archive/refs/tags/v0.10.0.zip
$ unzip v0.10.0.zip
$ cd controller-tools-0.10.0
$ go build -a -o controller-gen cmd/controller-gen/main.go
$ mv controller-gen /usr/local/bin/
$ controller-gen --version
Version: (devel)

安装kubebuilder

1
2
3
4
# go env GOOS -- 获取操作系统类型,例如:linux等
# go env GOARCH -- 获取系统架构,例如:arm或amd64等
$ curl -L -o kubebuilder https://go.kubebuilder.io/dl/latest/$(go env GOOS)/$(go env GOARCH)
$ chmod +x kubebuilder && mv kubebuilder /usr/local/bin/

安装完成,查看下版本

1
2
# kubebuilder version
Version: main.version{KubeBuilderVersion:"3.2.0", KubernetesVendor:"1.22.1", GitCommit:"b7a730c84495122a14a0faff95e9e9615fffbfc5", BuildDate:"2021-10-29T18:32:16Z", GoOs:"linux", GoArch:"amd64"}

krew

之前的文章用到一个安装命令

1
kubectl krew install ns

用到了krew来安装ns插件。

krew 是一个用来管理 kubectl 插件的工具,类似于 apt 或 yum,支持搜索、安装和管理kubectl 插件。

安装krew

安装命令:

1
2
3
4
5
6
7
set -x; cd "$(mktemp -d)" &&
OS="$(uname | tr '[:upper:]' '[:lower:]')" &&
ARCH="$(uname -m | sed -e 's/x86_64/amd64/' -e 's/\(arm\)\(64\)\?.*/\1\2/' -e 's/aarch64$/arm64/')" &&
KREW="krew-${OS}_${ARCH}" &&
curl -fsSLO "https://github.com/kubernetes-sigs/krew/releases/latest/download/${KREW}.tar.gz" &&
tar zxvf "${KREW}.tar.gz" &&
./"${KREW}" install krew

生效

1
2
echo 'export PATH="${KREW_ROOT:-$HOME/.krew}/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

验证安装成功

1
2
3
4
[root@paas-m-k8s-master-1 ~]# kubectl plugin list
The following compatible plugins are available:

/root/.krew/bin/kubectl-krew

krew命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@paas-m-k8s-master-1 ~]# kubectl krew
krew is the kubectl plugin manager.
You can invoke krew through kubectl: "kubectl krew [command]..."

Usage:
kubectl krew [command]

Available Commands:
help Help about any command
index Manage custom plugin indexes
info Show information about an available plugin
install Install kubectl plugins
list List installed kubectl plugins
search Discover kubectl plugins
uninstall Uninstall plugins
update Update the local copy of the plugin index
upgrade Upgrade installed plugins to newer versions
version Show krew version and diagnostics

比较简单,命令参数不多。

搜素

image-20240311170020039

安装

1
kubectl krew install ns

查看安装

1
2
3
4
5
[root@paas-m-k8s-master-1 ~]# kubectl krew list
PLUGIN VERSION
krew v0.4.4
ns v0.9.5

使用

image-20240311170129602

卸载、升级不演示了

目前的插件列表

Kubectl plugins available · Krew (k8s.io)

不算太多,二百多个。

有一些还是挺方便的。

比如tail,可以用来方便的打印pod或者ns下的所有pod,或者deploymeng,sts等的日志

现在更推荐使用krew来安装和管理kubectl命令插件,而不是直接安装安装包。

kube-ovn

ovs跟calico等有啥区别?

A6: calico 主要依赖 linux 的路由功能做网络打通,ovs 是在软件交换机层面实现网络打通,并提供了更丰富的网络功能

overlay 和 underlay

这两个是相对的概念。underlay就是指普通的组网,可以是二层也可以是三层网络。

overlay就是在正常网络之上的一层虚拟逻辑网络。相互连接的Overlay设备之间建立隧道,数据包准备传输出去时,设备为数据包添加新的IP头部和隧道头部,并且被屏蔽掉内层的IP头部,数据包根据新的IP头部进行转发。当数据包传递到另一个设备后,外部的IP报头和隧道头将被丢弃,得到原始的数据包,在这个过程中Overlay网络并不感知Underlay网络。

也就是说,报文进行了二次封装,这就是overlay网络了

kube-prometheus-stack

使用helm安装Prometheus

kube-prometheus-stack 20.0.1 · prometheus/prometheus-community (artifacthub.io)

步骤

  1. 加仓库
1
2
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
  1. 安装

查看版本

1
helm search repo kube-prometheus-stack -l

拉取chart,就用目前的最新版本吧

1
helm pull prometheus-community/kube-prometheus-stack --version 20.0.1

报错

unknown field “alertmanagerConfigSelector”

Error: unable to build kubernetes objects from release manifest: error validating “”: error validating data: [ValidationError(Alertmanager.spec): unknown field “alertmanagerConfigNamespaceSelector” in com.coreos.monitoring.v1.Alertmanager.spec, ValidationError(Alertmanager.spec): unknown field “alertmanagerConfigSelector” in com.coreos.monitoring.v1.Alertmanager.spec]

猜测原因:

1
2
3
4
5
6
7
8
9
[root@paas-m-k8s-master-1 kube-prometheus-stack]# kubectl get crd | grep coreos
alertmanagerconfigs.monitoring.coreos.com 2021-11-11T07:38:39Z
alertmanagers.monitoring.coreos.com 2021-07-14T01:13:12Z
podmonitors.monitoring.coreos.com 2021-07-14T01:13:12Z
probes.monitoring.coreos.com 2021-07-15T09:16:21Z
prometheuses.monitoring.coreos.com 2021-07-14T01:13:12Z
prometheusrules.monitoring.coreos.com 2021-07-14T01:13:12Z
servicemonitors.monitoring.coreos.com 2021-07-14T01:13:12Z
thanosrulers.monitoring.coreos.com 2021-07-14T01:13:12Z

以前不知道什么时候装的crd版本相对于当前最新的prometheus来说太老了

按照Readme里说的卸载

1
2
3
4
5
6
7
8
kubectl delete crd alertmanagerconfigs.monitoring.coreos.com
kubectl delete crd alertmanagers.monitoring.coreos.com
kubectl delete crd podmonitors.monitoring.coreos.com
kubectl delete crd probes.monitoring.coreos.com
kubectl delete crd prometheuses.monitoring.coreos.com
kubectl delete crd prometheusrules.monitoring.coreos.com
kubectl delete crd servicemonitors.monitoring.coreos.com
kubectl delete crd thanosrulers.monitoring.coreos.com

卸载后再次安装,ok

镜像pull failed

k8s.gcr.io/ingress-nginx/kube-webhook-certgen 下不下来