목차 |
---|
1. Pod
1.1 Pod 개요
쿠버네티스 노드 내에 한개 이상의 컨테이너를 가진 파드가 각각 실행되고 있으며, 파드마다 다른 IP를 가지고 있고 파드 내의 컨테이너끼리는 통신이 가능합니다.
파드 내 컨테이너끼리 볼륨을 공유하며 컨테이너가 죽고 재시작 되어도 파드가 살아있는 한 shared volume은 유지할 수 있습니다.
init-container(초기화 컨테이너) :파드의 앱 컨테이너들이 실행되기 전에 실행되는 특수한 컨테이너로 유틸리티 또는 스크립트 등을 포함할 수 있습니다.
(1) Pod Lifecycle
...
value
...
description
...
Pending
...
파드가 클러스터에 승인되었지만, 하나 이상의 컨테이너가 설정되지 않았고 실행할 준비가 되지 않은 상태입니다.
...
Running
...
파드가 노드에 바인딩되었고, 모든 컨테이너가 생성된 상태. 하나의 컨테이너가 아직 실행 중이거나, 시작 또는 재시작 중에 있는 상태입니다.
...
Succeeded
...
파드에 있는 모든 컨테이너들이 성공적으로 종료되었고, 재시작되지 않는 상태입니다.
...
Failed
...
파드에 있는 모든 컨테이너가 종료되었고, 적어도 하나 이상의 컨테이너가 실패로 종료된 상태입니다.
...
Unknown
...
어떤 이유에 의해서 파드의 상태를 얻을 수 없는 상태. 일반적으로 파드가 실행되어야 하는 노드와의 통신 오류로 인해 발생합니다.
(2) kubectl run으로 pod 생성
코드 블럭 |
---|
kubectl run test-nginx --image=nginx:1.19 |
정보 |
---|
또한 dry-run 옵션과 -o옵션을 이용하여 yaml파일을 간단하게 생성 할 수 도 있습니다 kubectl create deploy nginx --image=nginx --dry-run -o yaml > nginx-deploy.yaml |
(3) yaml 형식으로 pod 생성
코드 블럭 |
---|
apiVersion: v1
kind: Pod
metadata:
name: test-nginx2
spec:
containers:
- name: test-nginx2
image: nginx:1.19
ports:
- containerPort: 80
# yaml 파일 적용
kubectl apply -f [yaml file] |
...
value
...
description
...
apiVersion
...
오브젝트를 생성하기 위해 사용할 쿠버네티스 API 버전을 명세합니다.
https://kubernetes.io/ko/docs/concepts/overview/kubernetes-api/
...
kind
...
어떤 종류의 오브젝트를 생성하고자 하는지 명세합니다.
ex) pod, services, replicaset ...
...
metadata
...
name, UID, namespace 등을 기본적인 정보를 포함합니다.
name: 특정 namespace에서 유일한 값으로 설정
labels: 특정 오브젝트만 나열하거나 검색할 때 사용되는 key-value 쌍
spec: 생성할 오브젝트의 구체적인 내용을 정의. spec에 대한 포맷은 오브젝트의 종류마다 다릅니다.
...
(4) pod 조회, 수정 및 삭제
코드 블럭 |
---|
# pod 조회
kubectl get pod -n [namespace]
=> namespace를 지정하지 않으면 default namespace에 있는 pod를 조회합니다.
# 모든 Namespace의 pod 조회
kubectl get pod -A
# pod 수정
kubectl edit pod [pod name]
# pod 삭제
kubectl delete pod [pod name]
kubectl delete -f [yaml 파일] |
(5) 운영중에 이미지 버전 바꾸기
코드 블럭 |
---|
[root@m-k8s 0907]# cat nginx.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-nginx2
spec:
containers:
- name: test-nginx2
image: nginx:1.19
ports:
- containerPort: 80
[root@m-k8s 0907]# kubectl edit pod/test-nginx2
pod/test-nginx2 edited
[root@m-k8s 0907]# kubectl describe pod/test-nginx2
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Created 18s (x2 over 64m) kubelet Created container test-nginx2
Normal Killing 18s kubelet Container test-nginx2 definition changed, will be restarted
Normal Pulled 18s kubelet Container image "nginx:latest" already present on machine
Normal Started 17s (x2 over 64m) kubelet Started container test-nginx2 |
(6) Pod 설정 변경
파드 설정 변경 시, 변경 불가 항목인 경우 백업파일 생성 → 백업파일로 생성 가능
코드 블럭 |
---|
[root@m-k8s 0907]# kubectl edit pod test-nginx
A copy of your changes has been stored to "/tmp/kubectl-edit-1281676954.yaml"
error: At least one of apiVersion, kind and name was changed
[root@m-k8s 0907]# kubectl get pods
NAME READY STATUS RESTARTS AGE
test-nginx 1/1 Running 0 11m
test-nginx2 1/1 Running 0 10m
[root@m-k8s 0907]# kubectl apply -f /tmp/kubectl-edit-1281676954.yaml
pod/test-nginx3 created
[root@m-k8s 0907]# kubectl get pods
NAME READY STATUS RESTARTS AGE
test-nginx 1/1 Running 0 84m
test-nginx2 1/1 Running 1 (18m ago) 83m
test-nginx3 1/1 Running 0 72m |
새로 yaml 파일을 만들어서 생성
코드 블럭 |
---|
[root@m-k8s 0907]# kubectl get pod test-nginx2 -o yaml > test-nginx4.yaml
[root@m-k8s 0907]# vi test-nginx4.yaml
# name change from test-nginx2 to test-nginx4
[root@m-k8s 0907]# kubectl create -f test-nginx4.yaml
pod/test-nginx4 created
[root@m-k8s 0907]# kubectl get pods
NAME READY STATUS RESTARTS AGE
test-nginx 1/1 Running 0 165m
test-nginx2 1/1 Running 1 (99m ago) 163m
test-nginx3 1/1 Running 0 153m
test-nginx4 1/1 Running 0 17s |
(7) Pod 정보 확인
코드 블럭 |
---|
# pod 정보 자세히 보기
kubectl get pod -o wide
# pod 로그 확인
kubectl logs [pod name]
# pod의 상세 정보
kubectl describe pod [pod name]
# pod 정보를 yaml 파일 형식으로 출력
kubectl get pod [pod name] -o yaml |
(8) Pod 구성 설명서
apiVerion은 아래와 같이 확인 할 수 있습니다
정보 |
---|
yaml 파일은 아래 4가지의 형태를 가지며 해당 오브젝트내 값을 선언하여 사용 apiVersion : # kubectl api-version 명령어로 사용가능한 apiversion을 확인 |
모든데이터는 key: value 형태로 정의 합니다 :(콜론)와 value 사이에는 꼭 띄어쓰기가 들어가야 합니다.
(9) kubectl 자동완성
정보 |
---|
bash-completion 를 이용하여 kubectl도 자동완성 기능을 사용 할 수 있습니다 [root@m-k8s 0907]# yum install bash-completion -y [root@m-k8s 0907]# kubectl ap <tab> 누르면 자동완성 |
정보 |
---|
통상적으로 kubernetes는 k로 alias 주어서 수행 [root@m-k8s 0907]# which k |
2. 워크로드 리소스
2.1 ReplicaSet
파드를 생성 및 복제하고 복제된 파드의 개수를 yaml 파일에서 선언된 개수 만큼 지속적으로 유지합니다.
코드 블럭 |
---|
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: nginx-rs
labels:
app: nginx-rs
tier: nginx-rs
spec:
# modify replicas according to your case
replicas: 3
selector:
matchLabels:
tier: nginx-rs
template:
metadata:
labels:
tier: nginx-rs
spec:
containers:
- name: nginx-rs
image: nginx |
yaml 파일에 선언된 대로 3개의 Pod가 실행되며, 하나의 Pod가 문제가 발생했을 경우 ReplicaSet은 문제가 생긴 파드를 지우고, 기존 것과 다른 IP와 Name을 가진 파드를 새롭게 구동시킵니다.
...
코드 블럭 | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
정보 | ||||||||||||||||
실습환경 연결
TIp> 아래와같이 forwarding된 포트가 있으면 바로 진입이 가능하다.
이 세팅은 Vagrantfile에서 아래와 같이 세팅한다.
특정 포트를 열기위해서는 아래와 같이 세팅한다.
세팅후 reload로 cofiguration을 반영한다.
|
정보 |
---|
file위치는 master node의 아래에 위치한다. root@cp-k8s:~/2024_k8s/edu# pwd |
1. Pod
1.1 Pod 개요
쿠버네티스 노드 내에 한개 이상의 컨테이너를 가진 파드가 각각 실행되고 있으며, 파드마다 다른 IP를 가지고 있고 파드 내의 컨테이너끼리는 통신이 가능합니다.
파드 내 컨테이너끼리 볼륨을 공유하며 컨테이너가 죽고 재시작 되어도 파드가 살아있는 한 shared volume은 유지할 수 있습니다.
init-container(초기화 컨테이너) :파드의 앱 컨테이너들이 실행되기 전에 실행되는 특수한 컨테이너로 유틸리티 또는 스크립트 등을 포함할 수 있습니다.
(1) Pod Lifecycle
value | description |
---|---|
Pending | 파드가 클러스터에 승인되었지만, 하나 이상의 컨테이너가 설정되지 않았고 실행할 준비가 되지 않은 상태입니다. |
Running | 파드가 노드에 바인딩되었고, 모든 컨테이너가 생성된 상태. 하나의 컨테이너가 아직 실행 중이거나, 시작 또는 재시작 중에 있는 상태입니다. |
Succeeded | 파드에 있는 모든 컨테이너들이 성공적으로 종료되었고, 재시작되지 않는 상태입니다. |
Failed | 파드에 있는 모든 컨테이너가 종료되었고, 적어도 하나 이상의 컨테이너가 실패로 종료된 상태입니다. |
Unknown | 어떤 이유에 의해서 파드의 상태를 얻을 수 없는 상태. 일반적으로 파드가 실행되어야 하는 노드와의 통신 오류로 인해 발생합니다. |
(2) kubectl run으로 pod 생성
코드 블럭 |
---|
kubectl run test-nginx --image=nginx:1.19 |
정보 |
---|
또한 dry-run 옵션과 -o옵션을 이용하여 yaml파일을 간단하게 생성 할 수 도 있습니다 kubectl create deploy nginx --image=nginx --dry-run -o yaml > nginx-deploy.yaml |
(3) yaml 형식으로 pod 생성
5/00-nginx-pod.yaml
코드 블럭 |
---|
apiVersion: v1
kind: Pod
metadata:
name: test-nginx
spec:
containers:
- name: test-nginx
image: nginx:1.19
ports:
- containerPort: 80 |
코드 블럭 |
---|
# yaml 파일 적용
kubectl apply -f [yaml file] |
value | description |
---|---|
apiVersion | 오브젝트를 생성하기 위해 사용할 쿠버네티스 API 버전을 명세합니다. https://kubernetes.io/ko/docs/concepts/overview/kubernetes-api/ |
kind | 어떤 종류의 오브젝트를 생성하고자 하는지 명세합니다. ex) pod, services, replicaset ... |
metadata | name, UID, namespace 등을 기본적인 정보를 포함합니다.
|
(4) pod 조회, 수정 및 삭제
코드 블럭 |
---|
# pod 조회
kubectl get pod -n [namespace]
=> namespace를 지정하지 않으면 default namespace에 있는 pod를 조회합니다.
# 모든 Namespace의 pod 조회
kubectl get pod -A
# pod 수정
kubectl edit pod [pod name]
# pod 삭제
kubectl delete pod [pod name]
kubectl delete -f [yaml 파일] |
(5) 운영중에 이미지 버전 바꾸기 (===> nginx:latest로 변경
)
코드 블럭 |
---|
[root@m-k8s 0907]# cat nginx.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-nginx2
spec:
containers:
- name: test-nginx2
image: nginx:1.19 ===> nginx:latest로 변경
ports:
- containerPort: 80
[root@m-k8s 0907]# kubectl edit pod/test-nginx2
pod/test-nginx2 edited
[root@m-k8s 0907]# kubectl describe pod/test-nginx2
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Created 18s (x2 over 64m) kubelet Created container test-nginx2
Normal Killing 18s kubelet Container test-nginx2 definition changed, will be restarted
Normal Pulled 18s kubelet Container image "nginx:latest" already present on machine
Normal Started 17s (x2 over 64m) kubelet Started container test-nginx2 |
(6) Pod 설정 변경
파드 설정 변경 시, 변경 불가 항목인 경우 백업파일 생성 → 백업파일로 생성 가능
Pod.metadata.name: test-nginx ==> test-nginx3
코드 블럭 |
---|
[root@m-k8s 0907]# kubectl edit pod test-nginx A copy of your changes has been stored to "/tmp/kubectl-edit-1281676954.yaml" error: At least one of apiVersion, kind and name was changed [root@m-k8s 0907]# kubectl get pods NAME READY STATUS RESTARTS AGE test-nginx 1/1 Running 0 11m test-nginx2 1/1 Running 0 10m [root@m-k8s 0907]# kubectl apply -f /tmp/kubectl-edit-1281676954.yaml pod/test-nginx3 created [root@m-k8s 0907]# kubectl get pods NAME READY STATUS RESTARTS AGE test-nginx 1/1 Running 0 79s nginx-rs-zr4fl 84m test-nginx2 1/1 Running 01 (18m ago) 83m test-nginx3 1/1 79s => replica로 생성된 3개의Running pod를 확인할 수0 있습니다. # pod 삭제 kubectl delete pod nginx-rs-hxd29 72m |
새로 yaml 파일을 만들어서 생성
코드 블럭 |
---|
[root@m-k8s 0907]# kubectl get pod NAMEtest-nginx2 -o yaml > test-nginx4.yaml [root@m-k8s 0907]# vi test-nginx4.yaml # name change from READYtest-nginx2 to STATUS RESTARTS AGE nginx-rs-nh7q4 1/1test-nginx4 [root@m-k8s 0907]# kubectl create -f test-nginx4.yaml pod/test-nginx4 created [root@m-k8s 0907]# kubectl get pods NAME RunningREADY 0STATUS RESTARTS 2m4sAGE nginx-rs-zbqlctest-nginx 1/1 Running 0 8s nginx-rs-zr4fl 165m test-nginx2 1/1 Running 01 (99m ago) 163m test-nginx3 1/1 2m4s => yaml 파일에 선언된Running 개수만큼 유지하기 위해0 한 개의 pod 새로 생성됩니다. |
2.2 Deployment
Deployment는 쿠버네티스가 어플리케이션의 인스턴스를 어떻게 생성하고 업데이트 해야하는지를 지시합니다.
Replica 개수변경을 통해 손쉬운 Pod 증설/축소 가능합니다.
Deployment는 파드가 구동될 때, 가장 리소스 사용량이 적은 쪽으로 여러 개의 파드를 구동시킬 수 있습니다.
...
|
...
|
...
|
...
|
...
|
...
153m |
...
test- |
...
nginx4 |
...
1/1 |
...
Running |
...
|
...
0 |
...
|
...
|
...
|
...
17s |
(7) Pod 정보 확인
코드 블럭 |
---|
# pod 정보 자세히 보기 |
...
kubectl |
...
get pod -o |
...
wide # pod 로그 |
...
확인 kubectl logs [pod name] # |
...
pod의 상세 정보 kubectl describe pod [pod name] |
...
|
...
# pod 정보를 yaml 파일 |
...
형식으로 출력 kubectl get pod [pod name] |
...
2.3 DaemonSet
모든 노드에 동일한 파드를 생성해야 할 필요가 있는 경우에 사용합니다.
쿠버네티스 클러스터에 Worker Node 증설 시, 자동으로 증설 된 Node에 Pod가 생성됩니다.
모니터링(데이터 수집) 등 경우에 사용합니다.
...
코드 블럭 |
---|
root@k8s-master01:~# kubectl -n kube-system get ds NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE calico-node 5 5 5 5 5 kubernetes.io/os=linux 25h kube-proxy 5 5 -o yaml |
(8) Pod 구성 설명서
apiVerion은 아래와 같이 확인 할 수 있습니다
정보 |
---|
yaml 파일은 아래 4가지의 형태를 가지며 해당 오브젝트내 값을 선언하여 사용 apiVersion : # kubectl api-versions 명령어로 사용가능한 apiversion을 확인 |
정보 |
---|
kubectl explain으로 하위 정보를 모두 확인할수 있다. root@cp-k8s:~/2024_k8s/edu/5# kubectl explain pod.metadata.name |
모든데이터는 key: value 형태로 정의 합니다 :(콜론)와 value 사이에는 꼭 띄어쓰기가 들어가야 합니다.
(9) kubectl 자동완성
정보 |
---|
bash-completion 를 이용하여 kubectl도 자동완성 기능을 사용 할 수 있습니다 [root@m-k8s 0907]# apt install bash-completion -y [root@m-k8s 0907]# kubectl ap <tab> 누르면 자동완성 |
정보 |
---|
통상적으로 kubernetes는 k로 alias 주어서 수행 [root@m-k8s 0907]# which k |
...
2. 워크로드 리소스
2.1 ReplicaSet
파드를 생성 및 복제하고 복제된 파드의 개수를 yaml 파일에서 선언된 개수 만큼 지속적으로 유지합니다.
5/01-replicaset.yaml
코드 블럭 |
---|
apiVersion: apps/v1 kind: ReplicaSet metadata: name: nginx-rs labels: app: nginx-rs tier: nginx-rs spec: # modify replicas according to your case replicas: 3 selector: matchLabels: tier: nginx-rs template: metadata: labels: 5 tier: nginx-rs 5spec: containers: 5 - name: nginx-rs kubernetes.io/os=linux 25h nodelocaldns 5 image: nginx |
yaml 파일에 선언된 대로 3개의 Pod가 실행되며, 하나의 Pod가 문제가 발생했을 경우 ReplicaSet은 문제가 생긴 파드를 지우고, 기존 것과 다른 IP와 Name을 가진 파드를 새롭게 구동시킵니다.
...
코드 블럭 |
---|
# kubectl get pod NAME 5 READY STATUS 5 RESTARTS AGE 5nginx-rs-hxd29 1/1 Running 0 5 79s nginx-rs-nh7q4 kubernetes.io/os=linux 22h |
2.4 Static Pod
모든 Node가 Kubernetes Cluster 내에서 정상적으로 동작하기 위해서는 노드 시작(부팅)과 동시에 실행되어야할 Pod가 존재하며, 이를 Static Pod라고 지칭합니다.
Static Pod는 노드의 Kubelet 데몬이 실행되면서 자동으로 기동됩니다.
/etc/kubernetes/manifest 경로에 yaml 파일이 존재합니다.
kube-apiserver, kube-controller-manager, kube-scheduler
3. 컨피그맵
Key-Value 쌍으로 기밀이 아닌 데이터를 저장하는 데 사용하는 API 오브젝트입니다.
컨테이너 이미지에서 환경 별 구성을 분리하여, 애플리케이션을 쉽게 이식할 수 있습니다.
개발/운영 환경의 컨테이너는 동일하게 구성하고, 컨피그맵 설정을 다르게 적용하여 서비스를 관리할 수 있습니다.
파드와 컨피그맵은 동일한 네임스페이스에 있어야 합니다.
3.1 컨피그맵 사용
(1) 컨피그맵을 생성합니다.
코드 블럭 |
---|
apiVersion: v1
kind: ConfigMap
metadata:
name: prod-account
namespace: default
data:
ID: prod-user
PASSWORD: prod-pass
LOG_LEVEL: info |
(2) 컨테이너에서 prod-account 컨피그맵의 LOG_LEVEL값을 가지고 오도록 설정합니다.
코드 블럭 |
---|
piVersion: apps/v1 kind: Deployment metadata: name: configmap-test labels: app: prod spec: replicas: 1 selector: matchLabels: app: prod template: metadata: labels: app: prod spec: containers: - name: testapp image: nginx:1.191/1 Running 0 79s nginx-rs-zr4fl 1/1 Running 0 79s => replica로 생성된 3개의 pod를 확인할 수 있습니다. # pod 삭제 kubectl delete pod nginx-rs-hxd29 # kubectl get pod NAME READY STATUS RESTARTS AGE nginx-rs-nh7q4 1/1 Running 0 2m4s nginx-rs-zbqlc 1/1 Running 0 8s nginx-rs-zr4fl 1/1 Running 0 ports: - containerPort: 80802m4s => yaml 파일에 선언된 개수만큼 유지하기 위해 한 개의 pod 새로 생성됩니다. # kubectl scale replicaset --replicas 2 nginx-rs # kubectl get pods NAME env: - name: LOG_LEVEL valueFrom: READY STATUS RESTARTS configMapKeyRef: AGE nginx-rs-2d9f6 name: prod-account 1/1 Running key: LOG_LEVEL |
(3) 설정이 제대로 되었는지 파드 안에서 확인합니다.
코드 블럭 |
---|
root@k8s-master01:~/kb# kubectl get pod NAME 0 2m23s nginx-rs-pk7ll READY STATUS RESTARTS AGE configmap-test-779ff45747-f4969 1/1 Running 0 80s root@k8s-master01:~/kb# kubectl exec2m23s -it configmap-test-779ff45747-f4969 -- bash root@configmap-test-779ff45747-f4969:/# env | grep LOG_LEVEL LOG_LEVEL=info |
4.시크릿릿
비밀번호, OAuth 토큰, ssh 키와 같은 민감한 정보를 저장하는 용도로 사용됩니다.
시크릿 생성 시 데이터는 base64로 인코딩되어 저장됩니다.
컨피그맵은 보안/암호화를 제공하지 않기 때문에, 저장하려는 데이터가 기밀인 경우, Secret을 사용하여 데이터를 비공개로 유지합니다.
시크릿은 ETCD에 암호화되지 않은 상태로 저장되기 때문에, API 접근 권한이 있는 모든 사용자는 시크릿을 조회/수정 할 수 있습니다.
TLS 인증서를 시크릿으로 저장하여 사용하는 경우도 많습니다.
secret 리소스의 type 필드로 타입을 명시 할 수 있습니다.
...
빌트인 타입
...
사용처
...
Opaque
...
임의의 사용자 정의 데이터
...
kubernetes.io/service-account-token
...
서비스 어카운트 토큰
...
kubernetes.io/dockercfg
...
직렬화 된(serialized) ~/.dockercfg
파일
...
kubernetes.io/dockerconfigjson
...
직렬화 된 ~/.docker/config.json
파일
...
kubernetes.io/basic-auth
...
기본 인증을 위한 자격 증명(credential)
...
kubernetes.io/ssh-auth
...
SSH를 위한 자격 증명
...
kubernetes.io/tls
...
TLS 클라이언트나 서버를 위한 데이터
...
bootstrap.kubernetes.io/token
...
부트스트랩 토큰 데이터
5.1 불투명(Opaque) 시크릿 사용
5.1.1 명령어로 시크릿 생성
코드 블럭 |
---|
root@k8s-master01:~/kb# cat prod-user.txt prod-user root@k8s-master01:~/kb# cat prod-pass.txt prod-pass root@k8s-master01:~/kb# kubectl create secret generic prod-user --from-file=./prod-user.txt --from-file=./prod-pass.txt secret/prod-user-secret created root@k8s-master01:~/kb# kubectl get secrets NAME # kubectl delete rs/nginx-rs |
2.2 Deployment
Deployment는 쿠버네티스가 어플리케이션의 인스턴스를 어떻게 생성하고 업데이트 해야하는지를 지시합니다.
Replica 개수변경을 통해 손쉬운 Pod 증설/축소 가능합니다.
Deployment는 파드가 구동될 때, 가장 리소스 사용량이 적은 쪽으로 여러 개의 파드를 구동시킬 수 있습니다.
5/02-deployment.yaml
코드 블럭 |
---|
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.19 ports: TYPE DATA AGE prod-user-secret Opaque 2 4s root@k8s-master01:~/kb# kubectl get secrets prod-user-secret -o yaml apiVersion: v1 data: prod-pass.txt: cHJvZC1wYXNzCg== prod-user.txt: cHJvZC11c2VyCg== kind: Secret metadata: creationTimestamp: "2023-03-13T02:35:54Z" name: prod-user-secret namespace: default resourceVersion: "1226226" uid: 41a2cb2d-97f2-41bc-824f-c0c2783ec678 type: Opaque *원래 값 확인방 root@k8s-master01:~/kb# echo cHJvZC11c2VyCg== | base64 --decode prod-user |
5.1.2 yaml 파일로 시크릿 생성
yaml 파일로 생성시 필요 값들을 base64로 인코딩된 값을 넣어야 합니다.
코드 블럭 |
---|
root@k8s-master01:~/kb# echo -n "prod-user" | base64
cHJvZC11c2Vy
root@k8s-master01:~/kb# echo -n "prod-pass" | base64
cHJvZC1wYXNz |
시크릿을 생성합니다.
코드 블럭 |
---|
apiVersion: v1
kind: Secret
metadata:
name: prod-user
type: Opaque
data:
username: cHJvZC11c2Vy
password: cHJvZC1wYXNz |
생성된 시크릿을 확인합니다.
코드 블럭 |
---|
root@k8s-master01:~/kb# kubectl apply -f prod-user-secret.yaml root@k8s-master01:~/kb# kubectl get secrets NAME containerPort: 80 |
2.3 DaemonSet
모든 노드에 동일한 파드를 생성해야 할 필요가 있는 경우에 사용합니다.
쿠버네티스 클러스터에 Worker Node 증설 시, 자동으로 증설 된 Node에 Pod가 생성됩니다.
모니터링(데이터 수집) 등 경우에 사용합니다.
...
코드 블럭 |
---|
root@k8s-master01:~# kubectl -n kube-system get ds NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE calico-node 5 5 5 5 5 kubernetes.io/os=linux 25h kube-proxy 5 5 5 TYPE5 DATA AGE prod-user Opaque5 2 5s root@k8s-master01:~/kb# kubectl get secrets prod-user -o yaml apiVersion: v1 data: password: cHJvZC1wYXNz username: cHJvZC11c2Vy kind: Secret metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"v1","data":{"password":"cHJvZC1wYXNz","username":"cHJvZC11c2Vy"},"kind":"Secret","metadata":{"annotations":{},"name":"prod-user","namespace":"default"},"type":"Opaque"} creationTimestamp: "2023-03-13T02:49:45Z" name: prod-user namespace: default resourceVersion: "1228228" uid: a5eff12c-2329-4697-92f7-f252a4f724ba type: Opaque |
5.1.3 시크릿 사용
코드 블럭 |
---|
apiVersion: apps/v1 kind: Deploymentkubernetes.io/os=linux 25h |
2.4 Static Pod
모든 Node가 Kubernetes Cluster 내에서 정상적으로 동작하기 위해서는 노드 시작(부팅)과 동시에 실행되어야할 Pod가 존재하며, 이를 Static Pod라고 지칭합니다.
Static Pod는 노드의 Kubelet 데몬이 실행되면서 자동으로 기동됩니다.
/etc/kubernetes/manifest 경로에 yaml 파일이 존재합니다.
kube-apiserver, kube-controller-manager, kube-scheduler
코드 블럭 |
---|
root@cp-k8s:~/2024_k8s/edu/5# ls -al /etc/kubernetes/manifests/
total 24
drwxrwxr-x 2 root root 4096 May 23 18:46 .
drwxrwxr-x 4 root root 4096 May 23 18:46 ..
-rw------- 1 root root 2394 May 23 18:46 etcd.yaml
-rw------- 1 root root 4032 May 23 18:46 kube-apiserver.yaml
-rw------- 1 root root 3543 May 23 18:46 kube-controller-manager.yaml
-rw-r--r-- 1 root root 0 Feb 14 20:32 .kubelet-keep
-rw------- 1 root root 1463 May 23 18:46 kube-scheduler.yaml
|
...
3. 컨피그맵
Key-Value 쌍으로 기밀이 아닌 데이터를 저장하는 데 사용하는 API 오브젝트입니다.
컨테이너 이미지에서 환경 별 구성을 분리하여, 애플리케이션을 쉽게 이식할 수 있습니다.
개발/운영 환경의 컨테이너는 동일하게 구성하고, 컨피그맵 설정을 다르게 적용하여 서비스를 관리할 수 있습니다.
파드와 컨피그맵은 동일한 네임스페이스에 있어야 합니다.
3.1 컨피그맵 사용
(1) 컨피그맵을 생성합니다.
5/03-configmap.yaml
코드 블럭 |
---|
apiVersion: v1 kind: ConfigMap metadata: name: secretappprod-account labelsnamespace: default data: appID: secretappprod-user spec: replicas: 1 selector: matchLabels: app: secretapp templatePASSWORD: prod-pass LOG_LEVEL: info |
코드 블럭 |
---|
# k apply -f 03-configmap.yaml |
(2) 컨테이너에서 prod-account 컨피그맵의 LOG_LEVEL값을 가지고 오도록 설정합니다.
5/04-cm-deployment.yaml
코드 블럭 |
---|
apiVersion: apps/v1 kind: Deployment metadata: name: configmap-test labels: metadataapp: prod spec: labelsreplicas: 1 selector: matchLabels: app: prod template: metadata: secretapp labels: app: prod spec: containers: - name: testapp image: nginx:1.19 ports: - containerPort: 8080 env: - name: SECRETLOG_USERNAMELEVEL valueFrom: secretKeyRefconfigMapKeyRef: name: prod-useraccount key: username LOG_LEVEL |
(3) 설정이 제대로 되었는지 파드 안에서 확인합니다.
코드 블럭 |
---|
root@k8s-master01:~/kb# kubectl get pod NAME - name: SECRET_PASSWORD valueFrom: READY STATUS secretKeyRef:RESTARTS AGE configmap-test-779ff45747-f4969 1/1 Running 0 name: prod-user 80s key: password |
...
root@k8s-master01:~/kb# kubectl exec -it |
...
configmap-test- |
...
779ff45747- |
...
f4969 -- bash |
...
root@configmap-test- |
...
779ff45747- |
...
f4969:/# env | grep |
...
2. Label & Selector
Label
Label은 Pod와 같은 객체에 연결된 키/값 쌍입니다.
리소스를 논리적인 그룹으로 나누거나, 식별의 편의를 위해 붙이는 이름표입니다.
Label은 생성 시 객체에 첨부할 수 있으며 나중에 언제든지 추가 및 수정할 수 있습니다.
Selector
특정 Label에 해당하는 객체를 식별하고 검색할 수 있습니다.
2.1 Node Label
...
코드 블럭 |
---|
# Node Label 확인
kubectl get nodes --show-labels
# Node Label 추가
kubectl label nodes k8s-worker01 svc=web |
2.2 Pod Selector
pod-label.yml
코드 블럭 |
---|
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
nodeSelector:
svc: web |
3. 쿠버네티스 볼륨
PV(PersistentVolume): PV는 관리자가 프로비저닝했거나 스토리지 클래스를 사용해 동적으로 프로비저닝한 클러스터의 스토리지입니다. PV는 볼륨과 같은 볼륨 플러그인이지만 PV를 사용하는 개별 Pod와 독립적인 수명 주기를 가집니다.
PVC(PersistentVolumeClaim): PVC는 사용자가 볼륨을 사용하기 위해 PV에 하는 스토리지 요청입니다. Pod와 유사하게 Pod는 노드 리소스를 소비하고, PVC는 PV 리소스를 소비합니다.
3.1 PV의 Lifecycle
...
3.1.1 Provisioning
PV를 생성하는 단계로 프로비저닝 방법에는 두 가지가 있습니다.
정적 프로비저닝
정적 프로비저닝은 클러스터 관리자가 미리 적정 용량의 PV를 만들어 두고 사용자의 요청이 있을 시 미리 만들어 둔 PV를 할당하는 방식입니다.
사용할 수 있는 스토리지 용량에 제한이 있을 때 유용합니다.
동적 프로비저닝
동적 프로비저닝은 사용자가 PVC를 거쳐서 PV를 요청했을 때 생성해 제공합니다.
클러스터에 사용자가 원하는 만큼의 스토리지 용량이 있다면, 원하는 용량만큼을 생성해서 사용할 수 있습니다.
3.1.2 Binding
바인딩은 프로비저닝으로 생성된 PV를 PVC와 연결하는 단계입니다. PVC에서 원하는 스토리지 용량과 접근방법을 명시해서 용청하면 거기에 맞는 PV가 할당됩니다. PV와 PVC의 매핑은 1대1 관계입니다.
3.1.3 Using
PVC는 Pod에 설정되고, Pod는 PVC를 볼륨으로 인식해서 사용합니다. 클러스터는 PVC를 확인하여 바인딩된 PV를 찾고 해당 볼륨을 Pod에서 사용할 수 있도록 해줍니다. 할당된 PVC는 파드를 유지하는 동안 계속 사용되며, 시스템에서 임의로 삭제할 수 없습니다.
3.1.4 Reclaiming
사용이 끝난 PVC는 삭제되고, PV를 초기화(reclaim)하는 과정을 거칩니다. PV는 기존에 사용했던 PVC가 아니더라도 다른 PVC로 재활용이 가능합니다.
PV 초기화 정책
Retain: PV의 데이터를 그대로 보존합니다.
Recycle: 재사용하게 될 경우 기존의 PV 데이터들을 모두 삭제 후 재사용합니다.
Delete: 사용이 종료되면 해당 볼륨을 삭제합니다.
3.2 PV 생성
코드 블럭 |
---|
apiVersion: v1 kind: PersistentVolume metadata: name: test-pv labels: name: test-pv spec: capacity: storage: 1Gi accessModes: - ReadWriteMany hostPath: path: "/test/volume" # Value - capacity: 사용할 용량을 설정합니다. - accessModes:특정 접근 모드를 선택합니다. - hostPath: 노드에 저장되는 디렉토리를 설정합니다. # 적용하기 kubectl apply -f test-pv.yaml # PV 조회 kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE test-pv 1Gi RWXLOG_LEVEL LOG_LEVEL=info |
...
4.시크릿
비밀번호, OAuth 토큰, ssh 키와 같은 민감한 정보를 저장하는 용도로 사용됩니다.
시크릿 생성 시 데이터는 base64로 인코딩되어 저장됩니다.
컨피그맵은 보안/암호화를 제공하지 않기 때문에, 저장하려는 데이터가 기밀인 경우, Secret을 사용하여 데이터를 비공개로 유지합니다.
시크릿은 ETCD에 암호화되지 않은 상태로 저장되기 때문에, API 접근 권한이 있는 모든 사용자는 시크릿을 조회/수정 할 수 있습니다.
TLS 인증서를 시크릿으로 저장하여 사용하는 경우도 많습니다.
secret 리소스의 type 필드로 타입을 명시 할 수 있습니다.
빌트인 타입 | 사용처 |
---|---|
| 임의의 사용자 정의 데이터 |
| 서비스 어카운트 토큰 |
| 직렬화 된(serialized) |
| 직렬화 된 |
| 기본 인증을 위한 자격 증명(credential) |
| SSH를 위한 자격 증명 |
| TLS 클라이언트나 서버를 위한 데이터 |
| 부트스트랩 토큰 데이터 |
4.1 불투명(Opaque) 시크릿 사용
(1) 명령어로 시크릿 생성
코드 블럭 |
---|
root@cp-k8s:~/2024_k8s/edu/5# echo "prod-user" > prod-user.txt
root@cp-k8s:~/2024_k8s/edu/5# echo "prod-pass" > prod-pass.txt
|
코드 블럭 |
---|
root@k8s-master01:~/kb# cat prod-user.txt prod-user root@k8s-master01:~/kb# cat prod-pass.txt prod-pass root@k8s-master01:~/kb# kubectl create secret generic prod-user-secret --from-file=./prod-user.txt --from-file=./prod-pass.txt secret/prod-user-secret created root@k8s-master01:~/kb# kubectl get secrets NAME Retain TYPE DATA AvailableAGE prod-user-secret Opaque 2 4s root@k8s-master01:~/kb# kubectl get secrets prod-user-secret -o yaml apiVersion: v1 data: prod-pass.txt: cHJvZC1wYXNzCg== 15s |
3.3 PVC 생성
코드 블럭 |
---|
apiVersion: v1prod-user.txt: cHJvZC11c2VyCg== kind: PersistentVolumeClaimSecret metadata: namecreationTimestamp: test-pvc spec:"2023-03-13T02:35:54Z" accessModesname: - ReadWriteMany resources: prod-user-secret namespace: default requestsresourceVersion: "1226226" storage: 1Gi kubectl apply -f test-pvc.yaml # PV, PVC 조회 kubectl get pv,pvc NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE persistentvolume/test-pv 1Gi RWX Retain Bound default/test-pvc 2m22s NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE persistentvolumeclaim/test-pvc Bound test-pv 1Gi RWX 18s => PV와 PVC가 연결되어 PV가 Bound 상태로 변경된 것을 확인할 수 있습니다. |
3.4 PVC를 사용할 Pod 생성
코드 블럭 |
---|
apiVersion: v1 kind: Pod metadata: name: test-nginx2 spec: containers: - name: test-nginx2 image: nginx:1.19 ports: - containerPort: 80 volumeMounts: - mountPath: "/test/volume"uid: 41a2cb2d-97f2-41bc-824f-c0c2783ec678 type: Opaque *원래 값 확인방 root@k8s-master01:~/kb# echo cHJvZC11c2VyCg== | base64 --decode prod-user root@k8s-master01:~/kb# kubectl delete secret/prod-user-secret secret "prod-user" deleted |
(2) yaml 파일로 시크릿 생성
yaml 파일로 생성시 필요 값들을 base64로 인코딩된 값을 넣어야 합니다.
코드 블럭 |
---|
root@k8s-master01:~/kb# echo -n "prod-user" | base64
cHJvZC11c2Vy
root@k8s-master01:~/kb# echo -n "prod-pass" | base64
cHJvZC1wYXNz |
시크릿을 생성합니다.
5/05-secret.yaml
코드 블럭 |
---|
apiVersion: v1
kind: Secret
metadata:
name: prod-user
type: Opaque
data:
username: cHJvZC11c2Vy
password: cHJvZC1wYXNz |
생성된 시크릿을 확인합니다.
코드 블럭 |
---|
root@k8s-master01:~/kb# kubectl apply -f 05-secret.yaml
root@k8s-master01:~/kb# kubectl get secrets
NAME TYPE DATA AGE
prod-user Opaque 2 5s
root@k8s-master01:~/kb# kubectl get secrets prod-user -o yaml
apiVersion: v1
data:
password: cHJvZC1wYXNz
username: cHJvZC11c2Vy
kind: Secret
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","data":{"password":"cHJvZC1wYXNz","username":"cHJvZC11c2Vy"},"kind":"Secret","metadata":{"annotations":{},"name":"prod-user","namespace":"default"},"type":"Opaque"}
creationTimestamp: "2023-03-13T02:49:45Z"
name: prod-user
namespace: default
resourceVersion: "1228228"
uid: a5eff12c-2329-4697-92f7-f252a4f724ba
type: Opaque
|
(3) 시크릿 사용
5/06-secret-deployment.yaml
코드 블럭 |
---|
apiVersion: apps/v1 kind: Deployment metadata: name: secretapp labels: app: secretapp spec: replicas: 1 selector: matchLabels: app: secretapp template: metadata: labels: app: secretapp spec: containers: - name: testapp image: nginx:1.19 ports: - namecontainerPort: test-pv8080 volumes: - nameenv: test-pv persistentVolumeClaim: - claimNamename: test-pvcSECRET_USERNAME # 옵션 - volumeMounts.mountPath: 볼륨 마운트할 컨테이너 안의 경로를 작성합니다. - volumes:.persistentVolumeClaim: 컨테이너에서 사용할 PV의 이름을 가져오고, PV와 연결되어 있으며 요청을 보낼 PVC를 지정합니다. # 적용하기 kubectl apply -f test-nginx2.yaml # 확인해보기 # 외부에서 확인 # kubectl describe pod test-nginx2 | grep -A1 MountsvalueFrom: secretKeyRef: name: prod-user Mounts: /test/volume from test-pv (rw) # 컨테이너 내부에서 확인 kubectl exec -it test-nginx2 -- bash root@test-nginx2:/# df -Th | grep volume /dev/vda1 xfskey: username - name: SECRET_PASSWORD valueFrom: 50G 3.7G secretKeyRef: 47G 8% /test/volume => 지정한 경로에 볼륨이 마운트된 것을 확인할 수 있습니다. # 컨테이너 내부에서 test용 파일 생성 root@test-nginx2:/# touch /test/volume/test.txt # PV 생성 시 설정한 노드의 경로에서도 확인이 가능합니다. [root@worker-node ~]# ls -al /test/volume/ total 0 drwxr-xr-x 2 root root 22 Mar 10 06:22 . drwxr-xr-x 3 root root 20 Mar 10 06:18 .. -rw-r--r-- 1 root root 0 Mar 10 06:22 test.txtname: prod-user key: password |
코드 블럭 |
---|
kubectl apply -f 06-secret-deployment.yaml |
파드 안에서 시크릿 데이터를 확인합니다.
코드 블럭 |
---|
root@k8s-master01:~/kb# kubectl exec -it secretapp-69d4797f86-7r95g -- bash
root@secretapp-69d4797f86-7r95g:/# env | grep SECRET
SECRET_USERNAME=prod-user
SECRET_PASSWORD=prod-pass |
실습파일을 정리합니다.
코드 블럭 |
---|
root@cp-k8s:~/2024_k8s/edu/5# kubectl delete deploy/configmap-test
deployment.apps "configmap-test" deleted
root@cp-k8s:~/2024_k8s/edu/5# kubectl delete deploy/secretapp
deployment.apps "secretapp" deleted
root@cp-k8s:~/2024_k8s/edu/6# kubectl delete deploy/nginx-deployment |