스토리 홈

인터뷰

피드

뉴스

조회수 1385

개발팀의 유행어 제조기, Mark를 만나다

 * 2015년에 작성된 글입니다편집자 주: 잔디에는 현재 40명 가까운 구성원들이 일본, 대만, 한국 오피스에서 일하고 있습니다. 국적, 학력, 경험이 모두 다른 멤버들. 이들이 어떤 스토리를 갖고 잔디에 합류했는지, 잔디에서 무슨 일을 하고 있는지 궁금해하시는 분들이 많았습니다.  이에 잔디 블로그에서는 매 주 1회 ‘맛있는 인터뷰’라는 인터뷰 시리즈로 기업용 사내 메신저 ‘잔디’를 만드는 사람들의 이야기를 다루고자 합니다. 인터뷰는 매 주 선정된 인터뷰어와 인터뷰이가 1시간 동안 점심을 함께 하며 다양한 이야기를 나누며 진행됩니다. 인터뷰이에 대해 궁금한 점은 댓글 혹은 이메일([email protected])을 통해 문의 부탁드립니다.인터뷰 시작에 앞서 편집자 스스로 잔디의 개발팀에 궁금한 점이 있었다. 매 주 수요일 아침 8시, 오피스 근처 카페에서 스터디를 하는 그들의 문화가 바로 그 것이다. 회사의 강요가 아닌 공부를 하겠다는 자발적인 이유로 모인다는 그들. 그들 중 한 명인 Mark를 이번 주 맛있는 인터뷰에 어렵게 모시게 되었다.세렝게티의 한 마리 표범과 같은 그의 눈빛이 향한 곳은 가.츠.나.베반갑습니다. 우리 좀 걷지 않았나요? 회사에서 꽤나 멀리 떨어진 ‘오무라안’을 온 특별한 이유가 있다면?회사 바로 앞에 있는 ‘탄’보다는 조금 고급스러운 일식 레스토랑이에요. 우연히 알게 된 곳인데 맛이 딱 제 취향이라 즐겨 찾습니다. 항상 가츠나베를 먹는데요. 그 맛은.. 말로 형용하기 어렵네요.가츠나베성애자이시군요. 얼마나 있는지 모르겠으나 ‘맛있는 인터뷰’ 독자들을 위해 인사 부탁드립니다.안녕하세요, 부산 남자 Mark입니다. 잔디에 합류한 지 약 두 달 정도 되었어요. 잔디에서는 Front-end 개발 업무를 맡고 있습니다.주로 어떤 일을 하시나요?쉽게 말하자면 사용자들이 접하는 부분을 책임지는 역할이에요. 지금은 Jihoon, Young과 함께 일하고 있는데 궁합이 잘 맞는 것 같아요. 사람이 적으면 할 수 있는 일이 한정되어 있고 반면 사람이 많으면 커뮤니케이션이 힘든데 저희 세 명은 예외인 것 같습니다.왔노라, 보았노라, 달렸노라Mark님만의 유행어가 있더라고요?‘가자!’ 를 말씀하시는 것 같은데요. 맞나요? (웃음) 비글로벌 서울 2015 우승 후, 뒷풀이 회식에서 흥에 겨워 술과 함께 외친 ‘가자!’가 다른 분들에게 인상적으로 각인되었던 것 같아요.네, 저도 그 자리에 있었는데요. 굉장히 인상적이었어요. 술이 센 편이신 것 같은데요?아니에요. 사실 술을 잘 하는 편도, 자주 마시는 편도 아니에요. 주량이라면 소주 두 병 정도? 그 날은 저희 회사가 좋은 일도 있고 해서 평소보다 많이 마시긴 했지만 기분이 좋았던 게 그런 사태를 만든 주된 이유인 듯 합니다.잔디 비글로벌 서울 2015 우승!잔디의 개발자 채용 과정이 다른 곳에 비해 까다롭다고 들었어요. 직접 경험하신 분으로서 어땠는지 여쭤볼 수 있을까요?정말 까다로워요. 다른 곳도 코딩시험을 보기는 하는데 잔디는 인사부에서 1차 코딩 시험을 보고 2차 면접에서는 왜 그렇게 코딩을 했는지 설명을 해야 합니다. 그리고 나서 인성 면접을 봤습니다. (잔디에서는 이 면접을 Behavior Interview 라고 부르며, 여러 부서의 인원들이 참여해 해당 인터뷰이가 함께 일할 사람으로서 적합한지 판단하게 된다 – 편집자 주)마치 수험생 같다는 느낌이 들었어요. 면접 과정 중에는 ‘뭐 이리 깐깐하게 굴어?’ 라는 생각을 했었는데, 지금 돌이켜 보면 이런 과정을 거쳐 합류한 인재들이 모여 있어 잔디가 빠르게 성장할 수 있지 않을까 추측해 봅니다.잔디에서의 생활은 어떤가요?신기한 점이 참 많은 것 같아요. 좋은 점은 출중한 능력을 가진 분들이 많다는 점이에요. 그분들을 통해 배울 점도 많고, 개인적으로는 분발해야겠다는 생각을 하게 해요. 많은 자극을 받고 있어요.신기한 점이라면 어떤 부분일까요?예를 들면 아침에 출근하면 Dan(CEO)이 제게 다가와 영어로 말을 건네는 것이 가장 신기한 것 같아요. 당황스러우면서도 한편으로는 신기해요.이건 개인적으로 궁금한 건데요. 개발팀의 아침 스터디에 대해 어떻게 생각하시나요?사실 아직 참여해 보진 못했어요. 잔디 개발팀에서는 매주 아침 8시까지 나와서 자발적으로 스터디를 하고 있는데요. 강요가 아닌 자발적으로 업무 외에 스터디를 한다는 점이 참 인상 깊어요.그렇군요. 질문을 좀 바꿔볼게요. 쉬는 날엔 뭐 하시나요? 부산 사람이니 야구?보통 쉬는 날엔 서울에 있는 친구들을 만나거나 게임을 해요. 야구는 부산 사람이다 보니.. 삶의 일부 같은 느낌이죠. 우리가 공기를 좋아하거나 싫어할 수 없듯, 야구 역시 좋아하거나 싫어할 수 있는 대상이 아니에요.보통 ‘부산 사람=야구’라고 생각하는데 Mark도 여기에 해당하는 분이었군요. 게임은 어떤 걸 즐겨 하시나요?WOW(Wolrd of Warcraft)라고 아세요? 저는 게임에 있어서 저만의 철학이 있어요. 게임에도 레벨이 존재한다고 생각하는데요. 모바일 게임을 아주 안 하는 것은 아니지만 모바일 게임에 투자하는 시간은 아깝다고 느껴져요. 물론 개인적인 생각입니다.록타르.. 피바람을 몰고올 Mark여..그러면 Mark가 생각하기에 게임으로서 ‘와우’는 어느 정도 레벨인가요?제가 알고 있는 게임들 중 와우는 Top3에 듭니다. 물론 생각을 깊게 해 본 적은 없어서 나머지 2개에 뭘 넣어야 할지 고민해야겠지만 와우는 정말 잘 만든 수작이에요.이제 곧 휴가철이잖아요. 부산 여행 추천 장소 좀 해주세요.외지 사람들은 보통 해운대 많이 가는데, 사실 부산 사람들은 해운대를 잘 안가요. 사람이 너무 많잖아요? 부산 여행 장소를 찾으신다면 개인적으로 을숙도를 추천하고 싶어요. 여긴 가족 단위 여행객이 많은 곳인데요. 서울 사람들이 한강을 찾듯 부산 사람들은 을숙도를 찾아요.이번 여름 휴가는 을숙도로!을숙도? 섬인가요?네, 섬이긴 한데 엄청 큰 다리로 육지와 연결되어 있어서 차를 타고 들어갈 수 있는 곳이에요. 공원이 잘 조성되어 있어요. 자전거도 빌려 탈 수 있고 까페도 있어서 여행 장소로는 딱이에요.축구장도 엄청 많아서 축구 동호회 분들이 자주 찾으시는데요. 사람으로 북적거리지 않는 부산 여행지를 찾는다면 이번 여름 여행은 을숙도로 가보세요. 참고로 을숙도에는 음식점이 많지 않아요. 저 같은 경우, 을숙도 갈 때마다 도시락을 챙겨가곤 합니다.다음은 맛있는 인터뷰의 고정 코너 ‘어서 말을 해’입니다. Jinho가 남긴 질문 ‘잔디를 한문장으로 표현한다면?’에 대해 답을 주신다면?잔디란 ‘기회’ 입니다. IT 업에서 제가 어디까지 능력을 발휘할 수 있을지 확인해볼 수 있는 좋은 기회이기 때문이죠. 좀 진부한가요?전~혀 진부하지 않아요. 멋진 답변을 주셨으니 다음 인터뷰이를 위해 질문 하나 남겨주시겠어요?저는 이걸 꼭 물어보고 싶어요. ‘최근 3년 동안 당신에게 가장 행복했던 일은?’Mark와 개인적으로 얘기를 나눠보고 싶었는데 이렇게 소원이 이뤄졌네요. 개인적으로 뿌듯한 인터뷰였습니다.감사해요. 잘 좀 편집해 주세요.#토스랩 #잔디 #JANDI #개발팀 #개발자 #개발 #팀원소개 #팀원인터뷰 #팀원자랑 #기업문화 #사내문화 #조직문화
조회수 2288

[어반베이스 피플] 알고리즘으로 전 세계 도면을 변환하다_CV 개발자 인터뷰

최근의 가장 핫한 연구분야인 '자율주행'의 바탕에는 '컴퓨터 비전'이 필요하다는 사실을 아셨나요? 홍채인식, 스노우 어플도 '컴퓨터 비전'을 사용한 사례입니다. 우리의 가까이 다가와 있지만, 기술 자체에 대해서는 어딘가 생소합니다. 어반베이스의 CV개발자 대희님이 멀고도 가까운 컴퓨터 비전의 모든 것을 알려드립니다!멀고도 가까운 컴퓨터비전(CV)의 모든 것Q. 간단한 자기소개를 해주세요.네, 안녕하세요. 어반베이스에서 컴퓨터 비전(CV) 개발자 윤대희라고 합니다.Q. CV가 생소한 분들이 많을 것 같아요. CV에 대해 쉽게 설명 부탁드려요.CV는 컴퓨터비전(Computer Vision)의 약자에요. 쉽게 말해 컴퓨터가 인체라면 '눈'역할을 담당해요. 카메라를 사용해 입력받은 이미지나 영상을 프로세싱하면 '컴퓨터 비전 처리했다'고 말해요. 예를 들면, 카메라 어플 내에서 얼굴을 인식한 후에 안경을 달아준다거나, 눈을 크게 해준다거나 그런 것들을 컴퓨터 비전에서 처리할 수 있는 거죠. Q. 그렇다면 컴퓨터 비전의 시작은 언제부터인가요? 최근에 생긴 기술 같은데요. 그렇지 않아요. CV의 시작은 60년대부터 있었어요. (60년대요?) 네. 달 표면을 찍은 위성 사진의 화질을 개선하기 위해 디지털 이미지 프로세싱 분야가 탄생했어요. 그동안 기술력이 뒷받침되지 않아서 무언가를 할 수 없었을 뿐이에요. 하드웨어, 즉 카메라 장비나 처리 기술이 발전하면서 이제서야 붐이 일어난 거죠. Q. CV 개발이 활발히 이루어지는 분야가 있을까요?핸드폰 카메라 어플, 자율주행, 홍채인식 등에도 모두 CV가 필요해요.특히 요즘 떠오르고 있는 분야가 자율 주행이에요. 자율주행을 하려면 주행 시 주위 환경을 모두 살펴해야 해요. 차선이나 신호, 보행자와 차량도 봐야 하죠. 실시간으로 영상을 인식하고 처리하는 분야이니 CV 개발이 활발해요.의학 쪽에서도 많이 써요. MRI 사진을 찍은 후 세포의 영역을 볼 때, 의사가 그 모든 세포를 볼 수가 없으니까 CV 처리를 한 후 이상이 있는 세포의 특징만 뽑아내는 거죠. 아까 말씀드렸듯이 항공 쪽에서는 옛날부터 많이 썼어요. 최근에는 무인 우주선의 이미지 분석에 사용돼요. 무인 우주선에서 여러 가지 이미지 데이터를 보내오는데, 기상상황에 의해 이미지를 제대로 판단하지 못하는 경우가 있어요. 그래서 이런 이미지들을 보정하거나 특징을 뽑아내는, 전처리 과정을 CV 통해 해야 해요. 자율주행의 차량인식스노우 어플 (출처 : 스노우 앱 페이지)홍채인식 (출처 : 삼성전자 블로그)Q. 컴퓨터 비전에 대해 조금 더 자세히 알 수 있을까요?최근에 나온 명함인식 어플도 컴퓨터 비전을 사용해요. 명함에 사람의 사진이 붙어 있는 경우도 CV를 통해서 인식하게 될 거예요. 컴퓨터의 입장에서 사람의 얼굴은 공통적인 특징이 있어요. 눈 밑, 코 밑은 어두울 것이고 광대 이마 등은 밝을 거예요. 이런 패턴을 분석해서 명함 내의 얼굴을 인식하게 만드는 것이 CV에요.Q. 제가 알기론 머신러닝도 이미지를 인식하고 분류해주는 역할이라고 알고 있어요. 컴퓨터 비전과 머신러닝은 어떻게 다른 건가요?간단히 말해 컴퓨터 비전은 '눈', 머신러닝은 '뇌' 역할이죠.CV는 머신러닝에 앞선 전처리를 해주는 역할이에요. 앞서 말했듯 CV를 통해 사람 얼굴을 인식할 수 있어요. 우리 모두 눈 밑, 코 밑은 어둡고 광대 이마는 밝게 인식되겠죠. 하지만 사람마다 패턴이 미묘하게 다를 거예요. 또한 같은 사람이라도 각도나 조명에 의해 패턴이 달라질 거고요. 그래서 이런 패턴을 분석해주는 게 머신러닝이에요.'사람'을 분류해주는 건 CV로, 그 사람들 중 '홍길동'을 인식하는 것은 머신러닝인거죠.사람을 분류해주는 건 CV, '홍길동'을 인식하는 건 머신러닝CV 개발자, 어떻게 시작했나요?Q. 개발자가 되기까지의 과정이 궁금해요. 원래 컴퓨터공학을 전공하셨나요?아뇨, 기계설계를 전공했어요. 요즘은 기계 쪽에서도 공장 자동화를 기본 베이스로 하고 있어서 물건의 바코드 인식이나 라벨 색상 처리도 모두 CV의 영역이에요. Q.기계설계 중에서도 다양한 분야가 있는데, CV를 선택하신 이유가 있나요?저는 처음부터 CV를 생각했어요. 과 특성상 하드웨어 설계와 소프트웨어 설계를 동시에 하는데 저는 소프트웨어 쪽에서도 CV를 많이 했어요. CV는 다른 것에 비해서 확실히 재밌어요. 카메라로부터 받은 데이터들을 처리하는 과정이 눈으로 확실히 보이니까 훨씬 재미있게 느껴져요.Q. 운영하고 계신 블로그를 구경한 적이 있는데, 굉장히 정리가 잘 되어 있더라고요. 블로그 사이트는 어떻게 시작하게 된 거예요? 저는 누군가에게 무언가를 알려주고, 지식을 공유하는 걸 좋아해요. 제가 알고 있는 것을 함께 공유하고 공부하기 위해 블로그를 시작했어요. 어떤 것을 설명하는 방법이 그것에 대한 가장 좋은 공부법이라는 말도 있잖아요? 정보를 함께 공유하고 피드백도 받으면서 굉장히 도움이 많이 됐어요. 그래서 지금도 계속 쓰고 있어요.대희님의 블로그블로그의 강좌 목록Open CV 강좌많은 러브콜을 뒤로하고, 어반베이스에 합류하게 된 이유Q. 어반베이스의 합류 과정이 남달랐던 것으로 알고 있어요. 일종의 '스카웃 당했다'고 말할 수 있을 것 같은데요. 합류 과정을 알려주실 수 있을까요?제가 CV 온라인 강의를 진행하고 있었는데, 그때 저를 보시고 연락을 주셨어요. 강의하는 홈페이지에는 개인적인 연락처를 적어 놓지 않고 제 블로그 링크만 달아놨었어요. 그런데 제 블로그에 있는 메일 주소를 찾으셔서 연락을 주셨어요. Q. 어반베이스의 제안을 받고 어땠어요?좋았어요. 말씀해주신 업무를 제가 할 수 있을 것 같았고, 또 면접을 함께한 현우님에게 굉장히 좋은 인상을 받았어요. 부담을 안 가지고 편하게 얘기했는데 좋게 봐주셨던 것 같아요.Q. 여러 산업분야에서 CV로 할 수 있는 것들이 굉장히 많은데 어반베이스를 선택한 이유가 있을까요?확실하게 ‘사람’의 이유가 가장 컸던 것 같아요. 어반베이스에서 저를 믿고 먼저 연락을 주셨고, 함께 이야기를 나누다 보니 좋으신 분이라는 게 확실히 느껴졌어요. 사실 다른 곳에서도 연락이 많이 왔지만 일단 제 능력을 믿어주는 사람과 같이 일하고 싶었어요. 제 능력을 펼치고 싶어도 그렇게 할 수 없는 경우가 있잖아요. 하지만 어반베이스는 확실하게 제 의견을 반영해주시고 제가 하고 싶은 일을 할 수 있는 환경이라는 생각이 들었어요. 결국은 ‘사람’이 좋아서 선택한 거죠. 그게 가장 큰 이유에요. Q. 어반베이스는 VR, AR을 활용해서 공간데이터 사업을 하는 곳이잖아요. 어반베이스 비즈니스에 대한 첫인상은 어땠어요?저는 되게 좋았어요. 자동화한다는 것 자체에 메리트가 느껴졌어요.기계공학을 전공했지만 기계공학에서 건축과 닮은 부분이 있어요. 기계 도면 역시 2D로 그린 후 3D 파일을 또 만들고, 그 이후 텍스처를 설정하는 과정을 거쳐요. 분야만 다를 뿐 일련의 과정들이 건축과 굉장히 비슷해요. 그래서 막연히 '2D 도면을 3D로 바꿔주는 과정을 CV로 자동화 처리하면 괜찮지 않을까?'라는 생각을 했었어요. 분야가 기계에서 건축으로 바뀌었을 뿐, 제가 가지고 있었던 생각이랑 어느 정도 맞아떨어지더라고요. 그래서 어반베이스 비즈니스에 대한 생각이 굉장히 좋았어요. Q. 그렇다면 입사하신 이후 느꼈던 어반베이스의 개발 환경은 어때요? 굉장히 좋아요. 사람에 대한 믿음이 확실히 느껴져요. 맡은 일에 대해 믿어준다는 느낌이 있어요. 그리고 다른 분들에게 질문을 해도 항상 본인 일을 멈추고 먼저 알려주려고 하세요. 그런 모습을 보며 억압하는 분위기가 없고, 협업을 중시하고 사람을 중시한다는 걸 많이 느꼈어요. 물리적인 환경도 좋아요. 사양 좋은 맥북을 새로 사주셨거든요. 하하사양 좋은 맥북과 함께 일하는 대희님어반베이스 기술의 핵심, 도면 변환 알고리즘을 개발하다Q. 대희님이 하고 있는 일을 소개해주세요. 건축도면 이미지(2D)를 읽어서 3D 모델로 만들어주는 알고리즘을 개발하고 있어요.도면 변환에 가장 중요한 것은 좌표에요. 꼭짓점만 알면 벽을 그릴 수 있잖아요? 2D 도면상 좌표의 위치를 알아내서 벽, 문, 창문의 위치를 만들어내는 역할이에요. 좌표의 위치를 안다면 그 도면에 대해서 3D로 만들 수 있는 거죠. 3D로 만드는 과정까지 제가 담당하고 그 후의 렌더링은 3D 파트에서 담당하고 계세요. 대희님의 작업 과정Q. 업무 일과나 업무 스타일은 어때요?하루 종일 개발밖에 안 해요. 알고리즘 만든 후에 도면을 대입해서 처리가 되는지 확인하고, 오류가 있으면 수정하는 이런 패턴의 반복이죠. 어느 정도 완성이 됐다면 다음 단계로 넘어가는 거죠.제 업무 스타일은 목표한 게 있으면 끝까지 하는 스타일이에요. 해야 할 일을 정해놓고 그 일을 모두 마쳐야 퇴근해요. (막히는 경우가 생길 수도 있지 않나요?) 그러면 쉬지 않고 계속 개발하면 돼요. (웃음)Q.대희님은 어떤 분들과 협업을 많이 하나요? 2D에서 3D로 바꿔주는 도면 변환 부분, 즉 가장 베이스가 되는 부분을 만들고 있다 보니 개발 부문 대부분과 협업을 하고 있어요. 제가 만든 것을 사람들에게 보여줘야 하니까 UI/UX팀과 협업을 많이 해요. 제가 만든 API에 대해서도 이야기해야 하기 때문에 API, 백엔드팀과도 협업을 많이 하고요.Q. CV 개발자로 입사 후 가장 기뻤을 때는 언젠가요?제가 입사한 후 CV 코드 리뷰를 하고 코드를 개선해서 확실하게 좋아진 것이 보일 때 정말 좋았어요. 제 의견이 반영이 되어 바뀔 수 있었고, 결과적으로 결과도 좋았으니까요. 그 부분이 가장 좋았어요.제가 만든 알고리즘이 도면 인식을 잘 할 때도 기분이 좋죠. 도면을 넣었을 때 내가 생각한 대로 처리가 잘 되고 생각한 대로 오류가 잘 날 때 뿌듯해요.Q. 앞으로 어반베이스 내에서 개발 계획은 어떻게 되나요?이번 해에는 도면 변환 알고리즘이 구동될 수 있게끔 만들고, 내년 초부터 코드를 수정하면서 알고리즘의 정확도를 높이는 작업을 계속하려고 해요. 그다음엔 해외 도면을 처리하는 과정을 생각하고 있어요. 데드라인이 정해져있는 프로젝트는 아니지만 최대한 빨리 진행하려고 해요. 2D에서 3D로 도면을 변환하는 개발을 저 혼자 하고 있어서 제가 일을 쉬면 프로젝트 자체가 아예 멈춰 버리니까, 되도록 빨리해야죠. 그렇게 해야 수정하고, 피드백을 받고, 출시하는 모든 과정들이 빠르게 진행될 수 있으니까요.CV 개발자에게 가장 필요한 역량은 코딩 능력이 아니다.Q. 여러 분야의 개발자가 있지만 '컴퓨터 비전(CV) 개발자'는 많이 들어보지 못했는데 최근 들어 '컴퓨터 비전 개발자'의 채용이 굉장히 늘고 있는 것 같아요. 앞으로의 CV 시장을 어떻게 예측하세요?사실 이전까지는 기술력 부족으로 할 수 있는 것이 많이 없었어요. 카메라로 찍었을 때 화질이 안 좋으면 CV 처리하기가 굉장히 힘든데 최근에 카메라 성능이 최근에 굉장히 좋아져서 처리 과정이 수월해진 거죠. 그래서 'CV 개발자'에 대한 수요도 늘고 있어요. 이미지로 무언가를 한다면 무조건 CV 개발자가 필요해요. 요즘은 손쉽게 카메라를 설치하고 이미지/영상 데이터들을 얻을 수 있으니까, 더욱 많이 필요할 거예요. 모든 산업분야에서 CV와 관련된 더 많은 개발자, 더 많은 기술이 필요할 것이라고 생각해요.Q. CV 개발자에게 가장 필요한 역량은 뭘까요? 코드를 잘 짜는 것보다 수학을 잘 하는 게 중요해요. 대부분의 이미지 인식 과정에서 수학공식이 사용되기 때문에 후처리를 하려면 수학을 잘 해야 해요. CV는 공업수학, ML은 통계학이 많이 관련되어 있어요.Q. 그러면 코드를 짤 때 코드에서 막히기보다 수학 공식에서 막힐 때가 있잖아요. 그럴 땐 어떻게 해요?늘 거기서 막혀요. 학교를 최근에 졸업했으니 아직 공식이 머릿속에 많이 남아있어서, 막힐 때가 있으면 이런저런 다른 공식 적용을 시도하죠. 어반베이스의 알고리즘으로 전 세계 도면을 변환하다Q. 좋아하거나 롤모델로 삼고 있는 사람이 있나요?루카스 카나데 교수님이요. CV 분야의 세계적인 권위자이신 분이에요. 교수님의 이름을 딴 함수가 있을 정도로요. 그 정도의 명예와 재력이 있는데도 불구하고 꾸준히 공부하고 논문을 발표하시는 모습도 정말 멋있다고 생각해요.Q. 혹시 CV 외에 어반베이스 내에서 욕심나는 분야가 있어요?머신러닝이요. CV에서 전처리를 하고 머신러닝 후에 후처리에 또 CV가 필요해요. 그래서 중간 영역인 머신러닝을 배우면 모든 프로세스를 혼자서 처리할 수 있으니까 머신러닝을 공부해보고 싶어요.   Q. 어반베이스가 혁신적인 기술을 통해서 많이 이슈가 되고 있고, 많은 컨택이 오고 있잖아요. 스스로 어반베이스의 개발자로서 어반베이스의 가능성은 어떻다고 생각해요?확실히 굉장히 높다고 생각해요. CV로 처리해서 자동화한다는 것 자체가 굉장히 뜨고 있는 기술이고 앞으로 계속 발전할 기술이기 때문에 가능성도 굉장히 크다고 생각해요. Q. 대희님의 포부는 뭐예요?전 세계의 2D 도면을 어반베이스의 알고리즘을 통해 3D로 변환할 수 있게끔 만드는 거죠. 단기간은 국내, 중장기적으로는 해외 도면까지요.컴퓨터 비전. 그저 어렵게만 느껴졌던 단어인데, 이번 인터뷰를 통해 컴퓨터 비전과 많이 가까워진 느낌이 듭니다. 어반베이스의 핵심기술을 담당하고 있는 CV 개발자 대희님! 대희님이 만든 알고리즘으로 전 세계 도면이 3D로 변환될 날이 왔으면 좋겠습니다 :)출처: https://blog.naver.com/urbanbaseinc 
조회수 2462

데이블 주니어 개발자 직무 인터뷰

오후 두 시의 회의실. 개발자들의 스터디하는 소리로 뜨겁다. 국내 최고의 추천 기술을 보유했다는 데이블. 10년 이상의 경력을 가진 노련한 시니어 개발자들 사이에서, 스쳐 지나가는 단어 하나하나 놓치지 않으려 귀 기울이고 있는 주니어 개발자들을 만났다.안녕하세요? 간략한 소개와 두 분의 업무에 관해 설명해주세요.형주: 안녕하세요? 저는 데이블 개발팀 최형주입니다.저는 백앤드 개발팀의 신입 개발자로서 데이블의 인프라 관리, 백앤드 개발 그리고 가끔 데이터 분석을 하고 있습니다. 주로 사용하는 서버는 클라우드 플랫폼인 AWS(Amazon Web Service)과 Nodejs 이고, MySQL, Redshift, Python을 사용하여 데이터 처리와 분석을 하고 있어요.성현: 안녕하세요. 저는 데이블 개발팀 이성현입니다.제 메인 업무는 데이블 위젯의 스타일링과 관련 문제 해결입니다. 고객사 페이지를 분석해서 위젯 디자인을 만들고, 추천 결과가 안 나오는 경우에 문제를 수정하는 작업입니다. 특별한 기능이 필요한 위젯이 있으면 스크립트 작업도 하고요. 작업 도구는 회사 내부 시스템이 있어서 그 안에서 직접 작업하고, CSS로 작성합니다.위 업무가 메인이지만 다른 영역과 겹칠 때도 잦아서 회사에서 사용하는 여러 시스템을 만질 수 있어야 합니다. 도구는Html+CSS+js 외에 Node, gulp, react, angular angularJS, PHP, 젠킨스, AWS, MYSQL, git를 사용하고 있습니다.두 분 다 신입 개발자이신 만큼 회사를 선택하는 데 있어 신중했을 것 같아요.데이블을 선택한 이유는 무엇인가요?형주:  저는 대학원에서 빅데이터 처리관련 연구를 주로 했었어요. 졸업할 때쯤 제 전공과 관련된 회사에 지원했었고 많은 면접을 보았습니다. 여러 회사에서 면접을 봤지만 데이블에서 봤던 면접 경험이 만족스러웠고 특히 개발자들의 실력과 내공이 느껴져 신입으로서 많은 것을 배우고 싶어서 입사하게 되었습니다. 복지 또한 여느 알려진 회사들에 비해 부족하지 않아서 굉장히 만족하고 있습니다.성현: 처음 데이블에 호감을 느끼게 된 건 기술 중심 스타트업이라는 점이었습니다. 도전하는 자세, 유연한 사고, 성장 가능성, 복지 등 여러 가지 기준들이 있겠지만, 내가 재미를 느낄 수 있는가, 개발자로서의 성장 이 두 가지로 압축되었어요. 저 같은 경우에는 블로그를 보면서 회사 분위기를 대략 파악했던 것 같네요. 자유로운 분위기도 잘 느껴지고, 서로를 배려하면서 열심히 일하는 것을 간접적으로 경험할 수 있었어요. 면접 보러 갔을 때, 블로그에서 보던 사람들이 블로그 글과 비슷한 느낌으로 편하게 얘기하는 걸 보면서 마음을 굳히게 됐어요.데이블의 분위기는 어떤가요?형주: 분위기는 실제로 굉장히 수평적입니다. 서로 존댓말을 사용해서 존중받는 기분이 들어요.성현: 저는 데이블 오기 전에 잠시 다른 회사에 있었는데, 거기서는 과한 예절이나 눈치를 보는 분위기가 있었어요. 데이블은 수평적인 분위기이다 보니 스트레스 받지 않고 일에 집중할 수 있어 좋아요.형주: 저 같은 경우, 잠에 굉장히 민감한 편인데 출퇴근이 탄력적이어서 지각에 대한 스트레스가 없어서 좋아요. 그래서 저는 보통 9시 넘어서 일어나서 10시쯤 출근하고 7시쯤 퇴근하는 편입니다. 그리고 식대도 지원해주고 있어요~성현: 매일 4시쯤 회사가 지원하는 간식 타임이 있어요. 오랜 시간 앉아서 일하다 보면 집중력 떨어질 때 쯤 다 같이 모여 대화를 나누면서 간식을 같이 먹습니다. 만약 생일이 있으면 간식 타임과 더불어 생일 파티를 해요.형주: 간식과 음료수가 항상 냉장고에 갖춰져 있어서 먹을 것을 좋아하는 사람에게 최고인 것 같아요. 저는 살이 잘 안 찌는 체질인데 입사 후 2킬로가 쪘어요.성현: 거의 슬랙과 트렐로 위주로 업무를 하는데 간식 타임에는 여러 사람과 대화를 할 수 있어 좋습니다. 서로 대화도 같이하고, 같이 활동할 수 있는 시간을 마련하기 위해 ‘플레이 데이’ 도 2개월에 한 번씩 열고 있어요! 회사-집, 집-회사를 반복하다가 다 같이 뭔가를 하니 신선했어요. 업무 외적으로 같이 활동하면서 사람들과 친밀감을 느낄 수 있어서 좋았어요.데이블을 선택했던 이유 중 개발자로서 성장 가능성도 있었는데 이것은 어떻게 채워지고 있나요?성현: Dabler, Be The Expert 프로그램(이하 BTE 프로그램)이 있고 업무 관련 스터디도 활발히 진행하고 있어요.자세히 설명해주세요. 성현: BTE 프로그램의 경우 장기목표를 정하고 반기별로 관련 학습 계획을 세워요. 그 안에서 책도 사고 강의도 신청하고 하는 거지요. 스스로 목표를 잡고 자유롭게 계획을 세울 수 있어서 좋아요. 본인이 정말 원하는 것을 배울 수 있고, 필요한 자금은 회사가 지원하는 거죠. 단, 업무에 관련된 성장 계획이어야 한다는 가이드라인이 있어요.이 외에도 백엔드 개발자들과 함께 AWS 사용법을 주제로 스터디도 해요! 보통 프론트엔드를 담당하지만, 백엔드 영역도 경험할 수 있어요. 본인 스스로 영역을 넓히기 위해 공부하고 능력이 된다면 활동 범위가 굉장히 넓어져요. 회사 차원에서도 그런 시도를 장려해요. 빨리 성장해야겠다는 욕심이 있어요.형주: 전 회사에서 일주일에 2번 모여서 스터디도 하고 있고 MOOC 강의를 수강하거나 책을 사고 싶을 때 눈치 볼 필요 없이 신청하면 돼요. 그리고 반기별로 자기 개발을 잘한 직원에게 인센티브를 줘요.※BTE 프로그램이란?그럼 두 분은 BTE 프로그램을 통해 어떤 것들을 배우고 계시는가요?형주: 저는 Coursera에서 Recommender System 수업을 듣고 있어요. 아무래도 우리 회사의 핵심기술이 추천 기술이다 보니까 이쪽 분야를 깊게 공부해야겠다는 생각이 들었습니다.성현: 저는 웹을 능숙하게 다루고 싶어서 상반기에는 인프라, 자바스크립트, 웹 표준, node 등 기본을 다시 챙기고 하반기에는 웹 최신 기술을 공부하려고 해요.지금은 자바스크립트 관련 책 3권과 강의 2개를 신청해서 주로 퇴근 후 또는 주말에 듣고 있어요. 업무와 관련된 것을 공부하고 나서 코드를 작성하면 대충 넘어갔던 부분들이 보여요. 그 부분을 놓치지 않고 수정하고 개선하다 보면 예전보다 나은 결과물이 나오고 뭔가 아는 게 늘었구나! 하는 보람을 느낍니다.데이블에서 개발자로 일하며 느끼는 점형주: 저의 경우에는 신입 개발자 관점에서 경험 많은 개발자분의 피드백을 통해 노하우를 전수하는 점이 좋았어요. 그러면서 기존에 놓치고 있던 부분이나 실무와 이론 사이의 괴리감을 좁히는 경험이었습니다. 저도 학부, 대학원 시절 많은 코딩을 했지만 제가 작성한 코드가 잘 작성된 코드인지 잘 읽히는 코드인지는 스스로 공부하기 힘들었는데 이러한 피드백을 통해 성장함을 느꼈습니다.어려웠던 점은 우리 회사는 애드테크 회사이다 보니 광고 용어를 굉장히 많이 사용하는데 광고에 관해 얘기할 때 처음에는 광고 용어를 몰라 답답했었는데, 스터디를 만들어서 어려운 점을 조금은 해소할 수 있었어요.성현: 자기만 할 수 있으면 얼마든지 여러 프로젝트에 참여할 수 있는 문화가 좋아요. 예를 들면 저는 위젯 담당이지만, 위젯 업무 틈틈이 데이블 시스템 페이지 수정을 할 수도 있고 내부 DB를 이용해서 사업팀에게 도움이 되는 통계 페이지를 만들기도 해요. 얼마 전에는 커뮤니티에 데이블 추천 기능을 직접 넣는 프로젝트를 했습니다. 보통 추천 연동은 고객사가 하고 저는 위젯만 만들고 있었거든요. 이번에 고객사 입장에서 서버 쪽을 만져본 거죠.미래의 데이블은 어떤 모습일까요?형주, 성현: 세계 No. 1 콘텐츠 디스커버리 플랫폼! 경영진이 자기 개발 지원이나 복지에 신경을 많이 쓰고 있어서 계속 나아질 것 같아요.데이블의 개발자가 되기 위해 어떤 것들이 필요할까요?형주: 제가 생각하기에 시니어 개발자분들이 가장 중요하게 여기는 부분은 CS 분야의 기본기였던 것 같습니다. 이 기본기를 통해 자주 사용하는 툴이나 오픈 소스가 내부적으로 어떻게 구성되어 있고 동작하는지에 대한 공부를 하면 도움이 될 것 같습니다.성현: 저는 주도적인 자세요! 스스로 일하고 배우는 자세가 필요합니다. 다른 개발자와 소통하면서도 자기 일의 진행 관리나 조율은 스스로 해야 해요. 다음 일을 직접 찾아야 할 때도 있고요. 또 전부를 물어볼 수는 없으니 어느 정도 혼자 찾아 공부하는 습관도 필요해요. 그리고 자기가 지원하는 포지션에서 사용하는 핵심 기술 하나는 능숙하게 사용할 수 있어야 해요. #데이블 #팀원 #개발자 #개발팀 #개발 #팀원소개 #인터뷰 #기업문화
조회수 998

[Tech Blog] Software architecture: The important stuff

마틴 파울러는 Software architecture 를 “무엇이건 간에 중요한 것들(The important stuff whatever it is)” 이라고 정의합니다. 조금은 재미있는 정의지만, 그 정의를 도출하기 위해 제시한 다른 정의를 들어보면 고개를 끄덕이게 합니다.  Software architecture 는 전문 개발자들이 같은 생각을 가지고 이해하는 시스템 디자인입니다. Software architecture 는 이른 시기에 정해져야 하는 디자인 결정들입니다. 혹은 여러분이 “아, 처음부터 좀 더 잘 생각하고 할 껄”이라고 후회하는 바로 그 결정들입니다. Software architecture 는 또한 바꾸기 어려운 결정들의 집합입니다.  결국 무엇을 중요하게 생각할 것인가, 그것이 Software Architecture 라는 의미입니다. Why is it important? 왜 중요한지 설득하지 못한다면 사실 중요하지 않은 것일지도 모르죠. 그래서 왜 Software Architecture 이 중요한지 짚어보고자 합니다. 쿠팡은 Microservice architecture 로 전환하는 여정을 글로 남겼는데요. 블로그 글의 제목을 “행복을 찾기 위한 우리의 여정” 이라고 지었습니다. (좋은 글이니 읽어보시길!) 다시 말해서, Software Architecture는 개발가자 더 좋은 제품을 만들 수 있는 길이기 때문에 중요하다고 말합니다. 그러나 좋은 Software Architecture를 만드는 일은 쉽지 않습니다. 블로그 글을 인용 해보겠습니다: “여기 저렴한 제품과 비싼 제품이 있습니다. 비싼 제품은 software architecture 가 잘 고려되어 있고, 저렴한 제품은 시스템 디자인에 대한 고민 없이 구현되어 있습니다. 하지만 두 제품은 겉으로 보기에 차이가 없습니다. 소비자가 보기에 똑같이 보이고, 똑같은 기능이 있으며, 성능 또한 같습니다. 어떤 제품을 사야할까요?” 소비자는 제품을 만든 개발자의 행복을 위해 더 비싼 제품을 선택하지는 않습니다. 개발자 역시 동료들에게 “내가 행복하려면 시간과 돈이 좀 더 들더라도 좋은 software architecture 를 구성해야 해.” 라고 주장하기엔 설득력이 부족하죠. Software architecture 가 왜 중요한지 모두가 공감하려면 경제적인 입장에서 그 중요성을 설득해야 합니다. “내부 품질을 좀 포기하더라도 이번 릴리즈에 더 많은 기능들이 들어가야 해.” 라는 의견에 “안돼 우리(개발자)는 더 전문적으로 구성해야 해.”라는 의견으로 대응하면 항상 질 수 밖에 없습니다. 장인 정신과 경제 논리 사이의 싸움에서는 경제 논리가 항상 이겨왔거든요.   Cumulative functionality over Time Software architecture 를 고려하지 않으면서 제품을 개발하면 초기에는 기능 추가 속도가 빠를 수 있지만, 시간이 흐름에 따라 제품의 기능 증가 속도는 점차 느려집니다. 이미 구현된 기능들과 코드가 새로운 기능을 추가하는데 걸림돌이 되기 때문입니다. 한편, 좋은 설계를 지속적으로 건강하게 유지하고, 주기적으로 리팩토링을 하고, 코드를 깨끗하게 유지한다면 시간이 흘러도 기능 추가가 느려지지 않을 수 있습니다. 오히려 기능을 추가하기 위해 수정해야 할 곳들이 명확하고 모듈화 또한 잘 되어있기 때문에 시간이 갈 수록 기능 추가가 더욱 빠르게 진행될 수 있습니다. 새로운 개발자가 참여하는 시점에도 시스템을 더욱 빠르게 이해하고, 더 빠르고 안전하게 기능을 추가할 수 있게 됩니다. 결국 장기적으로 더 많은 기능을 생산하고 빠르게 고객에게 전달하기 위해서 개발팀은 좋은 디자인과 설계에 대해 깊게 고민해야 합니다. What is the best software architecture? 옳은 software architecture 는 없습니다. 상황에 따라 해답은 다를 수 있습니다. Microservice architecture 가 좋다고 해서 모든 것에 대한 답이 microservice architecture 인 것은 아니고, 마찬가지로 어떤 시스템이 monolithic architecture 로 구현되어 있다고 해서 뒤쳐져 있는 것도 아닙니다. 모든 선택에는 Tradeoff 가 있기 마련이니까요. 유선 통신 시스템을 구성한다고 생각해 볼까요? 우리 나라처럼 인터넷이 잘 구성된 상황에서 Skype 로 할 수 있는 통화는 무료이고, 품질도 좋고, 영상 통화까지 됩니다. “Skype 만세! 인터넷을 통한 통신이 항상 옳습니다!” 라고 외치려던 시점에 정전이 되었습니다. 방금 외친 외침은 멀리 가봐야 옆집 정도 닿겠죠. 한편 기존 유선 전화 시스템은 느리고 화상 통화도 안되지만, 전화선 자체에 전원이 공급되고 있기 때문에 정전 시에도 통화가 가능합니다. 전쟁 상황이나 기타 재난 등에도 반드시 통신이 가능해야 하는 곳은 유선 전화 시스템이 꼭 필요할 것 같습니다. 은행 시스템도 적절한 예시가 될 수 있습니다. 비밀번호 입력, 전화 인증, OTP 확인하는 등 은행 업무는 왜이리도 복잡할까요? 그냥 비밀번호 기억해주고 로그인 유지해주면 참 편할텐데 말이죠. 안전하기 위해서겠죠. 여러분의 자산은 소중하니까요. 사용성(Usability)과 안전성(Security)은 종종 둘 사이를 조절해야 하는 Tradeoff 입니다. 만들려는 제품과 시스템, 환경, 시기와 조건 등에 따라서 적절한 architecture 는 달라집니다. 좋은 architecture 를 선택할때 개발자는 선택한 것의 대척점에 있는 무언가를 포기 해야합니다. 그렇기에 software architecture 는 기술적인 범주 안에서만 고려되면 안되고, 구현하고자 하는 비지니스를 매우 잘 이해하고 고려해서 적용해야 합니다. What are you going to do? 이미 구성된 software architecture 를 변경하는 것은 굉장히 어렵습니다. 이미 구성되어 있는 것들을 상세하게 알고 있어야 하고, 비지니스의 요구 사항을 수용해야 하며, 이미 존재하는 기능이 변경 도중 문제 없이 동작해야 합니다. 또한 기존 시스템에 기여한 개발자들과 변경 사항에 대한 공감대를 이뤄야 하며, 겉으로 보기에 당장 변화가 없는 것에 대한 비용에 대해 많은 사람들을 설득해야 합니다. 최근 Buzzvil 에서는 Architecture Task Force 팀을 구성하였습니다. 이를 통해 전체적인 설계를 정비하고 모든 개발팀이 구조적으로 같은 이해를 할 수 있도록 분석, 조사, 계획 수립, 실행에 옮길 예정입니다. 지속적인 공유를 통해 전사적인 공감대를 유지하고 체계적인 문서화와 가이드라인을 통해 모든 팀원이 함께 실행하며 성장할 수 있는 기반을 준비하게 될 것입니다. 궁극적으로 전사 프로젝트와 모든 팀이 더욱 빨리 움직일 수 있는 software architecture 를 구성하고, 이를 통해 더 많은 기능을 더 빠르게 전달할 수 있게 할 것입니다. 아직 해야할 일들이 많이 남아있지만 제대로 계획하고 빠르게 움직인다면 충분히 좋은 결과를 만들 수 있을 것 같습니다. 당장은 눈에 보이는 변화가 없을지라도, 좋은 디자인에 대한 고민과 실행이 우리가 궁극적으로 바라는 비전과 목표에 한 걸음 더 빠르게 다가가는 올바른 길이라고 믿습니다.   *버즈빌에서 개발자를 채용 중입니다. (전문연구요원 포함)작가소개 Whale, Chief Architect “Keep calm and dream on.”
조회수 3057

GitHub 계정으로 Kubernetes 인증하기

초기에는 kube-aws가 만들어준 관리자 인증서를 통해 Kubernetes를 관리했는데 역시나 대내외적으로 여건이 바뀌니 변화가 필요했다. 내부적으로는 개발 인력이 늘고 여러 프로젝트가 동시 진행되니 Staging 환경이 급격히 바뀌는데 계정이 하나이니 누가 무슨 작업을 했는지 확인하기 어렵고 외부적으로는 경쟁사의 보안사고 등에 영향을 받아 보안을 강화할 필요가 생겼다. 하여 보안 관련 작업을 여럿했고 그 중 하나가 바로 GitHub와 Kubernetes를 OAuth로 엮는 일이다.기본적으로는 개발자 각자가 자신의 GitHub 계정으로 인증 토큰을 받고 이를 이용해 Kubernetes API에 접근하는 것이다. 전체적인 흐름은 How I built a Kubernetes cluster so my coworkers could deploy apps faster 등을 참고하면 이해하기 그리 어렵지 않다.1. Admin time should be saved (since they are also our developers)2. New users can generate their own credentials without needing the admin3. User credential is always private for security reasons4. Developers have their own space to experiment5. Project spaces can be accessed and changed by multiple users6. In the future, we may want to enable auditing to track changes다만 저들과 달리 Webhook 토큰 인증 플러그인을 직접 짜지 않고 coreos/dex를 이용했다. Dex를 이용하면 GitHub를 비롯해 다양한 OpenID, OAuth 2.0 인증 서비스와 Kubernetes 클러스터를 엮기 쉽다. 더욱이 kube-aws에 Dex가 통합되어서 설치하기도 쉽다.설치하기구구절절 어떻게 설정하는지 설명할 생각은 없는데 회사와 프로젝트에 따라 세부적인 차이가 꽤나 클 수 있기 때문이다. 그러니 대략적인 작업 순서를 간략히 기술하고 끝내려 한다.우선 kube-aws의 cluster.yaml를 보자.# # Enable dex integration - https://github.com/coreos/dex # # Configure OpenID Connect token authenticator plugin in Kubernetes API server. # # Notice: always use "https" for the "url", otherwise the Kubernetes API server will not start correctly. # # Please set selfSignedCa to false if you plan to expose dex service using a LoadBalancer or Ingress with certificates signed by a trusted CA. # dex: # enabled: true # url: "https://dex.example.com" # clientId: "example-app" # username: "email" # groups: "groups" # selfSignedCa: true # # # Dex connectors configuration. You can add configuration for the desired connectors suported by dex or # # skip this part if you don't plan to use any of them. Here is an example of GitHub connector. # connectors: # - type: github # id: github # name: GitHub # config: # clientId: "your_client_id" # clientSecret: "your_client_secret" # redirectURI: https://dex.example.com/callback # org: your_organization # # Configure static clients and users # staticClients: # - id: 'example-app' # redirectURIs: 'https://127.0.0.1:5555/callback' # name: 'Example App' # secret: 'ZXhhbXBsZS1hcHAtc2VjcmV0' # # staticPasswords: # - email: "[email protected]" # # bcrypt hash of the string "password". You can use bcrypt-tool from CoreOS to generate the passwords. # hash: "$2a$10$2b2cU8CPhOTaGrs1HRQuAueS7JTT5ZHsHSzYiFPm1leZck7Mc8T4W" # username: "admin" # userID: "08a8684b-db88-4b73-90a9-3cd1661f5466"우선 GitHub의 Organization Settings 메뉴로 가서 OAuth Apps에 Dex를 추가한다. 이때 Authorization calllback URL은 https://dex.example.com/callback가 된다.GitHub가 준 Client ID와 Client Secret를 cluster.yaml에 적어넣는다.dex: enabled: true url: "https://dex.example.com" clientId: "example-app" username: "email" groups: "groups" selfSignedCa: false # # # Dex connectors configuration. You can add configuration for the desired connectors suported by dex or # # skip this part if you don't plan to use any of them. Here is an example of GitHub connector. connectors: - type: github id: github name: GitHub config: clientId: "GITHUB_OAUTH_APP_CLIENT_ID" clientSecret: "GITHUB_OAUTH_APP_CLIENT_SECRET" redirectURI: https://dex.example.com/callback org: DailyHotel # # Configure static clients and users staticClients: - id: 'example-app' redirectURIs: 'https://kid.example.com/callback' name: 'Example App' secret: 'ZXhhbXBsZS1hcHAtc2VjcmV0'staticPasswords: - email: "[email protected]" # # bcrypt hash of the string "password". You can use bcrypt-tool from CoreOS to generate the passwords. hash: "$2a$10$2b2cU8CPhOTaGrs1HRQuAueS7JTT5ZHsHSzYiFPm1leZck7Mc8T4W" username: "admin" userID: "08a8684b-db88-4b73-90a9-3cd1661f5466"여기서 dex.example.com은 kube-aws가 띄울 dex Deployment와 연결되는 서비스(ELB)의 도메인주소가 되어야 한다. 그런데 kube-aws는 Dex의 External service를 생성해주지 않으므로 아래와 같이 직접 서비스를 생성해야 한다. GitHub가 이쪽으로 콜백을 보내야 하므로 방화벽을 열어야 하고 회사 도메인 인증서를 붙일 것이므로 `selfSignedCa`값은 `false`로 한다.apiVersion: v1 kind: Service metadata: name: dex namespace: kube-system labels: app: dex component: identity dns: route53 annotations: domainName: dex.example.com service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:blahblah service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http service.beta.kubernetes.io/aws-load-balancer-ssl-ports: https spec: ports: # the ports that this service should serve on - name: https port: 443 targetPort: 5556 protocol: TCP selector: app: dex component: identity type: LoadBalancer loadBalancerSourceRanges: - 0.0.0.0/0staticClients / example-app는 Dex에 포함된 예제 프로그램이다. 이를 이용하면 웹 브라우저를 통해 GitHub에 인증하고 토큰을 내려받을 수 있다. DailyHotel/kid 등의 도커 이미지를 사용하면 쉽게 띄울 수 있다. kube-aws는 이 예제 프로그램을 띄우지 않기 때문에 직접 올려야 한다.apiVersion: v1 kind: Service metadata: name: kid namespace: kube-system labels: app: kid dns: route53 annotations: domainName: "kid.example.com" service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:blahblah service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http service.beta.kubernetes.io/aws-load-balancer-ssl-ports: https spec: ports: - name: https port: 443 targetPort: 5555 protocol: TCP selector: app: kid type: LoadBalancer loadBalancerSourceRanges: - 사무실IP/32 --- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: kid namespace: kube-system spec: replicas: 1 template: metadata: labels: app: kid spec: containers: - name: kid image: dailyhotel/kid:latest livenessProbe: tcpSocket: port: 5555 timeoutSeconds: 120 ports: - containerPort: 5555 env: - name: CLIENT_ID value: example-app - name: CLIENT_SECRET value: ZXhhbXBsZS1hcHAtc2VjcmV0 - name: ISSUER value: https://dex.example.com - name: LISTEN value: http://0.0.0.0:5555 - name: REDIRECT_URI value: https://kid.example.com/callback이때 example-app의 REDIRECT_URI는 Dex의 REDIRECT_URI와는 다르다는 점에 주목하자. 옵션의 이름이 비슷하기 때문에 헷갈릴 수 있다. 또한 CLIENT_ID와 CLIENT_SECRET은 cluster.yaml 중 GitHub connector 설정이 아닌 staticClients 설정에서 쓴 값이라는 점도 눈여겨볼 필요가 있다.이 정도만 주의하면 dex를 설치하고 설정하는 것은 어렵지 않다. 이제 인증하는 방법을 알아보자.인증하기웹브라우저로 kid에 방문해서 토큰을 받는다. 첫 화면에서 Login 버튼을 누른 후 GitHub 로그인을 하면 토큰이 나온다.GitHub Public profile 메뉴로 가서 Public email 설정을 확인한다. 공개 이메일이 없다면 하나 추가한다. 로그인시 사용자 아이디로 쓰기 위함이다.kubeconfig 파일을 열고 kubeconfig 파일을 열고 MY_PUBLIC_GITHUB_EMAIL에는 GitHub 공개 이메일 주소를 적고 VISIT_KID_EXAMPLE_COM_AND_GET_TOKEN에는 앞서 받은 토큰을 적는다.apiVersion: v1 kind: Config clusters: - cluster: certificate-authority: credentials/ca.pem server: https://MY_KUBE_CLUSTER name: kube-aws-cluster contexts: - context: cluster: kube-aws-cluster namespace: default user: MY_PUBLIC_GITHUB_EMAIL name: kube-aws-context users: - name: MY_PUBLIC_GITHUB_EMAIL user: token: VISIT_KID_EXAMPLE_COM_AND_GET_TOKEN current-context: kube-aws-context인증 파일의 설정이 정확한지 확인하려면 kubectl --kubeconfig=./kubeconfig version을 실행해보자. 아래와 같이 Client/Server의 버전이 둘다 나오면 정상이다.$ kubectl --kubeconfig=./kubeconfig version Client Version: version.Info{Major:"1", Minor:"6", GitVersion:"v1.6.1", GitCommit:"b0b7a323cc5a4a2019b2e9520c21c7830b7f708e", GitTreeState:"clean", BuildDate:"2017-04-03T20:44:38Z", GoVersion:"go1.7.5", Compiler:"gc", Platform:"darwin/amd64"} Server Version: version.Info{Major:"1", Minor:"6", GitVersion:"v1.6.2+coreos.0", GitCommit:"79fee581ce4a35b7791fdd92e0fc97e02ef1d5c0", GitTreeState:"clean", BuildDate:"2017-04-19T23:13:34Z", GoVersion:"go1.7.5", Compiler:"gc", Platform:"linux/amd64"}참고 자료johnw188/dex-exampleKubernetes / Authenticating#데일리 #데일리호텔 #개발 #개발자 #개발팀 #기술스택 #도입후기 #일지 #경험공유 #Kubernetes #Github
조회수 2574

타다 시스템 아키텍처 - VCNC Engineering Blog

2018년에는 VCNC에 큰 변화가 있었습니다. 오랫동안 비트윈 기반의 서비스들을 개발하고 운영했지만 2018년 10월에 기사 포함 렌터카 서비스를 포함한 종합 모빌리티 플랫폼인 타다를 기획하고 출시하였습니다. 변화가 많은 모빌리티 시장에서 신규 서비스를 성공적으로 출시하기 위해 많은 고민을 하였습니다. 이번 글에서는 타다의 시스템 구성과 이를 위해 사용한 여러 기술을 소개하면서, 타다 개발팀의 기술적 결정을 공유해보고자 합니다.타다에서 사용하는 기술들의 로고. 왼쪽부터 Kotlin, Spring Boot, Kubernetes, Terraform, gRPC, Redis.기존과 다른 선택비트윈의 경우 Netty를 이용해 인하우스 네트워크 라이브러리를 만들기도 하였고, 메인 데이터베이스로 NoSQL인 HBase를 사용하는 등 남들이 통상적으로 사용하지 않는 기술 스택을 선택한 경우가 많았습니다. 그 배경에는 나름대로 이유가 있었지만, 서비스 초기에는 안정성에 어려움을 겪기도 하였고 서버 배포 과정이 느리고 복잡하여 쉬운 길은 아니었습니다. 여러 문제를 해결하기 위해 Haeinsa 등 라이브러리와 소프트웨어를 직접 만들기도 하였습니다.타다는 이슈가 많은 모빌리티 시장을 타겟으로 하고 있기 때문에 Time to Market이 특히 중요했습니다. 개발하는 기간 동안 시장 상황에 따라 기능의 우선순위가 변하기도 하였습니다. 이에 따라 서비스를 빨리 출시하고 외부의 변화에 유연하게 대처할 수 있도록, 완성도 있게 만들어져 있는 프레임워크나 라이브러리를 선택하였고, AWS에서 이미 잘 관리되고 있는 서비스를 적극적으로 활용하였습니다.사용 중인 기술들Kotlin: Java는 불편한 점이 많지만, JVM에 대한 경험을 무시할 수는 없어 비교적 새로운 JVM 기반 언어인 Kotlin을 사용하기로 하였습니다. 다른 여러 JVM 기반의 대안 언어들이 있지만, Spring Boot에 쉽게 적용할 수 있고 커뮤니티에서 적극적으로 권장하고 있는 점 등 여러 이유로 Kotlin을 선택하게 되었습니다.Spring Boot: 널리 쓰는 웹 프레임워크이며 이미 지원하는 기능 또한 많기 때문에 보일러 플레이트 코드 작성을 줄이고 서비스 개발에 집중할 수 있습니다. SQS 메시지 처리, HTTP 요청 및 응답으로 Protocol Buffers 메시지 사용 등 프레임워크에서 제공하는 기능을 많이 활용하고 있습니다.Kubernetes: 컨테이너 오케스트레이션 플랫폼으로 배포 자동화와 스케일링 등 여러 가지 운영적인 편의성을 제공합니다. 처음에는 kops를 이용해 클러스터를 직접 띄웠지만, 지금은 EKS를 이용하고 있으며 직접 object를 만들기보다 helm을 이용하고 있습니다.gRPC: 실시간성이 중요한 차량 위치나 운행 상태 변화 등은 Streaming을 이용하여 전달하고 있습니다. 직접 개발할 수도 있었지만, 서비스 개발에 집중하고 앞으로의 관리 오버헤드를 줄이기 위해 gRPC를 이용하기로 하였습니다.Redis: 서버 간 메시징을 위해 Redis의 Pub/Sub 기능을 사용하고 있습니다. 메시지 브로커 기능을 제공하는 RabbitMQ, ActiveMQ, Kafka 등 여러 옵션이 있었지만, 개발을 시작하던 당시에는 Redis만이 ElastiCache를 이용하여 쉽게 띄우고 관리할 수 있어 Redis를 선택하게 되었습니다.Protocol Buffers: gRPC 뿐만 아니라 HTTP/2로 주고받는 메시지를 정의할 때도 이용하고 있습니다. 덕분에 따로 문서화 하지 않고 proto파일을 공유하여 더욱 명확하고 편리하게 API 명세를 공유할 수 있었습니다.Terraform: HCL을 이용해 인프라스트럭처 프로비저닝 및 관리를 편하게 해주는 도구입니다. AWS 서비스의 생성 및 관리를 콘솔에서 직접 하지 않고 Terraform을 이용하고 있습니다.사용 중인 AWS 서비스들AWS는 개발팀이 오랜 기간 사용하여 가장 익숙한 클라우드 플랫폼이기 때문에 큰 고민 없이 선택할 수 있었습니다.EKS: Kubernetes 클러스터의 마스터 노드들을 쉽게 띄우고 관리해주는 서비스입니다. 서울 리전에 EKS가 출시된 후에는 관리 오버헤드를 줄이기 위해 EKS로 옮겼습니다.ECR: 타다 서버를 배포할 때는 Docker Gradle Plugin을 통해 docker 이미지를 만들고 ECR에 푸시합니다. 그 후 helm 명령을 통해 Kubernetes에 배포합니다.SQS: 배차 요청을 처리하기 위해 SQS를 이용합니다. 배차 요청을 구현하는 방법에는 다양한 옵션이 있었지만 AWS 서비스를 최대한 활용하여 빠르게 개발할 수 있었습니다.RDS: 타다의 대부분 데이터는 Aurora에 저장하고 있습니다. RDS를 이용하면 DB의 배포와 관리가 쉬우며, Aurora는 MySQL과 호환될 뿐만 아니라 같은 비용이면 성능이 더 좋습니다.Kinesis: 실시간 차량 위치 정보 및 로그를 수집하기 위해 사용하고 있습니다. 다른 오픈소스 소프트웨어를 직접 이용하기보다는 AWS에서 제공하는 서비스를 최대한 이용하고 있습니다.Firehose: 비트윈에서는 KCL를 활용해 Acheron이라는 프로그램을 직접 만들어 로그들을 S3에 저장하였지만, 이제는 서울 리전에서 Firehose를 사용할 수 있으므로 큰 고민 없이 사용하기로 하였습니다.시스템 구성타다에서는 필요에 따라 서비스를 여러 종류로 분리하여 운영하고 있습니다. 일반적인 모바일 앱 API와 실시간 차량의 위치 정보를 바탕으로 사용자의 요청에 대해 적합한 차량을 배차하는 기능이 필요했습니다. 핵심적인 역할을 하는 일부 서비스와 시스템 구성에 대해 간단하게 소개합니다.라이더 앱: 아이폰은 Swift, 안드로이드는 Kotlin으로 작성하였으며 여러 오픈소스 라이브러리를 적극적으로 활용하였습니다. 서비스 특성상 RIBs라는 아키텍처를 사용하여 개발하였습니다.드라이버 앱: 아이폰과 안드로이드를 모두 지원하려면 기술적, UX적으로 고려해야 할 점들이 많고 불특정 다수의 유저를 대상으로 하는 앱도 아니었기 때문에 안드로이드 버전으로만 개발하게 되었습니다.서버: 모바일 앱의 요청을 대부분 처리하며 Spring Boot로 작성된 HTTP/2 API 서버입니다. Protocol Buffers로 정의된 메시지를 JSON 형태로 주고받습니다.gRPC 서버: 서버에서 발생하는 이벤트를 실시간으로 전달하기 위한 서버입니다. Redis Pub/Sub을 통해 받은 이벤트 메시지들을 클라이언트들에게 전달합니다.Dispatcher: 배차 요청을 처리하는 서버입니다. 주변 차들의 ETA 계산을 위해 외부 API를 이용하는데, Reactor를 이용해 비동기적, 동시적으로 요청하여 쓰레드 점유 없이 효율적으로 처리되도록 구현하였습니다.Tracker: 차량 위치 정보 수집 서버입니다. KCL를 이용해 위치 정보 레코드를 읽어 들여 TrackerDB에 기록합니다.Redis: 서비스 초기에는 차량의 최신 위치 등을 저장하기도 했지만, 지금은 주로 서버 간 메시징을 위해 Pub/Sub 기능을 이용하고 있습니다.DB: 운행 기록, 사용자 데이터 등 대부분 데이터를 기록합니다. 비트윈에서는 HBase를 이용했지만 타다의 경우 아직 절대적인 트래픽이 많지 않기 때문에 트랜잭션 등 다양한 편의 기능을 제공하는 RDB를 이용하고 있습니다.TrackerDB: 차량 운행 정보 및 차량의 최신 위치 등을 저장합니다. Aurora를 이용하며 대부분의 요청이 차량 위치 정보 업데이트이므로 안정성을 위해 별도의 인스턴스를 띄워 사용하고 있습니다.Kinesis Log Stream: 타다의 여러 서비스에서 로깅을 위해 이용합니다. Firehose를 통해 S3에 기록됩니다.Kinesis Tracker Stream: 드라이버의 실시간 위치 정보는 Kinesis를 통해 Tracker로 전달됩니다.서비스 플로우차량 위치 업데이트차량 위치 업데이트는 요금 계산, 차량 위치 제공 등 서비스에서 가장 많이 일어나는 요청입니다. 드라이버 앱에서 안드로이드 Foreground 서비스를 이용해 GPS 정보를 수집하고 일정 주기마다 서버로 현재 위치를 전송합니다. 이렇게 전송받은 GPS 위치 정보는 데이터 크기를 최소화하기 위해 Protocol Buffers로 직렬화되어 Kinesis 레코드로 만들어지게 됩니다. Tracker에서는 전달된 Kinesis 레코드를 읽어 간단한 처리를 한 후에 TrackerDB에 삽입합니다.서비스 초기에는 차량의 마지막 위치에 대한 정보만 Redis에 적었습니다. 그러나 차량의 이동 경로를 효율적으로 조회해야 할 일이 생겼는데, 당시 차량 이동 경로는 로그로만 저장되고 있었습니다. S3 Select나 Athena를 이용해 조회하는 방안도 고려했지만, 일단은 Aurora에 저장하기로 하였습니다. 당분간은 Aurora로도 충분했고 RDB를 쓰는 것이 가장 쉽고 편한 방법이었기 때문입니다.차량 배차차량 배차는 서비스의 가장 기본적인 기능으로 배차 요청에 가장 적절한 주변 차량을 할당하는 플로우입니다. 라이더 앱에서 유저가 배차를 요청하면 서버가 배차 요청 정보를 DB에 기록하고 배차 요청 메시지를 SQS 대기열에 집어넣습니다. Dispatcher가 배차를 처리하는 로직을 수행하여 차량이 매칭되면 드라이버 앱으로 이벤트가 전달됩니다.드라이버가 배차를 수락하면 서버로 수락 요청이 전송되고 서버에서는 DB의 배차 요청 상태를 수락 상태로 변경합니다. 배차 요청이 수락되었다는 이벤트는 결과적으로 gRPC 서버를 통해 해당 이벤트를 구독하고 있던 유저에게 전달됩니다.Dispatcher에서 배차를 처리하는 로직은 여러 옵션이 있었지만 가장 간단하고 효율적으로 개발하기 위해 SQS의 기능을 최대한 활용하였습니다. Dispatcher 수를 늘리는 것만으로도 처리량 확장이 가능하며 Dispatcher가 갑자기 종료되어도 한 대라도 살아있다면 결국에는 잘 처리가 됩니다. Dispatcher가 배차 요청을 받으면 다음과 같은 로직을 수행합니다. 종료 조건을 만족하지 않았다면 일정 시간 후 동일한 로직을 다시 반복합니다.배차가 가능한 상태라면 배차 로직을 수행합니다. 이동 경로와 교통정보를 고려하여 적합한 주변 차량을 찾습니다.만약 적합한 차량이 있다면 배차 요청을 해당 드라이버에게 할당되었다는 정보를 DB에 적고 배차 할당 이벤트를 전파합니다. 드라이버의 수락을 기다리기 위해 일정 시간 후 로직을 재시도합니다.만약 적합한 차량이 없다면 일정 시간 후에 로직을 재시도합니다.배차 요청이 드라이버의 수락을 기다려야 하거나 타임아웃이 남아있는 상태라면 적절한 시간 후 재시도합니다.배차 요청이 수락되어 완료된 상태거나 취소되었거나 타임아웃이 지난 상태라면 SQS에서 메시지를 삭제합니다.못다 한 이야기타다를 런칭하는 날, 기사 간담회에서 쏘카의 VCNC 인수 이후 짧은 기간 동안 타다를 만들 수 있었을 리 없으니, 실제 개발 기간은 어느 정도냐는 질문이 있었습니다. 짧은 기간 내 서비스를 성공적으로 런칭할 수 있었던 것은 상황에 맞는 올바른 기술적 선택들뿐만 아니라 훌륭한 팀원들이 있었기에 가능했던 일이었습니다. 타다는 개선해야 할 부분도 많고 앞으로 새로운 기술적 도전들이 많이 있을 것입니다.네 그렇습니다. 결론은 기술적 난제들을 고민하면서 좋은 팀과 서비스를 함께 만들고 키워나갈 좋은 분들을 기다리고 있다는 것입니다.
조회수 2762

Next.js 튜토리얼 4편: 동적 페이지

* 이 글은 Next.js의 공식 튜토리얼을 번역한 글입니다.** 오역 및 오탈자가 있을 수 있습니다. 발견하시면 제보해주세요!목차1편: 시작하기 2편: 페이지 이동 3편: 공유 컴포넌트4편: 동적 페이지  - 현재 글5편: 라우트 마스킹6편: 서버 사이드7편: 데이터 가져오기8편: 컴포넌트 스타일링9편: 배포하기개요여러 페이지가 있는 Next.js 애플리케이션을 만드는 방법을 배웠습니다. 페이지를 만들기 위해 한 개의 실제 파일을 디스크에 만들어야 합니다.그러나 진짜 애플리케이션에서는 동적 컨텐츠를 표시하기 위해 동적으로 페이지를 생성해야 합니다. Next.js를 사용해 이를 수행하는 여러 방법들이 있습니다.쿼리 문자열을 사용하여 동적 페이지를 생성해봅시다.간단한 블로그 애플리케이션을 만들 예정입니다. 이 애플리케이션은 home (index) 페이지에 전체 포스트 목록을 가지고 있습니다.포스트 제목을 클릭하면 뷰에서 각 포스트를 볼 수 있어야 합니다.설치이번 장에서는 간단한 Next.js 애플리케이션이 필요합니다. 다음의 샘플 애플리케이션을 다운받아주세요:아래의 명령어로 실행시킬 수 있습니다:이제 http://localhost:3000로 이동하여 애플리케이션에 접근할 수 있습니다.포스트 목록 추가하기먼저 home 페이지 안에 포스트 제목 목록을 추가해봅시다.pages/index.js에 다음과 같은 내용을 추가해주세요.위의 내용을 추가하면 다음과 같은 페이지가 보입니다:첫 번째 링크를 클릭하면 404 페이지가 나지만 괜찮습니다.페이지의 URL은 무엇인가요?- /?id=Hello Next.js- /post?title=Hello Next.js- /post?title=Hello Next.js- /post쿼리 문자열을 통해 데이터 전달하기쿼리 문자열(쿼리 파라미터)를 통해 데이터를 전달했습니다. 우리의 경우에는 "title" 쿼리 파라미터입니다. 다음에서 보이는 것처럼 PostLink 컴포넌트를 이용해 구현해봅시다:(Link 컴포넌트의 href prop를 확인해주세요.)이처럼 쿼리 문자열을 이용하여 원하는 모든 종류의 데이터를 전달할 수 있습니다."post" 페이지 생성이제 블로그 포스트를 보여줄 post 페이지를 생성해야 합니다. 이를 구현하기 위해 쿼리 문자열로부터 제목을 가져와야 합니다. 어떻게 구현하는지 살펴봅시다:pages/post.js 파일을 추가하고 다음과 같이 내용을 작성해주세요:다음과 같이 보입니다:위의 코드에서 무슨 일이 일어났는지 살펴봅시다.- 모든 페이지에서 현재 URL과 관련된 내용들을 가진 "URL" prop를 가져옵니다.- 이 경우 쿼리 문자열을 가진 "query" 객체를 사용하고 있습니다.- props.url.query.title를 사용해 제목을 가져왔습니다.애플리케이션에서 몇 가지를 수정해봅시다. "pages/post.js"를 다음과 같이 변경해주세요: http://localhost:3000/post?title=Hello Next.js 페이지로 이동하면 무슨 일이 일어날까요?- 예상대로 동작할 것이다.- 아무 것도 랜더링하지 않을 것이다.- 해더만 랜더링할 것이다.- 에러를 발생시킬 것이다.특별한 prop "url"보다시피 위의 코드는 이와 같은 에러를 발생시킵니다:url prop는 페이지의 메인 컴포넌트에만 전달되기 때문입니다. 페이지에서 사용되는 다른 컴포넌트에는 전달되지 않습니다. 필요하다면 다음과 같이 전달할 수 있습니다:마치며쿼리 문자열을 사용하여 동적 페이지를 생성하는 방법을 배웠습니다. 이제 시작일 뿐입니다.동적 페이지를 렌더링하기 위해 더 많은 정보가 필요합니다. 그리고 쿼리 문자열을 통해 모든 것을 전달할 수는 없을 것입니다. 또는 http://localhost:3000/blog/hello-nextjs와 같은 깔끔한 URL을 원할 것입니다.다음 편에서 이것들에 대해 모두 배울 수 있습니다. 이번 편은 모든 것의 기초입니다.#트레바리 #개발자 #안드로이드 #앱개발 #Next.js #백엔드 #인사이트 #경험공유
조회수 954

Culturalization of Video Game Soundtracks: An Interview with Pierre Langer, Managing Director & Founder of Dynamedion

 Game culturalization, the process of cultural adaption, is the key to successfully launching video games in foreign markets. The main aspects are to make content suitable, understandable, and meaningful for the gamers of the targeted markets. To achieve these objectives, it is necessary to look into the five central pillars of culturalization: history, religion, ethnic and cultural tensions, geopolitical situations, and in-game elements.One in-game element that must be considered is music. To learn more, we interviewed the video game music expert and composer Pierre Langer, founder and managing director of Dynamedion based in Mainz, Germany. Pierre will tell us more about his internationally renowned company, the video game music business, and the culturalization process of video game soundtracks.  Pierre Langer  Dear Pierre, please let us know more about you and your company and the key services that you provide.  Pierre Langer: Dynamedion was founded by Tilman Sillescu and me in early 2000. We started with work-for-hire audio in the German games industry doing music composition, sound design and later also interactive audio integration and Live Orchestra production. We were the first to produce with live orchestra for a German game, and we eventually rolled this out as a service for other composers and game developers all over the world.Today we are one of the biggest game audio studios in the world with nearly 50 people doing music composition, music licensing, sound design, source sound recordings, audio integration, audio software development, live orchestra and live choir recording, and orchestration and arrangement for all sorts of media. We are still very much focused on video games, having worked on more than 1,800 games, but we also do a lot of movie trailers, TV series, and films.In 2009 we started a sub company of Dynamedion called BOOM library, which produces original sound effects collections as products that can be licensed by audio professionals throughout the world. BOOM Library is today recognized as one of the most popular and high-quality sound effects libraries in the world. Apart from that we also run two side labels with royalty-free stock music in a unique adaptive format (SmartSound) and a new product line of virtual software instruments (SONUSCORE). Our latest addition to our services is that we have become well known for high end vehicle recordings (cars, airplanes, helicopters, bikes, tanks, etc.) – that is a lot of fun, but also a huge challenge to source all sorts of rare or weird or super expensive vehicles.So, in short: we are specialists for everything that has to do with music & sound for games – everything except voice overs, and our music or sound effects or live productions have been used and heard in nearly every large game worldwide. As an example, we recently have been involved in these titles: Assassin’s Creed Series, Elder Scrolls Online, Monster Hunter Online, Battlefield V, League of Legends, Destiny 1 & 2, Lineage II, Horizon Zero Dawn, Fortnite, Mortal Kombat Series, World of Tanks, Hitman Series, Total War Series.Currently we are working on five super large unannounced titles, all international.  What part of the world do your requests mainly come from?  Pierre Langer: It is very international, really. Up until 2009 we had a very strong (overly strong I would say) position in Germany, working on nearly every German game title, quite some in France and some occasional overseas projects. Meanwhile this has completely changed: we are doing a good amount of German titles, but the major part comes from the US, UK, Scandinavia, Japan, Korea and China – China being one of the most important markets now.  Have you experienced a shift or a change over the years in game creation from Western countries to an international mix?  Pierre Langer: Absolutely! It seems that the five big “individual” markets (North America, Europe, China, Japan / Korea) are getting closer to each other. Even very self-sustaining markets, like the Japanese market, are opening up for more international projects coming in, but they are also looking into getting their own games distributed internationally, and of course into becoming as successful as possible worldwide. And then there is a huge amount of projects coming from all the emerging markets, so it seems that there is really no end to a lot of new great games. The biggest challenge with a new game certainly is to make yourself “heard” or do something special that your competition does not do, in order to stand out in a new market.  Orchestral Session - Dynamedion  What is culturalization in terms of video game soundtracks and sound effect production?  Pierre Langer: It is actually a very straightforward thing and kind of a no-brainer, since audio is a rather inexpensive asset for a game, while it has a huge emotional and atmospheric impact. Culturalization of a game means that you adapt the game to the specific requests of a new market. Western world audiences are used to different things than Chinese players, for example. So, if a Chinese game developer wants to push a game into the Western market, the game should be “westernized” so to say. This certainly already happens with gameplay mechanics and with graphics and – of course – with the localization. But simply changing the texts and voice over from Chinese to English doesn’t adapt a Chinese game to an EU or US audience. The look and feel of a game need to change as well, and this is where music and sound “culturalization” comes in: adapting the music and sounds (and the way of implementation and audio functionality in the game) to the specific audience that is being targeted. This does of course work in all directions – Japan to China, China to Europe, Europe to Korea, etc.  Can you give us some examples of audio culturalization in specific markets? (E.g. MENA, South America, China/Asia)  Pierre Langer: Let me go back a few years, to our very first larger game title we did music and sound culturalization for. It was “Runes of Magic” by Runewaker Entertainment, a developer based in Taiwan. The game was not extremely successful in Taiwan and Mainland China, but a German publisher by the time (Frogster) saw some great potential in that game. So, they licensed the title and got the rights to publish it in Europe and the US. In some respects, the game was a mess for a Western audience, partly due to the music and the sound + the implementation of all audio. The marketing people at Frogster understood this very quickly and started working on all these issues. The music and sound side was done in a matter of a few weeks: they asked us to replace the soundtrack by using music we had in our back catalogue (music for games that we had written, that either failed, or that had been unsuccessful – which we kept the rights to) and write a few new themes that would work as the iconic main themes of the game, so that the audience has something new and recognizable. We did that, with a full focus on writing and licensing music that would be ideal for the target audience. Then we did a similar thing with the sound effects: we simply threw out all the stuff that was in there and replaced it with sounds that where produced to fit a Western audience. To give you a very quick example: Asian players are used to high frequency sounds, very aggressive, very loud, the whole sound atmosphere being very crowded. European and US players are used to low frequency sounds – sub-bass, deep impacts, rumbling and more focused sound design (you hear one thing prominently, and everything else gets balanced down to make space for the one important sound going on). This is a very clear and super important difference – and it is also easy to fix with some new content and some new mixing.  What are typical issues that occur in sound culturalization?  Pierre Langer: Typical issues are that there needs to be some trust from the developer to the sound team. In most cases, the developer asks for culturalization from their home market to a foreign market. So, a US developer asking us to adapt the sound to fit a Chinese audience better needs to trust us that we know what we are doing, since the US developer doesn’t know themselves (otherwise they wouldn’t need us). Then there is always a big challenge with the correct audio integration. The most important bit is certainly to replace music and sound effects, to get a fitting new set of assets for the target market. However, even the best assets do not help if they are poorly integrated. Simply swapping them is not enough if the way they are being played back is not fitting. This then needs some more time and attention and focus, since we need to work with the developer directly to e.g. add some audio functionality, balance mix and master the audio, or introduce an interactive music system. It can be a very elaborate thing, but you can achieve a lot of additional quality with the most basic strategies that only cost a lower 5 digit budget.  Dear Pierre, thank you for your time and effort in providing us such enlightening insights into your work!About Pierre:Pierre was born near Frankfurt / Germany. After years of playing in bands as a guitar player in his teens, he decided to take his studies in classical music at the Johannes Gutenberg University in Mainz..A few months before his final exams he met Tilman Sillescu in early 2000, Dynamedion was founded a few weeks later. In the first years of Dynamedion Pierre worked on basically every single bit of the job you can do as an audio person in the games business: music composition, sound design, audio integration, audio management, design of audio tool chains, recording, mixing, mastering, project management, etc.As the thing grew and all the other guys joined in, Pierre focused more and more on the business side of things, leaving the creative work to the really focused experts.Nowadays Pierre enjoys keeping in touch with all the different clients of Dynamedion, thinking up new product lines and business ideas to further expand the reach and prominence of Dynamedion and all related sub-labels such as BOOM Library, Sonic Liberty, Sonuscore... and more to come.The Interview was conducted by Moritz Demmig. 
조회수 4907

웹서버 로그 수집과 모니터링 설정

우리는 고객이 무엇에 관심 있어 하고 무엇에 관심 없어하는지, 어떤 것을 보았을 때 클릭해 들어가고 어떤 것을 보았을 때 사이트에서 이탈하는지 궁금해 합니다. 이러한 정보를 얻기 위해 봐야 할 것은 역시 웹서버의 접속 로그입니다.처음에는 매일 생성되는 로그 파일을 일일이 파싱해서 원하는 정보를 DB에 쌓는 방법을 이용했지만, 이러한 방식은 한계가 있었습니다. 저장할 수 있는 데이터의 양에 심각한 제한이 있었고, 따라서 처음에 얻고자 했던 데이터 이상의 것을 새로 추출할 수도 없었습니다.그래서 지금은 웹서버 로그를 하둡(Hadoop) 클러스터에 쌓고 있습니다. Google Analytics 같은 외부 분석툴을 사용하기도 하지만, 아무래도 데이터를 우리 손에 직접 들고 있는 것이 더 유연한 분석을 제공할 수 있지요. 클러스터에서 로그를 분석하려면 가장 먼저 로그 수집 시스템을 만들어야 합니다.이번 포스팅에서는 이 로그 수집 시스템이 어떻게 만들어져 있는지, 그리고 그보다 더 중요한 시스템의 모니터링을 어떻게 하고 있는지 설명하려고 합니다.Flume 에이전트 설정하기Apache FlumeApache Flume은 로그와 같은 데이터의 흐름(streaming)을 제어할 수 있게 해주는 도구입니다. 단순하면서도 확장성 높은 구조로 되어 있기 때문에 많은 시스템에서 채택하는 도구가 되었고, 리디북스에서도 Flume 을 사용하게 되었습니다.Flume 의 기본 구조는 단순합니다.기본적인 에이전트 구성 (이미지 출처: Apache Flume 홈페이지)에이전트(agent)는 Source, Channel, Sink 로 이루어진 자바 프로세스이다.소스(source)는 외부에서 이벤트를 입력받아 채널(channel)로 전달하고, 채널은 이벤트를 저장하고 있다가 싱크(sink)로 전달한다. 싱크는 이벤트를 외부로 출력한다.한 에이전트의 Sink와 다른 에이전트의 Source가 같은 타입이면, 에이전트 간에 이벤트를 전달할 수 있다.굉장히 간단하지만 강력한 모델입니다. Flume 은 Avro, Thrift, Exec, HDFS, Kafka 등 다양한 라이브러리를 적용한 소스와 싱크를 미리 제공하고 있기 때문에, 사용자는 자기 입맛에 맞게 이를 조합해서 시스템을 구성할 수 있습니다.예를 들면 아래와 같습니다.좀 더 복잡한 에이전트 구성 (이미지 출처: Apache Flume 홈페이지)초기 에이전트 구성: Avro를 통해 클러스터에 로그 전송저희가 맨 처음 설정한 Flume 에이전트의 구성은 다음과 같습니다.초기 에이전트 구성각 웹서버ExecSource: exec 명령으로 실행된 프로세스의 표준 출력을 이벤트로 입력받음. (tail -F <로그파일>)MemoryChannel: 메모리상의 큐(queue)로 구현된 채널AvroSink: 클러스터에 상의 에이전트가 실행하는 Avro RPC 서버로 이벤트를 전송하둡 클러스터AvroSource: 웹서버의 에이전트가 Avro RPC 로 보내는 이벤트를 수신MemoryChannelHDFSSink: HDFS 상의 지정된 경로의 파일에 이벤트 내용을 출력각 웹서버에는 에이전트가 하나씩 실행되어서, 로그 파일에 새로 추가되는 로그를 클러스터에 전송합니다. 클러스터 상의 에이전트는 단 한 개 존재하는데, 웹서버로부터 전송받은 로그를 HDFS(Hadoop File System) 에 파일로 출력하는 역할을 합니다. 웹서버 에이전트와 클러스터 에이전트 간의 통신은 Avro RPC 로 하게 하였습니다. Flume 에서 기본적으로 AvroSource 와 AvroSink 를 구현하여 제공해 주는 것을 이용했습니다.사실은 클러스터 상의 에이전트가 Avro 서비스를 통해 데이터를 모아 주지 않고, 웹서버 상의 에이전트가 HDFSSink 를 이용해서 직접 클러스터에 파일을 쓰게 하더라도 대부분의 경우는 상관없습니다. 하지만 리디북스의 경우는 그렇게 할 수 없었는데, 왜냐하면 웹서버와 하둡 클러스터가 서로 다른 네트워크 상에 있기 때문입니다.리디북스의 웹서버는 국내 IDC에 존재하지만 하둡 클러스터는 Miscrosoft Azure 클라우드 내의 가상머신으로 실행되고 있습니다. 따라서 하둡의 네임노드(namenode)가 인식하는 각 노드의 사설 IP 주소를 웹서버들이 쉽게 접근할 수 없습니다. 이를 우회하는 다양한 방법을 시도해 보았지만 최종적으로는 Avro 서비스를 중간에 두어 해결하였습니다.모니터링 알람 설정하기JSON 리포팅 사용다음은 에이전트 프로세스를 모니터링하는 문제가 있었습니다. 예기치 않은 에러로 에이전트가 종료되어서 로그가 수집되지 않고 있는데 며칠 동안 모르고 있어서는 안되겠지요.Flume 에서는 모니터링 인터페이스도 여러가지를 제공하고 있는데, 그 중 가장 이용하기 간편한 것은 HTTP 를 통한 JSON reporting 이었습니다. 에이전트 자체가 HTTP 서비스로 작동해서, 특정 포트로 요청을 보내면 에이전트의 상태를 JSON 으로 정리하여 응답을 주게 되어 있습니다. 에이전트 실행시에 옵션 몇 개만 추가하면 바로 설정할 수 있기 때문에 매우 간단합니다.Health 페이지를 이용한 모니터링그런데 이 리포팅이 제대로 나오지 않으면 어떻게 알림을 받을 수 있을까요? 각 서버마다 JSON 리포팅을 요청해서 응답이 제대로 오지 않으면 이메일을 보내는 스크립트를 만들어서 cron 으로 5분마다 실행하는 방법도 있습니다. 하지만 이 스크립트가 제대로 동작하지 않거나, 이게 실행되는 서버가 다운되면?결국 스스로를 믿지 못하고 택한 방법은 외부 서비스 Pingdom을 이용하는 것이었습니다. 단, 외부 서비스가 각각의 웹서버에 직접 접근하여 리포팅을 요청하는 방식은 보안상 문제가 될 수 있어서 아래와 같이 보완하였습니다.웹 서비스 상에 health 페이지 구현. 이 페이지는 각 웹서버의 에이전트의 JSON reporting 포트로 요청을 보내서, 결과를 종합해서 다시 JSON 으로 보여줌.모든 에이전트가 정상적으로 리포트를 보내면 {“status”: “OKAY”} 를, 아니면 {“status”: “ERROR”} 를 보여줌.이 health 페이지의 내용을 모니터링하도록 Pingdom 설정. {“status”: “OKAY”} 가 응답에 없으면 알람 메일이 오도록 함.{ "status": "OKAY", "metrics": { "192.168.0.101": { "SOURCE.log_src": { ... }, "SINK.avro_sink": { "BatchCompleteCount": 562110, "ConnectionFailedCount": 294, "EventDrainAttemptCount": 56246850, "ConnectionCreatedCount": 31, "Type": "SINK", "BatchEmptyCount": 16, "ConnectionClosedCount": 30, "EventDrainSuccessCount": 56243927, "StopTime": 0, "StartTime": 1459135471379, "BatchUnderflowCount": 610 }, "CHANNEL.mem_channel": { ... } }, "192.168.0.102": { ... } } }Health 페이지의 Json내용JSON 리포팅의 문제이렇게 설정해 놓고, 며칠간 로그가 HDFS 상에 잘 수집되는 것을 확인하고 만족해 했습니다. 그런데 며칠간 신경을 쓰지 않은 사이, 다시 에이전트를 확인해 보니 모든 웹서버 에이전트가 죽어 있었습니다. HDFS에 로그도 쌓이지 않았구요.확인해 보니, MemoryChannel 의 설정 문제였습니다. byteCapacity 값을 실수로 너무 작게 설정해서, 채널 큐가 메모리 부족으로 터져나간 것이죠. 해당 문제는 byteCapacity 값을 늘려서 간단하게 해결했습니다.문제는 알람이 오지 않았다는 것이었습니다. 문제를 재현해 본 결과, 채널이 터져서 에이전트 실행이 중단되어도, 에이전트 프로세스는 죽지 않고 ExecSource 에서 실행한 자식 프로세스(tail -F)만 죽어 있었습니다. 이렇게 되면 JSON 리포팅도 정상적으로 나오기 때문에, 결국 JSON 리포팅으로는 이런 유형의 에러를 잡지 못한다는 결론이 나왔습니다.클러스터에 모니터링 설정하기결국 웹서버상에서 모니터링하는것 보다는 데이터를 최종 전달받는 하둡 클러스터 상에서 모니터링하는 것이 안정적이라 판단하였습니다. 다행히도, 하둡 클러스터에서 사용할 수 있는 꽤나 좋은 모니터링 도구가 이미 있었습니다.CDH 의 알람 트리거리디북스에서는 기본 하둡 패키지가 아닌, Cloudera에서 제공하는 하둡 배포판인 Cloudera CDH를 사용하고 있습니다. CDH는 클러스터 상에서 사용되는 서비스마다 각종 테스트를 자동으로 실행하여, 테스트가 통과되지 않을 때마다 메일로 알람을 보내줍니다. 그리고 웬만한 필수 테스트는 기본적으로 설정되어 있지만, 사용자가 커스텀 서비스를 직접 제작할 수도 있습니다. CDH가 각 에이전트의 소스, 채널, 싱크마다 초당 전송한 이벤트 개수 등의 측정치(metric)을 모두 기록하고 있기 때문에, 이 값들이 일정 수준 이상/이하가 될 때마다 알람이 트리거되도록 설정할 수 있습니다.CDH의 알람 트리거 편집 화면웹서버마다 알람 설정하기그런데 이것으로 끝이 아닙니다. 클러스터 에이전트는 각 서버에서의 트래픽이 모두 모이는 곳이기 때문에, 여기에서 모니터링을 하는 것은 웹서버 상에서 모니터링하는 것보다 기준이 애매해집니다.10대의 웹서버 중에 한 대만 문제가 생겼을 경우, 클러스터 에이전트가 받는 트래픽은 0으로 줄어드는 것이 아니라 90%로 줄어듭니다. 알람을 트리거하는 역치(threshold)를 평소 트래픽의 90%로 잡아야 한다는 것이지요. 그런데 트래픽이라는 것이 원래 날짜와 시간에 따라 달라지기 때문에, 이 역치값을 고정된 값으로 정할 수가 없습니다. 트래픽이 높은 때를 기준으로 하면, 트래픽이 낮아지는 새벽 시간마다 가짜 알람(false alarm)이 오게 되겠지요. 그렇다고 트래픽이 낮은 때를 기준으로 하면, 트래픽이 높은 때 웹서버 에이전트가 죽더라도 새벽이 될 때까지 알 수 없습니다.결국 클러스터 단에서도 각 웹서버마다 트래픽을 구분해 주어야 한다는 결론이 나옵니다. 다행히 한 에이전트가 여러 개의 채널과 싱크를 가질 수 있고, 이벤트 헤더의 내용에 따라 소스가 어느 채널로 이벤트를 보낼지 결정해 주는 채널 셀렉터 (Channel Selector)라는 것이 있습니다.웹서버 에이전트의 소스에서는 각 이벤트 헤더에 자기 호스트명을 달아 준다. (Interceptor 는 각 이벤트에 원하는 헤더를 달아주는 역할을 한다. HostInterceptor 이용)클러스터 에이전트는 1개의 소스와, 웹서버 대수만큼의 채널 및 싱크가 있다.클러스터의 소스는 이벤트의 host 헤더를 보고 그에 해당하는 채널로 이벤트를 전달한다. (MultiplexingSelector 사용)각 채널은 자신에게 대응되는 싱크에 이벤트를 전달하고, 싱크는 각자의 HDFS 경로에 이벤트를 파일로 출력한다.최종 에이전트 구성: 채널 셀렉터로 트래픽 나누기최종적으로 나온 에이전트의 구성은 다음과 같습니다.최종 에이전트 구성그리고 에이전트 설정 파일은 아래와 같이 작성했습니다.... log_to_avro.sources.log_src.type = exec log_to_avro.sources.log_src.command = tail -F /path/to/log/file log_to_avro.sources.log_src.restart = true log_to_avro.sources.log_src.channels = mem_channel log_to_avro.sources.log_src.interceptors = ts_ic host_ic # 호스트 인터셉터 설정 log_to_avro.sources.log_src.interceptors.ts_ic.type = timestamp # 이벤트 헤더에 timestamp 삽입 (날짜별 구분을 위해) log_to_avro.sources.log_src.interceptors.host_ic.type = host # 이벤트 헤더에 호스트명 삽입 (호스트별 구분을 위해) log_to_avro.sources.log_src.interceptors.host_ic.useIP = true # 호스트명 대신에 IP 사용 log_to_avro.channels.mem_channel.type = memory log_to_avro.channels.mem_channel.capacity = 10000 log_to_avro.channels.mem_channel.transactionCapacity = 10000 log_to_avro.channels.mem_channel.byteCapacityBufferPercentage = 20 log_to_avro.channels.mem_channel.byteCapacity = 10485760 log_to_avro.sinks.avro_sink.type = avro log_to_avro.sinks.avro_sink.channel = mem_channel log_to_avro.sinks.avro_sink.hostname = hostname.of.cluster.agent log_to_avro.sinks.avro_sink.port = 4141 ...웹서버 에이전트 설정파일... avro_to_hdfs.sources.avro_src.type = avro avro_to_hdfs.sources.avro_src.bind = 0.0.0.0 avro_to_hdfs.sources.avro_src.port = 4141 avro_to_hdfs.sources.avro_src.channels = c_101 c_102 avro_to_hdfs.sources.avro_src.selector.type = multiplexing # Multiplexing Selector 설정 avro_to_hdfs.sources.avro_src.selector.header = host # 호스트 이름으로 채널 나누기 avro_to_hdfs.sources.avro_src.selector.mapping.192.168.0.101 = c_101 # 192.168.0.101 에서 온 이벤트는 c_101 채널로 avro_to_hdfs.sources.avro_src.selector.mapping.192.168.0.102 = c_102 # 192.168.0.102 에서 온 이벤트는 c_102 채널로 # 채널 c_101 설정 avro_to_hdfs.channels.c_101.type = memory avro_to_hdfs.channels.c_101.capacity = 10000 avro_to_hdfs.channels.c_101.transactionCapacity = 10000 avro_to_hdfs.channels.c_101.byteCapacityBufferPercentage = 20 avro_to_hdfs.channels.c_101.byteCapacity = 10485760 # 싱크 k_101 설정 avro_to_hdfs.sinks.k_101.type = hdfs avro_to_hdfs.sinks.k_101.channel = c_101 avro_to_hdfs.sinks.k_101.hdfs.fileSuffix = .log.gz avro_to_hdfs.sinks.k_101.hdfs.path = hdfs://namenode/path/to/logs/dir/%Y%m%d/%{host} # 날짜별, 호스트별로 다른 디렉토리에 avro_to_hdfs.sinks.k_101.hdfs.rollSize = 104857600 avro_to_hdfs.sinks.k_101.hdfs.rollInterval = 7200 avro_to_hdfs.sinks.k_101.hdfs.rollCount = 0 avro_to_hdfs.sinks.k_101.hdfs.fileType = CompressedStream avro_to_hdfs.sinks.k_101.hdfs.codeC = gzip # 채널 c_102 설정 avro_to_hdfs.channels.c_102.type = memory avro_to_hdfs.channels.c_102.capacity = 10000 avro_to_hdfs.channels.c_102.transactionCapacity = 10000 avro_to_hdfs.channels.c_102.byteCapacityBufferPercentage = 20 avro_to_hdfs.channels.c_102.byteCapacity = 10485760클러스터 에이전트 설정파일p.s. Flume 설정 파일은 변수 또는 외부 파일 include 등을 지원하지는 않아서, 위와 같이 반복되는 설정을 여러 번 써 주어야 합니다.호스트마다 CDH 알람 트리거 설정그리고 CDH 상에서도 웹서버 호스트의 개수만큼 알람 트리거를 만들어 줍니다. 초당 이벤트 개수가 0에 가깝게 떨어지면 알람이 오도록 해 주면 됩니다. 채널/싱크 중 어느 것을 기준으로 해도 크게 상관은 없는데, 저희는 싱크가 초당 이동완료한 이벤트 개수를 기준으로 했습니다.CDH에서의 알람 트리거 상태 화면이렇게 해 놓으면 또 한가지 좋은 점은, CDH가 알아서 차트를 그려 주기 때문에, 웹서버마다 트래픽 추이를 한눈에 볼 수 있다는 것입니다.HDFSSink의 초당 이벤트 개수 그래프맺음말지금까지 Apache Flume 과 CDH 를 사용해 로그 수집 시스템을 구성하고 모니터링을 설정한 후기를 살펴 보았습니다. 이 과정에서 느낀 점들을 한번 정리해 보겠습니다.첫째, 일견 간단해 보이는 기능이었지만 의외로 많은 시행착오를 거쳐야 했습니다. 아무리 간단해 보이더라도 각자의 상황에 맞추어 시스템을 설계하는 데에는 그에 맞는 고민을 거쳐야 합니다.둘째, 처음에는 로그가 일단 수집되게 하는 것이 가장 중요하다고 생각했는데, 실제로 겪어보니 모니터링이 훨씬 어렵고 중요한 문제라는 것을 알게 되었습니다. 어떤 기능이 일단 실행되도록 설정을 해 놓더라도, 그것이 매일 문제없이 실행됨을 보장받는 것은 또 다른 문제입니다.셋째, Health 페이지와 Pingdom을 이용한 웹서버 측의 모니터링은 JSON 리포팅의 문제 때문에 큰 쓸모가 없게 되었습니다. 하지만 꽤 유용한 테크닉이라는 생각이 들고, 어딘가에서는 비슷하게 이용할 수 있을 것 같습니다.마지막으로 CDH 쓰면 좋습니다. 많은 것들이 편해집니다.P.S. 리디북스 데이터팀에서는 이러한 로그 시스템을 함께 고민하고 만들어나갈 분들을 찾고 있습니다. 많은 관심 부탁드립니다.#리디북스 #개발 #서버 #서버개발 #모니터링 #로그 #Flume #CDH #로그수정 #인사이트
조회수 1028

VCNC 개발팀 워크숍을 소개합니다. - VCNC Engineering Blog

VCNC 에서는 최근에 모빌리티 서비스 이동의 기본 타다를 출시했습니다. 신규 서비스를 준비하면서 팀도 새롭게 구성되고 새로운 멤버들이 팀에 합류했습니다. 이러한 변화 속에서도 좋은 개발 문화를 유지하기 위해서 VCNC 개발팀은 큰 노력을 하고 있습니다. 그중에서도 모두가 자랑하고 싶어 하는 VCNC 개발팀 워크숍을 소개합니다.VCNC 개발팀 워크숍최근 VCNC 개발팀 워크숍은 2018년 12월 19일 수요일에 진행되었습니다. 2016년 12월 처음 시작해서 최근까지 총 6번의 워크숍이 열렸습니다. VCNC 가 SOCAR에 인수되어 타다 서비스를 바쁘게 준비했던 2018년 8월을 제외하고 1년에 3번씩(4, 8, 12월) 꾸준히 개최되고 있습니다.VCNC 개발팀 워크숍은 개발팀 멤버들이 업무 외적으로 가지고 있던 각자의 관심사들을 공유하고 개발자들이 할 수 있는 고민을 같이 나눠보기 위한 욕구에 의해 처음 제안되었습니다. 포맷을 어떻게 할지 논의한 끝에 아래와 같은 포맷으로 워크숍을 진행하기로 했고 최근까지 이 포맷으로 워크숍을 진행하고 있습니다.오전 시간에는 모든 멤버가 각자의 관심사에 대해 5~10분 정도로 가벼운 라이트닝 톡을 하자.오후 시간에는 토의 주제를 정해서 몇 가지 깊은 토의를 나눠보자.회사의 업무에서 완전히 벗어나서 집중하기 위해 프로젝터 사용이 가능한 외부 카페를 대관하자.고기 회식을 하자!2018년 12월 제 6회 VCNC 개발팀 워크숍 단체 사진라이트닝 톡라이트닝 톡은 위에 언급했던 대로 모든 멤버가 5~10분 정도의 시간 동안 각자의 관심사에 대해서 다른 멤버들에게 소개하는 시간입니다. 발표 주제는 처음에는 개발로 한정 지었다가 더 폭넓게 관심사를 공유하기 위해 자유 주제로 변경했습니다. 다들 워크숍 전날까지는 어떤 발표를 해야 할지 걱정하며 투덜대지만, 막상 워크숍 당일이 되면 굉장히 흥미로운 주제들을 가지고 참여를 합니다. 라이트닝 톡이라는 의미에 맞게 1회 워크숍에서는 타이머를 켜고 시간 체크를 하면서 간단하게 발표를 했습니다. 그런데 기대했던 것보다 훨씬 좋은 발표들이 나오면서 발표 시간을 유동적으로 해서 발표의 퀄리티를 더 높이기로 했는데, 바로 다음 워크숍에 1시간 10분짜리 장대한 강의가 등장하는 바람에 절제의 중요성을 다시금 느끼면서 다시 타이머를 켜기로 했습니다…2017년 12월 워크숍에서는 PB팀이 상품 협찬을 해줘서 (PB팀 감사합니다!) 최고의 발표를 선정해 밀크 미니 인형을 지급했습니다. 영예의 수상자는 욕망의 흐름 이라는 발표를 정말 욕망의 흐름대로 발표한 Max로 선정되었습니다.<iframe src="https://docs.google.com/presentation/d/e/2PACX-1vQChBaARqlj8XfZx75MtkcejwupwBPt9tgD47sL99L1mHceYnPR2yDJnVAKFq8nFHXG9Pc9QbWBA5Eb/embed?start=false&loop=false&delayms=10000" frameborder="0" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"> 지금까지 워크숍을 6회나 진행했기 때문에 상당한 양의 라이트닝 톡 발표자료들이 모였습니다. 그중에서 몇 가지 발표의 슬라이드를 공유합니다.Glitches of Mario by PrinceOrigami - 종이접기와 수학 by PrinceLattice-based Cryptography by BradTADA-Android 회고 by David기반 작업들을 무엇을 했는가? + RIB 간단 설명Contract by DoogieAd Fraud by HughBB84 - 양자 역학을 이용한 절대적으로 안전한 키 분배 프로토콜 by James불완전성 정리 by James삼단논법 by JamesGAN by MaxReinforcement Learning based on AlphaGo by NelsonSteganography by Nelson재귀의 폭풍 by TedUBER: COSTS & REVENUES by TerryProbabilistic Filter by Youngboom다음 워크숍부터는 발표를 녹화해서 슬라이드와 함께 공유해보도록 하겠습니다.최고의 발표로 선정된 Max종이접기로 각의 3등분선 구하기 실습필자의 발표를 경청하는 멤버들디스크의 위험성을 온몸으로 표현 중 심층 토의VCNC 개발팀 워크숍에서는 회사의 주요 결정사항 혹은 공통으로 관심이 있는 이슈들을 선정해서 모두의 의견을 듣고 공감대를 형성하거나 액션 플랜을 세우는 토의를 진행합니다. 토의의 주제는 발전적이고 열린 커뮤니케이션을 지향하는 멤버들의 특성상 회사 생활 과정에서 자연스럽게 형성됩니다. VCNC 에서는 평소에도 서로의 의견을 공유하는 자리를 자주 가집니다. 그 예로는 매 달 진행하는 매니저와의 1:1 개인 리뷰 제도, 각 팀별 주간 회고 회의, 제품 피쳐 개발 단위로 진행하는 회고 회의 등이 있습니다. 이러한 의견 공유 과정에서 멤버 각자가 생각하는 불만, 문제점, 희망 사항들이 자연스럽게 워크숍의 토의 주제로 발전됩니다. 토의는 특별한 절차 없이 모든 구성원이 자연스럽게 끼어들면서 자신의 의견을 펼치며 진행됩니다. 모두의 의견을 듣는 것이 중요하기 때문에 특별한 주제가 아니라면 적은 인원으로 조를 구성해서 토의한 뒤 의견을 취합합니다. 정리한 내용은 제품팀 및 HR 담당자에게 전달되며 그 후 우리가 해볼 수 있는 시도들을 하거나 새로운 회사의 정책들이 생겨나기도 합니다.둘러앉아서 토의에 집중하는 멤버들 (편안한 자세 가능)아래의 항목들은 실제로 진행했던 토의의 주제들입니다.순수 개발 관련점차 높아지는 개발 복잡성을 어떻게 해결할까?서버-클라 간 프로토콜 문서화 문제제품 개발 프로세스 관련제품 개발 프로세스를 스프린트에서 칸반으로 변경하고 지금까지 겪었던 느낀 점, 문제점 및 해결 방안은?이슈 관리가 잘 안 되는데 원인 및 해결책은?QA가 필요한가? 제품 품질을 높이기 위해선 무엇을 해야 하는가?회사의 문화, 복지 등 전반회사에서 팀 간 커뮤니케이션을 원활하게 하기 위해 Manager 제도가 도입되는데 Manager 는 어떠한 역할을 맡아야 하는가?Manager 제도의 후기 공유 및 개선 방향.어떠한 모습의 회사를 원하는가?필요한 사내 문화 및 복지는 무엇이 있을까?개인의 발전 관련언제 동기부여가 되는가? 저하되게 만드는 요인은?어떠한 사람과 같이 일을 하고 싶은가?어떠한 모니터링 및 피드백을 받고 싶은가?VCNC 개발팀 워크숍의 토의 결과로 회사의 많은 부분이 발전하고 있습니다. QA 팀이 생겼고 해외 및 국내 콘퍼런스 지원 관련 복지 정책이 새로 생겼습니다. 제품 개발 프로세스는 새로운 시도를 거치면서 지속해서 발전해 나가고 있습니다.그 외우걱우걱워크숍에는 풍족한 먹을거리가 함께합니다. 카페를 대관하는 경우에는 무제한으로 음료가 제공되며 점심시간에는 배달을 시켜서 먹으면서 함께 이야기를 나눕니다. 마무리로 저녁에는 고기를 먹고 싶은 만큼 맘껏 먹으면서 역시 이야기꽃을 피웁니다.미니게임워크숍의 포맷이 라이트닝 톡 + 심층 토의 조합으로만 진행되어 느껴지는 지루함을 탈피하기 위해 2018년 4월 워크숍에서는 2인 1조로 팀을 구성해서 미니게임을 진행했습니다. 개발자 감성에 걸맞게 스크래치 게임인 Lightbot 2로 1시간 정도 플레이를 했습니다. 승패가 있는 대결은 아니었지만 다들 피로감을 호소할 정도로 엄청나게 집중하면서 시간을 보냈습니다.워크숍의 핵심은 고기를 굽는 것점심에는 피자를 시켜 먹으며 자유로운 대화를 나눕니다.집중해서 Lightbot 을 플레이하는 플레이어휴식 중에도 즐거운 대화는 계속됩니다. 마치며VCNC 개발팀 워크숍은 앞으로도 계속됩니다. 앞으로도 좋은 회사의 문화를 소개하는 기회를 자주 만들도록 노력하겠습니다. 저희와 함께 VCNC 를 발전시킬 좋은 분들을 기다리고 있으니 많은 지원 바랍니다!
조회수 1362

docker the cloud

당신의 기획안을 통과시키는 마법의 단어, 클라우드안녕, 여러분! 다들 다망하신 와중에 이렇게 지면으로 찾아뵙게 되어 굉장히 반갑습니다. 저는 spoqa의 노예 xym입니다. 어느덧 벌써 연말이네요. 온갖 골든 위크로 시작했던 4/4분기, 이제 한창 주말 외에는 법정공휴일이 없는 데스마치를 진행중이시리라 생각되는데요, 안 그래도 다들 크리스마스만 바라보고 미친듯이 달리고 계시죠?네, 그래서 제가 이렇게 잠시 여러분 머리를 식혀드리기 위해 한 번 재밌는 이야기를 하고자 찾아뵙게 되었습니다. 개발자가 아닌 분들에게도 별로 어렵지 않게 쓰고자 노력했으니 한번쯤 “오 이런 신기한 게 있구나”하고 읽어보시고 머리 좀 식히고 가세요.업계 분들이나, 이쪽 업계에 소식이 빠삭한 분들은 아시겠지만 몇년 전부터 이 바닥은 새롭게 몰아치는 파도를 맞고 있습니다. 2, 3년 전부터 올해 중순까지 업계 뜨거운 감자였던 키워드들에 대해서 기억하고 계신가요? 네, 그 소위 HTML5니 클라우드, 빅데이터, 소셜 게임 따위의, 기획안에 쓰면 사장님 입이 귀에 걸리게 만드는 마법의 단어들이요.이 글도 사실 그 마법의 단어들에 관련된 이야기입니다. 정확히는 클라우드 기술에 관련된 이야기예요.뜬구름 잡는 클라우드대관절 클라우드란 무엇이길래 여러분의 기획안을 통과시키게 하는가 궁금하지 않으셨나요? 알고 계신 분들도 많을 테니 간략하게 설명하고 넘어가겠습니다. 클라우드는 클라우드 컴퓨팅 기술의 약자입니다. 위키피디아에 있는 정의는 다음과 같습니다:인터넷 따위의 네트워크를 통해 실시간으로 많은 컴퓨터들을 관리하는 여러 컴퓨팅 기술과 관련된 개념들을 총칭얼핏 들으면 굉장히 뜬구름 잡는 소리입니다. 아니, 그럼 그 전까지는 그런 걸 안 했다는 건가? 물론 아닙니다. 클라우드 컴퓨팅이란 단어가 버즈워드로써 시장을 강타하기 전에도 소위 클라우드 컴퓨팅을 위한 기술들은 존재했습니다.엄밀히 말하면 클라우드 컴퓨팅은 ‘기술 융합’의 일종이라고 볼 수 있습니다. 기존에 존재하던 개념들과 기술들을 융합하여 새로운 접근법을 탄생시킨 것이죠. 간단히 소개하자면 그 클라우드 컴퓨팅을 이루는 기반에는 다음과 같은 두 개의 거대한 축이 있습니다.가상화(Virtualization) : 하나의 컴퓨팅 자원을 여러 개로 나누어 마치 여러 개의 독립된 컴퓨터처럼 사용하는 기술 혹은 개념그리드 컴퓨팅(Grid computing) : 하나의 작업을 동시에 여러 개의 컴퓨터가 분할하여 처리하는 기술 혹은 개념거기에 중요한 개념 하나만 더 얹고 넘어가겠습니다. 이것도 한 때는 버즈워드로 사람들을 흥분시켰었죠.Application Programming Interface(API) : 복잡한 내부 동작에 대해서는 잘 몰라도 정해진 규약(인터페이스)만 알고 있으면 해당 기능을 사용할 수 있도록 한다는 개념그러니까 어떤 작업을 하기 위해 하나의 컴퓨터를 여러 개로 분리하고(자르고), 또다시 그 분리된 컴퓨터들을 합쳐서(합치는), 어쨌든 정해진 규약대로 사용할 수 있게 만드는 것(편한 거).아, 너무 기네요. 줄여서 “난 잘 모르겠지만 뭔가 좀 편한 거군.” 정도로 해두죠. 그게 클라우드의 궁극적인 목표이자 본질이라고 볼 수 있겠습니다. 그래서 이름도 뜬구름 잡는 소리 같다고 클라우드잖아요?그래도 마냥 뜬구름 잡는 소리만 할 수는 없으니 한번 클라우드 서비스의 종류를 알아봅시다.IaaS(Infrastructure as a Service) - 인프라스트럭쳐, 한마디로 서버를 조립하고 설치하는 방법을 몰라도 쓸 수 있도록 편하게 제공한다고 보면 됩니다. Amazon Web Service 같은 애들이죠.PaaS(Platform as a Service) - 이번엔 IaaS를 잘 몰라도 서비스를 돌릴 수 있게 만들어진 플랫폼을 제공합니다. Heroku가 대표적입니다.SaaS(Software as a Service) - 그렇게 만들어진 플랫폼 위에 돌아가는 서비스들을 제공합니다. icloud.com의 keynote 따위가 있겠군요.생각보다 어렵지 않죠?docker 란 무엇인가사설이 길었네요. 이제부터가 본론입니다. 제가 오늘 소개할 녀석은 클라우드 컴퓨팅에 있어 “자르는” 축을 담당하는 가상화의 떠오르는 아이돌, LXC를 사용한 docker 입니다. LXC가 무엇인지는 여기서 중요하지 않습니다#2. 그냥 업계의 떠오르는 아이돌 정도로 해 둡시다. 그러니까 아이유 같은 존재죠.docker가 등장한 배경을 설명하자면 이렇습니다. Heroku와 함께 PaaS계에서 끗발을 날렸던 dotCloud는 어느 날 갑자기 충격적인 발표를 합니다. 자기네들이 쓰는 가상화 및 애플리케이션 플랫폼을 공개해 ‘오픈 소스로’ 제공하겠다는 것이죠. 아니, 이럴 수가! 이러시면… 이러시면 정말 감사합니다#3!docker의 가장 큰 특징은 다음과 같이 요약할 수 있습니다.image 관리의 간편화와 container 관리 간편화어떤 서비스를 돌리기 위해서는 필요한 서버들이 있습니다. 데이터베이스 서버, 웹 서버, 캐시 서버, 워커 서버 따위의 것들이죠. 이 모든 걸 한 군데로 퉁쳐서 모을 수도 있겠지만 그렇게 되면 데이터베이스, 웹, 캐시, 비동기 업무를 위한 설정과 프로그램들을 한 군데로 모아 관리해야 합니다. 그렇게 되면 설정이 복잡해지거나 애플리케이션이 거대해지거나 필요할 때 횡적인 확장을 하기가 어려워집니다.예를 들어 웹서버에서는 A라는 라이브러리의 1버전을 필요로 하는데 데이터베이스 서버에서는 2버전을 필요로 한다던지, 이벤트 하느라 접속자가 너무 증가했는데 다른 웹서버가 한시간 정도만 필요한 일을 그럴 수 없어서 서버를 통째로 하나 사야 한다던지 하는 일들이죠. docker는 그런 상황에 유연하게 대응하기 위해 서버 설정과 필요한 프로그램들을 따로 관리할 수 있는 환경을 제공합니다.docker는 이렇게 분리된 환경을 image라고 부르며, 이 image를 기반으로 여러 개의 container를 생성할 수 있습니다. 음… 이렇게 이해하시면 편할 것 같습니다. image는 유전자 설계도고, container는 그 유전자 지도에서 만들어진 생물체라고나 할까?즉, 이 설계도를 관리하면 필요할 때 목적에 적합하게 만들어진 생물체를 얼마든지 만들어낼 수 있게 되죠. 필요할 때는 설계도의 설계를 바꿔서 새로운 생물체를 만들어낼 수도 있습니다. 단순하지만 docker의 가장 커다란 컨셉이고 강력하기까지 합니다. 이렇게 단순하고 간편한 환경은 여러 가지 시도를 가능하게 합니다.오토스케일링(웹서버가 필요할 때 웹서버를 막 찍어낸다던가!)유연한 배포 정책(서버를 최신 버전으로 업데이트했는데 버그가 있어서 재빨리 옛날 버전으로 돌아가야 한다던가!)자원의 효율적인 활용(이 쪽 서버가 놀고 있으니까 여긴 웹서버 두개 정도 더 띄운다던지)거기다 수고를 좀 더 들이면, docker의 API를 활용해 Heroku 부럽지 않은 웹 GUI PaaS 서비스를 만들 수 있을지도 모릅니다(만들어 주시면 감사히 쓰겠습니다).한번 docker를 살펴봅시다이야기는 실컷 했으니 한번 설치해보고 실행시켜봅시다. 지면 관계상 모든 플랫폼을 다룰 수는 없기에 우분투 13.10을 기준으로 살펴보도록 하겠습니다. 필요하신 분들은 공식 홈페이지 설치 메뉴얼을 참고하여 진행해주세요.주의 : 이후 내용은 비 개발자 분들에게는 다소 지루한 내용일 수도 있습니다.docker 설치curl http://get.docker.io | sudo sh 참 쉽죠?자 이제 시작이야이제 여러분의 플랫폼에는 docker가 설치됐습니다. 한번 서버에서 기본 이미지를 다운받아 설치해 봅시다.sudo docker pull base 인터넷 환경에 따라 좀 기다리셔야 하실지도 모릅니다. 이미지가 설치되면 아래 명령으로 확인할 수 있습니다.sudo docker images 아래와 비슷한 화면이 나타났다면 성공한 겁니다.REPOSITORY TAG IMAGE ID CREATED SIZE base latest b750fe79269d 8 months ago 24.65 kB (virtual 180.1 MB) base ubuntu-12.10 b750fe79269d 8 months ago 24.65 kB (virtual 180.1 MB) …(생략) 이렇게 내려받은 image에는 다음과 같은 명령어로 접근할 수 있습니다.sudo docker run -i -t base /bin/bash 자세한 명령어 사양은 docker help run을 실행해 알아볼 수 있습니다. 여러분은 이제 base라는 image에 접속했습니다. 지금부터 하는 행동은 image에 영향을 미치게 되며, 이는 전부 로그로 남아 저장됩니다. 한번 이것저것 설치해봅시다.sudo apt-get install python ruby … 이후에 Ctrl+D를 눌러 이미지를 빠져나옵니다. 그리고 아래 명령을 입력하면 방금 전에 수정한 container 목록이 출력됩니다.sudo docker ps -a 아래와 같은 식으로 출력됩니다.CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES eda0060b7af9 base:latest /bin/bash 6 minutes ago Exit 0 lavender_deer 66c849867834 busybox:latest echo Docker has been 8 minutes ago Exit 0 blue_cat 이제 image의 수정사항을 기반으로 새로운 이미지를 만들어 봅시다. 이미지를 만드려면 변경사항을 commit 해야 합니다. VCS나 DVCS를 쓰시는 분이라면 무슨 말인지 감이 오실 겁니다. 네, 바로 버전 관리 시스템의 그것입니다. 기존 base를 기반으로 변경사항을 만들고 commit하여 새로운 이미지를 생성할 수 있습니다. 매우 쉽군요. 한번 생성해봅시다.docker commit [ID] [image name] commit 명령의 구조는 단순합니다. container ID와 그리고 만들 이미지 이름입니다. 이미지 이름은 보통은 만든이/목적 같은 컨벤션으로 만들곤 합니다. 저는 아래와 같이 만들어보겠습니다.sudo docker commit eda0060b7af9 xymz/grocery 확인은 당연히 아래와 같이 할 수 있습니다.sudo docker images repository 에서 여러분이 만든 이미지 이름을 확인할 수 있다면 성공한 겁니다. 여러분의 첫 docker image 생성을 축하합니다!물론 이렇게 약간 거칠어보이는 방법과는 다르게 Dockerfile 이라고, 딱 봐도 버전관리 시스템에 넣을 수 있을 거 같고 정리가 잘 되는 방법도 존재합니다. 아마도 실제로 사용하실 땐 Dockerfile을 사용하게 되실 거고, 그 방법이 훨씬 낫습니다. 다만 본 포스트의 목적은 개발자나 비개발자 분들에게 docker를 한번 소개해보자는 취지라서 Dockerfile의 operation 을 일일히 설명하기엔 얘기가 너무 복잡해질 것 같아 직접 try-out 하기에 쉬운 commandline 쪽을 선택하게 되었습니다.당연히 이게 끝은 아닙니다여기까지 나온 내용으로 서비스를 구성하기에는 무리가 있습니다. 우리는 이제 막 docker image를 생성하고 저장하는 방법을 알았을 뿐이지 그 외에는 아무것도 모릅니다. docker를 제대로 사용하기 위해서는 아래와 같은 방법들을 추가적으로 알아야 합니다.생성된 이미지 관리 : 새로 만든 이미지를 어딘가에 업로드하여 다른 docker 시스템(host)에 배포하기 위한 방법에 대해 알아야 합니다.실제 서비스를 container 에 올리고 관리하는 방법 : 아까 언급한 것처럼 예시를 들자면, 현재 서버에서 웹서버를 를 몇개나 띄울 건지 등을 결정하고 관리하는 방법에 대해 알아야 힙니다.docker host와 guest간의 통신 관리 : docker가 설치된 실제 서버와 그 위에서 돌아가는 container들 간에 오가는 통신에 대한 이해가 필요합니다. 포트 바인딩, 포트포워딩이라고도 하죠.docker API : 이 모든 스택을 관리하기 위한 docker의 API를 알고 있다면 무한한 활용이 가능해집니다.하지만 이 방법들에 대해 여기서 다 열거하고 넘어가기에는 무리가 있으니 좋은 링크를 몇 개 소개토록 하겠습니다.파이썬 웹앱 올려보기docker를 개발환경으로 사용해보기Dockerfile 로 image 관리하기포트 리다이렉션적어놓고 보니 대부분 docker 공식 홈페이지 자료들이네요. 사실 docker는 documentation이 훌륭한 편이라, 그 쪽만 참고해도 많은 도움이 되실 겁니다.Deis?그리고 이 모든걸 쉽게 해주겠다는 Deis라는 녀석이 있습니다. Docker, Chef, Heroku Buildpacks를 이용해 하나의 PaaS스택을 만들고 그 위에 여러분의 서비스를 돌릴 수 있도록 해주겠다는 녀석인데요. 어쩌면 진정한 Open source PaaS 종결자일지도 모르겠습니다. 기회가 된다면 다음에 또 소개할 수 있었으면 좋겠네요.마치기 전에즐거우셨나요? 중간 이후 내용은 다소 비개발자분들에게 지루한 내용이었을지도 모르겠습니다만, 전반적으로 최대한 쉽게 설명하고자 노력했습니다. 다음 번에는 더욱 재밌는 글로 찾아볼 수 있도록 하겠습니다. 그럼 뿅!참고한 링크들docker.ioUsing Docker as a Development EnvironmentDocker: Error starting container: Unable to load the AUFS module주석사실 API는 거창한 기술적 개념이라기보단, 소소한 개발 방법론에 가까운 이야기입니다. 온갖 프로그래밍 언어와 다양한 기술들이 난립하는 와중에 그 모든 걸 알고 전부 뭉쳐서 하나의 덩어리를 만들면 관리/사용하는 비용이 너무 커지니 각 영역을 딱딱 잘라 구분하여 ‘정해진 규약’만 알면 서로 통할 수 있게 만들자. 라는 개념입니다.(약간의 지식이 있는 분들을 위해) LXC(LinuX Containers)는 기존 전가상화full virtualization나 반가상화paravirtualization와는 다르게 OS 위에 가상머신이 따로 돌아가는 게 아니라 OS영역에서 공유 라이브러리를 가지고 유저가 생성하는 프로세스 단위로 성능 분리를 합니다. 덕분에 이름에서 보이듯 특정 플랫폼밖에 지원을 하지 않는다는 단점이 있네요. 그래도 가상화에 따른 자원 손실이 최소화된다는 점에서 많이들 선호하고 있습니다. Heroku에서도 LXC를 통해 가상화를 하고 있죠.보통 이렇게 자신들의 플랫폼을 오픈소스로 공개하는 이유는 단순히 사회에 기여하기 위해서도 있지만, 사내에서 사용되는 기술의 수준을 오픈 소스 커뮤니티의 참여를 통해 향상시키고, 또 좋은 개발자들을 리크루팅 할 수 있게 되는 기회를 만드는 등 선순환을 유도하기 위해서입니다. 그러니까 여러분도 사내에서 사용하는 기술을 공개해 주시면 누이 좋고 매부 좋은 일이라 할 수 있죠.이 글은 __저의 개인 텀블러__에서도 찾아볼 수 있습니다.#스포카 #개발 #개발자 #개발팀 #인사이트 #Docker #클라우드 #꿀팁
조회수 2899

iOS 개발을 위한 11가지 노하우

Overview기고 제안을 받자마자 iOS 개발을 시작했을 때가 떠올랐습니다. 신대륙을 마주한 것 같았던 그때의 기분을 아직도 잊지 못하기 때문입니다. 당시까지만 해도 Android 개발만 했기 때문에 iOS는 그야말로 미지의 영역이었습니다. 게다가 개발을 시작하려고 조심스럽게 첫 발을 내딛은 순간, 입이 떡 벌어질 수밖에 없었죠.“이렇게 느린 IDE가 있다니…““개발자 프로그램이 뭐 이렇게 비싸?”XCodeXCode는 그동안 접했던 IDE 중에서도 가장 최악이었고, 개발자 프로그램 등록은 13만 원 상당의 비용을 지불해야 했습니다. 가장 중요한 건 맥 컴퓨터(Macintosh)를 보유해야만 했죠. 처음 개발을 시작하려니 넘어야 할 산이 매우 많았습니다. 맞습니다. 팜므파탈의 대명사 마타하리(Mata Hari)처럼 iOS 개발은 밀당과도 같습니다. 분명 매력적인 일이지만 XCode와 개발자 프로그램 등록은 빙산의 일각이기 때문입니다. iOS는 곳곳에 구덩이를 파고 초보 개발자들을 집어삼킬 준비를 하고있습니다. (예를 들면 리소스를 묶어놓은 R.java 파일 같은 레퍼런스가 없습니다. 흑.)그래서 준비했습니다. 수많은 초보 개발자들이 iOS의 구덩이를 피해갈 수 있는 팁을 말이죠.iOS의 구덩이를 피하는 11가지 방법1.비싼 맥(Macintosh)을 사세요.iOS 개발자에게 MacOS는 필수입니다. XCode가 MacOS만 지원하기 때문입니다. 오픈 소스로 공개된 Swift에는 제약이 없지만 XCode는 MacOS에서만 동작하는 제약이 있습니다. 따라서 맥은 iOS 개발자에게 가장 필요한 준비물입니다. 게다가 하드웨어 리소스를 많이 사용하는 XCode 탓에 더 크고, 더 비싸고, 더 아름다운 맥을 구매하셔야 합니다. Macbook이나 Macbook Air 모두 추천하지 않습니다. 15형 Macbook Pro 모델을 비롯해, Mac Pro나 iMac Pro 등의 고급 모델을 사용하면.. 개발이 잘 됩니다.2.돈을 내세요.iOS를 개발하려면 가장 먼저 Apple Developer Portal에서 연 129,000원의 개발자 프로그램에 등록해야 합니다. XCode를 사용해서 코드만 볼 것이라면 문제가 되지 않지만, 디바이스에 앱을 설치하고, 테스트하며, AppStore에 배포할 거라면 반드시 구매해야 합니다. 이 계정은 앞서 말한 것처럼 1년이 지나면 다시 구매해야 합니다. 만약 기업 개발자로 등록하려면 Enterprise Program이 따로 준비되어 있습니다. 기업을 위해 특화된 In-House 배포 등의 이점이 있습니다. 구매해야할 것이 꽤 많죠? 이제 익숙해져야 합니다.3.XCode를 설치하세요.XCode는 Mac App Store에서 설치할 수 있습니다. 용량이 크기 때문에 설치하기 전에 하드디스크 저장공간부터 확인하는 것이 좋습니다. 처음 실행하면 추가 컴포넌트를 다운로드하는 과정이 실행되고, 그 이후에 XCode를 사용할 수 있습니다. XCode와 관련된 자세한 내용은 아래에서 자세하게 다루겠습니다.4.어려운 것에 대비하세요.1)인증서‘들’XCode 설치 이후에도 몇 가지를 발급 받고, 셋업해야 합니다. 방 탈출 게임처럼 한 단계 한 단계 거치는 과정이 필요합니다. 첫 번째로 인증서‘들’을 발급받아야 합니다. 애플을 대신해 앱을 설치하고, 배포할 수 있는 권한을 위임 받는 과정입니다. 이 인증서들은 Apple Developer Portal의 ‘Certificates, IDS & Profiles’ 항목에서 발급 받을 수 있으며, MacOS의 키체인 앱을 이용해 개인 키를 생성하는 방식으로도 방식으로 발급 받을 수 있습니다. 2)디바이스 등록디바이스-iOS-에 개발한 앱을 설치하려면 애플 개발자 계정에 개발용 디바이스를 등록해야 합니다. 이 과정은 XCode에 신규 디바이스를 연결하고, 빌드 및 배포를 할 때 XCode가 알아서 합니다. 만약 디바이스를 보유하고 있지 않은 상황이라면 해당 디바이스의 UUID를 받아서 개발자 포털에 직접 등록할 수도 있습니다. 3)Bundle IDBundle ID는, 앱의 고유한 ID입니다. iOS가 앱을 식별할 때 사용하는 식별자이며, 보통 ‘com.companyname.appname’ 의 형식으로 회사나 개인의 도메인을 거꾸로 쓰는 것이 보편적입니다. 하지만 Bundle ID는 어디까지나 개발자가 결정하는 영역이므로 인스턴스 이름 지정하듯이 자신만의 고유한 방법을 사용해서 Bundle ID를 지정해도 문제가 없습니다. 4)Provisioning ProfileProvisioning Profile은 디바이스 정보와 앱 정보, 인증서 정보를 매핑해주는 Profile입니다. 최신 XCode에서는 이 Provisioning Profile을 자동으로 관리해주기 때문에 따로 신경쓰지 않아도 좋습니다.5.개발자 포럼에 질문하거나, StackOverflow에 질문하거나!질문하는 사람은 아름답습니다. 궁금하거나, 잘 안 풀리는 코드는 개발자 포럼에서 질문할 수 있습니다. 대신 영어 실력이 좋아야 합니다.크게 기대는 하지 않는 것이 좋습니다. 등록된 discussion에 대한 답글들이 ‘나도 같은 상황이다’, ‘나도 궁금한 점이다’ 등의 다른 개발자들의 답변 정도가 일반적이기 때문이죠.그들의 답변...저는 개발자 포럼보다 StackOverflow를 더 선호합니다. 참여하는 개발자 규모가 다르기 때문에 보다 양질의 정보를 빠르게 찾을 수 있습니다. (하지만 허위 정보도 존재합니다.) Vote 시스템으로 신뢰 높은 정보를 필터링할 수 있으나, 어떤 정보를 선택할지는 당신의 몫입니다.6. iTunesConnect와 친하게 지내세요.앱을 개발했다면, iTunesConnect를 통해 앱을 전 세계의 사용자들에게 배포할 수 있습니다. iTunesConnect는 iOS용으로 개발된 바이너리를 배포하는 등 앱 배포/테스트와 관련된 전반적인 사항들을 관리할 수 있는 포털입니다. AppStore에서 앱을 판매하려면 이 iTunesConnect를 통해 애플과 계약을 해야만 가능합니다. 출시할 앱을 등록하기도 하고, 앱의 사용자들이 어떤 경향을 보이는지 Trend Analysis를 확인할 수도 있습니다.iTunesConnectiTunesConnect에는 다양한 메뉴들이 있고, 앱을 배포하고 관리하는데 필요한 여러 툴이 있으므로 개발 중에 시선을 환기하고자 한다면 iTunesConnect를 한 바퀴 둘러보는 것도 좋습니다. 언젠가는 다 사용하게 될 테니까요.7.앱 개발을 마쳐도 XCode를 사용하세요.앱을 개발하고 iTunesConnect에 업로드하려면, XCode를 통해 간접적으로 바이너리를 업로드하게 됩니다. 서드파티 앱을 사용할 수도 있지만, 제가 주로 많이 사용하는 방식은 XCode입니다. 소스코드가 준비되었다면, XCode 메뉴의 Product > Archive 메뉴를 선택해 XCode가 배포용 앱을 빌드합니다. 빌드가 완료되면, 자동으로 Organizer 창이 열리면서 앱을 업로드할 수 있게 되죠. 이 때 미리 구매한 개발자 계정의 인증서가 준비되어 있어야 합니다. 모든 준비가 완료되고 아카이빙이 완료되면, Organizer의 Archives 탭에서 우측단의 ‘Upload to App Store…’ 버튼으로 바이너리 업로드를 진행할 수 있습니다.8.배포 전에 시험비행을 해봅시다.앱을 개발했다면, 테스트플라이트(TestFlight)를 통해 실제로 앱을 배포하기 전 ‘시험비행’을 할 수 있습니다. iTunesConnect에 관련 테스터들을 등록하고, 등록된 사용자들을 대상으로 미리 앱을 테스트할 수 있도록 요청하는 것이죠. 이 테스트플라이트에 배포된 바이너리를 그대로 AppStore에 배포하게 되므로, 테스트용으로 유용합니다.TestFlight테스트플라이트는 원래 iOS 배포 관리 솔루션을 제공하는 업체였지만 지금은 애플이 인수해 iTunesConnect에서 관리하도록 제공하고 있습니다.9.앱이 죽는다면 Organizer로 확인하세요.iOS는 충돌보고 Crash Report를 Organizer를 통해 오류를 확인합니다. 앱을 설치한 사용자가 동의하면 XCode는 iOS가 앱을 실행하면서 발생한 Crash Report를 애플에 자동으로 업로드합니다. 업로드된 Crash Report들은 XCode의 Organizer를 통해 다운로드하고, 확인할 수 있습니다. Organizer는 XCode > Window > Organizer 항목에서 실행하세요.Organizer와 Crash ReportCrash Report는 Organizer의 상단 Crashes 탭에서 확인이 가능합니다. 또 현재 보고 있는 Crash Report의 어느 부분에서 오류가 발생했는지 알고 싶다면 우측단의 ‘Open in Porject…’ 버튼을 눌러보면 됩니다.10.내 친구 XCode최근 XCode는 메이저 업데이트를 통해 사용성과 퍼포먼스를 향상시켰습니다. 하지만 이만큼 무겁고 느린 통합개발툴 IDE는 이클립스(Eclipse) 이후에 처음입니다. 안드로이드의 경우 IntelliJ 기반의 Android Studio로 쾌적한 개발환경을 제공하고 있는 반면, XCode의 업데이트는 퍼포먼스나 사용성 개선보다는 Swift의 메이저 버전 반영에 더 급급한 느낌입니다. (업데이트 때마다 속지만 ‘혹시 이번에는..’하고 또 속아 넘어갑니다.) XCode 사용을 위한 네 가지 팁을 소개합니다.1)XCode는 모노로그입니다.XCode는 로그를 따로 ‘예쁘게’ 볼 수 없습니다. 검은 화면에 흰 로그가 정리되지 않은 상태로 마구마구 출력됩니다. 개발자들에게는 쥐약같은 상황이죠. 이런 불편한 로그 출력 방식 때문에 저는 별도의 GlobalLogger 모듈을 작성해서 다음과 같은 스타일로 로그를 출력하도록 하고 있습니다.$$ BrandiLogger Error Log ##MESSAGE: Initial Parameter is not exist. ##LOCATION: BRLogPringer.swift @Line: 122 2)iOS개발자를 위한 휴식시간, 빌드 타임XCode의 빌드 타임은 개발자에겐 기나긴 휴식 시간입니다. 소스가 비대해질수록 퍼포먼스는 떨어지며, 담배 한 대를 태우고, 화장실에서 손을 씻고 들어와도 빌드가 절반도 안 된 상황을 마주할 겁니다. 빌드 타임을 줄이고자 구글링을 하면 몇 가지 팁을 발견할 수 있는데, 특히 빌드 타임을 가장 많이 단축할 수 있는 방법이 있습니다.짜잔! 공개합니다!먼저, 프로젝트 셋팅의 ‘Build Settings’ 항목에서 ‘Optimization Level’을 검색합니다. ‘Swift Compiler - Code Generation’ 항목을 찾을 수 있는데요. 여기서 Optimization Level의 Debug 항목을 ‘None’으로 설정하면, 빌드시간이 엄청나게 줄어든 것을 확인할 수 있습니다. Brandi iOS 버전의 소스코드는 원래 컴파일에 7분 이상이 소요되었지만, Optimization Level을 변경한 후 1분 내외로 단축되었습니다. Optimization Setting을 변경할 때는 꼭 Debug 항목만 변경하고, Release 버전은 기존 설정을 유지하는 것이 좋습니다. 그래야 빌드 과정에서의 버그를 막을 수 있기 때문이죠. 만약 이 설정으로 개발하던 도중 소스가 충돌되면 Command+Shift+K 단축키를 눌러 소스를 한 번 클린하고, 재빌드하세요. 충돌이 사라지는 경우가 많습니다. 빠른 빌드를 위해 종종 감수해야 하는 부분이기도 합니다. 3)Derived Data빌드가 자꾸 안되고 꼬일 때는 Derived Data 폴더를 삭제 해 보세요. Derived Data 폴더는 XCode > File > Project Settings(Workspace Settings) 항목에서 ‘Derived Data’ 항목 아래의 폴더 경로에서 접근할 수 있습니다. Derived Data 접근 경로Derived Data 폴더를 삭제하면 거짓말처럼 빌드 오류가 사라지는 기적을 만날 수 있습니다. 4)CocoaPods‘바퀴를 두 번 발명할 필요는 없다’는 격언이 있습니다. 이것을 개발에 적용하면 ‘잘 만들어진 라이브러리를 사용하라’ 정도가 되겠습니다. 개발자의 개발 시간을 현저하게 단축시키는 오픈소스 라이브러리. 이것들을 간편하게 사용하는 방식이 iOS에도 존재하는데, 바로 CocoaPods입니다. 프로젝트 Root 폴더에 Podfile을 생성하고, 원하는 오픈소스 라이브러리들을 명시한 후에 ‘pod install’ 명령어를 입력해주면….CocoaPods오픈소스 라이브러리가 설치되었습니다. 귀찮은 소스 다운로드와 임포트 과정을 거치지 않아도 됩니다. CocoaPods 설치와 사용에 관한 글은 구글링으로 쉽게 찾을 수 있습니다. 꼭 사용하길 권합니다.Mac App Store에서의 XCode 평점XCode는 느리고 불편합니다. 숨겨진 편의기능도 많지만 고질적인 빌드 문제와 사용성 문제를 마주하면 높은 평점을 줄 수가 없습니다. 그런데, 저만 그렇게 생각하진 않더라고요.(위 스크린샷 참조) XCode의 사용법은 기회가 되면 따로 정리하겠습니다.11.어떤 경우에도 대응할 수 있는 화면 구성을 원한다면, AutoLayoutiOS를 사용하면서, 금융권이나 쇼핑 앱들을 사용하다 보면 이런 상황이 발생합니다. 금융권 앱. 화면에 꽉 차지 않는 레이아웃 혹은 비정상적으로 커진 글씨본래 iOS는 단일 디바이스를 지향하는 플랫폼이었습니다. 아이폰 시리즈도 해상도가 변하지 않았기 때문에, 디바이스 종류가 많은 안드로이드처럼 다양한 스크린 사이즈를 지원할 필요가 없었습니다. 하지만 이제는 iPhone SE, iPhone 8, iPhone 8 Plus의 해상도에 iPhone X의 해상도까지 더해지면서 그야말로 ‘해상도 춘추전국시대’가 되었습니다.이런 다양한 해상도를 모두 지원하는 레이아웃을 구성하려면, iOS에서는 AutoLayout을 사용해야 합니다. AutoLayout은 Xib Editor에서 AutoLayout을 활성화하는 방식으로 사용할 수 있습니다. 거기에 한 가지 덧붙이면 Layout Constraints라는 개념도 있습니다. 레이아웃에 조건을 주는 방식입니다. 예를 들어 ‘어떤 해상도에서든 이 컴포넌트는 왼쪽 끝으로부터 10Point의 여백을 가지도록 한다’ 라는 식이죠. AutoLayout, Layout Constraint이 Layout Constraint를 이용하면 짧은 시간 안에 다양한 해상도를 지원하는 레이아웃을 쉽게 만들 수 있습니다. 가히 AutoLayout의 꽃입니다.ConclusionXCode/iOS 개발과 관련된 팁은 대부분 구글링으로 찾을 수 있습니다. 다룰 내용이 많지만 초보 iOS개발자들이 당황할 수 있는 내용을 중심으로 글을 썼습니다. 소소한 이야기지만, 분명 도움을 받을 수 있을 겁니다.글이정환 과장 | R&D 개발1팀[email protected]브랜디, 오직 예쁜 옷만#브랜디 #iOS #개발기 #업무환경 #인사이트 #경험공유 

기업문화 엿볼 때, 더팀스

로그인

/