목표: 자신의 애플리케이션 프로그램을 Kubernetes 환경에 배포해서 운영 가능하도록 구성
cd shared-dir/collaboration
remote-cp -rf ./cloud /config/workspace
remote-cp -rf ./k8s-rbac /config/workspace
ls -al
만약 workspace의 user가 root인 경우
sudo chown -R 911:911
-R | 재귀적(recursively) 변경 — 디렉토리일 경우 하위 모든 파일과 폴더 포함 |
911:911 | 소유자 ID(uid): 911, 그룹 ID(gid): 911 로 설정 |
sudo chown -R 911:911 ./workspace
해당 코드로 user를 변경
쿠버네티스 API server에 접속하는 주체(Subject)를 의미
Pod 또는 외부 서비스가 클러스터 리소스에 접근할 수 있게 해주는 K8s 내장 계정
시스템 간 인증을 위한 계정
K8s 리소스로 Namespace 안에 생성
Pod 생성 시 default ServiceAccount가 자동 연결
사람이(Human) 사용하는 계정
kubectl CLI
, k8s Dashboard
, 또는 API를 직접 호출해서 사용
K8s 자체에서는 미지원, 외부 시스템과 연동 필요
예: OIDC, x509 인증서, SSO, alice@example.com
, devops-admin
여러 User를 묶는 논리적 단위
K8s 자체에서는 미지원, 외부 시스템과 연동 필요
kubernete 내에서는 다음과 같은 이유로 Service Account 중심으로 사용하며 User 와 User Group은 잘 사용하지 않음
계정은 단순히 사용자를 구분하는 용도
Kubernetes가 직접 User/Group을 관리 미지원
외부 인증 연동이 필요하며, 구성과 운영이 복잡
관리 포인트 증가
자동화 환경에서는 사람이 직접 API를 호출하는 경우가 거의 없음
대부분 앱이나 컨트롤러(예: ArgoCD, Tekton, Jenkins 등)가 자동으로 실행
자동화 앱이나 컨트롤러는 Pod로 동작하므로 ServiceAccount가 적합
kubectl 등을 활용한 접근 역시 Service Account로 생성해서 실행 가능
RBAC이 ServiceAccount에 최적화되어 있음
RoleBinding, ClusterRoleBinding 등에서 명확하게 ServiceAccount를 지정
Namespace 단위로 권한을 잘게 쪼개어 관리하기 용이
ServiceAccount 는 쿠버네티스 클러스터 내부에서 Pod나 서비스가 API 서버에 인증된 방식으로 접근할 수 있도록 만들어진 계정.
이를 위해 인증 수단으로 JWT(JSON Web Token) 형태의 ServiceAccount 토큰이 사용
k get sa
자기 네임스페이스에 대한 접근 권한을 가질 수 있음
Service Account는 Token 발행을 위해 동일 이름을 자동 생성, 1.24 이후 버전에서는 수동 연결해서 Token 발행
Pod가 Service Acount 연결 시 아래 디렉토리에 token, ca.crt, namespace 파일 생성
KubeConfig 환경변수 설정
config에 있는 토큰 값을 가져와서 담음
자기 홈 디렉토리 내 config에 있는 토큰을 가져옴
/var/run/…/serviceaccount 경로의 토큰을 가져옴
kubectl get pod -n skala-practice
k exec -it collabo-shared-sts-0 -- /bin/bash
collabo-shared-sts-0 Pod에 접속해서 bash 셸로 들어갈 수 있음.
cd /var/run/secrets/kubernetes.io/serviceaccount
ls
ctrl d로 나갈 수 있음
Kubernetes는 모든 리소스에 대한 처리는 kube API Server + ETCD Resource 에 대한 접근
모든 Action에 대해서 API Server를 활용해야 하므로, 통신을 위해선 RBAC을 사용해야 함
역할 기반 접근 제어 (RBAC)는 사용자가 직접 권한을 받는 것이 아니라, 역할(Role)을 통해 접근 권한을 조절하는 방법
ServiceAccount skala-admin-sa
가 namespace
리소스를 조회할 권한이 없어서 생긴 문제
namespaces
리소스를 조회할 권한이 없음api 그룹에 대한 path 내용도 담고 있음
⇒ Role은 namespace가 존재함
⇒ ClusterRole은 namespace가 존재하지 X
rules
필드 설명 (RBAC 권한 설정)RBAC의 rules
필드는 Role
또는 ClusterRole
안에서 사용되며, 권한을 정의합니다.
필드 이름 | 설명 |
---|---|
apiGroups | 리소스가 속한 API 그룹 지정예: "" (core), apps , rbac.authorization.k8s.io 등 |
resources | 권한을 부여할 리소스 종류예: pods , deployments , configmaps |
verbs | 허용할 동작(행위)예: get , list , watch , create , delete , update 등 |
resourceNames | (선택) 특정 리소스 이름에만 제한예: ["my-secret", "my-pod"] |
nonResourceURLs | (선택) API 외부 URL 경로에 대한 권한 (예: /metrics , /healthz )→ 보통 ClusterRole에서 사용 |
kubectl api-resources
명령어 예시kubectl api-resources
이 명령어는 Kubernetes 클러스터에서 사용 가능한 모든 API 리소스 목록을 보여줍니다.
필드 | 설명 |
---|---|
NAME | 리소스 이름 (예: pods , deployments ) |
SHORTNAMES | 줄임말 (예: po for pods, deploy for deployments) |
APIGROUP | 리소스가 속한 API 그룹"" 이면 core API group |
NAMESPACED | 해당 리소스가 Namespace에 종속적인지 여부 (true or false ) |
k get sa
k get secret
k get secret skala-admin-sa-token -o yaml
skala-admin-sa-token
이라는 이름의 시크릿(Secret) 리소스를 YAML 형식으로 출력
k get pod
쿠버네티스(Kubernetes)에서 파드(Pod)의 목록과 상태를 조회하는 명령어
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
labels:
amdp.io/app: skala25a-stock-api-wamdp
amdp.io/profile: skala.skala-a
argocd.argoproj.io/instance: skala25a-stock-api-wamdp.skala-a.skala
cluster-tier: dev
name: skala25a-stock-api-wamdp-pod-reader-skala-a
namespace: skala-practice
rules:
- apiGroups:
- ""
resources:
- pods
- configmaps
verbs:
- get
- watch
- list # 목록을 볼 수 있음
k get clusterrole admin -o yaml
쿠버네티스 클러스터 내에 정의된 admin
이라는 이름의 ClusterRole의 상세 정보를 YAML 형식으로 출력
k get --raw /metrics
쿠버네티스 API 서버 또는 각 컴포넌트(예: kubelet, kube-scheduler, kube-controller-manager 등)가 노출하는 Prometheus 형식의 시스템 메트릭을 그대로 출력
(RDE) > kcns skala-argocd
Context "skala-edu-cluster" modified.
쿠버네티스 환경에서 현재 작업 중인 네임스페이스를 skala-argocd
로 전환하는 역할
(= kubectl config set-context --current --namespace=skala-argocd)
Namespace는 Kubernetes 클러스터 안에서 리소스들을 논리적으로 분리해주는 가상 공간.
특정 리소스 자원을 나눠주는, 리소스를 각각의 분리된 영역으로 나누기 좋은 방법
(명시적 분리)
여러 네임스페이스를 사용하면 복잡한 쿠버네티스 시스템을 더 작은 그룹으로 분할
멀티 테넌트(Multi-tenant) 환경을 분리하여 리소스를 생산, 개발, QA 환경 등으로 사용
리소스 이름은 네임스페이스 내에서만 고유 명칭 사용
현재 클러스터의 기본 네임스페이스 확인하기
테넌트
: 클라우드 인프라/서비스 제공 방식에서 소프트웨어 인스턴스(Software Instance)를 공유하는 사용자
Namespace는 Kubernetes 리소스를 논리적으로 나누고 관리하는 컨테이너 역할을 하며, 자원 분리와 보안, 조직화에 매우 유용
kubectlget pod -A. (full argument: --all-namespaces)
전체 네임스페이스를 대상으로 kubectl을 실행하는 방법
Kubernetes는 Pod 단위로 라이프사이클을 관리하며, 컨테이너는 직접적인 관리를 하지 않는다
컨테이너의 공동 배포된 그룹이며 쿠버네티스의 기본 빌딩 블록을 대표
쿠버네티스는 컨테이너를 개별적으로 배포하지 않고 컨테이너의 포드를 항상 배포하고 운영
일반적으로 포드는 단일 컨테이너만 포함하지만 다수의 컨테이너를 포함 할 수 있음
포드는 다수의 노드에 생성되지 않고 단일 노드에서만 실행
여러 프로세스를 실행하기 위해서는 컨테이너 당 단일 프로세스가 적합
다수의 프로세스를 제어하려면? -> 다수의 컨테이너를 다룰 수 있는 그룹이 필요!
컨테이너는 보통 하나의 Pod 안에서 함께 실행되며, 같은 네트워크(IP), 같은 저장소(Volume)를 공유합니다.
항목 | 설명 |
---|---|
같이 스케줄링 | Pod 안의 모든 컨테이너는 같은 노드에 같이 배치됨 |
같은 네트워크 | Pod 안의 컨테이너들은 같은 localhost(127.0.0.1) 로 통신 가능 |
같은 Volume 사용 가능 | 공유 볼륨으로 파일을 공유할 수 있음 |
보통 하나의 컨테이너만 포함 | 대부분 1 컨테이너 = 1 Pod (sidecar 쓰는 경우 제외) |
포드는 밀접하게 연관된 프로세스를 함께 실행하고 마치 하나의 환경에서 동작하는 것처럼 보임
그러나 동일한 환경을 제공하면서 다소 격리된 상태로 유지
포드의 모든 컨테이너는 동일한 네트워크 및 리눅스 네임스페이스에서 실행
같은 호스트 이름 및 네트워크 인터페이스를 공유 (포트 충돌 가능성 있음)
포드의 모든 컨테이너는 동일한 IPC 네임스페이스 아래에서 실행되며 IPC를 통해 통신 가능
쿠버네티스 클러스터의 모든 포드는 공유된 단일 플랫, 네트워크 주소 공간에 위치
파드 사이에는 NAT 게이트웨이가 존재 하지 않음
⇒ 모든 Pod는 고유한 IP를 갖고 있고, 클러스터 내부에서는 NAT 없이 직접 통신이 가능.
파드내 컨테이너 간 통신은 local host 기반을 통신하면 모든 자원을 공유
컨테이너를 포드 전체에 적절하게 구성하는 방법
다수의 포드로 멀티티어 애플리케이션 분할하기
각각 스케일링이 가능한 포드로 분할하기
front/back 단을 병렬로 띄우기 위해선 나누어서 구성
: 둘 간의 communication 과정을 보고 결정하지만, 보통 main process는 나누어서 구성
컨테이너에서 호스트로 포트 포워딩, 로컬 PC ↔ 클러스터 내부 리소스 간에 직접 연결하는 유용한 디버깅 도구
디버깅 혹은 다른 이유로 서비스를 거치지 않고 특정 포드와 통신하고 싶을 때 사용
kubectlport-forward 명령으로 수행
컨테이너 8888 포트를 pod의 8080 포트로 전달
Multi-Pod에 Port-forward 시 개별 IP
kubectl port-forward pod/webserver-pod 8888:8080 –n {namespace}
bg
curl localhost:8888
kubectl port-forward
는 로컬 포트를 Kubernetes 리소스의 포트에 연결해서, 클러스터 내부 리소스를 외부에서 직접 접근 가능하게 해주는 도구.
Pod는 하나의 독자적인 실행 단위이며, kubernetes에서 관리하는 최소 단위
docker가 가지고 있는 arguments를 전달할 수 있음.
python3 fastserver.py --host 0.0.0.0 --port 8080
Pod의 실행되기 전 가장 먼저 초기에 실행되어 초기화 및 사전 작업을 수행하는 컨테이너로 Pod 내 포함
Pod 실행 시 최초 실행되며, Init-container가 정상적으로 종료해야 하지만 다음 절차가 실행
Init-container가 일정 시간 이상 내에 정상 처리되지 않으면 재시작 정책에 따라 재시도
apiVersion: v1
kind: Pod
metadata:
name: sk000-init-container-test
namespace: skala-practice
annotations:
prometheus.io/scrape: 'true'
prometheus.io/port: '8081'
prometheus.io/path: '/actuator/prometheus'
update: ${ANNOTATION_UPDATE}
labels:
app: sk000-init-container-test
spec:
initContainers:
- name: check-active-enabled
image: busybox
command:
- sh
- -c
- |
timeout 300 sh -c "
while [ ! -f /root/active.enabled ]; do
echo 'Waiting for active.enabled file...'
sleep 5
done
echo 'File active.enabled found. Initialization complete.'
"
volumeMounts:
- name: root-volume
mountPath: /root
containers:
- name: init-container-test
image: amdp-registry.skala-ai.com/skala25a/sk000-webserver:2.0.0
imagePullPolicy: Always
env:
- name: LOGGING_LEVEL
value: DEBUG
- name: USER_NAME
value: sk000
volumes:
- name: root-volume
emptyDir: {}
cicd.sh -y
중간에 묻는 질문 없이 자동으로 모든 과정을 진행하는 자동 확인 옵션
k apply –f init-pod.yaml
해당 YAML 파일을 기준으로 Kubernetes 리소스를 생성하거나 업데이트하는 명령어
k get pod –w
k exec -it sk021-init-container-test -c check-active-enabled -- /bin/sh
/ # cd /root
~ # ls
~ # touch active.enabled
해당 pod 내 check-active-enabled
컨테이너에 셸로 접속
~ # touch active.enabled
active.enabled
라는 빈 파일을 생성
sk021-init-container-test
라는 Pod의check-active-enabled
컨테이너 안에 접속해서/root/active.enabled
라는 상태 파일을 생성
sudo cicd.sh --all # -a or -build -push
sudo cicd.sh --all
은 Docker 이미지 빌드부터 푸시, 배포까지의 전체 파이프라인을 자동으로 실행하는 스크립트
Init Container
동작 원리 요약Init Container
는 메인 컨테이너보다 먼저 실행.
모든 Init Container
가 성공적으로 종료(exit 0) 되어야 메인 컨테이너가 실행되고, Pod 전체가 Running
상태가 됨.
보통 Init Container
는 특정 조건이나 파일 존재 등을 검사하고, 조건이 맞아야 끝나도록 설계됨.
init-container
의 목적은 어떤 조건이 충족될 때까지 기다리는 것이고, 그 조건이/root/active.enabled
존재 여부라면touch
로 조건을 만족시킴
initContainers:
- name: check-active-enabled
image: busybox
command:
- sh
- -c
- |
timeout 300 sh -c "
while [ ! -f /root/active.enabled ]; do
echo 'Waiting for active.enabled file...'
sleep 5
done
echo 'File active.enabled found. Initialization complete.'
"
해당 코드는 init-pod.yaml 중 일부로 init-container가 실행되면서
/root/active.enabled
파일이 존재할 때까지 최대 5분(300초) 동안 대기한다는 의미
항목 | 내용 |
---|---|
init-container 역할 | 특정 파일(/root/active.enabled )이 존재할 때까지 대기 |
동작 방식 | 쉘 루프로 감시, 파일 생기면 정상 종료 |
공유 방법 | emptyDir 를 /root 에 마운트해 다른 컨테이너와 공유 |
너의 행동 결과 | 예상대로 루프 종료 → Pod Running 상태 |
일반적으로 Pod는 주 컨테이너 와 지원 컨테이너인 한 개 이상의 side car 컨테이너로 이루어져 있다.
Pod내 컨테이너는 한 배를 탄 동지 죽어도 같이 죽고 살아도 같이 산다
Kubernetes의 핵심은 컨테이너의 탄력적 확장성 지원인데, Pod 내 컨테이너는 지원되지 않는다.
일반적으로 공통 기능을 옆에 같이 포함 (side car) 시켜서 컨테이너의 안정성, 네트워크, 로그, 모니터링, 자가 복구를 지원하도록 한다
service간 트래픽 연결을 그물망처럼 자유롭게 연결
외/내부의 모든 traffic을 관리할 수 있음
Traffic Flow Control & Traffic Resilient
ReplicaSet은 Kubernetes에서 지정한 수의 Pod 복제본을 항상 유지하도록 도와주는 컨트롤러
만약 어떤 Pod가 종료되거나 삭제되면, ReplicaSet이 자동으로 새로운 Pod를 생성해서 지정된 수를 유지
ReplicaSet을 사용자가 생성하지 않고 Deployment 적용 시 ReplicaSet Controller가 RepllicaSet을 자동 구성
Deployment는 여러 개의 ReplicasSet을 제공해서 버전 변화에 따라 Rolling Update 및 Rollback 실행
Replicaset을 둬서, Rolling-update 역할(점진적 업데이트)을 할 수 있음
pod 이미지 업데이트 시 새로운 ReplicaSet이 만들어지고 Old 와 New Pod가 점진적 업데이트 (Rolling update) 지원
ReplicaSet의 선언적 정의는 Deployment 내에 포함되어 있음
Rolling Update 시 기존 desired replica 개수보다 추가로 생성될 수 있는 Pod = 일시적 넘침
업데이트 중에 기존 desired replica 개수기준 동작하지 않아도 되는 Pod 수
maxSurge 만큼 넘친 다음에 항상 4개가 유지되도록 해서 멈춘 pod가 없게끔 설정
maxSurge 만큼 넘치지만, 최대 maxUnavailable만큼 비활성화될 수 있음
cicd.sh -y
kubectl apply -f deploy.yaml
k describe replicaset sk021-replicaset-test-7bd98549cd
kubectl rollout history deploy sk021-replicaset-test
kubectl rollout history deploy sk021-replicaset-test --revision=3
(RDE) > kubectl port-forward svc/sk021-replicaset-test 8080:8080
(RDE) > kubectl rollout undo deploy sk021-replicaset-test
(RDE) > kubectl rollout history deploy sk021-replicaset-test --revision=4
undo를 통해서 정상적으로 rollback이 됨을 확인할 수 있음
(⎈|skala-edu-cluster:skala-practice) ~/workspace/cloud/k8s-ddive/04.replicaset
(RDE) > k get pod -l app=sk021-replicaset-test
NAME READY STATUS RESTARTS AGE
sk021-replicaset-test-68fd9576bf-gjmbr 0/1 ImagePullBackOff 0 14m
sk021-replicaset-test-7bd98549cd-s4wzw 1/1 Running 0 44m
(⎈|skala-edu-cluster:skala-practice) ~/workspace/cloud/k8s-ddive/04.replicaset
(RDE) > k delete pod sk021-replicaset-test-68fd9576bf-gjmbr
pod "sk021-replicaset-test-68fd9576bf-gjmbr" deleted
(⎈|skala-edu-cluster:skala-practice) ~/workspace/cloud/k8s-ddive/04.replicaset
(RDE) > k get pod -l app=sk021-replicaset-test
NAME READY STATUS RESTARTS AGE
sk021-replicaset-test-68fd9576bf-z7jjq 1/1 Running 0 15s
Rollback을 했는데, Webserver에 1.0.0 버전이 없어서 오류가 발생
→ 해당 pod에는 오류가 생겨 정상적으로 작동하지 않고, 그 전의 pod를 죽이지 않고 그대로 유지
→ webserver에 우선적으로 1.0.0을 배포하고 오류가 있는 pod를 지우고 다시 실행해야 롤백한 버전이 정상적으로 웹에 뜸
C:\Users\Administrator\Desktop\cloud_k8s\rde-launcher-1.2.2.add-jmeter\exec\rde-launcher-windows\config\workspace\cloud\container\05.webserver
해당 경로에서
docker login amdp-registry.skala-ai.com/skala25a
아이디와 비밀번호를 입력한 후,
docker build --tag amdp-registry.skala-ai.com/skala25a/sk021-webserver:1.0.0 .
docker push amdp-registry.skala-ai.com/skala25a/sk021-webserver:1.0.0
해당 과정을 통해서 1.0.0 버전을 docker 로 push하여 webserver에 이미지를 올릴 수 있음
k port-forward deploy/sk021-replicaset-test --address 0.0.0.0 8080:8080
Deployment는 여러 개의 Replicas를 관리하기 위한 ReplicaSet 상위 리소스
새로운 이미지를 가지는 동일한 Deployment를 배포하는 경우 기존 운영 중인 Replica Set Pod와 신규 버전 Replica Set Pod가 점진적 업데이트되는데, 이를 통합 관리하는 것이 Deployment
k8s 리소스에 붙이는 Key-value 쌍의 메타데이터로, 리소스를 그룹화하기 위한 필터링 도구로 활용
⇒ 사용자가 리소스를 분류하거나 특정 그룹으로 묶는 데 사용예를 들어, 특정 애플리케이션, 환경, 또는 릴리즈 버전에 따라 리소스를 구분
붙였다가 땔 수 있음.
특정 조건에 따라 Label을 가진 리소스를 선택하는 기능
⇒ Service, Deployment, 또는 다른 리소스가 Selector를 통해 특정 Label을 가진 리소스(예: Pod)를 타겟팅하거나 관리