2019년 5월 26일 일요일

전쟁을 소재로 한 연극

고등학교 3학년에 재학 중일 때, 모의고사가 끝나면 나름대로 문화생활을 하겠다고 공연이나 전시를 찾아다닌 적이 있었다. 실제로 세 번 정도에 그치고 말았지만 모두 생생하게 기억이 난다.

  • 서양화가 이정규의 작품 전시회 - 유학을 마치고 귀국한 직후의 전시회였으니 정말 오래전의 일이다.
  • 싸트트르의 [무덤 없는 주검]
  • 테네시 윌리엄스 [뜨거운 양철 지붕 위의 고양이] 
(화가 이정규는 나의 이종사촌 누님이기도 하다. 마지막으로 뵌 지도 꽤 오래되었다.)

[무덤 없는 주검]은 세계대전 당시 프랑스 레지스탕스의 활동을 소재로 한다. 온갖 어려움 속에서도 가열찬 투쟁을 이어나가는 그런 이야기가 아니라, 고문 앞에서 조직을 살리기 위해 비밀을 지킬 것인가 혹은 자신이 살기 위해 비밀을 발설할 것인가의 놓고 벌이는 처절한 갈등을 그렸다. 후자의 선택을 비열한 것으로 여기는 것이 평화 시대를 살아가는 우리에게는 너무나 당연한 태도겠지만 그러한 위협이 실제로 자신의 목을 졸라 올 때, 당연히 정의를 지켜나가기 위해 자신의 목숨을 내어 놓을 수 있는 사람은 몇이나 있을까? 그렇다고 해서 침략자에게 부역을 한 사람을 전부 정당화할 수는 없는 노릇이다.

하지만 인류와 더불어 역사를 같이 해 온 전쟁을 관객과 같이 하는 즐거운 비언어 퍼포먼스로 바꾸어 놓은 거리극이 있었으니 그것은 바로 극단 필통의 물싸움 파트-1 '너무 오래된 전쟁'이었다. 때이른 더위가 기승을 부리던 5월 하순, 아내와 함께 국립중앙박물관을 찾았다가 생각보다 체력이 급격히 떨어지는 바람에 져서 사람이 적은 곳 위주로 돌면서 예상보다는 빨리 관람을 마치기로 했다. 서화관 불교회화실에 전시된 압도적 규모의 공주 마곡사 탱화(링크) 앞에서 기력을 좀 되찾고 나오는 길에 오다가 박물관 열린마당에서 열린 공연 행사를 보게 된 것이다(링크).

극단 필통의 비언어 퍼포먼스 [물싸움1-아주 오래된 전쟁].
몹시 더운 날, 제대로 씻지도 못하고 빗자루질을 하던 출연자 1은 너무나 목이 마르다. 무대 여기저기 흩어진 물병과 컵을 허겁지겁 찾아서 기울여 보지만 전부 빈 상태. 물병으로 가득 찬 궤짝은 자물쇠로 견고히 채워져 열리지 않는다. 곧이어 나타난 출연자들은 물이 가득한 궤짝을 너무나 쉽게 열고 자기들만의 물잔치를 벌이지만 정작 물 한잔만 달라고 애원하는 출연자 1에게는 불리한 게임을 제안하며 인색하게 군다. 급기야 이들 사이에는 물 전쟁이 벌어진다. 물 한잔은 출연자 1을 살릴 수 있는 것이었지만 이제는 무기가 되었다. 권총 수준의 물총에서 기관포, 탱크, 급기야 비행기까지 나타나서 서로에게 막대한 양의 물을 퍼부어댄다.

관객들에게도 물풍선과 물양동이가 주어지면서 직접 참여를 유도한다. 아이들은 아이들대로, 어른들은 어른대로 각자의 눈높이에 맞추어 이 연극을 해석할 수 있다. 더운 여름날 오후에 출연자와 관객이 모두 무대와 객석이라는 경계 없이 즐길 수 있는 시원한 거리극으로만 받아들여도 되고, 자원과 자본을 독점한 권력자와 그 앞에서 투쟁하는 힘 없는 개인이나 노동자로 해석해도 좋다.

마지막 장면에서는 승자도 패자도 없이 모두가 파멸하고 만다. 

약 30분에 걸친 공연을 보면서 아이들을 즐거워했지만 나는 왠지 슬퍼졌다. 아마 이를 기획한 사람도 이러한 의도를 갖고서 만든 작품이 아니었을까 한다. 앞쪽 줄에 앉아서 관람을 했음에도 불구하고 다행스럽게도 내 옷은 젖지 않았다. 공연이 끝난 뒤 터진 풍선과 물감을 들인 물 얼룩을 청소하려면 고생스럽겠다는 생각을 하면서 집으로 향했다.







2019년 5월 23일 목요일

자나깨나 오디오 DIY 타령

6N1+6P1 싱글앰프에 달았던 LED 파일럿 램프가 고장났다. 교류로 LED를 켜면 수명이 짧아진다는데 정말 그래서 망가진 것일까? 전류 제한용 저항값을 제대로 맞추지 못해서 고휘도 LED를 너무 어두운 상태로 써 왔었는데 그나마 없으니 불편하여 인터넷에서 네온램프로 만들어진 파일럿 램프를 주문해 놓았다. 이것은 220볼트에 연결하면 된다. 네온램프라면 직경이 큰 브라켓에 든 것만 있다고 생각했는데 직경 6mm 구멍에 맞는 작은 것이 있어서 기존의 설치 위치에 그냥 꽂으면 된다. 이것으로 금주 주말을 위한 작업 거리가 생겼다.

혹시 재활용할 것이 없을까 싶어서 버려진 로지텍 X-220 2.1채널 스피커 시스템을 하나 챙겼다. 좌우 위성 스피커는 이미 사라진 상태고 앰프가 내장된 서브우퍼만 남은 상태였다.


앰프 보드를 적출해서 퓨즈(0.5A)를 끊어내어 6N1+6P1 앰프에 활용하였다. 매우 평범한 4채널 앰프칩인 TDA7377(2x30W dual/quad power amplifier for car radio)이 하나 쓰였다. 채널 두 개는 브리지로 묶여서 저음 재생에, 나머지는 각각 좌우 채널에 쓰인다. 전원트랜스는 14볼트 1암페어 짜리가 쓰였다. 자동차용 앰프 칩이나 단전원을 쓰도록 되어있다. 공급할 수 있는 최대 전압은 18볼트이다.


4565D와 TL074CN 두 개의 op amp가 보인다.

이 앰프 보드를 활용할 방법이 없을까? TDA7377의 데이터 시트에서 핀 배열을 찾아내기는 했다. 그러나 커넥터의 각 핀에 어떻게 입출력이 연결되는지를 알아낸다면 이 보드를 특별히 개조하지 않고 그대로 활용할 수 있을 것이다. 9핀 DIN 케이블의 단자 번호는 다음과 같다.

출처: http://www.ni.com/product-documentation/54362/en/

데이터 시트에 나온 활용사례처럼 다른 부품은 다 무시하고 캐패시터 하나를 거쳐서 TDA7377에 입력 신호를 넣느니, 이 보드에 이미 마련된 프리앰프부를 활용하는 것이 낫지 않겠는가? 서브우퍼에는 별다른 관심이 없다.

자, 이 커넥터를 어떻게 연결해야 할까? 좌우 신호(입력), 좌우 출력(스피커), 전원 조작 등의 기능이 이 커넥터를 통해서 이루어질 것이다. 서비스 매뉴얼도 구할 도리가 없으니 구글을 되는대로 뒤져 보기로 하였다.


놀랍다! fixya라는 사이트에 이에 대한 해답이 있었다. 3일을 고생해서 연결 방법을 알아냈다고 한다.


잠깐, 여기에서 해답으로 제시된 것은 다른 모델인 X-230에 대한 것이다. 이 모델은 RS232 커넥터를 쓴다. 모양은 다르지만 번호 체계는 그대로인 것일까? 

그나저니 mini DIN 9핀 male connector를 어디서 구해야 하나? 국내 사이트에서는 도대체 찾기가 어렵다. 기판 패턴면에 선을 납땜하자니 너무 비좁아서 쉽지 않아 보인다. 커넥터 정보를 알아내려면 좀 더 씨름을 해야 될 것이다.

2019년 5월 24일 업데이트

녹색 네온 파일럿 램프가 생각보다 그렇게 밝지가 않다. 적색이나 황색으로 선택하면 좋았을 것을. 수축튜브가 없어서 납땜한 연결 부위를 절연테이프로 처리하였다. 유리관 퓨즈는 실수로 용량을 제대로 지정하지 않아서 무려 10암페어 짜리를 주문하였다. 이걸을 무엇에 쓴담?


2019년 5월 21일 화요일

대덕연구개발특구를 떠나는 기업들

대덕넷에 안타까운 기사가 실렸다.

중견부터 신생벤처까지 脫대전 "기업인 중심 특구로"

과거 대덕연구단지로 불리던 곳, 그리고 갑천 이북의 유성구는 마치 거대한 '섬'과 같다. 출퇴근 시간에만 반짝 교통이 정체될 뿐, 활기를 찾기 어렵다. 엑스포과학공원을 헐고 그 위치에 49층짜리 초고측 복합몰을 만든다고 하여 과연 달라질 것인가? 공급자 위주의 사고방식에서 벗어나지 않으면 더 이상 혁신을 꾀하기 힘들다고 생각한다. 좋은 기술을 개발했는데 왜 가져다 쓰는 사람이 없지? 그것은 우리 생각이다. 리스크를 두려워하지 않고 새로운 도전을 해야 하는데, 항상 결과는 '성공'이다.

잠시 대전을 떠나 수도권의 기업에서 파견 근무를 하면서, 판교 혹은 그 근방의 활력을 보면 너무나 부러움이 느껴진다. 사람들은 계속 서울로 몰리기만 할 뿐이다. 위에서 인용한 기사의 덧글을 보면 정말 가슴을 치게 한다.
"세금이 말잔치모임 거마비로 낭비되고 있습니다."
새로움과 활력이 묻어나야 하는데, 현재의 대전은 그렇지가 못하다. 시장께서는 2019년을 '대전방문의 해'로 자랑스럽게 선포하였지만 과연 무엇을 보여주고 무엇을 즐기게 할 것인가? 하다못해 대전을 가면 꼭 먹어봐야 할 특색있는 음식이라도 충분히 갖추고 있는가? 이미 1분기가 훌쩍 지났지만 대전의 주요 관광지점의 입장객 수는 변동이 없었다고 한다.

거창한 행사나 표어, 포럼으로 사진 몇 장 찍고 해결될 일이 아니다. 궁극적으로는 전 지역이 특색을 갖고 골고루 발전하는 미래가 그려져야 하는데, 지금은 수도권이 모든 것을 빨아들이고 있다. 많은 비용을 들이면서 나는 현재의 처지를 잠깐이나마 즐기고 있지만, 언젠가는 다시 내 집이 있는 대전으로 돌아가야 하지 않은가? 기회가 더 많은 수도권에 자녀가 정착하도록 힘을 써야 올바른 부모인 것인지... 참 답이 나오지 않는 고민거리이다.

2019년 5월 19일 일요일

덕업상권 - 덕질은 서로 권한다

5월에 쓰는 글은 계속 오디오 공작 '덕질'에 해당하는 것이다. 업무(미생물 유전체 분석)에 관한 사항은 요즘 사내에서 사용할 매뉴얼 작성에 전념하면서 나머지 절반 분야의 '글쓰기' 욕망을 배출할 통로가 약간 바뀐 상태라서 블로그에는 당분간 쓰지 못하고 있다.

공고 전자과 출신의 친구가 지난 금요일 모임에서 내가 만든 앰프의 모습을 보더니 '야, 이건 납땜이 아니지. 그냥 연결한 거지~'라고 핀잔을 주었다. 그렇다고 해서 내가 덕질의 열정에 스스로 소화기를 들이댈 것 같지는 않다. 그 친구가 학창시절에 진공관으로 앰프를 만들었더니 선생님께서 이렇게 말씀하셨다고 한다.

"야! 요즘 세상에 무슨 진공관이냐? 트란지스터를 해야지!"

온 세상이 빅데이터와 인공지능을 떠들고 있는 2019년 5월 현재, 아직도 구시대의 기술이라고 여겨지는 진공관 앰프에 매력을 느끼고 직접 만드는 수준을 넘어서 사업화까지 꾸려나가는 사람이 적지 않다는 것은 놀랍기만 하다. 캐나다에서 Fluxion Audio Technology를 운영하는 안세영 선생님(Young Ahn)의 유튜브 영상을 보면서 인생에서 도전이란 끝이 없다는 생각을 하게 되었다. 다음에 소개한 유튜브 플레이리스트의 제목은 "진공관 앰프에 관한 전자공학 전공 엔지니어의 소견"이다.

https://www.youtube.com/playlist?list=PLGVIFKQFFQ32DpVCh7qe_TI9LkZZxB84g


강기동 박사님(1934~, 신문 기사)은 반도체 개발자이지만 한편으로는 진공관 앰프 자작인들에게 많은 영감을 주신 분이기도 하다. 이런 분들 덕분에 나와 같은 초보 자작인이 지적인 호기심을 채우고 도전을 하는 것 아니겠는가? 또한 제이앨범과 같은 커뮤니티가 있어서 그보다 한 두 세대 젊은(?) 사람들이 꾸준히 '덕질'을 이어갈 수 있는 것이다. 그리고 그 덕질에는 사업화 또는 두번째 커리어의 싹이 숨어 있을지도 모른다.

오늘의 덕질은 버려진 액티브 스피커(로지텍 X-220, 다나와 등록연도는 무려 2004년!)를 주워다가 기판 납땜용 0.5A 유리관 퓨즈를 떼어다가 재활용한 것이 전부이다. 위성 스피커와 케이블 등이 하나도 없는 상태라서 부품을 떼어내어 재활용하는 것 말고는 다른 용도를 찾기 어려웠다.

덕질은 물건을 사들이고 즐기는 것에서 끝나는 것이 아니라 고치고 개선하며 재창조하는 것에서 완성된다...

2019년 5월 17일 금요일

40W 세라믹 히터 납땜인두의 감동적인 성능

납땜 작업을 할 공구 일체를 어제 받아들었다. 인두 스탠드(EXSO ST-66)의 생김새는 다소 어색한데 적당히 무게감도 있고 뜨거운 인두를 널찍하게 둘러싸고 있어서 실제로 써 보니 매우 마음에 든다. 마이크로 드라이버는 웹사이트에 나온 사진만을 보고서 길이는 겨우 맟어었는데 두께가 다르다. 플러스는 3mm인데 마이너스는 2.5mm였다! 마이너스 드라이버를 3mm짜리고 선택하면 길이가 더 긴 것을 사야만 한다.



전날 피복을 벗긴 연선으로 꼬아서 테스트했던 전원 트랜스의 단자에 확실하게 납땜을 하였다. 작동이 잘 됨을 확인하고 앰프의 커버를 씌우는데 불꽃이 번쩍 나면서 차단기가 내려갔다. 아뿔싸! 기판용 퓨즈 홀더 대충 납땜을 하여 절연 테이프를 둘러 놓았었는데 날카로운 접점 부분이 이를 뚫고 나와서 섀시에 접촉을 한 것이었다. 당연히 유리관 퓨즈도 끊어졌다. 임시로 퓨즈 없이 직결하여 전원을 복구하였다.

새로 교체하여 넣은 전원트랜스를 바닥에 고정하는 것, 제대로 된 퓨즈 홀더를 쓰는 것, 너무 어두운 LED 파일럿 램프를 바꾸는 것 정도가 앞으로 개선할 사항이다.

충분히 조심을 한다고 생각하지만 매번 작은 사고를 겪는다. 220V를 다루는 일은 아무리 안전을 강조해도 지나치지 않다.

2019년 5월 16일 목요일

또 트랜스포머!

아세아전원에서 50VA 노출형 복권트랜스(1차: 220V, 2차: 220V)를 구입하였다. 노이즈컷 트랜스(NTC)라고도 물리는 이 물건은 전압을 변환하지 않고 단지 전기적인 절연만을 한다. 모델명은 AT1OD50-2201S이다. 홈페이지에 나온 품목명을 보면 2202S가 맞는 것 같기도 하다.


단권트랜스+보호회로, 또는 트랜스포머 두 개의 병렬연결 등 B 전원을 얻기 위한 다양한 방법을 구상하고 또 시도해 보았으나 가장 명쾌한 해답은 하나의 단상복권트랜스(기성품)를 쓰는 것이다. 스위칭 전원을 만들어서 쓰지 않는다면 말이다.

전선도 없고 납땜 도구도 없어서 임시로 전원을 연결하여 테스트를 해 보았다. 형광등 폐기상자에서 버려진 안정기를 주워다가 전선을 잘라서 재활용하였다. 열에 의해 피복이 경화되고 갈라진 것이 많아서 쓸만한 상태는 아니었다. 아래 사진에서 직렬로 연결하여 사용했던 왼쪽과 가운데의 트랜스를 이번에 구입한 것 하나로 대체하였다. 아마 전압은 10V 혹은 그 이상으로 줄었을 것이다. 험이 현저하게 줄어든 것 같지는 않다.


내가 생각하는 소출력 진공관 싱글 앰프의 전원 구성은 전통적인 방식과는 좀 다르다. B와 히터 전부 스위칭 전원을 쓰거나, 아니면 220V 입출력의 절연트랜스로 B 전원을 구성하고 히터는 별도의 DC 어댑터를 사용하는 것이다. 그러면 전원트랜스 2차 출력을 300V 혹은 그 이상 요구하는 진공관 앰프는 어떻게 할 것인가? 나도 모른다. 몇가지 싱글 앰프에서 요구하는 트랜스의 용량을 알아보았다. 전부 양파정류회로로 되어 있어서 센터탭이 필요하지만, 브리지 정류를 해도 별 상관은 없다. 다이오드 정류를 하면서도 양파 정류회로를 선호하는 이유를 잘 모르겠다.

  • 소리전자 돌쇠(6V6 SE): 220-0-220V 150mA
  • 소리전자 부르지마(6BM8-ECL83 PP): 200V 450mA
  • 소리전자 장미빛 인생(6BQ5 SE): 260-0-260V 150mA
  • 중국제 6N1+6P1 SE(이 실험에 사용하는 것): 230-0-230V 100mA
  • 소리전자 졸업작품-2(EL34-6L6GC): 320-0-320V 300mA
  • ebay EL34+ECC83 SE PCB: 230V 300mA(220~250V 가능)
막상 조사를 해 보니 2차 전압으로 220V가 나오는 전원트랜스로는 만들 수 있는 앰프가 그렇게 많지 않다. 물론 동작점을 설계하기 나름이겠으나...

(주)엑소의 본사 쇼핑몰에서 40와트급 세라믹 히터 납땜인두인 JY-2200과 기타 용품도 주문을 하였다. 모든 부품과 주요 공구가 전부 대전 집에 있어서 파견근무지 숙소에서 공작을 한다는 것이 쉬운 일은 아니다. 납땜 정도는 가능하지만 비좁은 오피스텔에서 전동드릴을 돌려서 구멍을 뚫는 것은 이웃에 큰 민폐를 끼치는 일이다.

택배가 오기를 기다리는 엑소 JY-2200. 사진 출처: G마켓
대전 집에서 전기 먹이기를 기다리는 다른 앰프들이 보고싶다!

2019년 5월 13일 월요일

트랜스포머의 직렬 연결(II) - 복권과 단권을 연결하기

초급 수준의 진공관 앰프를 만들면서 '삼극관 전압증폭회로'나 '오극관 전력증폭회로' 등의 주제에 관해서 공부를 하는 것이 마땅하겠으나 실제로 관심을 갖는 곳은 전원회로에 관한 것이다. 모든 오디오 앰프가 다 그렇듯이 입력 신호를 이용하여 양질의 전원을 조작(?)하는 것이 목표이니 관심을 가지지 않을 수가 없다.

별의별 트랜스포머 조합이나 스위칭 파워에 관심을 갖게 된 것은 진공관 앰프 자작을 위해 최초로 구입했던 파워트랜스포머에서 심한 울림이 발생했기 때문이다.

출처: 내 블로그(링크)
이 파워트랜스포머는 애초에 잘못 주문을 하였다. 원래 의도했던 6N1+6P1 싱글 앰프의 히터 전류 필요량에 미치지 못했던 것이다. 울림은 전원트랜스의 용량 부족에서 기인하는 것으로 생각하여 다른 전원을 이용하여 히터를 점화하면 B 전원용으로는 문제가 없을 것으로 생각했었다. 그러나 앰프를 작동시키면 여전히 울림이 발생하였다.

백열전구를 트랜스 2차 230V에 연결하여 설계 설계용량 수준의 전류를 흘리면 소음이 나지 않는다. 그런데 왜 진공관 앰프 부하에 연결하면 소음이 발생하는지는 잘 이해가 가지 않는다.

6N1+6P1 싱글 앰프는 자작 SMPS와 트랜스 직렬 연결 등의 여러 실험을 거쳐서 완벽하지는 않지만 실용적으로 큰 불만이 없는 현재의 상태에 이르게 되었다. 그러면 무용지물이 된 위 사진 속의 트랜스는 어떻게 할 것인가? 6N1+6P1 싱글 앰프보다 출력이 더 낮은 앰프의 제작에나 써야 되겠다고 생각하고 치워 두었었다.

43 싱글 앰프는 출력도 작고, 낮은 수준의 플레이트 전압(~160V)을 필요로 한다. 여기에 문제의 전원트랜스는 출력 전압이 너무 높다(230V). 저항을 직렬로 삽입하여 전압을 낮추면 여분의 전력이 모두 열로 소모되니 낭비가 심하다. 그렇다면, 놀고 있는 단권 트랜스를 적절히 조합하면 되지 않겠는가? 아래 사진에서 오른쪽에 보인 것이 바로 30VA 급의 단권트랜스이다.

출처: 내 블로그(링크)
단권트랜스의 440V 또는 380V 단자에 220V를 인입하였을 때 2차(220V 및 110V)에 출력되는 전압을 계산해 보았다.

감압비율은 위로부터 50%, 50%, 57.9%, 28,9%이다,

정류회로를 거치면 43 싱글 앰프용 B 전원으로 적당할 것 같고, 용량 면에서도 부족함이 없다. 더구나 단권트랜스는 크기가 작아서 설치 면적이 크게 필요하지 않다. 전단에 연결된 트랜스가 복권트랜스라서 안전 문제도 없다.

갖고 있는 트랜스를 직렬로 연결하여 원하는 전원을 얻고 싶다면, 최소한 두번째에 위치할 트랜스는 단권트랜스라 해도 상관이 없다.

2019년 5월 10일 금요일

단권형 변압기를 1:1 절연트랜스로 개조하기

어떻게하면 단권변압기를 진공관 앰프 B+ 전원 공급용으로 안전하게 사용할 수 있을지 고민을 하면서 구글을 뒤적이다가 새로운 아이디어를 발견하였다. 220V->110V 강압용 단권변압기를 개조하여 권선이 분리된 1:1 절연트랜스를 만든다는 것이다. 글쓴이의 고민은 1:1 절연 트랜스는 수요가 적어서 구하기가 어렵다는 데에 있었다. 운영트랜스나 이디마트에서는 잘 안보이지만 아세아전원의 홈페이지에는 분명히 있기는 하다.

220V->110V 단권형 변압기를 이용한 절연트랜스 제작

원리는 매우 간단하다. 단권 트랜스를 만들 때에는 한 가닥의 선을 이용하여 보빈의 둘레를 감아 나가다가 아래 그림의 C점에 해당하는 횟수에 다르면 그 선을 바깥으로 길게 빼서 꼰 다음 다시 보빈으로 되돌아가서 나머지를 감는다.

따라서 C 점에 해당하는 외부 탭에는 두 가닥으로 꼬인 에나멜선이 납땜이 되어 있을 것이다. 이를 끊어서 두 가닥으로 만들면 전체 권선은 1:1의 권선비로 나뉜 복권트랜스가 된다.

여기에는 두 가지 명백한 문제가 있다. 첫번째는 220V->110V용 강압 단권 트랜스를 개조하는 경우에는 원래 설계된 것보다 두 배의 전압을 걸게 된다는 것이다. 이 트랜스는 위 그림을 기준으로 보았을 때 V1
에 220V를 걸게 만든 것이다. 따라서 A-C, C-B에는 이의 절반인 110V씩이 걸린다. 그러나 개조 후에는 이 구간에 각각 110V가 걸리게 되는 셈이다.
두번째 문제는 1차와 2차 사이에 제대로 절연처리가 되지 않는다는 것이다. 제대로 만든 복권 트랜스라면 1차(혹은 2차)를 다 감은 뒤 절연지(또는 절연 테이프)를 감은 다음 그 위에 2차(혹은 1차) 권선을 감게 되므로 충분한 절연이 된다. 하지만 단권 트랜스를 개조하게 되면 1차와 2차는 에나멜선의 피복 말고는 아무런 절연 처리가 되지 않은 상태이다.

그래도 상용 전원의 live와 neutral을 구별하여 부하에 전기를 흐르게 하는 보호회로를 만들어서 단권 변압기를 구동하느니 이렇게 간단하게 단권 변압기 자체를 개조하는 것이 낫지 않을까? 그대로 쓰는 것에 비해서는 훨씬 안전할 것이 자명하다.

2019년 5월 8일 수요일

돈이 선물이 될 수 있을까

'어버이날 가장 받기 싫은 선물은 책·카네이션 그런 거고, 가장 받고 싶은 것은 돈이래'

아내에게 들은 말이다. 이런 고약한 뉴스는 어디에서 나왔을까? 주요 일간지 웹사이트에 자극적인 제목이 달린 기사가 여럿 눈에 뜨였다.

"이 선물은 피하세요"... 어버이날 받기 싫은 선물 1위는? 조선일보
부모님이 꼽은 '어버이날 받기 싫은 선물' 1위는? 중앙일보

기사 본문을 보면 SK텔레콤이 소셜 분석 서비스 플랫폼인 스마트 인사이트를 통해서 빅데이터 분석을 하여 얻은 결과를 인용했다고 한다. 원본 사이트의 제목은 일간지 기사의 제목보다는 덜 자극적이다.

SKT, 어버이날 선물 트렌드 빅데이터로 분석

선물이라는 것은 주는 사람과 받는 사람이 모두 만족해야 하는 것이다. 선물을 하는 사람은 받을 사람에 대한 애정어린 관찰(상당한 노력이 필요하다)을 통해서 과연 그 사람이 무엇을 필요로 하는지 파악해야 한다. 만약 그 선택의 과정이 귀찮고 성가시다면 선물을 하지 않는 것이 옳다. 반면 선물을 받는 사람은 준비한 사람의 노고를 치하하고 선물을 통해서 전달되는 속마음을 읽는 수고를 해야 한다. 또한 주는 사람은 받는 사람이 느끼는 만족감 이상의 결과를 원해서는 안된다. 마치 보험을 들듯이 댓가를 바라고 주는 선물은 의미가 없다. 받는 사람이 이에 대해서 보답을 하는 것은 그 사람의 자유이다.

'음, 내가 이런 것을 받는 것은 당연해'라고 생각한다면 그건 선물이 아니라 뇌물이 된다. 주기 싫은데도 마지못해 주는 것 역시 옳지 않다. 권력 순위가 높은 사람에게 일방적으로 가는 선물은 참다운 선물이 아니다. 결국 그것은 댓가 혹은 환심이라는 부차적인 효과를 누리는 것이므로.

돈이라는 매개체는 선택의 기회를 전적으로 받는 사람에게 넘기게 만든다. 그러면 주는 사람에게 선물을 고르는 수고를 덜게 만드는 고마운 방편일까? 그럴지도 모른다. 경제학적인 관점에서만 건조하게 판단한다면 돈을 선물로 주는 것은 여러모로 합리적이고 효율적인 일일지도 모른다. 주는 사람의 선택에 관한 고민도 덜 수 있고, 받는 사람이 그 돈을 이용하여 실제로 필요한 물건을 사면 그만이기 때문이다. 자기것이 될 물건을 고르는 것은 별로 고통스럽지도 않다.

그런데 여기에는 상당한 부작용이 따른다. 돈은 기억에 남지 않는다. '언제 누가 무엇을 선물로 주어서 참 좋았었지'라는 기억은 돈으로 대신하기 어렵다. '아, 그때 누가 5만원을 선물로 주어서 이것으로 무엇을 샀었지'라는 기억은 오래 가지 않는다. 그리고 돈을 선물로 주었을 때의 더 나쁜 부작용은 금액의 크기로 선물을 준 사람을 평가하려는 마음이 생기는 것 아닐까? 사람이 직접 마음을 쓰고 정성을 들여야 하는 모든 부분에 상업 서비스가 점점 더 많이 개입하는 현실이 가뜩이나 마음에 들지 않는데, 이제는 돈 자체로 선물을 대신하려고 한다니 더욱 짜증이 난다.

글을 적어놓고 보니 다분히 선물을 주려는 사람의 입장에서 쓴 것으로 느껴진다. 선물을 주는 행위를 더욱 효율적으로 하기 위하여(결국 받는 사람의 만족을 극대화해야 하므로) 추가적으로 해야 하는 고민을 언론에서 이렇게 친절하게 알려주는 현실이 싫은 것이다. 사실 입장을 바꾸어 내가 받는 사람이라고 해도 돈은 싫다. 돈이란 정확한 명목이 있는 지원금(나중에 갚을 수 있다면 더 좋다) 혹은 투자금으로나 받아야지, 선물이라는 포장을 두르고 싶지는 않다.

그래도 돈 싫다는 사람은 없더라.

2019년 5월 7일 화요일

과부 제조기(widowmaker) 앰프

과부 제조기(widowmaker, widow maker, or widow-maker)는 매우 위험한 작업을 뜻한다. 해리슨 포드와 리암 니슨이 출연한 2002년 영화의 제목 K-19: The Widowmaker으로도 잘 알려져 있다. 위험한 일은 꼭 남자(혹은 남편)만이 해야 하는가? 다소 성차별적인 낱말이 아닐 수 없다.


오디오 앰프의 세계에도 과부 제조기에 해당하는 것이 있다고 한다. 1940~50년대에 많이 보급되었던 진공관 라디오 혹은 기타용 앰프 중에서 전원트랜스포머 없이 가정용 교류 전원에 직결하게 만든 것을 뜻한다. 진공관 앰프 회로의 구성품 중 가장 무겁고 가격이 많이 나가는 것은 진공관이 아니라 트랜스포머다. 출력 트랜스포머는 생략할 방법이 없으니 전원쪽의 것을 과감히 생략하여 제조 원가도 절감하고 회로의 단순화도 꾀할 수 있게 만든 것이다. 히터는 전부 직렬로 연결하고, 전원선은 그대로 정류하거나 심지어는 배전압 정류까지 한다. 만약 앰프의 그라운드가 전원의 cold(또는 neutral)에 연결된 상태라면 그냥저냥 약간은 위험한 수준으로 사용 가능하지만, 만약 전원 플러그를 뒤집어 꽂으면 금속으로 된 외함(대개 접지를 한다)이나 외부에 노출된 커넥터의 그라운드 부분은 그대로 100 볼트 이상이 흐르는 상태가 되어 감전 사고의 위험이 커진다. 5개의 진공관이 쓰인 All American Five(AA5) 라디오 수신기가 바로 그렇다. 라디오 수신기는 사용자가 오디오 신호를 연결하는 커넥터를 직접 여기에 꽂을 일이 없으므로 케이스 전체를 나무로 잘 싸고 볼륨 놉에 전기 전도성이 없는 것을 재료로 쓰면 전원부의 핫-콜드를 제대로 연결하지 않아도 감전이 될 위험성은 다소 줄어든다. 물론 그래도 위험하다! 오디오 신호 입력 단자 다음에 신호용 트랜스포머를 삽입하는 것도 방법인데 절연등급이 이러한 구성을 감당할 수 있는지, 그리고 음질의 열화가 생기지는 않는지 고민해 봐야 한다.

가정으로 들어오는 교류에는 극성이 없다. 그러나 이 중에 어느 하나는 접지에 연결되어 있어서 손을 대도 안전하지만, 나머지는 그렇지가 않다. 네이버의 '골마루의 전기장판 이야기'는 이러한 사항을 아주 친절하게 설명해 놓았다.

20번째 이야기 - 전자파, 전기상식 2
21번째 이야기 - 전자파, 전기상식 3
22번째 이야기 - 전자파, 전기상식 4

Rob Robinette라는 사람은 이러한 구식 '과부 제조기 앰프(및 라디오 수신기)'의 실태를 소개하고 이를 안전하게 개조하는 방법을 설명하였다. 권선비가 1:1인 트랜스포머를 전원쪽에 삽입하는 것으로 위험을 제거할 수 있다.

Widowmaker Amps

내가 이토록 위험한 과부 제조기 앰프에 새삼스럽게 관심을 갖는 것은 실수로 구입한 단권 변압기(auto transformer)를 어떻게 해서든 활용을 해 보고 싶기 때문이다(트랜스포머 풍년). 단권 트랜스는 효율이 좋고 가벼우며 가격도 싸다. 물론 목숨을 담보로 호기심을 충족하는 것은 옳지 못하다!

단권 변압기는 이렇게 생긴 물건이다. 입출력 공통 단자에 AC 220V의 콜드 단자가 연결되면 그런대로 안전하다. 그러나 전원 콘센트에 반대로 플러그를 꽂으면 매우 위험하다.

출처: http://wiki.modulestudy.com/

따라서 핫과 콜드에 정확히 플러그가 꽂혀야 부하로 전원이 공급되게 만드는 회로('6N1+6P1 싱글 앰프, 멀리 이사를 오다'에서 소개한 유튜브 링크를 참조할 것)에 관심이 있는 것이다. 혹은 다음과 같은 회로(phase-neutral-earth fault indicator circuit)도 도움이 될 것이다.

출처: http://www.theorycircuit.com/phase-neutral-earth-fault-indicator-circuit-diagram/


감전 위험성이 해결된다 해도 220V 전원을 직접 다루는 것에 따르는 문제는 또 있다. 전원의 임피던스가 매우 낮은 상태라서 만약 앰프 회로 내부에서 단락이 일어나면 급격히 대전류가 흐른다. 이는 차단기나 퓨즈만으로 해결할 수 있는 것이 아니다. 만약 단권변압기를 통해서 어느 정도의 강압이나 승압이 이루어진다면 권선에 의한 임피던스가 조금은 작용할 것이다. 그러나 1차와 2차 전압이 별 차이가 없게 탭을 선택한다면(0-100-110-200-220V 단권 트랜스에서 200V 탭에 220V을 인입하고 220V탭에서 242V를 인출하는 경우) 사실상 입력과 출력을 그대로 연결하는 것이나 큰 차이가 없다. 그렇다면 앰프 회로에서 단락이 일어날 경우 그 결과는 매우 위험할 것이다. 200V 탭에 220V을 인입하는 것도 별로 바람직하지는 않다.

그런데 반도체 앰프와 달리 진공관은 망가지는 경우 단락이 일어나지 않고 보통 내부적으로 끊어지게 된다. 그래서 전원쪽 혹은 스피커 쪽에 무리를 주는 일은 좀처럼 생기지 않는다(고 믿는다).

일반적인 소출력 진공관 싱글 앰프라면 230~250V 정도의 전압을 전원트랜스 2차에서 뽑게 된다. 그렇다면 위에서 소개한 단권 트랜스(0-100-110-200-220V, 이디마트 기준 75VA급이 2만원)의 전원쪽에 보호 회로를 넣고(유튜브에서 회로를 따야 한다), 2차에서는 110V을 인출하여 배전압 정류를 하면 되지 않을까 생각한다.

위험 요소를 좀 더 조사한 다음 천천히 실험에 착수해 보겠다.

2019년 5월 8일 업데이트

전원트랜스가 없는 진공관 앰프는 110V를 사용하던 국가에서 주로 쓰인 것 같다. 감전 사고가 났을 때 220V의 위험도는 110V와 비교가 되지 않는다고 한다. 한번만 더 생각해 봐야 되겠다.

2019년 5월 5일 일요일

6N1+6P1 싱글 앰프, 멀리 이사를 오다

한달만에 대전 집을 찾아서 짐을 정리하고 왔다. 불필요한 짐을 가져다 놓고, 또 여름을 나기 위해서 필요한 물건을 챙겼다. 사실 본심은 어떻게 해서든 오디오를 들고 오는 것에 있었다. CD나 튜너는 상상하기 어려운 좁은 숙소에서 오직 유튜브와 KBS Kong을 소스로 쓰면서 어떻게 음악을 즐겨야 할까? 진공관 앰프 4대와, 그리고 스피커 3세트를 놓고 하룻밤 내내 밀린 음악을 들으며 어려운 결정을 내렸다.


최종 결정은 6N1+6P1 싱글 앰프(위 사진에서 앞줄 왼쪽 앰프)와 JBL FE-M2125로 내려졌다. 책상 위에 두기에는 다소 큰 스피커지만 검토 대상에 든 스피커 중에서 가장 균형이 있고 충실한 저음을 내 주었기 때문이다. Sensitivity는 87db/W/1m로 진공관 싱글 엔디드 앰프에 매칭하기에는 약간 불리하지만 좁은 청취 환경을 고려하면 그렇게 부족하지는 않다. 부피가 가장 작은 6J6 푸시풀 앰프도 고려 대상이었지만 기왕이면 내가 직접 만든 앰프를 택하고 싶은 욕망이 더 컸다. 6P1으로 말할 것 같으면... 현대 출력관 중에서 가장 싼 진공관이다!

6N1+6P1 싱글 앰프에는 자작 R코어 출력트랜스를 연결하였다. 전원 트랜스가 무려 3개나 내부에 들어 있어서 유도 험을 최소화하기 위해 배치에 신경을 썼다. 그러나 간격을 더 이상 줄 수가 없는 것이 안타까운 일이다. 실용적으로 큰 문제가 되지 않을 수준으로 만들어 놓았다.

어지러운 배선 상태. 공개하기에 심히 부끄럽다.

어쩌다가 전원 트랜스가 3개나 있는 앰프를 만들게 되었나? 그 이유는 지난 1월에 작성한 글 트랜스포머 풍년트랜스포머의 직렬연결에 소개하였다. 만약 220V 전원선에서 라이브와 뉴트럴을 매번 구별하여 사용할 수 있다면 용량에 비하여 크기가 훨씬 작은 단권 변압기를 가지고 안전하게 전원을 공급할 수 있을지도 모른다. 검색을 해 보니 이런 용도의 회로가 존재한다. AC reverse polarity indicator/protection circuit이라는 제목의 다음 동영상을 참조하면 단권 변압기를 안전하게 오디오 앰프용 전원 트랜스로 쓸 수 있는 회로를 꾸밀 수 있을 것 같다.



예비용으로 지난 2월에 구입한 실바니아 43 오극관도 오랜만에 오디오 작업을 하면서 정상적으로 소리가 나는지 확인하였다. 아무런 문제가 없다. 아래 사진의 앰프에 붙어있던 R코어 트랜스는 분당으로 출장을 왔으니 적당한 EI 코어 트랜스를 한 쌍 구입하여 달아주어야 되겠다.


올해의 오디오 자작 여건은 너무나 불리하다. 부품, 공구, 음원 등 모든 것들을 파견 근무지의 숙소에는 갖출 수 없기 때문이다. 이런 여건에서라도 뭔가 작은 것을 이루고 싶은데 아직은 아이디어가 부족하다.

2019년 5월 6일 업데이트

속된 말로 '구경이 깡패'라는 말이 있다. 렌즈의 구경이 클 수록 절대적으로 유리함을 뜻하는 것이다. 이는 스피커에도 그대로 적용할 수 있다. JBL FE-M2125를 한동안 쓰면서 이보다 구경이 작은 스피커는 앞으로 쓰지 말아야 되겠다는 생각을 하였다. 만약 자작을 하게 된다 해도 마찬가지일 것이다.


2019년 5월 3일 금요일

Circlator의 에러: Found spades but couldn't get version

Python 3.7을 기본으로 하는 conda 환경에 circlator를 설치하고 나서 필요한 모든 프로그램이 있는지를 확인하기 위해 circlator progcheck를 실행하였다. SPAdes의 권장 버전인 3.7.1은 바이너리 파일을 직접 받아서 설치한 상태이다.

그런데 SPAdes의 버전을 확인하지 못한다는 에러 메시지가 나온다.

Found spades but couldn't get version.

왜 그럴까? 구글 검색(관련글 링크)과 테스트를 거쳐서 찾아낸 이유는 파이썬 버전이 맞지 않기 때문이었다. 명령행에서 python `which spades.py`를 실행했을 때 오류 메시지를 출력하지 않아야 한다. 파이썬 3.6 환경에서 이를 실행하면 다음과 같은 메시지가 나온다.

== Error ==  python version 3.6 is not supported!

Supported versions are 2.4, 2.5, 2.6, 2.7, 3.2, 3.3, 3.4, 3.5

SPAdes 최신 버전은 물론 이런 문제를 일으키지 않을 것이다.

Base environment(python 2.7)에 circlator를 다시 설치하려고 시도하였는데 이상하게 시간이 많이 걸린다. 뭐가 잘못되었나? Circlator의 bioconda-recipe를 찾아 보았다. 파이썬 버전 3 이상을 요구하는 것처럼 보였다. 환경을 바꾸어서 LS-BSR environment(python 3.5)에 circlator를 설치하였다. Circlator spades 3.13.0이 포함되어 있지만 circlator progcheck를 하면 3.7.1을 권장한다는 메시지가 나온다. 

(ls_bsr) [hyjeong@tube ~]$ circlator progcheck
Circlator version: 1.5.5

External dependencies:
bwa	0.7.17	/opt/anaconda2/envs/ls_bsr/bin/bwa
WARNING: Didn't find canu in path. Looked for:canu
nucmer	3.1	/opt/anaconda2/envs/ls_bsr/bin/nucmer
prodigal	2.6.3	/opt/anaconda2/envs/ls_bsr/bin/prodigal
samtools	1.9	/opt/anaconda2/envs/ls_bsr/bin/samtools
WARNING: SPAdes version 3.13.0 is being used. It will work, but better results are usually obtained from Circlator using SPAdes version 3.7.1. Although 3.7.1 is not the latest version, we recommend it for Circlator.
spades	3.13.0	/opt/anaconda2/envs/ls_bsr/bin/spades.py

Python version:
3.5.6 |Anaconda, Inc.| (default, Aug 26 2018, 21:41:56) 
[GCC 7.3.0]

Python dependencies:
openpyxl	2.4.0-b1	/opt/anaconda2/envs/ls_bsr/lib/python3.5/site-packages/openpyxl/__init__.py
pyfastaq	3.17.0	/opt/anaconda2/envs/ls_bsr/lib/python3.5/site-packages/pyfastaq/__init__.py
pymummer	0.11.0	/opt/anaconda2/envs/ls_bsr/lib/python3.5/site-packages/pymummer/__init__.py
pysam	0.15.2	/opt/anaconda2/envs/ls_bsr/lib/python3.5/site-packages/pysam/__init__.py

SPAdes 3.7.1의 바이너리를 PATH에 추가한 뒤 다시 circlator progcheck를 하였다. 더 이상 SPAdes와 관련한 불평은 나오지 않는다. 대신 canu가 PATH에 없다는 경고가 나왔다. Assembler로서 canu와 SPAdes 중 어느 하나만 있으면 되니 별로 문제가 될 것은 없다. 오늘은 이것으로 nanopore sequencing 조립결과(pomoxis 사용)를 처리해 볼 것이다.

2019년 4월 28일 일요일

데이터과학 입문(Doing Data Science)

'데이터과학 입문(Doing Data Science)'은 지난주에 구입한 책의 제목이다. 토요일 아침 자동차 검사소에 가서 정기검사가 끝나기를 기다리면서 전체를 찬찬히 훑어보았다. O'Reilly사의 웹사이트를 방문하면 영문으로 된 소개와 목차를 볼 수 있다(링크). 연초에 학회에서 주최했던 하루짜리 머신러닝 교육에 참석했던 것이 기본적인 개념을 잡는데 도움을 주었다. 감염성 병원체의 유전체학 관련 연구를 하는 생명과학자인 나에게는 제12장 역학(Epidemiology)가 특히 중요하다.


빅데이터와 데이터과학의 현재 문제점은 무엇일까? 28쪽에서 다음과 같은 내용을 발견할 수 있다.
  1. 기본적인 용어에 대한 정의가 없다.
  2. 오랫동안 이런 대상을 연구해온 학계와 산업체 연구소 연구자들이 이상하게 존경을 받지 못한다.
  3. 열풍이 너무 지나치다.
  4. 통계학자들은 이미 자신들이 '데이터의 과학'을 연구하거나 수행하고 있으며, 그것이 자신의 직업적 일상이라고 느낀다...어쩌면 통계학자들은 여러분이 정체성을 도둑맞았을 떄 드는 느낌을 갖고 있을 것이다.
  5. '자신을 과학이라고 불러야 하는 어떤 것도 과학이 아니다'라는 말이 있다. (과학이 아니라 기예craft에 가깝다는 뜻도 된다)
데이터과학은 현 시점에서 정의가 구체화되어 가는 매우 새로운 학문이다. 현재의 정의에 완벽하게 만족하는 사람은 아직 적겠지만. '데이터화'가 매우 중요한 활동의 하나임은 부인할 수 없다.
일단 대상을 데이터화하면, 우리는 그것의 사용 목적을 바꾸고 그 정보를 새로운 형식의 가치로 전환할 수 있다(32쪽).
여기에서 '우리'는 사람들이 어떤 것을 구매하게 함으로써 돈을 버는 모형 개발가와 사업가들이고, '가치'는 자동화를 통해서 향상된  효율성과 같은 것을 의미한다. 데이터 도사geek가 갖춘 매력적인 기술은 통계학·데이터 변환·시각화이다.

저자 중 하나인 캐시 오닐은 어딘가 모르게 낯이 익다. 아, 그렇다! '대량살상 수학무기'를 쓴 수학자이다(독후감). 알고리즘이니 데이터 모형이니 하는 것이 인간의 삶에서 더 많은 부분을 좌지우지하는 것을 경고하는 이 책은 미국에서 2016년에 출판되었다. 그러면 캐시 오닐은 '데이터 사이언스 입문'을 언제 출간하였을까? 이보다 앞선 2013년이었다. '대량살상 수학무기'라는 책을 이보나 나중에 냈다고 해서 캐시 오닐이 데이터 사이언스 자체에 회의적으로 바뀌었다고 볼 수는 없다. 칼이 사람을 찔렀다고 해서 주방에서 칼을 몰아낼 수는 없는 노릇 아니겠는가? 가치 중립적인 도구의 장단점을 제대로 파악하고 좋은 의도에서 이를 활용하려는 마음가짐을 갖고 있는 한 지나치게 우려를 할 필요는 없을 것이다.

2019년 상반기의 목표는 이 책을 통독하고 실습을 위해 필요한 수준으로 R 활용 능력을 향상시키는 것이다. 정확히 자리를 잡지 못하고 뇌세포 사이를 떠돌던 핵심 개념들도 제 자리를 잡게 될 것으로 믿는다

300B 싱글 앰프

진공관 앰프를 사랑하는 사람이라면 누구나 최종 목적지로 도착한다는 직열 삼극관 300B 싱글 앰프. 인터넷을 통해서만 보았던 300B 싱글 앰프를 어제 제이앨범 정기 모임에서 처음으로 만나보았다(모임 소식). 오디오 니르바나의 풀레인지 스피커를 쾅쾅 울려주던...


PSVANE의 300B. 흔히 '푸스반느'라고 읽는데 맞는지는 모르겠다.
위키피디아의 설명에 의하면 300B는 1938년 미국의 웨스턴 일렉트릭에 의해 처음 만들어진 삼극관으로, 전화 선로의 신호를 증폭하기 위한 목적으로 개발된 것이다. 그런데 1980년대에 일본의 오디오파일에 의해서 가정용 오디오 앰프 자작용으로 인기를 끌게 되었다. 이때의 열풍이 결코 합리적인 것은 아니었다는 평도 없지는 않다.

웨스턴 일렉트릭은 이제 잊혀진 회사가 되었고 지금은 작은 회사에 의해서 브랜드가 유지되고 있다. 현재 몇 회사에서 300B가 만들어지고 있는데, 2018년 웨스턴 일렉트릭의 원래 이름을 달고 재발매가 되었다고 한다(링크). Matched pair는 무려 1499 달러!

'내 평생 이것 하나는 만들어 보겠다'는 목표가 이제 조금씩 생겨나려고 한다. 집에 두고 온 앰프를 이곳 숙소로 가져오는 것부터 먼저 시도하고 볼 일이다.

2019년 4월 25일 목요일

CentOS 7 업그레이드 후 docker 설치 및 docker pull 실행에 성공하다

모든 문제는 SSL 인증서로 귀결된다. 회사 프록시 서버가 중간 과정에서 인증서를 건드리면서 Somansa라는 '비공인' 인증기관의 것으로 바꾸어서 내부 클라이언트로 전달하고, 응용프로그램에서는 이를 인정하지 못하겠다며 거부한다. 자체 인증서에 대한 CA bundle 위치를 제시하려 해도 응용 프로그램마다 그 방법이 전부 제각각이라는 것이 문제이다.

지난번 글 회사 프록시 서버 뒤에서 docker pull을 실행하지 못하는 문제에 도전해 보자는 결국 성공하지 못했다. 인증서 문제가 발생하지 않는 컴퓨터(예를 들어 윈도우에 설치한 docker)에서 이미지를 받은 뒤 이를 리눅스 서버로 옮겨서 docker run을 하는 우회 방법도 시도하였지만 만족스럽지 않았다. 그래서 CentOS 7으로 업그레이드를 하는 것에서 모든 것을 다시 시작하기로 했다. CentOS 6에서 설치 가능한 docker는 너무 옛날 것이고, 인터넷에서 찾아낸 사용자 지정 CA bundle 설치법도 잘 먹히질 않았다.

Docker 자체를 설치하는 것으로부터 시작해 본다. 다음의 docker 공식 문서 사이트를 참조하였다.

Get Docker CE for CentOS

시작부터 순탄하지 않다. https://로 시작되는 주소에 있는 repo 파일을 가져오는 것부터가 문제다.

# yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo
Loaded plugins: fastestmirror, langpacks
adding repo from: https://download.docker.com/linux/centos/docker-ce.repo
grabbing file https://download.docker.com/linux/centos/docker-ce.repo to /etc/yum.repos.d/docker-ce.repo
Could not fetch/save url https://download.docker.com/linux/centos/docker-ce.repo to file /etc/yum.repos.d/docker-ce.repo: [Errno 14] curl#60 - "Peer's certificate issuer has been marked as not trusted by the user.

wget(--no-check-certificate)으로 repo 파일을 받은 다음, 각 엔트리에 대해서 sslverity=0을 삽입한다. 이렇게 수정한 파일을 가지고 다시 yum-config-manager를 실행하라. 그리고 이후 과정을 통해서 docker 관련 패키지를 설치한 다음에 최초의 docker pull 명령을 실행하면 익숙한 에러 메시지가 나온다('x509: certificate signed by unknown authority').

# yum-config-manager --add-repo docker-ce.repo
# yum install docker-ce docker-ce-cli containerd.io
# systemctl start docker
# docker pull hello-world
Using default tag: latest
Error response from daemon: Get https://registry-1.docker.io/v2/: x509: certificate signed by unknown authority

이제부터는 방법을 잘 알고 있다. CentOS 6 시절에 너무나 여러번 반복을 했기 때문이다. 물론 실패했지만... 하지만 CentOS 7에 깨끗한 docker CE를 설치했다면 이야기는 달라진다.

# cp _path_to_/Somansa_ROOT_CA.cer /etc/pki/ca-trust/source/anchors/
# update-ca-trust force-enable
# update-ca-trust extract
# systemctl restart docker
# docker run hello-world

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

만약 내가 전산망 보안이 까다로운 회사로 오지 않았더라면 프록시 서버로 보호받는(?) 내부에서 SSL 인증서와 엮인 어려움을 전혀 알지 못했을 것이고, CentOS 7 업그레이드도 적어도 반년 뒤에나 시도했을 것이다. 어려움은 도전을 낳고 많은 경우에 해결이 된다. 속이 다 시원하다!

2019년 4월 24일 수요일

회사 프록시 서버는 DFAST의 reference database 다운로드도 어렵게 한다

비슷한 제목의 글을 연일 작성하게 되었다.
회사 프록시 서버는 ....을 어렵게 한다.
https://로 시작하는 곳을 접속하여 파일을 가져오는 것을 어렵게 하는 문제를 4월 초부터 하나씩 해결을 해 나갔다. 이제는 거의 다 해결을 했다고 생각했는데, 파이썬 코드 안에서 urllib 모듈을 사용하여 파일을 다운로드하는 request 메소드의 실행에서 문제가 벌어졌다. 라이브러리, 모듈, 함수, 메소드에 대한 정확한 정의는 일단 무시하도록 하자. 나는 파이썬 코드를 직접 쓰는 사람이 아니고 파이썬 응용프로그램을 설치하고 사용만 하는 사람이므로.

미생물 유전체 주석화 파이프라인의 대명사인 prokka와 병행하여 사용할 다른 프로그램을 검토 및 테스트하는 중에 벌어진 일이다. 일본에서 개발한 DFAST의 참조 데이터베이스를 설치하는 과정에서 또다시 SSL 인증 불가 문제가 드러난 것이다. wget/curl/pip를 실행하는 과정에서 SSL 인증을 건너뛰는 방법은 이제 충분히 알아낸 상태이지만, 코드 내에서 실행되는 함수 수준에서 벌어지는 에러라면 어떻게 할 것인가?

# python scripts/file_downloader.py --protein dfast
No handlers could be found for logger "dfc.utils.path_util"
Downloading DFAST reference. Files will be written into '/usr/local/apps/dfast_core/db/protein'
Traceback (most recent call last):
  File "scripts/file_downloader.py", line 169, in <module>
    retrieved_file = retrieve_dfast_reference(db_name, out_dir)
  File "scripts/file_downloader.py", line 74, in retrieve_dfast_reference
    request.urlretrieve(target_url, output_file)
  File "/usr/lib64/python2.7/urllib.py", line 94, in urlretrieve
    return _urlopener.retrieve(url, filename, reporthook, data)
  File "/usr/lib64/python2.7/urllib.py", line 240, in retrieve
    fp = self.open(url, data)
  File "/usr/lib64/python2.7/urllib.py", line 208, in open
    return getattr(self, name)(url)
  File "/usr/lib64/python2.7/urllib.py", line 437, in open_https
    h.endheaders(data)
  File "/usr/lib64/python2.7/httplib.py", line 1037, in endheaders
    self._send_output(message_body)
  File "/usr/lib64/python2.7/httplib.py", line 881, in _send_output
    self.send(msg)
  File "/usr/lib64/python2.7/httplib.py", line 843, in send
    self.connect()
  File "/usr/lib64/python2.7/httplib.py", line 1260, in connect
    server_hostname=sni_hostname)
  File "/usr/lib64/python2.7/ssl.py", line 348, in wrap_socket
    _context=self)
  File "/usr/lib64/python2.7/ssl.py", line 609, in __init__
    self.do_handshake()
  File "/usr/lib64/python2.7/ssl.py", line 831, in do_handshake
    self._sslobj.do_handshake()
IOError: [Errno socket error] [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:618)

문제가 되는 것은 file_downloader.py 스크립트의 다음 줄이다.

    from urllib import request
    ...
    request.urlretrieve(target_url, output_file)

SSL verification 여부를 함수의 인자에 줄 수 있는 것 같지는 않다. pip 말고 파이썬 자체가 참조하는 인증서 번들 위치를 찾아서 Somansa의 루트 인증서 파일을 넣어도 될 것이다. 그런데 어디인지를 잘 모르겠다. 인증서 번들이라 해도 중간 단계 인증서는 없으므로 소만사에서 발급한 것 하나면 충분하다.

문제 해결 답안의 보물창고인 StackOverflow에서 힌트를 발견하였다. PYTHONHTTPSVERIFY 환경변수를 0으로 놓으면 된다.

urllib and "SSL: CERTIFICATE_VERIFY_FAILED" Error

# PYTHONHTTPSVERIFY=0 python scripts/file_downloader.py --protein dfast

환경변수 설정과 명령어를 한 줄에 놓는 것은 처음에는 매우 어색하게 느껴졌었다. 그러나 지금은 매우 익숙해졌다. 여기에서 PYTHONHTTPSVERIFY는 환경변수인가 쉘변수인가? 여기여기를 방문하여 잠깐 생각해 보도록 하자.

2019일 4월 25일 업데이트

HMMer와 RPS-BLAST 데이터베이스를 다운로드하는 과정에서 또다시 문제가 발생하였다.

# python scripts/file_downloader.py --cdd Cog --hmm TIGR

다운로드한 파일의 압축을 풀고 hmmpress를 실시하는 등의 후처리가 돌아가야 이 작업이 완료된다. 그런데 다운로드 자체가 원활하지 않아서 파일을 받다가 만 상태로 다음 과정으로 진행하는 것이다. 그래서 소스 코드를 참조하여 완전한 형태의 두 파일을 wget으로 미리 받은 다음(중간에 접속이 끊겨도 재전송이 가능), 다운로드 명령을 무력화한 소스 코드를 재실행하는 것으로 마무리하였다. 파이썬을 잘 알지 못하는 상태에서 소스를 고친다는 것이 대단히 부담스러웠다. 한 일이라고는 '#'를 소스 내 두 줄의 시작 부분에 삽입한 것이 전부였지만.

2019년 4월 23일 화요일

회사 프록시 서버는 R 라이브러리 패키지 설치도 어렵게 한다

epel 저장소 정보 파일의 주소 정보(baseurl) 라인을 활성화하여 CentOS 7에서 R rpm 패키지가 설치되도록 만들고 나서 일반 사용자 권한으로 필요한 R 라이브러리를 설치하려 하였더니 또 SSL 인증서와 관련한 에러가 발생하였다. 이젠 정말 지긋지긋하다!

> install.packages("BiocManager")
‘/home/hyjeong/R/x86_64-redhat-linux-gnu-library/3.5’의 위치에 패키지(들)을 설치합니다.
(왜냐하면 ‘lib’가 지정되지 않았기 때문입니다)
--- 현재 세션에서 사용할 CRAN 미러를 선택해 주세요 ---
경고: failed to download mirrors file (URL 'https://cran.r-project.org/CRAN_mirrors.csv'를 열 수 없습니다); using local file '/usr/share/doc/R-3.5.2/CRAN_mirrors.csv'
경고: 저장소 https://cran.ism.ac.jp/src/contrib에 대한 인덱스에 접근할 수 없습니다:
  URL 'https://cran.ism.ac.jp/src/contrib/PACKAGES'를 열 수 없습니다
경고메시지(들): 
1: In download.file(url, destfile = f, quiet = TRUE) :
  URL 'https://cran.r-project.org/CRAN_mirrors.csv': status was 'Peer certificate cannot be authenticated with given CA certificates'
2: 패키지 ‘BiocManager’(들)이 사용가능하지 않습니다 (그 이유는 for R version 3.5.2 입니다) 

Somansa의 Root 인증서 위치를 지정하는 옵션이 어딘가에 있을 것이라 생각하고 구글을 검색해 보았다. 홈 디렉토리의 .Renviron 파일에 이를 넣으면 된다고 한다. 힌트는 [StackOverflow] R Server: install.packages() certificate error에서 얻었다.

$ cat .Renviron 
CURL_CA_BUNDLE=.cert/Somansa_ROOT_CA.cer

다음은 bioconductor를 설치한 뒤의 모습이다.

> library(BiocManager)
Bioconductor version 3.8 (BiocManager 1.30.4), ?BiocManager::install for help

Somansa가 가로채기(?)를 하여 만들어 놓은 '자체 인증서' 문제는 앞으로 또 무슨 프로그램의 설치 작업에서 불거져 나올지 자못 궁금하다.

[CentOS 7] yum으로 R을 설치하지 못하던 문제를 해결하다(epel-repo)

epel(Extra Packages for Enterprise Linux)-release를 설치한 다음 R을 yum으로 깔려고만 하면 "One of the configured repositories failed"메시지가 나타나는 현상에 직면하였다. epel 저장소에 분명히 문제가 있는 것 같은데 구글을 뒤져보아도 마땅한 해결 방법을 찾기가 어려웠다. 그래서 conda base environment에 우선 설치를 해 놓은 다음, yum을 이용한 방법에 다시 도전하였다.

다음의 글에서 힌트를 얻었다.

[SOLVED] One of the configured repositories failed (Unknown)

/etc/yum.repos.d/epel.repo 파일을 열어서 baseurl= 앞의 '#'를 제거하고, metalink= 줄은 주석 처리를 하였다. 아마도 metalink 주소에 문제가 있는 것 같다. epel-repo 파일을 수정한 다음 yum install R을 실행하니 245개나 되는 패키지를 시원스럽게 다운로드하여 설치가 완료되었다.


[epel]
name=Extra Packages for Enterprise Linux 7 - $basearch
baseurl=http://download.fedoraproject.org/pub/epel/7/$basearch
#metalink=https://mirrors.fedoraproject.org/metalink?repo=epel-7&arch=$basearch
failovermethod=priority
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7

의존성이 있는 프로그램을 한방에 설치해 주는 데에는 conda만한 것이 없다. Qiime 2 정도가 되면 bioconda의 힘을 빌리지 않고 설치하는 것은 정말 고통스러울 것이다(실제로 공식 문서 사이트에서는 소개하고 있지도 않다). 그러나 구체적인 애플리케이션에 대하여 너무 개별적으로 환경을 만들어 주는 것은 그렇게 바람직하다고 생각하지 않는다. 가능하다면 다소 수고스럽더라도 의존성을 해결해 가면서 하나씩 해결을 하려는 노력을 아끼지 않는 것이 중요하다고 본다. Prokka나 Roary 정도라면 직접 설치를 할만하다. 그리고 bioconda라고 해서 의존성 있는 프로그램/라이브러리를 전부 자동으로 설치해 주는 것은 아님에 유의해야 한다. 따라서 설치법 문서를 주의 깊게 읽어야 한다.

그럼에도 불구하고 Sanger Institute의 Artemis는 bioconda를 이용하여 설치하였다. 왜냐하면 수작업으로 설치할 때 필요한 Apache Maven을 아직 잘 이해하지 못했기 때문이다.

어제는 집에서 사용하는 노트북 컴퓨터에 자바 런타임을 설치하려고 다운로드 사이트에 갔더니 오라클에 유저 등록을 하라는 메시지를 접하게 되었다. 예전에는 라이선스에 동의하는 것만으로도 설치 파일을 내려받을 수 있었는데... 돈이 드는 것은 아니지만 그동안 편리하게 사용한 것에 대해 이 정도의 수고는 감수해야 할 것이다.

2019년 4월 22일 월요일

도대체 내가 Perl 사용자 자격이 있는가?

오랫동안 Perl을 사용해 왔고, 가끔 초보 수준의 스크립트를 짜면서 '아무리 지저분해도 어쨌든 돌아가면 된다(혹은 한 가지 목적을 달성하는 방법은 여러 가지가 있다)'는 순진한 생각이 Perl의 기본 정신과 맞닿아 있다는 안이한 생각에 빠져 있었다. 그런데 이번에 CentOS 7을 새롭게 설치한 뒤 Perl module을 하나씩 재설치하면서 기본이 없어도 너무 없다는 생각을 갖게 되었다. 아무리 경험이 많아도 정확한 지식을 기반으로 한 것이 아니라면 사상누각과 같지 않겠는가?

일반 사용자 권한으로 Perl -MCPAN -e shell(혹은 명령행에서 cpan 실행)을 처음으로 실시하면 다음과 같은 질문을 던진다. 펄 라이브러리 디렉토리에 쓰기 권한이 없으니 어떻게 할 것이냐는 뜻이 되겠다.

Warning: You do not have write permission for Perl library directories.

To install modules, you need to configure a local Perl library directory or
escalate your privileges.  CPAN can help you by bootstrapping the local::lib
module or by configuring itself to use 'sudo' (if available).  You may also
resolve this problem manually if you need to customize your setup.

What approach do you want?  (Choose 'local::lib', 'sudo' or 'manual')
 [local::lib] 

관리자 권한으로 이 명령을 불러냈음에도 불구하고 왜 local::lib을 쓴다고 했는지 모르겠다. 그러니 .bashrc에 일반 사용자는 접근할 수 없는 위치로PERL_LOCAL_LIB_ROOT PERL_LOCAL_LIB_ROOT PERL_LOCAL_LIB_ROOT PERL_LOCAL_LIB_ROOT 등의 변수가 줄줄이 선언되어서 root를 제외하고는 접근을 하지 못하게 된 것 아니던가.

어떤 펄 모듈의 설치 위치를 알고 싶다면 'perl -I 모듈명'을 입력하면 된다. 다음의 결과를 보라. 빨간색 디렉토리는 local::lib을 쓰겠다고 하는 바람에 root 디렉토리 아래의 위치로 설정된 환경변수를 나타낸다. 상황이 이러하니 BioPerl을 설치했다고 믿었음에도 불구하고 일반 사용자로는 이를 쓸 수 없었던 것이다.

# perldoc -l Bio::Perl
/root/perl5/lib/perl5/Bio/Perl.pm
# perl -e 'print join "\n", @INC; print "\n"'
/root/perl5/lib/perl5/5.16.3/x86_64-linux-thread-multi
/root/perl5/lib/perl5/5.16.3
/root/perl5/lib/perl5/x86_64-linux-thread-multi
/root/perl5/lib/perl5
/usr/local/lib64/perl5
/usr/local/share/perl5
/usr/lib64/perl5/vendor_perl
/usr/share/perl5/vendor_perl
/usr/lib64/perl5
/usr/share/perl5
.

/root/.cpan/CPAN/MyConfig.pm을 삭제한 다음, BioPerl installation 문서에 나온 방법을 이용하여 다시 BioPerl을 설치하였다. 이번에는 /usr/local/share/perl5 아래에 제대로 펄 모듈들이 위치하였다.

App::cpanminus

cpan은 기본적으로 말이 많다. 그것이 성가시다면 cpanminus를 쓰면 된다. Perl이 설치된 시스템에 cpan은 자동적으로 따라오지만, cpanminus는 그렇지 않으니 추가적으로 깔아야 한다. cpan과 마찬가지로 App::cpanminus는 cpanm이라는 스크립트를 통해서 실행된다. 

많은 펄 모듈이 rpm 패키지로도 제공됨을 기억하면 좋다. 즉, cpan 혹은 cpanm 명령이 아닌 yum 명령으로 설치할 수도 있다는 것이다. 내가 App::cpanminus의 rpm 패키지를 설치했던가? 패키지의 이름은 약간 다르므로 주의해야 한다.

$ rpm -qa | grep perl-App-cpanminus
perl-App-cpanminus-1.6922-2.el7.noarch

설치가 된 상태였다. 이를 지우고 관리자로 전환한 다음 cpan에서 App::cpanminus를 실행해 보았다. 앗, 왜 다시 root 디렉토리에 설치를 하는 것인가?

Running make install
Manifying 1 pod document
Manifying 2 pod documents
Installing /root/perl5/lib/perl5/App/cpanminus.pm
Installing /root/perl5/lib/perl5/App/cpanminus/fatscript.pm
Installing /root/perl5/man/man1/cpanm.1
Installing /root/perl5/man/man3/App::cpanminus::fatscript.3pm
Installing /root/perl5/man/man3/App::cpanminus.3pm
Installing /root/perl5/bin/cpanm
Appending installation info to /root/perl5/lib/perl5/x86_64-linux-thread-multi/perllocal.pod
  MIYAGAWA/App-cpanminus-1.7044.tar.gz
  /usr/bin/make install  -- OK

생각을 해 보니 조금 전에 .bashrc에서 Perl 관련 환경변수를 삭제한 뒤에 다시 로그인을 하지 않아서 그런 것이었다. /root/perl5 디렉토리를 제거하고 로그아웃 후 다시 들어와서 cpan을 실행한 다음 'install App::cpanminus'를 실행하여 보았다. 예상한대로 /usr/local/share/perl5 아래에 제대로 설치가 되었고, 명령 프롬프트에서 cpanm을 실행해도 문제가 없다. cpanm 스크립트의 위치(/usr/local/bin/cpanm)은 yum으로 perl-App-cpanminus를 설치했을 때와는 다르다(/usr/bin/cpanm).

Perl의 패키지 관리 시스템은 허술해 보이기도 하지만 또 그런대로 유연하다. Perl package manger(PPM)은 파이썬으로 치자면 pip에 해당하는 것인가? 하지만 펄 라이브러리 설치 위치만 잘 기억하고 있으면 cpan(m)만으로도 충분하다고 생각한다. 몇 개의 환경변수, 그리고 @INC를 잊지 말자.

네이버 그린팩토리 방문

경기도 성남시 분당구 정자동에 위치한 네이버 신사옥 건물을 그린팩토리라고 부른다. 1층및 2층에 있는 도서관은 일반에게 개방이 되어 있다고 하여 무작정 가 보기로 하였다. 개인적으로 네이버를 별로 좋아하지는 않는데 네이버가 제공하는 대중 시설을 이용하는 것은 과연 옳은 일인가? 변절인가?

Do the right thing.

내가 스스로에게 부여한 좌우명에 해당하는 말이다. 나는 이를 '옳은 일을 해라' 정도로 생각하고 있다. 그런데 스파이크 리 감독의 1989년 영화의 제목 역시 Do the right thing('똑바로 살아라'로 번역)이다. '똑바로 살아라!'라고 하면 약간의 권위의식을 가지고 나무라는 것 같아서 별로 마음에 들지 않는다.

내가 현재 살고 있는 곳에서 산보 삼아 걸어서 네이버 그린 팩토리 도서관에 갈 수 있다는 것은 대단히 즐거운 일임에는 틀림이 없다. 잡지를 볼 수 있는 1층 공간은 회원 가입을 하지 않아도 자유롭게 출입이 가능하다. 이용 시간은 저녁 7시 반까지이다. 상당히 많은 잡지가 있어서 놀랐고, 그러한 반면 국내 잡지는 찾기가 쉽지 않았다. 영문 잡지명 기준으로 분류가 되어 있어서 그런것인지, 아니면 국내 잡지가 적어서 그런 것인지는 잘 모르겠다. 만약 네이처의 책장을 넘기면서 보고 싶다면 이곳을 찾으면 되겠다. 그렇다면 네이처 제네틱스는? 네이처 리뷰스 마이크로바이올로지는? 자매지까지 총망라하고 있는 것은 아니다. 스카이&텔레스코프를 여기서 볼 수 있어서 참 새로웠다.

비즈니스 관련 국내 잡지 몇 권을 읽으면서 머릿속이 새로운 생각으로 차오르는 느낌이 들었다. 그렇다. 잡지를 읽는다는 것이 바로 이런 것이로구나! 내가 종사하는 분야의 최신 논문을 늘 옆에 끼고 읽지 못하고 있다는 죄책감에 시달릴 필요가 없었다. 세상을 돌아가게 하는 큰 흐름을 읽는 것이 더 중요하다는 생각이 문들 들었다. 수첩을 들고 가지 못한 것이 너무 아쉬었다.
성공은 계획되지 않는다. 나중에 설명될 뿐이다.
어차피 도와줄 것이라면 특별한 도움이라는 것을 넌지시 알려주면 흔쾌히 도와주는 게 좋다.
(사내)정치란 관계의 정립이다. 자기 주변의 관계를 다음과 같이 정립하라.

오래 고민을 하고 궁리할수록 좋은 답이 나온다는 것이 나의 신념이었다. 그러나 판단은 빨리 내려야 한다. 판단과 이에 따르는 실행을 뒤로 미루기 위해 궁리를 계속 하고 있다면 그것은 옳은 일이 아니다. 특히 CEO는 70% 정도의 확신이 들 때 빨리 실행에 옮기고, 만약 잘못된 길을 가고 있다는 생각이 들면 빨리 고쳐나가는 것이 더 옳다는 글을 보고 많은 생각을 하였다. 당장 실행에 옮기는 것이 중요하다고 해서 날을 세우지 않은 톱으로 나무를 자를 수는 없는 노릇 아닌가. 빠른 결정과 실행이 곧 준비가 부족해도 됨을 의미하는 것은 아닐 것이다. 그럼에도 불구하고 모든 것을 미리 다 계획하여 단 하나의 예외도 발생하지 않을 것을 기대하고 추진을 하는 것은 너무 아름답지 못하다.


오늘 네이버 그린팩토리 방문은 계획한 일이 전혀 아니었다. 물론 아내가 같이 가자고 계속 얼마 전부터 권하기는 했었지만. 실패의 가능성까지 염두에 두고 일단 실행해 보는 것. 그것이 내게 필요한 자세이다.







2019년 4월 21일 일요일

Windows 7 지원의 종료가 멀지 않았다

사무실에서 사용하는 PC는 아직도 Windows 7을 고집하고 있었다. 2020년 1월 14자로 이것의 지원이 종료된다고 하니 익숙한 인터페이스에 작별을 고할 때가 멀지 않았다.

https://support.microsoft.com/ko-kr/help/4057281/windows-7-support-will-end-on-january-14-2020

내가 원래의 근무지에서 일하고 있었다면 설치매체를 대여하여 업그레이드를 한 다음 라이선스를 적용하면 모든 것이 해결된다. 그러나 지금은 장비를 반출하여 파견 근무지에 와 있으니 절차를 까다롭게 생각해 봐야 한다. 파견 근무지의 사이트 라이선스 계약을 파악하기 전에 내가 들고 온 PC에 파견지에서 제공하는 윈도우10을 설치할 수는 없을 것이다. 최악의 경우, PC를 들고 대전으로 출장을 가서 업그레이드를 한 다음 다시 가져와야 할지도 모른다.

윈도우 7이 출시된 것이 2009년 10월 22일이었다고 한다. 윈도우10의 공식 발매는 2015년 7월 29일. 10년 동안 소프트웨어 제품을 유지했다면 충분히 오랜 기간 노력을 한 것이다. 얼마 전에 아직 쓸만한 진공청소기의 부품(공기 배출구쪽의 필터)를 사러 갔더니 더 이상 보유하고 있지 않다고 하였다. 비록 먼지봉투는 여러 기종에서 공통으로 쓰이므로 아직 원활하게 구입을 할 수 있었다. 부품 보유 여부가 매우 중요하게 작용하는 자동차의 경우 부품 보유 기간은 생산 중단 시점으로부터 8년이라고 한다.

산업과 경제를 생각한다면 오래된 것은 가급적 버리고 새 것을 사는 것이 좋다. 어제 국립현대미술관 서울관에서 보았던 아스거 욘(Asger Jorn)의 설치작품 '삼면 축구'을 재현해 놓은 것에 이런 말이 적혀 있었다. '미래는 과거를 잊고 파괴하는 일에서 시작된다(정확하게 기억하는 것은 아님)'는...




환경을 생각한다면 낡은 것도 되도록 고쳐서 쓰는 것이 좋다. 그렇다면 손에 잡히지 않는 생각은 어떠한가?

2019년 4월 18일 목요일

CentOS 7로 업그레이드하기

연말까지는 되도록 업그레이드를 하지 않고 CentOS 6.10로 버티려고 했었으나 땜질 처방만으로 유지하는 것에는 한계가 있다고 생각하여 단호하게 업그레이드를 하기로 결심하고 즉시 실행에 옮겼다. 업무용(대부분 생명정보 분석용) 프로그램의 설치가 쉬운 Ubuntu 16.04로 갈아타는 문제도 한참을 고민하였지만 공용 서버로서 안정적이고 보수적인 운영을 원한다면 CentOS 7이 나을 것으로 최종 결정을 하였다.

언제나 그렇듯이 한 번의 시도에 흡족할 수준으로 설치가 되지는 않았다. 리눅스를 설치할 때마다 늘 혼동스러운 것은 하드디스크의 파티션 과정이다. 완전 자동으로 파티션을 하도록 만든 다음 설치를 마치고 났더니 /은 겨우 50 GB에 불과하고 나머지를 전부 /home으로 만든 것이 아닌가. 추가로 설치할 응용 프로그램이 상당히 많은데 이를 전부 심볼릭 링크로 만들 수는 없는 노릇이다. 다시 설치를 시도하였다. 요즘도 swap 파티션이 꼭 필요한 것인가하는 생각이 들기도 하고... 자동으로 생성한 파티션에서 swap 크기가 이 얼마였는지 확인을 해 보지 않고 재설치를 하고 말았다. df 명령으로는 swap 파티션이 보이지 않으므로 swapon -s 명령을 써야 한다(오늘 알게 된 사실).

'Swap 파티션의 크기는 대략 메모리의 두 배'라는 옛날의 기준을 수백 기가 바이트의 메모리가 장착된 요즘의 컴퓨터에도 적용해야 할까? 그렇지는 않으리라. 내 컴퓨터의 메모리는 256 GB이다.

Red Hat Enterprise Linux 권장 swap 크기는 어떻게 되나요?

16 GB면 충분한 것을, 무려 100 GB나 잡아 놓았다!!

CentOS 7로 업그레이드를 하니 예전에 즐겨 사용하던 palimpsest 디스크 유틸리티는 보이지 않고 거의 비슷한 외관의 gnome-disk-utility가 있다. 100 GB나 되는 공간이 swap으로 떡하니 자리를 차지하고 있는 것을 보니 안타깝다. 그놈 디스크 유틸리티(혹은 gparted)에서 구동 중인 하드디스크의 파티션을 조정하는 것이 가능한 것 같다(참고). 다만 바뀐 UUID를 수동으로 다시 맞추어 주어야 한다.

OS를 새로 설치하니 UID와 GID가 바뀌어서 NFS로 물린 시놀로지 NAS의 자료를 고치기가 어렵게 되었다. 계정명은 동일하지만 ID는 501에서 1001로 바뀌었으니 디렉토리와 파일이 주인을 잃은 상태가 되었다. 같은 시스템 안에 있던 RAID 공간에 있던 것들은 chown 명령으로 복구를 하였지만 NFS로 물린 것은 이렇게 고쳐지지 않는다. usermod 혹은 groupmod 명령어를 쓰는 것은 별로 권장할 일이 아닌 것 같다. 왜냐하면 홈 디렉토리 이외의 것에 대해서는 자동으로 고쳐지지 않기 때문이다. 또한 여기에 새로 만드는 파일 및 디렉토리의 권한은 777이 된 상태이다. NAS쪽에서 설정을 바꾸어야 하는 것일까? 보안과 squash 필드의 의미를 정확히 아는 것이 필요하다.

로컬 네트워크(NFS) 내에서 Synology NAS의 파일에 액세스하는 방법

아직도 해결할 일이 많이 남았다.

2019년 4월 21일 업데이트

새로 OS를 설치하는 것이니만큼 Perl 모듈도 깨끗하게 깔고자 하였으나 원하는대로 잘 되지는 않았다. 관리자 권한으로 perl -MCAPN -e shell 명령을 사용하여 BioPerl 설치 진행을 하였더니 루트의 홈 디렉토리에 펄 base directory가 지정되는 별로 바람직하지 않은 결과가 되었다. 여기에다가 필요에 의해 rpm 및 conda environment로 설치한 모듈까지 뒤죽박죽이 되고 말았다. prokka나 roary처럼 Perl 모듈에 대한 의존도가 높은 프로그램을 설치할 때 특히 주의를 해야 하는데 그렇게 하지를 못했다.

만약 내가 사용하려는 프로그램이 XML::Simple을 필요로 한다고 치자. perl -MCPAN -e shell 명령으로 설치를 했다 하더라도 yum install perl-XML-Simple 명령을 내리면 이미 시스템에 존재하는지를 확인하지 않고 중복하여 설치하는 것 같다. bioconda 패키지의 설치 역시 그런 것 같다.

앞으로 conda 환경이 아닌 시스템에서 직접 Perl 모듈을 설치할 때에는 CPANMinus(또는 CPANM) 유틸리티를 사용하는 것이 좋을 것이다. 그러려면 CPANM 자체를 설치하는 방법도 알아야 한다. App::cpanminus를 직접 설치하거나, 아니면 perl-App-cpanm rpm 패키지를 yum으로 설치하는 방법이 있다.

NAS의 최상위 디렉토리에서 파일이나 디렉토리를 만들면 777 권한이 되지만, 새로 만든 디렉토리의 권한을 적당히 바꾼 뒤 그 하위에 새로운 파일 또는 디렉토리를 만들면 umask에서 원래 설정한대로 되는 것을 확인하였다. Synology NAS쪽에서는 소유자가 잘못된 파일 등을 웹으로 접속하여 지우는 것 정도로만 마무리를 하였다.

2019년 4월 11일 목요일

회사 프록시 서버 뒤에서 docker pull을 실행하지 못하는 문제에 도전해 보자

프록시(proxy) 서버란 네트워크 서비스의 중계 역할을 하는 장비를 일컫는다. 과거에는 IP 주소를 세탁하고 접속이 차단된 곳을 둘러서 연결하게 만드는 뭔가 음험한 물건으로만 생각했었다. 원래 이 장비는 네트워크 트래픽을 줄이기 위한 목적으로 쓰는 것이라 하였다. 즉, 한번 접속해서 가져왔던 정보를 프록시 서버의 캐시에 저장해 둔 뒤, 같은 내용을 클라이언트에서 요청하는 경우 캐시의 것을 재전송함으로써 다시 원격 서버에 연결을 할 필요가 없게 만드는 것이다.

도대체 프록시 서버가 나와 무슨 관계가 있을까? 집에서 편히 앉아서 고속 인터넷망으로 접속을 하는 경우라면 프록시 서버의 존재에 신경을 쓸 필요가 없다. 그러나 회사 내 전산망이라면 사정은 다르다. 업무와 무관한 웹사이트의 접속을 차단하고, 중요 내부 정보의 유출을 막기 위한 보안 차원에서 프록시 서버를 사용하는 경우가 많다고 한다.

과연 나는 프록시 서버를 통해서 외부에 접속하는 것일까? Am I behind a proxy? 사이트에 접속을 하면 프록시 서버가 있는지를 알 수 있다고는 하지만, 이러한 서비스가 항상 프록시 서버의 존재 여부를 정확하게 검출하는 것은 아니다. 

기업의 입장에서 프록시 서버를 도입하여 운용하는 것을 뭐라고 할 수는 없다. 다만 HTTPS 트래픽을 복호화하여 필요한 '차단' 혹은 '기록(이것을 실제로 하는지는 잘 모른다)' 조치를 취한 다음 다시 암호화하여 내부로 돌려보내는 암호화 트래픽 복호화·가시성 장비(예: 소만사 HTTPS프록시)가 그렇게 만족스럽게 작동하지는 않는다는 것이다. SSL 가시성이라고 좋게 표현하지만, TLS(Transport Layer Security, SSL과 거의 같은 의미) interception이라고 써 놓으면 왠지 마뜩찮아 보인다.
보이지 않는 것은 보호할 수 없다.
멋진 말이기는 한데, 한편으로는 찝찝하다. 예를 들어 내가 소유한 은밀한 사진들을 비밀스런 사설 금고에 보관하고 싶은데, 이를 맡아주는 사람은 그 사진을 투명한 비닐백에 넣어 오지 않으면 안된다고 하는 것과 무엇이 다른가. '공공의 이익에 부합되지 않은 것을 보관해 줄 수는 없으니 금고지기는 내용물을 꼭 보아야 되겠다'라는 논리와 비슷하다. 물론 이 짧은 글을 통해서 이에 대한 논쟁을 확대하고 싶지는 않다.

어찌되었든 내가 앉아있는 책상 위의 컴퓨터에서 외부 세계로 HTTPS 접속을 한 뒤 인증서 정보를 열어보면 Somansa가 Root CA인 것으로 바뀌어서 나온다. 물론 소만사는 최상위 인증기관이 아니다. 소만사의 '공인되지 아니한' 루트 인증서는 업무용 컴퓨터(윈도우)를 세팅하는 과정에서 웹 브라우저에 설치가 되었다. 전산 담당자가 해 준 것인가, 저절로 한 것인가? 그건 잘 모르겠다. 변경(변조?)된 루트 인증서 정보에 보이는 Somansa라는 회사명으로 짐작하건대 아마도 이 회사의 프록시 서버가 변경을 했을 것이다. 이러한 루트 인증서 변경이 일어진다는 것을 안 것은 며칠 되지 않았다. 구글을 검색해 보면 이는 이미 잘 알려진 일이다.

[StackOverflow] Can proxy change SSL certificate? - 네, 그렇습니다!

문제는 리눅스 서버를 사용할 때이다. conda, curl, docker 등 https://(433번 포트)를 사용하는 서비스마다 연결이 제대로 되지 않아서 무척 애를 먹었다. 앞의 두 개는 각 프로그램의 고유한 설정 파일에 Somansa 루트 인증서를 넣어서 해결을 하였으나 docker는 도무지 해결이 되지 않았다.

$ docker pull ubuntu:16.04
Pulling repository ubuntu
Get https://index.docker.io/v1/repositories/library/ubuntu/images: x509: certificate signed by unknown authority

[StackOverflow] Docker : Get https://registry-1.docker.io/v2/: x509: certificate signed by unknown authority를 비롯한 많은 글에서 이에 대한 질문과 답변을 볼 수 있었다.
We have also a proxy. For monitoring our https connection to avoid malwares, our proxy creates a certificate on the fly for the secured connection between a station and the proxy. Then another secured connection is done between the proxy and the website. The message indicates that the certificate produced by the proxy was signed by an unknown authority: the "fake authority" which generates the certificates.
CentOS 6의 경우 소만사의 루트 인증서 파일을 받아다가 /etc/pki/ca-trust/source/anchors/ 아래에 복사한 다음 update-ca-trust force-enable와 update-ca-trust extract 명령을 차례로 실행한 뒤 docker 서비스를 재시동하면 된다는데 도무지 성공의 기미가 없다.
(인증서 파일을 받으려면 웹브라우저에서 내보내기를 하거나 openssl 프로그램을 쓰는 방법이 있다.)
남은 방법은 어떻게 해서든 docker image를 받아서(프록시 서버 영향을 받지 않는 다른 장비에서 docker pull 사용) 파일로 만든 뒤 이를 작업하고자 하는 리눅스 서버로 전송하여 docker load -f tar_file을 하는 것뿐이다. 네트워크를 거치는 docker pull만 아니라면, 일단 받은 이미지 파일을 docker run으로 올리는 데에는 문제가 없다. 혹은 docker pull 명령어를 쓰지 않고 이미지를 다운로드하는 유틸리티인 docker-drag(python 2.7 필요)을 쓰는 방법도 가능하다고 한다. 이는 검색에 검색을 거듭하여 겨우 알아낸 것인데([StackOverflow] How do I download docker images without using the pull command?), 아직 절반의 성공일 뿐이다. 왜냐하면 ubuntu:14.04 및 ubuntu:16.04를 다운로드하여 docker run을 하는 것은 성공하였지만...

$ python docker_pull.py ubuntu:14.04
Creating image structure in: tmp_ubuntu_14.04
e082d4499130: Pull complete [67148830]
371450624c9e: Pull complete [72650]
c8a555b3a57c: Pull complete [363]
1456d810d42e: Pull complete [162]
Docker image pulled: library_ubuntu.tar
$ docker load -i library_ubuntu.tar 
$ docker images
REPOSITORY                      TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
ubuntu                          14.04               7dc2e660bb0c        4 weeks ago         188.1 MB
hello-world                     latest              c72cc8666399        3 months ago        1.84 kB
anvio_jeong180710_cog           latest              bf09cd455d01        9 months ago        3.936 GB
... 중간 생략...
phacnml/plasmidprofiler_0_1_6   latest              ae30d10d24fc        2 years ago         6.564 GB
$ docker run --rm -it ubuntu:14.04 /bin/bash
root@d604c684d26c:/# df -h
Filesystem                                                                                         Size  Used Avail Use% Mounted on
/dev/mapper/docker-8:19-12583470-d604c684d26c2cfaf0f3e234dd867535d306734b37c4c35884bfa7673fe489ea  9.8G  219M  9.1G   3% /
tmpfs                                                                                              127G     0  127G   0% /dev
shm                                                                                                 64M     0   64M   0% /dev/shm
/dev/sdb3                                                                                          5.3T  1.9T  3.2T  37% /etc/hosts

qiime2/core:2018.11을 다운로드할 때에는 'IOError: Not a gzipped file'이라는 에러 메시지가 나면서 실패를 했기 때문이다.

같은 링크에서 소개한 download-frozen-image-v2.sh는 golang, jq 등 생소한 것들을 같이 설치해야 하는 문제로 테스트에 시간이 걸리고 있다. 이에 대해서는 나중에 기록할 예정이다. 이 두 가지 유틸리티 외에도 Downloading Docker Images from Docker Hub without using Docker를 살펴보면 좋은 아이디어가 많으니 참고해 보도록 한다.

download-frozen-image-v2.sh의 활용법(아직은 실패)

위에서 소개한 URL에서 스크립트를 다운로드한다. 추가적으로 jqgo가 필요하다. 두 프로그램 전부 리눅스용 바이너리로 배포되는 것을 받아서 사용하였다. 

curl은 anaconda2 base environment에서 재설치하였고, 문제의 Somansa 루트 인증서는 /opt/anaconda3/ssl/에 설치하였다. 인증서 재설치에 관해서는 curl에 신뢰하는 인증서 추가하기를 참조하였다. 그러나 qiime2은커녕 docker-drag로 받아서 잘 돌아가던 ubuntu 이미지조차 잘 실행되지 않는다.


$ ./download-frozen-image-v2.sh temp_download ubuntu:16.04
Downloading 'library/ubuntu:16.04@16.04' (4 layers)...
#######################################################

Download of images into 'temp_download' complete.
Use something like the following to load the result into a Docker daemon:
  tar -cC 'temp_download' . | docker load
$ tar -cC 'temp_download' . | docker load
Error response from daemon: could not find image: Prefix can't be empty

에혀~ 나도 모르겠다. 동료가 윈도우 Hiper-V 환경에서 받은 도커 이미지를 제공해 주어서 이것을 리눅스 서버로 갖고 들어와서 사용해 보았다. qiime2만 생각한다면 bioconda로 설치를 해 두었으니 실행을 하는 데에는 무리가 없다. 그러나 앞으로의 확장 가능성을 생각한다면 docker를 피해나갈 수는 없을 것이다.

2019년 4월 16일 업데이트

CentOS의 버전이 너무 오래된 것이 문제라는 생각이 든다. 현재의 docker 설치 안내문서(Get Docker CE for CentOS)를 읽어보면 다음과 같이 기재되어 있다.

OS requirements
To install Docker CE, you need a maintained version of CentOS 7. Archived versions aren’t supported or tested.

이제 진지하게 CentOS 6을 버리고 7로 업그레이드하는 것을 생각해 보도록 하자.

2019년 4월 9일 화요일

아직 끝나지 않은 HTTPS/SSL 문제

Conda 활용에서 걸림될이 되는 SSL 인증 관련 문제는 대충 해결이 되었다. 하지만 docker와 git는 아직 해결이 되지 않은 상태이다. git 명령의 경우 아쉬운대로 직접 압축파일(.ZIP)을 받아다가 수동 설치하는 것으로 땜질 처방을 하였다.

pip까지도 불만을 토해낸다. 무슨 파이썬 패키지가 설치되었는지를 알고 싶어서 pip list를 하면 다음과 같은 성가신 메시지가 나온다.

$ pip list
Package    Version  
---------- ---------
biopython  1.72     
certifi    2018.8.24
ls-bsr     dev      
numpy      1.15.2   
pip        18.0     
setuptools 40.4.3   
wheel      0.32.0   
Could not fetch URL https://pypi.org/simple/pip/: There was a problem confirming the ssl certificate: HTTPSConnectionPool(host='pypi.org', port=443): Max retries exceeded with url: /simple/pip/ (Caused by SSLError(SSLError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:719)'),)) - skipping
(py35) [hyjeong@tube LS-BSR-master]$ pip list --trusted-host pypi.org --trusted-host files.pythonhosted.org

팁 - 파이썬 패키지 설치할 때 SSL 인증 오류 해제 방법에서 힌트를 얻었다. 홈 디렉토리의 .pip/pip.conf에 다음의 내용을 추가하거나,


[global]
trusted-host = pypi.org
               files.pythonhosted.org

혹은 pip install 혹은 pip list 명령을 수행할 때 --trusted-host pypi.org --trusted-host files.pythonhosted.org 옵션을 주면 된다.


오후에 쓴 업데이트

직원의 도움으로 git 문제는 해결을 하였다. conda base environment에서 curl과 git를 업데이트한 다음, 인증서를 수동 설치하였다. git의 인증서 관련 설정을 변경하는 방법은 git에서 https repository 연결시 SSL 인증서 오류 해결법을 참조하였다.

인증서 체인이니 번들이니 하는 것의 개념을 아직 완벽하게 이해한 것이 절대로 아니다! 앞으로도 갈 길이 멀다. 다음의 사이트가 매우 유용하므로 이를 참조하자.

Get your certificate chain right

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.