kubernetes 를 핸즈온으로 공부하려면 로컬 머신에서 멀티 노드 클러스터를 구축하는게 가장 편리하다는 판단을 했다. 그래서 여러 가이드를 찾아보았다. 처음에는 multipass 라는 가상화 도구를 사용해서 시도해보고, 그 다음에는 kind 라는 kubernetes 를 docker 컨테이너로 올리는 도구도 사용해봤는데, 내공이 부족하여 실패하였다. 결국 docker desktop 에서 간단히 활성화 할 수 있는 kind 로의 프로비저닝 방식을 사용하여 구축에 성공했다.

하지만, Ingress 를 실습할 차례가 왔고, kind 방식으로 구축한 클러스터는 네트워크 구성이 실제 머신을 노드로 사용하는 클러스터와 달라서 실습이 불가능함을 깨달았다. 그래서, 실제 완전한 리눅스 OS와 동일하게 구성하기 위해 UTM 가상화 도구를 사용해 멀티 노드 클러스터를 구축했고, 그 과정을 기술한다.

 

1. UTM 설치

UTM 이라는 가상화 도구를 m1 맥북에 설치한다.

 

2. 가상머신 생성

가상머신 3대를 Ubuntu 24.04.3 LTS OS를 설치하며 생성한다.

1대는 control plane 용이고, 나머지 2대는 worker node 용이다.

시스템 자원은 본인이 사용하는 컴퓨팅 리소스에 맞게 할당한다.

 

3. 클립보드 붙여넣기 설정

개발 편의성을 위해 호스트 머신과 각 게스트 머신간 복붙을 가능하게 하여야 한다.

CLI 만 사용중이라면 아래 두가지 방법이 있다.(spice-vdagent 는 GUI 용 클립보드 공유 에이전트이므로 상관하지 않는다.)

  1) 리눅스 터미널에 openssh 를 설치하여 맥북에서 직접 ssh 접속

  2) 가상머신의 display 장치를 삭제하고 직렬 포트 장치로 사용

직렬 포트 장치가 간단하지만, CLI 가 이상하게 표시되는 현상이 종종 있으므로, ssh 접속하는 방법이 사용성이 더 낫다.

 

4. hostname 설정(모든 노드)

아래 커맨드를 통해서 각 노드에 hostname 을 지정해준다.

$ sudo hostnamectl set-hostname <새 호스트명>

 

아래 커맨드를 통해서 정상적으로 hostname 이 설정되었는지 확인한다.

$ cat /etc/hostname
# 또는
$ hostname
# 또는
$ hostnamectl

 

5. /etc/hosts 수정(모든 노드)

각 노드에서 아래 명령어를 실행하여 enp0s1 장치의 inet 에 기재된 IP 를 확인한다.

$ sudo ip addr

 

각 노드의 /etc/hosts 파일에 자신의 IP 를 제외한 나머지 노드의 IP 를 hostname 과 매핑해준다.

# master01 노드의 /etc/hosts 예시
...
127.0.1.1 master01
192.168.64.6 worker01
192.168.64.7 worker02
...

 

6. swapoff 및 영구 swapoff 적용(모든 노드)

아래 커맨드를 사용하여 각 노드에서 swapoff 를 적용한다.

$ sudo swapoff -a

 

아래 커맨드를 사용해 /etc/fstab 파일을 수정하여 부팅시마다 swapoff 가 자동 적용되도록 설정한다.(swap 설정을 주석처리하여 영구 비활성화 하는 행위)

$ sudo sed -i '/swap/s/^\(.*\)$/#\1/g' /etc/fstab

 

7. 커널 네트워크에 브릿지 트래픽 허용(모든 노드)

아래 커맨드를 실행하여 브릿지 네트워크로부터 들어오는 트래픽을 허용한다.

$ cat <<'EOF' | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
net.ipv4.ip_forward=1
EOF

# 커널 파라미터 설정 적용
$ sudo sysctl --system

 

8. containerd 설치(모든 노드)

아래 커맨드를 순차적으로 실행하여 각 노드에 containerd 를 설치한다.

# 1) 필요한 의존성 패키지 설치
$ sudo apt update
$ sudo apt install -y ca-certificates curl gnupg lsb-release

# 2) Docker의 APT repo 대신 Ubuntu 기본 repo 에서 containerd 설치
$ sudo apt install -y containerd

# 3) 기본 config 생성
$ sudo mkdir -p /etc/containerd
$ sudo containerd config default | sudo tee /etc/containerd/config.toml

# 4) 시스템에 맞춰 cgroup 설정(기본적으로 systemd cgroup 사용 권장)
# /etc/containerd/config.toml 에서 아래를 확인/적용:
# SystemdCgroup = true
# 아래 커맨드로 바로 수정 가능
$ sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml

# 5) pause:3.10 버전으로 수정(선택)
# (이건 kubernetes 1.31.3 버전과의 호환성을 위함이며, 사용하는 kubernetes 버전의 호환성을 확인하여 맞춰주시길 바랍니다.)
$ sudo sed -i 's|sandbox_image = "registry.k8s.io/pause:3.8"|sandbox_image = "registry.k8s.io/pause:3.10"|' \
  /etc/containerd/config.toml

# 6) containerd 부팅시 자동실행 설정(enable) 및 재시작(restart)
$ sudo systemctl enable containerd && sudo systemctl restart containerd

 

9. kubeadm, kubelet, kubectl 설치(모든 노드)

아래 커맨드를 순차적으로 실행하여 각 노드에 kubeadm, kubelet, kubectl 를 설치한다.

# 1) 필요한 의존성 패키지 설치
$ sudo apt-get update
$ sudo apt-get install -y apt-transport-https ca-certificates curl

# 2) APT 저장소의 서명 키(GPG key)를 보관할 디렉터리를 생성
$ sudo mkdir -p /etc/apt/keyrings

# 3) Kubernetes APT 저장소의 GPG 서명 키 다운로드 및 변환하여 저장(v1.31)
$ curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.31/deb/Release.key | \
  sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg

# 4) Kubernetes APT 저장소 등록 및 업데이트
$ echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] \
  https://pkgs.k8s.io/core:/stable:/v1.31/deb/ /" | \
  sudo tee /etc/apt/sources.list.d/kubernetes.list
$ sudo apt-get update

# 5) 설치 (버전 고정 원하면 =<버전> 지정)
$ sudo apt-get install -y \
  kubelet=1.31.3-1.1 \
  kubeadm=1.31.3-1.1 \
  kubectl=1.31.3-1.1

# 6) 자동 업그레이드 되지 않도록 버전 고정
$ sudo apt-mark hold kubelet kubeadm kubectl

# 7) kubelet 서비스 부팅시 자동실행 설정 및 재시작
$ sudo systemctl enable kubelet && sudo systemctl restart kubelet

 

10. VM에 브릿지 네트워크 설정 및 브릿지 IP 고정(모든 노드)

UTM 에서 네트워크 장치 추가 > 브릿지 네트워크 > 실제 접속중인 네트워크 인터페이스 선택 하고 저장한다.

노드 접속 후 아래 커맨드로 게이트웨이 주소를 확인한다.

$ ip route
# 출력 예시
default via 192.168.0.1 dev enp0s2 proto dhcp src 192.168.0.36

 

default via 뒤의 IP 가 게이트웨이의 주소이므로 메모한다.(enp0s2 인터페이스의 게이트웨이)

아래 커맨드로 DNS 주소를 확인한다.

$ resolvectl status
# 출력 예시
Link 2 (enp0s2)
    Current DNS Server: 192.168.0.1
    DNS Servers: 192.168.0.1 168.126.11.1 168.126.11.2

 

DNS Servers 목록이 DNS 주소이므로 메모한다.

/etc/netplan/*.yaml 파일에 enp0s2 설정을 추가하고 게이트웨이 주소와 DNS 주소를 아래 내용처럼 적용한다.

# /etc/netplan/*.yaml 파일을 열어서 아래처럼 enp0s1, enp0s2 을 추가/수정
network:
  version: 2
  renderer: networkd
  ethernets:
    enp0s1:
      dhcp4: yes
      optional: true
    enp0s2:
      dhcp4: no
      addresses:
        - 192.168.0.36/24
      routes:
        - to: default
          via: 192.168.0.1
      nameservers:
        addresses:
          - 192.168.0.1
          - 168.126.11.1
          - 168.126.11.2

$ sudo netplan apply

 

아래 커맨드를 실행하여 enp0s2 장치에 inet 이 잡혔는지 확인한다.

$ sudo ip addr

 

만약 enp0s2 가 아직 DOWN 상태라면 아래 커맨드를 실행한다.

$ sudo ip link set enp0s2 up

 

11. 각 노드에 필요한 패키지들 설치(모든 노드)

아래 커맨드를 실행하여 각 노드에 추가 패키지를 설치한다.(클러스터 구성 및 운영에 필요)

# k8s 구성 및 운영에 필요한 패키지들 설치
$ sudo apt-get update
$ sudo apt-get install -y \
  conntrack \
  ipset \
  iptables \
  ebtables \
  ethtool \
  socat \
  ipvsadm

 

12. control-plane 초기화(master 노드)

master 노드에서 아래 커맨드를 순차적으로 실행하여 kubernetes control plane 초기화를 진행한다.

# 초기화 실행. <MASTER_NODE_BRIDGE_IP> 에는 master 노드의 브릿지 네트워크 ip를 넣는다.
# pod-network-cidr 는 고정이다.
$ sudo kubeadm init --kubernetes-version=1.31.3 \
  --pod-network-cidr=10.244.0.0/16 \
  --apiserver-advertise-address=<MASTER_NODE_BRIDGE_IP>

# 성공 후 출력되는 메시지를 따라 진행하면 된다.(아래는 예시)
To start using your cluster, you need to run the following as a regular user:

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

Alternatively, if you are the root user, you can run:

  export KUBECONFIG=/etc/kubernetes/admin.conf

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

# 위 링크를 따라 들어가면 나오는 flannel CNI 파드 네트워크 구성 예시
$ kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml

Then you can join any number of worker nodes by running the following on each as root:

# 아래 join 커맨드를 복사해놓고, 각 worker node 에서 root 권한으로 실행해줍니다.
kubeadm join...

# 가이드에는 없는데, node join 후 control plane 에서 containerd 를 재시작 해줘야 한다.
$ sudo systemctl restart containerd

 

만약 kubeadm init 중간에 실패하거나 다시 init 하려면 아래 커맨드로 reset 실행 후 다시 init 진행한다.

$ sudo kubeadm reset -f
$ sudo systemctl stop kubelet
$ sudo iptables -F && sudo iptables -t nat -F && sudo iptables -t mangle -F && sudo iptables -X
$ sudo rm -rf /etc/cni/net.d & \
  sudo ipvsadm --clear & \
  sudo rm -rf $HOME/.kube/config & \
  sudo rm -rf $HOME/.kube/cache

 

만약 flannel CNI 가 제대로 생성되지 않아 재구성해야 한다면 아래 커맨드로 삭제를 먼저 진행해야 한다.

# flannel CNI 파드 네트워크 제거 예시(CNI 파드 네트워크 구성중 문제가 발생하여 제거하고 다시 설치해야 할 때)
$ kubectl delete -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml --ignore-not-found=true

 

만약 flannel pod(DaemonSet)가 생성되지 않는다면 모든 노드(master/worker)에서 아래 순서대로 실행한다.

# 모듈 로드
$ sudo modprobe br_netfilter
$ sudo modprobe overlay

# 부팅시 유지
$ cat <<'EOF' | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

# 브릿지 네트워크 트래픽 허용(이미 위에서 적용했으나, 재확인해보자)
$ cat <<'EOF' | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
net.ipv4.ip_forward=1
EOF
$ sudo sysctl --system

 

master 노드에서 아래 명령어로 flannel 재시작 후 파드를 확인한다.

# flannel 재시작
$ kubectl -n kube-flannel rollout restart ds/kube-flannel-ds

# 정상 확인
$ kubectl -n kube-flannel get pods -o wide
$ kubectl -n kube-system get pods

 

만약 worker node 에서 클러스터 join 시에 아래와 같은 에러가 나타난다면

error execution phase preflight: [preflight] Some fatal errors occurred:
        [ERROR FileAvailable--etc-kubernetes-kubelet.conf]: /etc/kubernetes/kubelet.conf already exists
        [ERROR Port-10250]: Port 10250 is in use
        [ERROR FileAvailable--etc-kubernetes-pki-ca.crt]: /etc/kubernetes/pki/ca.crt already exists

 

이미 join 했던 노드라서 클러스터 정보와 kubelet 이(10250 포트를 점유하며) 남아있기 때문이다.

해당 노드에서 아래 커맨드를 순서대로 실행하여 clean reset 한 뒤 다시 join 해야 한다.

# 1) 노드의 kubeadm 리셋
$ sudo kubeadm reset -f

# 2) CNI/네트워크 잔여물 정리
$ sudo rm -rf /etc/cni/net.d & \
  sudo ipvsadm --clear & \
  sudo rm -rf $HOME/.kube/config & \
  sudo rm -rf /var/lib/cni & \
  sudo ip link delete cni0 2>/dev/null || true & \
  sudo ip link delete flannel.1 2>/dev/null || true & \
  sudo ip link delete kube-ipvs0 2>/dev/null || true

# 3) kubelet 정리 (10250 점유 해소)
$ sudo systemctl stop kubelet && \
  sudo rm -rf /etc/kubernetes & \
  sudo rm -rf /var/lib/kubelet && \
  sudo systemctl start kubelet

# 4) containerd 재시작
$ sudo systemctl restart containerd

 

13. host 머신에서 가상머신으로 공유 폴더 설정하기(선택)

UTM 에서 가상머신 편집 > 공유에서 아래를 설정한다.

  • 디렉터리 공유 모드: VirtFS
  • 경로: 공유폴더 지정

가상머신 부팅 및 로그인 후 아래 커맨드를 실행한다.

$ sudo mkdir /media/<공유폴더이름>
$ sudo mount -t 9p -o trans=virtio share /media/<공유폴더이름> -oversion=9p2000.L
$ sudo vi /etc/fstab
# 최하단에 아래 내용 추가하고 저장
share /media/<공유폴더이름> 9p trans=virtio,version=9p2000.L,rw,_netdev,nofail 0 0

 

이제 가상머신을 재실행하면 아래 경로에서 공유폴더를 확인 가능하다.

  • /media/<공유폴더이름>

참고로, 호스트 머신에서 공유폴터 내부에서 공유폴더 외부로 심볼릭 링크 된 파일은 가상머신에서 내용을 볼 수 없다.

블로그 이미지

망원동똑똑이

프로그래밍 지식을 자유롭게 모아두는 곳입니다.

,

k8s 의 nginx 컨테이너 내에서 패키지를 추가 설치하기 위해 apt update 및 install 을 실행시 아래와 같은 에러가 발생

root@sample-entrypoint:/# apt update
Ign:1 http://deb.debian.org/debian buster InRelease
Ign:2 http://deb.debian.org/debian buster-updates InRelease
Ign:3 http://security.debian.org/debian-security buster/updates InRelease
Err:4 http://deb.debian.org/debian buster Release
  404  Not Found [IP: 146.75.50.132 80]
Err:5 http://security.debian.org/debian-security buster/updates Release
  404  Not Found [IP: 151.101.66.132 80]
Err:6 http://deb.debian.org/debian buster-updates Release
  404  Not Found [IP: 146.75.50.132 80]
Reading package lists... Done
E: The repository 'http://deb.debian.org/debian buster Release' does not have a Release file.
N: Updating from such a repository can't be done securely, and is therefore disabled by default.
N: See apt-secure(8) manpage for repository creation and user configuration details.
E: The repository 'http://security.debian.org/debian-security buster/updates Release' does not have a Release file.
N: Updating from such a repository can't be done securely, and is therefore disabled by default.
N: See apt-secure(8) manpage for repository creation and user configuration details.
E: The repository 'http://deb.debian.org/debian buster-updates Release' does not have a Release file.
N: Updating from such a repository can't be done securely, and is therefore disabled by default.
N: See apt-secure(8) manpage for repository creation and user configuration details.

 

원인은, 이 nginx 컨테이너의 base OS 는 Debian Stretch 리눅스인데, Stretch 리눅스의 경우 일정 기간이 지나면 패키지 저장소가 archive 저장소로 이동된다. 따라서 현재 등록된 패키지 저장소에서 찾을 수 없다는 에러가 발생한 것이다.

따라서, http://deb.debian.org/debian 로 바라보고 있는  패키지 저장소 주소를 archive 저장소 주소로 변경해주면 해결된다.

 

root@sample-entrypoint:/# cat > /etc/apt/sources.list << EOF
> deb http://archive.debian.org/debian buster main
> deb http://archive.debian.org/debian-security buster/updates main
> deb http://archive.debian.org/debian buster-updates main
> EOF

 

/etc/apt/sources.list 에 지정된 경로에서 패키지를 가져오는데, 이 경로를 http://archive.debian.org 으로 바라보게 설정하면 된다.

이후에 다시 apt update && apt install ~~~ 실행하면 정상적으로 패키지를 업데이트하고 설치할 수 있다.

 

root@sample-entrypoint:/# apt update
Get:1 http://archive.debian.org/debian buster InRelease [122 kB]
Get:2 http://archive.debian.org/debian-security buster/updates InRelease [34.8 kB]
Get:3 http://archive.debian.org/debian buster-updates InRelease [56.6 kB]
Get:4 http://archive.debian.org/debian buster/main arm64 Packages [7737 kB]
Get:5 http://archive.debian.org/debian-security buster/updates/main arm64 Packages [600 kB]
Get:6 http://archive.debian.org/debian buster-updates/main arm64 Packages [8780 B]
Fetched 8559 kB in 6s (1329 kB/s)
Reading package lists... Done
Building dependency tree
Reading state information... Done
54 packages can be upgraded. Run 'apt list --upgradable' to see them.

 

블로그 이미지

망원동똑똑이

프로그래밍 지식을 자유롭게 모아두는 곳입니다.

,

1. 명령어 설명

리눅스 dd 명령어는 블록 단위로 파일복사, 파일변환을 수행하는 명령어이다.

리눅스 시스템에서는 디스크도 파일로 간주되므로, 디스크 및 디스크의 파티션을 복제하는데 사용 가능하다.

아래와 같은 용도로 자주 사용된다.

  • 파일 및 장치 복사
  • 디스크 및 파티션 백업/복원
  • 사이즈를 지정한 swap 파일 생성
  • 사이즈를 지정한 더미파일 생성
  • 디스크 I/O 성능 측정
Usage: dd [OPERAND]...
  or:  dd OPTION
Copy a file, converting and formatting according to the operands.

  bs=BYTES        read and write up to BYTES bytes at a time (default: 512);
                  overrides ibs and obs
  cbs=BYTES       convert BYTES bytes at a time
  conv=CONVS      convert the file as per the comma separated symbol list
  count=N         copy only N input blocks
  ibs=BYTES       read up to BYTES bytes at a time (default: 512)
  if=FILE         read from FILE instead of stdin
  iflag=FLAGS     read as per the comma separated symbol list
  obs=BYTES       write BYTES bytes at a time (default: 512)
  of=FILE         write to FILE instead of stdout
  oflag=FLAGS     write as per the comma separated symbol list
  seek=N          skip N obs-sized blocks at start of output
  skip=N          skip N ibs-sized blocks at start of input
  status=LEVEL    The LEVEL of information to print to stderr;
                  'none' suppresses everything but error messages,
                  'noxfer' suppresses the final transfer statistics,
                  'progress' shows periodic transfer statistics

N and BYTES may be followed by the following multiplicative suffixes:
c =1, w =2, b =512, kB =1000, K =1024, MB =1000*1000, M =1024*1024, xM =M,
GB =1000*1000*1000, G =1024*1024*1024, and so on for T, P, E, Z, Y.

 

2. 자주 사용하는 옵션

  • bs: 한번에 읽고 쓸 수 있는 최대 바이트 크기. 즉, block size
  • count: 복사할 block 수. 즉, bs * count 크기의 사이즈만큼 복사
  • if: 입력 파일 경로
  • of: 출력 파일 경로

3. 옵션에 사용되는 suffix 단위

  • c: 1byte (Character)
  • w: 2bytes (Word)
  • b: 512bytes (Block)
  • K: 1024bytes (Kibibyte, KiB)

4. 사용예시

[더미파일 생성]

# dd if=/dev/zero of=/dummyfile bs=1024 count=1024

=> 파일을 /dummyfile 경로에 생성하되, 0 문자(정확히는, ASCII NUL(0x00) 문자)를 복사해 채우며, 1024 byte 블록 단위로 1024번에 걸쳐 복사한다.

 

[디스크/파티션 복제]

# dd if=/dev/sdb1 of=/dev/sdc1 bs=1024

=> /dev/sdb1 파티션을 /dev/sdc1 파티션으로 복제하되, 1024byte 블록 단위로 복제한다.

 

[디스크/파티션 초기화]

# dd if=/dev/zero of=/dev/sdb1

=> /dev/sdb1 파티션을 초기화한다.

 

[파일을 복사하며 내용 중 소문자를 모두 대문자로 변환]

# dd if=/log1 of=/log1_upper bs=1024 conv=ucase

=> /log1 의 내용을 /log1_upper 로 1024byte 블록 단위로 복사하며, 모든 소문자를 대문자로 변환한다.

 

*/dev/zero 는 0을 무한히 반환하는 특수 파일

블로그 이미지

망원동똑똑이

프로그래밍 지식을 자유롭게 모아두는 곳입니다.

,

1. swap 파일 생성

명령어: dd if=/dev/zero of=/swapfile1 bs=1024 count=1048576

 

옵션 설명

  • bs: block size 로, byte 단위로 지정(1024byte == 1Kib)
  • count: block 갯수 지정
  • if: 빈 값으로 채우기 위해 /dev/zero 고정
  • of: 스왑파일경로 지정

 

2. swap 파일 권한 변경

명령어: chmod 600 {스왑파일명}

e.g) chmod 600 /swapfile1

 

3. swap 파일에 swap 파일 시스템 생성

swap 포멧으로 설정하는 행위

명령어: mkswap {스왑파일명}

e.g) mkswap /swapfile1

 

4. 부팅시 스왑파일 자동 활성화 설정 및 swap 활성화

/etc/fstab 에 아래 내용을 추가

/swapfile1 swap swap defaults 0 0

 

swapon -a

 

5. 확인

명령어: swapon -s

Type 이 file 인 스왑 생성 확인

블로그 이미지

망원동똑똑이

프로그래밍 지식을 자유롭게 모아두는 곳입니다.

,

1. 디스크 추가

디스크 추가 후 lsblk 로 추가된 디스크 확인

 

2. 스왑용 파티션 생성

fdisk 또는 gdisk 명령어로 생성

명령어: gdisk {블록디바이스명}

e.g) gdisk /dev/sdc

 

안내된 커맨드에 따라 파티션 생성

스왑 파티션의 GUID 를 지정하는데, 이때 L 을 입력하여 스왑 파티션 코드를 확인하여 입력해야함

 

3. swap 파일 시스템 설정

스왑용 파티션을 스왑 타입으로 포멧하는 행위이다.

명령어: mkswap {파티션명}

e.g) mkswap /dev/sdc1

 

이제 blkid {파티션명} 으로 파티션 확인시 TYPE="swap" 으로 확인된다.

 

4. swap 활성화

명령어: swapon {파티션명}

e.g) swapon /dev/sdc1

 

5. swap 활성화 확인

swapon -s

 

6. 부팅시 스왑 파티션 자동 마운트 설정

/etc/fstab 파일에 아래 내용 등록

{스왑파티션명} swap swap defaults 0 0

 

7. /etc/fstab 에 등록된 내용 중 마운트되지 않은 스왑 파티션을 마운트

명령어: swapon -a

블로그 이미지

망원동똑똑이

프로그래밍 지식을 자유롭게 모아두는 곳입니다.

,

리눅스에서는 프로세스를 실행할 메모리 공간이 부족한 경우, 기존 프로세스 중 일부를 swap 공간(디스크 파티션 or 파일)으로 이동시켜 메모리 공간을 확보한다.

swap 공간으로 이동시키는 프로세스를 선택하는 기준은 아래와 같다.

  • 가장 오랫동안 사용되지 않은 프로세스(LRU)
  • priority 점수가 가장 높은(=우선순위가 낮음) 프로세스(0~39)

swap 공간으로 이동한 프로세스는 다시 호출될 때 메모리에 여유공간이 있다면 메모리로 다시 불러와진다.

 

1. swap 사용량 확인

  • free
  • top
  • swapon -s

e.g)

# free
              total        used        free      shared  buff/cache   available
Mem:        4017408      528376     2969828       13620      519204     3332876
Swap:       1048572           0     1048572

# top
top - 13:05:38 up 11:19,  0 users,  load average: 1.93, 1.98, 2.05
Tasks:   4 total,   1 running,   3 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.1 us,  0.1 sy,  0.0 ni, 99.8 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :   3923.2 total,   2896.2 free,    520.0 used,    507.1 buff/cache
MiB Swap:   1024.0 total,   1024.0 free,      0.0 used.   3250.7 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
    1 root      20   0    3620   2432   2304 S   0.0   0.1   0:00.09 bash
    8 root      20   0    3884   2944   2560 S   0.0   0.1   0:00.21 bash
   92 root      20   0    1948   1024   1024 S   0.0   0.0   0:00.00 sleep
  102 root      20   0    5732   2560   2176 R   0.0   0.1   0:00.00 top
  
# swapon -s
Filename				Type		Size	Used	Priority
/var/lib/swap                          	file    	1048572	0	-2

 

2. swap 비활성화

swapoff {스왑파일경로}

  • 스왑파일경로: swapon -s 로 조회된 Filename 경로

 

3. swap 활성화

swapon {스왑파일경로}

  • 스왑파일경로: swapon -s 로 조회된 Filename 경로

 

4. 부팅시 자동 활성화

/etc/fstab 에 아래 내용 추가

{스왑장치명} none swap sw 0 0
블로그 이미지

망원동똑똑이

프로그래밍 지식을 자유롭게 모아두는 곳입니다.

,

1. 디스크 용량 확장

 

2. 파티션 확장

growpart 패키지 사용

마지막 파티션을 확장하는 유틸리티. 마지막 파티션만 확장이 가능하며, 무조건 디스크의 마지막 섹터까지 모두 확장된다.

 

설치방법

  • centos: yum install -y cloud-utils-growpart
  • ubuntu: apt install -y cloud-guest-utils

 

사용방법

growpart {디스크명} {파티션번호}

e.g) growpart /dev/sdb 1

 

3. 파티션 내 파일시스템 확장

디스크 용량과 파티션 용량을 확장했더라도, 해당 파티션의 파일시스템을 포멧(타입 지정)해주지 않으면 파일시스템상에서 인식하지 못함.(df 명령어로 확인)

따라서, 파일시스템 확장을 수행해주어야 한다.

확장하려는 파일시스템 타입이 ext4 인지 xfs 인지에 따라 명령어가 다름

  • ext4: resize2fs {파티션명} {사이즈}
  • xfs: xfs_growfs {파티션명}

ext4 포멧인 경우는 파일시스템 확장/축소 모두 사이즈를 지정해서 가능하며, xfs 인 경우는 확장만 가능함

resize2fs 사이즈 파라미터 생략시 현재 파티션 사이즈를 사용

축소는 마운트 된 상태에서는 불가능하며, 확장은 마운트 된 상태에서도 가능하다.

블로그 이미지

망원동똑똑이

프로그래밍 지식을 자유롭게 모아두는 곳입니다.

,

디스크를 추가했다고 바로 사용할 수 있는게 아니라, 파일 시스템에 연결을 해 주어야 함.

즉, 특정 디렉토리와 추가한 디스크를 연결해준다고 이해하면 됨.

 

파티셔닝을 통해 1개의 물리적인 디스크를 2개 이상의 논리적인 블록 디바이스로 인식할 수 있음.(/dev/sdb1, /dev/sdb2, ...)

1개의 디스크 전체를 파티셔닝하지 않고 사용할 수도 있지만, 일반적으로 관리/확장성을 고려해 파티셔닝을 진행.

 

1. 추가 장착한 디스크 확인

명령어: lsblk

 

e.g) /dev/sdb 조회 확인

 

2. 파티셔닝

명령어: fdisk 또는 gdisk

fdisk {장치명}

 

e.g) fdisk /dev/sdb

입력 후 가이드에 커맨드를 입력하여 따라 파티션 조회/생성/수정/삭제 진행

 

자주 쓰는 파티셔닝 커맨드

  • p: 파티션 정보 출력
  • n: 새 파티션 생성
  • d: 파티션 삭제
  • t: 파티션 타입 변경
  • w: 저장 후 fdisk 종료
  • q: 저장 없이 fdisk 종료

 

3. 디스크 포멧(포멧타입 지정)

명령어: mkfs[ options] -t {파일시스템 타입} {장치명}

 

대표적인 filesystem 타입

  • ext4: ubuntu 배포판의 기본값
  • xfs: centos 배포판의 기본값
  • vfat: windows 와 호환됨
  • ntfs: windows 와 호환됨

 

참고

mkfs -t ext4 를 실행하면 실제로는 mkfs.ext4 로 동작함

mkfs -t xfs 를 실행하면 실제로는 mkfs.xfs 로 동작함

 

e.g) mkfs -t ext4 /dev/sdb1

실행하여 포멧을 지정하면 4Kib 크기의 블록들이 생성되고, 각각의 블록에는 index(inode) 가 붙어서 접근이 용이하게 된다.

blkid {장치명} 을 실행하면 파티션 id인 PARTUUID 이외에, 파일시스템상 id인 UUID 와 TYPE 정보도 출력된다.

 

4. 장치연결(mount)

디스크를 파일시스템의 특정 디렉토리에 연결하는 행위

명령어: mount {장치명} {마운트경로}

 

e.g) mount /dev/sdb1 /backup

 

mount 명령어를 인자 없이 실행하면 전체 마운트된 목록을 출력한다.

 

마운트 해제: umount {장치명 or 마운트경로}

 

5. 부팅시 자동마운트 되도록 설정

mount 설정파일인 /etc/fstab 파일에 설정

각 항목 설명

file system mount point type options dump fsck
장치명 or UUID 마운트 디렉토리 파일시스템 타입 마운트 옵션

defaults: rw, nouser, auto, exec, suid(일반적인 파일 시스템에 사용)
dump 명령어로 백업 허용 여부

0: 허용안함
1: 허용함
fsck 명령어로 부팅시 파일시스템 검사 여부

0: 검사안함
1: 1순위로 검사(root 파일 시스템)
2: 2순위로 검사(root 이외 파일 시스템)

 

e.g) /etc/fstab

# <file system> <mount point> <type> <options> <dump> <pass>
/dev/sdb1 /backup ext4 defaults 0 0

 

6. 자동마운트 설정 추가한 파일시스템을 마운트

명령어: mount -a

/etc/fstab 에 등록된 파일시스템 중 아직 마운트 안 된 파일시스템 전부 마운트 하는 명령어

블로그 이미지

망원동똑똑이

프로그래밍 지식을 자유롭게 모아두는 곳입니다.

,

1. 디스크 확인

리눅스 시스템에서 디스크는 블록 디바이스로 취급되며, 이를 확인하는 명령어. 

$ lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
vda    254:0    0  59.6G  0 disk
`-vda1 254:1    0  59.6G  0 part /etc/hosts
vdb    254:16   0   140M  1 disk
vdc    254:32   0 621.6M  1 disk

 

vda 블록 디바이스는 파티션이 vda1 하나로 이루어져 있음을 의미

vdb 블록 디바이스는 파티셔닝이 되어있지 않음을 의미

 

블록 디바이스(디스크) 이름 규칙

디스크 종류 디바이스 이름 규칙 파티션 이름 규칙 비고
플로피 디스크 /dev/fd0, /dev/fd1    
CDROM /dev/sr0, /dev/cdrom    
IDE 디스크 /dev/hda, /dev/hdb    
SCSI 디스크 /dev/sda, /dev/sdb /dev/sda1, /dev/sda2  
NVMe /dev/nvme0n1, /dev/nvme0n2 /dev/nvme0n1p1, /dev/nvme0n1p2 컨소시엄에서 SSD 전용으로 만든 표준

 

 

2. 블록 디바이스 id 확인

blkid

블록 디바이스의 uuid 와 파일 시스템 타입을 출력

 

 

 

블로그 이미지

망원동똑똑이

프로그래밍 지식을 자유롭게 모아두는 곳입니다.

,

1. 파티션 디스크 용량 확인

파티션 단위로 디스크 용량을 확인하는 명령어.

즉, 조회하려는 파일시스템이 속한 파티션에 대한 디스크 용량 정보를 나타낸다.

 

명령어: df [options] [디렉토리]

 

자주 쓰는 옵션

  • h: 용량을 읽기 좋은 형태로 출력(기본은 Kib)
  • T: 파일시스템 타입 포함
$ df -hT /

Filesystem     Type     Size  Used Avail Use% Mounted on
overlay        overlay   59G  4.4G   51G   8% /

 

 

속성 설명

  • Type: 파일시스템 타입
  • Size: 전체 용량
  • Used: 현재 사용중인 용량
  • Avail: 남은 용량
  • Use%: 현재 사용률
  • Mounted on: 마운트된 경로

2. 특정 디렉토리/파일 용량 확인

하위 디렉토리를 포함한 용량 확인.

 

명령어: du [options] 경로

 

자주 쓰는 옵션

  • h: 용량을 읽기 좋은 형태로 출력(기본은 Kib)
  • s: 요약(디렉토리의 경우 기본적으로 디렉토리 하위 파일이 따로 출력됨)
$ du -sh /home
68K	/home
블로그 이미지

망원동똑똑이

프로그래밍 지식을 자유롭게 모아두는 곳입니다.

,