프로젝트

일반

사용자 정보

실행

새 기능 #12787

csi-driver snapshot 기능 개발

이 헌제님이 약 2달 전에 추가함. 약 2달 전에 수정됨.

상태:
진행
우선 순위:
보통
담당자:
목표 버전:
시작 시간:
2025/12/26
완료 기한:
2026/01/07 (38일 지연)
진척도:

0%

추정 시간:
20:00 시간
발견 버전:
반영 버전:
난이도:
쉬움
중요도:
조력자:
회사:
연락처:
점수:
6.88

설명

개요

  • csi-driver-lvm 에 각 볼륨 마다 스냅샷을 지정할 수 있도록 스냅샷에 관련된 기능을 개발한다.
  • 현재 matal-stack/csi-driver-lvm 에는 해당 내용이 없어 우선 topolvm 의 스냅샷 내용을 조사한다.
  • standalone 및 cluster 에서도 스냅샷 기능을 활용할 수 있도록 설계 및 개발한다.

난이도 및 추정시간

  • 스냅샷은 아직 알아보지 못해서 조사에 다소 시간이 들 것으로 보임.
  • 단순 API 연동으로 난이도 쉬움, 많은 리소스에 대한 생성으로 추정시간 20 시간
실행 #2

이 헌제님이 약 2달 전에 변경

  • yaml 추가
// values
snapshotter: registry.k8s.io/sig-storage/csi-snapshotter:v5.0.1

// daemonset (코드 수정 필요)
224           {{- if .Values.image.csi.csiSnapshotter }}
225           image: {{ .Values.image.csi.csiSnapshotter }} 
226           {{- else }}     
227           image: "{{ .Values.image.repository }}:{{ default .Chart.AppVersion .Values.image.tag }}"
228           {{- end }}          
229           {{- with .Values.image.pullPolicy }}  
230           imagePullPolicy: {{ . }}   
231           {{- end }}   
232           securityContext:   
233             allowPrivilegeEscalation: false  
234             capabilities:     
235               drop:      
236                 - ALL                     
237           {{- with .Values.resources.csi_snapshotter }}
238           resources: {{ toYaml . | nindent 12 }}     
239           {{- end }}     
240           {{- with .Values.env.csi_snapshotter }}  
241           env: {{- toYaml . | nindent 12 }}   
242           {{- end }}        
243           command:     
244             - /csi-snapshotter          
245             - --csi-address=/run/topolvm/csi-topolvm.sock 
246             {{- if .Values.controller.leaderElection.enabled }}                 
247             - --leader-election
248             - --leader-election-namespace={{ .Release.Namespace }}              
249             {{- end }}    
250             - --http-endpoint=:9811   
251           ports:            
252             - containerPort: 9811  
253               name: csi-snapshotter  
254           volumeMounts:       
255             - name: socket-dir    
256               mountPath: /run/topolvm  
257         {{- end }} 

  • capa
// Capabilities
581 func (s controllerServerNoLocked) ControllerGetCapabilities(context.Context, *csi.ControllerGetCapabi    litiesRequest) (*csi.ControllerGetCapabilitiesResponse, error) {
582 >---capabilities := []csi.ControllerServiceCapability_RPC_Type{                 
583 >--->---csi.ControllerServiceCapability_RPC_CREATE_DELETE_VOLUME, 
584 >--->---// csi.ControllerServiceCapability_RPC_CLONE_VOLUME,  
585 >--->---csi.ControllerServiceCapability_RPC_GET_CAPACITY, 
586 >--->---csi.ControllerServiceCapability_RPC_EXPAND_VOLUME, 
587 >--->---csi.ControllerServiceCapability_RPC_CREATE_DELETE_SNAPSHOT,  
588 >---}           
589                  
590 >---csiCaps := make([]*csi.ControllerServiceCapability, len(capabilities))      
591 >---for i, capability := range capabilities {    
592 >--->---csiCaps[i] = &csi.ControllerServiceCapability{ 
593 >--->--->---Type: &csi.ControllerServiceCapability_Rpc{ 
594 >--->--->--->---Rpc: &csi.ControllerServiceCapability_RPC{ 
595 >--->--->--->--->---Type: capability,    
596 >--->--->--->---},    
597 >--->--->---},       
598 >--->---}             
599 >---}                
600                        
601 >---return &csi.ControllerGetCapabilitiesResponse{  
602 >--->---Capabilities: csiCaps,   
603 >---}, nil        
604 }
  • 함수
// 스냅샷 생성
341 // CreateSnapshot creates a logical volume snapshot.
342 func (s controllerServerNoLocked) CreateSnapshot(ctx context.Context, req *csi.CreateSnapshotRequest)     (*csi.CreateSnapshotResponse, error) {
...
352 >---if req.GetSourceVolumeId() == "" {      
353 >--->---return nil, status.Error(codes.InvalidArgument, "missing source volume id")
354 >---}                                       
355                                             
356 >---if req.GetName() == "" {                
357 >--->---return nil, status.Error(codes.InvalidArgument, "missing name")         
358 >---}    

...      

360 >---name := strings.ToLower(req.GetName())  
361 >---sourceVolID := req.GetSourceVolumeId()  
362 >---sourceVol, err := s.lvService.GetVolume(ctx, sourceVolID)                   
363 >---if err != nil {
364 >--->---if errors.Is(err, k8s.ErrVolumeNotFound) {
365 >--->--->---return nil, status.Error(codes.NotFound, "failed to find source volumes")
366 >--->---}                                 
367 >--->---return nil, status.Error(codes.Internal, err.Error())                   
368 >---}                                     
369 >---snapTimeStamp := &timestamp.Timestamp{
370 >--->---Seconds: time.Now().Unix(),
371 >--->---Nanos:   0,      
372 >---}    

...

378 >---snapshot, err := s.lvService.CreateSnapshot(ctx, node, deviceClass, sourceVolName, name, accessTy    pe, *currentSize)
379 >---if err != nil {                   
380 >--->---_, ok := status.FromError(err)
381 >--->---if !ok {       
382 >--->--->---return nil, status.Error(codes.Internal, err.Error())               
383 >--->---}              
384 >--->---return nil, err      
385 >---}  

...

387 >---return &csi.CreateSnapshotResponse{
388 >--->---Snapshot: &csi.Snapshot{
389 >--->--->---SizeBytes:      snapshot.Status.CurrentSize.Value(),                
390 >--->--->---SnapshotId:     snapshot.Status.VolumeID, 
391 >--->--->---SourceVolumeId: sourceVolID,
392 >--->--->---CreationTime:   snapTimeStamp,
393 >--->--->---ReadyToUse:     true,  
394 >--->---},     
395 >---}, nil   


// 스냅샷 삭제
398 // DeleteSnapshot deletes an existing logical volume snapshot.                  
399 func (s controllerServerNoLocked) DeleteSnapshot(ctx context.Context, req *csi.DeleteSnapshotRequest)     (*csi.DeleteSnapshotResponse, error) {
400 >---ctrlLogger.Info("DeleteSnapshot called",   
401 >--->---"snapshot_id", req.GetSnapshotId(),  
402 >--->---"num_secrets", len(req.GetSecrets()))        
403                    
404 >---if req.GetSnapshotId() == "" {          
405 >--->---return nil, status.Error(codes.InvalidArgument, "missing snapshot id")  
406 >---}                 
407                 
408 >---if err := s.lvService.DeleteVolume(ctx, req.GetSnapshotId()); err != nil {  
409 >--->---ctrlLogger.Error(err, "DeleteSnapshot failed", "snapshot_id", req.GetSnapshotId())
410 >--->---_, ok := status.FromError(err)        
411 >--->---if !ok {         
412 >--->--->---return nil, status.Error(codes.Internal, err.Error())               
413 >--->---}         
414 >--->---return nil, err     
415 >---}            
416                   
417 >---return &csi.DeleteSnapshotResponse{}, nil                
418 } 
실행 #3

이 헌제님이 약 2달 전에 변경

  • 상태 항목을 변경했습니다 (검토 => 진행)
실행 #4

이 헌제님이 약 2달 전에 변경

  • snapshot restore
CreateVolume
source := req.GetVolumeContentSource() // 참고
실행 #5

이 헌제님이 약 2달 전에 변경

추가 필요 조사사항

  • 스냅샷 생성, 복구 yaml 정의 예제
실행 #6

이 헌제님이 약 2달 전에 변경

  • 점수 항목을 변경했습니다 (0.00 => 6.88)

진행상황

  • thin 볼륨 생성 예제 추가
    • 생성 시 10초 이상 걸리는 이슈가 있음 (gRPC timeout 10s)
    • HA 구성이 오래 걸리는 경우가 있는데, share 리소스 에이전트 확인으로 100s 이내 생성 (10번까지 생성 재시도)
  • 스냅샷 관련 sidecar 설치 make 추가
  • 스냅샷 API 연동 (생성, 삭제, 병합- 병합은 볼륨 생성에서 추가 param 이 있음)
  • 스냅샷 관련 예제 추가
  • volumesnapshotclass 를 helm 에 추가하여 기본 지정
  • 위 내용을 적용하여 테스트 중
실행

내보내기 Atom PDF

클립보드 이미지 추가 (최대 크기: 50 MB)