kubernets controller 和 CRD的扩展
Kubernetes中文指南/云原生应用架构实践手册(201910)
(dlv) p pods
*k8s.io/api/core/v1.PodList {
TypeMeta: k8s.io/apimachinery/pkg/apis/meta/v1.TypeMeta {Kind: "", APIVersion: ""},
ListMeta: k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta {
SelfLink: "/api/v1/pods",
ResourceVersion: "145208",
Continue: "",},
Items: []k8s.io/api/core/v1.Pod len: 8, cap: 8, [
(*k8s.io/api/core/v1.Pod)(0xc00033a000),
(*k8s.io/api/core/v1.Pod)(0xc00033a360),
(*k8s.io/api/core/v1.Pod)(0xc00033a6c0),
(*k8s.io/api/core/v1.Pod)(0xc00033aa20),
(*k8s.io/api/core/v1.Pod)(0xc00033ad80),
(*k8s.io/api/core/v1.Pod)(0xc00033b0e0),
(*k8s.io/api/core/v1.Pod)(0xc00033b440),
(*k8s.io/api/core/v1.Pod)(0xc00033b7a0),
],}
从运行流程和list-watch看kubernetes系统的设计理念
如何基于Kubernetes开发自定义的Controller
Kubernetes CRD (CustomResourceDefinition) 自定义资源类型
kubernetes系列之十四:Kubernetes CRD(CustomResourceDefinition)概览
kubernetes系列之十六:Kubernetes CRD sample-controller的编译和测试
This Picture from this blog and official doc
Analyzing value of Operator Framework for Kubernetes community
Install GO:
wget -O- https://raw.githubusercontent.com/udhos/update-golang/master/update-golang.sh | sudo bash export PATH=$PATH:/usr/local/go/bin go env |grep GOPATH >> ~/.profile
go env |grep GOROOT >> ~/.profile
echo "export GOPATH" >> ~/.profile
echo "export GOROOT " >> ~/.profile
echo "export PATH=\$PATH:/usr/local/go/bin:$GOPATH/bin:$GOROOT/bin" >> ~/.profile source ~/.profile
install sample:
go get github.com/tools/godep
cd $GOPATH/src
git clone https://github.com/kubernetes/sample-controller.git
cd sample-controller
godep restore
cd $GOPATH/src/k8s.io/sample-controller
go build -o sample-controller .
debug:
go get github.com/derekparker/delve/cmd/dlv
dlv exec ./sample-controller -- -kubeconfig=$HOME/.kube/config
分析:
main.go
1. 获取配置信息(构建client使用)
clientcmd.BuildConfigFromFlags(masterURL, kubeconfig)
从"/home/ubuntu/.kube/config" 获取登陆的证书, key和CA
2. 生成一个client,来登陆api server
// "k8s.io/client-go/kubernetes"
kubeClient, err := kubernetes.NewForConfig(cfg)
3. 生成一个sample的client,用户来登陆controller
// clientset "k8s.io/sample-controller/pkg/client/clientset/versioned"
clientset.NewForConfig(cfg)
4. 分别生成 kubeInformerFactory 和 exampleInformerFactory
// kubeinformers "k8s.io/client-go/informers"
// informers "k8s.io/sample-controller/pkg/client/informers/externalversions"
// SharedInformerFactory a small interface to allow for adding an informer without an import cycle
type SharedInformerFactory interface {
Start(stopCh <-chan struct{})
InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer
}
// SharedInformerOption defines the functional option type for SharedInformerFactory.
type SharedInformerOption func(*sharedInformerFactory) *sharedInformerFactory type sharedInformerFactory struct {
client versioned.Interface
namespace string
tweakListOptions internalinterfaces.TweakListOptionsFunc
lock sync.Mutex
defaultResync time.Duration
customResync map[reflect.Type]time.Duration informers map[reflect.Type]cache.SharedIndexInformer
// startedInformers is used for tracking which informers have been started.
// This allows Start() to be called multiple times safely.
startedInformers map[reflect.Type]bool
}
SharedInformer具有共享数据缓存,并且能够将对缓存更改的通知分发给通过AddEventHandler注册的多个listeners。 如果使用此方法,则与标准Informer相比,有一个行为不同。 当您收到通知时,缓存将至少与通知一样的fresh,甚至更fresh。 您不应该依赖缓存的内容与处理函数中收到的通知完全匹配。 如果创建后紧接着是删除,则缓存可能没有这个条目了。 这比广播者有优势,因为它允许我们在多个控制器之间共享公共缓存。 扩展广播者需要我们为每个wach保留重复的缓存。
// SharedInformer has a shared data cache and is capable of distributing notifications for changes
// to the cache to multiple listeners who registered via AddEventHandler. If you use this, there is
// one behavior change compared to a standard Informer. When you receive a notification, the cache
// will be AT LEAST as fresh as the notification, but it MAY be more fresh. You should NOT depend
// on the contents of the cache exactly matching the notification you've received in handler
// functions. If there was a create, followed by a delete, the cache may NOT have your item. This
// has advantages over the broadcaster since it allows us to share a common cache across many
// controllers. Extending the broadcaster would have required us keep duplicate caches for each
// watch.
type SharedInformer interface {
// AddEventHandler adds an event handler to the shared informer using the shared informer's resync
// period. Events to a single handler are delivered sequentially, but there is no coordination
// between different handlers.
AddEventHandler(handler ResourceEventHandler)
// AddEventHandlerWithResyncPeriod adds an event handler to the shared informer using the
// specified resync period. Events to a single handler are delivered sequentially, but there is
// no coordination between different handlers.
AddEventHandlerWithResyncPeriod(handler ResourceEventHandler, resyncPeriod time.Duration)
// GetStore returns the Store.
GetStore() Store
// GetController gives back a synthetic interface that "votes" to start the informer
GetController() Controller
// Run starts the shared informer, which will be stopped when stopCh is closed.
Run(stopCh <-chan struct{})
// HasSynced returns true if the shared informer's store has synced.
HasSynced() bool
// LastSyncResourceVersion is the resource version observed when last synced with the underlying
// store. The value returned is not synchronized with access to the underlying store and is not
// thread-safe.
LastSyncResourceVersion() string
} type SharedIndexInformer interface {
SharedInformer
// AddIndexers add indexers to the informer before it starts.
AddIndexers(indexers Indexers) error
GetIndexer() Indexer
}
怀疑是代码自动生成的。
git grep "func NewSharedInformerFactory"
pkg/client/informers/externalversions/factory.go:func NewSharedInformerFactory(client versioned.Interface, defaultResync time.Duration) SharedInformerFactory {
pkg/client/informers/externalversions/factory.go:func NewSharedInformerFactoryWithOptions(client versioned.Interface, defaultResync time.Duration, options ...SharedInformerOption) SharedInformerFactory {
vendor/k8s.io/client-go/informers/factory.go:func NewSharedInformerFactory(client kubernetes.Interface, defaultResync time.Duration) SharedInformerFactory {
vendor/k8s.io/client-go/informers/factory.go:func NewSharedInformerFactoryWithOptions(client kubernetes.Interface, defaultResync time.Duration, options ...SharedInformerOption) SharedInformerFactory {
vendor/k8s.io/code-generator/_examples/MixedCase/informers/externalversions/factory.go:func NewSharedInformerFactory(client versioned.Interface, defaultResync time.Duration) SharedInformerFactory {
vendor/k8s.io/code-generator/_examples/MixedCase/informers/externalversions/factory.go:func NewSharedInformerFactoryWithOptions(client versioned.Interface, defaultResync time.Duration, options ...SharedInformerOption) SharedInformerFactory {
vendor/k8s.io/code-generator/_examples/apiserver/informers/externalversions/factory.go:func NewSharedInformerFactory(client versioned.Interface, defaultResync time.Duration) SharedInformerFactory {
vendor/k8s.io/code-generator/_examples/apiserver/informers/externalversions/factory.go:func NewSharedInformerFactoryWithOptions(client versioned.Interface, defaultResync time.Duration, options ...SharedInformerOption) SharedInformerFactory {
vendor/k8s.io/code-generator/_examples/apiserver/informers/internalversion/factory.go:func NewSharedInformerFactory(client internalversion.Interface, defaultResync time.Duration) SharedInformerFactory {
vendor/k8s.io/code-generator/_examples/apiserver/informers/internalversion/factory.go:func NewSharedInformerFactoryWithOptions(client internalversion.Interface, defaultResync time.Duration, options ...SharedInformerOption) SharedInformerFactory {
vendor/k8s.io/code-generator/_examples/crd/informers/externalversions/factory.go:func NewSharedInformerFactory(client versioned.Interface, defaultResync time.Duration) SharedInformerFactory {
vendor/k8s.io/code-generator/_examples/crd/informers/externalversions/factory.go:func NewSharedInformerFactoryWithOptions(client versioned.Interface, defaultResync time.Duration, options ...SharedInformerOption) SharedInformerFactory {
vendor/k8s.io/code-generator/cmd/informer-gen/generators/factory.go:func NewSharedInformerFactory(client {{.clientSetInterface|raw}}, defaultResync {{.timeDuration|raw}}) SharedInformerFactory {
vendor/k8s.io/code-generator/cmd/informer-gen/generators/factory.go:func NewSharedInformerFactoryWithOptions(client {{.clientSetInterface|raw}}, defaultResync {{.timeDuration|raw}}, options ...SharedInformerOption) SharedInformerFactory {
5. 生成 controller
"controller.go" 定义了Controller
低层定义见 pkg/client/informers/externalversions/samplecontroller/v1alpha1/foo.go
6. 运行 kubeInformerFactory, exampleInformerFactory 和 controller
(dlv) b k8s.io/sample-controller/pkg/client/informers/externalversions.(*sharedInformerFactory).Start
Breakpoint 5 set at 0xf42f08 for k8s.io/sample-controller/pkg/client/informers/externalversions.(*sharedInformerFactory).Start() ./pkg/client/informers/externalversions/factory.go:111
(dlv) b k8s.io/sample-controller/vendor/k8s.io/client-go/informers.(*sharedInformerFactory).Start
Breakpoint 6 set at 0xefb888 for k8s.io/sample-controller/vendor/k8s.io/client-go/informers.(*sharedInformerFactory).Start() ./vendor/k8s.io/client-go/informers/factory.go:126 // https://github.com/kubernetes/sample-controller/blob/master/pkg/client/informers/externalversions/factory.go // Start initializes all requested informers.
func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) {
f.lock.Lock()
defer f.lock.Unlock() for informerType, informer := range f.informers {
if !f.startedInformers[informerType] {
go informer.Run(stopCh)
f.startedInformers[informerType] = true
}
}
}
0 0x0000000000f46733 in main.(*Controller).enqueueFoo
at ./controller.go:338
1 0x0000000000f4785e in main.NewController.func1
at ./controller.go:120
2 0x0000000000e6f96d in k8s.io/sample-controller/vendor/k8s.io/client-go/tools/cache.ResourceEventHandlerFuncs.OnUpdate
at ./vendor/k8s.io/client-go/tools/cache/controller.go:202
3 0x0000000000e81066 in k8s.io/sample-controller/vendor/k8s.io/client-go/tools/cache.(*ResourceEventHandlerFuncs).OnUpdate
at <autogenerated>:1
4 0x0000000000e7ee3b in k8s.io/sample-controller/vendor/k8s.io/client-go/tools/cache.(*processorListener).run.func1.1
at ./vendor/k8s.io/client-go/tools/cache/shared_informer.go:552
5 0x00000000009b478c in k8s.io/sample-controller/vendor/k8s.io/apimachinery/pkg/util/wait.ExponentialBackoff
at ./vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:203
6 0x0000000000e7efa9 in k8s.io/sample-controller/vendor/k8s.io/client-go/tools/cache.(*processorListener).run.func1
at ./vendor/k8s.io/client-go/tools/cache/shared_informer.go:548
7 0x00000000009b4c14 in k8s.io/sample-controller/vendor/k8s.io/apimachinery/pkg/util/wait.JitterUntil.func1
at ./vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:133
8 0x00000000009b451e in k8s.io/sample-controller/vendor/k8s.io/apimachinery/pkg/util/wait.JitterUntil
at ./vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:134
9 0x00000000009b444d in k8s.io/sample-controller/vendor/k8s.io/apimachinery/pkg/util/wait.Until
at ./vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:88
10 0x0000000000e7a58d in k8s.io/sample-controller/vendor/k8s.io/client-go/tools/cache.(*processorListener).run
at ./vendor/k8s.io/client-go/tools/cache/shared_informer.go:546
11 0x0000000000e7f50a in k8s.io/sample-controller/vendor/k8s.io/client-go/tools/cache.(*processorListener).run-fm
at ./vendor/k8s.io/client-go/tools/cache/shared_informer.go:390
12 0x00000000009b4b8f in k8s.io/sample-controller/vendor/k8s.io/apimachinery/pkg/util/wait.(*Group).Start.func1
at ./vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:71
13 0x00000000004594e1 in runtime.goexit
at /usr/local/go/src/runtime/asm_amd64.s:1333
0 0x0000000000f469f0 in main.(*Controller).handleObject
at ./controller.go:378
1 0x0000000000f47f5e in main.(*Controller).handleObject-fm
at ./controller.go:130
2 0x0000000000e6f8f9 in k8s.io/sample-controller/vendor/k8s.io/client-go/tools/cache.ResourceEventHandlerFuncs.OnAdd
at ./vendor/k8s.io/client-go/tools/cache/controller.go:195
3 0x0000000000e80f32 in k8s.io/sample-controller/vendor/k8s.io/client-go/tools/cache.(*ResourceEventHandlerFuncs).OnAdd
at <autogenerated>:1
4 0x0000000000e7eecd in k8s.io/sample-controller/vendor/k8s.io/client-go/tools/cache.(*processorListener).run.func1.1
at ./vendor/k8s.io/client-go/tools/cache/shared_informer.go:554
5 0x00000000009b478c in k8s.io/sample-controller/vendor/k8s.io/apimachinery/pkg/util/wait.ExponentialBackoff
at ./vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:203
6 0x0000000000e7efa9 in k8s.io/sample-controller/vendor/k8s.io/client-go/tools/cache.(*processorListener).run.func1
at ./vendor/k8s.io/client-go/tools/cache/shared_informer.go:548
7 0x00000000009b4c14 in k8s.io/sample-controller/vendor/k8s.io/apimachinery/pkg/util/wait.JitterUntil.func1
at ./vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:133
8 0x00000000009b451e in k8s.io/sample-controller/vendor/k8s.io/apimachinery/pkg/util/wait.JitterUntil
at ./vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:134
9 0x00000000009b444d in k8s.io/sample-controller/vendor/k8s.io/apimachinery/pkg/util/wait.Until
at ./vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:88
10 0x0000000000e7a58d in k8s.io/sample-controller/vendor/k8s.io/client-go/tools/cache.(*processorListener).run
at ./vendor/k8s.io/client-go/tools/cache/shared_informer.go:546
11 0x0000000000e7f50a in k8s.io/sample-controller/vendor/k8s.io/client-go/tools/cache.(*processorListener).run-fm
at ./vendor/k8s.io/client-go/tools/cache/shared_informer.go:390
12 0x00000000009b4b8f in k8s.io/sample-controller/vendor/k8s.io/apimachinery/pkg/util/wait.(*Group).Start.func1
at ./vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:71
13 0x00000000004594e1 in runtime.goexit
at /usr/local/go/src/runtime/asm_amd64.s:1333
(dlv) print ownerRef
*k8s.io/sample-controller/vendor/k8s.io/apimachinery/pkg/apis/meta/v1.OwnerReference {
APIVersion: "samplecontroller.k8s.io/v1alpha1",
Kind: "Foo",
Name: "example-foo",
UID: "118da85e-00fa-11e9-96e2-fa163e199d30",
Controller: *true,
BlockOwnerDeletion: *true,}
goroutines [41/326]
Goroutine 1 - User: ./controller.go:171 main.(*Controller).Run (0xf45a11)
Goroutine 2 - User: /usr/local/go/src/runtime/asm_amd64.s:311 runtime.systemstack_switch (0x457400)
Goroutine 3 - User: /usr/local/go/src/runtime/proc.go:303 runtime.gopark (0x42e3db)
Goroutine 4 - User: /usr/local/go/src/runtime/proc.go:303 runtime.gopark (0x42e3db)
Goroutine 5 - User: ./vendor/k8s.io/klog/klog.go:941 k8s.io/sample-controller/vendor/k8s.io/klog.(*loggingT).flushDaemon (0x5f185b)
Goroutine 6 - User: /usr/local/go/src/runtime/sigqueue.go:139 os/signal.signal_recv (0x44243c)
Goroutine 7 - User: /usr/local/go/src/runtime/proc.go:303 runtime.gopark (0x42e3db)
Goroutine 8 - User: ./pkg/signals/signal.go:36 k8s.io/sample-controller/pkg/signals.SetupSignalHandler.func1 (0xf449f4)
Goroutine 9 - User: ./vendor/k8s.io/apimachinery/pkg/watch/mux.go:207 k8s.io/sample-controller/vendor/k8s.io/apimachinery/pkg/watch.(*Broadcaster).loop
(0x772ab6)
Goroutine 10 - User: ./vendor/k8s.io/client-go/tools/record/event.go:231 k8s.io/sample-controller/vendor/k8s.io/client-go/tools/record.(*eventBroadcast$
rImpl).StartEventWatcher.func1 (0xe9d054)
Goroutine 11 - User: ./vendor/k8s.io/client-go/tools/record/event.go:231 k8s.io/sample-controller/vendor/k8s.io/client-go/tools/record.(*eventBroadcast$
rImpl).StartEventWatcher.func1 (0xe9d054)
Goroutine 12 - User: ./vendor/k8s.io/client-go/util/workqueue/queue.go:198 k8s.io/sample-controller/vendor/k8s.io/client-go/util/workqueue.(*Type).upda$
eUnfinishedWorkLoop (0xea1212)
Goroutine 13 - User: /usr/local/go/src/runtime/lock_futex.go:228 runtime.notetsleepg (0x40c4f7)
Goroutine 14 - User: ./vendor/k8s.io/client-go/util/workqueue/delaying_queue.go:206 k8s.io/sample-controller/vendor/k8s.io/client-go/util/workqueue.(*d$
layingType).waitingLoop (0xe9f2cf)
Goroutine 15 - User: /usr/local/go/src/runtime/sema.go:510 sync.runtime_notifyListWait (0x43f4fb)
Goroutine 16 - User: /usr/local/go/src/runtime/sema.go:510 sync.runtime_notifyListWait (0x43f4fb)
Goroutine 18 - User: /usr/local/go/src/runtime/proc.go:3063 runtime.exitsyscall (0x4353a9)
Goroutine 20 - User: /usr/local/go/src/runtime/proc.go:303 runtime.gopark (0x42e3db)
Goroutine 21 - User: /usr/local/go/src/runtime/proc.go:303 runtime.gopark (0x42e3db)
Goroutine 22 - User: /usr/local/go/src/runtime/proc.go:303 runtime.gopark (0x42e3db)
Goroutine 34 - User: /usr/local/go/src/runtime/proc.go:3063 runtime.exitsyscall (0x4353a9)
Goroutine 36 - User: ./vendor/k8s.io/client-go/tools/cache/shared_informer.go:425 k8s.io/sample-controller/vendor/k8s.io/client-go/tools/cache.(*sharedP
rocessor).run (0xe79b46)
Goroutine 37 - User: ./vendor/k8s.io/client-go/tools/cache/controller.go:103 k8s.io/sample-controller/vendor/k8s.io/client-go/tools/cache.(*controller).
Run.func1 (0xe7e0d4)
Goroutine 38 - User: ./vendor/k8s.io/client-go/tools/cache/reflector.go:302 k8s.io/sample-controller/vendor/k8s.io/client-go/tools/cache.(*Reflector).w$
tchHandler (0xe764e5)
Goroutine 41 - User: /usr/local/go/src/runtime/proc.go:303 runtime.gopark (0x42e3db)
Goroutine 42 - User: /usr/local/go/src/runtime/proc.go:303 runtime.gopark (0x42e3db)
Goroutine 43 - User: /usr/local/go/src/runtime/proc.go:303 runtime.gopark (0x42e3db)
Goroutine 44 - User: /usr/local/go/src/runtime/proc.go:303 runtime.gopark (0x42e3db)
Goroutine 45 - User: /usr/local/go/src/runtime/proc.go:303 runtime.gopark (0x42e3db)
Goroutine 50 - User: ./vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:374 k8s.io/sample-controller/vendor/k8s.io/apimachinery/pkg/util/wait.poller.fu$
c1.1 (0x9b4d93)
Goroutine 52 - User: ./vendor/k8s.io/client-go/tools/cache/shared_informer.go:425 k8s.io/sample-controller/vendor/k8s.io/client-go/tools/cache.(*shared$
rocessor).run (0xe79b46)
Goroutine 53 - User: ./vendor/k8s.io/client-go/tools/cache/controller.go:103 k8s.io/sample-controller/vendor/k8s.io/client-go/tools/cache.(*controller)$
Run.func1 (0xe7e0d4)
Goroutine 54 - User: ./vendor/k8s.io/client-go/tools/cache/reflector.go:302 k8s.io/sample-controller/vendor/k8s.io/client-go/tools/cache.(*Reflector).w$
tchHandler (0xe764e5)
Goroutine 58 - User: /usr/local/go/src/runtime/proc.go:303 runtime.gopark (0x42e3db)
Goroutine 59 - User: /usr/local/go/src/runtime/proc.go:303 runtime.gopark (0x42e3db)
Goroutine 60 - User: /usr/local/go/src/runtime/proc.go:303 runtime.gopark (0x42e3db)
Goroutine 61 - User: /usr/local/go/src/runtime/proc.go:303 runtime.gopark (0x42e3db)
Goroutine 62 - User: /usr/local/go/src/runtime/proc.go:303 runtime.gopark (0x42e3db)
Goroutine 63 - User: /usr/local/go/src/runtime/proc.go:303 runtime.gopark (0x42e3db)
Goroutine 65 - User: /usr/local/go/src/runtime/netpoll.go:173 internal/poll.runtime_pollWait (0x428dc6)
Goroutine 66 - User: ./vendor/k8s.io/client-go/tools/cache/shared_informer.go:549 k8s.io/sample-controller/vendor/k8s.io/client-go/tools/cache.(*proces$
orListener).run.func1.1 (0xe7ed04)
Goroutine 67 - User: ./vendor/k8s.io/client-go/tools/cache/shared_informer.go:517 k8s.io/sample-controller/vendor/k8s.io/client-go/tools/cache.(*proces$
orListener).pop (0xe7a356)
Goroutine 68 - User: /usr/local/go/src/runtime/proc.go:303 runtime.gopark (0x42e3db)
Goroutine 69 - User: /usr/local/go/src/runtime/proc.go:303 runtime.gopark (0x42e3db)
Goroutine 71 - User: ./vendor/k8s.io/client-go/tools/cache/reflector.go:207 k8s.io/sample-controller/vendor/k8s.io/client-go/tools/cache.(*Reflector).L$
stAndWatch.func1 (0xe7e56d)
Goroutine 72 - User: /usr/local/go/src/runtime/lock_futex.go:228 runtime.notetsleepg (0x40c4f7)
Goroutine 74 - User: /usr/local/go/src/runtime/sema.go:510 sync.runtime_notifyListWait (0x43f4fb)
* Goroutine 82 - User: ./controller.go:341 main.(*Controller).enqueueFoo (0xf46741) (thread 12081)
Goroutine 83 - User: ./vendor/k8s.io/client-go/tools/cache/shared_informer.go:517 k8s.io/sample-controller/vendor/k8s.io/client-go/tools/cache.(*process
orListener).pop (0xe7a356)
Goroutine 99 - User: ./vendor/k8s.io/client-go/tools/cache/reflector.go:207 k8s.io/sample-controller/vendor/k8s.io/client-go/tools/cache.(*Reflector).Li
stAndWatch.func1 (0xe7e56d)
Goroutine 102 - User: /usr/local/go/src/runtime/sema.go:510 sync.runtime_notifyListWait (0x43f4fb)
Goroutine 103 - User: /usr/local/go/src/runtime/sema.go:510 sync.runtime_notifyListWait (0x43f4fb)
Goroutine 114 - User: /usr/local/go/src/runtime/proc.go:303 runtime.gopark (0x42e3db)
Goroutine 146 - User: /usr/local/go/src/runtime/proc.go:303 runtime.gopark (0x42e3db)
Goroutine 179 - User: /usr/local/go/src/runtime/sema.go:510 sync.runtime_notifyListWait (0x43f4fb)
Goroutine 187 - User: /usr/local/go/src/runtime/proc.go:303 runtime.gopark (0x42e3db)
Other:
Understanding kubernetes networking: ingress
Load Balance East-West Traffic in Kubernetes Environment Using NetScaler CPX
How we run Kubernetes in Kubernetes aka Kubeception
Istio Handbook——Istio中文指南/服务网格实践手册
Kubernetes与云原生应用概览
比较典型CRD的例子是:
如何在GO语言中使用Kubernetes API?
视频: 沃趣:袁琳峰-使用 Operator 来扩展 Kubernetes
kubernets controller 和 CRD的扩展的更多相关文章
- kubernets controller 和 CRD 具体组件分析
(dlv) b k8s.io/sample-controller/pkg/client/informers/externalversions.(*sharedInformerFactory).Info ...
- ASP.NET MVC 5 Web编程3 -- Controller的应用及扩展
Controller基础 一. 访问修饰符 1.1 类的访问修饰符 Controller类的访问修饰符必须是public,url才能被拦截. internal能编译通过,但无法拦截url请求.priv ...
- MVC源码分析 - Controller创建和创建扩展
上一篇, 出现了一个至关重要的类:MvcHandler, 接下来就来看一下MvcHandler吧. 先不看具体方法, 先看一下类里面的情况. //这里实现了两个重要的接口, 异步处理和同步处理的接口p ...
- 深入解析 Kubebuilder:让编写 CRD 变得更简单
作者 | 刘洋(炎寻) 阿里云高级开发工程师 导读:自定义资源 CRD(Custom Resource Definition)可以扩展 Kubernetes API,掌握 CRD 是成为 Kubern ...
- 《InsideUE4》-6-GamePlay架构(五)Controller
<InsideUE4>-6-GamePlay架构(五)Controller Tags: InsideUE4 GamePlay 那一天 Pawn又回想起了 被Controller所支配的恐惧 ...
- ASP.NET MVC4学习笔记之Controller的激活
一. 高层相关类说明 当路由系统根据请求Url收集路由信息后,下一步就要将路由信息传给Controller激活系统,Controller激活系统负责实现了IController接口的Controlle ...
- kubernetes CRD学习笔记
前言 最近在极客时间订阅了kubernetes的专栏,这篇文章是想记录一下自己学习CRD(custom resource definition)的过程,加深一下记忆. 准备工作 首先安装一下我们用的g ...
- 【开源】 bsf.mvc spingboot的扩展
springboot的扩展实现,让springboot开发更加简单:形成demo模板,以后开发更方便. 开源地址:https://gitee.com/chejiangyi/bsf.mvc/tree/m ...
- Asp.Net Mvc 自定义扩展
目录: 自定义模型IModelBinder 自定义模型验证 自定义视图引擎 自定义Html辅助方法 自定义Razor辅助方法 自定义Ajax辅助方法 自定义控制器扩展 自定义过滤器 自定义Action ...
随机推荐
- vue table 固定首列和首行
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name ...
- 弄懂JDK、JRE和JVM到底是什么
首先是JDK JDK(Java Development Kit) 是 Java 语言的软件开发工具包(SDK).在JDK的安装目录下有一个jre目录,里面有两个文件夹bin和lib,在这里可以认为bi ...
- c++第三次实验
第一题: 先把代码贴上来 main.cpp #include <iostream> #include <cstdlib> #include<conio.h> #in ...
- 《图解HTTP》读书笔记(四:HTTP方法)
1.作用 告知服务器我的意图是什么使用以下方法下达命令. 2.方法 GET 方法用来请求访问已被 URI 识别的资源. 指定的资源经服务器端解析后返回响应内容. ---URI可以定位互联网上的资源 P ...
- TCP/IP协议 网络层
IP协议介绍 1.IP协议是TCP/IP协议族中最为核心的协议.IP协议将多个包交换网络连接起来,它在源地址和目的地址之间传送一种称为数据包的东西,它还提供对数据大小的重新组装功能,以适应不同网络对包 ...
- java项目对jar包加密流程,防止反编译
Java 开发语言以其安全性高.代码优化.跨平台等特性,迅速取代了很多传统高级语言,占据了企业级网络应用开发等诸多领域的霸主地位.特别是近年来大数据.互联网+.云计算技术的不断发展,Java 开发语言 ...
- 3.1.3 Spring之AOP
三.Spring之AOP 1. 代理模式 (1) 什么是代理模式? 代理模式是面向对象编程的23种基础设计模式之一.为其他对象(代理对象)提供一种代理以控制对这个对象(源对象)的访问. 就是说,声明一 ...
- 使用commons.cli实现MyCP
目录 Commons.cli库 MyCP 测试代码 总结 Commons.cli库 考虑到这次的任务是实现自己的命令行命令cp,我认为简单地使用args[]无法很好的完成需求.经过网上的一番搜索,我找 ...
- LeetCode-7-反转数组-c#
目前看到的网上的版本 都是用到数组的反转函数.对于代码实现的细节没给出 反转函数的想法没给出. 特在此补充. Reverse函数是从c#库源码中抠出的主要部分代码.主要是双端步进.交换,当然是o(1) ...
- Vue2leaflet 替换国内地图api,带{z}/{x}/{y}形式的
参考:https://www.cnblogs.com/gispathfinder/p/9535685.html Vue2leaflet安装后,默认自带的地图URL如下 url:'http://{s}. ...