Linux에서 과거 패키지 설치는 소스코드를 받아서 직접 gcc/g++로 컴파일하는 형태로 많이 설치하였다. 그러다가 rpm(redhat package manager)이 등장해서 조금더 편하게 설치하게 된 것이 yum이나 apt같은 것이 등장하면서 더욱더 전체 의존성을 잘 따져주면서 자동으로 인터넷에서 패키지를 다운받아 설치하거나 제거해주는 등 발전되었다.
그런데 이 모든 것이 폐쇄망 혹은 인터넷이 단절된 망 하에 들어가면 무용지물이 되어 버린다. 그리고 이런 상황에서 많은 엔지니어들이 시행착오를 거친다. 여기서는 몇가지 지식으로 이런 상황을 쉽게 돌파할 수 있는 방법을 가이드해본다.
대략 redhat 7.2버전에서 시험되었지만 전체적인 방법은 크게 다르지 않다. 그리고 여기서는 yum을 중심으로 설명한다.
1) yum은 어떻게 패키지를 다운받을 repository를 인식하고 설정할까?
특정한 파일 폴더 구조나 웹사이트 폴더 구조를 갖추면 yum이 쓸 수 있는 rpm이 들어있는 repository로 작동할 수 있고, 이것들은 생각보다 손쉽게 제어될 수 있다.
아래 명령을 입력해보면 현재 등록된 repository id와 이름 등을 확인할 수 있다.
$ sudo yum repolist
그러면 이 repository는 어디에 등록되어 있을까? 바로 /etc/yum.repos.d/*.repo에 하나씩 기록되어 있다.
위 Docker CE Stable - x86_64 를 찾아보자 아래와 같다.
해당 설정파일의 첫번째 줄부터 특정 repository를 명시하고 이름(name), URL(baseurl), 활성화여부(enabled), 유효성체크여부(gpgcheck)와 키파일(gpgkey)를 살펴볼 수 있다. (한 파일안에 중복 개수의 repository 선언도 가능하다)
그러면 이 repo는 URL만 가능할까? 아니다. 특정 디렉토리 구조만 갖추면 특정 폴더에도 rpm을 갖추어놓고 repository로 만들 수 있다. 현재 디렉토리에 rpm파일 들이 있다고 가정해보면 아래와 같이 하면 된다.
$ mkdir /tmp/myrepo
$ cp *.rpm /tmp/myrepo/
$ createrepo --database /tmp/myrepo
$ cat > /etc/yum.repos.d/offline-myrepo.repo
[offline-myrepo]
name=CentOS-$releasever - My Repository
baseurl=file:///tmp/myrepo
enabled=1
gpgcheck=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
즉 rpm을 복사해놓고 나서 createrepo라는 프로그램을 구동하면 추가 정보를 생성하여 repository folder로 변화시켜주고, yum의 repository 설정에 위와 같이 추가해주면 local repository 하나가 추가되는 것이다. 다만, 여기서는 내가 신뢰하는 패키지를 다루므로 설정이 복잡할 수 있는 gpgcheck설정은 0으로 해두자(잘 아시는 분은 제보를 부탁드린다)
자 이렇게 방금 rpm을 가지고 local에 repository를 구성할 수 있는 방법을 알게되었다.
위와 같이 설정하고 다시
$ sudo yum repolist
를 하면 상기 설정한 offline-myrepo가 보이는 것을 알 수 있다
yum을 제어하는 몇가지 명령들이 있어서 등록한 repository를 skip하거나 gpgcheck를 skip하는 등 다양한 조절이 가능하다. 여러가지 상황에서 응용해보자
(다른 repository를 모두 disable하고, offline-myrepo만 활성화해서 설치하는 옵션)
$ yum --disablerepo=\* --enablerepo=offline-myrepo install nodejs
$ yum --disablerepo=\* --enablerepo=offline-myrepo install nginx --nogpgcheck
2) 이제 위 원리에 기초해 인터넷에 연결된 on-line 서버에서 패키지를 받고 폐쇄망 서버로 옮겨서 패키지를 설치해보자.
redhat공식 가이드에서는 os의 repository 설정 전체를 복사해서 on-line된 서버로 옮긴 후 설치해서 다시 offline 서버로 옮기는 형태의 가이드가 존재하는데 보통 번거로운 작업이 아니다. 따라서 아래의 방법을 추천한다. 패키지는 앞서 밝힌대로 yum으로 설치하는 것이 전체 패키지를 모두 자동으로 잘 설치해주면서 해당 정보가 보존된다. rpm같은 경우 순서를 맞추어 하나하나 설치 및 삭제해주어야 하는데, 엄두가 안나는 경우가 많다.
2.1) on-line된 동일한 os의 구성에서 필요한 rpm을 다운받는다.
redhat 7.2의 경우에는 amazon의 community market에 RHEL 7.2 201603 버전을 실행해서 기본 패키지와 extra package를 repository로 적절히 지정해서 다운받을 수 있다. 그리고 별도의 필요한 repository를 선택해서 추가 지정하면 내가 필요한 rpm을 다운받을 수 있는 준비가 된다.
알아둘 것은 redhat 7.2의 CD에 있는 기본 패키지들은 그냥 전부 복사할 각오를 해야 실제 다운받을 패키지가 적어진다. 사실은 기본패키지와 EPEL(extra pacakge for Enterpreise Linux)까지 포함하면 되는데 최소한 기본 패키지들은 복사할 각오를 하자. 여기서는 EPEL repository도 복사하지 못한다고 가정하고 진행하기는 한다.
어떤 패키지가 기본이고 어떤 패키지가 EPEL인가 헷갈리겠지만 조금 하다보면 구별이 간다. 이제 계속해보자.
여기서는 docker container CE edition을 설치하는 것을 예로 들어보자. repository도 추가해야 하고 rpm도 받기에는 좋은 샘플이라고 판단된다.
우선 rpm을 다운로드 받을 수 있도록 yum-utils를 설치하자. 제일 중요한 yum-downloader를 쓸 수 있게 된다.
$ sudo yum repolist
..
$ sudo yum install yum-utils
..
아래가 실제 실행화면이다.
자세히 보면 설치를 위해 7개의 패키지(rpm, python-urlgrabber, rpm-libs,..)를 다운로드 받고 이 패키지들은 rhui-REGION-rhel-server-release repository에서 받는다는 것을 알 수 있다. 이것들을 잘 기억하면 yumdownloader를 통해 어떤 패키지를 받아야 하는지 알 수 있으니 필요한 패키지를 설치할때는 이를 잘 봐두자.
(사실은 yum install도 --downloadonly 옵션으로 패키지를 받을 수 있으나 잘 되지 않을때가 종종 있다. yumdownloader훨씬 더 직관적으로 패키지를 받을 수 있다)
시험삼아 createrepo패키지를 받아보자. (createrepo도 나중에 offline 서버에서 구동이 필요하다)
$ sudo yumdownloader createrepo
Loaded plugins: amazon-id, rhui-lb
createrepo-0.9.9-28.el7.noarch.rpm
$ ls -al *.rpm
-rw-r--r--. 1 root root 95888 Dec 6 2018 createrepo-0.9.9-28.el7.noarch.rpm
자 이제 무슨 패키지든 어떤 패키지가 필요한 지 알 수 있고 받을 수도 있게 되었다.
이제 실제 docker-ce를 설치하기 위한 rpm을 받아보자. 우선 docker-ce 설치에 필요한 repository를 설정한다.
$ sudo yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
$ sudo yum install -y http://mirror.centos.org/centos/7/extras/x86_64/Packages/container-selinux-2.107-3.el7.noarch.rpm
EPEL repository와 container-selinux가 추가되었다. EPEL에는 redhat 기본 패키지외에 많은 패키지가 들어있다.
그리고 곧바로 docker-ce repository를 아래와 같이 추가하자. 이 명령어들은 모두 아까 보았던 /etc/yum.repos.d/에 repository 설정 파일들을 생성하게 된다.
$ sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
그리고 최종 잘되었는지 확인한다.
$ sudo yum repolist
그리고 이제 docker-ce를 설치하면서 대체 어떤 패키지들을 받는지 살펴보자.
아까 전에 봤던 것처럼 rhui-REGION-rhel-server-release 기본 repository가 아닌 EPEL이나 docker repository에서 받는 파일은 모두 확인했다가 yumdownloader로 모두 받는다.
$ sudo yum install docker-ce
.....
$ mkdir /tmp/myrepo
$ cd /tmp/myrepo
$ sudo yumdownloader containerd.io #docker-ce설치시 download받은 패키지들..
$ sudo yumdownloader container-selinux #docker-ce설치시 download받은 패키지들..
....
$ tar cvfz all.tgz *.rpm
미리 가지고 있는 기본 패키지 말고 EPEL, docker-ce 같은 외부 repository에 있는 것만 위 yumdownloader로 받는다.
(yumdownloader --resolve옵션으로 dependency전체를 받을 수 있다고 하는데, 불필요한 중복파일을 받기 싫어서 위와 같이 진행했다.)
참고로 미리 이야기했던 yum install을 통해서도 이 패키지를 다운로드 받을 수 있는 명령이 존재한다. installroot를 통해 완전히 caching없이 모든 rpm을 받을 수 있도록 하고 실행하면 모든 dependency rpm을 받을 수 있다고 알려져있으나 본인의 경우에는 aws repository 문제인지 종종 잘 작동하지 않았다. 다만 버전차이 등으로 인할 수 있으니 시도해보기를 바란다.
$ mkdir /tmp/myrepo_root
$ sudo yum install --installroot=/tmp/myrepo_root --downloadonly --downloaddir=/tmp/myrepo/ [패키지명]
2.2) off-line 폐쇄망 서버로 위 all.tgz를 옮겨서 복사하고 이를 local repository로 만든 후 설치해보자.
우선 기본 패키지 파일들을 맨 처음 local repositry 구성하는 가이드를 따라서 구성한다. 역시 rpm을 복사한 후에 실행하면 되며 이후 아래 다운로드 받은 rpm으로 추가로 local repository를 구성한다. 사실 동일한 과정의 반복이다.
기본패키지에 있는 createrepo는 초기 셋팅시에 설치해둘 필요가 있다.
$ mkdir /tmp/myrepoadd
$ cd /tmp/myrepoadd
$ tar xvfz all.tgz
$ createrepo --database /tmp/myrepoadd
$ cat > /etc/yum.repos.d/offline-myrepoadd.repo
[offline-myrepoadd]
name=CentOS-$releasever - My Docker Repository
baseurl=file:///tmp/myrepoadd
enabled=1
gpgcheck=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
자 이렇게 하면 이제 한번 repository정상유무를 확인해주자. 아무도 오류도 없어야 한다
$ sudo yum repolist
자 이제 설치를 할 시간이다. 기본 패키지들에 대한 repository를 역시 잘 구성되었다면 위 추가된 패키지들과 연계되어 제대로 잘 설치가 되어야 정상이다.
간단하게 on-line 서버에서 패키지의 rpm들을 다운로드 받고 이를 옮겨서 local repository를 구성한 후 설치하는 방법을 알아보았다. 참고로 내가 가진 현재 repository 상태에서 설치할 수 있는 모든 패키지는 아래 명령으로 확인가능하다. 문제가 있을시 확인을 해보도록 한다.
$ sudo yum list
'IT 실무 (환경구성)' 카테고리의 다른 글
python 보안환경에서 구동하기, 인증서 문제(SSL_CERTIFICATE_VERIFY_FAILED)를 겪고 계신가요? (2) | 2023.10.07 |
---|---|
Python package를 폐쇄망에 설치하기 (pip3) (4) | 2021.01.05 |
서버 인증서 설치의 내부 메카니즘/원리, 폐쇄망 엔지니어를 위한 글 (5) | 2020.12.27 |