During the Sensey Lancer project, we were faced with a question about defining the relation between an Image and a Kubernetes node.
Currently, this is our Image entity:
package com.sensey.lancer.macrocleaner.entity;
import java.time.Instant;
import java.util.List;
import java.util.UUID;
import com.sensey.lancer.macrocleaner.enums.ImageStatus;
import jakarta.persistence.*;
import lombok.*;
@Entity
@Table(name = "images")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class ImageEntity {
//--------Atts----------------//
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id", nullable = false, unique = true, updatable = false)
private UUID id;
/**
* Image ID from Docker (?)
* Example: 77af4d6b9913
*/
@Id
@Column(nullable = false, unique = true)
private String imageId;
@Column(name = "name", nullable = false)
private String name;
@Column(name = "tag", nullable = false)
private String tag;
@Column(name = "size_mb", nullable = false)
private Long sizeMB;
/**
* Instant is always stored as UTC, making it ideal for global applications.
*/
@Column(name = "created_at", nullable = false)
private Instant createdAt;
@Column(name = "pulled_at", nullable = false)
private Instant pulledAt;
@Column(name = "deleted_at", nullable = true)
private Instant deletedAt;
//--------Enums----------------//
@Enumerated(EnumType.STRING)
@Column(name = "status", nullable = false)
private ImageStatus status;
//--------Relations------------//
/**
* Many images can have 1 node.
*/
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "node_id", nullable = false)
private NodeEntity node;
/**
* An image can have many containers.
* When an image is removed, the containers must be kept intact.
* The containers need to be removed first,
* and then the image needs to be removed for a correct procedure.
*/
@OneToMany(mappedBy = "image", cascade = CascadeType.PERSIST, orphanRemoval = false)
private List<ContainerEntity> containers;
}
In this troubleshoot session, we will focus on this part of the code:
/**
* Many images can have 1 node.
*/
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "node_id", nullable = false)
private NodeEntity node;
In the current situation, the relation is defined as many-to-one, meaning:
Howewer, after some discussion between the developers, a question was raised:
Should this not be a many-to-many relation? Since:
Which is a many-to-many relation, according to the brainstorm of developer - let’s say his name is X.
To understand the discussion better and to be able to answer this question. A decision was made to to take a step back, and analyze the situation - by understanding how in the name of Kubernetes the process of pulling images and scheduling truly works.
According to my current knowledge, the logic of image pulling in Kubernetes is like this:
Indicating, a many-to-many relation since:
Now, let’s verify with ChatGPT if X his knowledge is true: