서버/인프라 엔지니어를 위한 DevOps
를 읽고 정리한 내용입니다.
: 자동화된 인프라를 실현하기 위한 방법 중 하나로, 지금까지 수작업으로 해오던 인프라 구축이나 변경 작업을 코드로 작성해서 자동화하는 것
기존에 인프라를 구축할 때는 사전에 가이드라인이나 체크리스트를 준비해두고 이 가이드라인에 따라 사람이 하나씩 작업하는 것이 일반적이었다.
ex) 서버 구축 - 터미널 프로그램을 사용해 SSH로 서버에 접속해서 패키지를 설치하거나 설정
이러한 방식에는 아래와 같은 문제점이 있다.
- 작업 대상이 늘어나면 그만큼 작업에 많은 시간이 걸린다.
- 수작업으로 장시간 작업을 하면 실수할 가능성이 크다.
- 실수를 피하려고 가이드라인이나 체크리스트를 작성해도 올바른지를 알 수 없다.
(ex. 새로운 버전에 대응하지 못하거나, 사소한 작업 순서 변경에 따라 완성된 인프라의 상태가 달라지는 경우도 있다.)- 실수가 일어나도 잘못된 것을 알아차릴 장치가 없다.
- 프로젝트나 서비스별로 다른 체제나 내용으로 가이드라인을 작성하게 되면 재사용이 어렵고 낭비가 발생한다.
코드에 의해 인프라를 구축하면 앞서 설명한 문제 중 상당수가 해결될 수 있다.
- 작업 대상이 늘어나더라도 작성한 코드를 적용하기만 하면 되므로 구축하는 데 시간이 오래 걸리지 않는다.
- '코드 = 가이드라인'이 되므로 같은 코드를 동작시키면 같은 인프라가 왼성된다.
- 코드를 지속적 통합 도구를 사용해서 테스트하고 계속 유지보수 함으로써 언제라도 해당 코드를 통해 인프라를 구축할 수 있다.
- Serverspec과 같은 도구를 사용하여 완성된 인프라가 올바른지 자동으로 테스트할 수 있다.
- 재사용이 쉽다.
#!/bin/sh
yum install -y httpd httpd-devel php php-mbstring php-pdo php-mysql mysql-server
/sbin/chkconfig --level 2345 httpd on
/sbin/chkconfig --level 2345 mysqld on
/etc/rc.d/init.d/mysqld start
/etc/rc.d/init.d/httpd start
CentOS에서 yum 명령을 사용해서 서비스를 활성화해서 시작하는 예시이다.
Capistrano나 Fabric과 같이 배포를 자동화해주는 도구를 사용하는 방법도 있다.
그러나 배포 도구는 어디까지나 소프트웨어를 배포할 목적으로 만들어진 것이다.
인프라 구축의 자동화를 위해 이용할 경우 배포 스크립트에 많이 삽입하는 형태가 되어 규모가 커짐에 따라 가독성이 떨어지기 쉬워 유지보수가 어려워진다.
(쉘 스크립트를 이용한 방식에서 발생하는 문제가 그대로 발생)
desc "Capistrano로 필요한 패키지를 설치하는 예"
task : install_amp, roles => :web do
run <<-CMD
sudo yum install -y httpd httpd-devel php php-mbstring php-pdo php-mysql mysql-server &&
sudo /sbin/chkconfig --level 2345 httpd on
sudo /sbin/chkconfig --level 2345 mysqld on
sudo /etc/rc.d/init.d/mysqld start
sudo /etc/rc.d/init.d/httpd start
CMD
end
아래는 Chef를 사용한 작업 자동화 코드를 일부 발췌한 것이다.
%w{httpd httpd-devel php php-mbstring php-pdo php-mysql mysql-server}.each do |p|
package p do
action :install
end
end
service "httpd" do
action [:enable, :restart]
supports :status => true, :start => true, :stop => true, :restart => true
end
service "mysqld" do
action [:enable, :restart]
supports :status => true, :start => true, :stop => true, :restart => true
end
기존에는 코드에 의한 인프라 관리를 서버 내 OS 설정이나 패키지 설치에 머물렀던 것이 일반적이지만 요즘은 AWS와 같은 클라우드 컴퓨팅이 일반화되며 상황이 달라졌다.
클라우드 컴퓨팅 서비스 자체가 API를 이용자에게 공개하고 있어 코드에서 API를 호출함으로써 서버 이외의 다양한 리소스를 다룰 수 있게 되었다.
멱등성: 몇 번이고 같은 작업을 실행하더라도 같은 결과로 수렴되는 것
위에서 들었던 Chef를 사용한 처리 자동화에도 문제가 있다.
%w{httpd httpd-devel php php-mbstring php-pdo php-mysql mysql-server}.each do |p|
package p do
action :install
end
end
코드를 동작시키는 타이밍에 따라 설치되는 패키지의 버전이 다를 가능성이 있다.
즉, 지금 만든 서버와 1개월 후 만든 서버가 같은 상태로 수렴하지 않을 수 있다는 것이다.
해당 문제를 방지하려면 :install
을 :upgrade
로 지정할 수 있다.
그러나, 이것만으로는 충분하지 않다.
만약 Chef Server가 아닌 Chef Solo나 Chef Client의 로컬 모드를 사용하고 있는 경우에는 새로운 서버를 만들 때 기존 서버에도 모두 이 코드를 적용하지 않는다면, 마찬가지로 버전 차이가 발생할 수 있다.
이처럼 자동화 코드를 준비할 때는 다양한 점을 고려해가며 만들어야 하며, 실제로 운용을 할 경우에는 이것이 부하를 유발할 가능성도 있다.
이러한 문제를 해결하기 위해 고안된 것이 Immutable Infrastructure
이다.
불변하는 인프라라는 의미이며, 서버를 예로 들면 일단 서버를 구축했으면 그 후에는 서버의 소프트웨어에 변경을 가하지 않는 것이다.
그 대신 새로운 서버를 만들어 기존 서버를 모두 대체하는 접근 방식이다.
Immutable Infrastructure를 채택했을 때 인프라 관점에서의 장점은 아래와 같다.
주의해야 할 점은 아래와 같다.
Immutable Infrastructure를 실현하는 대표적인 기술로는 컨테이너 기술이 있고, 컨테이너 기술에는 대표적으로 Docker가 있다.