云原生学习路线导航页(持续更新中)
- 本文是 Kubernetes operator学习 系列第七篇,对 目前编写Operator的常用脚手架 kubebuilder 进行学习,主要涉及 ** kubebuilder 的安装及简单使用**,kubebuilder的原理会在后续介绍
- 基于 kubernetes v1.24.0 代码分析
- Kubernetes operator学习系列 快捷链接
- Kubernetes operator(一)client-go篇
- Kubernetes operator(二)CRD篇
- Kubernetes operator(三)code-generator 篇
- Kubernetes operator(四)controller-tools 篇
- Kubernetes operator(五)api 和 apimachinery 篇
- Kubernetes operator(六)CRD控制器 开发实战篇
- Kubernetes operator(七) kubebuilder 的安装及简单使用 篇
- Kubernetes operator(八) controller-runtime 篇
controller-runtime
和 controller-tools
两个库的基础上开发的kubebuidler 的 github 仓库
kubebuilder的官方文档
推荐书籍
# download kubebuilder and install locally.
curl -L -o kubebuilder "https://go.kubebuilder.io/dl/latest/$(go env GOOS)/$(go env GOARCH)"
chmod +x kubebuilder && mv kubebuilder /usr/local/bin/
curl -L -o kubebuilder "https://go.kubebuilder.io/dl/master/$(go env GOOS)/$(go env GOARCH)"
chmod +x kubebuilder && mv kubebuilder /usr/local/bin/
curl: (35) Encountered end of file
。此时推荐使用安装方法二wget https://github.com/kubernetes-sigs/kubebuilder/releases/download/v3.14.0/kubebuilder_linux_amd64
mv kubebuilder_linux_amd64 kubebuilder
chmod +x kubebuilder && mv kubebuilder /usr/local/bin/
[root@master test]# kubebuilder version
Version: main.version{KubeBuilderVersion:"3.14.0", KubernetesVendor:"1.27.1", GitCommit:"11053630918ac421cb6eb6f0a3225e2a2ad49535", BuildDate:"2024-01-30T09:29:27Z", GoOs:"linux", GoArch:"amd64"}
kubebuilder init --domain my.domain --repo my.domain/guestbook
--domain
:指定自定义资源的 API 组的域名,通常是域名的反向形式,例如 domain.com 反转后为 com.domain--repo
:指定项目代码的存储库位置go get controller-runtime
和 go mod tidy
kubebuilder create api
[root@master guestbook]# kubebuilder init --domain my.domain --repo my.domain/guestbook
INFO Writing kustomize manifests for you to edit...
INFO Writing scaffold for you to edit...
INFO Get controller runtime:
$ go get sigs.k8s.io/[email protected]
INFO Update dependencies:
$ go mod tidy
Next: define a resource with:
$ kubebuilder create api
[root@master guestbook]# tree
.
├── cmd
│ └── main.go
├── config
│ ├── default
│ │ ├── kustomization.yaml
│ │ ├── manager_auth_proxy_patch.yaml
│ │ └── manager_config_patch.yaml
│ ├── manager
│ │ ├── 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
│ ├── role.yaml
│ └── service_account.yaml
├── Dockerfile
├── go.mod
├── go.sum
├── hack
│ └── boilerplate.go.txt
├── Makefile
├── PROJECT
├── README.md
└── test
├── e2e
│ ├── e2e_suite_test.go
│ └── e2e_test.go
└── utils
└── utils.go
10 directories, 28 files
guestbook
,但是从目录上看,还没有创建Operator相关的CRD资源和ControllerGV(Group Version)
,然后为该GV创建一个 Kind
webapp/v1/Guestbook
kubebuilder create api --group webapp --version v1 --kind Guestbook
[root@master guestbook]# kubebuilder create api --group webapp --version v1 --kind Guestbook
INFO Create Resource [y/n]
y
INFO Create Controller [y/n]
y
INFO Writing kustomize manifests for you to edit...
INFO Writing scaffold for you to edit...
INFO api/v1/guestbook_types.go
INFO api/v1/groupversion_info.go
INFO internal/controller/suite_test.go
INFO internal/controller/guestbook_controller.go
INFO internal/controller/guestbook_controller_test.go
INFO Update dependencies:
$ go mod tidy
INFO Running make:
$ make generate
mkdir -p /root/zgy/project/guestbook/bin
Downloading sigs.k8s.io/controller-tools/cmd/[email protected]
/root/zgy/project/guestbook/bin/controller-gen-v0.14.0 object:headerFile="hack/boilerplate.go.txt" paths="./..."
Next: implement your new API and generate the manifests (e.g. CRDs,CRs) with:
$ make manifests
[root@master guestbook]# tree
.
├── api
│ └── v1
│ ├── groupversion_info.go
│ ├── guestbook_types.go
│ └── zz_generated.deepcopy.go
├── bin
│ └── controller-gen-v0.14.0
├── cmd
│ └── main.go
├── config
│ ├── crd
│ │ ├── kustomization.yaml
│ │ └── kustomizeconfig.yaml
│ ├── default
│ │ ├── kustomization.yaml
│ │ ├── manager_auth_proxy_patch.yaml
│ │ └── manager_config_patch.yaml
│ ├── manager
│ │ ├── 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
│ │ ├── guestbook_editor_role.yaml
│ │ ├── guestbook_viewer_role.yaml
│ │ ├── kustomization.yaml
│ │ ├── leader_election_role_binding.yaml
│ │ ├── leader_election_role.yaml
│ │ ├── role_binding.yaml
│ │ ├── role.yaml
│ │ └── service_account.yaml
│ └── samples
│ ├── kustomization.yaml
│ └── webapp_v1_guestbook.yaml
├── Dockerfile
├── go.mod
├── go.sum
├── hack
│ └── boilerplate.go.txt
├── internal
│ └── controller
│ ├── guestbook_controller.go
│ ├── guestbook_controller_test.go
│ └── suite_test.go
├── Makefile
├── PROJECT
├── README.md
└── test
├── e2e
│ ├── e2e_suite_test.go
│ └── e2e_test.go
└── utils
└── utils.go
17 directories, 41 files
// GuestbookSpec defines the desired state of Guestbook
type GuestbookSpec struct {
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
// Important: Run "make" to regenerate code after modifying this file
// Quantity of instances
// +kubebuilder:validation:Minimum=1
// +kubebuilder:validation:Maximum=10
Size int32 `json:"size"`
// Name of the ConfigMap for GuestbookSpec's configuration
// +kubebuilder:validation:MaxLength=15
// +kubebuilder:validation:MinLength=1
ConfigMapName string `json:"configMapName"`
// +kubebuilder:validation:Enum=Phone;Address;Name
Type string `json:"alias,omitempty"`
}
// GuestbookStatus defines the observed state of Guestbook
type GuestbookStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make" to regenerate code after modifying this file
// PodName of the active Guestbook node.
Active string `json:"active"`
// PodNames of the standby Guestbook nodes.
Standby []string `json:"standby"`
}
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:resource:scope=Cluster
// Guestbook is the Schema for the guestbooks API
type Guestbook struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec GuestbookSpec `json:"spec,omitempty"`
Status GuestbookStatus `json:"status,omitempty"`
}
api/v1/guestbook_types.go
make manifests
命令就可以生成[root@master guestbook]# make manifests
/root/zgy/project/guestbook/bin/controller-gen-v0.14.0 rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases
api/v1/guestbook_types.go
,就一定要执行一下 make manifests
Kind 的 types结构文件编写好,并且 Controller 开发完毕后,再次执行:make manifests
,重新生成一下 资源清单
将CRD安装到当前 kubernetes-cluster 中
make install
输出如下:
[root@master guestbook]# make install
/root/zgy/project/guestbook/bin/controller-gen-v0.14.0 rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases
Downloading sigs.k8s.io/kustomize/kustomize/[email protected]
go: downloading sigs.k8s.io/kustomize/kustomize/v5 v5.3.0
go: downloading sigs.k8s.io/kustomize/api v0.16.0
go: downloading sigs.k8s.io/kustomize/cmd/config v0.13.0
go: downloading sigs.k8s.io/kustomize/kyaml v0.16.0
go: downloading github.com/go-errors/errors v1.4.2
go: downloading golang.org/x/exp v0.0.0-20231006140011-7918f672742d
go: downloading golang.org/x/text v0.13.0
go: downloading k8s.io/kube-openapi v0.0.0-20230601164746-7562a1006961
go: downloading github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00
go: downloading github.com/xlab/treeprint v1.2.0
go: downloading github.com/imdario/mergo v0.3.13
go: downloading gopkg.in/evanphx/json-patch.v5 v5.6.0
go: downloading google.golang.org/protobuf v1.30.0
go: downloading go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5
go: downloading github.com/google/go-cmp v0.5.9
go: downloading github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
/root/zgy/project/guestbook/bin/kustomize-v5.3.0 build config/crd | kubectl apply -f -
customresourcedefinition.apiextensions.k8s.io/guestbooks.webapp.my.domain created
可以看到,最后一句输出:customresourcedefinition.apiextensions.k8s.io/guestbooks.webapp.my.domain created
。即这个crd被创建
验证结果
[root@master guestbook]# kubectl get crds
NAME CREATED AT
guestbooks.webapp.my.domain 2024-03-02T15:23:02Z
make run
[root@master guestbook]# make run
\/root/zgy/project/guestbook/bin/controller-gen-v0.14.0 rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases
/root/zgy/project/guestbook/bin/controller-gen-v0.14.0 object:headerFile="hack/boilerplate.go.txt" paths="./..."
go fmt ./...
api/v1/guestbook_types.go
go vet ./...
go run ./cmd/main.go
2024-03-02T23:42:47+08:00 INFO setup starting manager
2024-03-02T23:42:47+08:00 INFO controller-runtime.metrics Starting metrics server
2024-03-02T23:42:47+08:00 INFO controller-runtime.metrics Serving metrics server {"bindAddress": ":8080", "secure": false}
2024-03-02T23:42:47+08:00 INFO starting server {"kind": "health probe", "addr": "[::]:8081"}
2024-03-02T23:42:47+08:00 INFO Starting EventSource {"controller": "guestbook", "controllerGroup": "webapp.my.domain", "controllerKind": "Guestbook", "source": "kind source: *v1.Guestbook"}
2024-03-02T23:42:47+08:00 INFO Starting Controller {"controller": "guestbook", "controllerGroup": "webapp.my.domain", "controllerKind": "Guestbook"}
2024-03-02T23:42:47+08:00 INFO Starting workers {"controller": "guestbook", "controllerGroup": "webapp.my.domain", "controllerKind": "Guestbook", "worker count": 1}
apiVersion: webapp.my.domain/v1
kind: Guestbook
metadata:
labels:
app.kubernetes.io/name: guestbook
app.kubernetes.io/instance: guestbook-sample
app.kubernetes.io/part-of: guestbook
app.kubernetes.io/managed-by: kustomize
app.kubernetes.io/created-by: guestbook
name: guestbook-sample
spec:
size: 1
configMapName: cm-test
alias: Phone
[root@master samples]# kubectl apply -f config/samples/webapp_v1_guestbook.yaml
guestbook.webapp.my.domain/guestbook-sample created
[root@master samples]# kubectl get guestbook
NAME AGE
guestbook-sample 7m5s
# 命令格式
make docker-build docker-push IMG=<some-registry>/<project-name>:tag
gesang321/guestbook
[root@master guestbook]# make docker-build docker-push IMG=gesang321/guestbook:v1
docker build --network host -t gesang321/guestbook:v1 .
Sending build context to Docker daemon 132.6kB
Step 1/18 : FROM golang:1.21 AS builder
---> 603d8d7f7de0
Step 2/18 : ARG TARGETOS
---> Using cache
---> 482316cd42d0
Step 3/18 : ARG TARGETARCH
---> Using cache
---> be05abbe45e6
Step 4/18 : ENV GO111MODULE=on
---> Using cache
---> aa0c0397e236
Step 5/18 : ENV GOPROXY=https://goproxy.cn
---> Using cache
---> 9d532d2a3eda
Step 6/18 : WORKDIR /workspace
---> Using cache
---> 7bb2c0d4524b
Step 7/18 : COPY go.mod go.mod
---> Using cache
---> 65d463ab60d2
Step 8/18 : COPY go.sum go.sum
---> Using cache
---> 97a850a41214
Step 9/18 : RUN go mod download
---> Using cache
---> 962faccef7ba
Step 10/18 : COPY cmd/main.go cmd/main.go
---> Using cache
---> a91aaa2fe247
Step 11/18 : COPY api/ api/
---> Using cache
---> d52a03f7523e
Step 12/18 : COPY internal/controller/ internal/controller/
---> Using cache
---> 2daac03cea36
Step 13/18 : RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o manager cmd/main.go
---> Using cache
---> 0e03838a9253
Step 14/18 : FROM gcr.io/distroless/static:nonroot
---> 51a1a0f285f9
Step 15/18 : WORKDIR /
---> Running in 697a5679fbb1
Removing intermediate container 697a5679fbb1
---> 4e153340a2ca
Step 16/18 : COPY --from=builder /workspace/manager .
---> c08825e79d7e
Step 17/18 : USER 65532:65532
---> Running in 29e184d23ba2
Removing intermediate container 29e184d23ba2
---> d202f2ddf6c0
Step 18/18 : ENTRYPOINT ["/manager"]
---> Running in 2a0ac6725a8c
Removing intermediate container 2a0ac6725a8c
---> 7bf4b9ede810
Successfully built 7bf4b9ede810
Successfully tagged gesang321/guestbook:v1
docker push gesang321/guestbook:v1
The push refers to repository [docker.io/gesang321/guestbook]
31ac0a0f7a4f: Pushed
be245a236de8: Mounted from katanomi/distroless-static
00af80914b10: Mounted from katanomi/distroless-static
67c1a9e72017: Mounted from katanomi/distroless-static
v1: digest: sha256:47331b3faf3aee3619454ab6c21a98d1a441c8561613f247a7f52889a769def9 size: 1156
go: github.com/beorn7/[email protected]: Get "https://proxy.golang.org/github.com/beorn7/perks/@v/v1.0.1.mod": dial tcp 142.250.72.145:443: connect: connection refused
[root@master guestbook]# make docker-build docker-push IMG=gesang321/guestbook:v1
docker build -t gesang321/guestbook:v1 .
Sending build context to Docker daemon 132.6kB
Step 1/16 : FROM golang:1.21 AS builder
---> 603d8d7f7de0
Step 2/16 : ARG TARGETOS
---> Using cache
---> 482316cd42d0
Step 3/16 : ARG TARGETARCH
---> Using cache
---> be05abbe45e6
Step 4/16 : WORKDIR /workspace
---> Using cache
---> d9122045a4a3
Step 5/16 : COPY go.mod go.mod
---> Using cache
---> b9d3a8104258
Step 6/16 : COPY go.sum go.sum
---> Using cache
---> 5464452ac3dc
Step 7/16 : RUN go mod download
---> Running in 29475cc7a5bd
# Build the manager binary
FROM golang:1.21 AS builder
ARG TARGETOS
ARG TARGETARCH
# 就是加上这两句,设置一下go的国内代理加速
ENV GO111MODULE=on
ENV GOPROXY=https://goproxy.cn
WORKDIR /workspace
# Copy the Go Modules manifests
COPY go.mod go.mod
COPY go.sum go.sum
......
--network host
,这是让我们的机器使用主机网络,能够连接外网# If you wish to build the manager image targeting other platforms you can use the --platform flag.
# (i.e. docker build --platform linux/arm64). However, you must enable docker buildKit for it.
# More info: https://docs.docker.com/develop/develop-images/build_enhancements/
.PHONY: docker-build
docker-build: ## Build docker image with the manager.
$(CONTAINER_TOOL) build --network host -t ${IMG} .
make docker-build docker-push IMG=gesang321/guestbook:v1
Step 13/18 : RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o manager cmd/main.go
---> Using cache
---> 0e03838a9253
gcr.io/distroless/static:nonroot
,改了名称后上传到了dockerhubgcr.io/distroless/static:nonroot
gcr.io/distroless/static:nonroot
,自然就不会报错了[root@master guestbook]# docker pull katanomi/distroless-static:nonroot
[root@master guestbook]# docker tag katanomi/distroless-static:nonroot gcr.io/distroless/static:nonroot
[root@master guestbook]# docker images | grep gcr
gcr.io/distroless/static nonroot 51a1a0f285f9 19 months ago 2.97MB
make docker-build docker-push IMG=gesang321/guestbook:v1
# 命令格式
make deploy IMG=<some-registry>/<project-name>:tag
[root@master guestbook]# make deploy IMG=gesang321/guestbook:v1
/root/zgy/project/guestbook/bin/controller-gen-v0.14.0 rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases
cd config/manager && /root/zgy/project/guestbook/bin/kustomize-v5.3.0 edit set image controller=gesang321/guestbook:v1
/root/zgy/project/guestbook/bin/kustomize-v5.3.0 build config/default | kubectl apply -f -
namespace/guestbook-system created
customresourcedefinition.apiextensions.k8s.io/guestbooks.webapp.my.domain unchanged
serviceaccount/guestbook-controller-manager created
role.rbac.authorization.k8s.io/guestbook-leader-election-role created
clusterrole.rbac.authorization.k8s.io/guestbook-manager-role created
clusterrole.rbac.authorization.k8s.io/guestbook-metrics-reader created
clusterrole.rbac.authorization.k8s.io/guestbook-proxy-role created
rolebinding.rbac.authorization.k8s.io/guestbook-leader-election-rolebinding created
clusterrolebinding.rbac.authorization.k8s.io/guestbook-manager-rolebinding created
clusterrolebinding.rbac.authorization.k8s.io/guestbook-proxy-rolebinding created
service/guestbook-controller-manager-metrics-service created
deployment.apps/guestbook-controller-manager created
guestbook-system
的namespaceguestbook-controller-manager
的 deployment[root@master guestbook]# kubectl get deploy -n guestbook-system
NAME READY UP-TO-DATE AVAILABLE AGE
guestbook-controller-manager 1/1 1 0 26m
[root@master guestbook]# kubectl get pods -n guestbook-system
NAME READY STATUS RESTARTS AGE
guestbook-controller-manager-6475ff77d-kqsfv 2/2 Running 0 28m
ImagePullBackOff
gcr.io/kubebuilder/kube-rbac-proxy
镜像拉取失败[root@master guestbook]# kubectl describe pods -n guestbook-system guestbook-controller-manager-6475ff77d-kqsfv
......
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled <unknown> default-scheduler Successfully assigned guestbook-system/guestbook-controller-manager-6475ff77d-kqsfv to master
Normal Pulled 2m15s kubelet, master Container image "gesang321/guestbook:v1" already present on machine
Normal Created 2m15s kubelet, master Created container manager
Normal Started 2m15s kubelet, master Started container manager
Warning Failed 59s (x3 over 2m15s) kubelet, master Failed to pull image "gcr.io/kubebuilder/kube-rbac-proxy:v0.15.0": rpc error: code = Unknown desc = Error response from daemon: Get https://gcr.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
Warning Failed 59s (x3 over 2m15s) kubelet, master Error: ErrImagePull
Normal BackOff 19s (x6 over 2m15s) kubelet, master Back-off pulling image "gcr.io/kubebuilder/kube-rbac-proxy:v0.15.0"
Warning Failed 19s (x6 over 2m15s) kubelet, master Error: ImagePullBackOff
Normal Pulling 5s (x4 over 2m31s) kubelet, master Pulling image "gcr.io/kubebuilder/kube-rbac-proxy:v0.15.0"
config/default/manager_auth_proxy_patch.yaml
文件image: gcr.io/kubebuilder/kube-rbac-proxy:v0.15.0
改成 image: kubebuilder/kube-rbac-proxy:v0.15.0
,这是dockerhub上一个国内可访问的镜像kubebuilder/kube-rbac-proxy:v0.15.0
,再把它的名称改成 gcr 的,这样 make deploy 的时候,就会在本地找到镜像,以为是自己需要的[root@master guestbook]# docker pull kubebuilder/kube-rbac-proxy:v0.15.0
v0.15.0: Pulling from kubebuilder/kube-rbac-proxy
07a64a71e011: Pull complete
fe5ca62666f0: Pull complete
b02a7525f878: Pull complete
fcb6f6d2c998: Pull complete
e8c73c638ae9: Pull complete
1e3d9b7d1452: Pull complete
4aa0ea1413d3: Pull complete
7c881f9ab25e: Pull complete
5627a970d25e: Pull complete
c9c9ec7a3926: Pull complete
Digest: sha256:a3768b8f9d259df714ebbf176798c380f4d929216e656dc30754eafa03a74c41
Status: Downloaded newer image for kubebuilder/kube-rbac-proxy:v0.15.0
[root@master guestbook]# docker tag kubebuilder/kube-rbac-proxy:v0.15.0 gcr.io/kubebuilder/kube-rbac-proxy:v0.15.0
make deploy
命令make uninstall
命令卸载CRD资源make uninstall
的批处理命令,是guestbook目录下的 Makefile 提供的,必须在guestbook目录下执行[root@master guestbook]# make uninstall
/root/zgy/project/guestbook/bin/controller-gen-v0.14.0 rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases
/root/zgy/project/guestbook/bin/kustomize-v5.3.0 build config/crd | kubectl delete --ignore-not-found=false -f -
customresourcedefinition.apiextensions.k8s.io "guestbooks.webapp.my.domain" deleted
[root@master guestbook]# kubectl get crds
No resources found in default namespace.
[root@master project]# kubectl get guestbook
Error from server (NotFound): Unable to list "webapp.my.domain/v1, Resource=guestbooks": the server could not find the requested resource (get guestbooks.webapp.my.domain)
make undeploy
命令 卸载CRD资源,并删除controller对应的deploymake undeploy
的批处理命令,是guestbook目录下的 Makefile 提供的,必须在guestbook目录下执行[root@master guestbook]# make undeploy
/root/zgy/project/guestbook/bin/kustomize-v5.3.0 build config/default | kubectl delete --ignore-not-found=false -f -
namespace "guestbook-system" deleted
customresourcedefinition.apiextensions.k8s.io "guestbooks.webapp.my.domain" deleted
serviceaccount "guestbook-controller-manager" deleted
role.rbac.authorization.k8s.io "guestbook-leader-election-role" deleted
clusterrole.rbac.authorization.k8s.io "guestbook-manager-role" deleted
clusterrole.rbac.authorization.k8s.io "guestbook-metrics-reader" deleted
clusterrole.rbac.authorization.k8s.io "guestbook-proxy-role" deleted
rolebinding.rbac.authorization.k8s.io "guestbook-leader-election-rolebinding" deleted
clusterrolebinding.rbac.authorization.k8s.io "guestbook-manager-rolebinding" deleted
clusterrolebinding.rbac.authorization.k8s.io "guestbook-proxy-rolebinding" deleted
service "guestbook-controller-manager-metrics-service" deleted
deployment.apps "guestbook-controller-manager" deleted
[root@master guestbook]# kubectl get crds
No resources found in default namespace.
[root@master guestbook]# kubectl get deploy -A
NAMESPACE NAME READY UP-TO-DATE AVAILABLE AGE
default nginx 1/1 1 1 27d
kube-system coredns 2/2 2 2 27d
[root@master project]# kubectl get guestbook
Error from server (NotFound): Unable to list "webapp.my.domain/v1, Resource=guestbooks": the server could not find the requested resource (get guestbooks.webapp.my.domain)