운영 중 반복해서 찾게 되는 짧은 명령과 판단 기준을 주제별로 모았다. 각 절은 독립적이며, RHEL 8 계열을 기준으로 확인한 것이다.
grep -rin "error" ./logs # 재귀·대소문자 무시·줄번호
grep -rEn "[0-9]+(\.[0-9]+)?[[:space:]]?G[BI]" 대상 # 10GB, 1.5GB, 500 GI 같은 용량 표기
grep -B 5 "찾을문자열" app.log # 매칭 줄 위 5줄 (-A 아래, -C 위아래)
tail -f app.log | grep -B 5 "ERROR"
-w 는 단어 단위 일치, -l 은 파일명만, -c 는 건수만, -v 는 반전이다. 매칭이 여러 곳이면 -- 구분선으로 나뉜다.
cp 에는 제외 옵션이 없다. 셸 글롭 * 가 . 으로 시작하는 항목을 건너뛰는 성질을 이용하거나, 하위 디렉터리까지 빼려면 rsync 를 쓴다.
cp -r /src/* /dst/ # 최상위 숨김 파일만 제외
rsync -av --exclude='.*' /src/ /dst/ # 하위 디렉터리의 숨김 파일까지 제외
shopt dotglob # on 이면 * 가 숨김 파일도 잡으므로 확인
dnf install bind-utils
dnf localinstall bind-utils-*.rpm # 폐쇄망이면 RPM 직접 설치
nmap -p 22 192.168.1.0/24
sudo nmap -p 22 -sS --open -oG - 192.168.1.0/24 # SYN 스캔, 열린 호스트만, grep 친화 출력
sudo nmap -p 22 -sS -sV --open 192.168.1.0/24 # SSH 서버 버전까지
root 권한이 없으면 -sS 대신 -sT 를 쓴다. 허가된 대역에서만 실행하고 결과를 외부에 남기지 않는다. /26 은 64개 주소 블록이므로 192.168.0.130/26 의 사용 가능 범위는 192.168.0.129 ~ 192.168.0.190 (네트워크 .128, 브로드캐스트 .191) 이다.
curl -u 'user:${PASSWORD}' https://example.com/api # Basic 인증, 특수문자는 작은따옴표
curl -u user https://example.com/api # 비밀번호를 프롬프트로 입력 (히스토리에 남지 않음)
curl -n https://example.com/api # ~/.netrc (chmod 600) 사용
curl --digest -u user https://example.com/api # --ntlm, --negotiate(Kerberos), --anyauth
Basic 인증은 Base64 인코딩일 뿐이므로 HTTPS 에서만 쓴다. curl -v 출력에는 Authorization 헤더가 그대로 찍히므로 공유 전에 가린다.
wget -c http://server/path/file # 이어받기
curl -C - -O http://server/path/file
wget -r -np -nH --cut-dirs=1 http://server/dir/ # 디렉터리 리스팅이 켜져 있을 때
받은 파일이 file 명령에서 HTML document 로 나오거나 head -c 300 에 <html> 이 보이면 403/404 오류 페이지를 받은 것이다. 이미지 로드 스크립트에서 checksum does not match 가 나는 원인이 대개 이것이다. httpd 쪽에서는 namei -l <경로> 로 권한을 단계별로 확인하고, 심볼릭 링크는 Options +FollowSymLinks 와 원본 파일 권한, /var/www/html 밖의 경로는 SELinux 컨텍스트(chcon -R -t httpd_sys_content_t) 를 본다.
lscpu; nproc; cat /proc/cpuinfo
free -h; cat /proc/meminfo; vmstat 1 5
top; htop
dmidecode -t memory; dmidecode -t processor
top 의 load average 는 논리 코어 수와 비교해서 판단한다. 72 코어 서버에서 9.2 는 13% 수준이며, wa 가 높고 kswapd 가 상위에 보이면 CPU 가 아니라 I/O 대기이므로 iostat -x 1, numastat -m 으로 확인한다. free 의 free 값이 낮아도 available 이 충분하면 캐시가 잡고 있는 것이다. Swap 이 0 이면 OOM 시 프로세스가 바로 죽는다.
cat /proc/sys/fs/file-nr; sysctl fs.file-max # 시스템 전체
cat /proc/<PID>/limits | grep -i "open files"; ls /proc/<PID>/fd | wc -l
ls -l /proc/<PID>/fd | awk '{print $NF}' | sed 's/[0-9]*$//' | sort | uniq -c | sort -rn | head
ss -tan state close-wait | wc -l # 앱이 close() 를 안 한 커넥션
dmesg -T | grep -iE "too many open files|VFS: file-max"
socket: 이 대부분이면 커넥션 누수, deleted 가 많으면 삭제된 로그 파일을 물고 있는 것이다. systemd 로 뜨는 서비스는 /etc/security/limits.conf 가 적용되지 않으므로 systemctl edit <svc> 로 [Service] LimitNOFILE=65535 를 넣고 daemon-reload 후 재시작한다. 한도 상향은 응급조치이며 CLOSE_WAIT 누적은 앱 쪽 원인이다.
tmux ls
tmux attach -t 세션명
tmux ls -F '#{session_name}: #{session_windows}창, 생성 #{t:session_created}'
세션 안에서는 Ctrl+b 뒤 s 로 세션 목록을 띄워 전환한다.
kubectl get pod db-0 -n <ns> -o jsonpath='{.spec.containers[*].name}'
kubectl exec -it db-0 -n <ns> -c db -- /bin/bash
kubectl exec -it db-0 -n <ns> -c db -- psql -U sense sense
-c 뒤에는 컨테이너 이름이 와야 하며, 기본 컨테이너(예: fluent-bit 사이드카)에는 bash 가 없는 경우가 많다. 컨테이너 안에서 psql 이 local user with ID 999 does not exist 를 내면 -U 로 DB 사용자를 명시한다. Cloudera AI 의 내부 DB 는 사용자와 DB 이름이 sense 이다.
레지스트리 주소를 바꾸는 정도라면 jq 없이 편집해도 된다. 한 줄로 뭉친 파일은 jq . in.json > pretty.json 으로 먼저 펴고, 치환 후 grep -c image_identifier 로 건수를 대조한다.
sed -E 's#(container\.repository\.cloudera\.com|docker\.repository\.cloudera\.com)#registry.airgap.example.com#g' in.json > out.json
vi 안에서는 :%s#원본호스트#새호스트#g 를 쓴다. 이미지마다 이름과 태그가 다르면 전체 값을 덮어쓰지 말고 호스트 부분만 바꾼다.
docker inspect--format=... 처럼 inspect 와 --format 사이 공백이 빠지면 unrecognized command 가 난다. 로컬에서 build 만 한 이미지는 RepoDigests 가 비어 있으므로 조건 처리한다.
docker inspect --format='{{if .RepoDigests}}{{index .RepoDigests 0}}{{else}}<no-digest>{{end}}' "${SOURCE_IMAGE}"
touch /etc/containers/nodocker # Emulate Docker CLI 안내 메시지 제거
/etc/os-release 로는 알 수 없다. 설치 시 고른 환경 그룹을 본다.
dnf group list installed | grep -i -E "workstation|server with gui"
systemctl get-default # graphical.target 이면 GUI 부팅
rpm -q gnome-shell gdm
systemctl set-default graphical.target && systemctl isolate graphical.target
GUI 화면은 IPMI 외에도 tigervnc-server(SSH 터널 권장), XRDP(EPEL 필요, 3389/tcp), 개별 앱은 ssh -X, 관리 용도는 Cockpit(9090) 으로 볼 수 있다.
Ozone 버킷 아래 S3 키 이름에 콜론(:) 은 대개 생성되지만 URL 인코딩(%3A) 처리가 클라이언트마다 달라 권장하지 않는다. 버킷 이름은 소문자·숫자·점·하이픈만 허용된다. Cloudera AI Registry 는 특정 버킷 레이아웃을 요구하지 않으나, S3 API 만 쓰므로 새로 만든다면 OBS 레이아웃이 안전하다. 기본 레이아웃 설정이 비어 있으면 FSO 로 생성되므로 ozone sh bucket info 로 확인한다.