2019년 4월 5일 금요일

사람 헷갈리게 만드는 conda 환경 설정

Conda의 공식 문서 사이트의 사용자 가이드와 Anaconda 웹사이트의 Conda 4.6 Release 문서가 미묘하게 달라서 혼동을 유발하고 있다. conda init 명령이 바로 그것이다. 공식 문서 사이트에는 이에 대한 언급이 거의 없다.

Anaconda를 설치할 때, 로그인 스크립트에 conda 환경을 만들어 주는 코드(설치 디렉토리 하위의 /etc/profile.d/conda.sh)를 삽입할 것인지를 묻는다. 그렇지 않은 경우에는 PATH 환경변수의 맨 앞에 anaconda의 bin 디렉토리를 추가하라고 지시한다.
[참고] conda.sh를 로그인 스크립트에서 시동하면 잘 되지만, 명령행에서 source (PATH)/conda.sh를 쳐서 실행하면 잘 되지 않는다. 그러한 경우 environment 이름 없이 그냥 conda activate라고만 치면 된다(How do I activate a conda environment in my .bashrc?).
그런데 몇 가지 environment와 프로그램을 업데이트하고 conda 자체도 업데이트하였더니, 어느 순간에서부터 conda init SHELL_NAME을 실행하라는 메시지가 나오는 것이다. 이는 Anaconda의 Conda 4.6 Release의 맨 앞에 잘 설명이 되어 있다. 이 명령을 실행하면 .bashrc의 뒷부분에 다음과 같은 짤막한 코드를 삽입하게 된다.

# >>> conda initialize >>>
# !! Contents within this block are managed by 'conda init' !!
__conda_setup="$('/opt/anaconda3/bin/conda' 'shell.bash' 'hook' 2> /dev/null)"
if [ $? -eq 0 ]; then
    eval "$__conda_setup"
else
    if [ -f "/opt/anaconda3/etc/profile.d/conda.sh" ]; then
        . "/opt/anaconda3/etc/profile.d/conda.sh"
    else
        export PATH="/opt/anaconda3/bin:$PATH"
    fi
fi
unset __conda_setup
# <<< conda initialize <<<

또 다른 문제는 .condarc 설정 파일에 관한 문제이다. Conda 공식 문서를 보면 conda config 명령을 처음 실행할 때 홈 디렉토리에 이 파일이 생성되며, root environment에 있는 .condarc는 홈 디렉토리의 것에 우선하여 작동한다고 하였다.

The conda configuration file, .condarc, is an optional runtime configuration file that allows advanced users to configure various aspects of conda, such as which channels it searches for packages, proxy settings and environment directories.
The .condarc file is not included by default, but it is automatically created in your home directory the first time you run the conda config command.
.condarc file may also be located in the root environment, in which case it overrides any in the home directory.
anaconda2에서는 여기에 소개한 그대로 잘 작동하는 것 같았다. 그런데 anaconda3를 설치하고 몇 가지 작업을 하였더니 또 어느 순간부터는(아마도 conda 자체를 업데이트한 다음이 아닐까?) root environment에 무엇이 있든 상관이 없이 홈 디렉토리의 .condarc가 적용되는 것이다. 여기에서 root environment란  conda를 설치한 최상위 디렉토리를 의미한다. 즉 설치 과정에서 PREFIX=/opt/anaconda2로 정의되는 위치이다. <= 밑줄을 친 부분은 나중에 확인해보기 바란다. conda 버전에 따라서도 약간 다른 것 같다.

혹시 착각이 아니었을까? 확인을 위하여 anaconda2로 들어간 다음, anaconda 설치 root environment의 .condarc 파일을 수정하였다. 그러고나서 conda config --show를 했더니 바뀐 내용이 출력된다. 그런데 최신 (ana)conda에서는 오로지 홈 디렉토리에 있는 .condarc가 최우선이다.

Root environment라는 용어도 약간의 혼동을 초래한다. 이것은 conda를 설치하는 디렉토리를 말하는가, 혹은 conda create -n MYENV라고 실행하여 만들어내는 environment 부류 중에서 가장 기본이 되는 환경을 의미하는가? 후자에서 '기본 환경'이라 함은 최초로 conda create -n을 실행하기 전, 처음으로 anaconda를 설치했을 때의 환경을 말한다. Conda의 어떤 버전 문서에서는 root environment라고 부르다가, 최근 문서에서는 base environment라고 불리는 것 같다.

별 일이 아니라 생각했었는데 의외로 고려할 사항이 많다.

2019년 4월 7일 업데이트

Conda 공식 문서의 Troubleshooting 섹션에 SSL connection errors[1]에 대처하는 방법이 나온다. 이는 지난 며칠 동안 나를 괴롭혔던 문제(SSL과 관련한 conda 설치 에러)에 대한 직접적인 해결책이기도 하다. 내가 접한 에러 메시지를 그대로 복사하여 구글에서 검색을 하였을 때 이 페이지가 나오지 않았기 때문에 해결책을 알아내느라 고생을 한 것이다. 다음은 [1]에서 인용한 것이다. System-wide configuration file인 .condarc는 위에서 인용한 것과 같이 root environment에 있는 것인가?

When using conda config, the user's conda configuration file at ~/.condarc is used by default. The flag --system will instead write to the system configuration file for all users at /.condarc. The flag --env will instead write to the active conda environment's configuration file at/.condarc. If --env is used and no environment is active, the user configuration file is used.

2019년 4월 4일 목요일

13,495원을 내고 SSL 인증서를 구입하다

Hostinger에서 호스팅하는 내 위키 사이트를 더욱 안전하게 이용하기 위해 SSL 인증서(Lifetime SSL - Let's encrypt)를 구입하여 설치하였다. 한번 13,495원을 지불하고 평생 유지된다고 하니 투자해서 아까울 것은 없다.

실제 위키 사이트는 genoglobe.kr의 서브도메인에 있다.

이 사이트는 꽤 많은 정보를 계속하여 기록함은 물론 로그인 정보를 보내야 하기 때문에 SSL 인증서를 설치하여 https://로 시작하는 주소로 접속하게 하는 것이 매우 바람직하다. 그러나 나의 공식 홈페이지에 해당하는 http://genoglobe.com/은 로그인 기능이 없고 포함하는 정보도 매우 적으므로 그대로 두기로 하였다. 이 사이트에는 나에게 이메일을 보내는 폼이 있지만 설마 누가 여기에다가 국가 기밀이나 영업 기밀을 적어서 보내겠는가?

아직 남은 과제는 http://로 내 위키 사이트를 접속해도 강제로 https://...로 보내는 것이다. 이것은 hostinger tutorial을 참조하여 .htaccess를 편집하면 된다.

How to Force HTTPS

이 튜토리얼의 내용을 요약하자면 내 웹사이트로 들어오는 모든 요청이 https://로 강제로 보내지게 하려면 최상위 .htaccess 파일에 다음의 세 줄을 넣어 저장한 뒤 웹브라우저의 캐쉬를 지우고 재접속을 하면 된다. 주의할 것은 'RewriteEngine On' 라인이 .htaccess 파일 안에 단 한번만 존재해야 한다는 점.

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

.htaccess 파일을 잘못 건드리면 웹사이트가 아예 접속이 되지 않으므로 매우 주의를 기울여야만 한다. Hostinger 파일 관리자에서 수정을 완료한 다음 웹브라우저에 내 도메인 정보를 넣으니 저절로 https://로 접속이 된다.

hostinger.kr의 억지스런 우리말 번역을 보면 웃음이 날 지경이다.

'수색'이나 '시작하다' 정도면 그래도 준수하다.

'확인해 봐' 네, 네... 알겠습니다.


2019년 4월 3일 수요일

SSL과 관련한 conda 설치 에러 - anaconda3 [해결]

(2019년 4월 10일: 아무래도 정확하지 않은 정보를 가지고 섣불리 글을 쓴 것은 아닌지 걱정이 된다. 기본 개념부터 다시금 되짚어 보아야 하겠다. 본문은 2019년 4월 11일과 2023년 6월 20일에 수정되었다.)

공공연구기관에서는 멀쩡히 작동하던 리눅스 서버가 왜 기업 전산망 내부에서는 몽니를 부리는가? 4년 3개월 동안 아무런 장애 없이 나와 동고동락하던 서버를 정식으로 반출허가를 받아서 파견지로 힘들게 들고 나왔는데 왜 이런 일이 벌어지는 것일까? 달라진 것이라고는 네트워크 설정을 바꾸고 그리드 엔진을 삭제한 것뿐이다.

그동안 잘 사용해 오던 anaconda2 환경에 새로운 bioconda 패키지를 설치하려는데 도무지 되질 않는다. anaconda3을 새로 설치한 다음 conda 자체를 업데이트하고자 시도하였으나 다음과 같은 에러 메시지가 나왔다. Firefox에서 http 사이트를 연결하면 (다 그런 것은 아니지만) 안전한 연결이 아니라고 하면서 화면이 뜨지 않는다.

# conda install conda
Solving environment: failed

CondaHTTPError: HTTP 000 CONNECTION FAILED for url 
Elapsed: -

An HTTP error occurred when trying to retrieve this URL.
HTTP errors are often intermittent, and a simple retry will get you on your way.

If your current network has https://www.anaconda.com blocked, please file
a support request with your network engineering team.

SSLError(MaxRetryError('HTTPSConnectionPool(host=\'repo.anaconda.com\', port=443): Max retries exceeded with url: /pkgs/r/noarch/repodata.json.bz2 (Caused by SSLError(SSLError("bad handshake: Error([(\'SSL routines\', \'tls_process_server_certificate\', \'certificate verify failed\')])")))'))
처음에는 그저 사내 전산망을 보호하는 방화벽에서 443번 포트가 막혀서 그런가 보다하고 관리자에게 이를 풀어줄 것을 요청하면 될 것이라 생각했었다. 그런데 구글에서 내가 해결할 방안이 없을지 검색을 거듭한 결과 이는 SSL(Secure Socket Layer) 인증서와 연관된 문제라는 생각이 들었다. 나와 비슷한 문제를 겪는 사람이 의외로 많이 있었다. 이번에야말로 SSL 인증서가 무엇이고 왜 중요한지를 알아볼 수 있는 마지막 기회라고 생각하고 공부를 하기로 마음을 먹었다. 그렇지 않으면 영원히 초보 리눅서를 벗어날 수 없다! CD-ROM으로 슬랙웨어를 설치하던 것이 94년쯤이었나, 25년이 넘어가는 지금까지도 별로 실력이 늘지를 않았다.

웹 서버와 브라우저 사이의 안전한 접속을 보장하는 SSL을 알아보자. 다음의 동영상(유튜브 링크)을 한번 감상하고, 그 다음에 나열한 웹사이트를 찬찬히 읽어보라. (1) 데이터를 암호화하여 중간에 나쁜 의도를 가진 사람이 이를 가로채도 내용을 알아볼 수 없게 하는 것, 그리고 (2) 웹 브라우저가 접속한 서버가 가짜가 아닌지를 확인하는 것이 주된 목적이다.


인증 기관의 인증서 목록이 없거나 모르는 기관에서 발급한 인증서일 경우 "curl"은 인증서 검증 에러를 발생시키고 작업을 중단한다고 한다(curl에 신뢰하는 인증기관 인증서 추가하기). 아마 conda 명령어도 비슷한 심경으로 작업을 중단했을 것으로 생각한다. 정확한 것인지 자신은 없지만 내가 생각하는 문제의 원인은 이러하다. SSL 인증서는 웹사이트 자체에, 그리고 Verisign, Comodo 등 인증기관에 같이 존재한다.
엄밀히 말해서 위 아래 단락의 밑줄을 친 부분은 정확하게 기술한 것은 아니다. 만약 이를 문자 그대로 해석한다면, 웹 서버와 최상위 인증기관에 같은 인증서가 두 벌 존재하여 접속 시에 이것이 서로 일치하는지를 확인하는 것처럼 여겨지기 때문이다. 하위 단계의 인증서에는 이것이 어디에서 발급되었는를 보여주는 정보가 들어있다. 상세한 것은 Get your certificate chain right 웹사이트를 참고하라.
웹브라우저는 https로 주소가 시작되는 웹서버에서 인증서를 가져온 다음 인증기관의 것과 같은지 비교를 한 뒤 동일함이 검증되면 다음 그림과 같이 채워진 자물쇠 그림과 함께 안전한 웹사이트임을 나타낸다. 자물쇠를 클릭하면 인증서 정보가 보이고 이를 파일로 export할 수 있다.



그러면 어떻게 해야 하는가? 임시 방편으로는 인증서 검증 작업을 하지 않게 만드는 것이 있겠다. 물론 보안 측면에서는 별로 권장할만한 일은 아니다. 다음의 방법은 StackOverflow의 conda update CondaHTTPError: HTTP None에서 힌트를 얻은 것이다. no가 아니라 false를 써야 한다는 글도 있었다. 이 해결책은 꽤 많이 알려져 있으며, Windows에 설치한 anaconda에서도 작동한다는 것을 2023년 6월에야 알게 되었다. 이 명령에 대한 설명이 필요하면 'conda config --describe ssl_verify'를 입력하라. 설정 상태를 화면에 표시하려면 'conda config --show'를 입력하면 된다.

# conda config --set ssl_verify no
SSL 인증서와 관련한 원인은 이곳에서 알아볼 수 있다. 아마도 공인되지 않은 자체 인증서를 제시하는 웹서버가 문제의 주요 원인이 아닐까 한다. 보다 근본적인 해결 방법은 ssl_verify 기능을 아예 꺼 버리는 것이 아니라, 해당 웹사이트에서 자체 인증서를 가져다가 저장하는 것이다. 아래의 사례는 git에 해당하는 것이지만 conda도 크게 다르지 않을 것이다. conda가 파일을 가져올 때 curl을 쓰기 때문이다(확인을 해 봐야 함).

Installing self-signed certificates into Git cert store

자체 인증서를 쓰는 사이트를 회사 방화벽이 막는지는 잘 모르겠다. 내가 겪는 문제는 CentOS 6.10이 설치된 리눅스 머신에서만 일어나고 있기 때문이다. 사무용 PC에서는 전혀 문제가 없는데, 방화벽이 리눅스와 윈도우를 가려서 작동할리는 없다. 리눅스 배포판이 문제인가? 하지만 바로 지난주까지는 정부출연연구소 내부에서 별 문제가 없었는데? 이를 확인하려면 리눅스를 좀 더 최신 버전 혹은 다른 배포판(예: 우분투)로 업그레이드하면 되는데 20 테라바이트쯤의 데이터를 잠시 다른 곳으로 옮기려면 보통 일이 아니다. 우분투 16.04가 설치된 집 컴퓨터를 들고 출근해서 똑같이 테스트하면 어떨까? 그러면 이것이 CentOS 버전과 관계가 있는 문제인지를 알 수 있을 것이다.

문제가 되는 웹사이트에서 인증서를 export하여 파일로 저장한 다음 그 위치를 .condrc 파일 내에 ssl_verify: corp.crt 형식으로 지정하는 것이 좀 더 근본적인 방식이다.

하지만 이렇게 장광설을 늘어놔 봐야 무슨 소용이 있겠는가? 내일 출근을 해서 테스트를 하기 전까지는 알 수 없다.

타워형 케이스 안에 6개의 6TB HDD가 있고 5개는 RAID로 묶여있는 상태이다. 장애 여부가 LED로 표시되지 않으니 만약 어느 하나에 문제가 생기면 어떻게 찾을까? 이렇게 26년차 초보 리눅서를 괴롭히는 또다른 문제는 RAID 관리에 관한 것이다. 결국은 제대로 경력을 갖춘 서버 관리자를 채용하여 더 큰 일을 도모하는 것이 정답이지만 바이오 기업 혹은 연구소에서 이런 인력을 좋은 조건을 제시하며 채용하는 것은 썩 쉽지가 않다.

2019년 4월 4일 업데이트

'conda config --set ssl_verify no'의 다음의 편법이 잘 작동함을 확인하였다. .condarc 설정 파일은 홈 디렉토리에 존재하는데, 이 명령을 실행함으로 인해서 다음과 같이 바뀌었음을 알 수 있다.

channels:
  - conda-forge
  - bioconda
  - defaults
ssl_verify: false
그러면 좀 더 안전한 방법을 실제로 실행에 옮겨보기로 하자. 나에게 고통을 안겨주었던 https://repo.anaconda.com/으로 가서 인증서 내보내기를 실행하였다. 파일 형식은 'Base 64로 인코딩된 X.509(.CER)'로 하였고 anaconda.cer라는 이름으로 저장하였다. 그 다음은 아래에 보인 것과 같이 실행하였다. .condarc 파일의 ssl_verify가 수정되었음을 알 수 있다.

# conda config --set ssl_verify ./anaconda.cer
# cat ./condarc
channels:
  - conda-forge
  - bioconda
  - defaults
ssl_verify: ./anaconda.cer
실수로 인증서 파일을 지우면 곤란하므로 .conda와 같은 숨겨진 디렉토리에 인증서를 두는 것이 좋을 것이다. 그런데... 잘 안된다. www.anaconda.com conda.anaconda.org repo.anaconda.com 등 한 사이트에서 인증서를 받아서 설치하면 다른 사이트가 막히고, 또 그것을 해결하면 다른 사이트가 막히고.. 각 사이트를 돌아가면서 접근이 안된다는 메시지가 나오는 것이다. 그러면 각 사이트에서 전부 인증서를 받아서 하나의 파일로 어떻게든 만들어야 한다는 이야기인가? 정말로 모르겠다. cert (or CA) bundle이라는 말이 종종 나오는데 도대체 어떻게 해야 할까?
CA bundle이란 루트 및 중간 단계 인증서의 묶음이다. 여기에 서버 인증서까지 포함하면 인증서 체인이 된다. conda 설정에서 ssl_verify ≠ false인 경우 제공해야 하는 것은 CA bundle이거나 혹은 trusted CA의 인증서이다. (CA bundle is a file that contains root and intermediate certificates. The end-entity certificate along with a CA bundle constitutes the certificate chain. [What is CA bundle?])

드디어 해결!

구글을 뒤지고 뒤져서 해결을 하였다. 웹브라우저에서 X.509(.cer)로 내보낼 수 있는 인증서는 한 장이다. 바로 아래에 있는 PKCS #7 인증서(.p7b)는 인증 경로에 있는 인증서를 전부 포함할 수 있다고 한다. 하지만 이 형식은 conda가 인식하지 못한다. 그래서 openssl을 사용하여 여러 인증서가 줄줄이 연결된 pem 포맷으로 전환해 보았으나 계속 에러가 발생하였다(참조 사이트: How to convert a certificate into the appropriate format). .pem 파일의 용도는 다음의 설명을 참조하라.

.pem file is a container format that may just include the public certificate or the entire certificate chain (private key, public key, root certificates). 출처

.cert .cer .crt - A .pem (or rarely .der) formatted file with a different extension, one that is recognized by Windows Explorer as a certificate, which .pem is not. 출처

그러면 웹브라우저를 거치지 않고 인증서들을 한번에 가져올 수는 없을까? 방법이 있다. 다음은 그 전체 과정을 보여준다. -showcerts 옵션을 주지 않으면 서버 인증서만 출력이 된다.

# echo quit | openssl s_client -showcerts -servername "www.anaconda.com" -connect www.anaconda.com:443 > cacert.pem
depth=1 C = KR, O = Somansa, CN = Somansa Root CA
verify error:num=19:self signed certificate in certificate chain
DONE
# conda config --set ssl_verify cacert.pem 
# conda update conda
Collecting package metadata: done
Solving environment: done

# All requested packages already installed.

# conda install -c bioconda trimmomatic
...성공!
(Somansa는 SSL 인증서 인증기관이 아니다. 그런데 왜 Root CA라고 표시되는 것일까? 이 회사에 대한 자세한 사항은 아래의 4월 6일 업데이트 참조.)

openssl 명령어를 이런 용도로 사용하는 힌트를 구한 웹사이트 주소를 잊어버려서 여기에 고마움을 표하지 못하는 것이 정말 아쉽다. 마치 에러가 있는 것처럼 나오지만(자체 인증서) cacert.pem 파일은 잘 만들어진다.

단, anaconda2에서는 여러 인증서가 하나로 합쳐진 cacert.pem을 인식하지 못하는 것으로 보인다. 이를 개별 파일로 분리하여 특정 디렉토리에 넣은 다음 ssl_verify에 대응하는 값으로 공급해도 잘 되지는 않는다.

CustomValidationError: Parameter ssl_verify = 'cacert.pem' declared in <> is invalid.
ssl_verify value 'cacert.pem' must be a boolean, a path to a certificate bundle file, or a path to a directory containing certificates of trusted CAs.

종합적인 결론을 내리자면, 아마도 사내 방화벽은 자체인증서만을 보유한 웹사이트에 접근하는 것을 싫어하는 것 같다. conda에서 인증서 확인 기능을 아예 끄는(ssl_verify: false) 위험한 방법을 동원하지 않고도 얼마든지 conda(curl..)를 즐길 수 있다!

이번에 겪은 작은 사고가 아니었더라면 웹사이트 인증서와 openssl에 대해 공부를 하는 기회를 갖지 못했을 것이다.

참고할만한 국문 사이트를 소개하면서 이틀에 걸친 포스팅을 마친다.


OpenSSH(Secure Shell)는 OpenSSL(Secure Socket Layer)과 다르다^^(SSH vs. SSL: 바보 같은 설명 참조)

https://www.openssh.com/

그러면 내 위키사이트도 인증서를 발급받아야 하지 않을까?

당연한 이야기이다. 돈이 드는 방법, 돈이 들지 않는 방법 전부 가능하다. 내가 사용하는 hostinger에서는 다음의 자료를 제공하고 있다. 큰 돈이 드는 것이 아니니 조만간 인증서를 설치하는 것이 좋겠다.
그런데 Conda documentation을 보면 내가 고민했던 것의 기본적인 원리에 대한 것이 대부분 설명되어 있다. 에러에 대처하는 직접적인 방법은 나오지 않지만 말이다.

2019년 4월 6일 업데이트: 소만사? KRIBB은 수산INT!

회사 네트워크 내부에서 conda update와 관련하여 문제가 되었던 웹사이트의 인증서 정보를 브라우저에서 살펴보니 Somansa라는 회사의 이름이 보였다. 난 이것이 인증서를 발급하는 회사라고 생각했었다. 그런데 집에서 같은 웹사이트에 접속하여 인증서 정보를 찾아보면 다른 회사이름이 나오는 것이었다(COMODO ECC Domain Validation Secure Server CA 2). 어라? 소만사가 무엇을 하는 회사인가? 아! 정보보안 솔루션(웹키퍼 SG(T-Proxy, 프록시 서버, 얼마만에 듣는 용어인가!))을 제공하는 국내 회사였다. 소만사라는 이름은 '소프트웨어를 만드는 사람들'에서 유래한 것이라 한다. 아주 쉽게 말해서 실수 혹은 악의적으로 기업의 정보를 SSL로 암호화하여 빼내는 것을 찾아내어 차단하는 하드웨어·소프트웨어 일체형 장비를 판매하는 곳이었다. '암호화 트래픽 가시성 확보'라는 용어가 이런 곳에 쓰이는 말이었다. 즉 Somansa의 웹프록시 서버가 SSL로 암호화되어 들어오는 정보를 복호화한 뒤 다시 암호화하여 내부 클라이언트로 보내는 과정에서 이를 완벽하게 되돌려놓지 못하는 것이 conda 업데이트(bioconda 패키지의 설치를 포함하여) 불능 문제의 원인이었던 것으로 보인다. 좀 더 정확하게 말하자면 bad handshake라는 에러 메시지가 많은 단서를 제공하고 있음을 나중에 알게 되었다.

SSL이 양날의 검이라는 말을 이제 조금 이해할 수 있었다. 암호화 및 인증서를 통해서 내가 접속한 웹서버가 가짜가 아님을 확신할 수 있고, 또한 사용자와 웹서버 사이에서 전달되는 패킷이 중간에 유출되어도 나쁜 의도를 가진 제3자가 이를 해독하지 못하게 한다. 그러나 실수나 악의에 의해서 '내'가 만약 기업 내부의 정보를 외부로 빼내려 한다면? 이를 막기 위한 DLP(Data Loss Prevention)의 한 방법이 바로 소만사와 같은 회사가 제공하는 솔루션이었던 것이다.

사용자 정보의 보호를 위하여 편지봉투를 밀봉하여 전달하였더니, 기밀사항을 유출하는지 알 수가 없게 되었고 이에 따라서 봉투를 아예 쓰지 못하게 하거나, 혹은 햇볕에 비추어서 내용물을 들여다보는 기술이 생긴 것과 비슷한 이치라고 하겠다.

항생제를 함부로 쓰면 감염성 세균의 내성도 이에 따라서 똑같이, 아니 그 이상으로 증가한다. 진화적 군비경쟁이 IT 분야에서도 똑같이 벌어진다.


2019년 4월 2일 화요일

회사 생활 이틀째

(이보다 앞서서 벤처기업에서 약 2년 반, 그리고 정부출연연구소에서 16년 3개월을 일했다)

일찍 퇴근하여 숙소로 돌아왔다. 창밖으로 내다보이는 높다란 건물에는 아직 일을 마치지 못한 직장인이 많은지 대부분의 사무실에 불이 켜진 상태이다.


비교적 긴장감이 적은 공공연구기관에서 직장 생활을 하다가 새로운 경험을 하고 싶어서 기업체로 온지 이틀이 지났다. 생존 혹은 생계를 위한 마지못한 선택도 아니요, 정해진 시간이 지나면 다시 돌아갈 곳이 있다는 점에서 어쩌면 매우 배부른(?) 결정이었는지도 모르겠다. 대전을 제2의 고향 삼아서 인생의 절반을 훌쩍 넘도록 살다가 다시 수도권으로 돌아와서 지하철로 출퇴근을 하노라니 정말 새로운 기분이다. 생각을 해 보니 나는 모든 학창생활 기간 동안 걷거나 자전거로 통학을 하였고 그 이후로는 승용차를 이용했기 때문에 전적으로 대중교통을 이용하여 출퇴근을 한 적이 거의 없었다. 아주 최근에는 버스를 자주 타기는 했었다.

바삐 오가는 사람들은 광역시에서 만나는 사람들보다 왠지 더 바쁘고 세련되어 보인다. 과연 이번 기업 근무 경험에서 어떤 것을 얻어가게 될 것인가? 기대감과 불안감이 공존하는 묘한 기분이 느껴진다. '하늘에서 비가 돈처럼 내려도 요리조리 피해다니는' 나의 성격 속에 과연 기업가 정신('entrepreneurship')이라는 것이 깃들어 있을까? 이것은 타고나는 것일까, 아니면 만들어지는 것일까? 어떤 사람은 할 일이 이것밖에 없어서 사업을 하게 되었다고 ㅇ농담 반 진담 반으로 말하기도 한다.

많은 어려움에도 불구하고 개인이 가장 많은 자율성을 누릴 수 있는 기회는 창업을 하여 기업을 운영할 때가 아닌가 한다. 이렇게 일구어 나간 기업이 큰 고목나무처럼 수백년, 아니 그 이상을 존속하기를 바라지만, 기업에도 분명 수명이 존재한다. 매년 포춘지가 발표하는 500대 기업을 보면 평균 수명은 40년 정도라고 한다. 상공회의소가 발표한 우리나라 기업의 평균 수명은 23.8년. 왜 이렇게 짧은가? 이는 경영자들이 변화하는 환경에 대처하여 지속적인 혁신을 하지 못하기 때문으로 여겨진다.

내가 이번 4월부터 일하는 곳은 바이오·제약 분야의 중견기업이다. 이 분야는 까다로운 규제를 통과해야 하고 성공할 가능성도 극히 낮다. 그러나 제대로 성공만 한다면 그동안의 모든 노력을 충분히 상쇄하고도 남는 수익을 보장한다. 그런데 문제는 좋은 제품을 만들어서 그 매출액으로 수익을 내는 것이 아니라, 자신이 보유한 지분을 훨씬 높은 가격에 처분하여 이익을 실현하는 것이 '정도'이다. 난 사회주의자는 아니지만, 창업교육 등에서 이러한 원칙을 듣고서도 100% 납득을 하지 못하였다.

주식의 처분을 통해 이익을 실현하려면, 상당한 지분을 갖는 주주가 아니면 소용이 없다. 성공적인 IPO(기업공개)의 혜택이 그 기업의 직원에게는 별로 돌아가지 않는 것이다. 그것이 주식회사가 현재 돌아가는 원리이다.

나는 기업이 더 많은 사람에게 번영과 자유를 주었으면 좋겠다고 생각한다. 여기서 자유란 빈곤으로부터의 자유, 더 나은 제품 또는 기술을 통해 얻는 기쁨과 즐거움을 의미한다. 그럼에도 불구하고 기업이 만들어내는 가치에 무임승차를 하는 사람은 되도록 적었으면 좋겠다.  앞으로의 경험을 통해 기업이라는 것에 대한 내 나름대로의 철학을 갖게 될 것으로 기대한다. 그 철학에 따라서 창업을 해서 성공을 해야 되겠다는 생각이 들 수도 있고, 그렇지 않을 수도 있을 것이다.

창조하고 개척하는 사람이 될 것인가, 비평가가 될 것인가?

그 어떤 결론을 내리든, 나에게는 소중한 경험이 될 것이다. 두 곳을 오가며 생활을 하느라 비용은 더 들지만 충분히 투자할만한 가치가 있는 수업료라고 생각한다. 그리고 기업 근무를 하는 동안 대부분의 블로그 집필은 퇴근 후 집에서 하게 될 것이다. 어차피 보안 등의 문제로 근무 중에는 개인적인 일을 하기가 곤란하기 때문이다.

오디오 기기를 하나도 들고 오지 못했다. 그래도 인터넷 라디오와 주워온 멀티미디어 스피커가 있어서 귀의 심심함을 달래고 있다.


2019년 3월 31일 일요일

새로운 기회를 준비하면서

2019년 4월부터 경기도 소재의 한 중견기업에서 일을 하게 되었다. 16년 3개월 동안 근무한 정부출연연구소를 완전히 떠나는 것이 아니라, 기업의 기술혁신 지원을 위하여 파견 발령을 받은 것이다. 기업의 요청과 나 개인의 결심이 서로 일치하여 성사된 것으로서 전례가 없는 일이라 기관 최고 책임자 수준에서 결정이 난 다음 이를 추진하는 실무자들이 꽤 많은 수고를 하였다.

국가과학기술연구회와 중소벤처기업부에서 실행하는 공공연구기관 연구인력지원사업이라는 것도 있지만, 이는 중소기업 및 벤처기업에만 해당된다.

수도권에 머물 곳을 구하고, 짐을 옮기고, 하던 일을 정리하느라 매우 분주한 3월을 보냈다. 데이터를 백업하고 컴퓨터를 정리하여 원 소속센터의 연구원들이 사용할 수 있도록 세팅을 하는 것이 특히 큰 일이었다. 마지막날까지 Oxford Nanopore 시퀀싱 실험을 하느라 정신이 없었다. 48시간 사이클로 설정하였으니 아마도 어제(토요일) 저녁 6시쯤에 모든 과정이 끝났을 것이다. 예전에 몇 차례 테스트 시퀀싱을 했을 때에는 시퀀싱이 전부 끝난 다음 별도로 Albacore basecalling을 하느라 많은 시간이 소요되었지만 이번에 새로 설치한 MinKNOW 소프트웨어에서는 자체 basecalling option이 있어서 한결 수월하였다. 하루 정도를 지켜보니 약 65%의 진도로 basecalling이 진행되는 것을 볼 수 있었다.


마지막 주말에는 집에서 공동연구자의 sequencing raw data 51건을 NCBI SRA에 올리고 있다. 연구소 전산망보다는 속도가 느려서 시간이 생각보다 많이 걸린다. 그래도 중간에 전송이 끊기지는 않으니 다행이다.

공부를 위해 마지막으로 인쇄해 혼 논문을 아직 제대로 읽지는 못했다. 10년 간격을 두고 거의 같은 제목으로 나온 리뷰 논문을 비교해 보면서 얼마나 많은 지식이 이 분야에 축적되었는지를 알아보려 한다. 나의 원래 소속 부서와 파견 기업에서 같이 관심을 기울일만한 분야이다.


The role of microbiota in infectious disease. Stecher B, Hardt WD. Trends Microbiol. 2008 Mar;16(3):107-14.

The role of the microbiota in infectious diseases. Josie Libertucci & Vincent B. Young.
Nature Microbiology volume 4, pages 35–45 (2019).

앞으로 2년 동안 이 블로그를 운영하는 방식에도 변화가 있을 것 같다. 기업에서 추진하거나 겪은 일을 마치 일기를 쓰듯이 블로그에 쓸 수는 없기 때문이다. 개인적인 일, 취미와 관련된 것, 내가 종사하는 분야의 일반 동향, 리눅스/shell script/Perl/R 등의 자질구레한 팁 정도로 그 범위와 작성 빈도가 줄어들 것이고, 이는 충분히 예견했던 바다.

직장 및 삶의 터전을 한시적이나마 바꾸어 본다는 것은 개인 차원에서 할 수 있는 매우 효과적인 혁신의 한 수단이라고 생각한다. 나의 결심이 나 개인과 가족에게도 좋은 기회가 될 것으로 믿는다.

3월이 끝나기 전에 10회의 블로그 포스트를 달성한 것이 다행이다. 원래의 목표는 월 12회 이상 글을 쓰는 것이었다. 월 15회가 목표였던가?

2019년 3월 27일 수요일

컴퓨터 청소하기

내가 소유한 물건에 대하여 진지한 성찰을 하게 되는 가장 좋은 계기는 이사를 하는 것이다. 마지막 이사를 하면서 소중하게 챙겨왔던 물건을 한번도 꺼내지 않다가 새로 이사를 준비하면서 비로소 그 존재를 확인하게 되는 경우를 많이 겪는다. 누군가 이런 말을 한 적이 있다. 정말 필요한지 아닌지가 확신이 되지 않는 물건이라면 일단 상자에 넣어서 보관하여라. 6개월이 흐른 뒤 그동안 단 한번도 그 상자를 열어보지 않고 있었다면 버려도 좋다는 것이다. 내가 한마디 첨언한다면 6개월이 지나는 날, 버릴 결심을 하는 순간 그 상자에 무엇이 들어있었는지를 확인하기 위해 열어볼 필요조차 없다.

왜 하필이면 6개월일까? 계절이 바뀌면서 넣어 둔 옷은 다시 그 계절이 돌아올 때가 되어야 꺼내 입는 것이 당연하다. 그러한 주기는 대략 6개월로 볼 수 있으니, 이는 매우 합리적인 기준이 된다. 패션에 아주 민감한 부자가 아닌 이상 계절이 바뀌면 예전에 넣어둔 옷을 다시 꺼내 입어야 하지 않는가.

파견발령을 받아 4월 1일부터 근무지를 바꾸게 되면서 내가 쓰던 물건을 정리하는 것도 비슷한 맥락에서 바라볼 수 있다. 소위 '드라이 랩' 위주로 연구실을 운영하다 보니 내가 관리하는 대부분의 장비는 컴퓨터이다. 일부는 반출 신청을 하고, 나머지는 이전 근무지에서 계속 활용할 수 있도록 정비를 하였다. 고장난 RAID array는 새로 구성하고, 먼지를 털고, 성능이 너무 떨어지는 서버는 아예 전원을 내리고...

작년에 건물 지하에서 화재가 발생하여 발생한 그을음이 서버를 보관하는 3층 골방까지 타고 올라와서 서버를 엉망으로 만들었었다. 청소를 할 엄두가 나지 않아서 그냥 방치하였다가 최소 2년 동안은 내가 관리를 할 수 없는 상태가 되었으므로 칼을 빼들기로 하였다. 아래 사진에 보인 서버는 2009년 10월에 내가 최초로 구입한 랙마운트 조립서버이다. Tyan의 S7002 보드에 인텔 E5620(2.4GHz)가 두 개 꽂혀있다. 메모리는 보드에서 지원하는 최대 용량인 64GB를 장착하였다. 서버의 별칭은 proton. 21C 프론티어 양성자공학기술개발사업단의 과제 지원으로 구입하였으므로 양성자라는 이름을 붙인 것이다. 이 서버를 구입하기 전에는 사무용 컴퓨터 수준의 것에 리눅스를 깔아서 사용했었다. 만 10년 가까이 흐르는 동안 하드디스크드라이브를 추가한 것 외에는 단 한번도 장애가 발생하지 않았고 간혹 공지된 정전기간 이외에는 전원을 내리지도 않았다. 2015년에 현재 쓰는 서버(벌써 4년이 흘렀다)를 구입하면서부터는 하드디스크드라이브를 꽉 채워서 RAID array를 구성하여 바로 오늘에 이르기까지 잘 사용하였다. 참 대견한 녀석이다.


카트에 싣고 살살 건물 밖 마당으로 나가서 뚜껑을 열고 압축공기 캔으로 열심히 그을음을 떨어내었다. 컴퓨터에 내부에 보통 끼는 먼지와는 차원이 다르다. 공기로 떨어지지 않는 것은 걸레질을 해 가면서 열심히 닦았다. 또 다른 랙마운트 서버인 microbe는 USB 3.0 인터페이스 카드를 꽂아서 Oxfor Nanopore Technologies의 MinION을 구동할 수 있게 만들었다.

가장 성능이 좋은 Dell 서버는 전산센터동의 서버실에 있어서 특별히 유지 관리를 할 필요가 없다. 사실 이것도 내년이면 구입 10년차가 된다. 전산장비를 쓰면서 그렇게 큰 장애를 겪은 일이 없다는 것이 매우 다행스럽게 여겨진다. 수백 대의 서버를 관리하는 사람이라면 늘 긴장 상태이겠지만 나는 소규모 연구를 수행하는 사람으로서 관리하는 컴퓨터의 수는 열손가락으로 충분히 헤아릴 수 있는 수준이니까.

고만고만한 수준의 서버 4대를 모아서 오라클 그리드 엔진으로 묶었었는데 실제로 이를 많이 쓰지는 못했다. 하드웨어가 제각각인지라 가장 성능이 떨어지는 계산 노드가 항상 전체 실행 시간을 잡아먹고 있어서 점점 쓰지 않게 되었다. 그리드 엔진을 해체하면서 부팅을 할 때마다 마스터 및 계산 노드 각각이 실행하는 설정 스크립트를 어느 단계에서 돌리는지 찾아보았다. /etc/profile 파일의 맨 끝에 붙어 있기에(다음의 라인) 이를 코멘트 처리하였다. 내가 직접 오라클 그리드 엔진을 설치한 것이 아니라 KOBIC의 도움을 받은 것이라서 상세히 기억을 하지는 못한다.

source /data/gridengine/default/common/settings.sh

컴퓨터에 문제가 생기면 바로 곁의 KOBIC에서 늘 많은 도움을 받았었는데 이제 새 파견지로 가면 어떻게 해야 하나? 자력갱생을 해야지 어쩌겠는가?


2019년 3월 25일 월요일

새로운 잡종 동물


그렇다. '개새'. 개의 머리와 새의 몸체를 가진 우스꽝스런 동물이다. 출시된지는 제법 되었다. '개새'라는 결코 고상하지 않은 낱말을 입에 올릴 때, 묘한 쾌감이 느껴진다. 원래 욕설이란 것이 그런 것 아니겠는가?


남부터미널 상가에 다녀온 아들의 선물이다. 캡슐뽑기 가챠샵에서 구입한 것이라서 어떤 아이템이 나올지는 순전히 운에 좌우된다. 기왕이면 시바새였으면 좋았을텐데. 개새, 시바새... 전부 상쾌한 카타르시스가 느껴지는 이름 아닌가?

가끔은 이런 존재가 필요하다.