레이블이 pvc인 게시물을 표시합니다. 모든 게시물 표시
레이블이 pvc인 게시물을 표시합니다. 모든 게시물 표시

remove orphaned PVC stuck after a namespace deletion

네임스페이스가 삭제된 상태에 남아 있는 PVC 를 삭제하면 terminating 상태에서 진행이 되지 않는다.
pvc 의 finalizer 부분을 제거했는데 저장도 안된다.
# ysoftman-ns 네임스페이스 NotFound
kubectl get ns ysoftman-ns

# 고아 PVC 목록이 terminating 상태로 나온다.
kubectl get pvc -n ysoftman-ns

# finalizer 확인하면 삭제되지 않고 남아 있다.
kubectl get pvc -n ysoftman-ns vmselect-cachedir-...-0 -o jsonpath='{.metadata.finalizers}'

# 해결을 위해선 삭제된 네임스페이스를 다시 생성하면 된다.
# 네임스페이스 임시 재생성 (admission 거부를 풀기 위해)
kubectl create ns ysoftman-ns

# 이제 다시 PVC 전부 finalizer 제거
for pvc in $(kubectl get pvc -n ysoftman-ns -o name); do
  kubectl patch "$pvc" -n ysoftman-ns --type=merge -p '{"metadata":{"finalizers":null}}'
done

# 네임스페이스 재삭제
kubectl delete ns ysoftman-ns

install harbor

# chart 저장소로 chartmuseum 을 사용중이였는데 dashboard ui 가 없어 찾아 보니 chartmuseum-ui 가 있다.
# 그런데 chartmuseum-ui 는 helm 차트가 없고 현재 차트 업로드가 안되고 조회만 된다고 한다.
# harbor(https://github.com/goharbor/harbor) 는 CNCF 졸업한 프로젝트로 
# chart 외 Open Container Initiative(OCI) 표준을 따르는 컨테이너 이미지 및 기타 아티팩트(helm chart 파일)를 저장하고 
# 프로젝트별 구분 및 RBAC(롤 기반 접근제어)
# trivy(https://github.com/aquasecurity/trivy)를 통한 취약점 파악이 가능하다.
# 그리고 db(postgresql)를 사용해 아티팩트 사용에 대한 히스토리 및 push, pull 카운트도 알 수 있다.
# 물론 UI 도 있고, chartmuseum(3k) 보다 스타수도 26k로 많다.... 해서 harbor 를 설치해보자.

# harbor 2.x 에서는 chart 저장소가 chartmuseum 에서 oci 레지스트리로 변경되었다.
# harbor 2.8 (Apr 17, 2023) 부터 chartmuseum 을 지원하지 않는다.
# chart 는 image(artifact)와 동일하게 관리된다.

# harbor helm chart 다운로드
helm repo add harbor https://helm.goharbor.io
helm repo update
helm fetch harbor/harbor
tar zxvf harbor-1.17.1.tgz
cd harbor

# values.yaml 변경
# ingress, clusterIP, nodePort, loadBalancer (대소문자 구분) 중 하나를 선택하면 나머지 설정들은 스킵된다.
# nodePort 를 사용하면 기존 ClusterIP 타입의 서비스외  NodePort 타입의 harbor 서비스가 더 생성되고 여기서 기존 서비스들로 분배된다.(configmap > nginx.conf 참고)
expose.type: ingress
expose.tls.enabled: false

# harbor 접근할 웹 주소
expose.ingress.hosts.core: https://harbor.ysoftman.test

# docker 이미지나 helm chart 를 push/pull 할때 cli 명령에서 사용될 서버 주소
externalurl: https://harbor.ysoftman.test

# pv,pvc 기본으로 Container Storage Interface (CSI) 로 생성된다.
# pv,pvc 를 사용하면 파드를 삭제했다가 pvc 를 사용하는 새로운 파드를 다시 띄우면, k8s 는 기존 데이터가 남아있는 동일한 노드로 파드를 스케줄링(NodeAffinity)하여 이전 데이터를 그대로 이어받아 사용할 수 있다.
# kubectl get storageclasses 로 csi 가 연결된 스토리지 provisioner 확인
# csi 종류
# rancher.io/local-path 는 k8s 클러스터의 각 노드에 있는 로컬 스토리지를 Persistent Volume(PV)으로 사용해 emptyDir (Ephemeral Storage) 처럼 pod 삭제시 데이터가 날라가는것 방지할 수 있다.
# cinder.csi 는 openstack 환경에서 cinder API 호출하여 새로운 cinder 볼륨을 사용
# reclaimpolicy(pod 삭제시 pv등 정리 방법)는 delete 인 local-path 를 사용
persistence.persistentVolumeClaim.xxxxx.storageClass: "local-path-delete"

# 별도의 nfs 사용할 경우 pv, pvc 리소스를 추가하자.
# pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: ysoftman-harbor
spec:
  accessModes:
    - ReadWriteMany
  capacity:
    storage: 10Gi
  nfs:
    path: /xxxxx/ysoftman/harbor
    server: nfs.ysoftman.zzz
  persistentVolumeReclaimPolicy: Retain

# pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: ysoftman-harbor
  namespace: harbor
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 10Gi
  storageClassName: ""
  volumeName: ysoftman-harbor

# values.yaml 설정에서 existingClaim 명시
persistence.persistentVolumeClaim.xxxxx.storageClass: ""
persistence.persistentVolumeClaim.xxxxx.existingClaim: "ysoftman-harbor"

# harbor database(postgreSQL) 데이터 저장소로 nfs 사용시 권한 문제와 디렉터리 비어있지 않음등의 문제가 있다면 로컬 스토리지를 사용하자.
persistence.persistentVolumeClaim.database.storageClass: "local-path-delete"

# image/chart 저장소 타입 filesystem, azure, gcs, s3, swift 중 선택
persistence.imageChartStorage.type: filesystem

# image/chart filesystem 선택시 저장 경로
persistence.imageChartStorage.filesystem.rootdirectory: /storage

# 배포
helm upgrade --install harbor . \
--namespace harbor \
--create-namespace \
--values values.yaml

# 이제 admin / Harbor12345 로그인해서 메뉴에서 admin 암호를 변경(대소,특수,포함 8자리 이상등의 조건)한다.
https://harbor.ysoftman.test

#####

# nodePort 와 ingress 둘 다 사용하기
# ingress 상태로 띄우고
expose.type: ingress

# ingress 리소스를 templates/ysoftman_ingress.yaml 파일로 백업
kubectl get ing -o yaml > templates/ysoftman_ingress.yaml

# nodePort 로 다시 배포(helm upgrade)하면 nodePort 서비스가 추가된다.
expose.type: nodePort

# templates/ysoftman_ingress.yaml > backend service 를 NodePort 서비스명으로 변경 후 다시 배포(helm upgrade)

#####

# harbor database(postgresql)이 nfs로 저장이 안되고, 외부 gcs(google cloud storage), s3, 등을 사용할 수 없다면 덤프파일로 백업하자.

# database container 에 접속해서 psql 로 다음과 같이 사용자명과 db명을 파악하자.

# 로컬에서 접속할 수 있도록 port-foward
kubectl port-forward svc/harbor-database 5432:5432 -n harbor

# pg cli 툴 설치
# postgresql server 와 맞는 버전을 설치해야 한다.
# 14 버전 대신 15 버전으로 설치
brew unlink postgresql@14
brew install postgresql@15

# registry db 덤프
pg_dump -h localhost -p 5432 -U postgres -d registry > harbor_backup_20250807.sql

# 덤프 파일로 복구
psql -h localhost -p 5432 -U postgres -d registry < harbor_backup_20250807.sql

#####

# helm 3.7 부터는 oci registry 연동 시 https 만 지원하고 http 사용지 동작하지 않는다.
# oci 방식으로 저장된 차트는 url 로 다운로드가 할 수 없다.
# harbor ui 에서 올라간 차트 이미지에 대해 helm pull, docker pull 등의 커맨드를 클립보드로 복사하는 기능이 있다.

# harbor registry 로그인
helm registry login -u admin -p Harbor12345 https://harbor.ysoftman.test

# harbor 2.8 chartrepo 방식이 사라져 chartrepo 엔드포인트는 사용할 수 없고 oci 프로토콜로만 사용해야 한다.
# 차트 파일 library 프로젝트에 올리기
helm push ysoftman-chart-0.0.1.tgz oci://harbor.ysoftman.test/library

# library 프로젝트의 ysoftman 차트 다운로드
helm pull oci://harbor.ysoftman.test/library/ysoftman-chart --version 0.0.1

# docker 이미지 library 프로젝트로 태깅
docker tag aaa/ysoftman-image:dev harbor.ysoftman.test/library/ysoftman-image:dev

# docker 이미지 library 프로젝트에 올리기
docker push harbor.ysoftman.test/library/ysoftman:dev

# library 프로젝트의 ysoftman:dev 이미지 다운로드
docker pull harbor.ysoftman.test/library/ysoftman:dev

# harbor 버전 확인(로그인 메뉴 > about)
https://harbor.ysoftman.test/api/v2.0/systeminfo

k8s PersistentVolume 값 변경

# k8s PersistentVolume(pv) > nfs > ip 를 변경하고자 한다.
# patch 로 변경하면 다음과 같이 생성 후에는 변경할 수 없다고 나온다.
kubectl patch pv ysoftmanPV -p '{"spec":{"nfs":{"server":"10.10.10.10"}}}'
Forbidden: spec.persistentvolumesource is immutable after creation

# 참고로 pvc 용량 패치는 되는데, 용량을 줄이면 안된다.
kubectl patch pvc prometheus-1 -p '{"spec":{"resources":{"requests":{"storage":"10Gi"}}}}' -n monitoring
... spec.resources.requests.storage: Forbidden: field can not be less than previous value

# Available 아직 클레임에 바인딩되지 않은 사용할 수 있는 리소스
# Bound 볼륨이 클레임에 바인딩됨
# Released 클레임이 삭제되었지만 클러스터에서 아직 리소스를 반환하지 않음
# Failed 볼륨이 자동 반환에 실패함
status:
  phase: Bound

# claimRef 부분을 삭제하해 Available 상태로 만들 수 있다.
kubectl patch pv ysoftmanPV -p '{"spec":{"claimRef:"null}}'

# 하지만 pv 가 terminating 상태에서 삭제가 안된다.
# finalizers: 오브젝트 삭제 시 충족해야될 조건을 명시하는 곳
# kubernetes.io/pv-protection: pv, pvc 등에서 실수로 오브젝트 삭제를 막기위해 기본적으로 명시되어 있다.
kind: PersistentVolume
metadata:
  finalizers:
  - kubernetes.io/pv-protection

# 다음과 같이 finalizers 조건을 패치(또는 kubectl edit.. 로 해당 부분 삭제)하면, pv 가 삭제된다.
kubectl patch pv ysoftmanPV -p '{"metadata":{"finalizers":null}}'

#####

# 위 내용을 바탕으로 많은 PV 값을 수정해 반영하는 스크립트를 다음과 같이 작성한다.
# 우선 변경할 pv 들을 yaml 로 로컬에 백업해두자.
mkdir -p pv
for name in $(kubectl get pv -A | grep -i aaa | awk '{print $1}'); do 
    echo "backup pv manifest(yaml)... ./pv/$name.yaml"
    kubectl get pv $name -o yaml > ./pv/$name.yaml
done

# pv 삭제
for name in $(kubectl get pv -A | grep -i aaa | awk '{print $1}'); do 
    echo "delete pv manifest(yaml)"
    # delete 하면 terminating 상태가 유지되는데, 이때 finalizers > kubernetes.io/pv-protection 를 삭제해야 완전히 제거된다.
    kubectl delete pv $name & kubectl patch pv $name -p '{"metadata":{"finalizers":null}}'
done

# 백업해둔 pv yaml 에서 ip 만 변경해서 적용
for f in $(ls -1 ./pv); do 
    cat ./pv/$f | sed -e 's/server: 10.10.10.11/server: 10.10.10.12/'g | kubectl apply -f -
done

bitnami etcd snapshot 으로 복구하기

bitnami-etcd helm chart 옵션 중 snapshot 파일로 백업된 db를 복구하기 위해 다음과 같이 파라메터를 사용할 수 있다.
startFromSnapshot:
  enabled: true
  existingClaim: bitnami-etcd-snapshotter
  snapshotFilename: db-2023-01-20_05-00

다른곳의 phase 의 snaphot 파일을 sudo 로 복사해온 경우
uid 1001 로 변경해줘야 한다.
sudo chown 1001:root db-2023-01-20_05-00

위 설정을 적용 후 etcd 클러스터를 재시작했지만 스냅샷 db 가 복구되지 않았다.
그래서 etcd container 접속해 다음 명령으로 복구를 시도하니
etcdctl snapshot restore /snapshot/db-2023-01-20_05-00 --data-dir /bitnami/etcd/data
--> /bitnami/etcd/data 를 읽을 수 없다고 에러가 발생했다.

bitnami-etcd 는 다음과 같은 구성요소를 가지고 있다.
- etcd bitnami-etcd-snapshotter(cronjob) 으로 container /snapshots/db-xxxx 로 백업되고 있음
- Statefulsets(sts)는 etcd pod 3개를 관리(순차적으로 시작해야함)
- 각 etcd pod는 /bitnami/etcd/data 경로를 Persistentvolumeclaims(pvc)로 저장하고 있다.

[해결방법]
1.우선 Statefulsets(sts) 삭제로 etcd pod 를 제거한다.(pvc 사용처를 없앤다.)
2.data-bitnami-etcd-0~2 pod가 사용했던 Persistentvolumeclaims(pvc, /bitnami/etcd/data) 삭제를 삭제한다.
3.이제 다음과 같이 파일(container /snapshots/db-xxxx)명 명시하고 재시작
이제 etcdkeeper 등으로 보면 스냅샷 db 내용이 복구된것을 확인 할 수 있다.

[bitnami-etcd-snapshotter (pvc) 삭제된 경우]
startFromSnapshot > enables: false 로 적용하면 bitnami-etcd-snapshotter pvc 가 생성된다.
이후 startFromSnapshot 를 활성화할 수 있다.

Prev