Skip to content

Commit

Permalink
feature: add volume cleanup behaviour and optimize setup defaults pro…
Browse files Browse the repository at this point in the history
…cedure (#21)
  • Loading branch information
ptyin authored Sep 6, 2024
1 parent 433dd3f commit f629513
Show file tree
Hide file tree
Showing 9 changed files with 500 additions and 111 deletions.
18 changes: 11 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,14 @@ To deploy Seata Server using the Operator method, follow these steps:
serviceName: seata-server-cluster
replicas: 3
image: seataio/seata-server:latest
store:
resources:
requests:
storage: 5Gi
persistence:
volumeReclaimPolicy: Retain
spec:
resources:
requests:
storage: 5Gi
```
For the example above, if everything is correct, the controller will deploy 3 StatefulSet resources and a Headless Service to the cluster. You can access the Seata Server cluster in the cluster through `seata-server-0.seata-server-cluster.default.svc`.

### Reference
Expand All @@ -61,9 +63,11 @@ For CRD details, you can visit [operator.seata.apache.org_seataservers.yaml](con

5. `resources`: Used to define container resource requirements.

6. `store.resources`: Used to define mounted storage resource requirements.
6. `persistence.spec`: Used to define mounted storage resource requirements.

7. `persistence.volumeReclaimPolicy`: Used to control volume reclaim behavior, possible choices include `Retain` or `Delete`, which infer retain volumes or delete volumes after deletion respectively.

7. `env`: Environment variables passed to the container. You can use this field to define Seata Server configuration. For example:
8. `env`: Environment variables passed to the container. You can use this field to define Seata Server configuration. For example:

```yaml
apiVersion: operator.seata.apache.org/v1alpha1
Expand Down
20 changes: 12 additions & 8 deletions README.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,15 @@ https://github.com/seata/seata-docker
serviceName: seata-server-cluster
replicas: 3
image: seataio/seata-server:latest
store:
resources:
requests:
storage: 5Gi
persistence:
volumeReclaimPolicy: Retain
spec:
resources:
requests:
storage: 5Gi

```

对于上面这个 CR 的例子而言,如果一切正常的话,controller 将会部署 3 个 StatefulSet 资源和一个 Headless Service 到集群中;在集群中你可以通过 seata-server-0.seata-server-cluster.default.svc 对 Seata Server 集群进行访问。

### Reference
Expand All @@ -66,9 +68,11 @@ https://github.com/seata/seata-docker

5. `resources`: 用于定义容器的资源要求

6. `store.resources`: 用于定义挂载的存储资源要求
6. `persistence.spec`: 用于定义挂载的存储资源要求

7. `persistence.volumeReclaimPolicy`: 用于控制存储回收行为,允许的选项有 `Retain` 或者 `Delete`,分别代表了在 CR 删除之后保存存储卷或删除存储卷

7. `env`: 传递给容器的环境变量,可以通过此字段去定义 Seata Server 的配置,比如:
8. `env`: 传递给容器的环境变量,可以通过此字段去定义 Seata Server 的配置,比如:

```yaml
apiVersion: operator.seata.apache.org/v1alpha1
Expand Down Expand Up @@ -99,7 +103,7 @@ https://github.com/seata/seata-docker
data:
password: seata
```
### For Developer
Expand Down
86 changes: 79 additions & 7 deletions api/v1alpha1/seataserver_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@ package v1alpha1

import (
apiv1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
const (
DefaultSeataSessionStorageVolumeSize = "5Gi"
DefaultSeataServerImage = "seataio/seata-server:latest"
)

// SeataServerSpec defines the desired state of SeataServer
type SeataServerSpec struct {
Expand All @@ -35,13 +38,32 @@ type SeataServerSpec struct {
Replicas int32 `json:"replicas"`

// +kubebuilder:validation:Optional
// +kubebuilder:default=seata-server
// +kubebuilder:default=seata-server-cluster
ServiceName string `json:"serviceName"`

// +kubebuilder:validation:Optional
Ports Ports `json:"ports,omitempty"`

Store Store `json:"store"`
// +kubebuilder:validation:Optional
Persistence Persistence `json:"persistence,omitempty"`
}

func (s *SeataServerSpec) withDefaults() (changed bool) {
if s.ContainerName == "" {
s.ContainerName = "seata-server"
changed = true
}
if s.ServiceName == "" {
s.ServiceName = "seata-server-cluster"
changed = true
}
if s.Image == "" {
s.Image = DefaultSeataServerImage
changed = true
}
changed = s.Ports.withDefaults() || changed
changed = s.Persistence.withDefaults() || changed
return changed
}

// SeataServerStatus defines the observed state of SeataServer
Expand All @@ -63,6 +85,10 @@ type SeataServer struct {
Status SeataServerStatus `json:"status,omitempty"`
}

func (s *SeataServer) WithDefaults() bool {
return s.Spec.withDefaults()
}

//+kubebuilder:object:root=true

// SeataServerList contains a list of SeataServer
Expand All @@ -76,7 +102,9 @@ type ContainerSpec struct {
// +kubebuilder:validation:Optional
// +kubebuilder:default=seata-server
ContainerName string `json:"containerName"`
Image string `json:"image"`
// +kubebuilder:validation:Optional
// +kubebuilder:default="seataio/seata-server:latest"
Image string `json:"image"`
// +kubebuilder:validation:Optional
Env []apiv1.EnvVar `json:"env"`
// +kubebuilder:validation:Optional
Expand All @@ -95,8 +123,52 @@ type Ports struct {
RaftPort int32 `json:"raftPort"`
}

type Store struct {
Resources apiv1.ResourceRequirements `json:"resources"`
func (p *Ports) withDefaults() bool {
if *p == (Ports{}) {
p.ConsolePort = 7091
p.ServicePort = 8091
p.RaftPort = 9091
return true
}
return false
}

type Persistence struct {
// VolumeReclaimPolicy is a seata operator configuration. If it's set to Delete,
// the corresponding PVCs will be deleted by the operator when seata server cluster is deleted.
// The default value is Retain.
// +kubebuilder:validation:Enum="Delete";"Retain"
VolumeReclaimPolicy VolumeReclaimPolicy `json:"volumeReclaimPolicy,omitempty"`
// PersistentVolumeClaimSpec is the spec to describe PVC for the container
// This field is optional. If no PVC is specified default persistent volume
// will get created.
PersistentVolumeClaimSpec apiv1.PersistentVolumeClaimSpec `json:"spec,omitempty"`
}

type VolumeReclaimPolicy string

const (
VolumeReclaimPolicyRetain VolumeReclaimPolicy = "Retain"
VolumeReclaimPolicyDelete VolumeReclaimPolicy = "Delete"
)

func (p *Persistence) withDefaults() (changed bool) {
if p.VolumeReclaimPolicy != VolumeReclaimPolicyDelete && p.VolumeReclaimPolicy != VolumeReclaimPolicyRetain {
changed = true
p.VolumeReclaimPolicy = VolumeReclaimPolicyRetain
}
p.PersistentVolumeClaimSpec.AccessModes = []apiv1.PersistentVolumeAccessMode{
apiv1.ReadWriteOnce,
}

storage, _ := p.PersistentVolumeClaimSpec.Resources.Requests["storage"]
if storage.IsZero() {
p.PersistentVolumeClaimSpec.Resources.Requests = apiv1.ResourceList{
apiv1.ResourceStorage: resource.MustParse(DefaultSeataSessionStorageVolumeSize),
}
changed = true
}
return changed
}

func init() {
Expand Down
34 changes: 17 additions & 17 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit f629513

Please sign in to comment.