chap1. 취향을 말하다

『가재가 노래하는 곳』 델리아 오언스

습지에서 홀로 살아가는 소녀 카야의 성장 이야기.

“카야는 죽은 칠면조 옆에 무릎을 꿇고 앉아 시카모어 잎으로 눈을 덮어주었다.”

가족에게 버려진 채 습지에서 홀로 살아가는 카야의 이야기다. 한 인물의 성장 과정을 중심으로 로맨스와 미스터리 요소가 어우러져 있어 카야의 삶 전체를 가까이에서 들여다보는 듯한 느낌을 준다.

카야와 같은 삶을 경험한 적은 없지만, 그가 느끼는 외로움과 성장 과정에서 마주하는 감정에는 자연스럽게 공감할 수 있었다. 책을 읽는 동안에는 주인공이 된 듯 이야기에 깊이 빠져들었고, 책장을 덮은 뒤에도 카야의 삶과 감정이 오랫동안 마음에 남았다. 한 인물의 삶을 따라가며 깊이 몰입할 수 있는 성장소설을 찾고 있다면 추천하고 싶은 책이다.

💡 이 책, 이런 분께 추천합니다
✔️ 성장소설을 좋아하는 사람
✔️ 자연을 배경으로 한 이야기를 좋아하는 사람
✔️ 몰입감 있는 장편소설을 찾는 사람

『아침이 온다』 츠지무라 미즈키

긴 밤을 지나 결국 아침을 맞이하는 사람들의 이야기.

“그러나 아침이 왔다. 끝없이 이어지는 밤의 밑바닥을 걸어, 빛 하나 없는 터널을 빠져나왔다.”

입양을 둘러싼 여러 인물의 시점을 따라 이야기가 전개된다. 같은 사건을 마주한 인물들은 저마다 다른 상처와 사정을 품고 있다. 그들의 이야기를 하나씩 알아갈수록 누구의 입장도 쉽게 판단할 수 없게 된다.

이야기가 진행될수록 감춰져 있던 인물들의 감정이 차례로 드러난다. 읽는 내내 마음이 무거웠지만, 그럼에도 계속 다음 장을 넘기게 만드는 힘이 있었다. 특히 “그러나 아침이 왔다”라는 문장이 오래 기억에 남았다. 책을 끝까지 읽고 나니 제목이 왜 ‘아침이 온다’인지 조금은 알 것 같았다. 누군가에게는 끝나지 않을 듯 길고 어두운 밤일지라도 결국 아침은 찾아온다는 사실이 위로가 됐다. 그 위로를 다른 사람과도 나누고 싶어 이 책을 추천한다.

💡 이 책, 이런 분께 추천합니다
✔️ 감정선이 깊은 소설을 좋아하는 사람
✔️ 책을 덮은 뒤에도 여운이 남는 이야기를 좋아하는 사람
✔️ 인간관계와 가족을 다룬 이야기에 관심이 있는 사람

『키르케』 매들린 밀러

신들의 세계에서 벗어나 자신만의 삶을 선택해 가는 키르케의 이야기.

“무한한 능력을 소유한, 자기 자신 말고는 어느 누구에게도 답을 할 필요가 없는.”

태양신 헬리오스의 딸이지만 신들의 세계에서 환영받지 못했던 키르케가 자신만의 삶을 만들어가는 이야기다. 익숙한 그리스 신화 속 인물들이 등장하지만, 영웅들의 활약보다는 키르케라는 한 인물이 오랜 시간에 걸쳐 변화하고 성장하는 과정에 초점을 맞춘다.

그리스 신화를 좋아해 읽기 시작했지만, 예상했던 것보다 훨씬 인간적인 이야기였다. 다른 이에게 인정받고 싶어 하고, 관계 속에서 상처받기도 하는 키르케의 모습이 낯설지 않았다. 타인의 시선과 기대에 흔들리던 키르케가 점차 스스로 삶의 방향을 선택해 가는 과정도 인상 깊었다. 익숙한 신화를 새로운 인물의 시선으로 만나고 싶다면 흥미롭게 읽을 수 있는 작품이다.

💡 이 책, 이런 분께 추천합니다
✔️ 그리스 신화에 관심이 있는 사람
✔️ 판타지 소설을 좋아하는 사람
✔️ 한 인물의 긴 삶과 성장을 따라가는 소설을 좋아하는 사람

『네 명의 완벽주의자』 이동귀·손하림·김서영

완벽주의라는 마음을 통해 나 자신을 이해하도록 도와준 책.

“칸트는 결혼을 해야 하는 이유 354가지와 결혼을 하지 말아야 하는 이유 350가지를 찾아냈고, 이점이 더 크다는 것을 확인한 후 결혼을 하기로 마음먹었다.”

이 책은 완벽주의를 단순히 장점이나 단점으로 구분하지 않는다. 완벽주의를 여러 유형으로 나누고, 유형에 따라 생각하는 방식과 행동 패턴이 어떻게 달라지는지를 설명한다. 구체적인 사례가 다양하게 담겨 있어 심리학 용어에 익숙하지 않은 사람도 내용을 비교적 쉽게 이해하고 자신의 모습과 연결해볼 수 있다.

평소 ‘왜 나는 이런 부분에 유독 예민할까?’, ‘왜 결과보다 과정에서 더 많은 스트레스를 받을까?’와 같은 의문을 품고 있었다. 이 책을 읽으며 그동안 품었던 질문의 답을 조금씩 찾을 수 있었다. 다른 사람의 행동을 분석하기보다 나 자신의 생각과 행동을 더 깊이 들여다보게 됐다는 점도 좋았다. 완벽주의에서 벗어나는 방법만을 알려주는 책이 아니라, 자신의 성향을 이해하고 적절히 활용하는 방법을 함께 생각하게 한다. 스스로를 조금 더 이해하고 싶은 사람에게 도움이 될 만한 책이다.

💡 이 책, 이런 분께 추천합니다
✔️ 스스로를 한계까지 몰아붙이는 사람
✔️ 자기 이해에 관심이 많은 사람
✔️ 심리학은 어렵다고 생각했던 사람

『면도날』 서머싯 몸

삶의 의미를 찾아가는 한 사람의 길고 깊은 질문.

“그땐 생각할 시간이 많았어요. 그래서 끊임없이 자문했죠. 삶의 목적이 무엇일까?”

제1차 세계대전을 겪은 뒤 삶의 의미를 찾아 나서는 청년 래리의 이야기다. 주변 사람들이 안정적인 직업과 사회적 성공을 향해 나아갈 때, 래리는 자신만의 답을 찾기 위해 그들과 다른 길을 선택한다. 책은 래리와 주변 인물들의 삶을 통해 행복과 성공, 신념과 삶의 목적에 관한 질문을 던진다.

이 책이 좋았던 가장 큰 이유는 삶에 관한 하나의 정답을 제시하지 않기 때문이다. 대신 삶의 목적은 무엇인지, 나는 무엇을 위해 살아가고 있는지를 계속 생각하게 만든다. 읽는 동안 밑줄을 긋고 싶은 문장도 많았고, 책장을 덮은 뒤에도 문득 다시 펼쳐보고 싶어졌다. 빠르게 답을 얻기보다 오랫동안 질문을 품고 생각해보고 싶은 사람에게 추천하고 싶은 책이다.

💡 이 책, 이런 분께 추천합니다
✔️ 생각할 거리를 던지는 책을 찾는 사람
✔️ 삶의 방향과 의미를 고민하고 있는 사람
✔️ 서로 다른 삶의 가치관을 들여다보고 싶은 사람

chap3. 독서 페어링 아이템

헤드폰

주로 출퇴근길 지하철이나 잠들기 전 침대에서 책을 읽는다. 이때 책의 분위기와 맞는 음악을 들으면 책에 더 몰입할 수 있다. 그래서 독서할 때 가장 자주 사용하는 아이템은 헤드셋이다. 노래는 책을 이미 읽어본 사람에게 추천받기도 하고, 실사화된 작품이라면 해당 작품의 OST를 듣기도 한다. 게다가 노이즈 캔슬링 기능까지 갖춰 소음이 심한 전철 안에서도 책에 집중할 수 있도록 도와준다.

#1

여느 때와 다름없는 오늘, 시끄러운 알람 소리가 나를 깨운다.

어두운 새벽녘에 눈을 뜬다.

밖은 비가 내렸는지 짙은 안개가 자욱했다.

지끈지끈한 두통으로 잠을 설친 나는 지칠 대로 지친 몸을 억지로 일으켰다.

긴 하품과 함께 물을 벌컥벌컥 마신 후 뜨거운 물에 샤워를 했다.

주섬주섬 옷가지를 입고 출근을 한다.

출근길에 마주치는 사람들은 나와 같이 다 피로해 보였다.

그들도 삶의 투쟁을 하고 있었다.

열차 소리와 방송 안내음 외에는 아무 소리가 나지 않는 적막한 열차 안.

나를 비롯한 사람들은 스마트폰 세상 속에 살고 있다.

시선은 언제나와 같이 스마트폰을 향해 있다.

이어폰을 귀에 꽂고 주위에서 벌어지는 일에는 관심을 가지지 않는다.

오직 반딧불이처럼 빛나는 액정에만 시선을 둔다.

그렇게 도착역에 다 와갈 때쯤.

누군가가 나에게 손을 뻗어 강제로 종이를 쥐여주고 사라졌다.

‘이건 무슨 일이지?’

‘나에게 지금 뭘 전달하려는 거지?’

종이를 펼쳐 보니 그것은…….

#2

사내 캠페인 홍보지였다.

[마인드 리셋 데이]
3, 6, 9, 12월 넷째 주 금요일
필수 인원을 제외한 전 직원에게 휴식을 권장합니다.

처음엔 ‘우리 회사가 유급 휴가를?’ 같은 의심이 블라인드를 도배했다.

하지만 이제는 참여하지 않는 사람을 찾기가 더 어려웠다.

모두 아는 제도를 굳이 홍보할 이유가 있나?

자세히 보니 재작년 날짜였다.

지금은 쓰지 않는 합병 전 로고도 눈에 띄었다.

뭐야, 우리 회사 사람이었어?

이걸 왜…… 나한테?

빠르게 멀어지는 뒷모습을 멍하니 바라보다, 한 번 더 종이를 살폈다.

[대외비 / 담당자 외 열람 금지]
해당 일자에는 사옥 내 모든 기록 시스템이 일시 정지됩니다.

이전 분기 발생한 보안 사고를 고려하여, 일부 조치가 다음과 같이 변경되었습니다.

급하게 출력한 듯 내용이 잘린 공문.

여백엔 빨간 색연필로 휘갈긴 글씨가 한 줄 적혀 있었다.

– 이번 달엔 뭘 할래?

무심코 종이를 문지른 손끝에 붉은 자국이 남았다.

마치 지장이라도 찍은 듯, 선명하게.

#3

사무실에 도착하자 분위기가 묘하게 달랐다.

출근 시간인데도 사람들의 대화는 줄어 있었다.

다들 화면을 바라보며 불편한 표정을 짓고 있었다.

메신저에는 “오늘 시스템이 자꾸 끊긴다”는 메시지가 줄줄이 올라왔다.

순간 아침에 본 문구가 떠올랐다.

[해당 일자에는 사옥 내 모든 기록 시스템이 일시 정지됩니다.]

설마…… 우연일까?

나는 조심스럽게 종이를 다시 펼쳐 보았다.

여백에 적힌 붉은 글씨가 어째서인지 더 선명하게 보였다.

– 이번 달엔 뭘 할래?

그때, 휴대폰이 울렸다.

모르는 번호였다.

망설이다 전화를 받자, 낮고 차분한 목소리가 흘러나왔다.

#4

“종이 받으셨죠?”

“이번 달은 당신 차례입니다.”

“네?”

“뭐가 제 차례인가요?”

상대방이 말했다.

“지금 가장 하고 싶은 일이 무엇이죠?”

그 질문에 나는 너무 놀란 나머지 미처 대답하지도 못하고 전화를 끊어버렸다.

전화기를 내려놓고 잠시 숨을 골랐다.

주위를 살펴보았지만, 통화 속 상대방의 목소리가 계속 머릿속을 맴돌았다.

어디선가 들어본 듯한, 묘하게 익숙한 목소리였다.

기묘한 전화 통화를 뒤로하고 회사에 도착했다.

동료들은 아무 일 없다는 듯 모니터 앞에서 키보드를 두드리고 있었다.

나 역시 밀린 업무를 처리하기 위해 자리에 앉았다.

그때 사무실 전체의 불이 잠시 깜빡였다.

곧이어 안내 방송이 흘러나왔다.

사내 캠페인 홍보지를 받은 사람은
즉시 회사 밖으로 나오세요.

놀란 동료들이 자리에서 일어났다.

무슨 일이냐며 서로 물었지만, 아무도 아는 사람이 없는 눈치였다.

홍보지와 이상한 전화를 받은 사람은 나뿐인 것 같았다.

그 안내 방송은 결국, 나를 향한 경고임을 분명히 알리고 있었다.

#5

‘뭔가 이상한 하루야.’

조심스럽게 아까 받은 종이를 구겨 주머니에 넣었다.

놀란 마음을 가라앉히기 위해 구겨진 종이 아래 깔린 담배 한 개비를 꺼내 들었다.

그리고 비상구 계단으로 향했다.

그때, 뚜벅뚜벅 누군가의 발걸음 소리가 들려왔다.

이미 요동치던 가슴이 더 거세게 뛰기 시작했다.

나는 본능적으로 아래층으로 몸을 피했다.

어둡고 쾌쾌한 공기 속에서 숨소리가 들렸다.

내가 위치한 곳은 23층과 22층 사이.

바로 22.5층이었다.

그때였다.

그의 눈이 내 눈과 마주쳤다.

순간, 공기마저 얼어붙은 듯한 느낌이었다.

나는 그가 왜 여기 있는지, 그가 나와 어떤 관계가 있는지 전혀 알 수 없었다.

하지만 그의 손에 쥐어진 종이.

그것은 분명 내가 방금 전에 받은 그 종이와 똑같았다.

“너도 받은 거야?”

내 목소리가 떨렸다.

그의 표정은 차가웠다.

마치 내가 말하는 것에 전혀 관심이 없는 듯했다.

대신 그는 잠시 내 얼굴을 쳐다보다가 천천히 고개를 끄덕였다.

“그래.”

그가 낮은 목소리로 대답했다.

“우리가 다 받았다는 게 문제야.”

그는 종이를 펼쳤다.

#6
– 이번 달엔 뭘 할래?

내가 받은 종이에 있던 것과 같은 붉은 글씨가 선명했다.

머릿속이 이해되지 않는 정보로 뒤죽박죽이었다.

오늘은 회사 지정 ‘마인드 리셋 데이’도 아니었다.

그런데 기록 시스템은 제대로 작동하지 않고 있었다.

사내 홍보지도 우리 둘에게만 온 듯했다.

또 이 남자는 누구지?

내가 이 목소리를 어디서 들었었지?

이 종이에 쓰여 있는 말은 무슨 말일까?

머릿속을 정리하는 사이에 깊은 침묵이 흘렀다.

침묵을 깬 것은 남자였다.

“이 짓을 몇 번이나 해도 생각 많은 건 여전하네.”

“뭐라고?”

“……아냐.”

남자는 잠시 말을 삼켰다.

“일단 밖으로 나가자.”

“안내방송에서 나오라고 했으니까.”

그 말을 듣자 밖으로 나가면 어떤 일이 있을지 모른다는 불안감이 엄습했다.

하지만 나가지 않으면 왠지 영원히 멈춰 있을 것 같다는 생각이 동시에 들었다.

남자는 먼저 비상계단 밖으로 걸어 나갔다.

나 또한 홀린 듯 그의 뒤를 따랐다.

#7

비상계단을 벗어나 남자를 따라 들어간 곳은 사옥 깊숙이 숨겨진 낯선 전산실이었다.

서버가 돌아가는 낮은 기계음 사이로 일정한 간격의 마찰음이 들려왔다.

방 한가운데 놓인 낡은 컴퓨터.

그와 연결된 프린터가 쉴 새 없이 종이를 뱉어내고 있었다.

가까이 다가가 확인한 종이 위에는 소름 끼치는 광경이 펼쳐져 있었다.

방금 내가 비상계단에서 나누었던 대화.

그리고 지금 이 방에 발을 들인 순간의 묘사.

모든 것이 실시간으로 기록되고 있었다.

마지막 문장은 모니터 위에서 붉은 글씨로 깜빡였다.

[이번 달엔 뭘 할래? : 당신의 선택]

“이게 대체 다 뭐야?”

“어떻게 우리가 하는 말이 실시간으로…….”

내가 떨리는 목소리로 묻자, 앞서가던 남자가 멈춰 섰다.

그는 나를 돌아보았다.

“망설일 시간 없어.”

“시스템이 복구되면 이 기회도 사라질 테니까.”

그의 눈빛은 서늘하기 짝이 없었다.

“누구의 눈치도 보지 말고, 네가 진짜 하고 싶었던 일을 써.”

나는 홀린 듯 키보드 위에 손을 올렸다.

차가운 기계식 키보드의 감촉이 손가락 끝에 닿자 묘한 전율이 일었다.

자판 위에서 갈피를 잡지 못하고 파르르 떨리던 손가락.

그 사이로 삼켜왔던 문장들이 목구멍까지 차올랐다.

나는 마른침을 삼키며 첫 자판을 내리눌렀다.

타닥.

정적을 깨는 둔탁한 타건음과 함께, 나의 비밀스러운 소망이 화면 위로 한 글자씩 새겨지기 시작했다.

#8

‘지금 내가 원하는 것은…….’

타닥.

화면 위에 찍힌 첫 문장은 너무나도 간단했다.

[당장 퇴근한다.]

순간 프린터가 미친 듯이 돌아가기 시작했다.

종이가 바닥으로 쏟아졌다.

남자는 곧장 종이를 집어 들고 내가 쓴 문장을 읽었다.

그리고 작게 비웃었다.

“푸핫. 겨우 그거야?”

“이 엄청난 시스템에 쓰는 바람이 고작 ‘퇴근’이라고?”

“하지만 역시, 다들 처음엔 그걸 쓰지.”

“다들……?”

혼란스러워하며 되물었다.

남자는 프린터에서 막 나온 종이 더미를 내 앞에 내려놓았다.

“이 방에 들어온 사람들은 전부 한 번씩 선택을 했어.”

남자가 모니터를 가볍게 두드리며 말했다.

“그리고 시스템은…… 그 선택을 현실로 만들지.”

그 말이 끝나자마자 모니터의 붉은 글씨가 바뀌었다.

[선택 확인 : 퇴근한다]
실행까지 남은 시간
00:09:59

내 심장이 철렁 내려앉았다.

“설마…….”

“10분 안에 네가 진짜로 퇴근하지 못하면, 시스템이 다른 방식으로라도 그 선택을 완수할 거야.”

“다른 방식……?”

그는 잠시 말을 멈췄다가 낮게 말했다.

“뭐, 예를 들면…… 회사가 사라진다든지.”

그 순간, 건물 어딘가에서 경보음이 울리기 시작했다.

#9

경보음이 사옥 전체에 요란하게 울려 퍼졌다.

모니터 속 숫자는 인정사정없이 줄어들고 있었다.

실행까지 남은 시간
00:09:41

“그냥 나가면 되는 거 아니야?”

내가 묻자 남자는 무겁게 고개를 저었다.

“시스템은 네가 쓴 문장이 아니라, 그 문장을 쓸 때의 ‘마음’을 실행해.”

그 순간 전산실 문밖에서 여러 사람의 거친 발소리가 들려왔다.

남자는 내 팔을 붙잡고 뒷문으로 달렸다.

좁고 어두운 통로 끝에는 낡은 문 하나가 덩그러니 놓여 있었다.

[퇴근 처리실]

문 옆 벽면에는 빛바랜 명단이 붙어 있었다.

그 안에는 내 이름이 여러 번 선명하게 적혀 있었다.

3월, 6월, 9월, 12월…….

그리고 이번 달.

“나…… 전에도 여기 온 적 있어?”

남자는 대답 대신 침묵을 지켰다.

실행까지 남은 시간
00:05:12

문 안쪽에서 아침에 들었던 바로 그 낯익은 목소리가 흘러나왔다.

“늦으셨네요.”

“이번 달 담당자님.”

나는 떨리는 손으로 차가운 문고리를 잡았다.

남자가 낮게 읊조렸다.

“문을 열면, 모든 게 기억나게 될 거야.”

딸깍.

문이 열리자 수십 대의 모니터 화면 속에 일제히 내가 나타났다.

종이를 건네받는 나.

필사적으로 도망치는 나.

위태로운 선택을 하는 나.

그리고 방 한가운데.

나와 함께 도망쳐온 남자와 똑같은 얼굴을 한 사람이 나를 바라보며 기묘하게 웃고 있었다.

#10

문이 열리자 좁은 방 안 가득 모니터 불빛이 번쩍였다.

화면마다 서로 다른 ‘나’가 있었다.

누군가는 사무실을 뛰쳐나갔다.

누군가는 울고 있었다.

또 다른 나는 멍하니 키보드만 바라보고 있었다.

방 중앙에는 비상계단에서 만난 남자와 똑같은 얼굴의 사람이 앉아 있었다.

그는 담담한 목소리로 말했다.

“이 시스템은 사람들의 선택을 현실로 만드는 장치야.”

“넌 이미 여러 번 여기 왔었어.”

믿기 어려웠지만 벽에 붙은 기록 속에는 내 이름이 반복해서 적혀 있었다.

그 순간 경보음이 울렸다.

화면에는 남은 시간이 떠올랐다.

실행까지 남은 시간
00:00:30

남자는 내게 마지막 선택을 하라고 말했다.

예전의 나는 늘 “퇴근한다”라고 적었다고 했다.

나는 한참 동안 망설이다가 키보드 위에 손을 올렸다.

타닥.

[반복을 끝낸다.]

문장을 입력하는 순간 전산실의 불빛이 차례로 꺼졌다.

모니터 속 수많은 ‘나’도 하나씩 사라졌다.

정신을 차렸을 때 나는 출근길 지하철 안에 앉아 있었다.

손바닥에는 붉은 자국만 희미하게 남아 있었다.

“내가 꿈을 꾼 걸까…….”

#11

그 남자의 얼굴을 떠올렸다.

이상하리만치 선명했다.

마치 방금 전까지 눈앞에 서 있었던 사람처럼.

얼굴은 이토록 또렷한데, 그에 대해 아는 것은 아무것도 없었다.

이름도, 소속도, 심지어 정말 회사 사람이 맞는지조차 확신할 수 없었다.

나는 직원 검색창을 열어 떠오르는 단어들을 하나씩 입력해 보았다.

[전산실]
검색 결과 없음
[퇴근 처리실]
검색 결과 없음

그래.

나올 리가 없지.

팽팽하게 조여 있던 긴장이 풀리며 피로가 밀려왔다.

결국 아무런 단서도 얻지 못한 채 퇴근 시간이 찾아왔다.

엘리베이터를 기다리며 멍하니 서 있던 나는 무심코 옆을 돌아보았다.

한 남자가 서 있었다.

시선은 자연스럽게 그의 사원증으로 향했다.

이름을 읽으려던 순간, 남자가 천천히 고개를 돌렸다.

눈이 마주쳤다.

비상계단에서 만났던 그 남자였다.

심장이 미친 듯이 뛰었다.

엘리베이터 문이 열렸다.

사람들이 가득 차 있었고, 남자가 그들 사이에 섞여 탔다.

하지만 나는 움직일 수 없었다.

그 자리에 굳어 선 채, 닫혀 가는 문만 바라보았다.

문이 거의 닫히려는 순간 남자가 조용히 입을 열었다.

소리는 들리지 않았다.

그러나 입모양만큼은 분명히 읽을 수 있었다.

#12

‘도’

‘망’

‘쳐’

굳어버린 머리로 각 음절을 합쳐 겨우 뜻을 이해하자 얼굴의 핏기가 가시는 것이 느껴졌다. 도망치라니, 그게 무슨 의미야? 누구로부터? 어디로? …그리고 왜?

엘리베이터 문을 다시 열기 위해 버튼을 다급하게 눌러봤지만, 간발의 차이로 놓친 승강기는 야속하게도 벌써 다른 층을 향해 움직이고 있었다. 그가 어디서 내릴지 확인하기 위해 붉은 숫자를 확인하던 나는 금방 포기하고 시선을 돌렸다. 사람이 가득 찬 엘리베이터는 여러 층에서 멈춰서고 있었고, 그 많은 층을 나 혼자 뒤지기는 불가능에 가까웠다.

“잠깐.”

초조하게 손톱을 물어뜯던 나의 머릿속에 한 가지 좋은 생각이 떠올랐다. 분명 이 건물의 엘리베이터와 복도에는 모두 CCTV가 설치되어 있었다. CCTV를 확인하면 남자의 얼굴뿐 아니라 어느 층에서 내려 어느 팀으로 갔는지, 이 수수께끼의 인물이 누구인지 알아낼 수 있을 것이다. 하지만 동시에 조금 망설여지기도 했다. 수많은 모니터들이 설치된 보안실에 방문하려니, 얼마 전 꿈인지 현실인지 모를 전산실에서의 상황이 오버랩되어 꺼려졌다. 게다가 남자가 만약 아군이라면 나는 얼른 이곳에서 벗어나 어디론가 가야 하는 것이 아닐까?

#13

나는 발걸음을 멈췄다.

보안실로 간다면 남자의 정체를 알 수도 있다.

하지만 그 순간, 머릿속을 스치고 지나간 장면이 있었다.

수십 대의 모니터,

수없이 반복되던 ‘나’,

그리고 남자의 마지막 말.

그 기억이 사실이라면, CCTV를 확인하는 행동조차 이미 누군가가 예상한 선택일지도 모른다.

그때 주머니 속에서 바스락 소리가 났다.

분명 구겨 넣었던 홍보지였다.

조심스레 펼쳐 보니 종이에 쓰인 글자가 바뀌어 있었다.

[아직도 남을 믿을 거야?]

순간 등골이 서늘해졌다.

기억상 주머니에 넣은 이후로 종이를 만진 적이 없는 게 분명했다.

넋이 나간 채로 글자를 바라보고 있는데, 그때 휴대폰 진동이 울렸다.

황급히 휴대폰을 꺼내 봤으나 발신번호는 표시되지 않았다.

받을까 말까 망설이던 끝에 통화 버튼을 누르자 익숙한 숨소리가 들렸다.

“…보안실 가지 마.”

이번에는 비상계단의 남자가 아니었다.

※ 박스 안을 스크롤하면 전체 이야기를 볼 수 있습니다.

이전 시리즈에서는 Cilium의 기본 개념과 Identity, Endpoint, IPAM 등을 쿠버네티스 환경에서 직접 실습했고, Socket LB(East-West Load Balancing)는 TCPDUMP를 기반으로 패킷을 하나하나 분석하며 이해를 진행했다. 다만 내용이 길어지면서 다음 주제인 North-South Load Balancing은 다루지 못했다. 이번 글에서는 North-South Load Balancing을 다루고자 한다.

North-South Load Balancing

지금까지 다룬 내용은 In-Cluster 내 Pod to Pod 통신, 즉 East-West 통신을 기반으로 진행했다. In-Cluster 통신의 경우 출발지 파드가 클러스터가 소유한 노드에 있기 때문에, 출발지 파드가 네트워크 연결을 요청할 때 connect() 함수를 eBPF로 후킹할 수 있었다. 하지만 North-South 통신의 경우 외부 클라이언트로부터 트래픽이 인입되기 때문에 connect() 함수를 후킹할 수 없다. 그렇기에 패킷이 도착하는 목적지 노드의 tc(tcx) 계층에서 DNAT을 수행해야 한다(cil_from_netdev@eth0). 그리고 백엔드가 다른 노드에 있다면 해당 노드로 패킷을 포워딩까지 해야 한다. 응답의 경우 처음 도착했던 노드를 통해서 최초의 외부 클라이언트에게 응답을 제공해야 한다(클라이언트는 요청했던 노드 IP:포트에서 응답을 기다리고 있기 때문이다).

North-South 로드밸런싱에는 3가지 모드가 존재한다.

SNAT 모드 (기본)

클러스터 외부 클라이언트에서 발생한 패킷이 노드 A에 도착했다고 가정하자. 이때 전송하려는 백엔드 파드가 노드 B에 있다면, 노드 A는 패킷의 소스를 자신의 IP로 변경(SNAT)한 뒤 노드 B로 전송한다. 응답받은 파드는 다시 노드 B로 전달하고 노드 B는 노드 A로 전달한다. 최종적으로 노드 A가 외부 클라이언트에게 응답한다. ExternalTrafficPolicy가 local이라면 백엔드가 클라이언트의 IP를 볼 수 있지만, 그 외의 경우에는 소스 IP가 노드 A의 IP로 변경되어 있다. 또한 응답이 노드 A를 거치므로 네트워크 홉이 하나 더 생긴다.

DSR (Direct Server Return)

패킷이 노드 A에 도착했을 때 소스를 클라이언트 IP 그대로 유지한 채 노드 B로 전달한다. 전달받은 노드 B는 백엔드 파드에게 전달한다. 전달받은 백엔드 파드는 소스가 클라이언트 IP로 되어 있기 때문에 외부 클라이언트에게 직접 응답을 제공한다. 즉, 노드 A를 거치지 않는다. 장점이라면 클라이언트 IP를 보존할 수 있고, 응답 경로를 단축할 수 있다는 점이다. 다만, 최초 패킷을 받은 노드 A는 원래 목적지(클라이언트의 주소 정보)를 노드 B에게 어떻게든 전달해야 하는 과정이 필수적이다.

Hybrid

TCP는 DSR 방식으로, UDP는 SNAT 방식을 사용함을 의미한다.

kubectl -n kube-system exec ds/cilium -- cilium status --verbose | grep -iA 12 "KubeProxyReplacement Details"

KubeProxyReplacement Details:
  Status:               True
  Socket LB:            Enabled
  Socket LB Tracing:    Enabled
  Socket LB Coverage:   Full
  Devices:              eth0    172.18.0.4 fc00:f853:ccd:e793::4 fe80::4488:54ff:fe83:e798 (Direct Routing)
  Mode:                 SNAT
  Backend Selection:    Random
  Session Affinity:     Enabled
  NAT46/64 Support:     Disabled
  XDP Acceleration:     Disabled
  Services:
  - ClusterIP:      Enabled

현재 클러스터는 SNAT 모드로 동작하고 있음을 확인할 수 있다.

Cilium + eBPF 기반 SNAT 모드에서의 패킷 캡처 확인

cilium-lab-worker(172.18.0.3) 노드에는 netshoot-7b776d8bd4-brh8b 파드가 배포되어 있고 cilium-lab-worker2(172.18.0.4) 노드에는 netshoot-7b776d8bd4-wlsk9 파드가 배포되어 있다. 각각 80번 포트의 웹서버가 동작 중이라고 가정할 때, 외부 도커 컨테이너(클러스터 외부)가 cilium-lab-worker 노드에 요청을 보내 cilium-lab-worker2 노드로 패킷이 전달되어 netshoot-7b776d8bd4-wlsk9 파드로 트래픽이 최종적으로 흐르는 상황이다. 그전에 netshoot Deployment에 NodePort 서비스를 추가한다.

# NodePort 서비스 추가
kubectl expose deployment netshoot --type=NodePort --port=80 --name=netshoot-np

kubectl get svc

NAME           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes     ClusterIP   10.96.0.1       <none>        443/TCP        25h
netshoot-np    NodePort    10.96.136.151   <none>        80:31178/TCP   20s
netshoot-svc   ClusterIP   10.96.57.113    <none>        80/TCP         24h

NodePort로 31178을 사용하는 것을 알 수 있다.

# 외부 도커 컨테이너 실행 및 HTTP 요청
docker run -d --name ext-client --network kind nicolaka/netshoot sleep infinity
docker exec ext-client curl http://172.18.0.3:31178

# cilium-lab-worker2에서 tcpdump 캡처 시작
docker exec cilium-lab-worker2 bash -c "apt update && apt install tcpdump -y"
docker exec cilium-lab-worker2 tcpdump -i any -n "tcp and (tcp port 80 or tcp port 31178)"

15:29:56.953692 cilium_vxlan P   IP 10.0.2.37.59516 > 10.0.0.203.80: Flags [S], seq 1729550172, win 65495, options [mss 65495,sackOK,TS val 3966506285 ecr 0,nop,wscale 7], length 0

15:29:56.954004 lxcb816d8186f24 In  IP 10.0.0.203.80 > 10.0.2.37.59516: Flags [S.], seq 1814208142, ack 1729550173, win 65418, options [mss 65430,sackOK,TS val 384236862 ecr 3966506285,nop,wscale 7], length 0

15:29:56.954120 cilium_vxlan Out IP 10.0.0.203.80 > 10.0.2.37.59516: Flags [S.], seq 1814208142, ack 1729550173, win 65418, options [mss 65430,sackOK,TS val 384236862 ecr 3966506285,nop,wscale 7], length 0

tcpdump로 cilium-lab-worker2에서 캡처한 패킷 중 중요 부분만 일부 표시 및 분석을 진행한다.

15:29:56.953692 cilium_vxlan P   IP 10.0.2.37.59516 > 10.0.0.203.80: Flags [S], seq 1729550172, win 65495, options [mss 65495,sackOK,TS val 3966506285 ecr 0,nop,wscale 7], length 0

10.0.2.37 IP는 cilium-lab-worker의 cilium_host 인터페이스다. 이는 노드에서 트래픽이 나가는 지점이기에 해당 IP로 소스가 설정된다. 이 VXLAN 패킷을 cilium_vxlan 인터페이스에서 수신한다. 이를 cilium-lab-worker2 노드의 파드에 트래픽을 전달한다. 여기서 재미있는 점이 존재한다. 만약 cilium에서 kube-proxy가 존재하는 IPTables 상태였다면 노드 입장에서 파드의 veth pair 쌍인 lxcXXXXXX와 eth0 간 통신 과정에서 lxcXXXXXX로 패킷이 나가는 흐름이 캡처됐을 것이다. 하지만 현재는 cilium + eBPF 모드이기 때문에 호스트의 TC(TCX) 계층에서 수신한 패킷이 eBPF 프로그램인 cil_from_overlay에 의하여 내부적으로 bpf_redirect_peer() bpf helper 함수를 호출하여 lxcXXXXXX의 veth pair 인터페이스인 파드의 netns 내 eth0에 패킷을 포워딩한다. 그렇기에 파드의 veth pair(호스트에 설치된 인터페이스) lxcXXXXXX에는 패킷이 흐르지 않아 호스트에서 실행 중인 tcpdump에는 캡처되지 않는다.

15:29:56.954004 lxcb816d8186f24 In  IP 10.0.0.203.80 > 10.0.2.37.59516: Flags [S.], seq 1814208142, ack 1729550173, win 65418, options [mss 65430,sackOK,TS val 384236862 ecr 3966506285,nop,wscale 7], length 0

이는 백엔드 파드의 응답이다. 처음 목적지인 cilium-lab-worker에 응답하는 것을 볼 수 있다. 다만, Out은 안 보이고 lxc In만 보이는 이유는 bpf_redirect_peer() bpf helper 함수가 단방향으로 패킷을 주입하는 함수이기 때문이다. 그렇기에 파드의 응답은 파드 내 netns에 설치된 eth0, 그리고 그 veth pair 쌍인 lxcXXXXXX에는 In으로 캡처된다.

15:29:56.954120 cilium_vxlan Out IP 10.0.0.203.80 > 10.0.2.37.59516: Flags [S.], seq 1814208142, ack 1729550173, win 65418, options [mss 65430,sackOK,TS val 384236862 ecr 3966506285,nop,wscale 7], length 0

이는 VXLAN 회신이다. 이처럼 SNAT 모드라면 요청과 응답이 모두 최초 트래픽의 진입 지점 노드를 통과한다는 것을 알 수 있다.

Cilium + eBPF 기반 DSR 모드에서의 패킷 캡처 확인

이전 SNAT 실습에서 클라이언트 소스 IP가 사라지고 응답 구간에서 노드의 추가 홉이 생기는 것을 볼 수 있었다. 이번에는 이 두 가지 단점을 해결하는 DSR(Direct Server Return) 방식을 확인한다.

IPIP

노드에서 향하는 트래픽을 IP IN IP 형식으로 IP 헤더 안에 IP 헤더를 포함시킨다. 즉, 터널 간 캡슐화를 진행한다. 캡슐화된 패킷은 해당 파드를 호스팅하는 노드로 라우팅되고, Cilium은 터널을 종료하고 외부 헤더를 제거한 후 DNAT를 수행하여 외부 목적지 주소로 식별된 백엔드 파드에 내부 패킷을 전달한다. 다만, Cilium VXLAN 통신에서는 사용할 수 없으며 네이티브 라우팅 환경에서만 사용이 가능하다.

IP Option

클라이언트가 접속했던 최초 진입 노드의 IP, 포트 정보가 IP Option 형태로 저장되어 추가된다. 다만 해당 기능을 사용하려면 네이티브 라우팅을 사용해야 하며 캡슐화 모드에서는 사용할 수 없다.

Geneve

클라이언트가 최초 진입하는 노드의 IP/포트를 Cilium IP Option을 추가하여 처리하면, 일부 데이터 센터 라우터는 IP 옵션을 알 수 없는 패킷을 Layer 2 Slow Path라는 소프트웨어 처리 단계로 전달한다. 또한 IP 옵션이 포함된 패킷의 양이 특정 임계값을 초과하면 해당 패킷을 버리는데, 이는 네트워크 성능에 영향을 미칠 수 있다. Cilium은 이러한 문제를 방지하기 위해 Geneve를 사용한 모드를 제공한다. 이는 라우팅 모드가 네이티브 모드인지 캡슐화 모드인지와 상관없다.

이번 실습에서는 IP Option을 사용해서 DSR 모드를 실습해보는 것으로 진행한다. 클러스터 설치부터 DSR 모드로 설정한다.

# 기존 클러스터 삭제
kind delete cluster -n cilium-lab

# 클러스터 설치 (without kube-proxy)
kind create cluster --config ./kind/kind-cilium.yaml

# DSR 모드 및 ip option DSR 모드로 cilium 설치
helm install cilium cilium/cilium --version 1.19.5 \
  --namespace kube-system \
  --set kubeProxyReplacement=true \
  --set k8sServiceHost=cilium-lab-control-plane \
  --set k8sServicePort=6443 \
  --set routingMode=native \
  --set autoDirectNodeRoutes=true \
  --set ipv4NativeRoutingCIDR=10.244.0.0/16 \
  --set loadBalancer.mode=dsr \
  --set loadBalancer.dsrDispatch=opt \
  --set bpf.masquerade=true

# cilium 설치 대기
cilium status --wait

# netshoot 디플로이먼트 파드 설치 및 노드포트 추가
kubectl create deployment netshoot --image=nicolaka/netshoot -- sleep 3600
kubectl scale deployment netshoot --replicas=2
kubectl expose deployment netshoot --type=NodePort --port=80 --name=netshoot-np

# 양쪽에 웹서버 띄우기
for p in $(kubectl get pod -l app=netshoot -o jsonpath='{.items[*].metadata.name}'); do
  kubectl exec $p -- sh -c "nohup python3 -m http.server 80 >/dev/null 2>&1 &"
done
sleep 2

# nodeport 서비스 포트 확인
kubectl get svc

# DSR 설치 확인
kubectl -n kube-system exec ds/cilium -- cilium status --verbose | grep -iA 12 "KubeProxyReplacement Details"
KubeProxyReplacement Details:
  Status:                True
  Socket LB:             Enabled
  Socket LB Tracing:     Enabled
  Socket LB Coverage:    Full
  Devices:               eth0    172.18.0.4 fc00:f853:ccd:e793::4 fe80::741a:1fff:fedc:4d08 (Direct Routing)
  Mode:                  DSR
    DSR Dispatch Mode:   IP Option/Extension
  Backend Selection:     Random
  Session Affinity:      Enabled
  NAT46/64 Support:      Disabled
  XDP Acceleration:      Disabled
  Services:

DSR 모드로 IP Option을 사용하는 것으로 클러스터 설치가 되었다는 것을 확인할 수 있다. 이제 앞서와 마찬가지로 cilium-lab-worker2에서 tcpdump로 외부 클라이언트로부터 요청한 패킷을 캡처한다.

# ext-client(외부 클라이언트)가 cilium-lab-worker 노드에 요청
docker exec ext-client bash -c "nc -zv 172.18.0.3 32619"

# tcpdump 설치
docker exec cilium-lab-worker2 bash -c "apt update && apt install tcpdump -y"

# worker2에 감지된 패킷 캡처
docker exec cilium-lab-worker2 tcpdump -i any -n -v "tcp port 80 or tcp port 32619"

# 결과
tcpdump: data link type LINUX_SLL2
tcpdump: listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
14:53:31.872585 eth0  In  IP (tos 0x0, ttl 63, id 35763, offset 0, flags [DF], proto TCP (6), length 68, options (unknown 154))
    172.18.0.5.46726 > 10.0.0.7.80: Flags [S], cksum 0xb64c (incorrect -> 0x8887), seq 3961816526, win 65495, options [mss 65495,sackOK,TS val 4223527638 ecr 0,nop,wscale 7], length 0
14:53:31.872848 lxcad54fbc1e6bb In  IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60)
    10.0.0.7.80 > 172.18.0.5.46726: Flags [S.], cksum 0xb64c (incorrect -> 0xdfea), seq 3447068812, ack 3961816527, win 65468, options [mss 65480,sackOK,TS val 1535338287 ecr 4223527638,nop,wscale 7], length 0
14:53:31.873011 eth0  Out IP (tos 0x0, ttl 63, id 0, offset 0, flags [DF], proto TCP (6), length 60)
    172.18.0.3.32619 > 172.18.0.5.46726: Flags [S.], cksum 0x585b (incorrect -> 0xbec0), seq 3447068812, ack 3961816527, win 65468, options [mss 65480,sackOK,TS val 1535338287 ecr 4223527638,nop,wscale 7], length 0

위처럼 패킷 덤프를 뜰 수 있다. 하나하나 곱씹어 본다.

14:53:31.872585 eth0  In  IP (tos 0x0, ttl 63, id 35763, offset 0, flags [DF], proto TCP (6), length 68, options (unknown 154))
    172.18.0.5.46726 > 10.0.0.7.80: Flags [S], cksum 0xb64c (incorrect -> 0x8887), seq 3961816526, win 65495, options [mss 65495,sackOK,TS val 4223527638 ecr 0,nop,wscale 7], length 0
14:53:31.872848 lxcad54fbc1e6bb In  IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60)

외부 클라이언트(172.18.0.5)의 SYN 패킷이 worker2 백엔드로 이미 DNAT된 채, IP Option(type 154, length 68)을 달고 도착했다. 이때 SNAT과 달리 외부 클라이언트의 소스가 유지된다.

14:53:31.872848 lxcad54fbc1e6bb In  IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60)
    10.0.0.7.80 > 172.18.0.5.46726: Flags [S.], cksum 0xb64c (incorrect -> 0xdfea), seq 3447068812, ack 3961816527, win 65468, options [mss 65480,sackOK,TS val 1535338287 ecr 4223527638,nop,wscale 7], length 0
14:53:31.873011 eth0  Out IP (tos 0x0, ttl 63, id 0, offset 0, flags [DF], proto TCP (6), length 60)

백엔드가 SYN-ACK를 응답한다. 소스 IP는 백엔드(10.0.0.7)이고 목적지는 클라이언트(172.18.0.5)이다. 여기까지는 소스가 백엔드 파드 IP로 되어 있다.

14:53:31.873011 eth0  Out IP (tos 0x0, ttl 63, id 0, offset 0, flags [DF], proto TCP (6), length 60)
    172.18.0.3.32619 > 172.18.0.5.46726: Flags [S.], cksum 0x585b (incorrect -> 0xbec0), seq 3447068812, ack 3961816527, win 65468, options [mss 65480,sackOK,TS val 1535338287 ecr 4223527638,nop,wscale 7], length 0

여기서 소스 IP가 cilium-lab-worker로 변경되어서 클라이언트에게 전달된 것을 확인할 수 있다. worker에서 worker2로 패킷을 전달할 때 IP Option에 원래 노드 IP(172.18.0.3.32619)를 추출해서 NAT 엔트리에 저장했고, 이를 백엔드 응답이 나갈 때 eth0(Out) 인터페이스에서 소스를 복원한다.

관측 가능성 (Hubble)

지금까지는 패킷이 왜 DROP되었는지, 왜 이 노드에서 DROP됐는지, 이 패킷의 Identity는 무엇이고 어떤 Identity를 향해 가는지 등을 monitor, bpf 명령어 또는 맵 등을 통해서 확인해왔다. 하지만 이때마다 명령어를 호출하고 조건을 걸고 다른 맵을 살펴보는 것은 운영 환경에서는 불리하게 작용한다. Cilium은 Hubble을 통해 앞서 말한 문제점을 해결하고 관찰 가능성을 제공한다. 즉, Hubble은 Identity·서비스·정책 판정이 붙은 구조화된 플로우로 보여준다.

Hubble의 구성 요소

kubectl -n kube-system exec ds/cilium -- cilium status | grep -i hubble

Hubble:                  Ok              Current/Max Flows: 4095/4095 (100.00%), Flows/s: 5.88   Metrics: Disabled

위는 Hubble을 확인하는 명령어이고 아래 명령어로 설치가 가능하다.

# Hubble + Relay 활성화 (필요시)
helm upgrade cilium cilium/cilium --version 1.19.5 \
  --namespace kube-system --reuse-values \
  --set hubble.enabled=true \
  --set hubble.relay.enabled=true \
  --set hubble.ui.enabled=true

kubectl -n kube-system rollout restart ds/cilium
kubectl -n kube-system rollout status ds/cilium --timeout=120s

# MacOS의 경우
brew install hubble

호스트에도 Hubble을 설치한다.

# hubble relay를 로컬 포트로 포워드
kubectl -n kube-system port-forward hubble-relay-785f7df-fst9d 4245:4245 &

# CLI가 해당 포트로 접속 및 마지막 10건 수집
hubble observe --server localhost:4245 --last 10

Aug  3 14:04:11.925: 10.0.2.178:51188 (host) -> kube-system/hubble-ui-6bb97d8894-zlsmx:8081 (ID:24960) to-endpoint FORWARDED (TCP Flags: ACK, FIN)
Aug  3 14:04:12.605: 172.18.0.4:53516 (remote-node) <- 10.0.2.249:4240 (health) to-network FORWARDED (TCP Flags: ACK)
Aug  3 14:04:15.165: 172.18.0.2:40266 (host) -> 172.18.0.4:4240 (remote-node) to-network FORWARDED (TCP Flags: ACK)

hubble observe 명령어를 통해 트래픽 플로우를 확인할 수 있다. 내용을 자세히 살펴보면 (host)와 (ID:24960)이 양쪽의 Identity다. host(예약 Identity)에서 hubble-ui 파드로 가는 것을 볼 수 있다. to-endpoint는 datapath의 어느 지점인지를 나타낸다. 이는 파드로 배달되는 단계이다. FORWARDED는 정책 판정(허용)이다. DROP이면 DROPPED로 뜨게 된다.

정책 기반 관찰

다음으로는 정책을 추가하여 관측을 진행한다. 이전에 배포해둔 외부 클라이언트 ext-client(172.18.0.5)가 존재한다고 가정한다.

허용 로그

hubble observe --server localhost:4245 --pod netshoot -f

Aug  3 15:02:19.969: 172.18.0.5:43488 (world) -> default/netshoot-7b776d8bd4-pd2c8:80 (ID:25373) to-endpoint FORWARDED (TCP Flags: SYN)
Aug  3 15:02:19.969: 172.18.0.5:43488 (world) <- default/netshoot-7b776d8bd4-pd2c8:80 (ID:25373) to-network FORWARDED (TCP Flags: SYN, ACK)
Aug  3 15:02:19.969: 172.18.0.5:43488 (world) -> default/netshoot-7b776d8bd4-pd2c8:80 (ID:25373) to-endpoint FORWARDED (TCP Flags: ACK)
Aug  3 15:02:19.969: 172.18.0.5:43488 (world) -> default/netshoot-7b776d8bd4-pd2c8:80 (ID:25373) to-endpoint FORWARDED (TCP Flags: ACK, PSH)
Aug  3 15:02:19.980: 172.18.0.5:43488 (world) <- default/netshoot-7b776d8bd4-pd2c8:80 (ID:25373) to-network FORWARDED (TCP Flags: ACK, PSH)
Aug  3 15:02:19.980: 172.18.0.5:43488 (world) <- default/netshoot-7b776d8bd4-pd2c8:80 (ID:25373) to-network FORWARDED (TCP Flags: ACK, FIN)
Aug  3 15:02:19.980: 172.18.0.5:43488 (world) -> default/netshoot-7b776d8bd4-pd2c8:80 (ID:25373) to-endpoint FORWARDED (TCP Flags: ACK, FIN)
Aug  3 15:02:19.980: 172.18.0.5:43488 (world) -> default/netshoot-7b776d8bd4-pd2c8:80 (ID:25373) to-endpoint FORWARDED (TCP Flags: ACK)

라벨 기반 정책 적용

# hubble-deny.yaml
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: netshoot-deny
spec:
  endpointSelector:
    matchLabels:
      app: netshoot
  ingress:
    - fromEndpoints:
        - matchLabels:
            app: nothing

위 yaml 파일을 hubble-deny.yaml로 저장하고 정책을 적용한다. 이는 nothing이라는 라벨을 가진 Identity만 정책을 허용한다는 뜻이다.

kubectl apply -f hubble-deny.yaml

hubble observe --server localhost:4245 --pod netshoot -f

Aug  3 15:04:07.076: 172.18.0.5:44074 (world) <> default/netshoot-7b776d8bd4-pd2c8:80 (ID:25373) policy-verdict:none TRAFFIC_DIRECTION_UNKNOWN DENIED (TCP Flags: SYN)
Aug  3 15:04:07.076: 172.18.0.5:44074 (world) <> default/netshoot-7b776d8bd4-pd2c8:80 (ID:25373) Policy denied DROPPED (TCP Flags: SYN)
Aug  3 15:04:08.093: 172.18.0.5:44074 (world) <> default/netshoot-7b776d8bd4-pd2c8:80 (ID:25373) policy-verdict:none TRAFFIC_DIRECTION_UNKNOWN DENIED (TCP Flags: SYN)
Aug  3 15:04:08.093: 172.18.0.5:44074 (world) <> default/netshoot-7b776d8bd4-pd2c8:80 (ID:25373) Policy denied DROPPED (TCP Flags: SYN)
Aug  3 15:04:09.117: 172.18.0.5:44074 (world) <> default/netshoot-7b776d8bd4-pd2c8:80 (ID:25373) policy-verdict:none TRAFFIC_DIRECTION_UNKNOWN DENIED (TCP Flags: SYN)
Aug  3 15:04:09.117: 172.18.0.5:44074 (world) <> default/netshoot-7b776d8bd4-pd2c8:80 (ID:25373) Policy denied DROPPED (TCP Flags: SYN)
Aug  3 15:04:10.141: 172.18.0.5:44074 (world) <> default/netshoot-7b776d8bd4-pd2c8:80 (ID:25373) policy-verdict:none TRAFFIC_DIRECTION_UNKNOWN DENIED (TCP Flags: SYN)

정책에 의해 DROP된 것을 확인할 수 있다. 지금까지는 이를 cilium monitor로 관측했었는데 hubble로 손쉽게 관측이 가능해졌다.

L3/L4 포트 기반 정책 적용

라벨 기반으로 정책을 적용하는 것뿐만 아니라 L4, L7 등 다양하게 정책을 적용할 수 있다. 다음은 포트 기반으로 클러스터 내 다른 노드로부터만 트래픽을 허용하는 정책을 적용해본다.

# hubble-port.yaml
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: netshoot-allow
spec:
  endpointSelector:
    matchLabels:
      app: netshoot
  ingress:
    - fromEntities:
        - remote-node
      toPorts:
        - ports:
            - port: "80"
              protocol: TCP

# 정책 적용
kubectl apply -f hubble-port.yaml

# hubble 모니터링 진행
hubble observe --server localhost:4245 --pod netshoot -f

Aug  3 15:24:05.074: 172.18.0.5:58126 (world) <> default/netshoot-7b776d8bd4-pd2c8:80 (ID:25373) policy-verdict:none TRAFFIC_DIRECTION_UNKNOWN DENIED (TCP Flags: SYN)

위처럼 클러스터 내부 노드가 아닌 외부 클라이언트의 연결은 정책에서 DROP된 것을 확인할 수 있다.

L7 기반 정책 적용

eBPF는 커널에서 패킷 헤더(L3/L4)를 본다. 그런데 HTTP 메서드/경로/상태 코드는 TCP 스트림을 재조립해서 파싱해야 알 수 있다. 그렇기에 커널/eBPF에서 처리하기에는 어렵다. 그렇기에 cilium은 L7 트래픽 제어가 필요하면 트래픽을 Envoy 프록시로 우회시킨다. Envoy가 HTTP를 파싱하고 결과를 Hubble L7 flow에 넘긴다.

if (lb4_svc_is_l7_loadbalancer(svc)) {
    ...
    return 0;   /* Let the TC level eBPF datapath redirect to L7 LB. */
}
# hubble-l7.yaml
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: netshoot-l7
spec:
  endpointSelector:
    matchLabels:
      app: netshoot
  ingress:
    - fromEntities:
        - world
      toPorts:
        - ports:
            - port: "80"
              protocol: TCP
          rules:
            http:
              - method: "GET"
                path: "/"

위 정책은 GET 메서드로 “/” 경로만 요청을 허용하겠다는 뜻이며, 클러스터 내부 노드가 아니라 외부 클라이언트로부터만 연결을 허용하겠다는 뜻이다.

kubectl apply -f hubble-l7.yaml

hubble observe --server localhost:4245 --pod netshoot -t l7 -f

Aug  3 15:28:49.290: 172.18.0.5:58718 (world) -> default/netshoot-7b776d8bd4-pd2c8:80 (ID:25373) http-request FORWARDED (HTTP/1.1 GET http://172.18.0.3:32619/)
Aug  3 15:28:49.300: 172.18.0.5:58718 (world) <- default/netshoot-7b776d8bd4-pd2c8:80 (ID:25373) http-response FORWARDED (HTTP/1.1 200 13ms (GET http://172.18.0.3:32619/))
Aug  3 15:28:54.778: 172.18.0.5:39606 (world) -> default/netshoot-7b776d8bd4-pd2c8:80 (ID:25373) http-request DROPPED (HTTP/1.1 GET http://172.18.0.3:32619/hello)
Aug  3 15:28:54.778: 172.18.0.5:39606 (world) <- default/netshoot-7b776d8bd4-pd2c8:80 (ID:25373) http-response FORWARDED (HTTP/1.1 403 0ms (GET http://172.18.0.3:32619/hello))

위처럼 어떤 경로에 접근했는지, DROP되었는지 확인할 수 있다. 다만 L7 정책을 추가하면 트래픽이 커널에서 유저스페이스(Envoy)로 전달되었다가 다시 돌아오기 때문에 socket LB를 사용하지 못하는 단점이 발생한다(높은 지연과 CPU 사용량).

kubectl -n kube-system exec cilium-qsqpp -- cilium endpoint list | grep netshoot

2613       Enabled            Disabled          25373      k8s:app=netshoot

netshoot 워크로드의 endpoint가 2613인 것을 확인한다.

kubectl -n kube-system exec cilium-qsqpp -- cilium bpf policy get 2613

POLICY   DIRECTION   LABELS (source:key[=value])   PORT/PROTO   PROXY PORT   AUTH TYPE   BYTES   PACKETS   PREFIX   COOKIE
Allow    Ingress     reserved:host                 ANY          NONE         disabled    -       -         0        0
Allow    Ingress     reserved:world                80/TCP       16221        disabled    558     7         24       0
Allow    Ingress     reserved:world-ipv4           80/TCP       16221        disabled    -       -         24       0
Allow    Ingress     reserved:world-ipv6           80/TCP       16221        disabled    -       -         24       0
Allow    Egress      ANY                           ANY          NONE         disabled    -       -         0        0

endpoint의 정책 eBPF 맵을 확인해보면 16221 포트로 프록시 서버가 동작 중인 것을 확인할 수 있다.

Hubble UI

마지막으로 hubble 명령어가 아닌 UI로, 웹페이지에서 트래픽을 모니터링하는 방향으로 진행한다.

kubectl -n kube-system port-forward hubble-ui-6bb97d8894-zlsmx 8081:8081 &

그리고 localhost:8081로 접근해서 namespace를 선택하면 트래픽을 확인할 수 있다.

Hubble UI에서 네임스페이스별 트래픽 흐름을 시각화한 서비스맵 화면
Hubble UI에서 namespace를 선택하면 서비스 간 트래픽 흐름을 시각화된 서비스맵으로 확인할 수 있다.

멀티클러스터 그리고 Cluster Mesh

Cluster Mesh란 여러 쿠버네티스 클러스터를 하나의 네트워크로 묶는 역할을 한다.

파드 간 직접 통신

클러스터 A의 파드가 클러스터 B의 파드 IP로 통신 가능하도록 한다.

글로벌 서비스

같은 이름의 서비스를 양쪽 클러스터에 두면 백엔드가 자동으로 합쳐진다. 로컬 백엔드 장애 발생 시 다른 클러스터에 배포된 백엔드로 페일오버(Failover)된다.

크로스클러스터 정책

클러스터 B의 '서비스만 허용' 같은 Identity 정책 기반 적용이 가능하다.

이번 챕터는 Cilium의 Cluster Mesh를 사용해서 KIND로 배포된 서로 다른 쿠버네티스 클러스터를 하나의 클러스터로 묶는 실습을 진행한다.

해결해야 하는 문제

멀티클러스터를 구축하기 위해서는 해결해야 하는 문제가 존재한다.

설계

실제 실습 전에 확인해야 할 사항이 존재한다. 그리고 이를 반영한 클러스터를 아래처럼 구축한다.

cluster name  : cluster1     | cluster2
cluster id    : 1            | 2
pod CIDR      : 10.1.0.0/16  | 10.2.0.0/16
service CIDR  : 10.11.0.0/16 | 10.12.0.0/16
# kind-c1.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: cluster1
networking:
  disableDefaultCNI: true
  kubeProxyMode: none
  podSubnet: "10.1.0.0/16"
  serviceSubnet: "10.11.0.0/16"
nodes:
  - role: control-plane
  - role: worker
---
# kind-c2.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: cluster2
networking:
  disableDefaultCNI: true
  kubeProxyMode: none
  podSubnet: "10.2.0.0/16"
  serviceSubnet: "10.12.0.0/16"
nodes:
  - role: control-plane
  - role: worker
kind create cluster --config kind-c1.yaml
kind create cluster --config kind-c2.yaml

그리고 각 클러스터에 cilium을 설치한다.

# --- cluster1 ---
helm install cilium cilium/cilium --version 1.19.5 \
  --namespace kube-system \
  --kube-context kind-cluster1 \
  --set cluster.name=cluster1 \
  --set cluster.id=1 \
  --set ipam.mode=cluster-pool \
  --set ipam.operator.clusterPoolIPv4PodCIDRList={10.1.0.0/16} \
  --set kubeProxyReplacement=true \
  --set k8sServiceHost=cluster1-control-plane \
  --set k8sServicePort=6443 \
  --set bpf.masquerade=true \
  --set hubble.enabled=true \
  --set hubble.relay.enabled=true

  # --- cluster2 ---
helm install cilium cilium/cilium --version 1.19.5 \
  --namespace kube-system \
  --kube-context kind-cluster2 \
  --set cluster.name=cluster2 \
  --set cluster.id=2 \
  --set ipam.mode=cluster-pool \
  --set ipam.operator.clusterPoolIPv4PodCIDRList={10.2.0.0/16} \
  --set kubeProxyReplacement=true \
  --set k8sServiceHost=cluster2-control-plane \
  --set k8sServicePort=6443 \
  --set bpf.masquerade=true \
  --set hubble.enabled=true \
  --set hubble.relay.enabled=true

각 클러스터에 cilium이 설치됐지만 아직 clustermesh로 연결된 상태는 아니다. 그렇기에 먼저 연결 전 상태를 확인한다.

kubectl --context kind-cluster1 -n kube-system exec ds/cilium -- cilium status | grep -iE "cluster|kvstore"

# etcd모드가 아닌 CRD모드 사용
KVStore:                 Disabled
Kubernetes APIs:         ["cilium/v2::CiliumCIDRGroup", "cilium/v2::CiliumClusterwideNetworkPolicy", "cilium/v2::CiliumEndpoint", "cilium/v2::CiliumNetworkPolicy", "cilium/v2::CiliumNode", "core/v1::Pods", "networking.k8s.io/v1::NetworkPolicy"]

# 아직 연결된 클러스터가 없음.
ClusterMesh:             0/0 remote clusters ready
Cluster health:          2/2 reachable   (2026-08-09T07:03:08Z)   (Probe interval: 1m36.566274746s)

이제 Identity도 확인해본다.

kubectl --context kind-cluster1 -n kube-system exec ds/cilium -- cilium identity list | head -20

ID       LABELS
1        reserved:host
[...]
84424    k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=kube-system
         k8s:io.cilium.k8s.policy.cluster=cluster1
         k8s:io.cilium.k8s.policy.serviceaccount=coredns

보면 84424 Identity가 생긴 것을 확인할 수 있다. 이는 Cluster ID 값이 적용된 유니크한 Identity 값임을 알 수 있다.

clusterIDShift = NumericIdentityBitlength - clusterIDLen    // 기본 24 - 8 = 16

// cluster ID로부터 identity 범위 계산
return NumericIdentity((1 << GetClusterIDShift()) * clusterID)

// identity에서 cluster ID 추출
return (uint32(id) >> uint32(GetClusterIDShift())) & cmtypes.ClusterIDMax

또한 라벨에도 k8s:io.cilium.k8s.policy.cluster=cluster1처럼 클러스터 이름이 적혀 있어, 유니크한 라벨 덕분에 클러스터 내 정책에서 충돌 및 제한으로부터 자유롭다.

fromEndpoints:
  - matchLabels:
      k8s:io.cilium.k8s.policy.cluster: cluster2
      app: frontend        # "cluster2의 frontend만 허용"
kubectl --context kind-cluster1 -n kube-system exec ds/cilium -- cilium bpf ipcache list | head -20

IP PREFIX/ADDRESS   IDENTITY
10.1.0.51/32        identity=4 encryptkey=0 tunnelendpoint=172.18.0.4 flags=hastunnel
10.1.0.147/32       identity=6 encryptkey=0 tunnelendpoint=172.18.0.4 flags=hastunnel
10.1.1.31/32        identity=1 encryptkey=0 tunnelendpoint=0.0.0.0 flags=
10.1.1.96/32        identity=84424 encryptkey=0 tunnelendpoint=0.0.0.0 flags=
10.1.1.155/32       identity=115908 encryptkey=0 tunnelendpoint=0.0.0.0 flags=
10.1.1.163/32       identity=84262 encryptkey=0 tunnelendpoint=0.0.0.0 flags=
172.18.0.3/32       identity=1 encryptkey=0 tunnelendpoint=0.0.0.0 flags=
[...]

cluster1에서 ipcache를 조회했을 때 자신이 관리 중인 IP 목록은 포함되어 있지만, cluster2에 포함된 IP 목록(10.2.0.0/16)은 아직 포함되지 않은 것을 알 수 있다.

Cluster Mesh 배포 및 연결

이제 본격적으로 kind-cluster1과 kind-cluster2, 2개의 쿠버네티스 클러스터를 하나로 묶는 작업을 진행한다.

참고) tls.authMode 값의 기본값은 Migrate다. 이 경우 추가적인 ConfigMap이 필요하기 때문에 여기서는 Legacy로 설정한다.

# 양쪽에 clustermesh-apiserver 활성화
helm upgrade cilium cilium/cilium --version 1.19.5 \
  --namespace kube-system --kube-context kind-cluster1 --reuse-values \
  --set clustermesh.useAPIServer=true \
  --set clustermesh.apiserver.service.type=NodePort \
  --set clustermesh.apiserver.tls.authMode=legacy

helm upgrade cilium cilium/cilium --version 1.19.5 \
  --namespace kube-system --kube-context kind-cluster2 --reuse-values \
  --set clustermesh.useAPIServer=true \
  --set clustermesh.apiserver.service.type=NodePort \
  --set clustermesh.apiserver.tls.authMode=legacy

clustermesh를 배포한다. 그리고 아래 명령어로 클러스터를 연결한다.

cilium clustermesh connect --context kind-cluster1 --destination-context kind-cluster2

Error: Unable to connect cluster: Cilium CA certificates do not match between clusters cluster1 and cluster2. Use --allow-mismatching-ca to allow this by adding remote CAs to the CA bundle

clustermesh로 서로 다른 클러스터를 연결하려면 CA를 공유해야 한다. 공유하기 위한 방법으로 아래 2가지가 존재한다.

이 중 1번 방법을 사용해 진행한다.

kubectl --context kind-cluster1 -n kube-system get secret cilium-ca -o yaml > ./ca.yaml

양쪽 클러스터의 CA 값을 명령어로 확인한다. 그리고 cluster1의 CA 값을 ca.yaml로 저장하고, 여기서 resourceVersion, creationTimestamp, annotations 필드를 제거한다.

kubectl --context kind-cluster2 -n kube-system delete secret cilium-ca

# hubble 관련 시크릿도 삭제
kubectl --context kind-cluster2 -n kube-system delete secret \
  hubble-server-certs \
  hubble-relay-client-certs \
  hubble-relay-server-certs \
  hubble-ui-client-certs \
  --ignore-not-found

# clustermesh 쪽도 아직 안 지웠으면 같이
kubectl --context kind-cluster2 -n kube-system delete secret \
  clustermesh-apiserver-server-cert \
  clustermesh-apiserver-admin-cert \
  clustermesh-apiserver-remote-cert \
  clustermesh-apiserver-local-cert \
  --ignore-not-found

# CA 덮어쓰기
kubectl --context kind-cluster2 -n kube-system apply -f ./ca.yaml

# 기존 인증서 시크릿 삭제 → helm이 새 CA로 재생성
kubectl --context kind-cluster2 -n kube-system delete secret \
  clustermesh-apiserver-server-cert \
  clustermesh-apiserver-admin-cert \
  clustermesh-apiserver-remote-cert \
  2>/dev/null

# helm 재적용으로 새 CA 기반 인증서 생성
helm upgrade cilium cilium/cilium --version 1.19.5 \
  --namespace kube-system --kube-context kind-cluster2 --reuse-values

# 재시작
kubectl --context kind-cluster2 -n kube-system rollout restart deployment/clustermesh-apiserver
kubectl --context kind-cluster2 -n kube-system rollout restart ds/cilium
kubectl --context kind-cluster2 -n kube-system rollout status deployment/clustermesh-apiserver --timeout=180s
kubectl --context kind-cluster2 -n kube-system rollout status ds/cilium --timeout=180s

# helm으로 새 CA 기반 재발급 (hubble)
helm upgrade cilium cilium/cilium --version 1.19.5 --namespace kube-system --kube-context kind-cluster2 --reuse-values

# 전부 재시작해서 새 인증서 로드
kubectl --context kind-cluster2 -n kube-system rollout restart ds/cilium
kubectl --context kind-cluster2 -n kube-system rollout restart deployment/hubble-relay
kubectl --context kind-cluster2 -n kube-system rollout restart deployment/clustermesh-apiserver

kubectl --context kind-cluster2 -n kube-system rollout status ds/cilium --timeout=180s
kubectl --context kind-cluster2 -n kube-system rollout status deployment/hubble-relay --timeout=120s

kind-cluster2에서 CA를 지우고 kind-cluster1에서 복제한 CA로 덮어쓴다. 클러스터 간 CA 값이 동일한지 아래 명령어로 확인한 뒤, 다시 clustermesh로 클러스터 간 연결을 진행한다.

# 양쪽 CA 인증서 지문 비교
echo "=== cluster1 CA ==="
kubectl --context kind-cluster1 -n kube-system get secret cilium-ca -o jsonpath='{.data.ca\.crt}' | base64 -d | openssl x509 -noout -fingerprint -sha256
echo "=== cluster2 CA ==="
kubectl --context kind-cluster2 -n kube-system get secret cilium-ca -o jsonpath='{.data.ca\.crt}' | base64 -d | openssl x509 -noout -fingerprint -sha256
cilium clustermesh connect --context kind-cluster1 --destination-context kind-cluster2

ℹ️  Found ClusterMesh service IPs: [172.18.0.5]
ℹ️ Configuring Cilium in cluster kind-cluster1 to connect to cluster kind-cluster2
ℹ️ Configuring Cilium in cluster kind-cluster2 to connect to cluster kind-cluster1
✅ Connected cluster kind-cluster1 <=> kind-cluster2!
kubectl --context kind-cluster1 -n kube-system exec ds/cilium -- cilium status | grep -i clustermesh
kubectl --context kind-cluster2 -n kube-system exec ds/cilium -- cilium status | grep -i clustermesh

ClusterMesh:             1/1 remote clusters ready
ClusterMesh:             1/1 remote clusters ready

두 개의 클러스터가 clustermesh로 연결된 것을 확인할 수 있다. 또한 ipcache도 다시 한번 확인한다.

kubectl --context kind-cluster1 -n kube-system exec ds/cilium -- cilium bpf ipcache list | head -20

IP PREFIX/ADDRESS   IDENTITY
10.1.0.0/24         identity=2 encryptkey=0 tunnelendpoint=172.18.0.4 flags=hastunnel
10.1.1.18/32        identity=93015 encryptkey=0 tunnelendpoint=0.0.0.0 flags=
10.1.1.96/32        identity=84424 encryptkey=0 tunnelendpoint=0.0.0.0 flags=
10.1.1.163/32       identity=84262 encryptkey=0 tunnelendpoint=0.0.0.0 flags=
10.2.0.142/32       identity=4 encryptkey=0 tunnelendpoint=172.18.0.5
10.2.1.40/32        identity=165001 encryptkey=0 tunnelendpoint=172.18.0.7 flags=hastunnel
10.2.1.102/32       identity=135358 encryptkey=0 tunnelendpoint=172.18.0.7 flags=hastunnel

10.2.0.102/32       identity=6 encryptkey=0 tunnelendpoint=172.18.0.5 flags=hastunnel,remotecluster

kind-cluster1의 ipcache에서 kind-cluster2의 파드 IP 목록이 보이는 것을 확인할 수 있다. 추가적으로 remotecluster는 remote-node로, 노드가 원격 클러스터에 속한다는 뜻이다. 그리고 hastunnel + tunnelendpoint는 "저 노드로 VXLAN으로 캡슐화해서 전송하라"는 뜻이다.

통신 확인

연결된 클러스터에 각각 백엔드를 배포하고, 외부 클라이언트에서 nc 명령어로 통신 및 장애 테스트(failover)를 진행한다.

kubectl --context kind-cluster1 create deployment netshoot --image=nicolaka/netshoot -- sleep infinity
kubectl --context kind-cluster1 rollout status deployment/netshoot

# cluster2
kubectl --context kind-cluster2 create deployment netshoot --image=nicolaka/netshoot -- sleep infinity
kubectl --context kind-cluster2 rollout status deployment/netshoot

# IP 확인
kubectl --context kind-cluster1 get pod -l app=netshoot -o wide
kubectl --context kind-cluster2 get pod -l app=netshoot -o wide

배포된 파드에 대해 우선 클러스터 간 통신을 진행한다.

kubectl --context kind-cluster1 exec  netshoot-57fdfc7498-xkhh9 -- ping -c 3 10.2.1.103

PING 10.2.1.103 (10.2.1.103) 56(84) bytes of data.
64 bytes from 10.2.1.103: icmp_seq=1 ttl=63 time=0.738 ms
64 bytes from 10.2.1.103: icmp_seq=2 ttl=63 time=0.212 ms

kind-cluster1에서 kind-cluster2로 정상적인 통신을 확인했다. 이제 서비스를 배포하고 외부 클라이언트로의 통신을 확인한다.

# 양쪽에 웹서버 띄우기
for ctx in kind-cluster1 kind-cluster2; do
  for p in $(kubectl --context $ctx get pod -l app=netshoot -o jsonpath='{.items[*].metadata.name}'); do
    kubectl --context $ctx exec $p -- sh -c "nohup python3 -m http.server 80 >/dev/null 2>&1 &" 2>/dev/null
  done
done
sleep 2

# 양쪽에 같은 이름의 서비스 + global annotation
for ctx in kind-cluster1 kind-cluster2; do
  kubectl --context $ctx expose deployment netshoot --port=80 --type=NodePort --name=global-svc
  kubectl --context $ctx annotate service global-svc service.cilium.io/global="true"
done

먼저 웹서버 백엔드를 python3으로 실행한다. 그리고 양쪽에 같은 이름의 서비스를 배포하기 위해서는 service.cilium.io/global="true"라는 Annotation을 붙인다. 이 Annotation을 붙이면 cilium이 해당 서비스를 클러스터 전역 서비스로 인식한다. 즉 다른 클러스터의 같은 이름을 가진 서비스 백엔드를 자신의 LB 맵에 합친다.

kubectl --context kind-cluster1 get svc
kubectl --context kind-cluster2 get svc

# kind-cluster1의 서비스
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)
global-svc   NodePort    10.12.106.229           80:32498/TCP

# kind-cluster2의 서비스
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)
global-svc   NodePort    10.12.254.36           80:31935/TCP

그리고 노드 IP를 확인하면 kind-cluster1은 172.18.0.3, kind-cluster2의 경우 172.18.0.7이다. 외부 클라이언트에서 kind-cluster1의 노드포트로 요청을 전송한다.

docker exec ext-client nc -zv 172.18.0.3 32498

그리고 kind-cluster2에서 cilium monitor로 관련된 백엔드 endpoint를 모니터링한다.

kubectl --context kind-cluster2 exec -n kube-system cilium-pdvgw -- cilium monitor --related-to 230

-> endpoint 230 flow 0x64c148f2 , identity world->136352 state new ifindex lxcebea5111109e orig-ip 10.1.1.31: 10.1.1.31:45596 -> 10.2.1.103:80 tcp SYN
-> overlay flow 0x20c3614 , identity 136352->remote-node state reply ifindex cilium_vxlan orig-ip 0.0.0.0: 10.2.1.103:80 -> 10.1.1.31:45596 tcp SYN, ACK
-> endpoint 230 flow 0x64c148f2 , identity world->136352 state established ifindex lxcebea5111109e orig-ip 10.1.1.31: 10.1.1.31:45596 -> 10.2.1.103:80 tcp ACK
-> endpoint 230 flow 0x64c148f2 , identity world->136352 state established ifindex lxcebea5111109e orig-ip 10.1.1.31: 10.1.1.31:45596 -> 10.2.1.103:80 tcp ACK, FIN
-> overlay flow 0x20c3614 , identity 136352->remote-node state reply ifindex cilium_vxlan orig-ip 0.0.0.0: 10.2.1.103:80 -> 10.1.1.31:45596 tcp ACK, FIN
-> endpoint 230 flow 0x64c148f2 , identity world->136352 state established ifindex lxcebea5111109e orig-ip 10.1.1.31: 10.1.1.31:45596 -> 10.2.1.103:80 tcp ACK

정상적으로 외부 클라이언트는 kind-cluster2로 TCP 패킷을 전송했지만, kind-cluster2가 최종적으로 트래픽을 전달받아 응답한 것을 볼 수 있다.

kubectl --context kind-cluster1 exec -n kube-system ds/cilium -- cilium service list

ID   Frontend                Service Type   Backend
11   0.0.0.0:32498/TCP       NodePort       1 => 10.1.1.104:80/TCP (active)
                                            2 => 10.2.1.103:80/TCP (active)
13   10.12.106.229:80/TCP    ClusterIP      1 => 10.1.1.104:80/TCP (active)
                                            2 => 10.2.1.103:80/TCP (active)

kind-cluster1에서 cilium service list를 실행했을 때, 백엔드 맵에 각 클러스터에 배포된 백엔드 IP가 담겨 있는 것을 알 수 있다.

장애 테스트

kind-cluster1에 배포된 netshoot deployment의 replicas를 0으로 설정한 후 다시 패킷을 전송한다.

kubectl --context kind-cluster1 scale deployment netshoot --replicas=0

docker exec ext-client nc -zv 172.18.0.3 32498

Connection to 172.18.0.3 32498 port [tcp/*] succeeded! 정상적으로 통신이 되는 것을 확인할 수 있다.

kubectl --context kind-cluster1 exec -n kube-system ds/cilium -- cilium service list

ID   Frontend                Service Type   Backend
11   0.0.0.0:32498/TCP       NodePort       1 => 10.2.1.103:80/TCP (active)
13   10.12.106.229:80/TCP    ClusterIP      1 => 10.2.1.103:80/TCP (active)

또한 서비스 맵에서 kind-cluster1에 배포된 백엔드 IP가 제거된 것을 볼 수 있다.

Affinity

추가적으로 로컬/원격 선호도를 Annotation으로 제어할 수 있다. 크로스클러스터의 경우 장애 발생 시 failover할 수 있는 장점이 있지만, 그만큼 네트워크 비용과 높은 레이턴시가 발생할 수 있다. 그렇기에 아래 Annotation으로 특정 상황에서만 크로스클러스터에 배포된 백엔드로 트래픽을 전달할 수 있다.

service.cilium.io/affinity: "local"    # 로컬 백엔드 우선, 없으면 원격
service.cilium.io/affinity: "remote"   # 원격 우선
service.cilium.io/affinity: "none"     # 구분 없이 균등 (기본)
kubectl --context kind-cluster1 annotate service global-svc service.cilium.io/affinity=local --overwrite

여기까지가 cilium clustermesh를 활용한 기본적인 고가용성 멀티클러스터 구축 방법이다. 고가용성뿐만 아니라 공유 서비스, 상태 저장 서비스와 상태 비저장 서비스의 분리 등 여러 방면에서 활용할 수 있다. 특히 공유 서비스의 경우, 각 클러스터 A, B, C끼리는 물리적 경계를 두고 A, B, C 클러스터가 공유하는 클러스터에만 연결을 맺는 방식이다. 이 공유 클러스터는 DNS 쿼리, 로깅 등 공통된 서비스만 모아서 처리할 수 있다.

이 글에서는 이전 시리즈에 이어 외부 클라이언트의 트래픽을 처리하는 North-South 통신(SNAT vs DSR)을 살펴보고, Cilium Hubble로 관측 가능성을 확인했으며, 멀티클러스터 통신 구축까지 다뤄보았다. Cilium은 iptables 같은 기존 레거시 구조에서 벗어나 eBPF를 이용해 다양한 시도를 이어가고 있는 오픈소스다. 그중에는 XDP를 이용해 로드밸런서까지 구축할 수 있을 만큼 강력하면서도 자유로운 확장성을 가진 영역도 있다.

참조문서

지난 기사에서 말했듯 재즈는 일단 ‘현장에서’, ‘라이브로’, ‘다양하게’ 들어보는 것을 추천하는 편이다. 하지만 재즈바도, 공연의 수도 기하급수적으로 늘어난 요즘, 입문자라면 자연스레 ‘첫 공연은 어디로, 누구의 무대를 보러 가야 할까’라는 질문이 떠오를 수밖에 없다.

물론 개개인의 취향과 선호하는 환경이 다 다르기 때문에 이 문제에는 정답이 없다. 다만 필자가 직접 가본 한정된 공간들 중에서 몇 군데를 추천하고 싶다.

지극히 개인적이고 주관적인 추천 재즈바 리스트

분위기와 맛있는 주류·음식이 중요하고, 비용 부담은 크지 않았으면 한다면 → 강남 플랫나인

강남 플랫나인

고급스러운 분위기가 매력적인 강남 플랫나인

사장님이 공연 전 관람 매너를 간단히 설명해줘서 좋았고, 분위기도 고급스러운 편이다. 다만 매장이 넓은 데 비해 음향 시설은 다소 아쉬워서 뒷좌석에서는 공연에 집중하기 어려울 수 있고, 주말 예약 시 보틀 1병을 무조건 주문해야 하는 점은 부담스럽게 느껴질 수 있다. 공연비를 비롯해 메뉴판의 전반적인 가격대도 높은 편이지만, 그만큼 맛은 확실히 보장된다.

부담 없는 비용으로 시작하고 싶고, 다양한 요일과 시간대에 공연이 있는 곳을 원한다면
→ 녹사평 부기우기

녹사평 부기우기

매일 세 타임의 공연을 만날 수 있는 녹사평 부기우기

매일 세 타임의 공연이 열리며, 공연비와 음식료 모두 다른 재즈바에 비해 저렴한 편이다. 그만큼 다채로운 밴드가 무대에 오르고, 내 일정에 맞는 공연을 찾기도 수월하다. 대신 좌석은 다소 불편한 편이고 음향도 최상급이라고는 말하기 어렵다. (가급적 사전 예약을 하면서 공연이 잘 보이는 자리로 배정해 달라고 요청하는 것을 추천한다.)

이곳의 가장 큰 장점은 인스타그램 계정을 활발히 운영해 공연자 정보가 자세히 올라온다는 점이다. 밴드 구성원은 물론 지향하는 장르, 셋리스트까지 비교적 상세히 안내되어 있어, 입문자일 때 미리 공연의 성격을 파악하고 가기에 좋았다.

좀 더 진지한 분위기에서 공연에 집중하고 싶다면 → 홍대 클럽 에반스, 후암시장 사운드독

홍대 클럽 에반스

홍대 클럽 에반스

2001년부터 자리를 지켜온 홍대 클럽 에반스

음악 업계에서 일하는 지인이 “일본에 ‘블루노트’가 있다면 한국에는 ‘클럽 에반스’가 있다”라고 말한 적이 있다. 그만큼 무대에 서는 문턱이 높은 편이라 실력 좋은 뮤지션들이 많이 찾는 곳이다. 가끔 열리는 Jam Day(뮤지션들이 각자 악기를 들고 모여 자유롭게 협연하는 날)에도 많은 사람이 참가할 정도로 명성과 역사가 깊다.

후암시장 사운드독

후암시장 사운드독

재래시장 골목에 자리한 이색적인 재즈바, 사운드독

후암시장이라는 독특한 장소에 자리한 사운드독 역시, 한국의 3대 재즈바를 꼽으라면 빠지지 않을 만한 곳이다. 재즈를 진심으로 사랑하는 사장님이 영화 <라라랜드>를 보고 감동해 수익을 크게 생각하지 않고 연 곳인데, 그만큼 음향 시설이 좋은 편이다. 또한 유튜브에 매 공연의 라이브 영상을 올려주기 때문에, 공연을 직접 가지 못한 날에도 현장의 분위기를 느낄 수 있다.

두 곳 모두 조리 음식을 판매하지 않는다는 공통점도 있다. 클럽 에반스는 간단한 핑거푸드와 음료만 판매하며, 사운드독 역시 비슷한 환경으로 콜키지 비용을 내면 외부 음식 반입이 허용된다. 아무래도 주방에서 음식을 조리하는 소리와 냄새가 뮤지션에게 방해가 될 수 있기 때문일 것이다. 그만큼 음악에 집중하고 싶은 헤비 리스너들이 많이 찾는 편이기도 하다.

이 외에도 여러 지역에 멋진 구/신 재즈바가 있으며(천년동안도, 재즈클럽 야누스 등), 필자가 아직 가보지 못한 더 좋은 장소도 분명 있을 것이다. 만약 ‘막연히 마음이 가는 곳’이 있다면, 그곳이 운명일지도 모르니 일단 한번 문을 두드려 보자.

재즈바 매너

재즈바에도 지켜야 할 매너가 있다

물론 이런 공간에서 지켜야 할 에티켓도 있다.

재즈바에서 지켜야 할 필수 예절

1. 공연비를 잊지 말기

요즘은 재즈바 쪽에서 섭외비를 지급하는 경우도 있다고 들었지만, 대부분의 재즈바에서는 관객이 내는 ‘공연비’만 뮤지션에게 돌아간다. 이 때문에 공연비를 15,000~20,000원으로 고정해 결제를 요청하거나, 10,000원 이상 자유롭게 지불하도록 하는 곳(예: 부기우기)도 있다.

평일 저녁에 재즈바를 가면 관객이 10명이 채 안 될 때도 있다. 이 10명이 모두 1만 원씩 낸다 치고 5인조 뮤지션들이 똑같이 나눈다면… 무덥거나 추운 날에도 악기를 짊어지고 다니고, 사비로 레슨까지 받으며 연습했을 뮤지션들이 최저 시급조차 받지 못하고 연주했다는 계산이 나온다. 정말 눈물 나는 현실이다.

물론 적은 관객을 감수하고도 무대에 오르는 것은, 그 자체가 뮤지션에게 좋은 실전 경험이 되기 때문이기도 하다. 그렇지만 평일 영화표 한 장이 1만 4천 원인 시대에, 눈앞에서 혼신을 다해 펼쳐지는 라이브를 보고도 공연비가 아깝다며 몰래 자리를 뜨지는 말자. (필자는 실제로 이런 경우를 두 번이나 목격했다. 공연비 봉투에 영수증이나 쓰레기만 넣고 가는 경우도 있다고 들었다.)

2. 박수를 잊지 말기

사전 지식 없이 재즈를 감상하다 보면 ‘다들 왜 이렇게 시도 때도 없이 박수를 치지?’라는 의문이 들 수 있다. 이는 재즈 연주의 기본적인 구조 및 형식과 관련이 깊다.

재즈 악보 예시

간단하게 이루어진 재즈 악보 예시 (출처 : MuseScore.com)

지난 기사에서 언급했듯 재즈는 자유로운 즉흥 연주가 특징이다. 그렇기에 재즈 악보는 위 예시처럼 매우 간단하게 이루어져 있고, 실제 연주에서는 대부분 많은 변주가 가해진다.

물론 연주 순서에는 (대체로) 지켜지는 룰이 있다.

  1. Intro 연주 (생략 가능)
  2. 멤버 전원이 ‘원곡’ 멜로디(중심 테마) 연주
    ※ ‘원곡’이라 부르지만 작곡가가 만든 그대로의 곡을 연주하는 것이 아니라 다양한 변형이 가해진다
  3. 한 사람씩 돌아가며 2번을 즉흥적으로 변주 (다른 악기들은 잔잔하게 배경음만 깔거나 가끔 추임새를 넣는다)
  4. 다 같이 다시 원곡 연주
  5. 마무리

이때 (3)번, 각 악기의 ‘솔로’라고 부르는 즉흥 연주 구간이 끝나는 타이밍마다 박수를 치는 것이 관례다. 재즈 밴드는 주로 3~5인 정도로 구성되기 때문에 (드럼이나 베이스는 가끔 솔로 없이 가기도 한다), 곡이 시작되기 전이나 끝난 후뿐 아니라 중간중간에도 박수를 쳐야 한다.

글로만 설명하면 이해가 어려울 수 있으니 예시 영상을 함께 살펴보자.

예시 영상으로 보기 ▶

(참고로 이 영상은 구간별로 어떤 파트인지 친절하게 표시되어 있다)

만약 이 팀의 연주를 직접 본다면, 박수는 아래와 같이 총 6번 치게 된다.

  • (영상에는 안 나왔지만) [연주 시작 전] 곡/멤버 소개 → 환영의 박수
  • 0:00~0:23 전주
  • 0:24~1:22 원곡 멜로디 다 같이
  • 1:23~3:22 색소폰 솔로 (3분 19초 눈빛 교환) → 끝나고 기타로 넘어가는 타이밍에 박수
  • 3:23~4:19 기타 솔로 (4분 16초부터 눈빛 교환) → 끝나고 피아노로 넘어가는 타이밍에 박수
  • 4:20~5:19 피아노 솔로 (5분 6초쯤부터 눈빛 교환) → 끝나고 드럼으로 넘어가는 타이밍에 박수
  • 5:20~7:09 드럼 솔로 (7분쯤부터 눈빛 교환) → 끝나고 원곡 멜로디를 다시 연주하는 타이밍에 박수, 보통 드럼 솔로 때는 연주가 격해지는 타이밍에 박수와 환호성을 함께 보내는 편
    ※ 참고로 이 영상 속 드럼 솔로는 “Trade”라는 형태로, 드럼이 짧은 소절을 다른 악기와 대화하듯 주고받으며 연주하는 기법이다.
  • 7:10~8:23 원곡 멜로디 다시 & 마무리 → 끝나고 잘 들었다는 의미로 박수

사실 공연이 한창 진행되는 와중에 각 악기의 솔로 구간이 끝나고 치는 ‘중간 박수’의 타이밍을 가늠하기란 쉽지 않다. 원곡 멜로디를 원래부터 아는 경우가 아니라면 더더욱 어려운데, 솔로 중에는 멜로디에 많은 변형이 가해지고 때로는 길이를 2~3배씩 늘려 연주하기도 하기 때문에, 필자 같은 비전문가가 음악만 듣고 짐작하기란 쉽지 않다.

그래서 추천하는 방법은 뮤지션들이 서로 몸짓과 눈짓을 주고받는 순간을 유심히 관찰하는 것이다. (위에 표시한 구간 참고) 그들 역시 사람이라 누가 언제 이어받아야 하는지 헷갈릴 수 있어, 보통 자신의 파트가 끝나기 전에 신호를 보낸다. 관객도 이 신호를 함께 살펴보면 타이밍을 잡기 쉬워진다.

많은 뮤지션이 이 ‘박수 치는 타이밍’과 ‘박수의 크기’에 귀 기울이며 ‘오늘 관객은 재즈를 어느 정도 아는구나’라고 가늠한다고 한다. 이 박수가 크고 정확할수록 뮤지션도 아무래도 더 의식하며 연주하기 마련이다. (실제로 필자도 무대 위 뮤지션에게 “박수 치는 타이밍을 보니 재즈를 많이 들으시는 분이 온 것 같아 긴장된다”라는 말을 들은 적이 있다.) 뮤지션들도 사람인 만큼, 호응이 좋은 관객을 만나면 더욱 열과 성을 다하기 마련이다.

그렇기 때문에 박수를 열심히 칠수록 뮤지션만 신나는 게 아니라, 관객 역시 더 좋은 공연을 즐길 가능성이 높아진다. 또한 재즈 특유의 자유로운 분위기 덕분에, 공연 중 흥이 난다면 아무 때나 소리를 지르거나 박수를 쳐도 이상하게 보는 사람은 없다. 그러니 공연을 촬영하는 것도 좋지만, 가끔은 카메라를 내려놓고 그 순간의 분위기에 몸을 맡긴 채 손뼉을 치고 환호성도 질러보자.

다시 한번 강조하자면, 같은 뮤지션과 같은 곡도 매 공연마다 달라지는 것이 재즈의 묘미다. 그래서 지금 눈앞에 펼쳐지는 공연은 두 번 다시 반복될 수 없다. 그렇게 생각하면 눈앞의 공연에 더욱 몰입해 더 많은 감각을 느낄 수 있을 것이다.

공연을 고르는 법

지난 기사에서 설명했듯 재즈의 세부 장르는 무척 다채롭다. 솔직히 필자도 음악만 듣고는 무슨 장르인지 가늠이 안 될 때가 많을 정도다. 게다가 같은 뮤지션이라도 시기에 따라 다양한 스타일의 음악을 하고, 한 공연에서도 여러 스타일을 섞어 연주하는 경우가 많다.

그래서 공연 전 정보를 보고 대충 아래와 같이 짐작한다. (정확한 건 아니고 어디까지나 ‘대충’)

  • 스탠다드 재즈, 비밥/포스트밥, 스트레잇-어헤드 재즈, 스윙 재즈, 모던 재즈 → 누가 들어도 “아, 재즈!” 싶은 걸 하는구나
  • 라틴, 아프로 쿠반, 살사 → 남미스럽고 뜨거운 걸 하는구나
  • 보사노바 → 살랑거리는 걸 하는구나
  • 펑크 → 베이스가 강하고 그루브를 좀 타겠구나
  • 소울, 블루스 → 구슬프겠구나
  • 퓨전, 컨템포러리 재즈 → 현대적이겠구나
  • 집시 → 현악기가 메인이고 에스메랄다가 생각나겠구나
  • 뉴올리언스, 빅 밴드 → 관악기가 떼로 나오겠구나
  • 스피리츄얼 → 내가 잘 따라갈 수 있으려나

대체로 입문자에게는 문미향 퀸텟/쿼텟, 말로 밴드처럼 보컬이 있는 팀을 추천하는 편이다 (원래 클래식이나 뉴에이지처럼 가사 없는 음악을 즐겨 들었다면 예외). 가끔 유명한 타 장르곡을 재즈로 편곡하는 밴드(예: 게임과 애니메이션 OST를 편곡하는 Ganime)도 있는데, 취향에 맞는다면 이쪽도 좋은 선택이 될 수 있다. 아무래도 내가 아는 곡을 라이브로 듣는 경험은 더 신나고 공연에 몰입하기 쉽게 만들어주기 때문이다.

문미향 퀄텟 가니메 말로

첫눈 기념으로 일찍 캐럴을 불러준 문미향 퀄텟(좌) / ‘진심’을 코스프레로 보여준 가니메(중) / 구성진 K-재즈를 들려준 재즈 싱어 말로(우)

또한 재즈 밴드는 보통 트리오(3인), 쿼텟(4인), 퀸텟(5인) 등으로 이루어지는데, 어떤 악기로 구성되었느냐에 따라 느낌이 많이 달라진다. 전통적인 구성을 원한다면 피아노+드럼+베이스+색소폰(혹은 트럼펫) 조합을 추천한다.

정 감이 안 온다면 관심 있는 연주자의 인스타그램이나 유튜브를 찾아보자. 대부분의 뮤지션들이 자신의 공연 영상을 충실하게 아카이빙해두는 편이다. (혹은 재즈바에서 업로드해주기도 한다.) 최근 몇 곡만 들어봐도 대강의 느낌을 알 수 있을 테니, 나와 ‘필’이 통하는 뮤지션을 발굴해 보자. 그것 역시 ‘재즈 덕질’의 재미 요소니까.

앞서도 간략히 언급했지만, 최근 재즈에 대한 관심은 빠르게 늘고 있는 반면 뮤지션 대다수는 여전히 열악한 환경에서 활동하고 있다. 최근 한 재즈 전문 기자가 공론화한 뮤지션 페이 미지급 사건(관련 영상)만 봐도 상황이 얼마나 심각한지 짐작할 수 있으며, 개인의 열정과 애정으로 겨우겨우 굴러가는 판이기도 하다.

그러니 부디 좋아하는 마음을 직관, 호응, ‘좋아요’ 등으로 뮤지션에게 꾸준히 전해주자. 당신이 무심코 건넨 한마디가 뮤지션이 커리어를 이어가는 데 힘이 될지도 모른다. 오늘 밤, 가까운 재즈바에 발걸음을 옮겨보는 건 어떨까.

재즈팬 밈

(출처 : 레인보우 식스 시즈 갤러리)

“응 너 하나 안 들으면 이 판 망해~ by. 재즈팬”

“재즈가 뭐라고 생각하세요?”

공연예술통합전산망 집계 기준, 2026년 대한민국에서 가장 많은 관객이 방문한 음악 축제는 5월 22일부터 24일까지 올림픽공원에서 열렸던 <서울재즈페스티벌 2026>이다. K-POP이나 록, 힙합처럼 쟁쟁한 대중적 장르를 제치고 당당히 1위에 오른 축제가 다름 아닌 ‘재즈’ 행사라는 사실은, 한국의 재즈 열기가 얼마나 뜨거운지를 짐작하게 한다. (물론 ‘서재페는 재즈라는 근본을 잊었다’는 일부 마니아들의 원성은 잠시 옆으로 밀어두자.)

서울재즈페스티벌 2026

2026년 국내 최다 관객을 모은 서울재즈페스티벌 (출처 : 나무위키)

이런 인기를 의식한 듯, 해외 유명 재즈 뮤지션들이 한국을 투어 경유지에 포함시키는 경우도 늘고 있다. 예전에는 손에 꼽을 정도였던 재즈바 역시 여러 지역에서 속속 생겨나는 중이다.

하지만 이렇게 재즈가 대중적으로 흥하는 풍경 한편에는, ‘재즈가 정확히 어떤 장르인지’나 ‘어떻게 감상하고 즐겨야 하는지’를 아직 잘 모르겠다는 사람도 많다. 필자 역시 비교적 최근에 재즈에 입문한 터라 그 막막함에 깊이 공감하며 이 시리즈를 연재하게 되었다. 재즈에 흥미는 있지만 어디서부터 시작해야 할지 모르겠다는 분들에게 이 기사가 도움이 되길 바란다.

재즈가 뭐라고 생각하세요?

재즈가 뭐라고 생각하세요 밈

한 번쯤은 접해봤을, “재즈가 뭐라고 생각하세요?” 밈

재즈에 관심이 없는 사람도 “재즈가 뭐라고 생각하세요?”라는 밈은 한 번쯤 접해봤을 것이다. 개인적으로 이 밈이 흥한 이유는 영상 자체가 웃긴 것도 있지만, 그만큼 재즈가 난해한 장르이기 때문이라고 생각한다.

재즈는 19세기 말 차별과 핍박 속에 살던 미국 남부 흑인 커뮤니티에서 시작되어 전 세계로 퍼진 장르다. 탄생 배경에 대한 이야기도 다양하며, 당대의 여러 음악 장르와 영향을 주고받으며 진화하고 분화해왔다.

재즈 스타일 계보도

세분화하면 끝이 없는 재즈의 하위 장르들 (출처 : Ohio University “Jazz Styles”)

뉴올리언스 재즈, 딕시 재즈, 스윙, 비밥, 쿨, 하드밥, 프리 재즈…. 세분화해서 알아갈수록 끝이 없는 것이 재즈의 세계다. (솔직히 재즈를 3년 넘게 들어온 필자도 이들의 차이를 정확히 설명해보라 하면 자신이 없다.)

당연히 같은 ‘재즈’ 카테고리로 분류되더라도, 음악을 들었을 때의 느낌은 천차만별일 수밖에 없다.

라라랜드 스틸컷

영화 <라라랜드> 속 즉흥 연주 장면 (출처 : 영화 <라라랜드> 스틸컷)

영화 <라라랜드>에서 세바스챤이 피아노를 격렬하게 두드리며 연주하던 것도 재즈이며,

김연아 하우젠 CF

‘Sing Sing Sing’이 흘러나오던 김연아의 하우젠 CF (출처 : 삼성전자 하우젠 CF 캡쳐)

오래전 김연아가 에어컨 광고에서 불렀던 ‘Sing Sing Sing’ 역시 유명한 스윙 재즈곡이며,

프랭크 시나트라 Fly Me to the Moon 앨범 자켓

프랭크 시나트라의 ‘Fly Me to the Moon’ 앨범 자켓

웬 외국 남자가 느끼한 목소리로 끈적하게 부르는 ‘Fly Me to the Moon’ 역시 대표적인 재즈곡이다.

이파네마에서 온 소녀 유튜브 썸네일

물론 이것 역시 엄연히 재즈다 (출처 : 유튜브 영상 썸네일)

Girl From Ipanema 영상으로 보기 ▶

재즈를 폭넓게 바라보는 이들은 보사노바 같은 장르 역시 재즈의 일부로 보기도 한다. (정확히는 브라질의 삼바와 재즈가 결합한 장르지만.)

그러니 같은 재즈 페스티벌에 가더라도 ‘이 스테이지는 좋은데 저 스테이지는 지루하네’라고 느낄 수밖에 없다. 때로는 (특히 ‘대중적인’ 재즈만 많이 접해왔다면) ‘이런 것도 재즈야?’라는 말이 절로 나오기도 한다.

그래서 재즈 입문자에게 가장 중요한 단계는 ‘내가 어떤 재즈를 좋아하는지’를 깨닫는 것이 아닐까 생각한다. 금관악기 여럿이 화려하고 격렬하게 연주하는 것이 좋은지, 피아노가 정갈한 느낌으로 연주하는 것이 좋은지, 악기만 나오는 것보다 보컬이 곁들여지는 편이 편한지, 혹은 현악기가 중심이 되는 편을 선호하는지 생각해볼 필요가 있다.

그리고 이 답을 찾는 가장 확실한 방법은 결국 ‘많이 들어보는 것’일 때가 많다.

그래서… 재즈가 뭐라고 생각하세요?

다시 처음의 질문으로 돌아가서, 재즈란 무엇일까. 크게 세 가지 특징으로 정리해볼 수 있다.

재즈의 가장 기본이 되는 정신은 ‘자유로움’이며, 악보에 얽매이지 않는 즉흥 연주를 지향한다. (아마도 재즈의 뿌리가 된 아프리카계 미국인들이 자유로운 삶을 그만큼 갈망했기 때문일 것이다.) 이 때문에 완전히 같은 곡을 같은 뮤지션이 연주하더라도, 언제 어디서 누구와 함께 연주했느냐에 따라 곡의 디테일이 달라진다.

그렇다 보니 박자 역시 클래식처럼 딱딱 맞아떨어지는 정박이 아니다. 학교에서 배운 ‘강 약 중강 약’ 리듬 때문에 한국인은 대체로 1박과 3박에 강세를 두지만, 재즈는 2박과 4박에 강세를 둔다. 물론 여기에 다양한 변주를 더해 강약의 위치를 바꾸거나 음의 길이를 자유롭게 바꾸기도 한다.

또한 재즈에서는 음악사적으로 ‘한’이나 ‘슬픔’ 같은 ‘Blueness’가 느껴질 때가 많다. (음계가 어떻고 하는 어려운 이야기는 지금 단계에서는 잠시 접어두자.) 가요나 록 음악을 재즈풍으로 편곡했을 때 묘하게 차분하고 가라앉은 느낌이 드는 이유도 여기에 있다. (그리고 ‘어쩌면 이런 정서가 한민족의 정서와 잘 맞아서 좋아하는 것 아닐까’ 하는 것이 필자의 추측이기도 하다.)

이중 바로 첫 번째 특징 때문에, 재즈에 입문하는 사람에게는 ‘음반’보다 ‘현장에서 라이브를 들어보는 것’을 추천하는 편이다. 특히 규모가 큰 페스티벌이나 공연보다는 작은 재즈바에서의 공연을 권하고 싶다.

음반에는 상당히 정제된 음이 기록되는 반면, 현장에서는 각 악기가 내는 날것의 소리를 생생하게 들을 수 있다. 연주자들이 서로 눈짓을 주고받거나 호흡을 맞추는 교감의 순간을 포착하는 재미도 있다. 호응이 좋은 관객을 만났을 때 객석의 분위기가 무대까지 전염되어 뮤지션들이 한층 더 열정을 발휘하는 모습을 보다 보면, 나도 모르게 그 열정에 압도되곤 한다. 앞서 서술했듯 같은 곡도 뮤지션마다, 혹은 공연마다 다르게 해석해 연주하다 보니 매번 ‘랜덤 가챠’ 같은 요소가 있다는 점도 매력적이다.

그렇다면 오늘 밤에만 들을 수 있는 ‘One and Only’ 공연을 100% 즐기기 위해서는 어떤 지식이 필요할까. 1편에서는 재즈가 어떤 장르인지, 그리고 왜 음반보다 현장 라이브를 추천하는지를 짚어봤다면, 2편에서는 한 걸음 더 들어가 필자가 직접 다녀본 재즈바들과 그 특징, 공연장에서 꼭 알아야 할 공연비·박수 예절, 그리고 내 취향에 맞는 공연을 고르는 법까지 좀 더 실전적인 이야기를 담았다.

재즈 입문 가이드 2편 보러가기 ▶

Tip. 만약 재즈에 대해 스스로 더 공부해보고 싶다면?

재즈 잇 업 책 표지

만화로 보는 재즈의 역사, <재즈 잇 업! Jazz It Up!>

📚

만화 : 재즈 잇 업! Jazz It Up!

남무성의 만화로 보는 재즈의 역사 – 남무성 (2018, 서해문집)

굵직한 뮤지션을 비롯해 재즈의 역사를 총망라한 책으로, 만화 형식이라 초보자도 비교적 쉽게 이해하며 따라갈 수 있다. 세계적인 음악 시장으로 꼽히는 일본의 재즈 전문지에 연재되며 현지에서도 좋은 평가를 받았던 책이다.

블루 자이언트 영화 포스터 블루 자이언트 원작 만화

애니메이션 영화(왼쪽)와 원작 만화(오른쪽) <블루 자이언트>

🎬

애니메이션 영화 & 만화 : 블루 자이언트

영화 타치카와 유즈루 감독, 원작 만화 이시즈카 신이치 & NUMBER 8

2023년 개봉한 이 영화는 2시간 남짓한 분량으로 만화 원작의 일부만 압축해 보여주지만, 그만큼 ‘재즈가 무엇인지’를 큰 진입 장벽 없이 이해할 수 있는 작품이다. 유명 재즈 뮤지션 우에하라 히로미가 작곡하고 연주한 OST 역시 뛰어난 작품성과 대중성을 모두 갖추고 있어 그야말로 이 영화의 백미라 할 수 있다. 원작 만화는 영화 내용의 전후까지 길게 다루는 만큼 분량이 많으니, 우선 영화부터 보고 취향에 맞으면 만화로 넘어가는 것을 추천한다.

컴투스홀딩스가 글로벌 퍼블리싱을 맡고 인디게임 개발사 프로젝트모름(Project Moreum)이 개발 중인 신작 ‘론 셰프(Lone Chef)’는 요리와 탐험, 전투를 결합한 2D 액션 어드벤처 게임이다. 개발사는 요리(Cook)와 메트로배니아(Metroidvania)를 결합한 ‘쿡트로이드바니아(Cooktroidvania)’라는 독자적인 장르를 내세우고 있다. 직접 플레이하며 론 셰프만의 재미 요소를 하나씩 살펴봤다.

요리가 사라진 세계, 그리고 식당

낯선 동굴에서 눈을 뜬 주인공
눈을 떠보니 낯선 동굴, 기억은 아무것도 남아있지 않다

눈을 떠보니 낯선 동굴이다. 주인공은 자신의 이름도, 과거에 무슨 일이 있었는지도 기억하지 못한다. 몹시 배고픈 상태로 어두운 동굴을 둘러보다 발견한 것은 두꺼운 책 한 권과 오래된 상자 하나다. 상자를 열자 옷과 머플러, 거대한 국자가 나온다. 이 국자가 주인공의 첫 무기다.

머플러를 착용하는 주인공
머플러를 착용하자 떠오르는 기억의 조각

상자에서 발견한 머플러를 착용하자 잃어버렸던 기억의 일부가 떠오른다.

재료를 채집하는 주인공
사람들을 돕기 위해 재료를 모으고 요리를 시작한다

주인공은 사람들을 돕기 위해 곳곳을 돌아다니며 재료를 채집하고 요리를 만든다.

기억 속 소녀와의 약속을 지키기 위해 식당도 뚝딱 지어 올린다. 요리가 사라진 세계에 다시 음식을 선보일 공간이 마련되는 순간이다.

“내 조리대보다 크고 멋있는 건 금지야”

하지만 식당이 완성되자마자 붉은 머리의 여자가 나타나 건물을 부숴버린다. 힘들게 지은 식당이 눈앞에서 순식간에 무너지는 황당한 상황이 벌어진다.

“이 장소에 내 조리대보다 크고 멋있는 건 금지야. (…) 좋아, 기회를 줄게. 설산 정상으로 음식을 가져와. 세상에서 가장 맛있는 음식을. 그러면 식당을 짓도록 허락해 줄게.”

체험판 전체를 관통하는 메인 퀘스트가 여기서 시작된다. 종말 이후의 세계에서 거대한 국자를 든 요리사가 세상에서 가장 맛있는 음식을 만들기 위해 설산 정상으로 향한다. 다소 엉뚱해 보이는 설정이지만, 요리와 탐험이라는 론 셰프의 핵심 요소를 자연스럽게 하나의 목표로 묶어낸다.

요리는 스탯이자 모험의 열쇠다

맛 태그 시스템 화면
음식마다 붙는 맛 태그, 태그마다 다른 효과가 걸린다

론 셰프의 핵심 시스템은 음식마다 붙는 ‘맛 태그’다. 모든 음식에는 ‘달달한’, ‘깔끔한’, ‘담백한’, ‘든든한’, ‘매콤한’, ‘기름진’, ‘과열된’ 등의 태그가 붙으며, 각각 서로 다른 효과를 지닌다. 달달한 음식은 위력을 높이고, 고기 계열 음식은 근력 경험치를 제공한다. 특정 음식은 회복력이나 스태미나를 보충해준다. 캐릭터의 능력치 역시 체력과 민첩, 위력, 소화력 등으로 세분화돼 있다.

중요한 점은 음식과 맛 태그가 전투를 보조하는 용도로만 쓰이지 않는다는 것이다. 필드를 탐험하거나 퀘스트를 해결할 때도 음식이 일종의 열쇠 역할을 한다.

배고픈 여자 NPC
배고픈 여자는 달달한 음식을 원한다
고대 장치 퍼즐
멈춰 선 고대 장치는 과열된 음식을 요구한다

배고픈 여자는 ‘달달한’ 음식을 필요로 한다.
멈춰버린 고대 장치는 ‘과열된’ 음식을 요구한다.
겁에 질려 우는 아이는 ‘든든한’ 음식으로 달랠 수 있다.

레시피 도감 화면
새 요리를 만들면 자동 등록되는 레시피 도감

재료를 조합해 새로운 요리를 만들면 해당 레시피가 도감에 자동으로 등록된다. 과일화채와 고기야채볶음, 나물밥, 둥근빵 등 여러 음식을 직접 만들어보며 비어 있는 도감을 채우는 재미가 있다.

쪼그라든 버섯 재료
특별한 재료로만 만들 수 있는 고대 레시피, ‘쪼그라든 버섯’
쭈글쭈글 건강 스무디 효과
몸집이 작아져 좁은 공간을 통과할 수 있다

특별한 재료로만 만들 수 있는 고대 레시피도 존재한다. ‘쪼그라든 버섯’으로 만드는 ‘쭈글쭈글 건강 스무디’를 마시면 캐릭터의 몸집이 작아진다. 이를 활용하면 평소에는 지나갈 수 없었던 좁은 공간에 들어가 새로운 장소를 탐험할 수 있다.

이처럼 론 셰프의 요리는 체력을 회복하거나 능력치를 올리는 소비 아이템에 머물지 않는다. 캐릭터의 상태와 크기를 바꾸고, NPC의 요구를 해결하며, 새로운 탐험 경로를 여는 핵심 장치로 활용된다.

날씨를 바꾸면 지형이 바뀐다

오르지 못하는 절벽
초반엔 오를 수 없는 절벽, 메트로배니아 특유의 막힌 길

론 셰프의 탐험 구조는 메트로배니아의 특징을 뚜렷하게 보여준다. 초반에는 점프력이 부족해 오를 수 없는 절벽과 대시 능력이 없어 건너지 못하는 협곡이 곳곳에 등장한다. 처음에는 막혀 있던 길도 새로운 능력이나 장비를 얻은 뒤 다시 방문하면 통과할 수 있다.

이러한 길을 여는 열쇠 중 하나가 날씨다. 날씨를 관장하는 정령 NPC는 “날씨는 지형에 영향을 줘. 날씨를 바꾸면 새로운 탐험을 할 수 있다”고 설명한다.

비로 물이 차오른 지형
비를 부르자 수위가 올라가며 새 발판이 열린다

실제로 비를 내리게 하자 지형에 물이 차오르고, 수면의 높이가 올라가면서 이전에는 닿지 않았던 발판까지 이동할 수 있게 된다. 배경의 분위기만 달라지는 것이 아니라, 날씨의 변화가 실제 지형과 이동 경로에 영향을 주는 구조다.

또 다른 열쇠는 장비다. 체험판 후반부에 얻는 신발은 순간적으로 빠르게 이동하는 대시 능력을 제공한다. 이 장비를 손에 넣는 순간 건너지 못했던 협곡과 닿지 않았던 장소에 새로운 길이 열린다. 획득한 능력을 활용해 이전 지역을 다시 탐색하는 메트로배니아 특유의 재미를 확인할 수 있는 부분이다.

체험판의 하이라이트, 요리 경연 대회

체험판에서 가장 짜임새 있게 구성된 구간은 단연 요리 경연 대회다.

경연 대회 접수처 고양이 NPC
말끝마다 “~냥”을 붙이는 접수처 고양이 NPC

말끝마다 “~냥”을 붙이는 고양이 NPC가 대회 접수처를 지키고 있다. 대회에 참가하려면 추천서가 필요하며, 추천서는 위기에 빠진 요리사를 도와야 얻을 수 있다. 참가 자격을 얻는 과정에서도 탐험과 퀘스트가 자연스럽게 이어진다.

대회의 규칙은 간단하다. 세 명의 심사위원은 각자 다른 음식 취향을 가지고 있다. 한 명은 깔끔한 맛, 한 명은 담백한 맛을 선호하고, 나머지 한 명은 특별히 가리는 음식이 없다. 참가자는 주어진 재료를 활용해 심사위원들의 취향에 맞는 요리를 만들어야 한다.

관객석 대화 힌트
관객들의 대화에서 심사위원의 취향을 엿들을 수 있다

경연이 진행되는 동안 관객석에서는 심사위원의 취향을 파악할 수 있는 힌트를 발견할 수 있다. 관객들의 대화를 엿듣고 각 심사위원이 좋아하는 맛을 알아낸 뒤, 여러 취향을 동시에 만족시키는 요리를 완성하는 것이 핵심이다.

둥근빵 요리 완성 화면
깔끔한 맛과 담백한 맛을 모두 가진 ‘둥근빵’

곡물로만 만드는 ‘둥근빵’에는 깔끔한 맛과 담백한 맛이 함께 붙는다. 하나의 요리로 두 명의 심사위원을 동시에 만족시킬 수 있었고, 이를 통해 요리 경연에서 우승할 수 있었다. 정답을 바로 알려주는 방식이 아니라 주변 인물의 대화에서 단서를 찾고, 맛 태그를 조합해 해결책을 찾아야 한다는 점이 인상적이었다.

우승 상품 대시 신발
우승 상품으로 얻은 대시 신발

우승 상품은 앞서 언급한 대시 신발이다. 새로운 장비를 착용하자 기억 속 소녀와의 추억이 다시 떠오르고, 이어지는 튜토리얼을 통해 대시 사용법을 익힐 수 있었다. 요리 경연과 스토리, 장비 획득, 새로운 탐험 능력이 하나의 흐름으로 연결되는 구성이다.

스팀 체험판 플레이 방법

론 셰프는 현재 스팀에서 무료 체험판을 제공하고 있다. 정식 출시 전에 게임을 미리 만나보고 싶다면 아래 순서에 따라 체험판을 내려받을 수 있다.

스팀 론 셰프 상점 페이지
스팀 론 셰프 상점 페이지

STEP 1 스팀 상점의 론 셰프 페이지에 접속한다.

STEP 2 상점 페이지에서 ‘론 셰프 데모 다운로드’를 선택한다.

STEP 3 스팀 라이브러리에서 게임을 실행한다. 한국어 인터페이스와 자막을 지원한다.

체험판에는 게임 도입부부터 첫 보스 구간과 요리 경연 대회까지 포함돼 있다. 요리와 탐험, 전투가 어떻게 연결되는지 살펴보고 론 셰프가 어떤 재미를 지향하는 작품인지 파악하기에 충분한 분량이다.

이런 유저에게 추천한다

체험판을 플레이하고 나면 론 셰프가 어떤 취향의 유저를 겨냥하고 있는지 꽤 또렷하게 보인다. 아래 세 가지 중 하나라도 해당한다면 체험판을 한 번 플레이해볼 만하다.

음식 만드는 게임을 좋아한다면, 재료를 모아 레시피를 채우는 재미

레시피 조합 화면
두 재료를 조합해 처음 보는 요리를 완성하는 순간

요리 게임의 재미는 “이 재료와 저 재료를 섞으면 어떤 음식이 나올까”라는 궁금증에서 시작된다. 론 셰프는 이러한 감각을 정확히 짚어낸다. 두 가지 재료를 조합해 처음 보는 요리가 완성되면 해당 레시피가 도감에 자동으로 등록된다. 비어 있던 도감의 한 줄이 새롭게 채워지는 순간이 생각보다 뿌듯하다.

필드에서 말랑한 채소나 작은 알갱이 곡물을 발견할 때마다 “이 재료는 무엇과 섞어볼까”라는 생각이 먼저 들기도 한다. 새로운 재료를 찾는 탐험이 자연스럽게 새로운 요리를 만드는 과정으로 이어지는 것이다.

게다가 완성한 음식은 수집품에 머물지 않는다. 전투에 필요한 능력치를 높여주는 버프가 되기도 하고, NPC의 퀘스트를 해결하거나 막혀 있던 탐험 경로를 여는 열쇠로도 활용된다. 재료를 모으고 조합하며 도감을 채우는 플레이를 좋아하는 유저라면 가장 확실하게 만족할 만한 요소다.

새로운 능력으로 길을 개척하는 탐험을 좋아한다면

메트로배니아 탐험 화면
새로운 능력을 얻어야 열리는 길

점프만으로는 닿을 수 없는 절벽과 대시가 없어 건널 수 없는 협곡은 플레이어에게 다음 목표를 분명하게 제시한다. 날씨를 바꾸거나 새로운 장비를 획득한 뒤 이전 지역으로 돌아가면 보이지 않았던 길이 열리고, 새로운 장소와 재료를 발견할 수 있다.

한 번 지나온 장소도 어떤 능력을 얻었느냐에 따라 전혀 다른 탐험 공간으로 바뀐다. 지도를 돌아다니며 막힌 길을 기억해두고, 새로운 능력을 얻은 뒤 다시 찾아가는 메트로배니아 특유의 탐험을 좋아한다면 론 셰프의 구조도 반갑게 느껴질 것이다.

픽셀 아트와 유쾌한 이야기를 좋아한다면

종말 이후 요리가 사라진 세계라는 설정은 다소 무겁게 느껴질 수 있지만, 론 셰프는 이를 밝고 유쾌한 분위기로 풀어낸다. 힘들게 지은 식당을 단숨에 부숴버리는 붉은 머리의 여자와 말끝마다 “~냥”을 붙이는 고양이 접수원 등 개성 강한 캐릭터들이 곳곳에서 등장한다.

론 셰프 도트 그래픽 캐릭터 모션
촘촘한 프레임으로 자연스럽게 움직이는 도트 캐릭터들

아기자기한 픽셀 아트로 표현된 필드와 음식, 캐릭터의 움직임도 게임의 분위기와 잘 어울린다. 진지한 생존보다는 독특한 세계를 여행하며 다양한 인물과 만나고, 소소한 사건을 해결하는 모험을 선호하는 유저에게 잘 맞는다.

국자 하나 들고 떠나는 맛있는 모험

론 셰프 총평 이미지
요리 하나로 전투, 탐험, 서사를 모두 관통하는 게임

론 셰프는 요리를 별도의 미니게임으로 분리하지 않고 전투와 성장, 퀘스트, 탐험에 폭넓게 연결한다. 재료를 모아 새로운 음식을 만들고, 음식에 붙은 맛 태그로 NPC의 요구를 해결하며, 특별한 레시피와 장비를 활용해 막혀 있던 길을 개척한다. 각각의 요소가 따로 움직이지 않고 하나의 모험 안에서 자연스럽게 이어진다.

체험판에서 가장 인상적이었던 부분도 이러한 연결 구조였다. 관객들의 대화에서 심사위원의 취향을 파악하고, 맛 태그가 겹치는 요리를 만들어 경연에서 우승한 뒤, 보상으로 받은 대시 신발을 활용해 새로운 길을 탐험한다. 요리와 이야기, 퍼즐, 캐릭터 성장이 맞물리며 론 셰프만의 플레이 흐름을 만들어낸다.

새로운 재료를 발견할 때마다 어떤 음식이 완성될지 궁금해지고, 비어 있던 레시피 도감이 하나씩 채워질 때마다 다음 요리를 만들고 싶어진다. 재료를 모아 새로운 레시피를 완성하는 요리 게임과 새로운 능력으로 길을 넓혀가는 메트로배니아를 좋아한다면, 국자를 들고 떠나는 론 셰프의 모험을 미리 경험해보길 추천한다.

게임 데이터를 분석하려면 목적에 맞는 지표·차원·이벤트 구성을 매번 새로 정해야 한다. 처음 시도하는 분석일수록 이 준비 과정에 시간이 걸린다. Hive 애널리틱스의 템플릿은 대시보드·차트·퍼널·리텐션에서 자주 쓰는 구성을 미리 제공해 초기 설정 과정을 줄여준다. Create 메뉴에서 템플릿을 선택하면 주요 항목이 채워진 생성 화면으로 이동하며, 제공된 구성을 그대로 쓰거나 분석 목적에 맞게 수정할 수 있다.

처음부터 구성해야 하는 분석 콘텐츠

게임 데이터를 분석하려면 확인하려는 내용에 맞춰 지표와 차원, 이벤트 단계 등을 매번 구성해야 한다. 여러 지표를 한 화면에서 살펴보거나 이용자의 전환·이탈 흐름을 확인하려면, 어떤 데이터를 함께 배치하고 어떤 기준으로 보여줄지도 그때그때 정해야 한다.

처음 시도하는 분석은 적절한 항목을 선택하고 구성하는 데 시간이 걸린다. 분석 목적에 맞는 템플릿을 참고할 수 있다면 필요한 데이터와 세부 조건만 조정해 초기 설정에 드는 시간을 줄이고, 익숙하지 않은 분석도 빠르게 시작할 수 있다. 반복해서 확인하는 분석 역시 같은 구조를 매번 새로 만들지 않아도 되므로 효율적으로 준비할 수 있다.

Hive 애널리틱스의 템플릿

Hive 애널리틱스의 템플릿은 자주 사용하는 대시보드·차트·퍼널·리텐션 구성을 미리 제공하는 기능이다. Create 메뉴에서 템플릿을 선택하고 사용할 구성을 고르면 주요 항목이 입력된 생성 화면으로 이동한다.

템플릿은 콘텐츠 생성을 위한 초기 설정을 제공하며, 적용 후에는 모든 항목을 분석 목적에 맞게 수정할 수 있다. 대시보드 템플릿에서는 미리 배치된 패널마다 프로젝트를 선택할 수 있고, 콘텐츠·이미지·텍스트 패널을 추가하거나 기존 패널을 삭제할 수도 있다. 차트·퍼널·리텐션 템플릿에서는 제공된 설정을 바탕으로 필요한 측정값과 차원값, 이벤트와 분석 조건을 변경할 수 있다.

Hive 애널리틱스에서 대시보드와 차트, 퍼널, 리텐션 템플릿을 선택하는 화면
콘텐츠 유형별 템플릿 목록에서 필요한 분석 구성을 선택할 수 있다.

템플릿으로 필요한 분석 시작해보기

템플릿을 그대로 적용해 콘텐츠를 생성하는 방법과 제공된 설정을 분석 목적에 맞게 수정하는 방법을 각각 살펴보자.

템플릿으로 콘텐츠 만들어보기

템플릿을 선택하면 주요 설정이 입력된 생성 화면으로 이동한다. 제공된 구성을 그대로 사용하려면 미리보기에서 결과를 확인한 뒤 생성 버튼을 눌러 원하는 이름으로 콘텐츠를 저장하면 된다. 아래 화면은 활성 사용자(AU) 리텐션 템플릿을 적용한 예시로, 로그인 이벤트가 기준 이벤트와 복귀 이벤트로 설정되어 있으며 일자별 기준 이용자 수와 재방문 비율을 확인할 수 있다.

AU 리텐션 템플릿을 적용해 로그인 이용자의 날짜별 재방문 비율을 확인하는 화면
AU 리텐션 템플릿을 적용해 로그인 이용자의 일자별 기준 이용자 수와 재방문 비율을 확인할 수 있다.

템플릿을 수정해 콘텐츠 만들어보기

템플릿 생성 화면에서는 제공된 측정값과 차원값 등의 설정을 분석 목적에 맞게 변경할 수 있다. 아래 화면은 국가별 상품 매출 차트 템플릿을 적용한 예시로, 결제 사용자(PU)와 매출, 매출 건수 등의 측정값과 국가·상품명 차원이 구성되어 있다.

국가별 상품 매출 차트 템플릿을 적용한 차트 생성 화면
국가별 상품 매출 차트 템플릿을 적용해 국가와 상품별 매출 지표를 확인할 수 있다.

마켓별 상품 성과를 확인하려면 국가 차원을 마켓 차원으로 바꾸면 된다. 기존 측정값과 상품명 차원은 유지한 채 마켓별 상품 매출을 확인하는 차트로 전환하고, 미리보기에서 결과를 확인한 뒤 새로운 차트로 저장할 수 있다.

국가 차원을 마켓 차원으로 변경해 마켓별 상품 매출을 표시한 차트 생성 화면
국가 차원을 마켓 차원으로 변경해 마켓과 상품별 매출 차트로 생성할 수 있다.

Hive 애널리틱스 시작해보기

템플릿을 이용하면 분석 콘텐츠의 기본 구성을 빠르게 불러오고 필요한 항목만 수정해 게임 데이터 분석을 시작할 수 있다.

Hive 애널리틱스는 Hive SDK를 통해 수집한 게임 데이터를 미리 구성된 템플릿에 적용해 필요한 분석 콘텐츠를 빠르게 만들고 분석할 수 있는 게임 전문 애널리틱스 솔루션이다. 게임 데이터를 다양한 관점에서 살펴볼 수 있는 유용한 템플릿은 앞으로도 계속 추가될 예정이다. 지금 Hive 애널리틱스의 템플릿으로 필요한 게임 분석 콘텐츠를 빠르게 만들어보자.

여러 게임을 운영하는 조직에서는 구성원마다 담당 프로젝트와 필요한 데이터 접근 범위가 다르다. Hive 애널리틱스의 조직 관리는 조직 단위로 프로젝트와 멤버를 묶어, 데이터 관리자가 개별 사용자 권한을 매번 설정하지 않고도 업무 책임에 맞는 데이터 접근 범위를 구성할 수 있게 한다. 게임별로 조직을 나누거나 여러 게임을 총괄하는 조직을 만들면, 담당자가 바뀌어도 조직의 멤버 구성만 조정하면 된다.

여러 게임을 운영할수록 달라지는 데이터 접근 범위

여러 게임을 운영하는 조직에서는 구성원마다 담당하는 프로젝트와 필요한 데이터가 다르다. 특정 게임만 운영하는 담당자에게는 해당 게임의 지표가 필요하지만, 여러 게임을 총괄하는 구성원은 전체 프로젝트의 성과를 함께 확인해야 한다. 담당하지 않는 프로젝트의 데이터까지 조회할 수 있다면 정보 접근 범위가 실제 업무 책임과 어긋날 수 있으므로, 업무 책임에 맞춘 권한 통제 체계가 필요하다.

구성원과 프로젝트 권한을 함께 관리해야 하는 데이터 관리자

이를 위해 데이터 관리자는 개별 사용자마다 권한을 설정하는 대신, 조직·프로젝트 단위로 권한을 그룹화해 구성원이 담당 업무에 필요한 데이터에 접근하도록 해야 한다. 게임별 담당 조직에는 해당 프로젝트를 배정하고, 여러 게임을 담당하는 구성원에게는 업무 범위에 맞는 프로젝트를 제공해야 한다.

조직 개편이나 신규 프로젝트 추가로 담당 범위가 바뀌면 접근 권한도 함께 조정해야 한다. 이때 프로젝트와 구성원을 조직 단위로 묶어 관리하면, 변경된 담당 범위를 조직 정보에 반영하는 것만으로 구성원의 데이터 접근 권한을 함께 관리할 수 있다.

Hive 애널리틱스의 조직 관리

Hive 애널리틱스의 조직 관리는 조직별로 프로젝트 권한을 제어하고 멤버의 접근 범위를 설정하는 기능이다. 애널리틱스에 가장 먼저 접속한 사용자는 최초 조직 설정을 진행할 수 있으며, 설정을 완료하면 애널리틱스 관리자로 자동 등록된다. 최초 조직 설정에서는 조직명과 프로젝트, 멤버를 지정해 데이터 접근 범위를 구성할 수 있다.

최초 접속자가 애널리틱스 관리자와 첫 번째 조직을 등록하는 화면
최초 접속자가 애널리틱스 관리자와 첫 번째 조직을 등록하는 화면이다.

이후 애널리틱스 관리자 권한을 가진 사용자는 우측 상단의 계정 메뉴에서 조직 관리로 이동해 새로운 조직을 추가하거나 기존 조직의 정보를 수정할 수 있다. 담당 프로젝트나 멤버 구성이 다른 그룹이 있다면 별도의 조직을 만들고, 각 조직에 필요한 프로젝트와 구성원을 지정하면 된다.

조직에 포함된 프로젝트와 멤버 구성에 따라 조회 가능한 데이터 범위가 결정된다. 새로운 게임이 추가되거나 담당자가 변경된 경우에는 기존 조직의 프로젝트와 멤버를 수정해 실제 업무 범위에 맞게 관리할 수 있다.

담당 범위에 맞게 조직 구성해보기

게임별 담당 조직과 여러 게임을 총괄하는 조직을 예시로, 프로젝트 접근 범위를 설정하고 변경하는 방법을 살펴보자.

게임별로 담당 조직 나누기

게임별로 담당 조직이 나뉘어 있다면 각 게임의 프로젝트와 담당자를 하나의 조직으로 구성할 수 있다. 예를 들어 A 게임 조직에는 A 프로젝트와 해당 게임의 담당자를 등록한다.

A 게임 조직에 A 프로젝트와 담당자를 등록한 조직 관리 화면
A 게임 조직에 A 프로젝트와 담당자를 등록한다.

조직에 등록된 담당자는 차트를 포함한 Hive 애널리틱스의 모든 데이터 조회 기능에서 A 프로젝트만 선택할 수 있다. 이를 통해 각 구성원이 자신이 맡은 게임의 데이터 범위에서만 분석 업무를 진행하도록 관리할 수 있다.

A 게임 조직의 담당자가 차트에서 A 프로젝트만 조회할 수 있는 화면
A 게임 조직의 담당자는 차트에서 A 프로젝트만 선택해 데이터를 조회할 수 있다.

여러 게임을 총괄하는 구성원에게 권한 제공하기

여러 게임의 성과를 함께 확인해야 하는 구성원에게는 필요한 프로젝트를 모두 포함한 조직을 제공할 수 있다. 예를 들어 A·B·C 게임을 총괄하는 구성원이라면 세 프로젝트를 포함한 조직의 멤버로 등록해 여러 게임의 지표를 함께 확인하도록 구성한다.

A, B, C 게임 프로젝트와 여러 게임을 총괄하는 구성원을 등록한 조직 관리 화면
A·B·C 게임 프로젝트를 하나의 조직에 구성하고 여러 게임을 총괄하는 구성원을 등록한다.

이후 기존 담당자 jshwang이 다른 조직으로 이동하고 bhchoi가 새로 A·B·C 게임을 맡았다면, 조직 멤버에서 jshwang을 제외하고 bhchoi를 추가하면 된다. 프로젝트 구성은 그대로 유지한 채 담당자만 변경해 새로운 업무 범위에 맞는 접근 권한을 제공할 수 있다.

A, B, C 게임 조직에서 기존 담당자를 제외하고 bhchoi를 새 멤버로 등록한 화면
jshwang을 제외하고 새 담당자 bhchoi를 등록해 조직의 접근 권한을 변경한다.

Hive 애널리틱스 시작해보기

Hive 애널리틱스에 가장 먼저 접속했다면 최초 조직 설정 화면에서 첫 번째 조직을 등록해보자. 이후에는 계정 메뉴의 조직 관리에서 담당 게임과 구성원을 기준으로 조직을 추가하거나 수정할 수 있다.

Hive 애널리틱스는 Hive SDK로 수집한 데이터를 조직별 권한에 맞게 제공해, 구성원이 자신이 맡은 게임의 지표에 집중해 분석할 수 있게 돕는 게임 전문 애널리틱스 솔루션이다. 지금 Hive 애널리틱스에서 담당 프로젝트와 멤버를 구성해보자.

“오늘 사내식당 메뉴가 뭐더라?”

매일 메뉴 고민 없이 든든한 식사를 제공하는 컴투스 사내식당. 하지만 아무리 맛있는 사내식당이라도, 유난히 ‘바깥 공기’와 함께 뚝배기에 펄펄 끓는 뜨끈한 국물이 간절해지는 날이 있기 마련이다. 사내식당의 안락함을 잠시 뒤로하고, 한 번쯤 과감히(?) 문을 나설 가치가 있는 회사 근처 ‘찐’ 국밥 맛집들을 소개한다.

이레담 백암순대

이레담 백암순대 가게 정면

뜨끈함의 대명사, 이레담 백암순대 입구

첫 번째로 소개할 국밥 맛집은 뜨끈함의 대명사, ‘순대국’이 매력적인 [이레담 백암순대]다.

이레담 백암순대 메뉴판

이곳의 대표 메뉴는 순대국, 수육, 순대를 한 번에 즐길 수 있는 정식

이곳의 대표 메뉴는 순대국과 함께 수육, 순대를 모두 맛볼 수 있는 ‘정식(14,000원)’이다. 직접 먹어보니 왜 이 집이 인기가 많은지 단번에 이해가 가는 비주얼과 맛이었다.

이레담 백암순대 정식

순대국 + 수육 + 순대까지, 한 상 가득한 정식

우선 정식을 시키면 나오는 순대와 수육의 퀄리티가 남다르다. 속이 꽉 찬 통통한 순대와 입안에서 부드럽게 녹아내리는 촉촉한 수육은 새우젓만 콕 찍어 먹어도 감탄이 절로 나온다.

이레담 백암순대 순대국 양

고기와 건더기가 아낌없이 들어간 순대국

메인인 순대국은 기본으로 다데기(양념장)가 들어가 있어, 등장할 때부터 칼칼하고 얼큰한 국물색을 자랑한다. 무엇보다 뚝배기 안에 고기와 건더기가 아낌없이 들어가 있어서 “여기 국밥 양 진짜 많다”라는 소리가 절로 나올 정도다.

이레담 백암순대 점심시간 붐비는 모습

점심시간이면 어김없이 붐비는 인기 맛집

💡

기자 맛 팁 & 이용 가이드

  • 치열한 점심런 찐 맛집이라, 점심시간에 조금만 늦게 가도 재료가 품절되어 발길을 돌려야 할 수도 있다. 눈치 싸움에 성공해 조금 서둘러 출발하는 것을 추천한다.
  • 추천 타깃 어제 회식으로 확실한 해장이 필요한 날, 유난히 배가 고파 든든하고 특별한 외식을 하고 싶은 날 강력 추천한다.

대두네 순두부

대두네 순두부 가게 정면

회사 건물 지하 1층에 자리한 대두네 순두부

두 번째로 소개할 곳은 회사 건물 지하 1층에 위치한 순두부찌개 전문점 [대두네 순두부]다. 이곳은 순두부찌개도 맛있지만, 아는 사람들 사이에서는 ‘제육볶음 맛집'(2인 19,000원)으로도 유명하다.

대두네 순두부 메뉴판

순두부부터 제육볶음까지, 알찬 메뉴 구성

순두부 전문점답게, 제육볶음을 주문해도 일반 공깃밥과 함께 백순두부와 간장이 세트로 나온다. 불향이 가득한 제육볶음은 고기에 양념이 잘 배어 있어 맛이 진하다. 여기에 함께 나오는 백순두부가 부드럽고 고소해서 매콤한 제육볶음과 밸런스가 딱 맞는다.

대두네 순두부 제육볶음과 백순두부

불향 가득한 제육볶음과 담백한 백순두부의 조합

찌개 종류 중 가장 추천하고 싶은 메뉴를 꼽으라면 단연 차돌순두부찌개(9,000원)다. 부드러운 순두부에 고소한 차돌박이가 듬뿍 들어가 국물 맛이 한층 깊고 고소하다. 게다가 위에 고추기름이 아낌없이 올라가 있어 보기만 해도 얼큰하고 매콤칼칼한 맛을 자랑한다.

대두네 순두부 붐비는 점심시간

점심시간마다 발 디딜 틈 없이 붐비는 매장

컴투스인들의 진짜 단골집답게, 이곳의 또 다른 재미는 메뉴 하나당 쿠폰 스티커를 한 장씩 준다는 점이다. 차곡차곡 모아두었다가 저녁 시간에 방문할 때 유용하게 사용할 수 있으니 지갑에 잘 챙겨두는 것을 추천한다.

대두네 순두부 쿠폰 스티커

방문할 때마다 차곡차곡 쌓이는 단골 쿠폰 스티커

💡

기자 맛 팁 & 이용 가이드

  • 숨은 치트키 제육볶음을 시키면 나오는 담백한 백순두부와 불향 가득한 제육의 조합이 좋으니, 2인 이상 방문한다면 찌개와 제육을 섞어서 시키는 것을 추천한다.
  • 추천 타깃 매콤칼칼하고 진한 국물로 스트레스를 풀고 싶거나, 제대로 된 불맛 제육볶음이 당기는 날 방문하기 좋다.

동남집

동남집 가게 정면

가산 직장인들 사이에서 유명한 동남집

세 번째로 소개할 곳은 이미 가산 직장인들 사이에서 유명한 맛집인 [동남집]이다. 든든하고 깔끔한 국물이 생각날 때 고민 없이 찾게 되는 곳이다.

동남집 메뉴판

갈비탕부터 특곰탕까지, 든든한 국물 메뉴

이곳에서 추천하고 싶은 메뉴는 갈비탕(13,000원)과 특곰탕(12,000원)이다. 특히 특곰탕은 일반 곰탕에 도가니가 몇 조각 들어가 있어서 훨씬 쫄깃하고 풍성한 식감을 즐길 수 있다. 국물은 짭짤하고 깔끔해서 자꾸만 손이 가는 중독성 있는 맛이다.

동남집 국밥

짭짤하고 깔끔한, 중독성 있는 국물 맛

동남집만의 가장 큰 차별점은 소면 사리를 무한으로 제공한다는 점이다. 국밥에 밥을 말기 전에 먼저 제공되는 소면을 뜨끈한 국물에 풀어서 국수처럼 즐긴 뒤, 그다음에 밥을 말아 먹으면 두 가지 음식을 먹는 듯한 만족감을 느낄 수 있다.

동남집 무한 리필 소면

밥 말기 전, 먼저 즐기는 무한 리필 소면

만약 얼큰하고 칼칼한 국물이 당기는 날엔 얼큰양국밥(10,000원)을 추천한다. 여름 한정 메뉴였던 콩국수(10,000원)도 함께 판매하니, 방문 전 운영 여부를 확인해 보는 것도 좋다.

동남집 얼큰양국밥

칼칼한 국물이 당길 때는 얼큰양국밥

동남집 콩국수

여름철 별미로 인기 있던 콩국수

💡

기자 맛 팁 & 이용 가이드

  • 소면 먼저 공략 사리가 무한 리필되므로 면을 좋아한다면 밥을 먹기 전 소면 사리를 국물에 적셔 먼저 맛보는 코스를 놓치지 말자.
  • 추천 타깃 호불호 없이 깔끔하고 짭짤한 고기 국물로 속을 채우고 싶거나, 면과 밥을 모두 즐기고 싶은 날 방문하기 좋다.
동남집 참고사항

동우황태북어국

동우황태북어국 가게 정면

뉴티캐슬 건물에 위치한 동우황태북어국

마지막으로 소개할 곳은 뉴티캐슬 건물에 위치한 [동우황태북어국]이다. 아침 일찍부터 영업을 시작해 전날 회식으로 속풀이가 시급한 날이나, 든든하게 아침 식사를 하고 싶은 날 찾기 좋은 곳이다.

동우황태북어국 메뉴판

황태북어국과 황태떡국, 단 두 가지 메뉴

이곳의 메뉴는 황태북어국과 황태떡국 두 가지로 아주 심플하다. 아침 영업시간(06:30~09:40)에는 모든 메뉴를 8,000원에 즐길 수 있고, 점심에는 10,000원에 판매한다. 1층과 2층으로 공간이 나누어져 있어 피크 타임인 점심 12시에 방문해도 긴 대기 없이 입장할 수 있다는 점이 큰 장점이다.

동우황태북어국 매장 내부

1층과 2층으로 나뉘어 있어 대기 부담이 적은 매장

기본 반찬으로 계란후라이와 잡채가 함께 제공되어 한 상 차림이 더욱 알차게 느껴진다.

동우황태북어국 기본 반찬

계란후라이와 잡채까지, 알찬 기본 반찬

이 집의 국물은 사골 같은 인위적인 첨가물을 쓰지 않고 오직 황태로만 맛을 낸다. 직접 먹어보니 황태 특유의 시원하고 담백한 국물 맛이 그대로 느껴져 속이 정화되는 기분이었다. 참고로 국과 밥은 무한으로 리필이 가능하며, 황태떡국을 주문할 경우 공깃밥은 기본 제공되지 않으니 참고하자.

동우황태북어국 황태북어국

첨가물 없이 황태로만 낸 시원하고 담백한 국물

동우황태북어국 황태떡국

쫄깃한 떡이 가득한 황태떡국

여름 한정으로 맛볼 수 있었던 황태 미나리 비빔국수(10,000원) 역시 놓치기 아쉬운 별미였다. 부드러운 회와 새콤달콤한 양념, 그리고 향긋한 미나리가 잘 어우러진 메뉴로, 가을에도 판매하는지는 매장에 확인이 필요하다.

동우황태북어국 황태 미나리 비빔국수

여름철 인기 별미였던 황태 미나리 비빔국수

동우황태북어국 떡국과 비빔국수 한 상

든든한 떡국과 개운한 비빔국수, 취향껏 골라보자

💡

기자 맛 팁 & 이용 가이드

  • 아침 식사 타임 활용 새벽 6시 30분부터 아침 영업을 하므로 출근길 완벽한 해장이 필요한 날 8,000원의 가성비로 이용하기 좋다.
  • 추천 타깃 첨가물 없는 깔끔하고 시원한 황태 국물로 속을 달래고 싶은 사람에게 추천한다.

찬 바람이 불기 시작하면 뚝배기에서 김이 모락모락 피어오르는 따뜻한 국물이 절로 생각난다. 오늘만큼은 익숙한 사내식당을 잠시 벗어나 보는 것은 어떨까. 회사 근처 국밥 맛집에서 속까지 든든해지는 한 그릇으로 쌀쌀해진 가을 날씨를 따뜻하게 채워보자.

치열한 전투와 모험을 이어가는 아르콘들을 위해 오프라인 실물 보급품이 도착했다. <제우스: 오만의 신>이 정식 출시를 기념해 이마트24, 컨디션·새싹보리(HK이노엔)와 손잡고 다양한 인게임 보상을 제공하는 콜라보 이벤트를 진행한다. <제우스: 오만의 신>을 즐기고 있는 유저로서 쿠폰의 유혹을 참지 못하고 직접 콜라보 이벤트에 참여해봤다. 제품 구매부터 쿠폰 등록, 보상 활용법과 스탬프 이벤트 응모 방법까지 하나씩 소개한다.

편의점 털고 인게임 재화 득템! <제우스: 오만의 신> X 이마트24

이마트24와 <제우스: 오만의 신>이 콜라보 간편식 5종을 출시하고, 제품 구매 고객에게 인게임 쿠폰을 제공하는 이벤트를 시작했다. 가까운 이마트24 매장에서 간편하게 한 끼를 해결하고 캐릭터 성장에 필요한 재화까지 챙길 수 있는 기회다.

콜라보 대상 품목

  • 제육&우삼겹 반반김밥
  • 고추장제육볶음면
  • NEW 반반고기 정찬
  • 마요직화제육덮밥
  • 더빅더블 제육&숯불갈비맛 삼각김밥
든든한 한 끼 식사를 원한다면 도시락류의 콜라보 제품
든든한 한 끼 식사를 원한다면 도시락류의 콜라보 제품
간편한 끼니 해결을 원한다면 덮밥과 삼각김밥
간편한 끼니 해결을 원한다면 덮밥과 삼각김밥

콜라보 전 제품을 시식해 본 결과, 개인적으로 가장 만족도 높았던 제품은 ‘마요직화제육덮밥’이다. 토핑의 양은 다소 아쉬웠지만 양념에서 은은한 불향이 났고, 전체적인 밸런스도 좋았다. 무엇보다 한 그릇으로 식사를 끝낼 수 있는 간편함이 한몫했다.

쿠폰 등록부터 e24 코인 활용까지

배부른 식사 후 깜빡하면 안되는 것이 바로 동봉된 인게임 쿠폰 사용이다. 동봉된 쿠폰 뒷면에 쿠폰 번호가 적혀있고, 삼각김밥의 경우 포장 앞면에 있는 실링을 긁어내면 쿠폰 번호가 드러난다. 확인한 쿠폰 번호는 게임 내 [메뉴 > 환경설정 > 계정 > 쿠폰 등록] 또는 <제우스: 오만의 신> 공식 홈페이지 상단 메뉴의 [쿠폰 등록]에서 입력할 수 있다. 등록을 완료하면 각 상품에 해당하는 보상이 게임 내 우편함으로 지급된다.

쿠폰 보상으로 획득하게 되는 인게임 ‘e24 코인’은 각 콜라보 제품의 금액에 따라 32~59개가 제공되는 방식이다. e24 코인은 그 자체로 버프 아이템으로 사용하거나, 일정 수량을 모아 [메뉴 > 이벤트 > e24 코인 교환 이벤트]에서 ‘희귀 등급 확정 소환 선택상자’를 비롯한 다양한 인게임 아이템으로 교환할 수 있다. 버프로 사용할 경우 일반 몬스터 공격력/방어력/명중/회피와 같은 사냥에 핵심적인 스탯 버프 효과를 얻을 수 있다.

기자는 수령한 e24 코인으로 가장 먼저 ‘빛바랜 신탁 지령서’를 교환하여 사용했다. 공물과 여러 보상을 획득할 수 있는 신탁은 매일 진행 가능 횟수가 제한적이기 때문에, 게임 초반 성장을 위해 필수로 챙겨야 하는 요소 중 하나이다. 강화 재료, 제작 재료 등 성장 재화로 교환이 가능하다. 이외에는 강화 재료, 제작 재료 등 성장 재화로 교환이 가능하다. 기자의 다음 목표는 소환권이다.

e24 코인 교환 화면
e24 코인으로 교환 가능한 다양한 인게임 아이템

사냥 피로와 숙취를 한 번에! <제우스: 오만의 신> X 새싹보리

묵은 갈증을 해소해 주는 ‘새싹보리’와 회식 자리의 구원자 ‘컨디션’이 <제우스: 오만의 신>과 만났다. 사냥의 피로는 깔끔하게 날리고 시원한 보상까지 챙겨보자.

콜라보 대상 품목

  • [품절] 컨디션 x 제우스: 오만의 신 스페셜 팩 (컨디션맛(제로) 10입 × 1박스, 그린애플맛 10입 × 1박스)
  • 새싹보리·새싹보리블랙 x 제우스: 오만의 신

회식 자리 구원자, 컨디션 패키지

집으로 배송 받아 본 컨디션 패키지
집으로 배송 받아 본 컨디션 패키지

컨디션은 기존 숙취 해소 음료와 동일한 맛의 ‘컨디션맛’과 달콤한 사과 맛이 매력적인 ‘그린애플맛’ 2종으로 구성되어 있다. 얇은 포 형태의 부드러운 젤리라 밖에서도 간편하게 짜 먹기 좋다. 한 패키지에 각 맛이 10개씩, 총 20개 들어 있어 회식 자리에서 동료들과 나눠 먹기에도 충분하다. 다만 많은 관심 속에 현재 패키지 상품은 품절된 상태다.

누구나 좋아할 익숙한 맛, 새싹보리

제우스 일러스트가 라벨에 그려진 새싹보리·새싹보리블랙
제우스 일러스트가 라벨에 그려진 새싹보리·새싹보리블랙

새싹보리와 새싹보리블랙은 대한민국 누구나 어릴 적 마시며 자랐던 익숙한 보리차의 맛으로, 남녀노소 누구나 좋아할 맛이다. 제로 칼로리에 그저 차일 뿐이지만 고소한 맛이 왠지 모르게 속을 든든하게 채워주는 것도 같다. 고카페인으로 자극적인 커피 대신, 고소한 새싹보리 한 병으로 오후를 깨워보는 것은 어떨까?

쿠폰 등록하고 보상 챙기기

제품을 즐겼다면 이번에도 쿠폰을 사용할 차례이다. 컨디션 패키지 내 동봉된 쿠폰 뒷면의 실링을 카드나 동전으로 긁어 가려진 쿠폰 번호를 확인할 수 있다. 새싹보리의 경우 라벨을 벗겨 라벨 안쪽의 쿠폰 번호를 확인할 수 있다. 쿠폰도 사용하고 라벨도 분리배출할 수 있어 일석이조다. 확인한 쿠폰 번호는 게임 내 [메뉴 > 환경설정 > 계정 > 쿠폰 등록] 또는 ‘제우스: 오만의 신’ 공식 홈페이지 상단 메뉴의 [쿠폰 등록]에서 입력할 수 있다. 등록을 완료하면 각 상품에 해당하는 보상이 게임 내 우편함으로 지급된다.

스페셜 팩에 동봉된 ‘레전드 쿠폰’을 등록하면 ‘컨디션 특별 의상 11회 소환’ 아이템을 받을 수 있으며, 이를 통해 최대 전설 등급의 의상을 획득할 수 있다. 이외에도 고급~희귀 등급의 신석을 획득할 수 있는 ‘스페셜 신석 소환’과 각각 공격/방어 버프 아이템으로 사용 가능한 컨디션 콜라보 버프 아이템을 통해 성장 정체의 묵은 숙취를 함께 해소할 수 있다.

컨디션 쿠폰 사용 보상
컨디션 쿠폰 사용 보상
새싹보리 쿠폰 사용 보상
새싹보리 쿠폰 사용 보상

새싹보리와 새싹보리블랙 제품에는 ‘럭키보리 쿠폰’이 포함돼 있다. 쿠폰을 등록하면 확률에 따라 소환권이나 성장 재화를 얻을 수 있는 ‘럭키보리 보따리’를 비롯해 이벤트 제작 재료인 ‘다다익선 새싹보리’, 경험치 버프 아이템과 콜라보 버프 아이템 등을 획득할 수 있다.

‘다다익선 새싹보리’ 아이템은 여러 개를 모아 [메뉴>제작>이벤트>럭키보리 보따리]에서 재료로 사용된다. 수량에 따라 소환권, 강화 주문서, 오리하르콘 등 핵심 성장 재화가 담긴 상자로 교환할 수 있다.

인게임 내 이벤트 제작 화면
인게임 내 이벤트 제작 화면. 기자는 네 병을 마셔 [럭키보리 꾸러미 I]를 만들 수 있게 되었다.

나만 알고 싶은 꿀팁! 이마트24 앱을 사용한 쿠폰 할인과 스탬프 이벤트

콜라보 이벤트 소개를 읽고 당장 편의점으로 달려가려던 독자라면 잠시 멈춰보자. 콜라보 이벤트를 즐기기 전에 꼭 알아야 할 팁이 있다. 이 내용만 숙지하고 있다면 텅 비어버린 재고에 눈물 흘리며 돌아갈 일도, 눈앞의 제품을 전부 쓸어담다 지갑이 텅 비어버릴 일도 없다.

픽업 예약 30% 할인 쿠폰

기자의 꿀팁은 이마트24 앱 사용이다. 앱에서 미리 재고를 확인하고 픽업 예약을 하면 헤매지 않고 정확한 제품 구매가 가능하다. 또한 현재 이마트24 앱을 통해 픽업 예약 시 30% 할인 쿠폰을 사용할 수 있다. 3,200원인 삼각김밥 하나만 구매해도 천 원 가까이 할인받을 수 있고, 최대 100,000원까지 사용 가능이라 제한도 넉넉하니 선택이 아닌 필수 쿠폰이다.

제우스 콜라보 제품 예약 페이지에서 쿠폰 사용하는 방법
제우스 콜라보 제품 예약 페이지에서 쿠폰 사용하는 방법

스탬프 모아 ‘제육쓰 Lv.UP 챌린지’ 응모

픽업 할인을 놓쳤더라도 실망하기는 이르다. 이마트24에서는 매장에서 콜라보 제품을 구매한 고객을 대상으로 스탬프 이벤트 ‘제육쓰 Lv.UP 챌린지’를 진행하고 있다. 제품 하나당 스탬프 하나를 적립하여 스탬프 3개당 1회 응모가 가능하다. 응모는 최대 999회까지 가능하며, 5명이 추첨되는 응모권의 1등 경품은 영웅 등급 의상이나 탈것을 확정으로 얻을 수 있는 ‘이마트24 영웅 등급 소환 I 선택상자’다. 이외에도 4등까지 총 100명에게 다양한 인게임 소환권 및 이마트24 쿠폰을 추첨하니 매장 구매를 희망하는 사람은 스탬프 적립을 놓치지 않길 바란다.

이마트24 스탬프 이벤트 '제육쓰 Lv.UP 챌린지'
이마트24 스탬프 이벤트 ‘제육쓰 Lv.UP 챌린지’
가까운 이마트24 매장 찾기
오늘도 살아남은 직장인들의 힐링 아이템 모음!

오늘도 쌓이는 직장인의 스트레스

“오늘 안에 가능할까요?”

“서버에 오류가 있는 것 같습니다.”

“한 가지만 더 수정 부탁드립니다.”

직장인이라면 하루에도 몇 번씩 마주하는 문장이다.

메신저 알림은 계속 울리고, 오전에 정리한 할 일은 오후가 되기도 전에 몇 줄씩 늘어난다. 예상하지 못한 이슈는 꼭 퇴근 직전에 찾아오고, 마지막이라고 생각했던 파일에는 또다시 수정 의견이 달린다.

그렇다고 스트레스를 받을 때마다 자리를 박차고 나갈 수는 없는 일이다. 직장인들은 지금 있는 자리에서 잠깐이라도 기분을 바꿀 방법을 찾는다. 커피를 마시거나 짧게 산책하고, 책상 위에 놓인 물건을 습관처럼 만지작거리기도 한다.

그렇다면 컴투스인들은 어떤 아이템으로 업무 중 쌓인 스트레스를 풀고 있을까? 오늘도 각자의 자리에서 살아남은 컴투스인들의 힐링템을 하나씩 살펴봤다.

중요한 회의 전, 괜히 긴장된다면?
워리 스톤으로 마음을 가라앉혀보자

긴장요정 · 개발팀 · 회의 공포증(?) 보유

중요한 회의나 발표를 앞두면 챙길 것도 많아지고, 괜히 목소리까지 떨린다. 자료를 몇 번이고 다시 열어보고 발표 순서를 머릿속으로 되짚어봐도 긴장은 쉽게 가라앉지 않는다. 이럴 때 ‘긴장요정’이 찾는 것은 워리 스톤이다.

워리 스톤(Worry Stone)은 손안에 들어오는 작은 돌 형태의 소품이다. 가운데가 오목하게 파여 있어 엄지손가락을 올려놓고 반복해서 문지를 수 있도록 만들어졌다. 천연석뿐 아니라 클레이와 레진, 도자기 등 다양한 소재로 제작되며, 최근에는 동물이나 캐릭터 모양을 더한 제품도 쉽게 찾아볼 수 있다.

사용법은 단순하다. 오목한 부분을 엄지손가락으로 천천히 문지르며 손끝의 감각에 집중하면 된다. ‘긴장요정’ 역시 회의 전 워리 스톤을 한참 만지다 보면 발표에 대한 걱정에서 잠시 벗어나 마음을 가다듬을 수 있다고 한다.

최근 SNS에서는 완성된 제품을 구매하는 것을 넘어 자신이 좋아하는 색과 모양으로 워리 스톤을 직접 만드는 과정도 공유되고 있다. 동그란 고리를 달아 키링처럼 가방에 매달고 다니거나, 책상 위에 두고 필요할 때마다 만지는 식이다. 긴장을 풀기 위한 목적뿐 아니라 손이 심심할 때 만지는 촉감 아이템이나 취향을 담은 작은 소품으로 찾는 사람도 많다.

너무 자주 만진 탓인지 표면은 처음보다 한결 매끈해졌다는 후문이다. 그만큼 중요한 순간마다 함께했다는 뜻일지도 모른다.

🧘 긴장 힐링템

핸드메이드 워리 스톤 키링 12,900원 →

할 일이 너무 많아 머릿속이 복잡하다면?
말랑이와 슬라임을 만지며 잠시 생각을 내려놓아보자

말랑덕후 · 마케팅팀 · 촉감템 수집 중

해야 할 일은 머릿속에 가득한데, 막상 무엇부터 시작해야 할지 몰라 손이 멈추는 순간이 있다는 ‘말랑덕후’. 그럴 때는 억지로 업무를 붙잡기보다 잠시 생각을 내려놓는 것부터 시작한다고 한다.

말랑이와 슬라임은 누르고, 쥐고, 늘이고, 터뜨리는 등 손으로 다양한 촉감을 즐길 수 있는 아이템이다. 모두 비슷해 보이지만 제품마다 만졌을 때의 느낌과 소리는 제각각이다. 누른 뒤 천천히 원래 모양으로 돌아오는 스퀴시부터 얇은 왁스 막이 깨지는 왁뿌볼, 알갱이가 들어 있어 오독오독한 촉감을 느낄 수 있는 크런치 슬라임까지 종류도 다양하다.

‘말랑덕후’가 즐겨 찾는 아이템도 그날의 기분에 따라 달라진다. 답답한 날에는 왁뿌볼의 왁스 막을 ‘콰작’ 터뜨리고, 생각이 많을 때는 크런치 슬랑이를 조물조물 만진다. 손을 계속 움직이고 싶은 날에는 퍼티 슬라임을 길게 늘였다가 다시 접기를 반복한다.

최근에는 말랑이의 디자인과 촉감을 비교하거나 자신이 좋아하는 질감을 찾는 과정 자체를 취미로 즐기는 사람도 많다. 제품을 직접 만져보기 위해 소품숍을 찾아가고, 구매한 제품의 촉감과 소리를 영상으로 촬영해 공유하기도 한다. 단순히 귀여운 장난감을 모으는 것을 넘어 각자 취향에 맞는 촉감 아이템을 찾아가는 것이다.

‘말랑덕후’ 역시 몇 분간 손끝의 촉감에만 집중하고 나면 머릿속을 가득 채웠던 업무 생각에서 잠시 멀어질 수 있다고 한다. 그렇게 한동안 만지작거리고 나면 무엇부터 처리해야 할지도 다시 눈에 들어오기 시작한다.

🎯 집중 힐링템

청사과 왁뿌 말랑이 4,000원 → 수제 땅콩 슬랑이 10,500원 → 젠젠 박사 퍼티 슬라임 5,300원 →

“한 가지만 더 수정 부탁드립니다.”
오늘은 대왕 엔터키가 필요할지도

수정지옥 생존자 · 디자인팀 · 오늘도 최종_진짜최종_최종본 작업 중

오늘만 벌써 다섯 번째 수정이라는 ‘수정지옥 생존자’. 파일을 고치고 저장하고 다시 전달하다 보면, 어느새 키보드를 있는 힘껏 두드리고 싶은 순간이 찾아온다. 그럴 때 찾는 것은 책상 한쪽에 놓인 대왕 엔터키다.

대왕 엔터키는 이름 그대로 키보드의 엔터키를 커다랗게 키운 모양의 쿠션이다. 일반 키보드 키캡과 달리 푹신한 스펀지가 들어 있어 손바닥이나 주먹으로 힘껏 내려쳐도 부담이 적다. USB 케이블로 컴퓨터에 연결하면 실제 엔터키처럼 사용할 수 있는 제품도 있다.

평소에는 책상 위에 올려두는 독특한 소품이나 손목 쿠션으로 사용하다가 답답한 일이 생기면 마음껏 두드릴 수 있다. 쌓인 스트레스를 말이나 행동으로 바로 드러내기 어려운 사무실에서 잠시 기분을 환기하는 데 제법 유용하다고.

‘수정지옥 생존자’도 커다란 엔터키를 주먹으로 몇 번 힘껏 내려치고 나면 꾹 눌러두었던 답답함이 조금은 풀리는 기분이 든다고 한다. 해야 할 수정은 그대로지만, 다시 마우스를 잡을 힘 정도는 생긴다. 다섯 번째 수정이 마지막 수정이라는 보장은 없다. 그래도 대왕 엔터키만 있다면 ‘진짜최종_최종본’까지 한 번 더 버텨볼 수 있지 않을까.

😤 분노 힐링템

빅 엔터키 스트레스 해소 펀치 쿠션 12,000원 →

매일 반복되는 출퇴근길이 유난히 길게 느껴진다면?
키캡 키링으로 손끝에 작은 재미를 더해보자

출퇴근 고인물 · 운영팀 · 같은 길 9년째 이동 중

매일 같은 길을 오가다 보면 출퇴근 시간이 유난히 길고 지루하게 느껴지는 날이 있다는 ‘출퇴근 고인물’. 요즘은 가방에 달아둔 키캡 키링을 만지작거리며 이동하는 것이 작은 습관이 됐다.

키캡과 클리커는 버튼을 누를 때 나는 ‘딸깍’ 소리와 손끝에 전해지는 타건감을 즐기는 아이템이다. 키보드와 같은 스위치가 들어 있어 누를 때마다 실제 키를 누르는 듯한 느낌을 받을 수 있다. 스위치의 종류에 따라 누르는 압력과 소리도 달라 자신의 취향에 맞는 타건감을 고를 수 있다.

여기에 색상과 캐릭터, 입체적인 디자인을 더한 것이 아티산 키캡이다. ‘아티산(Artisan)’이라는 이름처럼 단순한 자판 부품을 넘어 하나의 작은 작품이나 수집품처럼 제작된다. 좋아하는 캐릭터를 키보드에 장착할 수도 있고, 키링 형태로 가방에 달아 가지고 다닐 수도 있다.

‘출퇴근 고인물’이 선택한 것은 ‘서머너즈 워’의 데빌몬과 엔젤몬을 입체적으로 구현한 아티산 키캡이다. 손에 쏙 들어오는 키캡을 ‘챱챱’ 누르고, 캐릭터의 모양을 손끝으로 따라가다 보면 지루했던 이동 시간도 어느새 금세 지나간다고 한다.

캐릭터를 보는 재미와 버튼을 누르는 재미를 함께 느낄 수 있다는 것도 매력이다. 특별한 준비 없이 가방에 달아두기만 하면 되니, 매일 반복되는 출퇴근길에 소소한 즐거움을 더하기에도 좋다.

🚇 출퇴근 힐링템

데빌몬 아티산 키캡 39,000원 → 엔젤몬 아티산 키캡 39,000원 →

퇴근 후에도 업무 생각이 떠나지 않는다면?
무드등을 켜고 하루를 천천히 마무리해보자

집순이 모드 · 사업팀 · 이제 아무도 날 찾지 마세요

업무를 마치고 집에 돌아온 뒤에도 메신저 내용이나 다음 날 처리할 업무가 계속 떠오른다는 ‘집순이 모드’. 몸은 집에 도착했지만 머릿속에서는 아직 업무가 끝나지 않았다. 이럴 때는 방의 밝은 조명을 끄고 한쪽에 놓아둔 무드등을 켠다.

무드등은 방 전체를 환하게 밝히는 일반 조명과 달리 은은한 빛으로 공간의 분위기를 바꿔주는 조명이다. 책상이나 침대 옆처럼 원하는 곳에 간단히 설치할 수 있고, 좋아하는 캐릭터나 색상이 더해진 제품은 인테리어 소품으로도 활용할 수 있다.

최근에는 밝은 조명과 스마트폰 등 하루 동안 이어진 자극을 줄이고 조용히 쉬는 시간을 갖기 위해 무드등이나 향초, 잔잔한 음악을 함께 활용하는 사람도 많다. 거창하게 방을 꾸미지 않아도 조명 하나만 바꾸면 공간의 느낌이 확연히 달라지기 때문이다.

‘집순이 모드’가 선택한 것은 ‘서머너즈 워’ 마도사 무드등이다. 불을 켜면 마도사의 모습이 은은한 빛과 함께 드러난다. 밝은 천장 조명을 끄고 무드등 아래에서 음악을 듣거나 게임을 즐기다 보면 조금 전까지 머릿속을 맴돌던 업무 생각도 서서히 멀어진다고 한다.

회사에서 집으로 이동했다고 해서 바로 퇴근 모드가 되는 것은 아니다. 밝은 조명을 끄고 무드등을 켜는 짧은 행동이 ‘오늘 업무는 여기까지’라고 알려주는 집순이 모드만의 퇴근 버튼인 셈이다.

🌙 퇴근 후 힐링템

데빌몬 무드등 32,000원 → 마도사 무드등 55,000원 →

마치며

스트레스를 푸는 데 꼭 거창한 방법이 필요한 것은 아니다. 답답할 때 한 번 힘껏 두드리고, 머리가 복잡할 때 잠시 손에 잡히는 무언가를 만지작거리는 것만으로도 기분이 조금 나아질 수 있다.

물론 이런 아이템이 밀린 업무를 대신 처리해주거나 스트레스를 완전히 없애주지는 않는다. 그래도 잠깐 웃고 다시 할 일을 시작할 힘을 얻는다면, 그것만으로 충분하지 않을까. 오늘도 수많은 알림과 수정 요청을 이겨낸 직장인 여러분, 각자의 방법으로 무사히 퇴근하시길!

메트로배니아라는 장르를 좋아한다면 컴투스홀딩스가 퍼블리싱한 ‘페이탈 클로(Fatal Claw)’라는 이름이 낯설지 않을 것이다. 오늘 컴투스 패밀리게임 코너에서는 이 게임을 자세히 리뷰해보려 한다 🙂

게임명 페이탈 클로(Fatal Claw)
개발사 엔데브게임즈(NDEV GAMES)
퍼블리셔 컴투스홀딩스
장르 2D 액션 어드벤처 / 메트로배니아
플랫폼 PC(Steam)
출시 2025년 11월 18일(얼리 액세스) – 정식 출시: 2026년 8월 26일

메트로배니아, 그리고 페이탈 클로

메트로배니아는 ‘메트로이드’와 ‘캐슬바니아’라는 두 게임의 이름을 합쳐 만든 장르명으로, 넓게 이어진 하나의 맵을 탐험하며 새로운 능력을 얻고, 그 능력으로 예전에는 갈 수 없었던 장소를 다시 찾아가는 구조를 기본으로 한다. 막혀 있던 길이 새로운 능력을 얻는 순간 열리고, 이미 지나쳤던 지역을 다시 방문하면서 숨겨진 아이템이나 새로운 경로를 발견하는 재미가 이 장르의 핵심이라 할 수 있다.

‘할로우 나이트’와 ‘오리와 눈먼 숲’ 같은 작품들이 대표적인 메트로배니아 명작으로 꼽히면서, 이제는 인디 게임에서도 낯설지 않은 장르로 자리 잡았다. 오늘 소개할 ‘페이탈 클로’ 역시 이 메트로배니아를 기반으로 만들어진 2D 액션 어드벤처 게임이다.

페이탈 클로 스크린샷 1 페이탈 클로 스크린샷 2

메트로배니아 장르에 대한 더 자세한 이야기는 지난 컴투스온 기사를 참고하자 (https://on.com2us.com/content/metroidvania/)

주인공은 조금 특별하다. 사람도, 기사도, 마법사도 아닌 검은고양이 ‘키샤(Kisha)’다. 키샤는 붕괴한 지하 왕국을 돌아다니며 감염된 생명체들과 싸우고, 살아남은 사람들을 구하면서 이곳에서 벌어진 사건의 진실을 찾아가게 된다.

페이탈 클로 스크린샷 3 페이탈 클로 스크린샷 4
주인공이 고양이라 오히려 더 좋았다

처음에는 귀여운 고양이가 주인공인 아기자기한 게임처럼 보이지만, 실제 분위기는 생각보다 어둡다. 폐허가 된 지하 왕국과 감염된 괴물들이 곳곳에 등장하고, 오래된 흔적들이 남아 있어 탐험하는 재미도 상당하다.

붕괴한 고대 왕국, 그리고 키샤의 여정

‘페이탈 클로’의 이야기는 지하 깊은 곳에 존재하는 고대 왕국에서 시작된다. 이곳에는 ‘에인션트(Ancients)’와 ‘커머너(Commoners)’가 함께 살아가고 있었지만, 무슨 일이 있었는지 왕국은 완전히 무너져버렸다.

지하 세계 곳곳에는 감염되어 날뛰는 생명체들이 돌아다니고 있고, 일부 구역은 봉인되어 접근조차 할 수 없는 상태다. 그런 어두운 분위기 속에서 유저는 선조들의 힘으로 다시 살아난 고양이 키샤를 조작하게 된다. 키샤는 지하 세계를 돌아다니며 살아남은 이들을 찾고, 각 지역에 남겨진 흔적을 따라가면서 이 왕국에서 벌어진 사건을 하나씩 알아간다.

페이탈 클로 스크린샷 5 페이탈 클로 스크린샷 6
이어지는 대화로 슬픈 조각들이 연결되기도 한다

스토리는 정식 버전에서 더 많은 내용을 담게 됐다. 얼리 액세스 당시에는 일부 NPC의 이야기와 세계관이 제한적으로 공개됐지만, 정식 출시와 함께 각 캐릭터의 이야기가 보다 구체적인 결말로 이어지며 여러 엔딩도 추가됐다. 한 번 엔딩을 봤다고 끝나는 게 아니라 다른 선택과 조건을 통해 새로운 결말을 확인할 수 있다는 점도 메트로배니아 장르를 좋아하는 사람이라면 꽤 반가운 부분이다.

개발사 측에서는 주요 콘텐츠와 복수 엔딩, 숨겨진 요소까지 포함해 약 30시간 정도의 플레이 타임을 제공한다고 설명하고 있다. 커뮤니티에서는 첫 엔딩까지 약 12시간 정도가 걸렸다는 평가도 있어, 빠르게 스토리만 진행하면 훨씬 짧게 끝낼 수도 있을 것 같다. 숨겨진 요소를 찾고 세계를 구석구석 탐험하며 모든 엔딩까지 확인하려고 하면 플레이 시간이 자연스럽게 늘어나는 구조다.

페이탈 클로 스크린샷 7 페이탈 클로 스크린샷 8
어두컴컴한 동굴 탐험이 제일 으스스하고 어렵다

얼리 액세스에서 정식 출시까지

‘페이탈 클로’는 2025년 11월 스팀 얼리 액세스로 처음 공개됐다. 처음부터 지금과 같은 규모였던 것은 아니다. 얼리 액세스 초기에는 약 6시간 정도의 콘텐츠를 중심으로 게임의 기본적인 재미를 보여줬고, 이후 업데이트를 통해 새로운 지역과 스킬, 스토리 등이 계속 추가됐다.

특히 두 차례의 대형 업데이트를 거치면서 세계가 점점 커졌고, 이용자들의 피드백을 반영해 여러 부분을 수정해 나갔다. 그리고 2026년 8월 26일 드디어 정식 버전이 출시됐다.

얼리 액세스에서 처음 플레이했던 사람이라면 정식판의 차이를 꽤 크게 느낄 만하다. 지역과 콘텐츠가 늘어난 것은 물론이고 NPC들의 이야기와 멀티 엔딩까지 추가되면서, 플레이 시간만 길어진 것이 아니라 게임 전체의 구성이 한층 탄탄해진 느낌이다. 개인적으로 얼리 액세스 게임은 정식 출시 때 얼마나 달라지는지가 중요하다고 생각하는데, ‘페이탈 클로’는 적어도 콘텐츠 규모 면에서는 확실히 성장한 편이다.

페이탈 클로 스팀 평가 화면
최근 평가, 전체 평가 모두 매우 긍정적이라는 점이 재밌는 게임, 잘 만든 게임이라는 증거다

엔데브게임즈가 만든 빠른 메트로배니아

‘페이탈 클로’를 개발한 곳은 국내 게임사 엔데브게임즈다. 엔데브게임즈는 2022년 설립된 개발사로, 주요 개발진 가운데에는 ‘엘소드’, ‘엘소드 모바일’, ‘커츠펠’ 등의 액션 게임 개발 경험을 가진 인력들이 포함돼 있다고 한다. 그래서인지 직접 플레이해 보면 전투와 캐릭터 움직임에서 액션 게임을 오래 만들어온 개발진의 색깔이 느껴진다.

이동이 빠르고 공격도 상당히 경쾌한 편이다. 키샤는 기본 이동 속도부터 꽤 빠르고, 대시나 벽점프, 글라이드 등의 능력을 얻을수록 움직임이 더 자유로워진다. 공중 공격이나 하강 공격을 연타로 이어가면 공중 체공 시간이 길어지는데, 이 흐름이 자연스러우면서도 빠른 템포의 전투를 만들어내는 점이 인상적이었다.

페이탈 클로 스크린샷 9 페이탈 클로 스크린샷 10
경쾌한 공격! 타격감이 제대로다

고양이인데 전투는 꽤 맵다

키샤의 공격은 기본적으로 근접 전투를 중심으로 한다. 가볍게 한 대 때리고 빠지는 방식보다는 공격을 이어가면서 콤보를 만들어내는 쪽에 가깝다. 적들에게서 얻는 ‘뮤테이티드 어빌리티(Mutated Abilities)’를 사용하고, 탐험을 통해 얻는 여러 스킬을 조합하면서 전투 스타일도 조금씩 달라진다. 여기에 ‘카비츠(Cabitz)’라는 마법석을 장착해 추가 효과를 더할 수도 있다.

페이탈 클로 스크린샷 13 페이탈 클로 스크린샷 14
강력한 적을 무찌르면 능력을 흡수할 수 있다

개인적으로 전투에서 가장 마음에 들었던 건 스킬 게이지와 회복 자원이 따로 관리된다는 점이다. 회복에 사용할 자원과 스킬 사용 자원이 분리되어 있어서, 스킬을 사용하고 싶어도 회복 때문에 게이지를 아껴야 하는 상황이 상대적으로 적다. 또한 중간중간 저장스팟에서 부활하는 경험 덕분에 실수로 죽었을 때 잃는 상실감에 대한 부담도 비교적 가벼운 편이다. 이런 구조 덕분에 전체적인 난이도는 소울라이크 성향이 강한 다른 메트로배니아 게임보다 한결 접근하기 쉽게 느껴졌고, 더 가볍고 편안하게 즐길 수 있었다.

손으로 그린 듯한 2D 아트 그래픽

그래픽은 ‘페이탈 클로’에서 상당히 눈에 띄는 부분이다. 전체적으로 2D지만 러프한 손그림 느낌이 강하면서 동시에 캐릭터와 배경 모두 애니메이션처럼 부드럽게 움직인다. 지하 왕국이라는 설정 때문에 배경은 어둡고 음침한 분위기가 강하지만, 키샤를 비롯한 캐릭터들은 꽤 귀엽게 그려져 있다. 이러한 분위기의 불균형함이 묘하게 잘 어울린다.

특히 키샤는 게임의 분위기를 너무 무겁게 만들지 않는 역할을 한다. 어두운 폐허를 돌아다니면서도 화면 한가운데에서 쫑쫑 움직이는 고양이를 보고 있으면 묘하게 긴장감이 풀리는 순간이 있다. 몸을 웅크리기만 해도 식빵을 굽는 듯한 자세가 나와서 그 모습 하나하나가 귀여웠다.

페이탈 클로 스크린샷 18
이런 포즈 하나하나에 어떤 고민을 했을지 느껴진다

개발진은 캐릭터와 배경을 수작업으로 제작했으며 생성형 AI를 사용하지 않았다고 밝히고 있는데, 실제 게임 화면에서도 이런 수작업 애니메이션의 느낌이 꽤 잘 살아 있다. 사운드 역시 분위기에 맞춰 ‘페이탈 클로’가 보여주려는 세계를 잘 살려주는 음악이라고 생각되었다.

페이탈 클로 스크린샷 16 페이탈 클로 스크린샷 17
점차 이 세계에 대해 알아가며 빠져드는 나 자신을 발견할 수 있다

빠르게 움직이고, 다시 돌아가는 재미

메트로배니아에서 중요한 건 결국 탐험이다. ‘페이탈 클로’ 역시 이 부분은 기본에 충실하다. 처음에는 갈 수 없는 길이 곳곳에 존재하고, 새로운 이동 능력을 얻으면 그 장소를 다시 찾아가야 한다. 대시가 필요했던 곳, 벽을 타야 했던 곳, 공중에서 더 멀리 이동해야 했던 곳이 하나씩 발견되며 다음 스테이지로의 문이 열리기 시작한다.

페이탈 클로 스크린샷 11 페이탈 클로 스크린샷 12

맵도 상당히 촘촘하게 연결돼 있는 편이다. 처음에는 길이 복잡해 보이지만 진행하다 보면 숏컷이 하나씩 열리고, 빠른 이동을 이용할 수 있게 되면서 이동 시간이 점점 줄어든다. 그래서 후반으로 갈수록 넓은 맵을 돌아다니는 것이 초반보다 훨씬 편해진다. 맵 자체도 탐험하는 만큼 자연스럽게 채워지는 방식이라 별도로 지도를 구매해서 해금할 필요가 없다. 드론을 이용해 특정 위치에 마커를 남길 수도 있기 때문에 아이템이나 다시 찾아가야 할 장소를 표시해두기도 편하다.

물론 메트로배니아를 오래 해온 사람이라면 지도 시스템 자체를 힌트로 활용해서 숨겨진 기믹이나 경로를 어렵지 않게 찾을 수도 있을 것이다.

‘페이탈 클로’는 처음부터 완전히 새로운 메트로배니아를 만들려던 게임은 아닌 것으로 보인다. 오히려 익숙한 장르의 재미를 가져오면서 좀 더 빠르고 가볍게 즐길 수 있도록 다듬은 쪽에 가깝다. 빠른 이동과 전투를 중심으로 게임의 속도감을 끌어올린 부분은 분명 ‘페이탈 클로’만의 장점이다.

무엇보다 고양이를 주인공으로 내세운 것도 꽤 재미있는 선택이다. 귀여운 외형과 달리 전투에서는 꽤 빠르고 거칠게 적을 베어버리는 모습이 은근히 잘 어울린다. 발톱이 제 얼굴만 하기도 하고 😂

페이탈 클로 스크린샷 15
하여튼 귀여운 고양이 주인공

빠르게 움직이며 적을 연속으로 몰아치는 액션을 좋아하고, 어둡고 신비로운 맵을 돌아다니며 숨겨진 길을 찾는 걸 좋아하는 게이머라면 ‘페이탈 클로’와 꽤 잘 맞을 것 같다.

익숙한 메트로배니아의 재미에 빠른 액션과 귀여운 고양이를 더한 게임. ‘페이탈 클로’는 딱 그 정도의 느낌으로 시작해서, 예상보다 훨씬 오래 붙잡고 몰입하게 만드는 게임이다.

바쁜 업무와 일상 속에서는 잠시 멈춰 숨을 고르는 시간이 필요하다. 컴투스 사내 차(Tea) 모임 ‘컴티스푼’은 은은한 차 향과 함께 이야기를 나누며 일상에 작은 여유를 더하는 동아리다.

차를 잘 알지 못해도 따뜻한 차 한 잔을 좋아한다면 누구나 편하게 참여할 수 있다. 말차와 홍차, 보이차, 허브티 등 다양한 차를 함께 나누는 컴티스푼의 활동을 소개한다.

함께 마시고 나누는 컴티스푼

컴티스푼에서는 차를 마시는 것을 시작으로, 다양한 차와 차 문화를 함께 경험할 수 있는 활동을 이어가고 있다.

혼자 사기 부담스러운 차도 함께, 차 구매 시스템

평소 마셔보고 싶었던 차나 혼자 구매하기에는 양과 가격이 부담스러웠던 차를 회원들과 함께 구매해 나눈다. 개별 구매와 공동 구매를 통해 여러 종류의 차를 부담 없이 맛볼 수 있다.

컴티스푼 회원들의 차 공동·개인 구매 목록

회원 1인당 매월 급여에서 1만 원이 차감되고, 회사 지원금 2만 원이 더해져 총 3만 원의 동아리 활동비가 마련된다. 이 가운데 5,000원은 공용 물품 구매와 이벤트 지원금, 분기별 외부 찻집 탐방 등에 사용하는 공용 회비로 적립한다. 나머지 2만 5,000원은 회원별 개인 활동비로 적립한다. 최근에는 이벤트와 모임 일정, 공용 회비와 개인 적립금을 한눈에 확인할 수 있도록 컴티스푼 전용 사이트도 만들었다.

컴티스푼 전용 사이트 화면

매월 한 번씩 만나는 정기 모임

컴티스푼은 매월 한 차례 정기 모임을 진행한다. 각자 소장하고 있는 차를 가져와 회원들과 나누거나 함께 시음하기도 한다. 각자가 좋아하는 차를 소개하고, 평소 접하지 못했던 차도 함께 맛본다.

컴티스푼 정기 모임에서 차를 나누는 회원들

맛과 향을 기록하는 차 리뷰

직접 마셔본 차의 맛과 향, 느낌을 자유롭게 기록하고 공유한다. 차를 처음 접하는 회원도 참고할 수 있도록 시음 기록과 추천 정보를 나눈다.

컴티스푼 회원의 차 시음 리뷰

차 관련 행사 참여 지원

차 박람회와 컨벤션 등 관련 행사 정보도 채팅방에서 수시로 공유한다. 관심 있는 회원들은 일정을 맞춰 함께 방문하며 새로운 차와 브랜드를 직접 접한다.

차 박람회와 컨벤션 행사 정보

행사에 다녀온 뒤에는 현장에서 맛본 차와 새롭게 알게 된 브랜드, 인상 깊었던 경험 등을 후기로 남긴다. 후기를 작성한 회원에게는 1인당 최대 2만 원의 활동 지원금을 지급하며, 작성된 후기는 다른 회원들이 차와 행사를 알아보는 데 참고 자료로 활용된다.

컴티스푼 회원이 작성한 차 박람회 후기

분기마다 떠나는 외부 찻집 탐방

3개월에 한 번은 사무실을 벗어나 외부 찻집을 찾아간다. 평소 눈여겨봤던 찻집에서 차를 함께 마시고, 티 클래스에도 참여한다. 차 전문가에게 차의 종류와 우리는 방법, 차를 즐기는 법 등을 배우며 차에 대한 이해를 넓힌다. 회원들과 각자의 취향과 경험을 나누는 시간도 가진다.

외부 찻집 탐방에서 차를 즐기는 컴티스푼 회원들

설문으로 알아본 컴티스푼 회원들의 차 취향

컴티스푼 회원들은 평소 어떤 차를, 언제 마실까. 회원들을 대상으로 차를 마시는 습관과 취향, 동아리에서 해보고 싶은 활동을 물었다.

컴티스푼 회원 차 취향 설문 결과

‘하루에 1~2잔’ 차를 마신다는 응답이 58.3%로 가장 많았고, 하루에 3잔 이상 마신다는 응답은 16.7%였다. 차를 가장 자주 마시는 시간은 출근 직후 33.3%, 오후 3~4시 25% 순이었다. 회원들에게 차는 하루를 시작할 때나 오후 업무 중 잠시 쉴 때 찾는 음료였다.

차를 고를 때 가장 중요하게 보는 기준은 맛 66.7%, 향 58.3%였다. 카페인 함량과 우려내기 편한 정도를 고려한다는 응답도 있었다. 좋아하는 차는 홍차가 58.3%로 가장 많았으며 우롱차가 41.7%로 뒤를 이었다. 말차와 허브티, 밀크티도 각각 33.3%를 기록했다. 한 종류만 고집하기보다는 기분과 상황에 따라 여러 차를 골라 마시는 회원이 많았다.

차를 마신 뒤 달라진 점으로는 ‘물을 더 많이 마시게 됐다’와 ‘차를 구매하는 데 돈을 더 쓰게 됐다’가 각각 50%로 나타났다. ‘다양한 향과 맛에 관심이 생겼다’는 답변도 41.7%였다. 차를 마시면서 새로운 종류와 브랜드에 관심을 갖게 된 회원도 많았다.

동아리에서 해보고 싶은 활동은 ‘차와 디저트 페어링’과 ‘유명 찻집 투어’가 각각 41.7%로 가장 많았다. 다도·티 클래스는 33.3%, 차 박람회 단체 방문과 블라인드 티 테스트는 각각 25%였다. 함께 차를 마시는 모임부터 차를 직접 배우고 비교해보는 활동까지 관심 분야도 다양했다.

컴티스푼의 가장 좋은 점으로는 ‘다양한 차를 맛볼 수 있어서’가 50%로 가장 많은 선택을 받았다. ‘외부 찻집이나 박람회를 함께 갈 수 있어서’는 25%, ‘혼자 사기 부담스러운 차를 함께 구매할 수 있어서’는 16.7%였다.

회원들에게 차 한 잔이 어떤 의미인지도 물었다. ‘잠깐의 휴식’이 33.3%, ‘업무 중 리프레시’가 25%였으며 ‘하루를 시작하는 루틴’, ‘맛있는 음료’, ‘취미’라는 답변도 나왔다.

컴티스푼에서는 각자 좋아하는 차를 나누고, 혼자 구매하기 부담스러웠던 차도 함께 맛본다. 찻집 탐방과 박람회, 티 클래스도 함께 다닌다. 회원들의 답변에서 드러나듯 차 한 잔은 이들에게 잠깐의 휴식이자 하루를 여는 루틴이다.

※ 설문에는 컴티스푼 회원들이 참여했으며, 복수 선택 문항은 응답률의 합계가 100%를 초과할 수 있다.

컴티스푼이 다녀온 공간들

컴티스푼은 정기 모임과 함께 외부 찻집 탐방과 차 관련 행사 참여도 진행하고 있다. 컴티스푼 회원들이 함께 다녀온 찻집과 차 행사를 소개한다.

가산 ‘지유명차’

가산 지유명차 내부와 차

장소 서울 금천구 지유명차 가산점

한 줄 평 깊고 그윽한 보이차를 맛볼 수 있는 곳이다. 차분한 분위기에서 편안하게 차를 마시기 좋다.

Tip 최대 5명까지 이용할 수 있는 아늑한 공간이다. 사장님이 직접 내려주는 보이차를 마시며 편안하게 이야기를 나눌 수 있다.

컴티스푼 회원이 다녀와서 쓴 후기

가산 지유명차 티클래스 후기: 차(茶)에는 낭만이 있다

대림 ‘온각찻집’

대림 온각찻집 내부와 차

장소 서울 영등포구 대림동

한 줄 평 이국적인 차 문화와 다양한 차를 접할 수 있는 공간이다. 감각적인 인테리어와 색다른 차 구성도 눈에 띈다.

Tip 여러 종류의 차를 주문해 함께 방문한 회원들과 조금씩 나눠 마시는 것을 추천한다.

국제차문화대전

국제차문화대전 현장

장소 서울 강남구 삼성동 코엑스

한 줄 평 평소 접하기 어려웠던 다양한 차를 한자리에서 만나고 차에 관한 설명도 직접 들을 수 있었다. 차에 관심이 있다면 방문해볼 만한 행사다.

Tip 차 시음이 처음이라 어색하더라도 주저할 필요는 없다. “차 한 잔 부탁드립니다”라고 편하게 말하면 다양한 차를 직접 맛볼 수 있다.

컴티스푼 회장에게 물었다

Q. ‘컴티스푼’을 만든 계기가 궁금해요.

A. 처음에는 말차에 흥미를 느끼면서 시작됐어요. 말차를 마시다 보니 자연스럽게 차를 좋아하는 사람들과 함께 마시고 싶어졌고, 예쁜 찻집도 같이 다녀보고 싶어 동아리를 만들게 됐습니다. 말차로 시작했지만 지금은 홍차와 보이차, 허브티 등 다양한 차를 즐기고 있어요.

Q. 현재 회원 구성은 어떻게 되나요?

A. 현재 총 26명의 회원이 함께하고 있습니다. 차를 잘 아는 분부터 이제 막 차에 관심을 가지기 시작한 입문자까지 다양하게 참여하고 계세요.

Q. 동아리의 주요 활동은 무엇인가요?

A. 기본적으로는 ‘차를 즐겁게 마시는 것’이에요. 차를 함께 구매하거나 추천하고 후기를 나누며, 매월 정기 모임에서 차 나눔을 진행할 때도 있습니다. 차를 나눠주시는 회원분들께 늘 감사한 마음이에요.♥️ 3개월에 한 번은 외부 찻집을 탐방하고, 차 관련 행사가 있을 때는 지원금을 활용해 참여하기도 합니다.

Q. 모임 장소와 시간은 주로 어떻게 되나요?

A. 주로 점심시간을 활용해 사내 카페나 휴게 공간에서 모입니다. 모두 바쁜 업무 중에 시간을 내어 참여하는 만큼, 저녁 늦게 모이거나 부담을 주는 일정은 잡지 않으려고 해요. 각자의 일상에 방해가 되지 않는 선에서 편안하게 운영하고 있습니다.

Q. 앞으로의 계획은 무엇인가요?

A. 앞으로는 조금 더 멀리 나가 차를 즐기는 야외 활동도 기획하고 있어요. 다도에 관심 있는 분들을 위해 차 클래스나 다도를 배워보는 시간도 마련해보려고 합니다. 동양차뿐만 아니라 애프터눈 티처럼 서양식 차 문화를 접하는 자리도 꾸준히 준비할 예정이에요. 동아리가 점점 커지는 만큼 다 같이 즐길 수 있는 다양한 이벤트도 준비해볼게요!

차를 처음 접한다면? 입문자용 차 추천

차를 처음 접하는 사람을 위해 컴티스푼 회장이 직접 마셔본 제품을 추천했다.

오설록 ‘차의 정원 9종 27입’

여러 종류의 차를 조금씩 맛볼 수 있는 티 세트다. 컴티스푼을 만들고 처음 구매했던 제품이기도 하다. 다양한 맛을 비교해보며 자신의 취향에 맞는 차를 찾아보기 좋다.

▶ 오설록 차의 정원 9종 27입

오설록 차의 정원 티 세트

BUBUTI ‘운남 보이숙차 티백’

지유명차에 다녀온 뒤 보이차에 대한 관심이 커졌을 때 차 관련 행사에서 시음하고 구매한 제품이다. 잔잔하고 은은한 맛이며 차갑게 우려 마실 수도 있다. 티백 제품이라 별도의 다구 없이 간편하게 마실 수 있다.

▶ BUBUTI 무이암차 우롱·운남 보이숙차 티백

BUBUTI 운남 보이숙차 티백

보성 소아다원 ‘말차·유기농 쑥차 분말’

차 관련 행사에서 시음한 뒤 구매한 제품이다. 전남 보성의 소아다원에서 생산한 말차와 유기농 쑥차 분말을 비교적 부담 없는 가격에 구매할 수 있다. 어떤 말차를 골라야 할지 고민된다면 소아다원의 유기농 말차부터 마셔보는 것도 좋다.

▶ 보성 소아다원 말차 100g

▶ 보성 소아다원 유기농 쑥차 분말·홍차 분말

보성 소아다원 말차와 쑥차 분말 제품

컴티스푼 회원들의 한마디

회원들에게 차를 마시며 느끼는 점과 컴티스푼 활동에 관한 이야기를 들어봤다.

“차를 마시고 나의 행복시대 시작됐다~! 하루에 힐링할 수 있는 활동이 하나 더 생겨 행복합니다.”

“차를 마시면서 마음의 평안을 찾아보세요!”

“차를 좋아해서 가입했지만, 컴티스푼 덕분에 차에 대해 더 많이 알게 되고 매력에 빠져가는 중입니다!”

“차를 자주 마시면서 자연스럽게 하루 음수량도 늘릴 수 있어 좋아요.”

“차를 내리는 모습도 힐링이고, 따뜻한 온기를 느끼며 마시는 기분도 정말 좋습니다.”

“바쁜 일상 속에서 무해한 사람들과 함께 즐기는 차 한 잔의 여유!”

“맛있는 차를 잔뜩 마실 수 있어 행복해요.”

“기본 차부터 가향차까지 종류가 정말 다양해요. 칼로리 부담 없이 여러 맛을 경험할 수 있다는 점도 행복합니다!”

“가장 빠르고 쉽게 즐길 수 있는 힐링이에요.”


바쁜 업무 중 차 한 잔의 여유를 즐기고 싶다면 컴티스푼의 문을 두드려보자. 차를 잘 몰라도 괜찮다. 따뜻한 차를 좋아하고 회원들과 함께 마셔보고 싶은 마음만 있으면 누구나 편하게 참여할 수 있다.

가입 문의 캐릭터원화2팀 남혜인 선임


TOP