Part 1. DevOps 란 무엇일까?
DevOps란 무엇일까?...
이 글을 작성하고 있는 지금 시점에서 저는 Streami 회사에서 1년 4개월 동안 DevOps Engineer로 근무를 하고 있습니다.
하지만 아직까지도 DevOps의 정의를 설명해 보라고 누군가 질문 한다면 정확히 말할 자신이 없습니다.
(단순 개발과 운영을 합친 포괄적인 의미로 설명하고 싶지 않습니다.)
하여 이 글을 통해 생각을 정리해보고자 합니다.
DevOps
DevOps는 Development & Operations의 합성어로 전채적인 개념을 보자면 개발과 운영을 합쳐놓은 것입니다.
또한 해당 용어는 Engineer의 뜻도 가질 수 있지만, 철학적인 뜻으로 설명되는 경우도 많습니다.
우선 철학적인 뜻으로 설명을 하자면...
지속적 통합 / 지속적 배포(CI/CD)를 통해 안정적이고 안전한 소프트웨어의 신속한 릴리스를 보장하는 것을 목표로 하는
포괄적인 개념 및 문화입니다. 때문에 DevOps하면 애자일(Agile)이 항상 붙어 오는 이유도 이 이유입니다.
애자일(Agile)에 대해 간단히 설명하자면, 애자일은 '민첩한' 이란 뜻으로
IT세상의 변화에 민첩하게 대응하고자 생긴 개발 프로세스 입니다.
때문에 개발주기를 짧게 가져가면서 지금 현재 우리 서비스에 필요한, 보완해야할 것들에 대해 TASK를 만들고 정해진 기간내에
빠르게 개발하는 것을 목표로 합니다. TASK 단위는 상당히 쪼개어, 크게 가져가는 것이 아닌, 작게 가져가는 것을 목표로 합니다.
(예를 들어 3일만에 해야할 일은 쪼개서 하루 단위로 나눈다던지 등...)
이렇게 개발주기가 짧아질수록 Production(운영환경)에 배포가 자주 이뤄져야 하는데,
이 배포 파이프라인을 구축하는 것이 DevOps의 대표적인 역할중 하나입니다.
또 하나의 철학적 의미는 "Development 와 Operations의 간극을 줄인다." 입니다.
그럼 Development와 Operations의 차이점은 무엇일까?
저는 Operations이 많이 했갈렸습니다. 제가 회사에서 하고 있는 일이 대부분 Operations이기 때문에,
Operations을 전담으로 하는 팀이 있는 회사에선 DevOps와 뭐가 다른건지? 에 대한 의문을 계속해서 품어왔기 때문입니다.
Googling을 통해 찾아보고, 주변 친구들에게 물어본 결과 저만의 결론을 도출할 수 있었습니다.
(해당 결론은 나중에 바뀔 수도 있으니 참고만 하시면 될 것 같습니다.)
애초에 Operations Team은 Cloud환경 이전부터 존재해 왔으며, On-Premise 환경에 좀 더 어울리는 Team이라 생각을 합니다.
상상을 해봅시다.
On-Premise환경인 회사에서 개발자가 Production(운영 환경)에 코드를 배포했는데, 오류가 발생했습니다.
해당 코드는 테스트 코드도 모두 통과하였으며, Staging기간 동안에 아무런 이상이 없었습니다.
개발자는 자신에 코드에 이상이 없다고 확신하고 있습니다. 해당 개발자는 무엇부터 의심을 할까요?
운영팀에서 해당 코드가 배포되기 전까지 아무런 이상이 없이 잘 되었습니다.
하지만 개발자가 코드를 배포한 후 문제가 생겼습니다.
운영팀은 무엇을 먼저 의심할까요?
결국엔 개발자 vs 운영팀에서 박터지게 싸우게 될 것입니다. 누가 문제인지를....
여기서 DevOps의 역할은 이 둘의 간극을 최대한 줄이는 것입니다. 확실한 데이터를 통해서요.
그래서 모니터링이 필요한 것입니다. 네트워크 트래픽적으로 문제가 없는지, 트랜잭션에서 에러를 뱉고 있지는 않은지, 코드단에서 에러를 뱉고있지는 않는지 등... Metric을 통해 이를 판단하고 원인을 빠르게 찾아야 합니다. 사실 이건 DevOps의 개념보다도 SRE의 개념에 가깝습니다. 때문에 DevOps의 문화 특징중 하나인 투명성이 보장되어야 합니다. 각 팀간의 커뮤니케이션도 요구가 되고요.
그리고 이런 오류가 났을 때 이를 자동화시켜 해결할 수 있도록 해야 합니다.
최대한 팀원들이 효율적으로 일할 수 있는 환경을 구성하는 것이죠.
사실 DevOps의 문화를 정의하는 것은 쉽지 않은 것 같습니다. 각 회사마다 정의하는 기준은 비슷할지 몰라도 세부적으로는 약간의 차이를 갖고 있습니다. 그리고 이 정의한 DevOps문화를 기준으로 DevOps Enginner의 역할도 나뉘는 것 같습니다.
현대에서는 Operations Team이라는 개념은 많이 사라지고 있는 것 같습니다.
Cloud시대로 넘어오면서 On-Premise 환경은 사라지고 있으며, 개발자, DevOps Engeinner도 손쉽게 Operation 단계를 할 수 있기 때문입니다. (Cloud에 장점 중 하나는 바로 Operation을 그들에게 맏길 수 있다는 점입니다. 하드웨어, 그와 연관된 이슈 처리 등...)
DevOps의 역할중 하나인 IaC를 통해서 인프라를 관리하게 되고, 자동화, 이중화 작업을 통해서(auto scaling, zero downtime, MSA etc...) Operation이 DevOps라는 거대한 문화적 기술에 흡수되고 있는 것 같습니다.(이 부분은 제 개인적인 생각과 의견이 담겨 있으며, 사람마다 다르게 생각할 수 있습니다.)
DevOps Enginner는 무엇을 해야 하는지 나열해보겠습니다.
1. CI / CD
앞서 말씀드린 CI / CD 입니다. 단순하게 CI / CD를 구축할 수 있습니다.
하지만 DevOps Enginner라면 이를 좀 더 구체화 시키고 세분화 시켜야 합니다.
CI(Continuous Integration)에서 어떤 작업이 들어가야 할까?
개발자가 단순히 Code review를 마치고 Master branch에 Merge하면 끝일까?
통합이란걸 단순하게 생각하면 위 개념대로 Master branch에 Merge되면 끝입니다.
하지만 Merge되기 까지 어떻게 할지가 중요합니다. 정적 코드분석을 통해서 Human Error를 잡고,
Code의 Syntex를 맞추고, 팀간의 정해진 Role에 따라 Code quality를 항상 유지해야 합니다.
또한 테스트 케이스를 모두 통과되어야 하죠.(자동으로)
이런 구조를 만드는 것이 CI를 구축하는데 있어서 필요한 작업입니다.
CD(Continuous Delivery)에서 어떤 작업이 들거아야 할까?
CI를 통해 Master branch에 무사히 Merge되었다고 합시다.
"수정된 코드를 언제 배포할 것인가요?"
"누가 배포할건가요?"
"배포하다 실패하면 어떻게 할건가요?"
"빌드 과정에서 에러가 난다면 어떻게 하실건가요?"
"배포도중 배포되는 코드의 순서가 바뀌어서 에러가 난다면 어떻게 하실건가요?"
"배포자의 실수로 10가지 변경사항에 대해 배포 하다가 9가지만 배포하게 되면 어떻게 하실껀가요?"
DevOps에서는 이러한 문제에 대해 자동화시켜야 할 줄 알아야하고,
사람이 직접 배포하지 않고 Jenkins같은 툴을 이용해서 구축해야 합니다.
그리고 DevOps문화를 가지는 회사일수록 배포는 자주 하게되고,
이걸 사람이 직접하면(예를 들어 코드 작성한 개발자라던지, 팀원들을 Rotate하여서 돌릴것인지 등..)
소모되는 인적 자원, 실패에 대한 시간 소모 등을 겪어야 합니다.
2. IaC
DevOps에서 IaC(Infrastructure as Code)는 중요합니다.
코드로서 인프라를 관리하게 된다면, 여러가지 이점이 있습니다.
1. 변경사항이 있을 때 빠르게 확인이 가능하다.
2. 코드로 관리되기 때문에 협업하는데 좋다.
3. 어느 리소스가 무슨 리소스를 사용하고 있는지 파악하기 용이하다.
4. Create, Update, Delete가 쉽다.(유지보수에 용이하다.)
5. Yaml같은 경우 주석을 통해서 이 리소스가 왜 만들어 졌는지 알 수 있다.
이 외 여러가지 이점이 있습니다. Terraform으로 작성된 경우 모듈화를 시켜서 좀 더 보기 편하게 모을 수 있다던지 등...
또한 코드로 관리되기 때문에 Auto scaling도 용이합니다.
이 모든 것이 Cloud환경으로 넘어오면서 가능해진 것입니다.
3. 모니터링
모니터링을 구축해야 합니다. 여기서 모니터링은 배포에 대한 모니터링을 의미 합니다.
배포까지의 걸리는 시간, 오류율, 빈도 수, 배포 실패시 복구되는데 까지 걸리는 시간 등...
자세한 설명은 "DevOps vs SRE" 파트에서 다루도록 하겠습니다.
4. 그 외 것들
제가 앞서 현대의 DevOps는 Operations 을 포함하는 개념이라고 했습니다. 그 이유는 Cloud환경으로 넘어오면서 하드웨어적인 부분을 관리하는 것이 아닌, IaaS, PaaS 수준의 서비스를 제공받음으로 써 아키텍처를 구성하고, 모니터링하며, 만들어진 리소스를 잘 가져다 사용하면 됩니다. 그걸 잘 다룰 수 있게 해주는 것이 IaS이구요.
결국 DevOps가 Infra를 관리하게 되면서, 자연스럽게 운영적인 측면을 담당하게 됩니다. 결국 운영을 담당한다는 것은,
회사의 어플리케이션을 돌리는 서버를 관리해야 한다는 뜻이며, 모니터링을 통해서 이상징후를 빠르게 파악해야 합니다.
그러기 위해선 다음을 잘 할줄 알아야 합니다.
- Linux
서버들은 보통 Linux위에서 돌리게 됩니다. 그럼 해당 Linux에 대한 설정, 로그, 사용자 분리 등을 할줄 알아야 합니다.- 설정은 Linux time을 어떻게 동기화 시킬 것인지, Iptables같은 응용프로그램을 어떻게 셋팅할 것인지, Linux에서 돌고 있는 어플리케이션이 죽었을 때, 어떻게 다시 refresh시킬 것인지 등...
- 로그는 문제가 생겼을 때, 해당 로그를 어떻게 신속, 정확하게 찾아서 파악할 것인지에 대한 것입니다.
응용프로그램을 돌릴 때, 로그를 어느 위치에 쌓을 것인지, 수 천 ~ 수 만줄 짜리 로그에서 내가 원하는 Error부분을 찾을 수 있는지, 로그들을 파싱해서 메트릭을 만들어내고 이를 시각화하여 좀 더 편하게 모니터링을 구축한다던지 등..
또한 해당 서버에 접속한 User들에 대한 로그 기록도 남겨야 합니다.(잘못된 접근, 해킹에 대한 위험 등...) - 사용자 분리는 말그대로 User를 나누는 것을 말합니다. 서버에 회사 응용프로그램이 돌아간다는 것은 결국, 서비스를 제공하는 어플리케이션이 돌고 있다는 뜻이고, 이 프로그램이 잘못되면 우리 회사 서비스를 이용하고 있는 고객들에게 불편함을 주게 됩니다. 결국 고객들에게 실망을 주게되고, 신뢰를 잃게되는 결과를 낳게 됩니다.
이런 중요한 서버에 아무나 접근하면 당연히 안되므로 접속할 수 있는 User를 제한하고, 권한을 제한해야 합니다. 때문에 특정 User들을 그룹단위로 묶거나 sudo명령어를 제안하는 등 설정이 필요합니다.
- Troubleshooting
Infra를 관리한다면 Infra가 설계에 맞게 셋팅 되었는지 잘 확인해야 합니다. Cloud환경에서 가장 어려운점 중 하나는 Trobleshooting입니다. 어느 구간에 문제로 인해 통신이 안되고 있는지 파악하기 어렵기 때문입니다. AWS를 많이 사용하는 입장에서 예시를 들자면 여러가지 경우가 있을겁니다. 보안그룹이 잘 열려있는지, 서브넷 설정은 잘 되었는지, 라우팅 테이블은 이상이 없는지, ACL도 이상이 없는지, VPC peering이 잘못되었는지, iptables 때문에 막혀있는지, IAM권한에는 문제가 없는지, DNS는 잘 찾는지 등...
물론 AWS에서 이를 해결하기 위한 Troubleshooting도구를 제공하긴 합니다. 하지만 저는 잘 사용하고 있지 않습니다. (별로 효율적이지 못합니다.) 때문에 문제가 생기면 손수 단계를 밟아 가면서 문제가 되는 지점을 파악하고 해결하고 있습니다.
더 나아간다면 이런 Troubleshooting을 자동으로 해주는 Tool개발도 필요합니다. - Migration
운영을 하다보면 Migration을 해야할 경우도 있습니다. 이럴 경우 Migration을 했을 때 데이터 정합성을 어떻게 점검할 것인지, 상위 호환성, 하위호환성을 잘 지켰는지, 마이그레이션 후 컬럼을 확인할 수 있는 User들을 제한한다던지 등... 확인해야할 것들이 많습니다.
사실 Migration은 DevOps혼자서 하기보단 Data enginner, Software developer와 같이 논의 후 진행하는 것이 가장 이상적인 방법입니다. Migration후 기존 Business code가 잘 도는지, ETL이 구축되어 있다면 호환성에 문제가 없는지 등... 여러가지 Test, Checking 을 진행하면서 이상유무를 판단해야 합니다. DevOps는 데이터를 어떻게 안전하고 빠르게 Migration을 할 수 있을지 생각하고 판단하여 실행에 옮겨야 하죠. - Script
자동화를 할 때 가장 필요한 것은 Script를 짜는 능력이라고 생각합니다. Linux에서 가장많이 사용되는 Script는 Shell script이고, Shell script를 얼마나 Graceful하게 만드느냐에 따라서 Code의 line수가 많이나게 됩니다. 또한 Shell script는 가독성이 좋은 Script가 아니라서 얼마나 가독성 있게 만드느냐도 중요합니다. 그 밖에 Jenkins의 Pipeline을 만들때도 Jenkins script를 사용하면 좀 더 효율적으로 만들 수 있고, Dockerfile, gradle 등... Script를 사용해야 할 곳이 너무도 많습니다. - Programming
DevOps라면 Programming은 할 줄 알아야 한다고 생각합니다. 모니터링을 구축할 때, Noti를 주는 프로그램을 만들 때, 원인이 되는 코드를 파악할 때 등... Script로 할 수 있는 것은 한계가 있으며, 이를 극복하기 위해선 Python, Javascript등을 이용한 Programming이 필요합니다. 개인적으로 공부를 하면서 느낀것은 OOP보단 Functional 한게 DevOps Programming방식에 맞는다는 생각을 합니다. 물론 거대한 Tool을 만든다면 재사용성, 추상화 등이 필요하지만 그 외적인 기능들은 (Noti를 주거나 Metric을 생성한다거나 등...) 데이터, 계산, 액션으로 나눠서 연속된 파이프라인을 타고 코드가 실행되는 것이 간결하고 깔끔하다는 느낌을 많이 받았습니다. (이건 Business code도 마찬가지라 생각합니다.)
물론 정답은 없지만 DevOps에서 필요한 Code를 짜야한다면, 저는 Functional하게 짜는 방향으로 갈 것 같습니다. - Kanban
DevOps는 애자일하게 운영되어야 합니다. 애자일에 방법은 Scrum과 Kanban, eXtreme Programming(XP)등이 있습니다.
이중 DevOps는 Kanban에 좀 더 적합하다고 생각을 합니다. Scrum이나 XP같은 경우에는 고객에 요청에 따라 매번 백로그에 Task들이 바뀌게 되지만 DevOps같은 경우에는 고객에 요청에 따라 Business logic을 만드는 것이 아니기 때문에 일정을 두고 정해진 목표를 향해 운영되어야 합니다. 때문에 계획(To-do), 진행중(Doing), 완료(Done)형태를 띄어야 하며, 업무 프로세스에 따라 계획이나 진행중이 바뀌어야 합니다. 실제로 DevOps는 유지 및 관리 측면에 치우처져 있고, 팀 내에서 개발자들이 개발에 집중할 수 있도록 환경을 구축하는 것이 중요하므로 Kanban이 좀 더 적합하다고 생각합니다.
마치며...
이 글을 쓰면서 저의 주관적인 생각이 많이 들어갔다고 생각합니다.
이 글을 쓰게된 계기또한 "내가 현재 DevOps적인 일을 하고 있는가?" 라는 의문에서 시작한 것입니다.
이렇게 정리해서 나열해보았을 때 DevOps는 굉장히 매력적이고 해야할 일들이 많은 직업이라 생각합니다.
하지만 현실은 그렇지 않을것입니다. 좋게 보면 DevOps고 나쁘게 보면 그냥 잡부(IT)가 되는 것이라 생각합니다.
개발과 운영의 어중간한 포지션에 속하게 되면서 개발 외적으로 생기는 문제들에 대해서 전부 DevOps가 일을 가져가야 하기 때문입니다.
제가 생각했을 때 DevOps에 궁극적인 목표는 개발자들을 Support해주는 거라고 생각합니다. 즉, 개발자가 개발에 집중할 수 있게끔 환경을 만들어 주는 것이죠. 때문에 DevOps로 목표를 정했다면 DevOps문화가 확실하고, 겸임이 아닌 개발과 DevOps 의 역할이 정확하게 분리되어 있는 회사를 가는것이 좋습니다.
분리가 안되어 있으면, 분리할 수 있도록... 즉, 자신의 의견을 내고 개선할 수 있는, 열려있는 회사로 가는게 좋습니다.
(물론 개발도 해야 하지만 맛보기 식으로 이것저것 하지 말라는 겁니다. DevOps에서 개발도 무척 중요합니다.)
물론 이 역할을 분리하는 것이 쉬운게 아닙니다. 저도 경험이 별로 없어서 이를 명확하게 나누는 기준을 잘 모르겠습니다.
실제로 제가 하고 있는 일이 역할이 분리된 일인지에 대한 확신이 없습니다. 아닌 것 같으면서도 맞는 것 같거든요.
하지만 이 글을 작성하면서 DevOps라면 해야할 일, 방향성 등을 정리한 것 같고, 저만의 기준선을 세우는데 도움이 된 것 같습니다.
저희 회사 시니어분중 한분이 이런 말씀을 하셨습니다.
"땅을 넓게 파냐 깊게 파냐는 중요하지 않다. 땅을 팔 면적을 보는게 중요하다."
DevOps같은 직군은 스팩트럼을 넓혀서 다양한 경험을 쌓는게 중요하다고 생각합니다.
그 후 방향성이 결정된다면 깊게 파고들어 전문성을 기르는것이 어떨까? 라는 생각이 들었습니다.(신입, 주니어라면 더더욱...)