CRD開発ガイドkubernetes

CRDの開発を習得する方法カスタムリソースCRDとadminsionのウェブフック、教え10分あなたは:拡張二つの最も一般的な何かを知っている必要がありkubernetes。

ポッドは、カスタムオブジェクト、コントローラプラスプロメテウスを作成kubectlを聞いカスタムのプロメテウスプロメテウスopteratorとして、組成kubernetesはこの1つは、広く使用されて、ちょうど展開statefulsetとして、ユーザーが自分のリソースオブジェクトをカスタマイズすることができます作成​​するために行ってきましたpormetheusクラスタ。ルークとその共感に。

私は、仮想マシンをスケジュールkubernetesが必要なので、カスタム型のVirtualMachineがあります

kubebuilder

kubebuilder私たちは多くの作業を節約するため、CRDとadminsionの開発は、風をウェブフック。

インストール

ソースインストールすることにより:

git clone https://github.com/kubernetes-sigs/kubebuilder
cd kubebuilder
make build
cp bin/kubebuilder $GOPATH/bin

またはバイナリをダウンロードします。

os=$(go env GOOS)
arch=$(go env GOARCH)

# download kubebuilder and extract it to tmp
curl -sL https://go.kubebuilder.io/dl/2.0.0-beta.0/${os}/${arch} | tar -xz -C /tmp/

# move to a long-term location and put it on your path
# (you'll need to set the KUBEBUILDER_ASSETS env var if you put it somewhere else)
sudo mv /tmp/kubebuilder_2.0.0-beta.0_${os}_${arch} /usr/local/kubebuilder
export PATH=$PATH:/usr/local/kubebuilder/bin

また、保持する必要がkustomizeこれはヘルム震えを聞かせてYAMLレンダリングアーティファクトです。

go install sigs.k8s.io/kustomize/v3/cmd/kustomize

使用

あなたはkubernetesクラスタを持っている必要があることに注意してください、あなたが行くステップインストール

CRDを作成します

kubebuilder init --domain sealyun.com --license apache2 --owner "fanux"
kubebuilder create api --group infra --version v1 --kind VirtulMachine

コントローラをCRDをインストールして起動します

make install # 安装CRD
make run # 启动controller

その後、我々は、CRDの作成を見ることができます

# kubectl get crd
NAME                                           AGE
virtulmachines.infra.sealyun.com                  52m

仮想マシンを作成するには:

# kubectl apply -f config/samples/
# kubectl get virtulmachines.infra.sealyun.com 
NAME                   AGE
virtulmachine-sample   49m

YAMLファイルを見てください:

# cat config/samples/infra_v1_virtulmachine.yaml 
apiVersion: infra.sealyun.com/v1
kind: VirtulMachine
metadata:
  name: virtulmachine-sample
spec:
  # Add fields here
  foo: bar

ここでYAMLにちょうどデポジットは再びetcdあり、我々はあなたが何の問題もしませんでしたイベントコントローラを作成するときに耳を傾けます。

コントローラは、クラスタにデプロイされています

make docker-build docker-push IMG=fanux/infra-controller
make deploy

私は人生を困難にするためにも、リモートkubenetes、テストではなかったときのメイクドッキングウィンドウビルド、無etcdのbinファイルなので、最初のテストをオフにします。

Makefileを変更します。

# docker-build: test
docker-build: 

Dockerfile gcr.io/distroless/static:latestこの画像も、ライン上で変更するためのランダムな変化をあなたをプルダウンして、私は変更golang:1.12.7

コードは、いくつかは、それが内にパッケージに依存するMODベンダーに行く可能にするために、プルダウン構築することも可能である場合には

go mod vendor
如果你本地有些代码拉不下来,可以用proxy:

輸出GOPROXY = https://goproxy.io

そしてDockerfileを変更、ダウンロードコメント:

更新:

# Build the manager binary
FROM golang:1.12.7 as builder

WORKDIR /go/src/github.com/fanux/sealvm
# Copy the Go Modules manifests
COPY . . 

# Build
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o manager main.go

# Use distroless as minimal base image to package the manager binary
# Refer to https://github.com/GoogleContainerTools/distroless for more details
# FROM gcr.io/distroless/static:latest
FROM golang:1.12.7
WORKDIR /
COPY --from=builder /go/src/github.com/fanux/sealvm/manager .
ENTRYPOINT ["/manager"]

make deploy ときにエラー: Error: json: cannot unmarshal string into Go struct field Kustomization.patches of type types.Patch

入れて変更をしますconfig/default/kustomization.yamlpatches:patchesStrategicMerge:

kustomize build config/default このコマンドは、次のを体験することができ、YAMLファイルのコントローラをレンダリングします

お使いのコントローラがアップ実行された参照してください。

kubectl get deploy -n sealvm-system
NAME                        DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
sealvm-controller-manager   1         1         1            0           3m
kubectl get svc -n sealvm-system
NAME                                        TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
sealvm-controller-manager-metrics-service   ClusterIP   10.98.71.199   <none>        8443/TCP   4m

開発

オブジェクトデータのパラメータを追加します。

設定/サンプルは、次の書類をYAML見て:

apiVersion: infra.sealyun.com/v1
kind: VirtulMachine
metadata:
  name: virtulmachine-sample
spec:
  # Add fields here
  foo: bar

ここでは、パラメータがありfoo:bar、我々は仮想CPU、メモリ情報を追加します。

直接api/v1/virtulmachine_types.go

// VirtulMachineSpec defines the desired state of VirtulMachine
// 在这里加信息
type VirtulMachineSpec struct {
    // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
    // Important: Run "make" to regenerate code after modifying this file
    CPU    string `json:"cpu"`   // 这是我增加的
    Memory string `json:"memory"`
}

// VirtulMachineStatus defines the observed state of VirtulMachine
// 在这里加状态信息,比如虚拟机是启动状态,停止状态啥的
type VirtulMachineStatus struct {
    // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
    // Important: Run "make" to regenerate code after modifying this file
}

そして、それを作ります:

make && make install && make run

そして、それはYAMLコントローラは、CRDは、CPUとメモリの情報に置かれているでしょうレンダリングするために行きます:

kustomize build config/default

properties:
  cpu:
    description: 'INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
      Important: Run "make" to regenerate code after modifying this file'
    type: string
  memory:
    type: string

YAMLを変更します。

apiVersion: infra.sealyun.com/v1
kind: VirtulMachine
metadata:
  name: virtulmachine-sample
spec:
  cpu: "1"
  memory: "2G"
# kubectl apply -f config/samples 
virtulmachine.infra.sealyun.com "virtulmachine-sample" configured
# kubectl get virtulmachines.infra.sealyun.com virtulmachine-sample -o yaml 
apiVersion: infra.sealyun.com/v1
kind: VirtulMachine
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"infra.sealyun.com/v1","kind":"VirtulMachine","metadata":{"annotations":{},"name":"virtulmachine-sample","namespace":"default"},"spec":{"cpu":"1","memory":"2G"}}
  creationTimestamp: 2019-07-26T08:47:34Z
  generation: 2
  name: virtulmachine-sample
  namespace: default
  resourceVersion: "14811698"
  selfLink: /apis/infra.sealyun.com/v1/namespaces/default/virtulmachines/virtulmachine-sample
  uid: 030e2b9a-af82-11e9-b63e-5254bc16e436
spec:      # 新的CRD已生效
  cpu: "1"
  memory: 2G 

ステータスは同様に、それは例えば、私は、リガの作成状況を入れ、上がるの仮想マシン(主にいくつかの制御ロジックレベル)を作成するために行くためのコントローラを表していないだろう、ステータスが完成実行中を作成するように変更します

唯一のインタフェースが実装さ和解

イベントリスナインタフェースを備えた回転コントローラがこの1、それにカプセル化されている。あなたはどのようにイベントリスナーを心配する必要はありません。

仮想マシンの情報を取得します。

func (r *VirtulMachineReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
    ctx = context.Background()
    _ = r.Log.WithValues("virtulmachine", req.NamespacedName)

    vm := &v1.VirtulMachine{}
    if err := r.Get(ctx, req.NamespacedName, vm); err != nil { # 获取VM信息
        log.Error(err, "unable to fetch vm")
    } else {
        fmt.Println(vm.Spec.CPU, vm.Spec.Memory) # 打印CPU内存信息
    }

    return ctrl.Result{}, nil
}

make && make install && make run仮想マシンを作成するには、この時間はkubectl apply -f config/samples、それがCPUのメモリからの出力を記録します。リストには同様のインタフェース、私は詳細には触れません。

r.List(ctx, &vms, client.InNamespace(req.Namespace), client.MatchingField(vmkey, req.Name))

更新状況

ステータスフィールドにはステータス構造に追加されます。

type VirtulMachineStatus struct {
    Status string `json:"status"`
}

コントローラは、更新状況を行きます:

vm.Status.Status = "Running"
if err := r.Status().Update(ctx, vm); err != nil {
    log.Error(err, "unable to update vm status")
}

ある場合:the server could not find the requested resourceこのエラーは、その後、CRD構造はコメントを追加する必要があります// +kubebuilder:subresource:status

// +kubebuilder:subresource:status
// +kubebuilder:object:root=true

type VirtulMachine struct {
    metav1.TypeMeta   `json:",inline"`
    metav1.ObjectMeta `json:"metadata,omitempty"`

    Spec   VirtulMachineSpec   `json:"spec,omitempty"`
    Status VirtulMachineStatus `json:"status,omitempty"`
}

それがすべてです

コンパイル後、発見状態が実行中となっている適用を開始:

# kubectl get virtulmachines.infra.sealyun.com virtulmachine-sample -o yaml
...
status:
  status: Running 

削除

time.Sleep(time.Second * 10)
if err := r.Delete(ctx, vm); err != nil {
    log.Error(err, "unable to delete vm ", "vm", vm)
}

10秒後、私たちは得ることはありません

コレクタファイナライザを削除します。

あなたがファイナライザを使用しない場合、コントローラは、CRDが得るthink'll取得することができなかったとき、直接削除etcdデータを削除kubectl:

ERRO[0029] VirtulMachine.infra.sealyun.com "virtulmachine-sample" not foundunable to fetch vm  source="virtulmachine_controller.go:48"

だから我々は、CRDは、ファイナライザを追加作成する必要がある場合:

vm.ObjectMeta.Finalizers = append(vm.ObjectMeta.Finalizers, "virtulmachine.infra.sealyun.com")

そして、あなたは私たちがフォローアップのプロセスを行うすることが唯一のCRDにタイムスタンプが付いて削除します削除したとき、我々は最後のファイナライザを削除するに対処します:

如果 DeleteionTimestamp不存在
    如果没有Finalizers
        加上Finalizers,并更新CRD
要不然,说明是要被删除的
    如果存在Finalizers,删除Finalizers,并更新CRD

完全なコード例を参照してください。

if cronJob.ObjectMeta.DeletionTimestamp.IsZero() {
        if !containsString(cronJob.ObjectMeta.Finalizers, myFinalizerName) {
            cronJob.ObjectMeta.Finalizers = append(cronJob.ObjectMeta.Finalizers, myFinalizerName)
            if err := r.Update(context.Background(), cronJob); err != nil {
                return ctrl.Result{}, err
            }
        }
    } else {
        if containsString(cronJob.ObjectMeta.Finalizers, myFinalizerName) {
            if err := r.deleteExternalResources(cronJob); err != nil {
                return ctrl.Result{}, err
            }

            cronJob.ObjectMeta.Finalizers = removeString(cronJob.ObjectMeta.Finalizers, myFinalizerName)
            if err := r.Update(context.Background(), cronJob); err != nil {
                return ctrl.Result{}, err
            }
        }
    }

ウェブフック

kuberentes有三种ウェブフック、ウェブフック入学、許可およびウェブフックCRD変換ウェブフック。

例えば、ここで我々はいくつかのデフォルト値を設定するCRDを与え、以下のユーザーが作成するためのパラメータの一部を充填され、作成し、私たちはこれらの事を禁止しなければなりません。

ウェブフックの使用も非常に簡単です、今定義達成するために構造を与えるDefaulterValidatorのインターフェイスが可能。

その他のインタフェース

重合構造クライアント・インターフェースを調整するので、すべてのクライアントがメソッドですCRDオブジェクトの操作に主に関連し、直接呼び出すことができます

type Client interface {
    Reader
    Writer
    StatusClient
}
// Reader knows how to read and list Kubernetes objects.
type Reader interface {
    // Get retrieves an obj for the given object key from the Kubernetes Cluster.
    // obj must be a struct pointer so that obj can be updated with the response
    // returned by the Server.
    Get(ctx context.Context, key ObjectKey, obj runtime.Object) error

    // List retrieves list of objects for a given namespace and list options. On a
    // successful call, Items field in the list will be populated with the
    // result returned from the server.
    List(ctx context.Context, list runtime.Object, opts ...ListOptionFunc) error
}

// Writer knows how to create, delete, and update Kubernetes objects.
type Writer interface {
    // Create saves the object obj in the Kubernetes cluster.
    Create(ctx context.Context, obj runtime.Object, opts ...CreateOptionFunc) error

    // Delete deletes the given obj from Kubernetes cluster.
    Delete(ctx context.Context, obj runtime.Object, opts ...DeleteOptionFunc) error

    // Update updates the given obj in the Kubernetes cluster. obj must be a
    // struct pointer so that obj can be updated with the content returned by the Server.
    Update(ctx context.Context, obj runtime.Object, opts ...UpdateOptionFunc) error

    // Patch patches the given obj in the Kubernetes cluster. obj must be a
    // struct pointer so that obj can be updated with the content returned by the Server.
    Patch(ctx context.Context, obj runtime.Object, patch Patch, opts ...PatchOptionFunc) error
}

// StatusClient knows how to create a client which can update status subresource
// for kubernetes objects.
type StatusClient interface {
    Status() StatusWriter
}

スキャンコード懸念sealyun:

ディスカッションは、QQグループを追加することができます:98488045

おすすめ

転載: www.cnblogs.com/sealyun/p/11265457.html