제공 :
한빛 네트워크
저자 : Mike Loukides
역자 : 이덕준
원문 :
What is DevOps?
아드리안 콕크로프트(Adrian Cockcroft)는
넷플릭스의 무운영(NoOps)이라는 기사로 몇 달간 타오른 논쟁의 불씨를 지폈다. 아드리안의 기사에 대한 존 올스포(John Allspaw)의 상세한 답변의 핵심은 다음과 같다. 아드리안이 "무운영"이라고 설명한 것이 실제로는 그렇지 않다는 것이다. 운영은 없어지지 않는다. 책임은 시간이 흐름에 따라 전이될 수 있으며, 전이되고 있다. 구인 공고도 마찬가지다. 책임을 어떻게 나누던지, 할 일은 여전히 해야하고, 그런 일 중 하나가 바로 운영이다. 아드리안이 넷플릭스의 무운영이라고 부르는 바로 그것이 Etsy의 운영과 전혀 다른 것이 아니다. 여기에서 질문을 하나 던져보자. 21세기의 "운영"은 무엇을 의미하는가? 무운영이 운영을 운영과 아주 유사한 무엇으로 대체하려는 움직임이라면, 혼란을 피할 수 없다. 논란으로 인한 격정이 가라앉은 지금, 운영이란 무엇인지, 시간이 흐름에 따라 어떻게 변하는지 더 잘 이해할 때가 되었다.
얼마전 존과 점심을 같이 할때, 그는 다음과 같이 말했다. 컴퓨터 시대의 여명을 돌아보면, 개발과 운영의 구분이 없었다. 개발을 했건 운영을 했건, 테이프를 마운트하고 전면 패널에서 스위치를 켜고 껐을 것이며, 문제가 발생하면 재부팅을 했고, 어쩌면 타버린 진공관을 교체했을 수도 있다. 괴짜스러운 하얀 연구복을 입어야 했을지도 모른다. 개발과 운영이 나뉜건 60년대 부터인데, 프로그래머나 분석가가 여러 상자의 천공카드를 판독기에 부어넣으면, "컴퓨터 운영자"는 유리벽 뒤에서 IBM JCL(작업 제어 언어)에 따라 마운팅된 테이프 사이를 종종걸음으로 다녔다. 그리고 운영자가 라인 프린터의 출력물을 이름표가 붙은 보관함에 밀어넣어주면, 거기에서 각자의 이름 아래 쌓인 결과물을 받아 볼 수 있었다.
70년대의 미니컴퓨터와 80년대의 PC의 도래로 인해 메인프레임 운영자와 사용자의 벽이 세분화되어서 1980년대와 90년대의 시스템 관리자와 네트워크 관리자가 등장했다. 이게 바로 현대의 "IT 운영자" 문화의 탄생이다. 미니컴퓨터 사용자는 위험하기에 딱 좋을만큼의 지식을 가진 컴퓨터 전문가이곤 했다(새로온 임원에게 루트 패스워드를 주고 "본인 계정을 만드세요"라고 했더니 30여명의 사용자가 나누어 쓰고 있는 VAX를 바로 망가뜨렸던게 기억난다). PC 사용자는 네트워크가 필요하고, 지원이 필요하며, 파일 서버나 메일 서버와 같은 공유 자원이 필요하다. 그리고 물론, "빌어먹을 운영자"(BOFH,
"Bastard Operator from Hell")같은 소설이 요즘의 세태를 상기시켜준다. 조금 다른 방식으로, 그런 문제를 가진 사람은 당신 말고 "아무도" 없다는 얘기를 들었는데, 모든 이가 바로 동일한 문제를 가졌다는 사실을 회의를 하기 전까지 알지 못했던 일이 기억난다. 우리가 운영이 사라지길 바란다는데에 의심의 여지가 없으며, 특히, 이론적으로, 개인용 컴퓨터와 데스크톱 워크스테이션의 발전이 우리 모두가 우리 개인의 머신에 대한 책임이 있다는 것을 의미하는 그 때부터 개발자와 시스템 관리자 사이의 벽이 있기를 바랐다는데에 의심의 여지가 없다.
하지만 누군가는 갈수록 더 중요해지는 웹사이트를 포함한 기반 체계를 운영해야한다. 회사와 전산 설비는 커지는데 반해 많은 시스템 관리자의 장애 대응에 대한 인식은 확장되지 않고 있다. 회사 전체가 386 한 대에서 운영되던(1990년도의 오라일리 같은) 때에는, 아무도 모르는 명령행 주문을 외워대는 것이 문제를 고치는 적절한 방법이었다. 하지만, 랙스페이스(Rackspace)나 아마존(Amazon)과 같이 수 백, 수 천대의 노드에 대해 얘기할 때에는 이런 방식은 통하지 않는다. 운영의 입장에서, 웹에 대한 화두는 브라우저에서 돌아가는 완전한 응용 프로그램으로의 진화가 아니다. 한 대의 서버에서 수십, 수백, 수천, (구글이나 페이스북의 경우에는) 수백만대의 서버로 성장하는 이야기다. 그런 규모의 운영을 하게되면, 명령 행에서 문제를 해결하는 방법을 선택할 수 없다. 추가적인 수정이나 패치에 대해 동기화가 되지 않은 장비를 그냥 두고 볼 수가 없다. "125대의 서버를 즉시 온라인에 붙여야하는데, 자동화할 시간이 없습니다"라는 소리를 듣는다는 것은 재난으로 가는 비결이다.
이 문제에 대한 운영 커뮤니티의 응답은 놀랍지 않았다. 오라일리의 벨로시티 컨퍼런스의 주제 중 하나는 "코드로써의 기반 체계(Infrastructure as Code)"였다. 안정적으로 운영하려면, 이를 재생산하고 프로그래밍 가능하게 만들 필요가 있다. 그런 이유로, 가상 머신이 소프트웨어를 설정 이슈에서 보호해준다.
Puppet과
Chef가 설정을 자동화해주고, 모든 머신이 똑같은 소프트웨어 설정이 된 채로 올바른 서비스를 구동하고 있음을 알 수 있다.
Vagrant가 모든 가상 머신이 처음부터 똑같이 구축되었음을 보장해주고, 자동화된 모니터링 도구가 클러스터가 모두 적절하게 돌아가고 있음을 알려준다. 노드가 사설 데이터 센터에 있는지, 호스팅 설비나 공용 클라우드에 있는지 여부는 중요치 않다. 이들을 관리하는 소프트웨어를 만들지 않으면 살아남을 수 없다.
게다가, 전통적인 하드웨어 서버나 네트워크에서 멀어질수록, 모든 단계에서 가상화된 세상으로 가면 갈수록, 구식의 시스템 관리는 중단되기 시작할 것이다. 물리적인 장비실의 물리 장비는 사라지지 않겠지만, 더 이상 그것만이 시스템 관리자가 신경써야 할 전부가 아니다. 동일 장소 배치 설비에서 가상 인스턴스의 루트 디스크 드라이브가 어디 있을까? 가상 스위치의 네트워크 포트는 어디에 있을까? 물론, 90년대의 시스템 관리자는 이런 자원을 소프트웨어로 관리했다. 펄 스크립트 포트폴리오가 없는 시스템 관리자가 제 값어치를 하는 일은 없었다. 차이점은 이제 네트워크 포트, 디스크 드라이브 또는 CPU 같은 자원 자체가 물리적인 자원일 수도 있고, 손으로 가리키거나 제거할 수 있는 물리적인 장치와는 상관 없는 소프트웨어일 수도 있다는 것이다. 이렇게 계층화된 자산을 관리하는 효과적인 방법은 소프트웨어를 통하는 것 뿐이다.
그래서 기반체계는 코드가 되어야한다. 위에서 언급한 펄 스크립트는 80년대 후반부터 이미 기반체계가 코드가 되고 있음을 보여준다. 사실상, 펄은 시스템 관리를 자동화하는데 사용하기 위해 설계된 프로그래밍 언어였다. 앞선 기술의 시스템 관리자가 손수 작성한 설정과 재생산 불가능한 주문이 그들의 장비를 운영하는데 나쁜 방법이라는 것을 깨닫게 되는데까지 그리 오래 걸리지 않았다. 이런 경향이 아마존이나 랙스페이스 때문에 시스템을 랙에 올리는 일이 줄어든, 전통적인 시스템 관리자의 종말이라고 할 수도 있다. 그러나 이는 성장하기를 거부하고 컴퓨팅 업계의 발전을 받아들이기를 거부하는 시스템 관리자의 운명일 뿐이다. (그리고 적응을 거부한 시스템 관리자는 BOFH 협회의 수를 늘릴 것이며, 우리 대부분은 그들이 떠나는 것을 보면서 기뻐할 것이다.) 좋은 시스템 관리자는 자동화가 관리 업무의 일부 요소임이 확실하며 자동화를 채택하는 일이 보다 더 중요해 질 것이라는 것을 항상 알고 있었다. 새로운 시스템 관리자는 머신을 끄거나 고장난 디스크 드라이브를 교체하고 재부팅하고 백업해둔 디스크에서 복구하는 일을 하지 않을 것이다. 새 관리자는 EC2 인스턴스가 오작동하고 있는 것을 자동으로 찾아내서 불량 인스턴스를 종료시키고 새로운 인스턴스를 생성시키고 구성하며, 서비스 중단 없이 이 모두를 수행하는 소프트웨어를 작성할 것이다. 이 정도 수준의 자동화를 해두면, 새로운 "운영자"는 수십대의 시스템을 책임지게 되던지, 만여대의 시스템을 책임지게 되던지 신경쓰지 않을 것이다. 현대의 BOFH는 변화를 수용하지 않기로한, 구식의 시스템 관리자일 가능성이 더 높다.
제임스 어쿼트(James Urquhart)는 클라우드에서 돌아가는 요즘 애플리케이션에 여전히 회복력과 내구성이 필요하며, 모니터링이 필요하고, 크게 변하는 부하에 대응할 필요가 있음을 설명하면서 이를 확실히 했다. 그러나 그는 예전에는 IT/기반 체계 운영에서 제공된 이런 기능들이 이제는 애플리케이션의 일부가 되어야하며, 특히 "서비스로서의 플랫폼(Platform as a service)" 환경이 되어야 한다고 언급했다. 운영은 사라지지 않으며, 개발의 일부가 된다. 빅 데이터, 웹 성능 최적화, 애플리케이션 미들웨어, 어마어마하게 분산된 환경에서의 내구성을 이해하고 있는 최고의 개발자 따위를 마음에 그리기 보다, 개발 팀에 있는 운영 전문가가 필요하다. 기반 체계는 사라지는 것이 아니며, 코드로 옮겨간다. 그리고 기반 체계, 시스템 관리자 및 기업의 IT 부서를 담당한 사람들은 발전해서 그들의 기반 체계를 유지할 수 있는 코드를 작성할 수 있다. 고립되기 보다는, 애플리케이션을 만든 개발자와 협동하고 협력할 필요가 있다. 이런 움직임이 비공식적으로 알려진 "개발운영(DevOps)"이다.
작년 아마존의 EBS 중단 사건은 "운영"의 성격이 어떻게 바뀌고 있는지를 잘 보여준다. 많은 손실을 입고 고생한 회사도 있고 그런 회사와 뚜렷한 차이를 보이며 그 정도 중단은 대수롭지 않게 넘긴 회사도 있다. 그 차이가 무엇인가? 넷플릭스를 포함, 그 사건으로 고생하지 않은 회사들은 신뢰성을 위한 설계법을 알고 있었다. 이들 회사는 회복력, 존(zone)을 넘어선 데이터 스프레딩 및 수많은 신뢰성 공학을 이해하고 있었다. 게다가, 그들은 회복성이 애플리케이션의 속성임을 이해했으며, 네트워크 일부에서 장애가 발생해도 애플리케이션이 살아남을 수 있음을 확실히 하기 위해 개발팀과 작업했다. 아마존의 서비스에 대해 부정적인 비판을 하는 것보다 더 중요한 것은 EBS가 죽어도 애플리케이션이 작동할 수 있도록 똑똑하고 주의깊게 설계했다는 추천서이다.
넷플릭스의 카오스멍키(ChaosMonkey)는 훌륭한데, 극단적으로, 복잡한 분산 애플리케이션이 장애에도 살아남을 수 있다는 것을 보장해주는 도구의 예이다. 카오스멍키는 임의로 애플리케이션의 인스턴스와 서비스를 죽인다. 애플리케이션이 지속적으로 임의의 (그리고 고의의!) 장애를 견뎌내고 성능 저하 없이 충분히 견고한지 보장하기 위해 개발팀과 운영팀은 협업한다.
반면, EBS 장애 동안, 아마존 직원이 아닌 그 누구도 하드웨어에 손 하나 대지 않았다. 그 때, JD Long은 EBS 장애에 대한 최선은 이를 고치려고 미친듯이 애쓰지 않는 것이라고 트윗했다. 어떻게 그럴 수 있는가. 하지만 여기서 20년, 심지어 10년 전 운영 경험과 어떤 차이가 있는지 아는 것이 중요하다. 이미 장애가 발생하기 전부터 이는 결정되어 있었던 일이다. 이런 장애을 성공적으로 다룬 사이트는 견고한 소프트웨어를 작성했고, 조심스럽게 데이터를 관리해서 단일 존에만 의존적이지 않았다. 또한 유사하게, 장애에서 복구하기 위해 허둥댄 사이트는 애플리케이션에 회복성를 구축하지 않았으며, 다른 존에 걸친 데이터 복제를 해두지 않았던 사이트었다.
이런 책임의 재분배에 더해서, 하위 계측 스택부터 애플리케이션 그 자체까지, 비용이 재분배되고 있음을 확인할 수 있다. 운영 비용이 사라졌다고 생각하면 오산이다. 새 서버를 사는데 들인 자본은 아마존의 월단위 청구서로 대체되었지만 여전히 비용이다. 전통적인 IT 스탭은 감축되었을 것이며, 확실히 스탭당 서버의 비율은 높아졌다. 이는 일부 IT 기능이 개발 그룹으로 사라졌기 때문이다. 이런 유대는 가변적이다, 하지만 확실히 핵심은 다음과 같다. 애플리케이션이 돌아가는 서버의 위치와 애플리케이션이 어떻게 관리되는지가 모두 바뀌어도 견고하고 안정적인 애플리케이션을 고객에게 제공하는 일은 똑같다.
운영의 중요한 일 하나는 아마존 같은 공용 클라우드, 사설 클라우드, 전통적인 동일 장소 배치, 전용 기반 체계 구축 사이에서 비용 트레이드 오프를 이해하는 것이다. 비용을 절감하고 부하의 변동에 따라 하드웨어를 할당하거나 해제해야하는 스타트업이라면 아마존을 안 쓸 수 없을 것이다. 피크의 성능을 다룰 수 있지만 대부분 시간동안 놀고 있는 거대한 클러스터를 갖고 싶지는 않을 것이다. 그러나 아마존은 값이 싸지는 않으며, 보다 큰 회사는 아마도 더 나은 조건으로 자신의 동일 장소 배치용 기반 체계에 올릴 수도 있을 것이다. 일부 큰 회사는 그들 자체 데이터 센터를 구축할 것이다. 비용 대비 유연성은 중요한 트레이드 오프가 된다. 물리 하드웨어를 가지고 있을 때 확장은 필연적으로 느릴 수 밖에 없으며 피크의 부하를 처리하기 위해 데이터 센터를 구축해야할 때 설비는 대부분 충분히 활용되지 못할 것이다. 보다 작은 회사는 AWS나 랙스페이스와 같은 공용 클라우드에 일부 기반 체계를 가져가고 일부는 내부 기반 체계를 활용하는 하이브리드 전략을 개발할 것이다. 이런 설비 사이에서 일을 어떻게 최적화시켜 분배할지는 간단한 문제가 아니다. 이것이 운영 조직의 분야이다. 하이브리드 환경에서 효율적으로 돌아가는 애플리케이션 개발은 운영 팀과의 건강한 협력 하에 가져야할 개발자의 책임이다.
시스템 성능을 모니터하기 위해 사용하는 메트릭은 시스템 관리자가 개발해야하는 또 다른 관점이다. 80년대나 90년대 초에는 전화벨이 울려대기 시작하면 기계가 고장났다는 것을 알 수 있었다. HP의 OpenView와 같은 초기 시스템 모니터링 도구는 시스템과 네트워크 동작에 대한 제한된 정보를 제공하기는 했지만 단순한 심박 테스트나 도달 가능여부 테스트 이상의 정보는 주지 못했다. DTrace와 같은 요즘의 도구는 거의 모든 시스템 행위에 대한 정보를 줄 수 있다. 현대 운영 조직의 가장 큰 도전 과제는 장애가 발생하기 전에 문제를 예측할 수 있는 데이터를 취할 수 있는 분석도구나 메트릭을 개발하는 것이다. 우리는 이제 필요한 데이터에 접근할 수 있지만 이를 어떻게 사용해야할지 모를 뿐이다. 그리고 우리가 분산 시스템에 더 의존하게 될수록, 모니터링은 보다 더 중요해진다. 다른 그 무엇보다도, 모니터링은 애플리케이션 그 자체의 일부가 되어야한다. 운영은 성공에 결정적이지만, 개발과 협업하고 애플리케이션의 개발에 참여해서 스스로를 모니터하고 복구할 수 있도록 확장하는 것만이 운영이 성공할 수 있는 방법이다.
성공은 운영을 온전히 개발에 통합하는데 기반하지 않는다. 고성능의 도전 목표, 분산 애플리케이션을 잘 알고 있는 최고의 개발 그룹이라면 절대로 망가지지 않는 소프트웨어를 만들 수 있으리라 생각한다면 순진한 생각이다. 이런 상부상조적인 관계에서, 개발자나 IT 스텝이 호출기를 착용해야 할까? 올스포가 지적했듯, 개발자를 그들의 결과물에서 분리시키지 않는 것이 중요한데, 왜냐하면 그들이 작성한 코드에서 종종 불이 나기도 하기 때문이다. 그래서 개발자와 운영자 둘 다 호출기를 가지고 다녀야 한다. 책임을 공유하는 것은 또 다른 이익을 가져온다. 장애가 나쁜 코드에 의한 것인지, 운영 실수에 의한 것인지 밝해내려 애쓰는, 서로를 손가락질 하는 사후 분석보다는 운영과 개발팀이 함께 장애를 해결하는 사후 분석이 누군가를 탓하는데 집중하기 보다 앞으로 시스템을 보다 견고하게 만드는데 집중할 수 있도록 해준다. 비록 장애가 발생하면 "근본 원인 분석"은 해야하지만, 단일 원인을 찾아내는 것은 도움이 되지 않는다는 것을 우리는 잘 알고 있다. 대부분의 장애는 평범한 일상의 작은 사고가 "엎친데 덮친, 복합적인 상황"의 결과이다. 무엇이 잘못되었는지 알아내고 재발 방지를 보장하는 절차(대부분 항상 비효율적이고 예상밖의 취약점을 수반하는 프로세스)를 수립하는 대신, 요즘의 운영은 일상의 에러에 직면해서 심지어 예상하지 못한 조합으로 에러가 발생해도 회복이 가능한 시스템을 설계한다.
10년 전에는, 소프트웨어 개발 실천법에 있어 주로 변화를 보아왔다. 지루한 선행 투자식 계획을 수반한 "폭포수" 방법론의 다양한 버전에서부터 "최소의 실행 가능한 제품", 지속적인 통합, 지속적인 배포에 이르기까지 변화했다. 폭포수와 80년대의 방법론이 "나쁜 생각"이거나 실수가 아니라는 것을 이해하는 것이 중요하다. 비닐 포장된 소프트웨어의 시대에는 이런 것들이 완벽하게 적용되었다. "골드 디스크"를 만들고 수천 장(또는 수백만장)의 사본을 양산하고 나서 무언가가 잘못되었음을 알게 되었을때 그에 따른 불이익은 어마어마했다. 버그가 있다면, 다음 출시까지 고칠 수 없다. 이런 환경에서, 소프트웨어 출시는 대단한 이벤트였다. 그러나 요즘같은 웹과 모바일 애플리케이션의 시대에서, 배포는 그렇게 대단한 일이 아니다. 조기에, 자주 출시할 수 있게 되었다. 지속적인 통합에서 지속적인 배치에까지 이르렀다. 새로운 릴리즈가 심각한 문제를 가진 경우 빠르게 해결할 수 있는 기술을 개발했으며, 사용자의 작은 일부분을 기반으로 테스트 릴리즈를 하는 A/B 테스팅 기법을 터득했다.
이런 모든 변화에는 개발자와 운영 스탭간의 협력과 협업이 필요하다. 운영 그룹은 이런 변화를 채택해야하며, 많은 경우, 이런 변화를 구현하기 위해 주도적으로 애써야한다. 이들은 복구와 모니터링, 변경 배포와 원상 복구의 전문가들이다. 오라일리의 벨로시티 컨퍼런스의 많은 참석자들, 강당에서의 논의, 대화와 기조연설에서 이들이 적응하고 있음을 볼 수 있었다. 이들은 소프트웨어 공학에서 완전히 새로운 회복력을 위한 접근을 채택하는 방법을 배우고 있다. 이들은 모니터하고 진단하며, 대규모의 자동화를 하고, 압박 속에서 디버깅하는 방법을 배우고 있다. 최근의 미팅에서, 제시 로빈스(Jesse Robbins)는 운영 스탭을 위한 응급 의료진 훈련 세션을 계획해서 그들이 응급 상황에서 어떻게 그들 자신을 제어하고 다른 이들과 의사소통하는지 이해할 수 있도록 하고자 한다는 이야기를 했다. 이는 흥미롭고 자극적인 발상이며, 현대 운영 스텝이 개발자와 같이 일할 때 염두에 두어야할 많은 것들 중 하나이다.
장차 운영에는 무슨 일이 일어날까? 시스템과 네트워크 모니터링은 이질적이고 최첨단 기술만 같았다. 지금은, 이런 것들이 요구된다. 하지만 아직 충분히 해보지는 못했다. 아직 어떻게 시스템을 모니터해야하는지, 현대 모니터링 도구에서 생성되는 데이터를 어떻게 분석하는지, 그리고 결과를 효과적으로 보여주도록 대시보드를 어떻게 구축해야 하는지를 배우고 있다. "하둡 클러스터를 모니터하기 위해 하둡 클러스터를 사용한다"고 농담하곤 했는데, 이게 현실과 그리 동떨어져 있지는 않다. 수집할 수 있는 정보의 양이 기하급수적이어서, 기계학습과 같은 기술을 사용하지 않고는 사람이 분석할 수 있는 정도를 넘어서기도 한다.
마찬가지로, 운영 조직은
SPDY와 같이 새롭고 보다 효율적인 웹을 위한 프로토콜을 배치하는데 대단한 역할을 하고 있다. 운영은 전보다 더 운영 체계와 서버(우리의 물리적 제어 밖의 것이라 하더라도)의 성능을 조율하는데 관여하고 있다. ISDN과 56Kbps 아날로그 모뎀 시대의 많은 TCP 튜닝의 "모범 사례"는 기가비트 이더넷, OC48* 파이버 및 그 파생 기술의 현실에 적용될 수 없다. 운영 조직은 이런 기술을 (그리고 그 계승 기술을) 어떻게 효율적으로 사용할 수 있을지 알아낼 책임이 있다. 이제 겨우 IPv6를 이 변화가 네트워크 기반 체계에 가져올 변화를 이제 이해하기 시작했을 뿐이다. 그리고 회복성을 애플리케이션에 구축하는 주제에 대해 많은 기고를 했지만, 아직 걸음마 단계에 있을 뿐이다. 우리가 아직 알지 못하는 많은 것들이 있을 것이다. 운영 그룹은 오래된 규율(제어시스템 이론, 제조, 의학)로부터 모범 사례를 채택하는데에 있어 리더가 되어 왔으며 이를 소프트웨어 개발에 통합시키고 있다.
무운영에 대해서는 어떤가? 궁극적으로, 이는 나쁜 이름이지만, 이름은 그리 중요치 않다. "무운영"을 성공적으로 실천하는 조직은 운영을 몰아낸 것이 아니다. 단지 운영이 다른 곳으로 옮겨져서 다른 이름으로 불리는 것 뿐이다. 잘못 지어진 이름이 앞으로 도움이 될지 방해가 될지는 지켜볼 일이지만, 운영은 사라지지 않는다. 운영은 효율적이고 신뢰할 만한 소프트웨어를 고객에게 인도하기 위한 도전에 맞서 발전할 것이다. 구식의 시스템 운영자는 아마도 정말 사라질 것이다. 그렇다 하더라도, 이들은 개발팀과 밀접하게 협업하고 지속적인 배치를 제대로 하는, 대규모로 분산된 시스템을 구축하는 보다 복잡한 운영 전문가로 대체될 것이다. 그리고 물론, EBS가 망가졌을 때 한밤 중에 호출기에 응답할 사람은 바로 개발운영이다.