삭제 모음 zip
root@master:~# kubectl delete pod --all
- pod 전부 삭제

root@master:~# kubectl delete pod --all -n kube-system
- 모든 파드를 삭제
root@master:~# kubectl run test1 --image=public.ecr.aws/docker/library/nginx:alpine
pod/test1 created
root@master:~# kubectl run test2 --image=public.ecr.aws/docker/library/nginx:alpine
pod/test2 created
root@master:~# kubectl get pod -o wide



둘 다 잘 연결되는 걸 확인할 수 있음
만약에 ip생성이 안되거나 연결이 안 된다면 최악의 상황.
1.kubectl delete -f kube-flannel.yml로 flannel CNI 삭제
2. 모든 노드에서 kubeadm reset으로 클러스터 리셋
3. 재부팅을 해서 CNI 관련된 호스트의 설정값들을 초기화
4.kubeadm init 및 kubeadm join으로 클러스터 재구성.
label - 리소스를 특정하기 위한 꼬리표
- 만약 내가 똑같은 pod를 3개 띄웠다면, pod들의 이름은 다르기 때문에 대상을 한꺼번에 특정하기 어렵다. 하지만 똑같은 label을 달아준다면 해당 레이블로 3개의 파드를 동시에 특정 가능함. 쿠버네티스에서는 보통 label을 통해 리소스를 식별하는 편
root@master:~# vi test-pod.yml

apiVersion: v1
kind: Pod
metadata:
name: test-pod
labels:
app: my-web
spec:
containers:
- image: public.ecr.aws/docker/library/nginx:alpine
name: test-pod
kubectl apply -f test-pod.yml

- 컨테이너 이름을 변경해 주기
kubectl apply -f test-pod.yml

kubectl describe pod test-pod

root@master:~/mani# kubectl delete pod test-pod
ReplicaSet(레플리카셋)
- 파드의 복제본. pod보다 한 단계 상위개념.
- 버전관리에 반드시 필요한 리소스.
- 스케일링이 가능함.
- selector를 통해 복제할 pod의 label을 선택할 수 있음.
root@master:~# mkdir mani
root@master:~# cd mani
root@master:~/mani# pwd
/root/mani
root@master:~/mani# vi rep.yml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: test-rep
spec:
replicas: 2 #2개 복제
selector:
matchLabels:
app: my-web #여기 있는걸 찾아서1
template: #template는 pod의 명세
metadata:
labels:
app: my-web #여기에 복제2
spec:
containers:
- image: public.ecr.aws/docker/library/nginx:alpine
name: test-pod-con


- test-pod pod를 삭제하지 않은 상태에서 실행하면 이름이 중복돼서 랜덤 한 문자가 제대로 부여받지 못함.
- 그래서 test-pod를 삭제하고 다시 실행하면 두 개의 pod가 잘 생성된 걸 확인할 수 있음


실습 1) label이 app: my-httpd이고 httpd:latest라는 이미지로 구성된 pod를 2개 띄우는 레플리카셋의 매니페스트 파일(rep-httpd.yml)을 만들어보세요.
root@master:~/mani# cp rep.yml rep-httpd.yml
root@master:~/mani# vi rep-httpd.yml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: httpd-rep
spec:
replicas: 2
selector:
matchLabels:
app: my-httpd
template:
metadata:
labels:
app: my-httpd
spec:
containers:
- image: public.ecr.aws/docker/library/httpd:latest
name: test-pod-con
root@master:~/mani# kubectl apply -f rep-httpd.yml

- 한 번 특정 파일을 지워보자

- 내가 지운 pod는 삭제가 되지만, 새로운 pod가 바로 생성됨
- Desired state가 app: my-httpd라는 라벨을 달고 잇는 파드가 2개이기 때문에 내가 파드를 한 개 삭제하는 순간, status는 replicas=1이 되기 때문에 즉시 하나 더 바로 생성됨
root@master:~/mani# kubectl delete -f rep.yml
root@master:~/mani# kubectl delete -f rep-http.yml
# 두 레플리카셋을 삭제하면
root@master:~/mani# kubectl get rs, pod
- 나머지 다 삭제해 주고 다음 실습으로 ㄱㄱ
kubectl 명령 자동완성
apt-get install -y bash-completion
echo 'source <(kubectl completion bash)' >>~/.bashrc
echo 'source <(kubeadm completion bash)' >>~/.bashrc
kubectl completion bash >/etc/bash_completion.d/kubectl
#자동완성
ln -s /usr/bin/kubectl /usr/local/bin/k
# kubectl 대신 k로 단축명령.
# 재부팅해야 됨 그래야 반영되는 걸 확인할 수 있음
root@master:~/mani# kubectl apply -f rep.yml
root@master:~# cd mani
root@master:~/mani# kubectl get pod test-rep-d -> 탭을 치면 자동으로 밑에 파일이 생성된 걸 확인할 수 있음
test-rep-dbwvs test-rep-dkdtl

실습 2)
k8s is easy라는 내용의 index.html 파일을 배포하는 아주 간단한 public.ecr.aws/docker/library/nginx:alpine 기반 app을 컨테이너 이미지로 만들어서 도커허브에 push 한 다음 쿠버네티스 로컬클러스터에 pod 3개로 배포해 보세요. 도커허브가 안되면 ECR에 해보세요!
1. k8s is easy라는 내용의 index.html 파일
2. public.ecr.aws/docker/library/nginx:alpine 기반 app을 컨테이너 이미지
3. 쿠버네티스 로컬클러스터에 pod 3개로 배포
1. 컨테이너이미지 생성을 위한 Dockerfile 작성
echo k8s is easy > index.html
vi Dockerfile
FROM public.ecr.aws/docker/library/nginx:alpine
WORKDIR /usr/share/nginx/html
COPY index.html index.html
2. 로컬에서 이미지 build & push

먼저 도커 허브에 로그인하기
root@master:~/mani# docker login -u choyunji
패스워드 입력해 주고
docker build -t <도커허브계정명>/easy:1 .
docker push <도커허브계정명>/easy:1

3. 쿠버네티스에서 push 한 이미지로 매니페스트 작성 및 apply
cp rep-http.yml rep-easy.yml
vi rep-easy.yml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: easy-rep
spec:
replicas: 3
selector:
matchLabels:
web: easy-k8s
template:
metadata:
labels:
web: easy-k8s
spec:
containers:
- image: oolralra/easy:1
name: easy-con
root@master:~/mani# kubectl apply -f rep-easy.yml

Deployment
- 디폴로이먼는 pod을 원하는 수만큼 유지하고, 업데이트와 롤백까지 자동으로 처리하는 컨트롤러
cp rep-http.yml dep-http.yml
vi dep-http.yml
apiVersion: apps/v1
kind: Deployment #수정
metadata:
name: my-dep
spec:
replicas: 2
selector:
matchLabels:
app: my-httpd
template:
metadata:
labels:
app: my-httpd
spec:
containers:
- image: public.ecr.aws/docker/library/httpd:latest
name: httpd-pod-con
root@master:~/mani# kubectl apply -f dep-http.yml
하면 잘 생성된 걸 확인할 수 있음

root@master:~/mani# kubectl get deploy
- 클러스터 Deployment 리소스 목록을 조회하는 명령어
- Pod를 배포하고 관리하는 상위 리소스

root@master:~/mani# kubectl get rs
- 쿠버네티스에서 리플리카셋(ReplicaSet) 리소스를 조회하는 명령어
- pod의 개수를 유지해 주는 컨트롤러

namespace
- pod 같은 리소스들을 공간적으로 분리/격리하기 위한 리소스.
- 비슷한 성질, 분류를 갖는 리소스들을 공간적으로 분리/ 격리하기 위한 리소스
- 네임스페이스별로 접근 제어도 가능


root@master:~/mani# kubectl create ns test-ns
namespace/test-ns created
- test-ns라는 이름을 갖는 네임스페이스 생성
root@master:~/mani# kubectl delete deploy --all
root@master:~/mani# kubectl delete rs --all
root@master:~/mani# kubectl delete pod --all
- 기존 리소스 삭제
root@master:~/mani# kubectl apply -f dep-http.yml -n test-ns
root@master:~/mani# kubectl get pod
root@master:~/mani# kubectl get pod -n default
- 우리가 네임스페이스 명시하지 않으면 기본 네임스페이스(default)에 명령어 들어감
root@master:~/mani# kubectl get pod -n test-ns

kubectl get pod --all-namespaces
# 모든 네임스페이스의 리소스를 다 보고 싶을 땐
kubectl delete ns test-ns
# 네임스페이스를 삭제 시, 내부의 모든 리소스가 전부 삭제된다.
vi test-ns.yml
# 이번에는 매니페스트로 ns를 정의
apiVersion: v1
kind: Namespace
metadata:
name: test-ns
kubectl apply -f test-ns.yml

실습 3)
네임스페이스: lunch
디플로이먼트: lunch-dep
를 생성하되, 하나의 yml파일로 매니페스트를 작성해야 하고, 디플로이먼트는 lunch라는 네임스페이스에 존재해야 합니다. 이미지는 public.ecr.aws/docker/library/nginx:alpine 로 하시고 레플리카 2개로 하세요.
따로 'kubectl create 같은 명령을 쓰진 마세요!!'
root@master:~/mani# vi lunch-dep.yaml
apiVersion: v1
kind: Namespace
metadata:
name: lunch
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: lunch-dep
namespace: lunch
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: public.ecr.aws/docker/library/nginx:alpine
name: lunch-con
root@master:~/mani# kubectl apply -f lunch-dep.yaml


잘 되는 걸 확인할 수 있음
✅ 여기서 질문!
디플로이먼트 먼저 정의하고 네임스페이스 정의해도 괜찮을까?
답은 아니! Deployment를 먼저 정의하고, 그 아래 네임스페이스를 정의하면 에러가 발생함!
Error from server (NotFound): namespaces "lunch" not found
Deployment를 만들려고 하는데, 아직 lunch 네임스페이스가 없기 때문임
그래서 네임스페이스 먼저 만들어주고 디폴로이먼트를 정의해 줘야 됨
Service
- 작은 로드밸런서, 주로 pod 같은 리소스들을 대표.(부하 분산 + 접속 지점)
- pod들을 주로 외부에 서비스하는 리소스
- 쿠버네티스에서 Pod은 자동으로 IP가 바뀌기 때문에, 직접 접근하면 매우 불편함
그래서 쿠버네티스는 service라는 고정된 접근 경로를 만들어줌
- 서비스를 생성 시 하나의 접속지점이 생성
- 이 서비스를 통해 모든 노드에 존재하는 파드에 트래픽을 인가할 수 있음
- 인가하는 기준은 labels를 통해 해당 파트를 특정하면 됨
- 서비스에는 다양한 종류(type)가 존재함
root@master:~/mani# kubectl delete -f lunch-dep.yaml
namespace "lunch" deleted
deployment.apps "lunch-dep" deleted
root@master:~/mani# vi dep.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-dep
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: my-con
image: public.ecr.aws/docker/library/nginx:alpine
kubectl apply -f dep.yml
# apply 하면 그림과 같은 deployment가 생성.
ClusterIP = 클러스터 내에서만 유효한 Service IP를 생성해 주는 타입 <내부만 가능>
기본값 => type: ClusterIP 생략 가능
=> 클러스터 외부에서는 찾아갈 수 없는 서비스. 내부 테스트 용도로만 서비스를 만들고 싶을 때 사용
vi dep-svc.yml
apiVersion: v1
kind: Service
metadata:
name: svc-nginx
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80

kubectl apply -f dep-svc.yml

- svc를 좀 더 자세히 보자


NodePort
1. 클러스터의 노드포트(nodePort, 30000-32767)로 사용자가 접근
2. 해당 노드포트에 매칭된 서비스의 포트(port)로 연결
3. 서비스는 selector를 통해 매칭된 파드의 포트(targetPort)로 접속
NodePort는 쿠버네티스 노드의 포트를 열어서 클러스터 외부에서 접근 가능하게 만드는 Service타입
✅ 흐름 정리
[브라우저] --> http://<노드 IP>:32000
↓
[NodePort Service]
↓
[nginx Pod:80]
vi dep-svc.yml의 타입을 NodePort로 변경
apiVersion: v1
kind: Service
metadata:
name: svc-nginx
spec:
selector:
app: nginx
type: NodePort # ClusterIP가 아닌 NodePort 타입,수정
ports: #3개의 포트를 명시
- nodePort: 30001 #추가
port: 80
targetPort: 80
# dep-svc.yml의 타입을 NodePort로 변경.
root@master:~/mani# kubectl apply -f dep-svc.yml
service/svc-nginx configured
- 기존 서비스가 변경
root@master:~/mani# kubectl get svc svc-nginx


- 어느 노드의 주소든 괜찮음
- 외부에서 노드로 통신만 된다면, 노드포트를 통해 pod로 접속 가능함
root@master:~/mani# kubectl describe svc svc-nginx

3개의 포트( nodePort, port, targetPort )가 각각 어떤 대상인지 구분할 수 있어야 함.
실습 4)
하나의 yml 파일을 통해
서비스이름: svc-ipnginx
서비스포트: 80
노드포트: 32000
label = app: myipnginx
이미지: oolralra/ipnginx
파드수: 3개
네임스페이스: ip-ns
위와 같이 구성해 보자
root@master:~/mani# vi svc-ipnginx.yml
# 네임스페이스 정의
# 네임스페이스: ip-ns
apiVersion: v1
kind: Namespace
metadata:
name: ip-ns
---
# 디플로이먼트 정의
#label = app: myipnginx
#이미지: oolralra/ipnginx
#파드수: 3개
apiVersion: apps/v1
kind: Deployment
metadata:
name: ipnginx-deploy
namespace: ip-ns
spec:
replicas: 3
selector:
matchLabels:
app: myipnginx
template:
metadata:
labels:
app: myipnginx
spec:
containers:
- name: ipnginx
image: oolralra/ipnginx
ports:
- containerPort: 80
---
# 서비스 정의
#서비스이름: svc-ipnginx
#서비스포트: 80
#노드포트: 32000
apiVersion: v1
kind: Service
metadata:
name: svc-ipnginx
namespace: ip-ns
spec:
type: NodePort
selector:
app: myipnginx
ports:
- port: 80
targetPort: 80
nodePort: 32000
✅ kubectl get pod에 왜 안 보이지?
-> 이걸 해결하려면 네임스페이스 개념을 정확히 이해해야 됨
-> 이 명령은 네임스페이스가 default안에 있는 pod만 보여줌
즉, 따로 설정하지 않으면 default 모음 안에 다 포함하게 됨
kubectl get pods -n ip-ns를 입력하면 잘 확인할 수 있음
kubectl get svc -n ip-ns

오류 /해결 방안 - oolralra/ipnginx파일을 가져와야 되는데 가져오지 못하는 상태임

파일이 잘 안 가져와지는 걸 확인할 수 있음
root@master:~/mani# kubectl get pod -n ip-ns
NAME READY STATUS RESTARTS AGE
ipnginx-deploy-bcb7b85-jcpgg 0/1 ImagePullBackOff 0 28m
ipnginx-deploy-bcb7b85-kqj5v 0/1 ImagePullBackOff 0 28m
ipnginx-deploy-bcb7b85-vkkdk 0/1 ImagePullBackOff 0 28m
- 이걸 보면 yaml파일이 정확히 작동해서 pod 3개가 생성되었음을 보여주지만 ImagePullBackOff 이기 때문에 정상적으로 실행이 안 되는 걸 확인할 수 있음
✅ 현재 상황 분석
STATUS: ImagePullBackOff
이 상태는 다음과 같은 의미야: 쿠버네티스가 Pod을 만들려고 했지만,
컨테이너 이미지를 다운로드(pull)할 수 없어서 "잠시 멈춤" 상태로 바뀐 거야.
즉, image: oolralra/ipnginx 를 다운로드할 수 없어서 생긴 문제야.
이럴 때는 테더링을 해주면 됨
테더링이란?
- 핸드폰 인터넷을 노트북, 태스크탑, 가상머신에 공유해 주는 기능
- 이럴 때 핸드폰 테더링(hotspot)을 사용해 인터넷 연결 가능

오류/ 해결 방안 - 3개 중 status가 하나만 running 된 상태임

3개가 다 running 된 상태여야 하는데 하나만 running된 상태임 지우고 다시 생성해 주겠음
root@master:~/mani# kubectl delete -f svc-ipnginx.yml
root@master:~/mani# kubectl apply -f svc-ipnginx.yml
root@master:~/mani# kubectl get pod -n ip-ns

- 계속 입력해주다 보면 결국 3개다 running 한 상태가 됨

자율과제1)
서비스에서 selector를 통해 pod의 label을 선택할때, 해당 label이 존재하지 않는경우의 svc를 describe해서 확인해보세요. 정상적인 svc와 deployment를 먼저 만들고 어떤 변경점이 있는지 비교해보세요.
hw1.yml을 열어서 Service의 라벨을 수정.


# app: myipnginx1이라는 라벨을 달고 있는 pod들이 없기때문에 svc의 describe상의 endpoints에도 뜨지 않
자율과제2)
61.254.18.30:5000 에는 박찬민의 http 통신을 하는 사설 레지스트리가 존재합니다. http://61.254.18.30:5001 통해 어떤 이미지레포가 있는지도 확인가능합니다! 이 사설 레지스트리에 본인이름으로 된 이미지를 push 하고, 본인의 클러스터에 해당 이미지를 배포해보세요
docker로 해당 레지스트리에 push를 하기 위해 docker 설정 변경
vi /etc/docker/daemon.json
{
"insecure-registries": ["61.254.18.30:5000"]
}
systemctl restart docker
root@master:~/mani# docker pull public.ecr.aws/docker/library/nginx:alpine
# push할 이미지를 아무거나
docker tag public.ecr.aws/docker/library/nginx:alpine 61.254.18.30:5000/pcm:1
# push를 하기위해 태그변경.
docker push 61.254.18.30:5000/pcm:1
docker image rm 61.254.18.30:5000/pcm:1
# 푸쉬후 로컬에 있는 이미지는 삭제
docker run -dp 5959:80 --name test 61.254.18.30:5000/pcm:1
# 이미지 유효한지 테스트.

# 테스트 목적: push된 이미지에는 문제가 없다라는걸 보장하고 싶음.
이미지를 땡겨오는 주체가 누구인지? 어디서 땡겨오는지?
1. docker라는 런타임이냐? 아니면 containerd라는 런타임이냐? => containerd
우리가 매니페스트 파일을 apply 하면, api-server를 통해 노드의 kubelet이 pod를 생성하는데 그때 kubelet이 containerd라는 컨테이너런타음으로 pod에 들어갈 컨테이너를 생성. 따라서 containerd라는 컨테이너런타임이 레지스트리에 접근할 수 있어야 함
docker에서는 daemon.json에서 구성했듯
containerd 에서는 /etc/containerd/config.toml 에 내용을 추가해야함
2. 어디서 땡겨 오냐?
- 각 워커노드기 때문에 containerd설정을 워커노드에서 해줘야됨
vi free.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-dep
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: my-con
image: 61.254.18.30:5000/pcm:1
# push된 이미지로 Deployment 매니페스트 작성.
kubectl apply -f free.yml


cat <<EOF >> /etc/containerd/config.toml
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."61.254.18.30:5000"]
endpoint = ["http://61.254.18.30:5000"]
[plugins."io.containerd.grpc.v1.cri".registry.configs."61.254.18.30:5000".tls]
insecure_skip_verify = true
EOF
systemctl restart containerd
kubectl delete -f free.yml
kubectl apply -f free.yml

'AWS Cloud School 8기 > 쿠버네티스' 카테고리의 다른 글
[쿠버네티스] 헬름(Helm) (0) | 2025.04.23 |
---|---|
[쿠버네티스] 컨테이너의 헬스체크/ livenessProbe/ readinessProbe/ StatefulSet(리소스)/ DaemonSet(리소스) (4) | 2025.04.17 |
[쿠버네티스] PV(Persistent Volume)/ AccessMode/ StorageClass/ ConfigMap/ Secret (2) | 2025.04.16 |
[쿠버네티스] LoadBalancer/ Ingress/ Monolithic/ Micro-service (3) | 2025.04.15 |
[쿠버네티스] Kubernetes/ 클러스터/ CRI/ 매니패스트 (2) | 2025.04.10 |