Kubernetes 설치 및 실습 on VMware
도커 스웜 실습 했던 VM환경에서 그대로 실습한다.
그 전에 사용하던 Docker은 종료해준다.
#systemctl status docker
#systemctl stop docker
#systemctl disable docker
마스터, 워커 노드 공동설정
# 시스템 패키지를 최신으로 업데이트하여 보안 패치 및 커널/라이브러리 버그 수정 적용
dnf update -y
# 시스템 타임존을 한국 표준시(Asia/Seoul, UTC+9)로 설정 → 로그 시간 동기화 목적
timedatectl set-timezone Asia/Seoul
# firewalld 비활성화 (즉시 중지 + 부팅 시 자동 실행 해제)
# → Pod 간 통신, kubelet, kube-proxy 등이 방화벽에 막히는 걸 방지
systemctl disable --now firewalld
# SELinux를 일시적으로 비활성화 (즉시 적용)
# → Kubernetes에서 일부 컨테이너 접근 권한 문제 방지 (init container 등)
setenforce 0
# 스왑 비활성화 (Kubernetes는 스왑 활성화된 시스템에서 동작 보장 안 함)
# Kubernetes는 노드의 실제 메모리 사용량을 기반으로 스케줄링한다. 스웝을 쓰면 이상해짐
swapoff -a
# fstab에서 스왑 항목 주석 처리 → 재부팅 후에도 스왑 자동 마운트 안 되게 설정
sed -i '/ swap / s/^/#/' /etc/fstab
# SELinux 영구 비활성화 설정 (재부팅 후에도 적용되도록)
sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config
# containerd가 필요로 하는 커널 모듈을 부팅 시 자동 로드하도록 설정
# - overlay: 컨테이너용 파일시스템 오버레이 지원
# - br_netfilter: iptables에서 브릿지 네트워크 통과 패킷 처리 가능하게 함
tee /etc/modules-load.d/containerd.conf <<EOF
overlay
br_netfilter
EOF
# overlay 및 br_netfilter 커널 모듈을 즉시 로드
# - overlay: containerd가 사용하는 파일 시스템 오버레이
# 수동으로 하는 이유 어떤 커널은 overlay가 기본 로드되지 않음
# containerd가 설치될 때 overlay 모듈이 없다고 에러 발생할 수 있음
# - br_netfilter: 브릿지 네트워크에서 iptables 필터링을 가능하게 함
# 쿠버네티스에서 Pod 간 통신, Service IP 할당 등을 iptables 사용 브릿지 네트워크가 없으면 안됨
modprobe overlay
modprobe br_netfilter
# Kubernetes 네트워크 요구사항 충족을 위한 커널 파라미터 설정
# - bridge-nf-* 설정은 브릿지를 통한 네트워크 트래픽이 iptables를 통과하도록 함
# - ip_forward: 패킷 포워딩 가능하도록 설정 (Pod 간 통신 필수)
tee /etc/sysctl.d/kubernetes.conf <https://download.docker.com/linux/centos/docker-ce.repo>
# 전체 시스템 패키지 업데이트 후 containerd 설치
dnf update -y && dnf install -y containerd.io
# containerd 설정 디렉토리 생성
mkdir -p /etc/containerd
# containerd의 기본 설정 파일을 생성 (표준 설정 템플릿)
containerd config default | sudo tee /etc/containerd/config.toml >/dev/null 2>&1
# containerd가 systemd cgroup 드라이버를 사용하도록 수정
# → kubelet과 cgroup 드라이버를 일치시키기 위해 반드시 필요
sed -i 's/SystemdCgroup \\= false/SystemdCgroup \\= true/g' /etc/containerd/config.toml
# containerd 데몬 재시작 및 부팅 시 자동 시작 설정
systemctl restart containerd
systemctl enable --now containerd
# Kubernetes 공식 저장소를 yum 리포지터리에 추가 (v1.31 기준)
# - GPG 키 포함
# - 기본 yum 동작에서 kubelet, kubeadm 등 제외하지 않도록 설정
cat <https://pkgs.k8s.io/core:/stable:/v1.31/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.31/rpm/repodata/repomd.xml.key
exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni
EOF
# Kubernetes 핵심 구성요소 설치
# --disableexcludes 옵션을 통해 위에서 설정한 exclude 무시
dnf install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
# kubelet 데몬을 부팅 시 자동 시작하도록 설정하고 즉시 시작
systemctl enable --now kubelet
# (내 환경에 맞게 수정) 클러스터 내 노드들의 고정 IP/호스트명 매핑
# - kubeadm init/join 과정에서 호스트명을 이용한 통신이 필요하기 때문에 설정
cat <> /etc/hosts
172.16.0.128 master
172.16.0.133 worker1
172.16.0.136 worker2
172.16.0.137 worker3
EOF
# 모든 설정이 완료되었으므로 재부팅하여 시스템 설정 반영
reboot
각 명령이 왜 사용 됐는지
마스터 노드 설정 명령어
# Kubernetes 클러스터 초기화 (Master 노드용)
# - API 서버가 광고할 IP 지정
# - Pod 네트워크 CIDR은 Flannel 기준으로 10.244.0.0/16 사용
kubeadm init --apiserver-advertise-address=172.16.0.128 --pod-network-cidr=10.244.0.0/16
# kubectl 명령어를 현재 사용자에서 쓸 수 있도록 설정
# - kubeconfig 경로 생성
mkdir -p $HOME/.kube
# - admin.conf를 복사하여 kubectl이 클러스터에 접근할 수 있게 함
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
# - 설정 파일의 소유자를 현재 사용자로 변경 (권한 문제 방지)
chown $(id -u):$(id -g) $HOME/.kube/config
# Flannel 네트워크 플러그인 설치 (Pod 간 통신을 위한 CNI)
# - 반드시 --pod-network-cidr와 일치하는 플러그인 설치할 것
kubectl apply -f <https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml>
# 모든 네임스페이스의 Pod 상태 확인
# - CoreDNS, kube-proxy, flannel 등 시스템 컴포넌트가 제대로 동작 중인지 점검
kubectl get pods --all-namespaces
# kubectl 자동완성 기능 설치 (입력 중 Tab 키로 명령어 자동완성 가능)
dnf install -y bash-completion
# 현재 bash 세션에 kubectl 자동완성 기능 로드
source <(kubectl completion bash)
# 향후 로그인 시 자동으로 kubectl 자동완성이 동작하도록 bashrc에 추가
echo "source <(kubectl completion bash)" >> ~/.bashrc
# 설정 마무리 후 root 세션 종료 (일반 사용자로 다시 로그인하거나 워커 작업 진행 가능)
exit
워커 노드 설정 명령어
- Worker nodes
kubeadm join 172.16.0.128:6443 --token utkwbb.2uo33ve2i17lxrdq \\
--discovery-token-ca-cert-hash sha256:22ebb62266ab330d9ee89087670046b78ccae7f6d9223fc8276f39c241436b8f
# kubectl get nodes
[root@master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master Ready control-plane 3m46s v1.31.10
worker1 Ready <none> 58s v1.31.10
worker2 Ready <none> 54s v1.31.10
worker3 Ready <none> 54s v1.31.10
CLI 기본 명령
# [기본 형식] kubectl [명령어] [리소스 유형] [이름] [옵션]
# 노드 상태, IP, 역할 등 정보 출력
# --show-labels 옵션은 클러스터에서 라벨 기반 스케줄링이나 선택자 기반 설정을 분석할 때 유용합니다.
kubectl get node -o wide --show-labels # 클러스터에 등록된 노드 목록을 출력, 라벨 포함하여 상세 정보 표시
# nginx 이미지를 기반으로 파드 생성 (단일 컨테이너 실행용)
kubectl run nginx-pod --image=nginx # nginx 컨테이너가 포함된 nginx-pod 생성
# 현재 실행 중인 파드 상태와 라벨 확인
kubectl get pod -o wide --show-labels # 모든 파드의 상태를 자세히 확인 (IP, 노드, 라벨 등 포함)
# 특정 파드의 상세 정보 확인 (이벤트, 환경변수, 볼륨 등)
kubectl describe pod nginx-pod
# 모든 서비스 목록 출력 (ClusterIP, NodePort 등 포함)
kubectl get services -o wide --show-labels
# nginx-pod를 ClusterIP 타입 서비스로 노출 (내부 통신용)
kubectl expose pod nginx-pod --name clusterip --type=ClusterIP --port 80
# 서비스 생성 결과 확인
kubectl get services -o wide --show-labels
# clusterip 서비스의 상세 정보 확인
kubectl describe service clusterip
# nginx-pod를 NodePort 타입으로 외부에 노출 (노드 IP + 포트 접근 가능)
kubectl expose pod nginx-pod --name nodeport --type=NodePort --port 80
# 서비스 상태 재확인
kubectl get services -o wide --show-labels
# nodeport 서비스 상세 정보 확인
kubectl describe service nodeport
# nginx-pod를 LoadBalancer 타입으로 외부 노출 (외부 로드밸런서나 static IP 활용 가능)
kubectl expose pod nginx-pod --name loadbalancer --type=LoadBalancer --external-ip 192.168.0.32 --port 80
# loadbalancer 서비스 설정 파일을 에디터로 열어 직접 수정
kubectl edit service loadbalancer
# 서비스 목록 재확인
kubectl get services -o wide --show-labels
# loadbalancer 서비스 상세 정보 확인
kubectl describe service loadbalancer
# nginx-pod 내부 bash 셸 접속 (컨테이너 내부 탐색)
kubectl exec -it nginx-pod -- bash
# 로컬 html 디렉토리를 nginx-pod 내 디렉토리로 복사
kubectl cp html nginx-pod:/usr/share/nginx
# 로컬 WAR 파일을 Tomcat 서버 파드로 복사
kubectl cp webapp.war nginx-pod:/usr/local/tomcat/webapps/ROOT.war
# 파드의 스펙(YAML)을 열어 직접 편집
kubectl edit pod nginx-pod
# kubectl 명령어 전역 옵션 보기
kubectl options
# 사용 가능한 모든 리소스 종류 출력 (e.g., pods, deployments, services 등)
kubectl api-resources
# 노드 상세 정보 출력
kubectl get nodes -o wide
# 헤더 없이 노드 정보 출력 (스크립트나 파싱 용도)
kubectl get nodes -o wide --no-headers
# 노드의 내부 IP만 추출 (스크립트에서 유용)
kubectl get nodes -o wide --no-headers | awk '{print $6}'
# 모든 리소스 출력 (파드, 서비스, 디플로이먼트 등 포함)
kubectl get all
# 모든 서비스 삭제
kubectl delete svc --all
# nginx-pod 삭제
kubectl delete pod nginx-pod
# 강제 종료로 파드 삭제 (graceful termination 생략)
kubectl delete pod <pod> --grace-period=0 --force
# 모든 파드와 서비스 강제 삭제
kubectl delete pod,svc --all --force
# nginx 디플로이먼트 생성 (레플리카 3개 포함)
kubectl create deployment nginx-app --replicas=3 --image=nginx
# 디플로이먼트 목록 확인
kubectl get deployments.apps
# 디플로이먼트에서 생성된 레플리카셋 확인
kubectl get replicasets.apps
# 파드 상태 확인 (레이블 포함, 어떤 노드에 배치됐는지 등)
kubectl get pods -o wide --show-labels
# nginx 디플로이먼트를 ClusterIP 서비스로 노출
kubectl expose deployment nginx-app --name clusterip-app --type=ClusterIP --port 80
# nginx 디플로이먼트를 NodePort로 외부에 노출
kubectl expose deployment nginx-app --name nodeport-app --type=NodePort --port 80
# nginx 디플로이먼트를 LoadBalancer로 노출 (외부에서 IP로 접근 가능)
kubectl expose deployment nginx-app --name loadbalancer-app --type=LoadBalancer --external-ip 192.168.0.33 --port 80
# 특정 파드 내부에 접속하여 index.html 파일 내용 변경
kubectl exec -it nginx-app-65fd5796b9-hf75k -- sh -c "echo 'worker3' > /usr/share/nginx/html/index.html"
# 서비스 상태 확인
kubectl get service -o wide --show-labels
# 디플로이먼트 YAML을 열어 수정 (이미지 교체, 레플리카 수 변경 등)
kubectl edit deployments.apps nginx-app
# 디플로이먼트의 레플리카 수를 6개로 확장
kubectl scale deployment nginx-app --replicas=6
# 파드 상태 확인
kubectl get pods -o wide --show-labels
# 레플리카 수를 3개로 다시 줄임
kubectl scale deployment nginx-app --replicas=3
# 파드 재확인
kubectl get pods -o wide --show-labels
# 디플로이먼트 삭제
kubectl delete deployments.apps nginx-app
# 모든 서비스 삭제
kubectl delete service --all
네임스페이스(Namespace)란
쿠버네티스 클러스터 안에서 파드, 서비스, 디플로이먼트 등의 리소스를 서로 격리해서 운영할 수 있게 해주는 논리적 구획이다.
하나의 클러스터를 여러 개의 가상 클러스터처럼 나누는 기능
기본적으로 제공하는 네임스페이스가 존재한다
이름 | 용도 |
default | 기본 네임스페이스 (명시 안 하면 여기에 생성됨) |
kube-system | Kubernetes 내부 시스템 컴포넌트 (예: kube-dns, controller 등) |
kube-public | 공개 리소스용 (클러스터 전체에 접근 가능) |
kube-node-lease | 노드 상태 헬스체크를 위한 heartbeat 정보 저장용 |
추가로 설치한 네임스페이스
kube-flannel Active 102m
Flannel은 Kubernetes에서 Pod 간 통신이 가능하도록 네트워크를 구성해주는 CNI 플러그인 중 하나이다.
이걸 설치해야지만 Pod-to-Pod 통신이 가능해짐
CNI는 Container Network Interface → NIC 역할
4: cni0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default qlen 1000
link/ether a6:d8:12:79:5e:58 brd ff:ff:ff:ff:ff:ff
inet 10.244.0.1/24 brd 10.244.0.255 scope global cni0
valid_lft forever preferred_lft forever
inet6 fe80::a4d8:12ff:fe79:5e58/64 scope link
valid_lft forever preferred_lft forever
# 해당 노드의 파드들은 10.244.0.X 이렇게 아이피를 할당 받을 것이다.
# namespace 검색
kubectl get namespaces
# 특정 네임스페이스 내부의 파드들 검색
kubectl get pods -n my-namespace
# 새로운 네임스페이스 생성
kubectl create namespace dev
# 파드 생성 시 네임스페이스 지정
kubectl run nginx --image=nginx -n dev
kube-system
Kubernetes 시스템 컴포넌트들이 실행되는 전용 네임스페이스이다.
여기 있는 파드들은 클러스터 관리, 내보 통신, 노드 상태 관리 등의 기능을 담당함
[root@master ~]# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-7c65d6cfc9-2bx9d 1/1 Running 0 109m
coredns-7c65d6cfc9-rd255 1/1 Running 0 109m
etcd-master 1/1 Running 0 109m
kube-apiserver-master 1/1 Running 0 109m
kube-controller-manager-master 1/1 Running 0 109m
kube-proxy-2tz2p 1/1 Running 0 106m
kube-proxy-4846n 1/1 Running 0 106m
kube-proxy-fz54h 1/1 Running 0 109m
kube-proxy-hrndn 1/1 Running 0 106m
kube-scheduler-master 1/1 Running 0 109m
이름 | 역할 | 상세 설명 |
coredns-* | 클러스터 DNS 서버 | 클러스터 내부에서 서비스 이름을 IP로 변환 (예: nginx-service → IP 주소)→ Pod 간 DNS 기반 통신을 가능하게 함 |
etcd-master | 분산 키-값 저장소 | 클러스터 상태, 구성 정보를 저장 (Kubernetes의 뇌)→ 모든 클러스터 상태(state)는 etcd에 저장됨 |
kube-apiserver-master | 클러스터 API 엔드포인트 | kubectl, dashboard, 컨트롤러 등이 요청하는 REST API 서버 역할→ 인증/인가/검증 등 중심 기능 담당 |
kube-controller-manager-master | 컨트롤 루프 관리자 | Deployment, ReplicaSet, NodeController 등 다양한 컨트롤러를 관리→ 클러스터의 실제 상태를 원하는 상태로 유지 |
kube-scheduler-master | 파드 스케줄러 | 파드를 어떤 노드에 배치할지 결정함 (CPU/메모리 등 고려하여)→ 원하는 리소스 조건을 만족하는 노드에 스케줄링 |
kube-proxy-*** (4개)** | 네트워크 프록시 & 로드밸런서 | 각 노드에 설치되어 서비스 IP와 실제 Pod IP 간 라우팅을 관리→ 클러스터 내부/외부 네트워크 통신 가능하게 함 |
Pod 생성
#kubectl run nginx-pod --image nginx
[root@master ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-pod 1/1 Running 0 9m49s 10.244.2.2 worker3 <none> <none>
[root@master ~]# curl 10.244.2.2
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
...
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
여기서의 IP가 CNI IP이다. 이건 내부 파드끼리의 통신을 위한 내부 IP이다.
이걸로는 외부에서 접근이 불가능하다. 그래서 Service 리소스가 필요함
Service가 외부에서의 요청을 이 파드로 프록시해주는 것이다.
여기서는 하나의 파드로 보내준다고하지만 여러개의 같은 역할을 하는 파드들을 연결하면 로드 밸런서 역할까지 가능함
외부 아이피(노드 IP) → 클러스터 IP(Service의 IP) → 파드 IP(CNI) → 컨테이너의 포트
파드의 여러 컨테이너가 들어갈 수 있다. 이때는 별도의 IP를 컨테이너에 부여하는게 아닌 포트 포워딩을 해주는 것이다.
apiVersion: v1
kind: Pod
metadata:
name: multi-container-pod
spec:
containers:
- name: app
image: myapp
ports:
- containerPort: 8080
- name: log-agent
image: logsidecar
ports:
- containerPort: 9000
Service 리소스 생성하기
[root@master ~]# kubectl expose pod nginx-pod --name clusterip --type ClusterIP --port 80
service/clusterip exposed
항목 | 설명 |
kubectl expose | 기존 리소스(파드 등)에 대해 Service 리소스를 생성하는 명령 |
pod nginx-pod | nginx-pod라는 이름의 파드를 대상으로 |
--name clusterip | 생성될 Service의 이름은 clusterip |
--type ClusterIP | 내부에서만 접근 가능한 서비스 타입. 외부 공개는 안 됨 |
--port 80 | Service가 노출할 포트는 80번 |
다음과 같은 Yaml로 만들어지는 것과 같음
apiVersion: v1
kind: Service
metadata:
name: clusterip
spec:
selector:
run: nginx-pod # (Label이 있을 경우 자동 셀렉터)
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIP
[root@master ~]# kubectl expose pod nginx-pod --name nodeport --type NodePort --port 80
[root@master ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
clusterip ClusterIP 10.103.245.104 <none> 80/TCP 25m
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3h20m
nodeport NodePort 10.102.233.162 <none> 80:30394/TCP 3m41s
[root@master ~]# curl 172.16.0.128:30394
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
항목 | 설명 |
expose | 기존 리소스(Pod)를 대상으로 Service 생성 |
--name nodeport | Service 이름은 nodeport로 지정 |
--type NodePort | Cluster 외부에서 접근 가능한 Service 타입 지정 |
--port 80 | Service가 클러스터 내에서 노출하는 포트 (→ targetPort는 파드의 80으로 자동 설정됨) |
여기서는 Type이 NodePort로 설정되어 있다. → 노드의 IP에 특정 포트가 해당 파드와 연결된 것이다.
이걸 해주는게 서비스
노드 IP + NodePort → 클러스터 IP → 파드 IP
여기서 노드 IP는 마스터, 워커 모두 사용가능하다.
→ kube-proxy가 Service를 Watch 하면서, 거기에 대한 정보를 항상 최신 상태로 유지중
그래서 모든 노드들이 Service 모두 유지 여기서 네임스페이스.svc.cluster.local 이런 형식으로 저장
이 경우 ip 뒤에 랜덤 포트 30000~32767로 정해지는 포트를 적어야한다.
하지만 Type을 loadbalancer로 했을 경우는 외부에서 접속 가능한 IP를 지정해 줄 수 있다.
이러면 먼저 NodePort가 만들어준다 80:30184/TCP
이후 클라우드 컨트롤러 매니저(Cloud Controller Manager)가 개입
나는 172.16.0.200 같은 ip를 수동으로 부여했음. 이건 BareMetal 환경에서 한것임
[root@master ~]# kubectl expose pod nginx-pod --name loadbalancer --type=LoadBalancer --external-ip 172.16.0.200 --port 80
[root@master ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
clusterip ClusterIP 10.103.245.104 <none> 80/TCP 59m
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3h53m
loadbalancer LoadBalancer 10.105.248.20 172.16.0.200 80:30184/TCP 15s
nodeport NodePort 10.102.233.162 <none> 80:30394/TCP 36m
동작 방식
[외부 사용자]
↓ (172.16.0.200:80)
[클러스터 노드 중 하나가 이 IP를 가지고 있어야 함]
↓ (NodePort or ClusterIP 내부 라우팅)
[kube-proxy가 처리]
↓
[nginx-pod의 80번 포트]
만약 이미지는 80을 리슨하고 서비스의 타겟 포트가 8080이면 연결되지 않음
kubectl expose pod nginx-pod --name loadbalancer8080 --type=LoadBalancer --external-ip 172.16.0.128 --port 8080
이렇게 되면 외부에서 받기를 기다리는 포트는 8080 즉 서비스의 포트
또한 별도의 명시가 없다면 target port 역시 8080
하지만 nignx 이미지로 만든 컨테이너는 80을 리슨 중
따라서 연결되지 않음
kubectl expose pod nginx-pod --name loadbalancer8080-1 --type=LoadBalancer --external-ip 172.16.0.128 --port 8080 --target-port 80
이렇게 --target-port 80 으로 명시를 해줘야 8080:80 이렇게 되어서 nginx가 리슨하는 80과 연결됨
동일한 yml
# kubectl edit svc loadbalancer8080-1
apiVersion: v1
kind: Service
metadata:
name: loadbalancer8080-1
namespace: default
spec:
type: LoadBalancer
externalIPs:
- 172.16.0.128
selector:
run: nginx-pod # 이 라벨은 해당 파드에 있는 라벨과 반드시 일치해야 함
ports:
- protocol: TCP
port: 8080 # 외부에서 접근할 포트
targetPort: 80 # 파드(컨테이너)가 실제로 리슨하고 있는 포트
kubectl exec
컨테이너 내부로 접근할 수 있다.
kubectl exec -it nginx-pod -- bash
컨테이너로 COPY 하기
파드 안쪽에 컨테이너로 html을 넣어서 적용되는 모습
mkdir html
tar xvf sale.tar -C html/
kubectl cp html nginx-pod:/usr/share/nginx
curl 172.16.0.128:8080
...
<body>
<!-- ======= Header ======= -->
<header id="header" class="fixed-top ">
<div class="container d-flex align-items-center">
<h1 class="logo me-auto"><a href="index.html">Arsha</a></h1>
<!-- Uncomment below if you prefer to use an image logo -->
<!-- <a href="index.html" class="logo me-auto"><img src="assets/img/logo.png" alt="" class="img-fluid"></a>-->
<nav id="navbar" class="navbar">
<ul>
<li><a class="nav-link scrollto active" href="#hero">Home</a></li>
<li><a class="nav-link scrollto" href="#about">About</a></li>
<li><a class="nav-link scrollto" href="#services">Services</a></li>
<li><a class="nav-link scrollto" href="#portfolio">Portfolio</a></li>
...
Pod 속 컨테이너 이미지 변경하기
kubectl edit pod nginx-pod
spec:
containers:
- image: johnlee0405/flask-ifconfig:v1.0 <- 여기를 변경
imagePullPolicy: Always
name: nginx-pod
resources: {}
[root@master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-pod 1/1 Running 2 (2m9s ago) 160m
[root@master ~]# curl 172.16.0.128:8080
당신의 IP는 10.244.0.0
yml이 변경 된다면 파드가 재시작함 → 이건 롤링 업데이트가 아닌 수동으로
파드는 불변이기 때문에 변경이 된게 아님
삭제되었다가 다시 그에 맞춰서 생성된 것 → 이건 서비스 중단을 의미
이젠 WAS 적용해보자
이미지 변경 8080 리슨하는 이미지로
war 파일 copy 하기
kubectl edit pod nginx-pod -> 이미지 tomcat
kubectl cp webapp.war nginx-pod:/usr/local/tomcat/webapps/ROOT.war
[root@master ~]# curl 172.16.0.128:8080
<form action="action_page.php">
<div class="container">
<h1>New user Register for DevOps Learning</h1>
<p>Please fill in this form to create an account.</p>
<hr>
<label for="Name"><b>Enter Name</b></label>
<input type="text" placeholder="Enter Full Name" name="Name" id="Name" required>
<br>
<label for="mobile"><b>Enter mobile</b></label>
<input type="text" placeholder="Enter moible number" name="mobile" id="mobile" required>
<br>
<label for="email"><b>Enter Email</b></label>
<input type="text" placeholder="Enter Email" name="email" id="email" required>
<br>
<label for="psw"><b>Password</b></label>
<input type="password" placeholder="Enter Password" name="psw" id="psw" required>
<br>
<label for="psw-repeat"><b>Repeat Password</b></label>
<input type="password" placeholder="Repeat Password" name="psw-repeat" id="psw-repeat" required>
<hr>
<br>
<p>By creating an account you agree to our <a href="#">Terms & Privacy</a>.</p>
<button type="submit" class="registerbtn">Register</button>
</div>
<div class="container signin">
<p>Already have an account? <a href="#">Sign in</a>.</p>
</div>
<h1> Thankyou, Happy Learning </h1>
</form>
마무리
Kubernetes 마스터 노드와 워커 노드를 구성해보고, Pod를 구성하고 다양한 Service 리소스의 타입 별로 테스트를 해봤다.
또한 kubectl 관련 명령어 get delete edit exec cp 등을 사용해보면서 실습했다.
오늘 실습은 yml파일을 직접 작성하지 않고, 명령어를 통해 자동 작성하게 하고, 내부를 edit으로 수정하며 실습했다. 하지만 실무에선 yml을 기반으로 작업한다.
이것이 git을 통해 버전 및 이력을 관리를 할 수 있기에 사용한다고 한다.