CI/CD 2추차 - Helm, Tekton
5장 헬름
헬름이란 ?
- 커스터마이즈와 유사하지만 템플릿 기반 솔루션
- 커스터마이즈와 헬름의 차이점 중 하나는 chart 개념
- 패키지 관리자처럼 동작하여 버전관리, 공유, 배포 가능 Artifact를 생성
- chart는 공유 가능한 쿠버네티스 패지리
- 헬름은 애플리케이션의 ConfigMap이 변경되면 자동으로 롤링 업데이트가 시작되도록 하는 기능 몇가지를 제공
5.1 Creating a Helm Project
실습을 위한 kind ( k8s ) 배포
# kind create cluster --name myk8s --image kindest/node:v1.32.8 --config - <<EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 30000
hostPort: 30000
- containerPort: 30001
hostPort: 30001
EOF
Creating cluster "myk8s" ...
✓ Ensuring node image (kindest/node:v1.32.8) 🖼
✓ Preparing nodes 📦
✓ Writing configuration 📜
✓ Starting control-plane 🕹️
✓ Installing CNI 🔌
✓ Installing StorageClass 💾
Set kubectl context to "kind-myk8s"
You can now use your cluster with:
kubectl cluster-info --context kind-myk8s
Have a question, bug, or feature request? Let us know! https://kind.sigs.k8s.io/#community 🙂
헬름 챠트 디렉터리 레이아웃 생성
# 헬름 챠트 디렉터리 레이아웃 생성
mkdir pacman
mkdir pacman/templates
cd pacman
# 루트 디렉토리에 차트 정의 파일 작성 : 버전, 이름 등 정보
cat << EOF > Chart.yaml
apiVersion: v2
name: pacman
description: A Helm chart for Pacman
type: application
version: 0.1.0 # 차트 버전, 차트 정의가 바뀌면 업데이트한다
appVersion: "1.0.0" # 애플리케이션 버전
EOF
# templates 디렉터리에 Go 템플릿 언어와 Sprig 라이브러리의 템플릿 함수를 사용해 정의한 배포 템플릿 파일 작성 : 애플리케이션 배포
## deployment.yaml 파일에서 템플릿화 : dp 이름, app 버전, replicas 수, 이미지/태그, 이미지 풀 정책, 보안 컨텍스트, 포트
cat << EOF > templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Chart.Name}} # Chart.yaml 파일에 설정된 이름을 가져와 설정
labels:
app.kubernetes.io/name: {{ .Chart.Name}}
{{- if .Chart.AppVersion }} # Chart.yaml 파일에 appVersion 여부에 따라 버전을 설정
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} # appVersion 값을 가져와 지정하고 따움표 처리
{{- end }}
spec:
replicas: {{ .Values.replicaCount }} # replicaCount 속성을 넣을 자리 placeholder
selector:
matchLabels:
app.kubernetes.io/name: {{ .Chart.Name}}
template:
metadata:
labels:
app.kubernetes.io/name: {{ .Chart.Name}}
spec:
containers:
- image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion}}" # 이미지 지정 placeholder, 이미지 태그가 있으 면 넣고, 없으면 Chart.yaml에 값을 설정
imagePullPolicy: {{ .Values.image.pullPolicy }}
securityContext:
{{- toYaml .Values.securityContext | nindent 14 }} # securityContext의 값을 YAML 객체로 지정하며 14칸 들여쓰기
name: {{ .Chart.Name}}
ports:
- containerPort: {{ .Values.image.containerPort }}
name: http
protocol: TCP
EOF
# service.yaml 파일에서 템플릿화 : service 이름, 컨테이너 포트
minji ~/Desktop/work/Gasida_series/practice/pacman cat << EOF > templates/service.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/name: {{ .Chart.Name }}
name: {{ .Chart.Name }}
spec:
ports:
- name: http
port: {{ .Values.image.containerPort }}
targetPort: {{ .Values.image.containerPort }}
selector:
app.kubernetes.io/name: {{ .Chart.Name }}
EOF
# 차트 기본값 default values이 담긴 파일 작성 : 애플리케이션 배포 시점에 다른 값으로 대체될 수 있는, 기본 설정을 담아두는 곳
minji ~/Desktop/work/Gasida_series/practice/pacman cat << EOF > values.yaml
image: # image 절 정의
repository: quay.io/gitops-cookbook/pacman-kikd
tag: "1.0.0"
pullPolicy: Always
containerPort: 8080
replicaCount: 1
securityContext: {} # securityContext 속성의 값을 비운다
EOF
# 디렉터리 레이아웃 확인
minji ~/Desktop/work/Gasida_series/practice/pacman tree
.
├── Chart.yaml
├── templates
│ ├── deployment.yaml
│ └── service.yaml
└── values.yaml
헬름 차트를 로컬에서 Yaml로 렌더링
minji ~/Desktop/work/Gasida_series/practice/pacman helm template .
---
# Source: pacman/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/name: pacman
name: pacman
spec:
ports:
- name: http
port: 8080
targetPort: 8080
selector:
app.kubernetes.io/name: pacman
---
# Source: pacman/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: pacman # Chart.yaml 파일에 설정된 이름을 가져와 설정
labels:
app.kubernetes.io/name: pacman # Chart.yaml 파일에 appVersion 여부에 따라 버전을 설정
app.kubernetes.io/version: "1.0.0" # appVersion 값을 가져와 지정하고 따움표 처리
spec:
replicas: 1 # replicaCount 속성을 넣을 자리 placeholder
selector:
matchLabels:
app.kubernetes.io/name: pacman
template:
metadata:
labels:
app.kubernetes.io/name: pacman
spec:
containers:
- image: "quay.io/gitops-cookbook/pacman-kikd:1.0.0" # 이미지 지정 placeholder, 이미지 태그가 있으면 넣고, 없으면 Chart.yaml에 값을 설정
imagePullPolicy: Always
securityContext:
{} # securityContext의 값을 YAML 객체로 지정하며 14칸 들여쓰기
name: pacman
ports:
- containerPort: 8080
name: http
protocol: TCP
# --set 파라미터를 사용하여 기본값을 재정의
minji ~/Desktop/work/Gasida_series/practice/pacman helm template --set replicaCount=3 .
---
# Source: pacman/templates/service.yaml
.
spec:
replicas: 3 # replicaCount 속성을 넣을 자리 placeholder
.
해당 챠트를 kind ( k8s )배포 및 helm 확인
# 해당 차트 배포
minji ~/Desktop/work/Gasida_series/practice/pacman helm install pacman .
NAME: pacman
LAST DEPLOYED: Thu Oct 23 22:27:43 2025
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
minji ~/Desktop/work/Gasida_series/practice/pacman helm list
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
pacman default 1 2025-10-23 22:27:43.064742 +0900 KST deployed pacman-0.1.0 1.0.0
# 배포된 리소스 확인
minji ~/Desktop/work/Gasida_series/practice/pacman kubectl get deploy,pod,svc,ep
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/pacman 1/1 1 1 108s
NAME READY STATUS RESTARTS AGE
pod/pacman-576769bb86-pqkg7 1/1 Running 0 108s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 18m
service/pacman ClusterIP 10.96.184.154 <none> 8080/TCP 108s
NAME ENDPOINTS AGE
endpoints/kubernetes 192.168.97.2:6443 18m
endpoints/pacman 10.244.0.5:8080 108s
minji ~/Desktop/work/Gasida_series/practice/pacman kubectl get pod -o yaml | kubectl neat | yq # kubectl krew install neat
apiVersion: v1
items:
- apiVersion: v1
kind: Pod
metadata:
labels:
app.kubernetes.io/name: pacman
pod-template-hash: 576769bb86
name: pacman-576769bb86-pqkg7
namespace: default
spec:
containers:
- image: quay.io/gitops-cookbook/pacman-kikd:1.0.0
imagePullPolicy: Always
name: pacman
ports:
- containerPort: 8080
name: http
volumeMounts:
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: kube-api-access-dzgc2
readOnly: true
preemptionPolicy: PreemptLowerPriority
priority: 0
serviceAccountName: default
tolerations:
- effect: NoExecute
key: node.kubernetes.io/not-ready
operator: Exists
tolerationSeconds: 300
- effect: NoExecute
key: node.kubernetes.io/unreachable
operator: Exists
tolerationSeconds: 300
volumes:
- name: kube-api-access-dzgc2
projected:
sources:
- serviceAccountToken:
expirationSeconds: 3607
path: token
- configMap:
items:
- key: ca.crt
path: ca.crt
name: kube-root-ca.crt
- downwardAPI:
items:
- fieldRef:
fieldPath: metadata.namespace
path: namespace
kind: List
metadata: {}
minji ~/Desktop/work/Gasida_series/practice/pacman kubectl get pod -o json | grep securityContext -A1
"securityContext": {},
"terminationMessagePath": "/dev/termination-log",
--
"securityContext": {},
"serviceAccount": "default",
##
minji ~/Desktop/work/Gasida_series/practice/pacman helm history pacman
REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION
1 Thu Oct 23 22:27:43 2025 deployed pacman-0.1.0 1.0.0 Install complete
# Helm 자체가 배포 릴리스 메타데이터를 저장하기 위해 자동으로 Sercet 리소스 생성 : Helm이 차트의 상태를 복구하거나 rollback 할 때 이 데이터를 이용
minji ~/Desktop/work/Gasida_series/practice/pacman kubectl get secret
NAME TYPE DATA AGE
sh.helm.release.v1.pacman.v1 helm.sh/release.v1 1 11m
업그레이드, 메타데이터 확인
##
minji ~/Desktop/work/Gasida_series/practice/pacman helm upgrade pacman --reuse-values --set relicaCount=2 .
Release "pacman" has been upgraded. Happy Helming!
NAME: pacman
LAST DEPLOYED: Thu Oct 23 22:39:50 2025
NAMESPACE: default
STATUS: deployed
REVISION: 2
TEST SUITE: None
##
minji ~/Desktop/work/Gasida_series/practice/pacman kubectl get pod
NAME READY STATUS RESTARTS AGE
pacman-576769bb86-pqkg7 1/1 Running 0 12m
# helm 배포 정보 확인
#-1. 모든 정보
minji ~/Desktop/work/Gasida_series/practice/pacman helm get all pacman
NAME: pacman
LAST DEPLOYED: Thu Oct 23 22:39:50 2025
NAMESPACE: default
STATUS: deployed
REVISION: 2
CHART: pacman
VERSION: 0.1.0
APP_VERSION: 1.0.0
TEST SUITE: None
USER-SUPPLIED VALUES:
relicaCount: 2
COMPUTED VALUES:
image:
containerPort: 8080
pullPolicy: Always
repository: quay.io/gitops-cookbook/pacman-kikd
tag: 1.0.0
relicaCount: 2
replicaCount: 1
securityContext: {}
HOOKS:
MANIFEST:
---
# Source: pacman/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/name: pacman
name: pacman
spec:
ports:
- name: http
port: 8080
targetPort: 8080
selector:
app.kubernetes.io/name: pacman
---
# Source: pacman/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: pacman # Chart.yaml 파일에 설정된 이름을 가져와 설정
labels:
app.kubernetes.io/name: pacman # Chart.yaml 파일에 appVersion 여부에 따라 버전을 설정
app.kubernetes.io/version: "1.0.0" # appVersion 값을 가져와 지정하고 따움표 처리
spec:
replicas: 1 # replicaCount 속성을 넣을 자리 placeholder
selector:
matchLabels:
app.kubernetes.io/name: pacman
template:
metadata:
labels:
app.kubernetes.io/name: pacman
spec:
containers:
- image: "quay.io/gitops-cookbook/pacman-kikd:1.0.0" # 이미지 지정 placeholder, 이미지 태그가 있으면 넣고, 없으면 Chart.yaml에 값을 설정
imagePullPolicy: Always
securityContext:
{} # securityContext의 값을 YAML 객체로 지정하며 14칸 들여쓰기
name: pacman
ports:
- containerPort: 8080
name: http
protocol: TCP
#-2. values 적용 정보
minji ~/Desktop/work/Gasida_series/practice/pacman helm get values pacman
USER-SUPPLIED VALUES:
relicaCount: 2
#-3. 실제 적용된 manifest
minji ~/Desktop/work/Gasida_series/practice/pacman helm get manifest pacman
---
# Source: pacman/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/name: pacman
name: pacman
spec:
ports:
- name: http
port: 8080
targetPort: 8080
selector:
app.kubernetes.io/name: pacman
---
# Source: pacman/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: pacman # Chart.yaml 파일에 설정된 이름을 가져와 설정
labels:
app.kubernetes.io/name: pacman # Chart.yaml 파일에 appVersion 여부에 따라 버전을 설정
app.kubernetes.io/version: "1.0.0" # appVersion 값을 가져와 지정하고 따움표 처리
spec:
replicas: 1 # replicaCount 속성을 넣을 자리 placeholder
selector:
matchLabels:
app.kubernetes.io/name: pacman
template:
metadata:
labels:
app.kubernetes.io/name: pacman
spec:
containers:
- image: "quay.io/gitops-cookbook/pacman-kikd:1.0.0" # 이미지 지정 placeholder, 이미지 태그가 있으면 넣고, 없으면 Chart.yaml에 값을 설정
imagePullPolicy: Always
securityContext:
{} # securityContext의 값을 YAML 객체로 지정하며 14칸 들여쓰기
name: pacman
ports:
- containerPort: 8080
name: http
protocol: TCP
# chart nodes
minji ~/Desktop/work/Gasida_series/practice/pacman helm get notes pacman
# 삭제 후 secret 확인
minji ~/Desktop/work/Gasida_series/practice/pacman helm uninstall pacman
release "pacman" uninstalled
minji ~/Desktop/work/Gasida_series/practice/pacman kubectl get secret
No resources found in default namespace.
5.2 Reusing Statements Between Templates
같은 코드 확인 및 재사용 가능 코드 블록 정의
# deployment.yaml, service.yaml 에 selector 필드가 동일
## deployment.yaml
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app.kubernetes.io/name: {{ .Chart.Name}}
template:
metadata:
labels:
app.kubernetes.io/name: {{ .Chart.Name}}
## service.yaml
selector:
app.kubernetes.io/name: {{ .Chart.Name }}
## 이 필드를 업데이트하려면(selector 필드에 새 레이블 추가 등) 3곳을 똑같이 업데이트 해야함
# 템플릿 디렉터리에 _helpers.tpl 파일을 만들고 그 안에 재사용 가능한 템플릿 코드를 두어 재사용할 수 있게 기존 코드를 디렉터링하자
## _helpers.tpl 파일 작성
minji ~/Desktop/work/Gasida_series/practice cat << EOF > templates/_helpers.tpl
{{- define "pacman.selectorLabels" -}} # stetement 이름을 정의
app.kubernetes.io/name: {{ .Chart.Name}} # 해당 stetement 가 하는 일을 정의
{{- end }}
EOF
## deployment.yaml 수정
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "pacman.selectorLabels" . | nindent 6 }} # pacman.selectorLabels를 호출한 결과를 6만큼 들여쓰기하여 주입
template:
metadata:
labels:
{{- include "pacman.selectorLabels" . | nindent 8 }} # pacman.selectorLabels를 호출한 결과를 8만큼 들여쓰기하여 주입
## service.yaml 수정
selector:
{{- include "pacman.selectorLabels" . | nindent 6 }}
minji ~/Desktop/work/Gasida_series/practice/pacman helm template .
---
# Source: pacman/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/name: pacman
name: pacman
spec:
ports:
- name: http
port: 8080
targetPort: 8080
selector:
app.kubernetes.io/name: pacman
app.kubernetes.io/version: 1.0.0
---
# Source: pacman/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: pacman # Chart.yaml 파일에 설정된 이름을 가져와 설정
labels:
app.kubernetes.io/name: pacman # Chart.yaml 파일에 appVersion 여부에 따라 버전을 설정
app.kubernetes.io/version: "1.0.0" # appVersion 값을 가져와 지정하고 따움표 처리
spec:
replicas: 1 # replicaCount 속성을 넣을 자리 placeholder
selector:
matchLabels:
app.kubernetes.io/name: pacman
app.kubernetes.io/version: 1.0.0 # pacman.selectorLabels를 호출한 결과를 6만큼 들여쓰기하여 주입
template:
metadata:
labels:
app.kubernetes.io/name: pacman
app.kubernetes.io/version: 1.0.0 # pacman.selectorLabels를 호출한 결과를 8만큼 들여쓰기하여 주입
spec:
containers:
- image: "quay.io/gitops-cookbook/pacman-kikd:1.0.0" # 이미지 지정 placeholder, 이미지 태그가 있으면 넣고, 없으면 Chart.yaml에 값을 설정
imagePullPolicy: Always
securityContext:
{} # securityContext의 값을 YAML 객체로 지정하며 14칸 들여쓰기
name: pacman
ports:
- containerPort: 8080
name: http
protocol: TCP
5.3 Updating a Container Image in Helm
차트 배포
# _helpers.tpl 파일 초기 설정으로 수정
minji ~/Desktop/work/Gasida_series/practice/pacman cat << EOF > templates/_helpers.tpl
{{- define "pacman.selectorLabels" -}}
app.kubernetes.io/name: {{ .Chart.Name}}
{{- end }}
EOF
# helm 배포
minji ~/Desktop/work/Gasida_series/practice/pacman helm install pacman .
NAME: pacman
LAST DEPLOYED: Thu Oct 23 23:32:37 2025
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
# 확인 : 리비전 번호, 이미지 정보 확인
minji ~/Desktop/work/Gasida_series/practice/pacman helm history pacman
REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION
1 Thu Oct 23 23:32:37 2025 deployed pacman-0.1.0 1.0.0 Install complete
minji ~/Desktop/work/Gasida_series/practice/pacman kubectl get deploy -owide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
pacman 1/1 1 1 84s pacman quay.io/gitops-cookbook/pacman-kikd:1.0.0 app.kubernetes.io/name=pacman
1.1.0 으로 이미지 갱신
# values.yaml에 이미지 태그 업데이트
minji ~/Desktop/work/Gasida_series/practice/pacman cat << EOF > values.yaml
image:
repository: quay.io/gitops-cookbook/pacman-kikd
tag: "1.1.0"
pullPolicy: Always
containerPort: 8080
replicaCount: 1
securityContext: {}
EOF
# Chart.yaml 파일에 appVersion 필드 갱신
minji ~/Desktop/work/Gasida_series/practice/pacman cat << EOF > Chart.yaml
apiVersion: v2
name: pacman
description: A Helm chart for Pacman
type: application
version: 0.1.0
appVersion: "1.1.0"
EOF
# 배포 업그레이드
minji ~/Desktop/work/Gasida_series/practice/pacman helm upgrade pacman .
Release "pacman" has been upgraded. Happy Helming!
NAME: pacman
LAST DEPLOYED: Thu Oct 23 23:36:24 2025
NAMESPACE: default
STATUS: deployed
REVISION: 2
TEST SUITE: None
# 확인
minji ~/Desktop/work/Gasida_series/practice/pacman helm history pacman
REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION
1 Thu Oct 23 23:32:37 2025 superseded pacman-0.1.0 1.0.0 Install complete
2 Thu Oct 23 23:36:24 2025 deployed pacman-0.1.0 1.1.0 Upgrade complete
minji ~/Desktop/work/Gasida_series/practice/pacman kubectl get secret
NAME TYPE DATA AGE
sh.helm.release.v1.pacman.v1 helm.sh/release.v1 1 4m16s
sh.helm.release.v1.pacman.v2 helm.sh/release.v1 1 29s
minji ~/Desktop/work/Gasida_series/practice/pacman kubectl get deploy,replicaset -owide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
deployment.apps/pacman 1/1 1 1 4m30s pacman quay.io/gitops-cookbook/pacman-kikd:1.1.0 app.kubernetes.io/name=pacman
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
replicaset.apps/pacman-576769bb86 0 0 0 4m30s pacman quay.io/gitops-cookbook/pacman-kikd:1.0.0 app.kubernetes.io/name=pacman,pod-template-hash=576769bb86
replicaset.apps/pacman-64c54b85f9 1 1 1 43s pacman quay.io/gitops-cookbook/pacman-kikd:1.1.0 app.kubernetes.io/name=pacman,pod-template-hash=64c54b85f9
여기서 잠깐
두 개의 개별 필드 ( tag, appVersion)대신 appVersion을 tag로도 쓰는 방법을 생각해 볼 수 있다.
버전 필드의 쓰임새, 버전 관리 전략, 소프트웨어 수명 주기에 따라 어느쪽으로 할지 정할 필요가 있다.
appVersion은 애플리케이션의 버전이므로 애플리케이션을 변경할 때 마다 업데이트가 필요
한편 version은 chart버전이기 때문에 chart정의 ( 템플릿 등 )가 변경되면 갱신한다.
따라서 두 필드는 서로 관계가 없다
이전 버전으로 롤백
# 이전 버전으로 롤백
minji ~/Desktop/work/Gasida_series/practice/pacman helm rollback pacman 1 && kubectl get pod -w
Rollback was a success! Happy Helming!
NAME READY STATUS RESTARTS AGE
pacman-576769bb86-t5scc 0/1 ContainerCreating 0 0s
pacman-64c54b85f9-xqx2n 1/1 Running 0 2m44s
pacman-576769bb86-t5scc 1/1 Running 0 3s
pacman-64c54b85f9-xqx2n 1/1 Terminating 0 2m47s
pacman-64c54b85f9-xqx2n 0/1 Error 0 2m47s
pacman-64c54b85f9-xqx2n 0/1 Error 0 2m48s
pacman-64c54b85f9-xqx2n 0/1 Error 0 2m48s
# 확인
minji ~/Desktop/work/Gasida_series/practice/pacman helm history pacman
REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION
1 Thu Oct 23 23:32:37 2025 superseded pacman-0.1.0 1.0.0 Install complete
2 Thu Oct 23 23:36:24 2025 superseded pacman-0.1.0 1.1.0 Upgrade complete
3 Thu Oct 23 23:39:08 2025 superseded pacman-0.1.0 1.0.0 Rollback to 1
4 Thu Oct 23 23:40:12 2025 deployed pacman-0.1.0 1.0.0 Rollback to 1
minji ~/Desktop/work/Gasida_series/practice/pacman kubectl get secret
NAME TYPE DATA AGE
sh.helm.release.v1.pacman.v1 helm.sh/release.v1 1 10m
sh.helm.release.v1.pacman.v2 helm.sh/release.v1 1 7m3s
sh.helm.release.v1.pacman.v3 helm.sh/release.v1 1 4m19s
sh.helm.release.v1.pacman.v4 helm.sh/release.v1 1 3m15s
minji ~/Desktop/work/Gasida_series/practice/pacman kubectl get deploy,replicaset -owide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
deployment.apps/pacman 1/1 1 1 11m pacman quay.io/gitops-cookbook/pacman-kikd:1.0.0 app.kubernetes.io/name=pacman
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
replicaset.apps/pacman-576769bb86 1 1 1 11m pacman quay.io/gitops-cookbook/pacman-kikd:1.0.0 app.kubernetes.io/name=pacman,pod-template-hash=576769bb86
replicaset.apps/pacman-64c54b85f9 0 0 0 7m37s pacman quay.io/gitops-cookbook/pacman-kikd:1.1.0 app.kubernetes.io/name=pacman,pod-template-hash=64c54b85f9
values yaml file override
# value 새 파일 작성
minji ~/Desktop/work/Gasida_series/practice/pacman cat << EOF > newvalues.yaml
image:
tag: "1.2.0"
EOF
# template 명령 실행 시 새 values 파일 함께 전달 : 결과적으로 values.yaml 기본값을 사용하지만, image.tag 값은 override 함
minji ~/Desktop/work/Gasida_series/practice/pacman helm template pacman -f newvalues.yaml .
---
# Source: pacman/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/name: pacman
name: pacman
spec:
ports:
- name: http
port: 8080
targetPort: 8080
selector:
app.kubernetes.io/name: pacman
---
# Source: pacman/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: pacman # Chart.yaml 파일에 설정된 이름을 가져와 설정
labels:
app.kubernetes.io/name: pacman # Chart.yaml 파일에 appVersion 여부에 따라 버전을 설정
app.kubernetes.io/version: "1.1.0" # appVersion 값을 가져와 지정하고 따움표 처리
spec:
replicas: 1 # replicaCount 속성을 넣을 자리 placeholder
selector:
matchLabels:
app.kubernetes.io/name: pacman # pacman.selectorLabels를 호출한 결과를 6만큼 들여쓰기하여 주입
template:
metadata:
labels:
app.kubernetes.io/name: pacman # pacman.selectorLabels를 호출한 결과를 8만큼 들여쓰기하여 주입
spec:
containers:
- image: "quay.io/gitops-cookbook/pacman-kikd:1.2.0" # 이미지 지정 placeholder, 이미지 태그가 있으면 넣고, 없으면 Chart.yaml에 값을 설정
imagePullPolicy: Always
securityContext:
{} # securityContext의 값을 YAML 객체로 지정하며 14칸 들여쓰기
name: pacman
ports:
- containerPort: 8080
name: http
protocol: TCP
5.4 Packaging and Distributing a Helm Chart
helm chart를 패키징하고 공개하여 다른 차트의 의존성으로 이용될 수 있도록 하거나 다른 사용자가 시스템에 배포할 수 있도록 하는 방법을 알아보자
# pacman 차트를 .tgz 파일로 패키징
minji ~/Desktop/work/Gasida_series/practice/pacman helm package .
Successfully packaged chart and saved it to: /Users/howoo/Desktop/work/Gasida_series/practice/pacman/pacman-0.1.0.tgz
minji ~/Desktop/work/Gasida_series/practice/pacman gzcat pacman-0.1.0.tgz
pacman/Chart.yaml0000644000000000000000000000016415076440060012433 0ustar0000000000000000apiVersion: v2
appVersion: 1.1.0
description: A Helm chart for Pacman
name: pacman
type: application
version: 0.1.0
pacman/values.yaml0000644000000000000000000000023015076440060012663 0ustar0000000000000000image:
repository: quay.io/gitops-cookbook/pacman-kikd
tag: "1.1.0"
pullPolicy: Always
containerPort: 8080
replicaCount: 1
securityContext: {}
pacman/templates/_helpers.tpl0000644000000000000000000000013315076440060015022 0ustar0000000000000000{{- define "pacman.selectorLabels" -}}
app.kubernetes.io/name: {{ .Chart.Name}}
{{- end }}
pacman/templates/deployment.yaml0000644000000000000000000000276515076440060015561 0ustar0000000000000000apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Chart.Name}} # Chart.yaml 파일에 설정된 이름을 가져와 설정
labels:
app.kubernetes.io/name: {{ .Chart.Name}}
{{- if .Chart.AppVersion }} # Chart.yaml 파일에 appVersion 여부에 따라 버전을 설정
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} # appVersion 값을 가져와 지정하고 따움표 처리
{{- end }}
spec:
replicas: {{ .Values.replicaCount }} # replicaCount 속성을 넣을 자리 placeholder
selector:
matchLabels:
{{- include "pacman.selectorLabels" . | nindent 6 }} # pacman.selectorLabels를 호출한 결과를 6만큼 들여쓰기하여 주입
template:
metadata:
labels:
{{- include "pacman.selectorLabels" . | nindent 8 }} # pacman.selectorLabels를 호출한 결과를 8만큼 들여쓰기하여 주입
spec:
containers:
- image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion}}" # 이미지 지정 placeholder, 이미지 태그가 있으면 넣고, 없으면 Chart.yaml에 값을 설정
imagePullPolicy: {{ .Values.image.pullPolicy }}
securityContext:
{{- toYaml .Values.securityContext | nindent 14 }} # securityContext의 값을 YAML 객체로 지정하며 14칸 들여쓰기
name: {{ .Chart.Name}}
ports:
- containerPort: {{ .Values.image.containerPort }}
name: http
protocol: TCP
pacman/templates/service.yaml0000644000000000000000000000050015076440060015022 0ustar0000000000000000apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/name: {{ .Chart.Name }}
name: {{ .Chart.Name }}
spec:
ports:
- name: http
port: {{ .Values.image.containerPort }}
targetPort: {{ .Values.image.containerPort }}
selector:
{{- include "pacman.selectorLabels" . | nindent 6 }}
pacman/newvalues.yaml0000644000000000000000000000002615076440060013400 0ustar0000000000000000image:
tag: "1.2.0"
# 해당 차트를 차트 저장소 repository 에 게시
# 차트 저장소는 차트 및 .tgz 차트에 대한 메타데이터 정보를 담은 index.html 파일이 있는 HTTP 서버
# 차트를 저장소에 게시하려면 index.html 파일을 새 메타데이터 정보로 업데이트하고 아티팩트를 업로드해야 한다.
# index.html file 생성
minji ~/Desktop/work/Gasida_series/practice/pacman helm repo index .
minji ~/Desktop/work/Gasida_series/practice/pacman
minji ~/Desktop/work/Gasida_series/practice/pacman cat index.yaml
apiVersion: v1
entries:
pacman:
- apiVersion: v2
appVersion: 1.1.0
created: "2025-10-23T23:50:45.092915+09:00"
description: A Helm chart for Pacman
digest: ecf7e2eb903a569ede9d11c989f76895d72850c653b630aa213835e5efe9a2b8
name: pacman
type: application
urls:
- pacman-0.1.0.tgz
version: 0.1.0
generated: "2025-10-23T23:50:45.092641+09:00"
※ Bitnami 공개 카탈로그 삭제
Bitnamo Helm Charts : 컨테이너 이미지 Tag ( latest )
# Bitnami nginx 의 OCI 주소
oci://registry-1.docker.io/bitnamicharts/nginx
# 기존 식 helm repo 확인
# helm 저장소를 추가 하지 않았으므로 Error
minji ~ helm repo list
Error: no repositories to show
# helm chart 가져오기
minji ~ helm pull oci://registry-1.docker.io/bitnamicharts/nginx --version 22.0.11
Pulled: registry-1.docker.io/bitnamicharts/nginx:22.0.11
Digest: sha256:22c9a95eced446e53f75fa41764059812049cfcbabe273942ea46b69183b496d
# 파일 목록 확인
minji ~ tar -tf nginx-22.0.11.tgz
nginx/
nginx/charts/
nginx/charts/common/
nginx/charts/common/templates/
nginx/charts/common/templates/validations/
nginx/templates/
.
.
.
# helm show 명령
## helm show readme oci://registry-1.docker.io/bitnamicharts/nginx
.
.
.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
<http://www.apache.org/licenses/LICENSE-2.0>
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
## helm show values oci://registry-1.docker.io/bitnamicharts/nginx
.
.
.
## @param metrics.startupProbe.successThreshold Success threshold for startupProbe
##
startupProbe:
enabled: false
initialDelaySeconds: 5
timeoutSeconds: 3
periodSeconds: 5
failureThreshold: 10
successThreshold: 1
## helm show chart oci://registry-1.docker.io/bitnamicharts/nginx
.
.
.
icon: https://dyltqmyl993wv.cloudfront.net/assets/stacks/nginx/img/nginx-stack-220x234.png
keywords:
- nginx
- http
- web
- www
- reverse proxy
maintainers:
- name: Broadcom, Inc. All Rights Reserved.
url: https://github.com/bitnami/charts
name: nginx
sources:
- https://github.com/bitnami/charts/tree/main/bitnami/nginx
version: 22.1.1
# helm chart 바로 설치
minji ~ helm install my-nginx oci://registry-1.docker.io/bitnamicharts/nginx --version 22.0.11
Pulled: registry-1.docker.io/bitnamicharts/nginx:22.0.11
Digest: sha256:22c9a95eced446e53f75fa41764059812049cfcbabe273942ea46b69183b496d
NAME: my-nginx
LAST DEPLOYED: Fri Oct 24 20:30:07 2025
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
CHART NAME: nginx
CHART VERSION: 22.0.11
APP VERSION: 1.29.2
.
.
.
minji ~ helm repo list
Error: no repositories to show
# helm 확인
minji ~ helm repo list
Error: no repositories to show
minji ~ helm list
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
my-nginx default 1 2025-10-24 20:30:07.731724 +0900 KST deployed nginx-22.0.11 1.29.2
pacman default 4 2025-10-23 23:40:12.59885 +0900 KST deployed pacman-0.1.0 1.0.0
minji ~ helm get metadata my-nginx
NAME: my-nginx
CHART: nginx
VERSION: 22.0.11
APP_VERSION: 1.29.2
ANNOTATIONS: fips=true,images=- name: git
version: 2.51.0
image: registry-1.docker.io/bitnami/git:latest
- name: nginx
version: 1.29.2
image: registry-1.docker.io/bitnami/nginx:latest
- name: nginx-exporter
version: 1.5.0
image: registry-1.docker.io/bitnami/nginx-exporter:latest
,licenses=Apache-2.0,tanzuCategory=clusterUtility
DEPENDENCIES: common
NAMESPACE: default
REVISION: 1
STATUS: deployed
DEPLOYED_AT: 2025-10-24T20:30:07+09:00
# deployment 확인 : IMAGES tags 확인
minji ~ kubectl get deploy -owide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
my-nginx 1/1 1 1 2m30s nginx registry-1.docker.io/bitnami/nginx:latest app.kubernetes.io/instance=my-nginx,app.kubernetes.io/name=nginx
pacman 1/1 1 1 21h pacman quay.io/gitops-cookbook/pacman-kikd:1.0.0 app.kubernetes.io/name=pacman
minji ~ helm get manifest my-nginx | grep 'image:'
image: registry-1.docker.io/bitnami/nginx:latest
image: registry-1.docker.io/bitnami/nginx:latest
# 삭제
minji ~ helm uninstall my-nginx
release "my-nginx" uninstalled
5.5 Deploying a Chart from a Repository
Bitnami / postgresql 배포 실습
# repo
minji ~ helm repo add bitnami https://charts.bitnami.com/bitnami
"bitnami" has been added to your repositories
minji ~ helm repo list
NAME URL
bitnami https://charts.bitnami.com/bitnami
minji ~ helm search repo postgresql
NAME CHART VERSION APP VERSION DESCRIPTION
bitnami/postgresql 18.1.1 18.0.0 PostgreSQL (Postgres) is an open source object-...
bitnami/postgresql-ha 16.3.2 17.6.0 This PostgreSQL cluster solution includes the P...
bitnami/cloudnative-pg 1.0.11 1.26.1 CloudNativePG is an open-source tool for managi...
bitnami/supabase 5.3.6 1.24.7 DEPRECATED Supabase is an open source Firebase ...
bitnami/minio-operator 0.2.9 7.1.1 MinIO(R) Operator is a Kubernetes-native tool f...
minji ~ helm search repo postgresql -o json | jq
[
{
"name": "bitnami/postgresql",
"version": "18.1.1",
"app_version": "18.0.0",
"description": "PostgreSQL (Postgres) is an open source object-relational database known for reliability and data integrity. ACID-compliant, it supports foreign keys, joins, views, triggers and stored procedures."
},
{
"name": "bitnami/postgresql-ha",
"version": "16.3.2",
"app_version": "17.6.0",
"description": "This PostgreSQL cluster solution includes the PostgreSQL replication manager, an open-source tool for managing replication and failover on PostgreSQL clusters."
},
{
"name": "bitnami/cloudnative-pg",
"version": "1.0.11",
"app_version": "1.26.1",
"description": "CloudNativePG is an open-source tool for managing PostgreSQL databases on Kubernetes, from setup to ongoing upkeep."
},
{
"name": "bitnami/supabase",
"version": "5.3.6",
"app_version": "1.24.7",
"description": "DEPRECATED Supabase is an open source Firebase alternative. Provides all the necessary backend features to build your application in a scalable way. Uses PostgreSQL as datastore."
},
{
"name": "bitnami/minio-operator",
"version": "0.2.9",
"app_version": "7.1.1",
"description": "MinIO(R) Operator is a Kubernetes-native tool for deploying and managing high-performance, S3-compatible MinIO(R) object storage across hybrid cloud infrastructures."
}
]
# 배포
minji ~ helm install my-db \
--set postgresql.postgresqlUsername=my-default,postgresql.postgresqlPassword=postgres,postgresql.postgresqlDatabase=mydb,postgresql.persistence.enabled=false \
bitnami/postgresql
NAME: my-db
LAST DEPLOYED: Fri Oct 24 20:36:45 2025
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
CHART NAME: postgresql
CHART VERSION: 18.1.1
APP VERSION: 18.0.0
.
.
.
WARNING: There are "resources" sections in the chart not set. Using "resourcesPreset" is not recommended for production. For production installations, please set the following values according to your workload needs:
- primary.resources
- readReplicas.resources
+info https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
# 확인
minji ~ helm list
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
my-db default 1 2025-10-24 20:36:45.218051 +0900 KST deployed postgresql-18.1.1 18.0.0
pacman default 4 2025-10-23 23:40:12.59885 +0900 KST deployed pacman-0.1.0 1.0.0
minji ~ kubectl get sts,pod,svc,ep,secret
NAME READY AGE
statefulset.apps/my-db-postgresql 1/1 77s
NAME READY STATUS RESTARTS AGE
pod/my-db-postgresql-0 1/1 Running 0 77s
pod/pacman-576769bb86-t5scc 1/1 Running 2 (18m ago) 20h
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 22h
service/my-db-postgresql ClusterIP 10.96.23.246 <none> 5432/TCP 77s
service/my-db-postgresql-hl ClusterIP None <none> 5432/TCP 77s
service/pacman ClusterIP 10.96.105.28 <none> 8080/TCP 21h
NAME ENDPOINTS AGE
endpoints/kubernetes 192.168.97.2:6443 22h
endpoints/my-db-postgresql 10.244.0.8:5432 77s
endpoints/my-db-postgresql-hl 10.244.0.8:5432 77s
endpoints/pacman 10.244.0.4:8080 21h
NAME TYPE DATA AGE
secret/my-db-postgresql Opaque 1 77s
secret/sh.helm.release.v1.my-db.v1 helm.sh/release.v1 1 77s
secret/sh.helm.release.v1.pacman.v1 helm.sh/release.v1 1 21h
secret/sh.helm.release.v1.pacman.v2 helm.sh/release.v1 1 21h
secret/sh.helm.release.v1.pacman.v3 helm.sh/release.v1 1 20h
secret/sh.helm.release.v1.pacman.v4 helm.sh/release.v1 1 20h
# 서드 파티 챠트 사용시 기본값(default value)나 override 파라미터를 직접 확인 할 수 없고, helm show 로 확인 가능
helm show values bitnami/postgresql
.
.
.
## rules:
## - alert: HugeReplicationLag
## expr: pg_replication_lag{service="{{ printf "%s-metrics" (include "postgresql.v1.chart.fullname" .) }}"} / 3600 > 1
## for: 1m
## labels:
## severity: critical
## annotations:
## description: replication for {{ include "postgresql.v1.chart.fullname" . }} PostgreSQL is lagging by {{ "{{ $value }}" }} hour(s).
## summary: PostgreSQL replication is lagging by {{ "{{ $value }}" }} hour(s).
##
rules: []
# 실습 후 삭제
minji ~ helm uninstall my-db
release "my-db" uninstalled
5.6 Deploying a Chart with a dependency
다른 챠트를 의존성으로 사용하는 차트를 배포
실습에서는 PostgreSQL, 데이터베이스에 저장된 노래 목록을 반환하는 Java 서비스를 배포
##
mkdir music
mkdir music/templates
cd music
##
minji ~/Desktop/work/Gasida_series/practice/music cat << EOF > templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Chart.Name}}
labels:
app.kubernetes.io/name: {{ .Chart.Name}}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app.kubernetes.io/name: {{ .Chart.Name}}
template:
metadata:
labels:
app.kubernetes.io/name: {{ .Chart.Name}}
spec:
containers:
- image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion}}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
name: {{ .Chart.Name}}
ports:
- containerPort: {{ .Values.image.containerPort }}
name: http
protocol: TCP
env:
- name: QUARKUS_DATASOURCE_JDBC_URL
value: {{ .Values.postgresql.server | default (printf "%s-postgresql" ( .Release.Name )) | quote }}
- name: QUARKUS_DATASOURCE_USERNAME
value: {{ .Values.postgresql.postgresqlUsername | default (printf "postgres" ) | quote }}
- name: QUARKUS_DATASOURCE_PASSWORD
valueFrom:
secretKeyRef:
name: {{ .Values.postgresql.secretName | default (printf "%s-postgresql" ( .Release.Name )) | quote }}
key: {{ .Values.postgresql.secretKey }}
EOF
##
minji ~/Desktop/work/Gasida_series/practice/music cat << EOF > templates/service.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/name: {{ .Chart.Name }}
name: {{ .Chart.Name }}
spec:
ports:
- name: http
port: {{ .Values.image.containerPort }}
targetPort: {{ .Values.image.containerPort }}
selector:
app.kubernetes.io/name: {{ .Chart.Name }}
EOF
## psql 10.16.2 차트 책 버전 사용 시
minji ~/Desktop/work/Gasida_series/practice/music cat << EOF > Chart.yaml
apiVersion: v2
name: music
description: A Helm chart for Music service
type: application
version: 0.1.0
appVersion: "1.0.0"
dependencies:
- name: postgresql
version: 10.16.2
repository: "https://charts.bitnami.com/bitnami"
EOF
##
minji ~/Desktop/work/Gasida_series/practice/music helm search repo postgresql
NAME CHART VERSION APP VERSION DESCRIPTION
bitnami/postgresql 18.1.1 18.0.0 PostgreSQL (Postgres) is an open source object-...
bitnami/postgresql-ha 16.3.2 17.6.0 This PostgreSQL cluster solution includes the P...
bitnami/cloudnative-pg 1.0.11 1.26.1 CloudNativePG is an open-source tool for managi...
bitnami/supabase 5.3.6 1.24.7 DEPRECATED Supabase is an open source Firebase ...
bitnami/minio-operator 0.2.9 7.1.1 MinIO(R) Operator is a Kubernetes-native tool f...
##
minji ~/Desktop/work/Gasida_series/practice/music helm search repo bitnami/postgresql --versions
NAME CHART VERSION APP VERSION DESCRIPTION
bitnami/postgresql 18.1.1 18.0.0 PostgreSQL (Postgres) is an open source object-...
bitnami/postgresql 18.0.17 18.0.0 PostgreSQL (Postgres) is an open source object-...
bitnami/postgresql 18.0.16 18.0.0 PostgreSQL (Postgres) is an open source object-...
bitnami/postgresql 18.0.15 18.0.0 PostgreSQL (Postgres) is an open source object-...
bitnami/postgresql 18.0.14 18.0.0 PostgreSQL (Postgres) is an open source object-...
bitnami/postgresql 18.0.12 18.0.0 PostgreSQL (Postgres) is an open source object-...
.
.
.
## 현재 최신 챠트 버전 사용
minji ~/Desktop/work/Gasida_series/practice/music cat << EOF > Chart.yaml
apiVersion: v2
name: music
description: A Helm chart for Music service
type: application
version: 0.1.0
appVersion: "1.0.0"
dependencies:
- name: postgresql
version: 18.0.17 # book 10.16.2
repository: "https://charts.bitnami.com/bitnami"
EOF
##
minji ~/Desktop/work/Gasida_series/practice/music cat << EOF > values.yaml
image:
repository: quay.io/gitops-cookbook/music
tag: "1.0.0"
pullPolicy: Always
containerPort: 8080
replicaCount: 1
postgresql:
server: jdbc:postgresql://music-db-postgresql:5432/mydb
postgresqlUsername: my-default
postgresqlPassword: postgres
postgresqlDatabase: mydb
secretName: music-db-postgresql
secretKey: postgresql-password
EOF
##
minji ~/Desktop/work/Gasida_series/practice/music cat << EOF > values.yaml
image:
repository: quay.io/gitops-cookbook/music
tag: "1.0.0"
pullPolicy: Always
containerPort: 8080
replicaCount: 1
postgresql:
server: jdbc:postgresql://music-db-postgresql:5432/mydb
postgresqlUsername: my-default
postgresqlPassword: postgres
postgresqlDatabase: mydb
secretName: music-db-postgresql
secretKey: postgresql-password
EOF
# 의존성으로 선언된 챠트를 다운로드하여 챠트 디렉터리에 저장
minji ~/Desktop/work/Gasida_series/practice/music helm dependency update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "bitnami" chart repository
Update Complete. ⎈Happy Helming!⎈
Saving 1 charts
Downloading postgresql from repo https://charts.bitnami.com/bitnami
Pulled: registry-1.docker.io/bitnamicharts/postgresql:18.0.17
Digest: sha256:84b63af46f41ac35e3cbcf098e8cf124211c250807cfed43f7983c39c6e30b72
Deleting outdated charts
##
minji ~/Desktop/work/Gasida_series/practice/music tree
.
├── Chart.lock
├── Chart.yaml
├── charts
│ └── postgresql-18.0.17.tgz
├── templates
│ ├── deployment.yaml
│ └── service.yaml
└── values.yaml
3 directories, 6 files
# 챠트 배포
minji ~/Desktop/work/Gasida_series/practice/music helm install music-db .
NAME: music-db
LAST DEPLOYED: Fri Oct 24 20:51:28 2025
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
# 확인
minji ~/Desktop/work/Gasida_series/practice/music kubectl get sts,pod,svc,ep,secret,pv,pvc
NAME READY AGE
statefulset.apps/music-db-postgresql 1/1 93s
NAME READY STATUS RESTARTS AGE
pod/music-6c45d566f4-v7btz 0/1 CreateContainerConfigError 0 93s
pod/music-db-postgresql-0 1/1 Running 0 93s
pod/pacman-576769bb86-t5scc 1/1 Running 2 (33m ago) 21h
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 22h
service/music ClusterIP 10.96.45.200 <none> 8080/TCP 93s
service/music-db-postgresql ClusterIP 10.96.131.73 <none> 5432/TCP 93s
service/music-db-postgresql-hl ClusterIP None <none> 5432/TCP 93s
service/pacman ClusterIP 10.96.105.28 <none> 8080/TCP 21h
NAME ENDPOINTS AGE
endpoints/kubernetes 192.168.97.2:6443 22h
endpoints/music 93s
endpoints/music-db-postgresql 10.244.0.11:5432 93s
endpoints/music-db-postgresql-hl 10.244.0.11:5432 93s
endpoints/pacman 10.244.0.4:8080 21h
NAME TYPE DATA AGE
secret/music-db-postgresql Opaque 1 93s
secret/sh.helm.release.v1.music-db.v1 helm.sh/release.v1 1 93s
secret/sh.helm.release.v1.pacman.v1 helm.sh/release.v1 1 21h
secret/sh.helm.release.v1.pacman.v2 helm.sh/release.v1 1 21h
secret/sh.helm.release.v1.pacman.v3 helm.sh/release.v1 1 21h
secret/sh.helm.release.v1.pacman.v4 helm.sh/release.v1 1 21h
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE
persistentvolume/pvc-5c9948cf-c5fe-41b3-ba23-33453f80eaf2 8Gi RWO Delete Bound default/data-my-db-postgresql-0 standard <unset> 16m
persistentvolume/pvc-947648b2-8fb2-43c3-816a-11078b1594f3 8Gi RWO Delete Bound default/data-music-db-postgresql-0 standard <unset> 91s
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
persistentvolumeclaim/data-music-db-postgresql-0 Bound pvc-947648b2-8fb2-43c3-816a-11078b1594f3 8Gi RWO standard <unset> 93s
persistentvolumeclaim/data-my-db-postgresql-0 Bound pvc-5c9948cf-c5fe-41b3-ba23-33453f80eaf2 8Gi RWO standard <unset> 16m
# TS 1 : secret에 key/value 추가
kubectl edit secret music-db-postgresql
postgresql-password: cG9zdGdyZXMK
# TS2 : 직접 해결해보자!
kubectl logs -l app.kubernetes.io/name=music -f
__ ____ __ _____ ___ __ ____ ______
--/ __ \/ / / / _ | / _ \/ //_/ / / / __/
-/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/
2025-10-24 11:58:11,847 WARN [io.agr.pool] (agroal-11) Datasource '<default>': Something unusual has occurred to cause the driver to fail. Please report this exception.
2025-10-24 11:58:11,876 WARN [org.hib.eng.jdb.env.int.JdbcEnvironmentInitiator] (JPA Startup Thread: <default>) HHH000342: Could not obtain connection to query metadata: org.postgresql.util.PSQLException: Something unusual has occurred to cause the driver to fail. Please report this exception.
at org.postgresql.Driver.connect(Driver.java:286)
.
.
.
# music service 에 port-forward 설정 후 호출하여 노래 목록 확인
minji ~/Desktop/work/Gasida_series/practice/music kubectl port-forward service/music 8080:8080
Forwarding from 127.0.0.1:8080 -> 8080
Forwarding from [::1]:8080 -> 8080
minji ~/Desktop/work/Gasida_series/practice/music helm uninstall music-db
release "music-db" uninstalled
minji ~/Desktop/work/Gasida_series/practice/music kubectl delete pvc --all
persistentvolumeclaim "data-music-db-postgresql-0" deleted
6장 Cloud Native CI/CD
- 기본적으로 지속적 통합 ( CI )은 개발자가 만들 새 코드를 가져와서 빌드, 테스트, 실행하는 과정을 자동으로 처리하는 프로세스
- 텍톤이란 ?
- 쿠버네티스 기반 오픈 소스 클라우드 네이티브 CI/CD 시스템이다
- 기본 개념
- Task
- 특정 기능 (예: 컨테이너 이미지 빌드)을 수행하는 재사용 가능하고 느슨하게 결합된 여러 개의 단계(steps).
- 태스크는 쿠버네티스 파드로 실행되고, 태스트의 각 단계는 컨테이너에 대응된다.
- Pipeline
- 앱을 빌드 및 또는 배포하는 데 필요한 Task의 목록
- TaskRun
- Task 인스턴스의 실행 및 그 결과
- PipelineRun
- Pipeline 인스턴스의 실행 및 그 결과. 다수의 TaskRun 포함
- Trigger
- 이벤트를 감지하고 다른 CRD에 연결하여 해당 이벤트가 발생했을 때 어떤 일이 발생하는지 지정.
- Task
- 구성요소
- 텍톤은 모듈식 구조로 되어 있다. 모든 구성 요소를 개별적으로 또는 한 번에 설치할 수 있다.
- Tekton Pilelines
- Task 및 Pipeline포함
- Tekton Triggers
- Trigger 및 EventListener 포함
- Tekton Dashbaord
- 파이프라인과 로그를 시각화 할 수 있는 대시보드
- Tekton CLI
- 텍톤 객체를 관리하기 위한 CLI (파이프라인 및 작업 시작/중지, 로그 확인)
- 텍톤 flow

6.1 install tekton
Pipeline
# Takton dependency pipeline 설치
minji ~/Desktop/work/Gasida_series/practice/music kubectl apply -f https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml
namespace/tekton-pipelines created
clusterrole.rbac.authorization.k8s.io/tekton-pipelines-controller-cluster-access created
clusterrole.rbac.authorization.k8s.io/tekton-pipelines-controller-tenant-access created
clusterrole.rbac.authorization.k8s.io/tekton-pipelines-webhook-cluster-access created
clusterrole.rbac.authorization.k8s.io/tekton-events-controller-cluster-access created
role.rbac.authorization.k8s.io/tekton-pipelines-controller created
role.rbac.authorization.k8s.io/tekton-pipelines-webhook created
.
.
.
# Takton dependency pipeline 설치 확인
minji ~/Desktop/work/Gasida_series/practice/music kubectl get crd
NAME CREATED AT
customruns.tekton.dev 2025-10-24T13:14:17Z
pipelineruns.tekton.dev 2025-10-24T13:14:17Z
pipelines.tekton.dev 2025-10-24T13:14:17Z
resolutionrequests.resolution.tekton.dev 2025-10-24T13:14:17Z
stepactions.tekton.dev 2025-10-24T13:14:17Z
taskruns.tekton.dev 2025-10-24T13:14:17Z
tasks.tekton.dev 2025-10-24T13:14:17Z
verificationpolicies.tekton.dev 2025-10-24T13:14:17Z
#
minji ~/Desktop/work/Gasida_series/practice/music kubectl get ns | grep tekton
tekton-pipelines Active 81s
tekton-pipelines-resolvers Active 81s
#
minji ~/Desktop/work/Gasida_series/practice/music kubectl krew install get-all
WARNING: To be able to run kubectl plugins, you need to add
the following to your ~/.zshrc:
export PATH="${KREW_ROOT:-$HOME/.krew}/bin:$PATH"
.
.
.
#
minji ~/Desktop/work/Gasida_series/practice kubectl get-all -n tekton-pipelines
NAME NAMESPACE AGE
configmap/config-defaults tekton-pipelines 7m
configmap/config-events tekton-pipelines 7m
configmap/config-leader-election-controller tekton-pipelines 7m
configmap/config-leader-election-events
.
.
.
#
minji ~/Desktop/work/Gasida_series/practice kubectl get-all -n tekton-pipelines-resolvers
NAME NAMESPACE AGE
configmap/bundleresolver-config tekton-pipelines-resolvers 7m36s
configmap/cluster-resolver-config tekton-pipelines-resolvers 7m36s
configmap/config-leader-election-resolvers tekton-pipelines-resolvers 7m36s
configmap/config-logging tekton-pipelines-resolvers 7m36s
configmap/config-observability tekton-pipelines-resolvers 7m36s
configmap/git-resolver-config tekton-pipelines-resolvers 7m36s
configmap/http-resolver-config tekton-pipelines-resolvers 7m36s
configmap/hubresolver-config tekton-pipelines-resolvers 7m36s
configmap/kube-root-ca.crt tekton-pipelines-resolvers 7m36s
configmap/resolvers-feature-flags tekton-pipelines-resolvers 7m36s
endpoints/tekton-pipelines-remote-resolvers tekton-pipelines-resolvers 7m36s
pod/tekton-pipelines-remote-resolvers-86f56b6664-rjhxv tekton-pipelines-resolvers 7m36s
serviceaccount/default tekton-pipelines-resolvers 7m36s
serviceaccount/tekton-pipelines-resolvers tekton-pipelines-resolvers 7m36s
service/tekton-pipelines-remote-resolvers tekton-pipelines-resolvers 7m36s
deployment.apps/tekton-pipelines-remote-resolvers tekton-pipelines-resolvers 7m36s
replicaset.apps/tekton-pipelines-remote-resolvers-86f56b6664 tekton-pipelines-resolvers 7m36s
lease.coordination.k8s.io/controller.tektonresolverframework.bundleresolver.00-of-01 tekton-pipelines-resolvers 7m4s
lease.coordination.k8s.io/controller.tektonresolverframework.cluster.00-of-01 tekton-pipelines-resolvers 7m4s
lease.coordination.k8s.io/controller.tektonresolverframework.git.00-of-01 tekton-pipelines-resolvers 7m4s
lease.coordination.k8s.io/controller.tektonresolverframework.http.00-of-01 tekton-pipelines-resolvers 7m4s
lease.coordination.k8s.io/controller.tektonresolverframework.hub.00-of-01 tekton-pipelines-resolvers 7m4s
endpointslice.discovery.k8s.io/tekton-pipelines-remote-resolvers-gtrch tekton-pipelines-resolvers 7m36s
rolebinding.rbac.authorization.k8s.io/tekton-pipelines-resolvers-namespace-rbac tekton-pipelines-resolvers 7m36s
role.rbac.authorization.k8s.io/tekton-pipelines-resolvers-namespace-rbac tekton-pipelines-resolvers 7m36s
#
minji ~/Desktop/work/Gasida_series/practice kubectl get all -n tekton-pipelines-resolvers
NAME READY STATUS RESTARTS AGE
pod/tekton-pipelines-remote-resolvers-86f56b6664-rjhxv 1/1 Running 0 7m47s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/tekton-pipelines-remote-resolvers ClusterIP 10.96.65.6 <none> 9090/TCP,8008/TCP,8080/TCP 7m47s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/tekton-pipelines-remote-resolvers 1/1 1 1 7m47s
NAME DESIRED CURRENT READY AGE
replicaset.apps/tekton-pipelines-remote-resolvers-86f56b6664 1 1 1 7m47s
# pod 확인
minji ~/Desktop/work/Gasida_series/practice kubectl get pod -n tekton-pipelines
NAME READY STATUS RESTARTS AGE
tekton-events-controller-99665746c-v4bw8 1/1 Running 0 8m49s
tekton-pipelines-controller-7595d6585d-vjhq8 1/1 Running 0 8m49s
tekton-pipelines-webhook-5967d74cc4-t5th4 1/1 Running 0 8m49s
Trigger
# Tekton Trigger 설치
minji ~/Desktop/work/Gasida_series/practice kubectl apply -f https://storage.googleapis.com/tekton-releases/triggers/latest/release.yaml
clusterrole.rbac.authorization.k8s.io/tekton-triggers-admin created
clusterrole.rbac.authorization.k8s.io/tekton-triggers-core-interceptors created
clusterrole.rbac.authorization.k8s.io/tekton-triggers-core-interceptors-secrets created
clusterrole.rbac.authorization.k8s.io/tekton-triggers-eventlistener-roles created
.
.
.
#
minji ~/Desktop/work/Gasida_series/practice kubectl apply -f https://storage.googleapis.com/tekton-releases/triggers/latest/interceptors.yaml
secret/tekton-triggers-core-interceptors-certs created
deployment.apps/tekton-triggers-core-interceptors created
service/tekton-triggers-core-interceptors created
clusterinterceptor.triggers.tekton.dev/cel created
clusterinterceptor.triggers.tekton.dev/bitbucket created
clusterinterceptor.triggers.tekton.dev/slack created
clusterinterceptor.triggers.tekton.dev/github created
clusterinterceptor.triggers.tekton.dev/gitlab created
# Tekton Trigger 설치 확인
minji ~/Desktop/work/Gasida_series/practice kubectl get crd | grep triggers
clusterinterceptors.triggers.tekton.dev 2025-10-24T13:26:39Z
clustertriggerbindings.triggers.tekton.dev 2025-10-24T13:26:39Z
eventlisteners.triggers.tekton.dev 2025-10-24T13:26:39Z
interceptors.triggers.tekton.dev 2025-10-24T13:26:39Z
triggerbindings.triggers.tekton.dev 2025-10-24T13:26:39Z
triggers.triggers.tekton.dev 2025-10-24T13:26:39Z
triggertemplates.triggers.tekton.dev 2025-10-24T13:26:39Z
#
minji ~/Desktop/work/Gasida_series/practice kubectl get all -n tekton-pipelines
NAME READY STATUS RESTARTS AGE
pod/tekton-events-controller-99665746c-v4bw8 1/1 Running 0 14m
pod/tekton-pipelines-controller-7595d6585d-vjhq8 1/1 Running 0 14m
pod/tekton-pipelines-webhook-5967d74cc4-t5th4 1/1 Running 0 14m
pod/tekton-triggers-controller-74fccfc888-kks9r 1/1 Running 0 118s
pod/tekton-triggers-core-interceptors-7b8dcb59fb-5h42s 1/1 Running 0 74s
pod/tekton-triggers-webhook-5465cc8d5b-9kq58 1/1 Running 0 118s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/tekton-events-controller ClusterIP 10.96.87.139 <none> 9090/TCP,8008/TCP,8080/TCP 14m
service/tekton-pipelines-controller ClusterIP 10.96.138.51 <none> 9090/TCP,8008/TCP,8080/TCP 14m
service/tekton-pipelines-webhook ClusterIP 10.96.164.74 <none> 9090/TCP,8008/TCP,443/TCP,8080/TCP 14m
service/tekton-triggers-controller ClusterIP 10.96.129.69 <none> 9000/TCP 118s
service/tekton-triggers-core-interceptors ClusterIP 10.96.150.198 <none> 8443/TCP 74s
service/tekton-triggers-webhook ClusterIP 10.96.22.249 <none> 443/TCP 118s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/tekton-events-controller 1/1 1 1 14m
deployment.apps/tekton-pipelines-controller 1/1 1 1 14m
deployment.apps/tekton-pipelines-webhook 1/1 1 1 14m
deployment.apps/tekton-triggers-controller 1/1 1 1 118s
deployment.apps/tekton-triggers-core-interceptors 1/1 1 1 74s
deployment.apps/tekton-triggers-webhook 1/1 1 1 118s
NAME DESIRED CURRENT READY AGE
replicaset.apps/tekton-events-controller-99665746c 1 1 1 14m
replicaset.apps/tekton-pipelines-controller-7595d6585d 1 1 1 14m
replicaset.apps/tekton-pipelines-webhook-5967d74cc4 1 1 1 14m
replicaset.apps/tekton-triggers-controller-74fccfc888 1 1 1 118s
replicaset.apps/tekton-triggers-core-interceptors-7b8dcb59fb 1 1 1 74s
replicaset.apps/tekton-triggers-webhook-5465cc8d5b 1 1 1 118s
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
horizontalpodautoscaler.autoscaling/tekton-pipelines-webhook Deployment/tekton-pipelines-webhook cpu: <unknown>/100% 1 5 1 14m
# Trigger 관련 deployment 설치 확인
minji ~/Desktop/work/Gasida_series/practice kubectl get deploy -n tekton-pipelines | grep triggers
tekton-triggers-controller 1/1 1 1 2m41s
tekton-triggers-core-interceptors 1/1 1 1 117s
tekton-triggers-webhook 1/1 1 1 2m41s
Dashboard
# Tekton dashboard 설치
minji ~/Desktop/work/Gasida_series/practice kubectl apply -f https://storage.googleapis.com/tekton-releases/dashboard/latest/release.yaml
customresourcedefinition.apiextensions.k8s.io/extensions.dashboard.tekton.dev created
serviceaccount/tekton-dashboard created
role.rbac.authorization.k8s.io/tekton-dashboard-info created
clusterrole.rbac.authorization.k8s.io/tekton-dashboard-backend-edit created
clusterrole.rbac.authorization.k8s.io/tekton-dashboard-backend-view created
clusterrole.rbac.authorization.k8s.io/tekton-dashboard-tenant-view created
rolebinding.rbac.authorization.k8s.io/tekton-dashboard-info created
clusterrolebinding.rbac.authorization.k8s.io/tekton-dashboard-backend-view created
configmap/dashboard-info created
service/tekton-dashboard created
deployment.apps/tekton-dashboard created
clusterrolebinding.rbac.authorization.k8s.io/tekton-dashboard-tenant-view created
clusterrolebinding.rbac.authorization.k8s.io/tekton-dashboard-pipelines-view created
clusterrolebinding.rbac.authorization.k8s.io/tekton-dashboard-triggers-view created
# Tekton Dashboard 설치 확인
minji ~/Desktop/work/Gasida_series/practice kubectl get crd | grep dashboard
extensions.dashboard.tekton.dev 2025-10-24T13:30:07Z
#
minji ~/Desktop/work/Gasida_series/practice kubectl get all -n tekton-pipelines
NAME READY STATUS RESTARTS AGE
pod/tekton-dashboard-7d4499b584-5fxb5 1/1 Running 0 58s
pod/tekton-events-controller-99665746c-v4bw8 1/1 Running 0 16m
pod/tekton-pipelines-controller-7595d6585d-vjhq8 1/1 Running 0 16m
pod/tekton-pipelines-webhook-5967d74cc4-t5th4 1/1 Running 0 16m
pod/tekton-triggers-controller-74fccfc888-kks9r 1/1 Running 0 4m26s
pod/tekton-triggers-core-interceptors-7b8dcb59fb-5h42s 1/1 Running 0 3m42s
pod/tekton-triggers-webhook-5465cc8d5b-9kq58 1/1 Running 0 4m26s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/tekton-dashboard ClusterIP 10.96.30.117 <none> 9097/TCP 58s
service/tekton-events-controller ClusterIP 10.96.87.139 <none> 9090/TCP,8008/TCP,8080/TCP 16m
service/tekton-pipelines-controller ClusterIP 10.96.138.51 <none> 9090/TCP,8008/TCP,8080/TCP 16m
service/tekton-pipelines-webhook ClusterIP 10.96.164.74 <none> 9090/TCP,8008/TCP,443/TCP,8080/TCP 16m
service/tekton-triggers-controller ClusterIP 10.96.129.69 <none> 9000/TCP 4m26s
service/tekton-triggers-core-interceptors ClusterIP 10.96.150.198 <none> 8443/TCP 3m42s
service/tekton-triggers-webhook ClusterIP 10.96.22.249 <none> 443/TCP 4m26s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/tekton-dashboard 1/1 1 1 58s
deployment.apps/tekton-events-controller 1/1 1 1 16m
deployment.apps/tekton-pipelines-controller 1/1 1 1 16m
deployment.apps/tekton-pipelines-webhook 1/1 1 1 16m
deployment.apps/tekton-triggers-controller 1/1 1 1 4m26s
deployment.apps/tekton-triggers-core-interceptors 1/1 1 1 3m42s
deployment.apps/tekton-triggers-webhook 1/1 1 1 4m26s
NAME DESIRED CURRENT READY AGE
replicaset.apps/tekton-dashboard-7d4499b584 1 1 1 58s
replicaset.apps/tekton-events-controller-99665746c 1 1 1 16m
replicaset.apps/tekton-pipelines-controller-7595d6585d 1 1 1 16m
replicaset.apps/tekton-pipelines-webhook-5967d74cc4 1 1 1 16m
replicaset.apps/tekton-triggers-controller-74fccfc888 1 1 1 4m26s
replicaset.apps/tekton-triggers-core-interceptors-7b8dcb59fb 1 1 1 3m42s
replicaset.apps/tekton-triggers-webhook-5465cc8d5b 1 1 1 4m26s
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
horizontalpodautoscaler.autoscaling/tekton-pipelines-webhook Deployment/tekton-pipelines-webhook cpu: <unknown>/100% 1 5 1 16m
# Dashboard 관련 deployment 설치 확인
minji ~/Desktop/work/Gasida_series/practice kubectl get deploy -n tekton-pipelines
NAME READY UP-TO-DATE AVAILABLE AGE
tekton-dashboard 1/1 1 1 2m34s
tekton-events-controller 1/1 1 1 18m
tekton-pipelines-controller 1/1 1 1 18m
tekton-pipelines-webhook 1/1 1 1 18m
tekton-triggers-controller 1/1 1 1 6m2s
tekton-triggers-core-interceptors 1/1 1 1 5m18s
tekton-triggers-webhook 1/1 1 1 6m2s
# service 정보 확인
minji ~/Desktop/work/Gasida_series/practice kubectl get svc,ep -n tekton-pipelines tekton-dashboard
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/tekton-dashboard ClusterIP 10.96.30.117 <none> 9097/TCP 3m9s
NAME ENDPOINTS AGE
endpoints/tekton-dashboard 10.244.0.25:9097 3m9s
#
minji ~/Desktop/work/Gasida_series/practice [200~kubectl get svc -n tekton-pipelines tekton-dashboard -o yaml~
✘ minji ~/Desktop/work/Gasida_series/practice
✘ minji ~/Desktop/work/Gasida_series/practice kubectl get svc -n tekton-pipelines tekton-dashboard -o yaml
apiVersion: v1
kind: Service
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"app":"tekton-dashboard","app.kubernetes.io/component":"dashboard","app.kubernetes.io/instance":"default","app.kubernetes.io/name":"dashboard","app.kubernetes.io/part-of":"tekton-dashboard","app.kubernetes.io/version":"v0.62.0","dashboard.tekton.dev/release":"v0.62.0","version":"v0.62.0"},"name":"tekton-dashboard","namespace":"tekton-pipelines"},"spec":{"ports":[{"name":"http","port":9097,"protocol":"TCP","targetPort":9097}],"selector":{"app.kubernetes.io/component":"dashboard","app.kubernetes.io/instance":"default","app.kubernetes.io/name":"dashboard","app.kubernetes.io/part-of":"tekton-dashboard"}}}
creationTimestamp: "2025-10-24T13:30:07Z"
.
.
.
# Service 를 node port 설정 ( nodeport 30000 )
minji ~/Desktop/work/Gasida_series/practice kubectl patch svc -n tekton-pipelines tekton-dashboard -p '{"spec":{"type":"NodePort","ports":[{"port":9097,"targetPort":9097,"nodePort":30000}]}}'
service/tekton-dashboard patched
#
minji ~/Desktop/work/Gasida_series/practice kubectl get svc,ep -n tekton-pipelines tekton-dashboard
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/tekton-dashboard NodePort 10.96.30.117 <none> 9097:30000/TCP 5m44s
NAME ENDPOINTS AGE
endpoints/tekton-dashboard 10.244.0.25:9097 5m44s
# tekton dashboard 접속
minji ~/Desktop/work/Gasida_series/practice open http://localhost:30000

Tekton CLI 설치
minji ~/Desktop/work/Gasida_series/practice brew install tektoncd-cli
==> Auto-updating Homebrew...
Adjust how often this is run with `$HOMEBREW_AUTO_UPDATE_SECS` or disable with
`$HOMEBREW_NO_AUTO_UPDATE=1`. Hide these hints with `$HOMEBREW_NO_ENV_HINTS=1` (see `man brew`).
==> Auto-updated Homebrew!
Updated 2 taps (homebrew/core and homebrew/cask).
==> New Formulae
btllib: Bioinformatics Technology Lab common code library
ghidra: Multi-platform software reverse engineering framework
.
.
.
#
minji ~/Desktop/work/Gasida_series/practice
✘ minji ~/Desktop/work/Gasida_series/practice
✘ minji ~/Desktop/work/Gasida_series/practice tkn version
Client version: 0.42.0
Pipeline version: v1.5.0
Triggers version: v0.33.0
Dashboard version: v0.62.0
6.2 Create a hello world task
Task 생성
#
minji ~/Desktop/work/Gasida_series/practice kubectl explain tasks.tekton.dev
GROUP: tekton.dev
KIND: Task
VERSION: v1
# task 생성
minji ~/Desktop/work/Gasida_series/practice cat << EOF | kubectl apply -f -
apiVersion: tekton.dev/v1
kind: Task
metadata:
name: hello
spec:
steps:
- name: echo # step 이름
image: alpine # step 수행 컨테이너 이미지
script: |
#!/bin/sh
echo "Hello World"
EOF
task.tekton.dev/hello created
# 확인
minji ~/Desktop/work/Gasida_series/practice tkn task list
NAME DESCRIPTION AGE
hello 9 seconds ago
#
minji ~/Desktop/work/Gasida_series/practice kubectl get tasks
NAME AGE
hello 29s
#
minji ~/Desktop/work/Gasida_series/practice kubectl get tasks -o yaml
apiVersion: v1
items:
- apiVersion: tekton.dev/v1
kind: Task
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"tekton.dev/v1","kind":"Task","metadata":{"annotations":{},"name":"hello","namespace":"default"},"spec":{"steps":[{"image":"alpine","name":"echo","script":"#!/bin/sh\necho \"Hello World\"\n"}]}}
creationTimestamp: "2025-10-24T13:52:15Z"
generation: 1
name: hello
namespace: default
resourceVersion: "25364"
uid: b29d6f56-b42c-4856-a412-186fc80cd25d
spec:
steps:
- computeResources: {}
image: alpine
name: echo
script: |
#!/bin/sh
echo "Hello World"
kind: List
metadata:
resourceVersion: ""
#
minji ~/Desktop/work/Gasida_series/practice kubectl get pod
NAME READY STATUS RESTARTS AGE
pacman-576769bb86-t5scc 1/1 Running 2 (154m ago) 23h

tkn CLI로 task 시작
# 신규 터미널 : pod status monitoring
minji ~ kubectl get pod -w
NAME READY STATUS RESTARTS AGE
pacman-576769bb86-t5scc 1/1 Running 2 (156m ago) 23h
hello-run-7rb4h-pod 0/1 Pending 0 0s
hello-run-7rb4h-pod 0/1 Pending 0 0s
hello-run-7rb4h-pod 0/1 Init:0/2 0 0s
hello-run-7rb4h-pod 0/1 Init:1/2 0 7s
hello-run-7rb4h-pod 0/1 PodInitializing 0 11s
hello-run-7rb4h-pod 1/1 Running 0 18s
hello-run-7rb4h-pod 1/1 Running 0 18s
hello-run-7rb4h-pod 0/1 Completed 0 19s
hello-run-7rb4h-pod 0/1 Completed 0 20s
# tkn CLI로 task 시작
minji ~/Desktop/work/Gasida_series/practice kubectl get pod
NAME READY STATUS RESTARTS AGE
pacman-576769bb86-t5scc 1/1 Running 2 (154m ago) 23h
minji ~/Desktop/work/Gasida_series/practice tk
n task start --showlog hello
TaskRun started: hello-run-7rb4h
Waiting for logs to be available...
[echo] Hello World
# pod 내 "2개의 init 컨테이너, 1개의 컨테이너" 확인
minji ~/Desktop/work/Gasida_series/practice kubectl describe pod -l tekton.dev/task=hello
.
.
.
Init Containers:
prepare:
Container ID: containerd://a43c17ce1d040c740775d3aa404a09ea90e048ba7a8a6e4c78008e4e6ec3331f
Image: ghcr.io/tektoncd/pipeline/entrypoint-bff0a22da108bc2f16c818c97641a296:v1.5.0@sha256:ff5ee925ff7b08853cc4caa93e5e3e0ee761a2db6ae0a1ae6a0f6f120f170b56
Image ID: ghcr.io/tektoncd/pipeline/entrypoint-bff0a22da108bc2f16c818c97641a296@sha256:ff5ee925ff7b08853cc4caa93e5e3e0ee761a2db6ae0a1ae6a0f6f120f170b56
.
.
.
# log 확인
minji ~/Desktop/work/Gasida_series/practice kubectl logs -l tekton.dev/task=hello -c prepare
2025/10/24 13:55:43 Entrypoint initialization
minji ~/Desktop/work/Gasida_series/practice kubectl logs -l tekton.dev/task=hello -c place-scripts
2025/10/24 13:55:46 Decoded script /tekton/scripts/script-0-tccks
minji ~/Desktop/work/Gasida_series/practice kubectl logs -l tekton.dev/task=hello -c step-echo
Hello World
#
minji ~/Desktop/work/Gasida_series/practice tkn task logs hello
Hello World
minji ~/Desktop/work/Gasida_series/practice tkn task describe hello
Name: hello
Namespace: default
🦶 Steps
∙ echo
🗂 Taskruns
NAME STARTED DURATION STATUS
hello-run-7rb4h 5 minutes ago 19s Succeeded
#
minji ~/Desktop/work/Gasida_series/practice tkn taskrun logs
[echo] Hello World
minji ~/Desktop/work/Gasida_series/practice tkn taskrun list
NAME STARTED DURATION STATUS
hello-run-7rb4h 5 minutes ago 19s Succeeded
# 다음 실습을 위해 taskrun 삭제
minji ~/Desktop/work/Gasida_series/practice kubectl delete taskruns --all
taskrun.tekton.dev "hello-run-7rb4h" deleted
6.3 Create a Task to compile and package an App from git
Tekton을 사용하여 git 저장소에 보관된 app code를 compile하고 패키징하는 작업을 자동화 해보자
지금 하는 내용의 핵심 아이디어는 추후 파이프라인을 만들 떄 쓸 수 있도록 input과 output이 잘 규정된 task를 만드는것
Tekton pipelines를 사용하여 git에서 소스 코드를 복제
# 파이프라인 파일 작성
owoo@ttokkang-ui-MacBookAir ~/Desktop/work/Gasida_series/practice cat << EOF | kubectl apply -f -
apiVersion: tekton.dev/v1
kind: Pipeline
metadata:
name: clone-read
spec:
description: |
This pipeline clones a git repo, then echoes the README file to the stout.
params: # 매개변수 repo-url
- name: repo-url
type: string
description: The git repo URL to clone from.
workspaces: # 다운로드할 코드를 저장할 공유 볼륨인 작업 공간을 추가
- name: shared-data
description: |
This workspace contains the cloned repo files, so they can be read by the
next task.
tasks: # task 정의
- name: fetch-source
taskRef:
name: git-clone
workspaces:
- name: output
workspace: shared-data
params:
- name: url
value: \$(params.repo-url)
EOF
pipeline.tekton.dev/clone-read created
# 확인
minji ~/Desktop/work/Gasida_series/practice tkn pipeline list
NAME AGE LAST RUN STARTED DURATION STATUS
clone-read 36 seconds ago --- --- --- ---
#
minji ~/Desktop/work/Gasida_series/practice tkn pipeline describe
Name: clone-read
Namespace: default
Description: This pipeline clones a git repo, then echoes the README file to the stout.
⚓ Params
NAME TYPE DESCRIPTION DEFAULT VALUE
∙ repo-url string The git repo URL to... ---
📂 Workspaces
NAME DESCRIPTION OPTIONAL
∙ shared-data This workspace cont... false
🗒 Tasks
NAME TASKREF RUNAFTER TIMEOUT PARAMS
∙ fetch-source git-clone --- url: string
#
minji ~/Desktop/work/Gasida_series/practice kubectl get pipeline
NAME AGE
clone-read 57s
#
minji ~/Desktop/work/Gasida_series/practice kubectl get pipeline -o yaml
apiVersion: v1
items:
- apiVersion: tekton.dev/v1
kind: Pipeline
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"tekton.dev/v1","kind":"Pipeline","metadata":{"annotations":{},"name":"clone-read","namespace":"default"},"spec":{"description":"This pipeline clones a git repo, then echoes the README file to the stout.\n","params":[{"description":"The git repo URL to clone from.","name":"repo-url","type":"string"}],"tasks":[{"name":"fetch-source","params":[{"name":"url","value":"$(params.repo-url)"}],"taskRef":{"name":"git-clone"},"workspaces":[{"name":"output","workspace":"shared-data"}]}],"workspaces":[{"description":"This workspace contains the cloned repo files, so they can be read by the\nnext task.\n","name":"shared-data"}]}}
creationTimestamp: "2025-10-24T14:11:08Z"
generation: 1
name: clone-read
namespace: default
resourceVersion: "29298"
uid: 835cc5df-8ad7-4ae7-af32-073069f38770
spec:
description: |
This pipeline clones a git repo, then echoes the README file to the stout.
params:
- description: The git repo URL to clone from.
name: repo-url
type: string
tasks:
- name: fetch-source
params:
- name: url
value: $(params.repo-url)
taskRef:
kind: Task
name: git-clone
workspaces:
- name: output
workspace: shared-data
workspaces:
- description: |
This workspace contains the cloned repo files, so they can be read by the
next task.
name: shared-data
kind: List
metadata:
resourceVersion: ""
minji ~/Desktop/work/Gasida_series/practice kubectl get pod
NAME READY STATUS RESTARTS AGE
pacman-576769bb86-t5scc 1/1 Running 2 (173m ago) 23h

# 파이프라인 실행 : 파이프라인을 인스턴스화하고 실제 값 설정
cat << EOF | kubectl create -f -
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
generateName: clone-read-run-
spec:
pipelineRef:
name: clone-read
taskRunTemplate:
podTemplate:
securityContext:
fsGroup: 65532
workspaces: # 작업 공간 인스턴스화, PVC 생성
- name: shared-data
volumeClaimTemplate:
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
params: # 저장소 URL 매개변수 값 설정
- name: repo-url
value: https://github.com/tektoncd/website
EOF
#
minji ~/Desktop/work/Gasida_series/practice kubectl get pipelineruns -o yaml
apiVersion: v1
items:
- apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
.
.
.
runningInEnvWithInjectedSidecars: true
verificationNoMatchPolicy: ignore
startTime: "2025-10-24T14:14:16Z"
kind: List
metadata:
resourceVersion: ""
#
minji ~/Desktop/work/Gasida_series/practice kubectl get pipelineruns
NAME SUCCEEDED REASON STARTTIME COMPLETIONTIME
clone-read-run-zjfkj False CouldntGetTask 45s 45s
#
minji ~/Desktop/work/Gasida_series/practice tkn pipelinerun list
NAME STARTED DURATION STATUS
clone-read-run-zjfkj 1 minute ago 0s Failed(CouldntGetTask)
#
minji ~/Desktop/work/Gasida_series/practice tkn pipelinerun logs
Pipeline default/clone-read can't be Run; it contains Tasks that don't exist: Couldn't retrieve Task "git-clone": tasks.tekton.dev "git-clone" not found
#
minji ~/Desktop/work/Gasida_series/practice tkn pipelinerun logs
Pipeline default/clone-read can't be Run; it contains Tasks that don't exist: Couldn't retrieve Task "git-clone": tasks.tekton.dev "git-clone" not found

# 파이프라인에서 git clone 작업을 사용하려면 먼저 클러스터에 설치 필요
minji ~/Desktop/work/Gasida_series/practice tkn hub install task git-clone
WARN: This version has been deprecated
Task git-clone(0.9) installed in default namespace
# 추가된 task 확인
minji ~/Desktop/work/Gasida_series/practice kubectl get tasks
NAME AGE
git-clone 43s
hello 27m
minji ~/Desktop/work/Gasida_series/practice kubectl get tasks git-clone -o yaml | kubectl neat | yq
apiVersion: tekton.dev/v1
kind: Task
metadata:
annotations:
tekton.dev/categories: Git
.
.
.
# 파이프라인 재실행
minji ~/Desktop/work/Gasida_series/practice cat << EOF | kubectl create -f -
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
generateName: clone-read-run-
spec:
pipelineRef:
name: clone-read
taskRunTemplate:
podTemplate:
securityContext:
fsGroup: 65532
workspaces:
- name: shared-data
volumeClaimTemplate:
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
params:
- name: repo-url
value: https://github.com/tektoncd/website
EOF
pipelinerun.tekton.dev/clone-read-run-fk5fb created
#
minji ~/Desktop/work/Gasida_series/practice tkn pipelinerun list
NAME STARTED DURATION STATUS
clone-read-run-fk5fb 24 seconds ago 19s Succeeded
clone-read-run-zjfkj 6 minutes ago 0s Failed(CouldntGetTask)
#
minji ~/Desktop/work/Gasida_series/practice tkn pipelinerun logs
? Select pipelinerun: ) [Use arrows to move, type to filter]
# pv, pvc 확인
minji ~/Desktop/work/Gasida_series/practice kubectl get pod,pv,pvc
NAME READY STATUS RESTARTS AGE
pod/clone-read-run-fk5fb-fetch-source-pod 0/1 Completed 0 100s
pod/pacman-576769bb86-t5scc 1/1 Running 2 (3h2m ago) 23h
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE
persistentvolume/pvc-b5399cd4-c602-4fe4-9424-ee3ea6e76cac 1Gi RWO Delete Bound default/pvc-fcf9b36883 standard <unset> 98s
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
persistentvolumeclaim/pvc-fcf9b36883 Bound pvc-b5399cd4-c602-4fe4-9424-ee3ea6e76cac 1Gi RWO standard <unset>
6.4 Create a task to compile and package an ap from private git
비공개 git 저장소의 앱을 컴파일하고 패키징하는 과정을 tekton으로 자동화
tekton은 git을 위해 2가지 인증 체계를 지원 : basic-auth, ssh
2가지 옵션 모두 k8s secret를 사용하여 자격 증명을 저장하고 이를 tekton 또는 pipeline을 실행하는 serviceaccount에 연결
실습 - 샘플 앱 생성 및 git 초기화
# git 초기화
minji ~/Desktop/work/Gasida_series/practice/my-sample-app git init
Initialized empty Git repository in /Users/howoo/Desktop/work/Gasida_series/practice/my-sample-app/.git/
# git 사용자 설정
minji ~/Desktop/work/Gasida_series/practice/my-sample-app main git config --global user.name "*********"
minji ~/Desktop/work/Gasida_series/practice/my-sample-app main git config --global user.email "*********"
minji ~/Desktop/work/Gasida_series/practice/my-sample-app main git add .
minji ~/Desktop/work/Gasida_series/practice/my-sample-app main ✚ git commit -m "Initial commit - sample app"
[main (root-commit) 88c932e] Initial commit - sample app
1 file changed, 1 insertion(+)
create mode 100644 app.js
Github remote 연결 및 push
# origin remote 등록:
minji ~/Desktop/work/Gasida_series/practice/my-sample-app main git remote add origin https://github.com/ktokang/my-sample-app.git
# 메인 브랜치 이름을 main으로 변경 (GitHub 기본 브랜치와 맞춤):
minji ~/Desktop/work/Gasida_series/practice/my-sample-app main git branch -M main
# push
minji ~/Desktop/work/Gasida_series/practice/my-sample-app main git push -u origin main
Username for 'https://github.com': *******
Password for 'https://ktokang@github.com':
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 247 bytes | 247.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
To https://github.com/ktokang/my-sample-app.git
* [new branch] main -> main
branch 'main' set up to track 'origin/main'.

SSH key로 인증 설정
# ssh key 생성 & 보기
minji ~/Desktop/work/Gasida_series/practice/my-sample-app main ls -al ~/.ssh | grep ed25519
-rw-------@ 1 howoo staff 411 10월 24 23:47 id_ed25519
-rw-r--r--@ 1 howoo staff 98 10월 24 23:47 id_ed25519.pub
#
minji ~/Desktop/work/Gasida_series/practice/my-sample-app main eval "$(ssh-agent -s)"
Agent pid 8866
#
minji ~/Desktop/work/Gasida_series/practice/my-sample-app main ssh-add ~/.ssh/id_ed25519
Identity added: /Users/howoo/.ssh/id_ed25519
#
minji ~/Desktop/work/Gasida_series/practice/my-sample-app main cat ~/.ssh/id_ed25519.pub
ssh 연결 방식 사용 테스트
#
minji ~/Desktop/work/Gasida_series/practice/my-sample-app main ssh -i ~/.ssh/id_ed25519 -T git@github.com
The authenticity of host 'github.com (20.200.245.247)' can't be established.
ED25519 key fingerprint is SHA256:+DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'github.com' (ED25519) to the list of known hosts.
Hi ktokang! You've successfully authenticated, but GitHub does not provide shell access.
#
minji ~/Desktop/work/Gasida_series/practice/my-sample-app main git remote set-url origin git@github.com:ktokang/my-sample-app.git
#
minji ~/Desktop/work/Gasida_series/practice/my-sample-app main git add .
#
minji ~/Desktop/work/Gasida_series/practice/my-sample-app main ✚ git commit -m "add readme.md file"
[main 604fcd4] add readme.md file
3 files changed, 10 insertions(+)
create mode 100644 readme.md
#
minji ~/Desktop/work/Gasida_series/practice/my-sample-app ↱ main git push -u origin main
Enumerating objects: 6, done.
Counting objects: 100% (6/6), done.
Delta compression using up to 10 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (5/5), 809 bytes | 809.00 KiB/s, done.
Total 5 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
To github.com:ktokang/my-sample-app.git
88c932e..604fcd4 main -> main
branch 'main' set up to track 'origin/main'.
Tekton Pipelines를 사용하여 git 소스코드를 복제
# Git 인증용 ssh 사설키를 base64 인코딩
minji ~/Desktop/work/Gasida_series/practice/my-sample-app main SSHPK=$(cat ~/.ssh/id_ed25519 | base64 -w0
# Git 인증서버 known_hosts 값을 base64 인코딩
minji ~/Desktop/work/Gasida_series/practice/my-sample-app main SSHKH=$(ssh-keyscan github.com | grep ecdsa-sha2-nistp256 | base64 -w0)
#
minji ~/Desktop/work/Gasida_series/practice/my-sample-app main cat << EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
name: git-credentials
data:
id_rsa: $SSHPK
known_hosts: $SSHKH
EOF
secret/git-credentials created
#
minji ~/Desktop/work/Gasida_series/practice/my-sample-app main kubectl get secret
NAME TYPE DATA AGE
git-credentials Opaque 2 47s
sh.helm.release.v1.pacman.v1 helm.sh/release.v1 1 24h
sh.helm.release.v1.pacman.v2 helm.sh/release.v1 1 24h
sh.helm.release.v1.pacman.v3 helm.sh/release.v1 1 24h
sh.helm.release.v1.pacman.v4 helm.sh/release.v1 1 24h
# serviceaccount 에 secret 속성 지정 및 확인
minji ~/Desktop/work/Gasida_series/practice/my-sample-app main cat << EOF | kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
name: build-bot
secrets:
- name: git-credentials
EOF
serviceaccount/build-bot created
#
minji ~/Desktop/work/Gasida_series/practice/my-sample-app main kubectl get sa
NAME SECRETS AGE
build-bot 1 6s
default 0 25h
파이프라인, 파이프라인 실행
# 파이프라인 파일 작성
minji ~/Desktop/work/Gasida_series/practice/my-sample-app main cat << EOF | kubectl apply -f -
apiVersion: tekton.dev/v1
kind: Pipeline
metadata:
name: my-clone-read
spec:
description: |
This pipeline clones a git repo, then echoes the README file to the stout.
params: # 매개변수 repo-url
- name: repo-url
type: string
description: The git repo URL to clone from.
workspaces: # 다운로드할 코드를 저장할 공유 볼륨인 작업 공간을 추가
- name: shared-data
description: |
This workspace contains the cloned repo files, so they can be read by the
next task.
- name: git-credentials
description: My ssh credentials
tasks: # task 정의
- name: fetch-source
taskRef:
name: git-clone
workspaces:
- name: output
workspace: shared-data
- name: ssh-directory
workspace: git-credentials
params:
- name: url
value: \$(params.repo-url)
- name: show-readme # add task
runAfter: ["fetch-source"]
taskRef:
name: show-readme
workspaces:
- name: source
workspace: shared-data
EOF
pipeline.tekton.dev/my-clone-read created
# 확인
minji ~/Desktop/work/Gasida_series/practice/my-sample-app main tkn pipeline list
NAME AGE LAST RUN STARTED DURATION STATUS
clone-read 1 hour ago clone-read-run-fk5fb 51 minutes ago 19s Succeeded
#
minji ~/Desktop/work/Gasida_series/practice/my-sample-app main tkn pipeline describe
? Select pipeline: [Use arrows to move, type to filter]
> clone-read
my-clone-read
.
.
.
#
minji ~/Desktop/work/Gasida_series/practice/my-sample-app main kubectl get pipeline -o wide
NAME AGE
clone-read 62m
my-clone-read 2m18s
#
minji ~/Desktop/work/Gasida_series/practice/my-sample-app main kubectl get pod
NAME READY STATUS RESTARTS AGE
clone-read-run-fk5fb-fetch-source-pod 0/1 Completed 0 53m
pacman-576769bb86-t5scc 1/1 Running 2 (3h54m ago) 24h
# show-readme task
cat << EOF | kubectl apply -f -
apiVersion: tekton.dev/v1
kind: Task
metadata:
name: show-readme
spec:
description: Read and display README file.
workspaces:
- name: source
steps:
- name: read
image: alpine:latest
script: |
#!/usr/bin/env sh
cat \$(workspaces.source.path)/readme.md
EOF
# 파이프라인 실행
minji ~/Desktop/work/Gasida_series/practice/my-sample-app main cat << EOF | kubectl create -f -
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
generateName: clone-read-run-
spec:
pipelineRef:
name: my-clone-read
taskRunTemplate:
serviceAccountName: build-bot
podTemplate:
securityContext:
fsGroup: 65532
workspaces:
- name: shared-data
volumeClaimTemplate:
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
- name: git-credentials
secret:
secretName: git-credentials
params:
- name: repo-url
value: git@github.com:gasida/my-sample-app.git # 제가 사용하는 것 or 자신의 private repo 지정
EOF
pipelinerun.tekton.dev/clone-read-run-cm7fg created
# 결과 확인 : 둘중에 한개는 실패함 ????
minji ~/Desktop/work/Gasida_series/practice/my-sample-app main kubectl get pod,pv,pvc
NAME READY STATUS RESTARTS AGE
pod/clone-read-run-cm7fg-fetch-source-pod 0/1 Error 0 19s
pod/clone-read-run-fk5fb-fetch-source-pod 0/1 Completed 0 55m
pod/pacman-576769bb86-t5scc 1/1 Running 2 (3h56m ago) 24h
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE
persistentvolume/pvc-b5399cd4-c602-4fe4-9424-ee3ea6e76cac 1Gi RWO Delete Bound default/pvc-fcf9b36883 standard <unset> 55m
persistentvolume/pvc-bdd52583-7010-4db6-8f82-219133ee1988 1Gi RWO Delete Bound default/pvc-964ade2b5e standard <unset> 16s
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
persistentvolumeclaim/pvc-964ade2b5e Bound pvc-bdd52583-7010-4db6-8f82-219133ee1988 1Gi RWO standard <unset> 19s
persistentvolumeclaim/pvc-fcf9b36883 Bound pvc-b5399cd4-c602-4fe4-9424-ee3ea6e76cac 1Gi RWO standard <unset>
# task를 실행하는 파드에 Serivce accout 정보 확인
minji ~/Desktop/work/Gasida_series/practice/my-sample-app main kubectl describe pod | grep 'Service Account'
Service Account: build-bot
Service Account: default
Service Account: default
# 삭제
kubectl delete taskruns,pipelineruns.tekton.dev --all