[튜토리얼] Docker로 apt-mirror 미러서버를 구축해보자

결과 확인해보기: https://mirror.limenas.ml

미러 서버는 , 데비안 계열 리눅스에서(Debian, Ubuntu),
시스템에 설치할 수 있는 deb 패키지들을 가지고 있는 서버이며,
이 서버에 빠르게 접근할 수 있도록 서버를 통째로 복제해둔 로컬 서버입니다.

Raspberry PiJetson Nano와 같은 SBC(Single Board Computer)를 사용하다 보면, 같은 Ubuntu/Debian 계열 Linux임에도 불구하고, CPU 아키텍쳐가 ARM이라는 이유로 카카오에서 제공하는 빠른 미러서버를 사용하기 어려워집니다.(이 미러서버에는 ARM 아키텍쳐의 바이너리들을 미러링을 하지 않습니다!) 저는 주로 한국에서 가장 빠른 mirror.kakao.com를 주 미러 서버로 사용하는데, 위의 문제 때문에 카카오 미러서버는 PC나 워크스테이션에만 한정하여 사용합니다.

사실 ports.ubuntu.com 라는 곳에서, 우분투 (반)공식으로 비-인텔 CPU(ARM, ARM64, MIPS 등등)에서 사용할 수 있는 패키지를 배포하긴 합니다. 다만, 서버는 영국에 있어서 경우에 따라서는 매우 느려서 속이 터집니다(한국인).

개인적으로, 라즈베리파이와 Jetson Nano를 모두 사용하고 있고, 연구 목적으로도 사용하고 있어서, 미러 서버를 구축하게 되었습니다.

1단계: apt-mirror-downloader Docker 이미지를 만들어보자

이 튜토리얼에서는 도커를 이용해서, 미러를 수행하는 Downloader를 실행합니다. 아래 Dockerfile을 이용해서 도커 이미지를 생성할 수 있습니다.

Dockerfile이라는 이름(확장자 없음)의 파일을 생성하여, 아래 내용을 저장합니다.

FROM ubuntu:latest

RUN sed -i "s|archive.ubuntu.com|mirror.kakao.com|g" /etc/apt/sources.list &&\
    apt -qq update && apt -y --no-install-recommends -qq install wget curl git make ca-certificates &&\
    rm -rf /var/lib/apt/lists

RUN git clone https://github.com/Stifler6996/apt-mirror.git && cd apt-mirror &&\
    make install && cd .. && rm -rf apt-mirror

ENTRYPOINT apt-mirror

위 파일을 저장한 뒤, 아래 명령어를 실행하여 이미지를 빌드합니다 (물론 이미지 이름이나 태그는 원하는 것으로 변경하면 됩니다).

Ubuntu에서 패키지로 배포하는 apt-mirror의 경우 c-n-f(Content-Not-Found)나 dep11(Dependency 관련)과 같은 특수 태그를 지원하지 않습니다. 이 튜토리얼에서는, 해당 최신 태그를 지원하도록 패치한 apt-mirror 버전인 Stifler6996/apt-mirror를 사용하여 진행합니다.

docker build . -t jungin500/apt-mirror:arm64

이미지를 만들었다면, 이제 미러링 설정 파일을 생성해줍니다. 어떤 사이트를 미러링할지, 쓰레드 수는 얼마나 줄 것인지 등을 설정하는 과정입니다. mirror.list라는 파일을 새로 만들어, 아래 내용을 저장합니다.

####### config
#
set base_path    /var/spool/apt-mirror
#
#set mirror_path  $base_path/mirror
#set skel_path    $base_path/skel
#set var_path     $base_path/var
#set cleanscript $var_path/clean.sh
#set defaultarch  
#set postmirror_script $var_path/postmirror.sh
#set run_postmirror 0
set nthreads     20
#set _tilde 0
#
####### end config

# Begin Raspberry Pi (Debian 10) ARM32/ARM64 configuration
deb [arch=armhf,arm64] http://archive.raspberrypi.org/debian buster main
# deb-src http://archive.raspbian.org/debian buster main
# End Raspberry Pi (Debian 10) ARM32/ARM64 configuration

위쪽 config 파트에서는 디렉토리나 thread수를 결정할 수 있습니다. 이 뒤부터는 보통 사용하는 sources.list와 동일합니다. 다만, 아키텍쳐를 [arch=armhf,arm64] 지시어로 지정합니다. 여기서는 armhf(32비트 ARM Hard Float)와 arm64(64비트 ARM) 두 가지 아키텍쳐에 해당하는 패키지만 다운로드한다는 의미입니다.

이런 식으로, 추가로 mirror.kakao.com나 ftp.kr.debian.org 등의 미러링이 가능합니다. 사용하고 있는 배포판에서 /etc/apt/sources.list를 뜯어서, 그 내용을 그대로 이 파일의 맨 아래에 넣어주면 됩니다. 다만, 아키텍쳐는 기본이 amd64로 지정되므로 위 내용 [arch=armhf,arm64]와 같이 explicit하게 지정해줘야 합니다!

다음으로는 두 번째 설정 파일입니다. 이 스크립트는 미러링이 끝난 뒤 ls-lR.gz 파일을 생성합니다. apt-get으로 패키지 메타데이터를 다운로드하게 되는데, ls-lR.gz는 이 때 필요한 파일입니다. 아래 스크립트를 postmirror.sh 라는 파일로 저장합니다.

#!/bin/bash
# ls-lR Creator Postscript for apt-mirror
# LimeOrangePie [email protected]

MIRROR_ROOT=/var/spool/apt-mirror
cd $MIRROR_ROOT/mirror

IFS=$'\n'
MIRRORS=( $(ls -1) )

for mirror_item in "${MIRRORS[@]}"
do
    cd $MIRROR_ROOT/mirror/$mirror_item
    DISTRIBUTIONS=( $(ls -1) )

    for dist_name in "${DISTRIBUTIONS[@]}"
    do
        cd $MIRROR_ROOT/mirror/$mirror_item/$dist_name
        rm -f ls-lR.gz
        ls -lR > ls-lR
        gzip ls-lR
    done
done

위 두 파일을 준비했다면, 다음으로, 만든 이미지를 이용해서 미러링을 수행합니다. 미러링을 할 디렉토리는 300GB 이상의 여유 공간이 있는 것이 좋습니다. 4개 서버를 미러링했더니 500GB정도가 나오네요. STORAGE_PATH를 변경하여 미러링할 대상 폴더를 지정해주세요.

DOCKER_WORKDIR=pwd
STORAGE_PATH=/mirror-storage
docker run \
         -it \
         --name apt-mirror-downloader \
         -v $DOCKER_WORKDIR/mirror.list:/etc/apt/mirror.list:ro \
         -v $DOCKER_WORKDIR/postmirror.sh:/var/spool/apt-mirror/var/postmirror.sh:ro \
         -v $STORAGE_PATH:/var/spool/apt-mirror:rw \
         --entrypoint apt-mirror \
         --rm \
         jungin500/apt-mirror:arm64

미러링은 3시간에서, 길면 반나절까지 걸립니다. 백그라운드로 돌리려면 docker 명령어에 -d 플래그를 붙여두고 기다리시면 됩니다.

다음 게시물에서는 만든 미러서버를 제공(Serve)하는 방법을 소개해 드리겠습니다. 지금까지 미러링한 서버를 실제로 다른 사람들이 쓸 수 있도록 간단한 웹 서버를 만들어서 배포합니다.

[Tutorial] Building lastest raspberry pi kernel for 64-bit Ubuntu (20.10)

One of the great parts about running Ubuntu is that just about all the Ubuntu-isms you’ve learned for other platforms work here too. Start with these links:

https://wiki.ubuntu.com/Kernel/BuildYourOwnKernel
https://wiki.ubuntu.com/KernelTeam/ARMK … ossCompile
https://wiki.ubuntu.com/KernelTeam/Kern … k_failures
https://askubuntu.com/questions/500095/ … er-version
https://bugs.launchpad.net/ubuntu/+sour … ug/1701756

What follows isn’t very polished, since came out of my notebook verbatim. This is how I built the kernel.

First uncomment the relevant line int /etc/apt/sources.list:

deb-src http://ports.ubuntu.com/ubuntu-ports focal-updates main restricted

Update the package database:

apt update

Get the kernel source package, as root in some place where you want it. Alternatively replace $(uname -r) with the version you want. This is probably easiest to do on the target:

apt-get source linux-image-$(uname -r)

If this is on a target, copy it to a dev machine.

Over on the dev machine, hack up your kernel as you please. Then in debian.raspi/changelog, edit the first version number from something like this:

linux-raspi (5.4.0-1019.21) focal; urgency=medium

to something like this:

linux-raspi (5.4.0-1019.21+g34950~20200925) focal; urgency=medium

Note that CONFIG_LOCALVERSION will break the Ubuntu scripts, and EXTRAVERSION in the highest level makefile doesn’t do anything interesting.

Set some environment variables:

export $(dpkg-architecture -aarm64); export CROSS_COMPILE=aarch64-linux-gnu-

Now change into the root directory of the source tree and clean the build area:

fakeroot debian/rules clean

Kick off a menuconfig session with script:

fakeroot debian/rules editconfigs

menuconfig insists on running once each for 32 and 64 bit builds of kernel.

Now build the kernel and associated packages. We skip checks that are likely to break because of a changed list of modules:

fakeroot debian/rules binary skipmodule=true skipabi=true

This will result in the following .deb packages being created in the level ABOVE the kernel source tree:

linux-buildinfo-5.4.0-1019-raspi_5.4.0-1019.21+g34950~20200925_arm64.deb
linux-headers-5.4.0-1019-raspi_5.4.0-1019.21+g34950~20200925_arm64.deb
linux-image-5.4.0-1019-raspi_5.4.0-1019.21+g34950~20200925_arm64.deb
linux-modules-5.4.0-1019-raspi_5.4.0-1019.21+g34950~20200925_arm64.deb
linux-raspi-headers-5.4.0-1019_5.4.0-1019.21+g34950~20200925_arm64.deb

After copying to the target, each of the relevant packages may be installed there with dpkg:

dpkg -i linux-headers-5.4.0-1019-raspi_5.4.0-1019.21+g34950~20200925_arm64.deb
dpkg -i linux-image-5.4.0-1019-raspi_5.4.0-1019.21+g34950~20200925_arm64.deb
dpkg -i linux-modules-5.4.0-1019-raspi_5.4.0-1019.21+g34950~20200925_arm64.deb
dpkg -i linux-raspi-headers-5.4.0-1019_5.4.0-1019.21+g34950~20200925_arm64.deb

GitLab 13.5.X+ 업그레이드시 nginx socket 파일 관련 이슈 (502 Bad Gateway, No such file or directory)

GitLab Omnibus를 nginx와 함께 설치하여 사용하고 있었습니다. 13.5.X 버전 이상으로 업그레이드할 일이 있었는데, 어이없는 일이 발생했네요.

뜬금없는 502 오류.

NGINX를 웹서버로 사용중이고, 이 뒤에 Proxy 형식으로 서버를 운영중입니다. 업그레이드를 하자마자 이슈가 생겼네요. 찾아보니까 정말 어이없는 이유였습니다. 아래는 NGINX 설정파일입니다(보통의 설치와 동일한 내용으로 되어있습니다).

??????????

파일이 없답니다. 분명 gitlab-ctl start로 돌려놓았는데….
그래서 한번 찾아보니, 소켓 파일 위치가 변경되었다는 GitLab 이슈 글이 눈에 띄네요.

NGINX configuration의 내용을 아래처럼 바꿉니다.

# 기존 코드
upstream gitlab-workhorse {
    server unix:/var/opt/gitlab/gitlab-workhorse/socket fail_timeout=0;
}

# 변경 코드
upstream gitlab-workhorse {
    server unix:/var/opt/gitlab/gitlab-workhorse/sockets/socket fail_timeout=0;
}

간단히 socket 부분을 sockets/socket 으로 변경하면 문제없이 작동합니다.
정말로 Documentation이 중요한 부분인데 다행히 Issue에 내용이 있었군요…

[Tutorial] Installing OpenCV on Raspberry Pi 4B with Ubuntu 20.04

This guide will show how to install OpenCV 4.5.0 (latest) on Raspberry Pi 4B running Ubuntu Server 20.04, where architecture is ARM64 (aarch64) – which is unusal part.

but installing procedure never changes – thanks to CMake. We can build own library within Raspberry Pi with following tutorials.

OpenCV-aarch64

This is a guide to natively install OpenCV on aarch64/arm64 devices (Updated 2020-12-13, by @LimeOrangePie)

Pre-requisites

Your aarch64 device should have Ubuntu/Debian/Armbian OS flashed on it.

Steps

  1. Install dependencies
sudo apt-get install python3-dev python3-pip python3-numpy

sudo apt-get install build-essential cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev  libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libdc1394-22-dev protobuf-compiler libgflags-dev libgoogle-glog-dev libblas-dev libhdf5-serial-dev liblmdb-dev libleveldb-dev liblapack-dev libsnappy-dev libprotobuf-dev libopenblas-dev libgtk2.0-dev libboost-dev libboost-all-dev libeigen3-dev libatlas-base-dev libne10-10 libne10-dev

pip3 install neon

sudo apt-get install libneon27-dev

sudo apt-get install libneon27-gnutls-dev
  1. Download Source
cd ~/

git clone https://github.com/opencv/opencv.git -b 4.5.0 --single-branch

git clone https://github.com/opencv/opencv_contrib.git -b 4.5.0 --single-branch
  1. Configuring OpenCV using cmake:

Put your username in place of [username] below for the path to opencv_contrib/modules

mkdir opencv_build

cd opencv_build

cmake -D CMAKE_BUILD_TYPE=RELEASE -D ENABLE_NEON=ON -D ENABLE_TBB=ON -D ENABLE_IPP=ON -D ENABLE_VFVP3=ON -D WITH_OPENMP=ON -D WITH_CSTRIPES=ON -D WITH_OPENCL=ON -D CMAKE_INSTALL_PREFIX=/usr/local -D OPENCV_EXTRA_MODULES_PATH=../opencv_contrib/modules/ ../opencv
  1. Compilation:
make -j${nproc}

sudo make install
  1. Testing:
python3
>>import cv2
>>

Repository: https://github.com/jungin500/OpenCV-aarch64

Original Repository: https://github.com/huzz/OpenCV-aarch64

AMD Radeon 4500U 드라이버 업데이트 – 레노버 Thinkpad E15 Gen2 (Radeon Graphics 384SP)

르누아르 노트북의 GPU 드라이버를 최신으로 업데이트를 하고싶다면
이제는 가능합니다. 원래는 안됐었어요. 암튼 그럼.

최신 드라이버는 먹기 싫어요

최근, 쓰던 노트북이 맛가서 새로 Thinkpad E15 Gen2 노트북을 장만했습니다.
Lenovo 노트북은 각 디바이스 드라이버를 Lenovo 홈페이지나 “Lenovo Vantage”라는 Windows 10 App으로 통합 관리할 수 있게 되어있습니다.

르누아르 GPU가 나온지 얼마 되지 않았기에, Lenono에서 공식 제공하는 드라이버도 Release History 맨 끝에 초기 버전으로 나와 있더군요.

결국 공식 그래픽 드라이버를 설치하면, 구버전을 쓰게 된다는 결론입니다. 어림도 없지 어딜
그래서 최신 드라이버를 설치하기로 했습니다. 다만 이 같은일을 한달 전쯤에 이미 했었죠.
당시 결론은, “아직은 불안정하다”였습니다. 초기 Windows 부팅 시 드라이버 로드 시, TDR (Time Detection & Recovery) 관련 드라이버가 로드가 안되는 이슈였습니다. 그래서 부팅 시간이 짧게는 2분, 길게는 3분 이상도 딜레이가 되고 있었습니다. 노트북인데!! 노트북이라서 못봐줍니다!! 다만 달리 할 수 있는 일이 없었기에, 원래 버전으로 롤백했습니다. 그리고, 어제 또다시 시도를 해봤습니다.

결과: 대성공(?).

이번 2020년 11월 말에 출시한 Radeon Software 20.11.3 (2020-11-25)을, DDU를 하지 않고 기존 드라이버 위에 다시 설치해봤습니다. 어? 이번엔 이 이슈를 수정했나봅니다. 문제없이 빠른 부팅이 되고 있습니다.

아직 한 발 남았다

하지만, Lenovo사는 Windows Update에 자사의 공식 드라이버를 Release하고 있습니다. 이렇단 얘기는, 드라이버 버전이 구버전이거나 설치되어 있지 않다면, 자동으로 Windows Update가 공식 GPU 드라이버를 설치한다는 말이 됩니다. 좋은 기능이지만, 최신 버전의 드라이버 설치에도 불구하고 자동 업데이트 기능은 쉬지 않았습니다…. 최신 버전을 설치하고 난 뒤, Windows Update는 구버전으로 다시 롤백을 시도하고 있었습니다.

이제, Windows Update를 없애버릴 시간입니다 조금 손봐서, GPU 드라이버를 설치하지 않도록 해보겠습니다. Windows 10에서 설치할 업데이트중 일부를 무시할 수 있는데, MS사에서 제공한 공식 도구를 사용하면 됩니다.

주의할점이 있다면, 드라이버를 먼저 설치한 뒤에 Windows Update를 실행해 업데이트를 확인하고, GPU Driver를 설치할 것이라는 리스트가 뜨면 이를 일시 중지하고 진행해야 합니다. 진행할 업데이트가 없는데 이를 Block할 수는 없으므로, 조금 복잡한 위의 방법대로 하는게 탈이 없을것 같아 이렇게 진행했습니다. 아, Windows Update를 확인만 하고 리스트가 뜨면 바로 일시 중지해야 합니다. 그렇게 하지 않으면, 작업하던 중간에 구버전으로 드라이버가 다시 설치될지도…?

어쨌든, 다운로드 받은 프로그램 실행후 “Hide Updates”를 누르면 지금 진행하려는 GPU 업데이트 패키지가 리스트에 뜹니다. 제 기억상 Lenovo와 AMD라는 단어가 같이 들어가있었던것 같네요. 이를 체크하고 Hide합니다. 이렇게 하면 나중에도 GPU 업데이트는 되지 않습니다.

공식보다는 최신을 쓰고 싶은 분들을 위한 정리

  1. Radeon Software 20.11.3 이상을 다운로드한다.
  2. 기존 드라이버 위에 설치한다 (저는 초기화 진행했습니다)
  3. Windows Update 확인 버튼을 눌러준다.
  4. 확인이 끝나고 설치를 해버리기 전에 “7일 동안 업데이트 일시 중지”를 누른다.
  5. 위의 툴로 해당 드라이버를 숨긴다.
  6. Profit!

참고

[TEST] Tensorflow 2.4.0-rc0 on RTX 3000 series (3070/3080/3090)

Tensorflow on RTX 3000 series (RTX 3070, RTX 3080, RTX 3090)

빌드 환경 (Build environment)

OS: Windows 10 Education (Build 19042.608)
Architecture: x86_64 (amd64)
Git branch: v2.4.0-rc0
Python: 3.7 (anaconda)
Target CUDA and CUDNN: CUDA 11.1 Update 1, CUDNN v8.0.5 (Novemvber 9th, 2020) (requires login)
Target arch: CC 8.6, 6.1 → Must be also usable on GTX 1000 series!
Numpy: 1.19.4 (Must be manually reinstalled back to version 1.19.3 before using!)

사용법 (Usage)

  1. Requirements: CUDA 11.1 Update 1, CUDNN v8.0.5 (Novemvber 9th, 2020) (requires login)
  2. Download tensorflow-2.4.0rc0-cp37-cp37m-win_amd64.whl
  3. Install within CMD or Powershell cmdline (where pip3 is available)
  4. Install tensorflow : pip install tensorflow-2.4.0rc0-cp37-cp37m-win_amd64.whl
  5. (Optional) Install additional requirements
  6. (Required) Roll back numpy version to 1.19.3: pip install numpy==1.19.3
  7. (Maybe optional) cupti library filename mismatch – add “C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.1\extras\CUPTI\lib64” to PATH and copy “cupti64_2020.2.1.dll” to “cupti64.dll” or “cupti.dll”.

제한 사항 (Restriction, To-Dos)

  • Higher GPU usage might be restricted – use those code to resolve SOME of those problems:
# Memory Pre-configuration
config = tf.compat.v1.ConfigProto(
    gpu_options=tf.compat.v1.GPUOptions(
        per_process_gpu_memory_fraction=0.8,
        allow_growth = True
    )
    # device_count = {'GPU': 1}
)
session = tf.compat.v1.Session(config=config)
tf.compat.v1.keras.backend.set_session(session)
  • Closing application while tensorflow library loads always failes – might be a buggy codes?
  • another unknown restriction would exist – this is a test build for my own use, so use with care! I will edit this article when tensorflow officially supports RTX3000 series (or tested).

WSL2 CUDA – Insider Preview 버전별 Support Matrix

내가 쓰는 Windows 10 Insider Preview 기준으로 WSL2와 CUDA가 잘 되는 버전들을 업데이트하고 있다.
※ 최신 버전: Windows 10 Insider Preview 21H1 Build 20241.1000 (2020-10-21)

Build 21H1Release DateWSL2CUDA
202412020-10-21OO
202362020-10-16OO
202312020-10-07OX
202262020-09-30OX
202152020-09-23XX
202112020-09-16XX
202062020-09-09OO
202012020-08-26
201902020-08-12
201852020-08-05
201802020-07-29
201752020-07-22
201702020-07-15
201612020-07-01
201522020-06-24
201502020-06-17OO

참고자료