2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

KubernetesのresourceVersionで楽観ロック

Posted at

Kubernetesのリソースは、その状態と一緒にresourceVersionというフィールドを持っています。このフィールドは、リソースが最後に変更されたときのバージョンを示す文字列です。そして、これを利用することで楽観ロックのような動作を実現することができます。

Custom Resourceの作成

まず、例としてCustom Resource Definition (CRD)を作成します。以下はそのためのYAMLです:

myobject.yaml
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: myobjects.example.com
spec:
  group: example.com
  names:
    kind: MyObject
    plural: myobjects
    singular: myobject
    listKind: MyObjectList
  scope: Namespaced
  versions:
    - name: v1
      served: true
      storage: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                value:
                  type: string

CRDをクラスタに適用します:

kubectl apply -f myobject.yaml

MyObjectリソースの作成

次に、新しく作成したCRDに基づくMyObjectリソースを作成します:

hello-world.yaml
apiVersion: example.com/v1
kind: MyObject
metadata:
  name: hello-world
spec:
  value: hello world

リソースをクラスタに適用します:

kubectl apply -f hello-world.yaml

resourceVersionの取得

上で作成したリソースのresourceVersionを取得するために、以下のコマンドを実行します:

kubectl get -f hello-world.yaml --output jsonpath='{.metadata.resourceVersion}'

結果:

92029503

このresourceVersionは、リソースを変更する際の楽観ロックに利用できます。

楽観ロックの実験

resourceVersionをリソースに明示的に指定することで、楽観ロックができます:

hello-world.yaml
apiVersion: example.com/v1
kind: MyObject
metadata:
  name: hello-world
  resourceVersion: "92029503" # 追加
spec:
  value: goodbye world # 変更

1回目の適用:

kubectl apply -f hello-world.yaml

上の適用はresourceVersion=92029503に対する変更なので、成功します:

myobject.example.com/hello-world configured

この適用でresourceVersionが増えます。

そのため、同じresourceVersionを使用して再度変更を適用しようとすると、エラーが発生します:

kubectl apply -f hello-world.yaml

結果:

Error from server (Conflict): error when applying patch:
{"metadata":{"resourceVersion":"92029503"}}
to:
Resource: "example.com/v1, Resource=myobjects", GroupVersionKind: "example.com/v1, Kind=MyObject"
Name: "hello-world", Namespace: "default"
for: "hello-world.yaml": error when patching "hello-world.yaml": Operation cannot be fulfilled on myobjects.example.com "hello-world": the object has been modified; please apply your changes to the latest version and try again

このエラーは、指定されたresourceVersionでの変更が許可されないことを示しています。つまり、他のユーザーやプロセスがリソースを変更して新しいresourceVersionが割り当てられた後での変更は拒否されます。

まとめ

KubernetesのresourceVersionを利用することで、リソースの変更の競合を検知し、楽観ロックのような動作を実現することができます。これは、複数のユーザーやプロセスが同時にリソースを変更しようとする際の競合を避けるために非常に役立ちます。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?