리눅스 - 패키지 매니저 / ubuntu apt!? update vs upgrade, remove 등 활용법

정현우·2024년 1월 7일
4

Linux Basic to Advanced

목록 보기
15/16
post-thumbnail
post-custom-banner

[ 글의 목적: 리눅스에서 패키지 매니저의 필요한 이유와 패키지 매니저의 활용, ubuntu apt 에 대한 기록 ]

Package Manager

개발을 하면서 무엇인가를 "설치" 할 때 apt(ubuntu), pip(python), npm(node), brew(mac), yam(centos) ... 등의 명령어(cli)를 사용한 경험이 있을 것이다. 이는 모두 "패키지" 라는 것을 "설치" 할 때 사용하는데 왜 이런 패키지 매니저들이 필요할까?

1. 리눅스 패키지 매니저(Package Manager)

1) 왜 필요할까?

  • 개발 생태계는 생각보다 서로가 서로를 엄청나게 참조한다. A라는 패키지는 순수하게 다른 패키지를 참조하지 않는 것 같지만, 무수히 많은 사전 패키지를 참조한다. 우린 모두 거인의 어깨위에 있다

  • 16년도 NPM의 11줄 코드 사건이 있다. 사소한 수정에도 이렇게 무수히 많은 패키지, 실제로 "운영 환경 까지" 영향을 줄 수 있다. 그리고 colors.js와 faker.js 사태가 준 교훈 글에서 볼 수 있는 재미있는 사례도 있다.

  • 이런 패키지 간에 서로 필요한 관계를 의존성(dependency)라고 하는데, 패키지 매니저는 이러한 의존성 관계 시스템이라고 볼 수 있다. 일종의 앱스토어라고 볼 수 있다.

  • 패키지 매니저의 근본적인 목표는 해당 패키지가 정상적으로 작동하기 위해 필요한 다른 패키지를 자동으로 찾아주는 것 이다.

  • 그에 따라 패키지 "업데이트 관리가 용이"하고, "구버전 패키지는 자동으로 삭제"되어, "버전을 충돌없이 깔끔하게 유지"할 수 있다.

2) 간단한 작동 원리

  • 아주 러프하게, 거시적으로 표현한 다양한 패키지 매니저들의 기본 동작 원리다.
  1. 설치 / 업데이트 / 삭제 명령어로 요청하고
  2. 패키지 매니저가 해당 명령(요청)을 받아
  3. 디펜던시(의존성) 체크를 하고, - 해당 부분이 종류마다 동작은 모두 달라진다.
  4. 저장소로 부터 모두 download 요청 (파일 요청)을 하고
  5. 해당 명령(요청)을 마무리 하는 것
  • 그리고 실제 원격 저장소에 접근하기 때문에 네트워크 통신과 "보안" 과 밀접한 관계도 있다. 패키지들을 설치하기 전에 디지털 서명 검증 (ssl 인증서 등)을 활용한다.

원격 저장소가 어디에 존재할까?

  • 우선 Ubuntu로 예시를 들자면 /etc/apt/sources.list어떤 원격 저장소를 찾는지 나와있다.
cat /etc/apt/sources.list
# See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to
# newer versions of the distribution.
deb http://us.archive.ubuntu.com/ubuntu focal main restricted
# deb-src http://us.archive.ubuntu.com/ubuntu bionic main restricted

## Major bug fix updates produced after the final release of the
## distribution.
deb http://us.archive.ubuntu.com/ubuntu focal-updates main restricted
# deb-src http://us.archive.ubuntu.com/ubuntu bionic-updates main restricted

## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu
## team. Also, please note that software in universe WILL NOT receive any
## review or updates from the Ubuntu security team.
deb http://us.archive.ubuntu.com/ubuntu focal universe
# deb-src http://us.archive.ubuntu.com/ubuntu bionic universe
deb http://us.archive.ubuntu.com/ubuntu focal-updates universe
# deb-src http://us.archive.ubuntu.com/ubuntu bionic-updates universe

... 생략 ...
  • python의 pip는 https://pypi.org/, 즉 Python Package Index(PyPI) 라는 곳에 있으며 node의 npm은 https://www.npmjs.com/, npm registry를 기본 저장소로 본다.

  • 오픈 소스의 활발한 생태계 유지를 위해서는 이런 패키지 원격 저장소 & 패키지 관리자가 필수적으로 따라온다.

의존성 해결은 어떻게 할까?

  • 엄청 다양한 방법과 접근방법이 존재한다. 어떻게 해결을 하느냐에 따라 기존 패키지 매니저를 대체할 정도로 강력해지기도 한다. 속도도 중요한 평가지표 중 하나다.

  • 가장 간단한 접근 방법은 아래와 같이 서로의 의존성을 제귀적으로 확인하는 방법 이다. "API" 라는 패키지 설치를 위해 다른 패키지를 설치하고, 그 다른 패키지를 설치하기 위해 (의존성 해결을 위해) 또 다른 패키지를 찾는 것이다.

# 예시 의존성 데이터
dependencies = {
    "API": ["AuthLib", "Requests", "Logger"],
    "AuthLib": ["Crypto", "Logger"],
    "Requests": ["Logger", "NetworkUtils"],
    "Logger": [],
    "Crypto": [],
    "NetworkUtils": []
}

# 의존성 해결 함수
def resolve_dependencies(package, resolved, unresolved):
    """ 재귀적으로 의존성을 해결하는 함수 """
    unresolved.append(package)
    for dep in dependencies[package]:
        if dep not in resolved:
            if dep in unresolved:
                raise Exception("Circular dependency detected: {}".format(dep))
            resolve_dependencies(dep, resolved, unresolved)
    resolved.append(package)
    unresolved.remove(package)

# 주어진 패키지의 의존성 해결
package_to_install = "API"
resolved_dependencies = []
resolve_dependencies(package_to_install, resolved_dependencies, [])

print("Installation Order:", resolved_dependencies)

2. ubuntu apt

1) Advanced Package Tool

  • apt 는 "데비안 기반 시스템"의 공식 패키지 매니저다. dpkg 라는 근본 패키지 매니저를 기반으로 구축되었다.

  • dpkg 는 Debian Package 의 약자이며 확장자가 .deb 로 끝나는 데비안 패키지를 설치, 삭제 등을 하기 위해 사용한다. deb 파일의 형식은 패키지 이름__버전 - 개정번호__아키텍처.deb 을 따르며, 상세한 내용은 아래 사진과 같다.

  • 이런 초기 버전의 dpkg 는 의존성 관리를 설치하는 사용자(개발자)가 직접 해결해야 했다. 그래서 apt 가 만들어졌다.
  • 위에서 살펴보았듯이 /etc/apt/sources.list 에서 어떤 원격 저장소를 찾는지 저장되어 있다.

2) apt sources.list, 원격 저장소 설명

  1. deb: 사전에 컴파일된 바이너리 패키지 .deb 파일 저장소를 사용하겠다는 의미이다.

  2. deb-src: 패키지 원본소스, Debian control(.dsc), 변경사하이 포함된 diff.gz 파일이 존재하는 저장소를 사용하겠다는 의미이다.

  3. focal, bionic: 이들은 Ubuntu의 버전 코드명이다. Ubuntu는 각 릴리스마다 고유의 코드명을 가지는데, 여기서 focal은 Ubuntu 20.04 LTS를, bionic은 Ubuntu 18.04 LTS를 가리킵니다.

  4. -updates: 이 저장소는 안정된 릴리스 이후에 발생하는 주요 버그 수정 및 소규모 업데이트를 포함한다. 이는 기존 소프트웨어의 안정성을 유지하면서 필요한 수정사항을 제공한다.

  5. -backports: 여기에는 더 최신 버전의 Ubuntu에서 사용 가능한 소프트웨어의 백포트(이전 버전으로의 이식) 버전이 포함된다. 이 저장소의 소프트웨어는 기본 저장소보다 새롭지만, Ubuntu 보안 팀에 의해 검토나 업데이트가 이루어지지 않을 수 있다.

  6. Main : 표준으로 제공된 무료 오픈소스 소프트웨어 의미한다.

  7. Restricted : 공식적으로 지원되지만, 저작권이나 법적 제한으로 인해 제한된 소프트웨어이다.

  8. Universe 커뮤니티들에 의해 유지되고 지원되는 오픈소스 소프트웨어를 의미한다.

  9. Multiverse : 공식적으로 지원되지 않는 사유 소프트웨어를 의미한다.(Adobe Flash)

3) "update" vs "upgrade"

  • 사실은 이 글을 쓰게된 이유다 ㅎ

apt update

  • apt update 명령은 시스템의 패키지 목록을 최신 상태로 업데이트한다.

  • 이 과정에서 APT는 /etc/apt/sources.list 파일과 /etc/apt/sources.list.d/ 디렉토리에 정의된 저장소의 목록을 사용하여 사용 가능한 패키지와 그들의 최신 버전 정보를 다운로드 한다.

  • 이 명령은 실제로 설치된 패키지들을 업데이트하지 않는다. 대신, 이용 가능한 패키지들의 새로운 버전이 있는지를 파악하고, 시스템이 다음 단계인 upgrade 명령을 통해 실제 업데이트를 수행할 수 있도록 준비한다.

  • 즉, apt update는 "패키지 목록"을 업데이트하며, 실제 패키지의 업데이트는 수행하지 않는다.

apt upgrade

  • apt upgrade 명령은 시스템에 설치된 패키지들을 최신 버전으로 업그레이드한다.

  • apt update최신화된 패키지 목록을 기반으로, 새로운 버전이 있는 패키지들을 찾아 설치 한다. 그리고 패키지 업그레이드는 "기존 시스템에 설치된 패키지들의 업데이트" 만 집중한다.

  • upgrade는 시스템의 안정성을 해치지 않는 범위 내에서 패키지들을 업데이트한다. 의존성 문제나 중요한 시스템 변경이 필요한 경우, 해당 패키지는 업그레이드되지 않을 수 있다!

apt update 를 먼저 실행하여 패키지 목록을 최신 상태로 만든 후, apt upgrade 를 실행하여 실제 패키지들을 업데이트하는 것이 일반적인 절차이다.

sudo apt update
sudo apt upgrade
sudo apt autoremove

4) remove, purge, autoremove

  • A - 설치하고자 하는 패키지, B - A 설치를 위한 의존성 관계로 설치 된 패키지 라고 하고 사용법은 아래와 같다.

apt remove

  • 패키지는 삭제하지만 환경설정은 삭제하지 않음
  • apt remove A: A 패키지만 삭제하고, A 패키지의 설정 값 및 B 패키지는 유지

apt purge

  • 패키지와 해당 패키지의 환경설정 값을 모두 삭제
  • apt purge A: A 패키지와 설정값을 삭제하고, B 패키지는 유지

apt autoremove

  • 다른 패키지의 의존성 때문에 설치 되었지만 지금은 사용하지 않는 패키지 삭제
  • apt autoremove A: A 패키지와 설정값을 삭제하고, A 패키지 의존성에 의해 설치 된 B 패키지도 삭제, B 패키지가 사용 중일 경우는 삭제하지 않음.

5) apt vs apt-get

  • apt 는 오래된 apt-get 를 확장하면서 대체하는 신규 패키지 매니저라고 보면 된다.

  • 지금의 apt는 Debian 기반 Linux 배포의 기본 패키지 관리 유틸리티이며 apt-get과 apt-cache 모두를 대체한다. 대부분의 apt-get 명령은 새로운 각 apt 명령에서 동일하게 작성 가능하다.


출처

profile
도메인 중심의 개발, 깊이의 가치를 이해하고 “문제 해결” 에 몰두하는 개발자가 되고싶습니다. 그러기 위해 항상 새로운 것에 도전하고 노력하는 개발자가 되고 싶습니다!
post-custom-banner

0개의 댓글