Upgrade to Pro — share decks privately, control downloads, hide ads and more …

docker/aws/rails를 이용한 시스템 구축/운용

kim
February 19, 2017

docker/aws/rails를 이용한 시스템 구축/운용

docker/aws/rails를 이용한 시스템 구축/운용 - docker편

kim

February 19, 2017
Tweet

More Decks by kim

Other Decks in Programming

Transcript

  1. 자기소개 이름:김세화(@negabaro) 사는곳: 일본 도쿄 경력: 2011년 토마x 안드로이드/JSP 어플리케이션

    개발(SI) 2013년 이스토x 인프라 엔지니어(EC) 2015년 퓨처아키텍x DevOps엔지니어 기술지원(IT컨설팅) 2017년 프리랜x 인프라/DevOps엔지니어(영화 관련) 취미:카라오케(건전한),풋살
  2. AWS /Docker/Rails 를 활용한 레뷰 시스템구축/운용 내용이 많아서 사용한 기술

    베이스로 잘라서 설명하겠습니다. 우선은 도커입니다..! <#>
  3. 목차 • 인프라구조 • 도커란? • 도커를 이용한 시스템 구축/운용중

    고민한 부분들 소개 – 디렉토리 설계 – Docker Automation build,deploy – rails서버 구축/운용 – nginx서버 구축/운용 – 그 외
  4. 인프라구조 어플리케이션 레이어 Middleware전부 docker로 구축(nginx,unicorn,php- fpm,td-agent) AWS ECS를 사용해서

    docker 클러스터 관리 호스트 인스턴스는 오토스켈링 그룹에 속해 있고 부하에 따라 스켈링in,out함
  5. Docker란? 도커관련 용어정리 용어 설명 도커 리눅스 컨테이너를 관리하는 도구(tool)

    도커 호스트,호스트OS, 도커 서버 하나 이상의 도커 컨테이너를 실행하는 리눅스 머신 도커 데몬,도커 서버 프로세스 도커 클라이언트의 요청을 받아 도커 컨테이너를 실행/종료/관리 Dockerfile 베이스 이미지에 넣을 패키지 일람을 정의해놓는 파일 도커 이미지 이미지도커 컨테이너의 초기 상태를 기록한 파일. 파일시스템을 효율적으로 압축한 파일이다(iso 파일처럼). 도커 이미지는 git과 같은 버저닝(commit),상속(branch),원격보관(push),내려받기(pull)을 가짐 도커 클라이언트 docker 명령을 실행하는 머신,도커 호스트와 다른 머실일 수 있고,리눅스가 아니어도 됨. 도커 허브 도커 이미지를 올리고/받고/검색할 수 있는 공식 도커 이미지 저장소(repository) 베이스 이미지 기본적인 OS인스톨 이미지(Docker hub에 올라가 있음) 컨테이너 도커 이미지를 실행한 상태 하나의 프로세스라고도 말할 수 있음
  6. Docker란? 그림으로 설명하면 이런 이미지? Base Image 철수는 영희에게 xx영화를

    받으려고 문구점에서 공시디를 사왔습니다. 공시디=베이스 이미지
  7. Docker란? 그림으로 설명하면 이런 이미지? Base Image docker build 영희는

    철수에게 받은 공시디에 xx영화를 구워서 철수에게 줬습니다. CD를 굽다 = docker build
  8. Docker란? 그림으로 설명하면 이런 이미지? Base Image docker run docker

    build 철수는 영희에게 받은 CD를 CD-ROM에 넣어 실행했습니다. CD-ROM에 넣어서 실행 = docker run
  9. Docker란? 그림으로 설명하면 이런 이미지? Conainer Base Image docker run

    docker build xx영화가 실행되었습니다 xx영화가 실행된 상태 =컨테이너
  10. Docker란? 그림으로 설명하면 이런 이미지? Container Base Image docker run

    docker build Host OS xx영화가 실행된 철수의 컴퓨터는 CPU i7 7700k, 그래픽 카드 nvidia titan x가 장착된 데스크톱입니다. xx영화 실행된 컴퓨터 = Host OS,docker host,docker server
  11. Docker란? 그림으로 설명하면 이런 이미지? Docker repository(Dokcer Hub,AWS ECR) 컨테이너

    베이스 이미지 docker run docker build Host OS 철수는 xx영화가 너무 재밌어서 xx영화가 들어있는 cd를 책상옆에 있는 cd보관함에 넣었습니다. CD보관함=Docker repository(docker hub,aws ecr) CD보관함에 넣다=docker push docker push
  12. Docker란? 그림으로 설명하면 이런 이미지? docker build docker run docker

    push 영희는 docker build를 했고 철수는 docker run,docker push를 했습니다. 영희와 철수는 docker관련 명령을 실행했으므로 docker 클라이언트라고 말할 수 있겠습니다.
  13. Docker란? 도커 구조 Linux Namespaces:컴퓨터 리소스 격리 Linux cgroups:컴퓨터 리소스

    제한 AUFS/Device Mapper Thin Provisioning: 파일/디렉토리 차분관리 Linux iptables:호스트,컨테이너 간의 네트워크 구성
  14. Docker란? 도커의 역사(사용자 시점) • 가상화 (vmware) • 반가상화(xen) •

    어려운 컨테이너 = Solaris Containers,오픈VZ, 리눅스컨테이너(LXC), lmcfty • 쉬운 컨테이너 = docker
  15. Docker란? 도커의 역사2(컨테이너의 역사) • 1983년 4.2BSD에서 Chroot 이라는System Call이

    도입됨 • 2000년 FreeBSD 4.0에서 FreeBSD Jail가 등장 • 일반 유저에게 루트 권한을 주기 위한 고안됨(이 시절은 그런게 안 됐었다함) • Solaris Containers • 가장 docker같은놈(패키징화해서 소스 빌드 생략!) • 2008년 리눅스 커널에 Linux cgroups가 merge됨 • LXC 구획화,분리화 라는 말을 쓰지 않고 컨테이너라는 용어가 나오기 시작 • Docker 2014년 등장 LXC는 관심밖으로 멀어짐
  16. Docker란? 도커의 역사3(docker자체의 역사) • LXC를 기반으로 시작 • 0.9버전에서

    자체적인 libcontainer 기술을 사용(옵션으로 LXC선택도 가능) • 그후 runC기술에 합쳐짐 • 현재 docker의 최신버전은 1.13
  17. Docker란? 도커의 특징 • 파일시스템과 라이브러리를 컨테이너 여러개가 공유하거나 별도로

    보유가능 • 커널의 Control Group(cgroups) 기능을 통해 CPU도 메모리도, 디스크와 네트웍자원까지 할당할 수 있도록 했고, 커널의 Namespace isolation(혹은 namespaces)이란 기능으로 프로세스트리와 사용자계정, fs까지도 격리 시킴 • 리눅스 커널 즉 호스트OS를 공유 • 이동 가능한 경량화된 가상화 기반의 운영체제 • Go언어로 만들어짐
  18. Docker란? 도커의 장점 • 리눅스 커널 환경의 OS에서 의존성없이 똑같이

    실행됨(portable함) • Hands ON시 환경구축에 대한 스트레스가 없음 • 가상화에 비해 퍼포먼스가 우수함 • 불필요한 리소스 없앨 수 있음 • 엄청난 확장성
  19. Docker란? 도커 용도 • 대규모의 프라이빗 클라우드나 퍼블릭 클라우드 구축시

    좋음 • 앱을 클라우드 기반 서비스 형태로 판다고 할 때 개발, 테스트, 운영에 이르는 프로세스가 대폭 단축됨 • 수많은 고객에게 별도의 애플리케이션 이용환경을 할당하고 업데이트를 지속해야 하는 SaaS와 PaaS 같은 클라우드 서비스 진영에서 많이 활용 • 하드웨어와 운영비용을 연간 수십만에서 수백만 달러까지 절감 가능 • 결론.규모가 크면 클수록 쓰면 좋음
  20. Docker란? VM vs Docker의 차이 VM은 가상화든,반가상화든 Hypervisor를 경유하기에 overhead가

    발생 docker는 hypervisor를 경유하지 않고 직접Host OS와 통신하므로 VM보다 퍼포먼스가 좋음
  21. Docker란? Docker vs Chef,Ansible,Puppet • 재사용성면에서 docker가 우수하다고 생각 •

    Docker는Immutable Infrastructure에 적합함 • Bootstrapping과Configuration의 차이 • Docker의 설정내용이 chef,ansible,puppet보다 직관적
  22. Docker란? Docker Command • Docker run • Docker build •

    Docker exec • Docker rm • Docker rmi • 등등이 있음
  23. Docker를 선택한 이유 • 재사용성 (rails의 DRY철학과 닮은 느낌) •

    개발환경과 production간의 의존성을 없애고 싶음 • 설정내용이 Chef,ansible보다 훨씬 직관적이다고 느낌 • Hot한 기술이니깐..
  24. 그외 원했던 환경 • 개발,인프라 환경 구축,설정을 모두 git안에서 일괄관리

    하고 싶음 • Wiki도 git으로 통합시키고 싶음 • 스케줄관리 trello에서 xenhub로 • git push만 하면 deploy까지 끝나게끔 하고 싶음
  25. 여러가지 문제에 조우.. • 디렉토리 구조 • Docker build,push,deploy •

    환경변수 관리 • 트러블 슈팅 • 디플로이 • 로그 수집 • 개발 환경 • 스켈링 • 등등등
  26. 디렉토리 구조 설계시 고민한 부분들 • 한 리포지토리에서 복수의 automation

    docker build가 가능하게 하고 싶음 • 각 middleware의 docker이미지는 rails_env별로 나눠짐 • Docker관련 파일 전부 하나의 리포지토리에서 관리하고 싶음 • 가능한 DRY하게 구성하고 싶음 • 재사용성을 위해 특정 패턴을 만들고 싶음
  27. Directory structure Rails_env Middleware docker Rails_root rails_root docker nginx unicorn

    development beta staging productoon shared memcached redis elasticsearch td-agent mysql base Dockerfile docker- compose.yml Middleware layer안의 각 하위 디렉토리에는 rails.env layer가 존재(unicorn외에는 생략) Mysql의 경우 development환경빼고 aws RDS를 쓰므로 development디렉토리만 존재
  28. Directory structure – Rails_root Rails_env Middleware docker Rails_root rails_root docker

    nginx unicorn development beta staging productoon shared memcached redis elasticsearch td-agent mysql Dockerfile docker- compose.yml Rails_root 전체 리포지토리 최상위 디렉토리입니다.
  29. Directory structure – docker Rails_env Middleware docker Rails_root rails_root docker

    nginx unicorn development beta staging productoon shared memcached redis elasticsearch td-agent mysql Dockerfile docker- compose.yml File name description docker-compose.yml 복수의 컨테이너를 간편히 실행 (주로development환경에서 사용) Dockerfile docker build시 사용 최상위 디렉토리에 있는 docker관련 디렉토리 입니다. Docker관련파일은 development환경에서 쓰이는 Dockerfile,docker-compose.yml뿐입니다.
  30. Directory structure – Middleware Rails_env Middleware docker Rails_root rails_root docker

    nginx unicorn development beta staging productoon shared memcached redis elasticsearch td-agent mysql base Dockerfile docker- compose.yml Docker 디렉토리안에는 사용되어지는 미들웨어가 디렉토리별로 존재합니다. 그외에 미들웨어의 상위 docker image에 해당하는 소스들을 관리하는 base디렉토리가 있습니다.(base디렉토리에 대해서는 나중에 설명)
  31. Directory structure – Rails_env Rails_env Middleware docker Rails_root rails_root docker

    nginx unicorn development beta staging productoon shared memcached redis elasticsearch td-agent mysql base Dockerfile docker- compose.yml Middleware디렉토리 하위는 환경별로 디렉토리로 나누어집니다. 그 외에 각환경에서 공통적으로 사용되어지는 파일이 있는 shared디렉토리가 있습니다.
  32. Directory structure – Rails_env - environment 환경 이름 설명 development

    각 개발자들이 개발용으로 로컬환경에서 쓰이는 환경 beta Github 레뷰가 끝난 소스가 놓여지는 환경 staging Production환경에 디플로이 하기 전에 최종 체크하는 환경 production 실제 서비스 환경
  33. Directory structure2 – Docker_build_root Docker build시 쓰여지는 첨부파일 Docker_build_root Rails_env

    {development staging, production} files set_env.sh set._key.sh run_sh.sh 그외 도커 컨테이너에서 필요한 파일 test Dockerfile build_docker.s h run_docker.sh push_docker.s h deploy 파일명 설명 Dockerfile docker build시 사용 Files디렉토리 docker컨테이너안에서 사용할 파일(Dockerfile안에서 files통째로 ADD함) build_docker.sh docker build시 사용하는 명령어를 정의 run_docker.sh docker build로 만들어진 도커이미지를 run할때 사용. 주로 컨테이너 동작 테스트시 사용(serverspec) Push_docker.sh Build,test가 끝난 docker이미지를 aws ecr에 push deploy디렉토리 디플로이 관련 설정파일(Task Definition file등)을 정의
  34. Directory structure2 – Docker build시 쓰여지는 첨부파일 Docker build시 쓰여지는

    첨부파일 Docker_build_root Rails_env {development staging, production} files set_env.sh set._key.sh run_sh.sh 그외 도커 컨테이너에서 필요한 파일 test Dockerfile build_docker.s h run_docker.sh push_docker.s h deploy 파일명 설명 set_env.sh S3에서 환경변수를 취득 set_key.sh S3에서 ssh key를 취득 run_sh.sh 도커 컨테이너를 올리기전에 실행하고 싶은 shellscript파일 정의 build_docker.sh docker build시 사용하는 명령어를 정의 Other_files 그외 도커 컨테이너 안에서 필요한 파일들
  35. 지금까지 설명한 디렉토리 구조를 베이스로 docker automation build docker container

    test by serverspec docker auto deploy for aws ecs 등을 실현
  36. How to do Docker build 환경별Docker_root Rails.env rails.env layer {development

    staging, production} files set_env.sh set._key.sh run_sh.sh 그외 도커 컨테이너에서 필요한 파일 Dockerfile build_docker.sh run_docker.sh push_docker.sh deploy Docker build시 사용되는 커맨드는 전부 build_docker.sh에 정의
  37. build_docker.sh내용 PR_NUMBER ="${CIRCLE_PR_NUMBER}" //circlieCI안에서 해당P.R번호를 환경변수로 취득 가능 Docker build

    –t [ECR-EndPoint]/[ECR-Image]:PR_NUMBER –t [ECR-EndPoint]/[ECR- Image] –file Dockerfile . //해당P.R번호를 태그에 붙여서 docker build Docker repository관리는 aws ECR을 사용
  38. How to do Docker Automaition Build 고민한 부분들 • Docker

    hub의 automation build 기능을 쓰려니 각 이미지별로 리포지토리를 만들어야 되서 리포지토리의 낭비가심하고 관리가 귀찮.. • 하나의 리포지토리 안에서 복수의 automation build 기능을 구현하고 싶음 • 각 환경별 branch에 git push만 해주면 build,push,test,deploy까지 전부 알아서 해주는 시스템을 만들고 싶음
  39. How to do Docker Automaition Build 그래서..결론 • Automation Docker

    Build 를 위해 circleCI를 이용 • Docker디렉토리 구조에서 설명했듯이 각 Middleware별로 docker build를 해주는build_docker.sh파일이 존재함 • circleCI안에서 git diff커맨드를 사용해서 해당Middleware하위 디렉토리에 있는 파일이 갱신되었을때만 해당 레이어의 build_docker.sh 파일을 실행시키도록 함
  40. How to do Docker Automaition Build 실행순서 • 대략적인 순서는

    git push -> circleCI에서 캐치-> git diff해서 build_docker.sh를 실행시킬 디렉토리 확인 -> build 실행시킬 레이어가 있다면 build_docker.sh실행 –> run_docker.sh 해서 컨테이너 실행 -> serverspec 으로 해당 컨테이너 동작test -> 문제 없다면 -> docker push -> deploy • 정리하면 • git push -> circleci -> git diff -> build_docker.sh
  41. How to do Docker Automaition Build 여기서 잠깐 폴리시 얘기

    • 현재 엔지니어 구성은 개발자 10명,인프라 엔지니어 1명인 상황 • P.R횟수는 절대적으로 rails관련이 많음 • circleCI상에서 실행되는 rails관련 rspec테스트만 20분이 걸림 • 거기에 docker build,run 시켜서 그 위에서 rspec을 실행하게 되면 테스트에 걸리는 시간이 더 늘어나게 됨.. • 결론. 각 환경 브랜치에 merge될때에만 docker 관련 build 테스트를 실행하기로 함
  42. How to do Docker Automaition Build circle.yml deployment: develop: branch:

    develop commands: - sh docker/run_git_diff.sh: timeout: 1500 betax: branch: betax commands: - sh docker/run_git_diff.sh: timeout: 1500 staging: branch: staging commands: - sh docker/run_git_diff.sh: timeout: 1500 production: branch: production commands: - sh docker/run_git_diff.sh: timeout: 1500 고로 docker관련 설정은 circleCI의deployment 레이어 에서만 실행 어떤 브랜치라도 실행하는 파일은 같음 run_git_diff.sh파일안에서 갱신된 파일을 보고 docker build할 리스트를 취득함
  43. How to do Docker Automaition Build git diff사용예 #!/bin/sh changed_files="$(git

    diff-tree -r --name-only --no-commit-id ORIG_HEAD)“ branch_name="${CIRCLE_BRANCH}" updated_nginx_status=false updated_unicorn_status=false updated_td-agent_status=false updated_rails_status=false for var in $changed_files do if [[ $var =~ ^docker/nginx/$branch_name ]]; then updated_nginx_status =true elif [[ $var =~ ^docker/unicorn/$branch_name ]]; then updated_unicorn_status=true elif [[ $var =~ ^docker/td-agent/$branch_name ]]; then updated_td-agent_status =true else updated_rails_status=true fi done
  44. How to do Docker Automaition Build git diff사용예 #!/bin/sh if

    [ $updated_nginx_status ]; then sh docker/nginx/$branch_name/build_docker.sh //docker build sh docker/nginx/$branch_name/run_docker.sh //docker run sh docker/nginx/$branch_name/test/run_test.sh //serverspec으로 실행된 컨테이너의 동작 테스트 sh docker/nginx/$branch_name/push_docker.sh //테스트중 에러가 없다면 aws ecr에 docker push else fi if [ $updated_unicorn_status ]; then sh docker/unicorn/$branch_name/build_docker.sh sh docker/unicorn/$branch_name/run_docker.sh sh docker/unicorn/$branch_name/test/run_test.sh sh docker/unicorn/$branch_name/push_docker.sh else fi autumation docker run,test,push도 동일한 방식
  45. How to do Docker Automaition Build 여기까지 내용을 정리하면 rails_root

    docker nginx unicorn development beta staging productoon shared memcached redis elasticsearch development Build_docker.sh td-agent production mysql base Dockerfile docker- compose.yml docker/nginx/beta/xx docker/elasticsearch/d evelopment/xxx docker/td- agent/production/xxx 위와 같은 파일이 development branch에 merge됬다면
  46. How to do Docker Automaition Build 여기까지 내용을 정리하면 rails_root

    docker nginx unicorn development beta staging productoon shared memcached redis elasticsearch development Build_docker.sh td-agent production mysql base Dockerfile docker- compose.yml docker/nginx/beta/xx docker/elasticsearch/ development/xxx docker/td- agent/production/xxx 위와 같은 파일이 development branch에 merge됬다면 Development 디렉토리가 수정된 elasticsearch/development/build_ docker.sh파일이 실행됨
  47. How to do Docker Automaition Build 여기까지 내용을 정리하면 rails_root

    docker nginx production build_docker.sh unicorn development beta staging productoon build_docker.sh shared memcached redis elasticsearch development build_docker.sh td-agent production build_docker.sh mysql base Dockerfile docker- compose.yml docker/nginx/production /xx docker/elasticsearch/dev elopment/xxx docker/td- agent/production/xxx 위와 같은 파일이 production branch에 merge됬다면 docker/unicorn/producti on/xxx
  48. How to do Docker Automaition Build 여기까지 내용을 정리하면 rails_root

    docker nginx production build_docker.sh unicorn development beta staging productoon build_docker.sh shared memcached redis elasticsearch development build_docker.sh td-agent production build_docker.sh mysql base Dockerfile docker- compose.yml docker/nginx/production /xx docker/elasticsearch/dev elopment/xxx docker/td- agent/production/xxx 위와 같은 파일이 production branch에 merge됬다면 docker/unicorn/producti on/xxx Production 디렉토리가 수정된 nginx,unicorn,td-agent의 build_docker.sh파일이 전부 실행됨
  49. How to do auto deployment • 다음 스탭은 AWS ECS를

    이용한 자동 디플로이입니다. • Git push -> circlieci -> git diff -> build_docker.sh - >run_docker.sh -> run_test.sh -> push_docker.sh -> create_task_def.sh -> update_task_def.sh
  50. How to do auto deployment 고민한 부분들 • AWS ECS를

    이용해서 디플로이함 • Blue green deployment방식은 간지가 나지 않으므로 사용하지 않음 • AWS ECS의Minimum healthy percent,Maximum percent값을 잘 이용해주면 무정지 디플로이가 가능 • 클러스터내에 서버가20대가 있다고 가정 Minimum healthy percent:50, Maximum percent 100을 지정해주면 10대의 컨테이너가 죽고 새로운 컨테이너가 올라옴 -> 나머지 10대의 컨테이너가 죽고 새로운 컨테이너가 올라오게 됨
  51. How to do auto deployment about deploy directory Docker build시

    쓰여지는 첨부파일 Docker_build_root Rails_env {development staging, production} files test deploy create_task_ def.sh dynamic_gen _task_def_js on.sh task_def.tem plate update_task _def.sh 파일명 설명 create_task_def.sh 새로 docker build해서 만든 이미지를 이용해서 task definition생성 dynamic_gen_task_def_json.sh task_def.templat을 이용해서 task_def.json파일을 생성(envsubust커맨드 사용) task_def.template Dynamic_gen_task_def_json.sh파일에서 사용하는 템플릿 update_task_def.sh 최신의 task_definition으로 갱신
  52. How to do auto deployment dynamic_gen_task_def_json.sh + task_def.template #!/bin/sh cd

    docker/unicorn/$BRANCH/deploy/ envsubst '¥$CIRCLE_PR_NUMBER' < task_def.template > task_def.json dynamic_gen_task_def_json.sh { "containerDefinitions": [ { "name": "unicorn", "image": “xx.dkr.ecr.ap-northeast-1.amazonaws.com/xx:${CIRCLE_PR_NUMBER}", "essential": true, … task_def.template
  53. How to do auto deployment create_task_def.sh #!/bin/sh cd docker/unicorn/$BRANCH/deploy/ sh

    dynamic_gen_task_def_json.sh aws ecs register-task-definition --cli-input-json file://task-def.json //새로 생성한 task definition을 aws ecs에 등록 create_task_def.sh
  54. How to do auto deployment update_task_def.sh 이부분은 well made툴인 ecs-deploy의

    소스를 참고했습니다 https://github.com/silinternational/ecs-deploy TASK_REVISIONS=`aws ecs list-task-definitions --family-prefix [family_name] --status ACTIVE --sort ASC` //해당 family에 속하는 전체 task definition일람을 취득 NUM_ACTIVE_REVISIONS=$(echo "$TASK_REVISIONS" | jq ".taskDefinitionArns|length") //취득한 task definition의 길이를 취득 OUTDATED_REVISION_ARN=$(echo "$TASK_REVISIONS" | jq -r ".taskDefinitionArns[NUM_ACTIVE_REVISIONS-1]") //그 길이의 -1이 최신 task definition이므로 해당 task def의 ARN을 취득 aws ecs update-service --cluster [cluaster_name] --service-name [service_name] --task-definition $OUTDATED_REVISION_ARN //최신 task_def로 해당 service업데이트 update_task_def.sh
  55. How to do auto deployment 주의 • 예외처리 로직은 내용이

    길어지므로 생략했습니다 • Production에서 auto deployment 해버려도 좋은가?는 아직까지 정답을 모르겠습니다..
  56. 환경변수/ssh key 관리 고민한 부분들 • Docker image는 portable한 장점이

    있지만 그 장점은 docker image가 유출될 가능성도 높다는 단점이 되기도 함 • 그러므로 docker image안에 가능한 password정보나 ssh key가 상시 존재하는 형태는 바람직하지 않음
  57. 환경변수/ssh key 관리 결론 • 환경변수는 S3에서 일괄관리 • 각

    미들웨어별 환경별 환경변수 파일을 가짐 • 기본적으로 환경변수,ssh key등이 dockerfile안에서 필요할 경우 s3에서 취득함. 사용이 끝나면 반드시 삭제할 것 • 도커 컨테이너 실행시는 무조건 S3에서 최신 환경변수 파일을 취득 • S3에서 환경변수 관리시 version설정 필수
  58. 환경변수 관리 환경별Docker_root Rails.env rails.env layer {development staging, production} files

    set_env.sh set._key.sh run_sh.sh 그외 도커 컨테이너에서 필요한 파일 Dockerfile build_docker.sh run_docker.sh deploy
  59. 환경변수 관리 set_env.sh 컨테이너 실행할 프로세스를 bash –lc “” 커멘드

    안에 정의 #!/bin/sh aws s3 cp –quiet s3://xx/env_[middleware_name]_[rails_env] /etc/profile.d/xx.sh #ex)aws s3 cp –quiet s3://xx/env_unicorn_production /etc/profile.d/xx.sh ex) bash -lc 'bundle exec unicornherder -u unicorn_rails -p /tmp/unicorn.pid -- -c /unicorn.rb'
  60. 트러블 슈팅..프로세스 재기동.. • 처음에는 docker run xx rails s

    로 컨테너 기동 • 트러블 슈팅이 귀찮.. 컨테이너 안에 들어가서 레일즈 재기동한후의 동작상태가 알고싶을때가 많음 • 컨테이너 재기동하지 않고 컨테이너안에서 환경변수등을 적용시키고 싶음 • Rails 프로세스를 직접 컨테이너로 실행하는게 아닌 • Supervisord를 이용해서 rails프로세스를 기동 컨테이너는 supervisord가 기동하고 있으므로 컨테이너안에서 자유롭게 rails재기동이 가능 • 혹시 graceful하게 재기동하고 싶다면 unicornherder를 사용
  61. 디플로이 속도 개선 • Rails&docker구성시 디플로이를 하려면 속도 개선을 위해

    여러가지 생각해야 할 부분이 있음 • 특히 캐쉬 안먹혔을때 bundle install 속도가 느림
  62. 디플로이 속도 개선 레일즈 3대장 손본 내용들 – bundle install

    Bundle install의 경우 RAILS_ENV환경변수가 필요(얘는 뭐 있어도 괜찮긴 함) Gemfile안에 private git repository가 있을 경우 ssh key도 필요(ssh key는 두기 싫다..) 게다가 bundle install은 캐쉬 안먹히게되면 docker build시간 상당히 오래걸리게 됨 bundle install
  63. 디플로이 속도 개선 레일즈 3대장 손본 내용들 - bundle install

    Bundle install을 docker build와 따로 관리 Gemfile이 갱신되면 bundle install한 결과를 패키지화 해서 s3에 보관하는 batch가 따로 움직임 Dockerfile안에서는 해당 s3파일을 취득 타이밍에 따라선 bundle install한 패키지 내용이 최신이 아닐 가능성이 있으므로 bundle install은 build시 항시 실행(기존 패키지 거의 존재하므로 시간 많이 안걸림) bundle install
  64. 디플로이 속도 개선 레일즈 3대장 손본 내용들 – assets_precompile assets_precompile한

    결과도 s3에 관리 assets_sync라는 gem을 이용하면 간단히 s3에 sync가능 sprockets-manifestxx.json파일을 갱신만 잘해놓으면 별 문제없음 assets_precompile
  65. 디플로이 속도 개선 레일즈 3대장 손본 내용들 – db_migrate 현재

    아무것도 손안댐 시간이 되면 git diff를 이용해서 migrate 관련 파일이 갱신 되었을때만 db_migrate하게끔 하면 다소는 속도개선 될지도.. db_migrate
  66. 도커를 이용한 nginx 운용 • nginx설정 안에서의 환경변수 이용을 어떤식으로

    설정할까 고민 • 처음엔 lua script를 이용했는데 실제로 환경변수가 제대로 반영되있는지 트러블 슈팅이 힘들었음 • 구글링한 결과 외국성님들이 envsubst 로 nginx설정 하는걸 발견 • 결론. Envsubst를이용해서 컨테이너 기동시 nginx.conf파일을 생성
  67. 도커를 이용한 nginx 운용 envsubst? apt-get install -y gettext Ubuntu에서

    envsubst 설치 방법 Envsubst커맨드는 쉘스크립트로 템플릿 처리를 해줌
  68. 도커를 이용한 nginx 운용 환경별Docker_root Rails.env rails.env layer {development staging,

    production} files set_env.sh dynamic_generate _nginx.conf.sh nginx.conf.templa te run_sh.sh 그외 도커 컨테이너에서 필요한 파일 Dockerfile build_docker.sh run_docker.sh deploy File name description dynamic_generate_nginx.conf.sh Envsubst커맨드 실행내용을 정의 nginx.conf.template nginx.conf를 만들기 위한 템플릿 파일
  69. 도커를 이용한 nginx 운용 dynamic_generate_nginx.conf.sh #!/bin/sh ####nginx.conf /bin/bash -c "envsubst

    '¥$OFFICE_GATEWAY' < /etc/nginx/nginx.conf.template > /etc/nginx/nginx.conf && cat /etc/nginx/nginx.conf"
  70. 도커를 이용한 nginx 운용 • Aws ELB사용시 • 꼭 씁시다..

    Resolver 10.0.0.2 valid=2s; ELB/ALB의 글로벌 아이피는 동적으로 바뀌므로 위 옵션 지정안할시名前解決 실패 하므로 주의
  71. 로그관리 컨테이너 안에 로그를 두지않는것이 원칙(언제 컨테이너가 죽을지 모르므로) 기본적으로는

    logdriver를 이용해서 표준 출력으로 받은 로그를 전부 전송 그외 로그들은 호스트인스턴스에 볼륨시켜둠 리얼타임 분석 목적이라면 Aws kinesis agent를 이용해서 AWS Kinesis Firehose에 전송 Firehose는 날짜별로 s3에 보존 AWS Athena로 분석
  72. 로그관리 logDriver를 사용해서 로그 수집하는 방법 AWS ECS사용시 위와같이 logDriver를

    이용해서 컨테이너에서 직접 logDriver를 td-agent로 변경하는것도 가능 Task definition "logConfiguration": { "logDriver": "awslogs", "options": { "awslogs-group": "rails-actionlog-production", "awslogs-stream-prefix": "production", "awslogs-region": "ap-northeast-1" } Dockerfile RUN ln -sf /proc/1/fd/1 /var/log/rails/xx.log
  73. TEST • 도커의 베이스이미지들은 공개 리포지토리에 있는 소스등을 사용해서 이미지를

    만듬 • 외부 소스의 변화에 의해 장애가 일어날 가능성이 있음 • 공개 리포지토리에 어떤 문제가 생겨도 시스템에 영향이 없게끔 하고 싶음 • 결론:도커 빌드시 테스트를 꼭 해야함, 사내용 베이스 이미지를 따로 가지고 있는게 안전 • 테스트는 뭘로? -> 인프라 쪽 테스틑 serverspec이 제일 유명
  74. TEST Docker build시 쓰여지는 첨부파일 Docker_build_root Rails_env {development staging, production}

    files set_env.sh set._key.sh run_sh.sh 그외 도커 컨테이너에서 필요한 파일 test Dockerfile build_docker.s h run_docker.sh push_docker.s h deploy test디렉토리 안에서 serverspec의 설정파일을 정의해둡니다. Circleci에서 해당 레이어의 파일이 갱신되었을때 build,run후 지정된 테스트 파일을 실행하게 됩니다.
  75. Base 디렉토리 Ubuntu:14.04 Ruby:2.3.3 Unicorn:xxx Unicorn:xxx의 build시간을 줄이기 위해서는 잘안바뀌는

    설정은 상위 베이스 이미지로 이동 시켜줄 필요가 있음 common
  76. Base 디렉토리 rails_root docker nginx unicorn base ruby 2.3.1 build_docker.sh

    2.3.3 build_docker.sh php nginx unicorn-common Dockerfile docker- compose.yml Base 디렉토리는 위와 같은 디렉토리 구조를 띔
  77. 개발환경에서의 docker • 개발환경과 production간의 의존성을 없앨 수 있음 •

    빠르게 환경구축 가능 • 볼륨 기능 사용시 Docker for mac느림-> 해결책 docker-async사용 • 개발자 입장에서는 생각보다 학습 코스트가 높은듯?? • 좀처럼..적응하지 못함 • 개발과 운영 모두에게 혜택을 줄 잠재력을 가졌지만, 여전히 개발을 할 줄 아는 운영자여야 도커에 관심을 갖는다. 데브옵스를 할 수 없는 운영자에게 현업시스템에서 도커를 쓰게 한다면, 그 회사의 IT환경은 도커의 장점을 전혀 누릴 수 없음
  78. 클러스터 관리 • Swarm,Kubernets? , ECS • 여러가지 툴이 있었지만

    주로AWS플랫폼만 쓰기에 AWS내의 시스템인 AWS ECS선택 • 그다지 큰 고민하지 않음..결과론적으로 ECS NOT BAD 지금까지 별문제 없이 잘 쓰고 있음
  79. 감시.. • 거의 모든 감시를 aws cloudWatch,new relic, bugsang이용 •

    아직도 컨테이너안의 디스크를 사용량을 감시할 방법을 모르겠음.. • 아시는 분 가르쳐주세요..@negabaro
  80. 도커 다이어트 • 도커 이미지의 경량화 대전쟁 • 도커의 이미지가

    가벼워지면 docker pull,push속도가 줄어드므로 deploy속도가 빨라짐 • 의외로 비싼 aws ebs의 용량을 최적화 시킴으로서 비용 절감에 도움이 됨 • CoreOS, rancheros, alpine OS등을 이용 • Ubuntu보단 debian이 가벼움 • 아직 docker diet는 하지못한 상태.. 돼지임..base image우분투14.04 사용중…
  81. cron운용 • Rails에서는 rake커맨드를 이용해서 크론 스크립트를 관리 • 여러

    방법이 있으나 현재는 호스트 인스턴스에서 docker exec로 rake를 실행중 ~/.bashrc export GET_CONTAINER="docker exec -t `docker ps | grep 3000 |grep 3005 |grep admin | grep unicorn |grep -v redmine | awk '{print ¥$1}'` crontab -e 30 * * * * source ~/.bashrc;$GET_UNICORN_CONTAINER bash -lc "bundle exec rake filmarks:xx RAILS_ENV=staging" 1 > /dev/null
  82. Cron운용 Lambda에서 docker exec rake실행 하게하는 방법도 lambda python에서 에이전트를

    향해 Docker exec rake실행 혹은 EC2 Run Command를 통해 실행 #!/bin/bash yum -y update curl https://[bucket-name].s3.amazonaws.com/latest/linux_amd64/amazon-ssm- agent.rpm -o amazon-ssm-agent.rpm yum install -y amazon-ssm-agent.rpm http://dev.classmethod.jp/cloud/aws/introduce-to-run-a-command-button-for-linux/ 호스트 인스턴스에 EC2RoleforSSM 에이전트 인스톨
  83. AWS ECS userdata설정 예 이하와 같은 설정으로 ec2생성후 ecs agent와

    ecs클러스터가 통신하게 함 #!/bin/bash sudo rm -rf /var/lib/ecs/data/ecs_agent_data.json echo ECS_CLUSTER=[ECS클러스터 명] >> /etc/ecs/ecs.config
  84. 그외 팁 • Docker 컨테이너 들어갈때 매번 docker exec 하기

    귀찮.. • 각 서버에 이하와 같은 alias정보를 넣어줌 alias uu="docker exec -it `docker ps | grep unicorn | grep 3000 | awk '{print $1}'` /bin/bash" alias nn="docker exec -it `docker ps | grep nginx | grep 80 | awk '{print $1}'` /bin/bash" alias pp="docker exec -it `docker ps | grep php | grep 80 | awk '{print $1}'` /bin/bash" alias rr="docker exec -it `docker ps | grep td-agent | awk '{print $1}'` /bin/bash alias drm='docker rm $(docker ps -aqf "status=exited") 2> /dev/null' alias drmi='docker rmi $(docker images -aqf "dangling=true") 2> /dev/null'
  85. 끝으로 ..감상 • 도커의 재사용성은 훌륭함 • 이론적으로 개발자 환경과

    production환경의 의존성을 없앤건 큰 성과 였지만 규모가 작아서 그런지 아직까지 큰 메리트가 없는 상태 • 현재 개발환경은 docker파, 안docker파로 나눠짐.. 프론트 엔지니어에게 특히 인기가 많았음. API쪽만 개발하는 분들에게는 인기가 없음..elasticsearch연계해서 개발할때만 사용하는 분위기 • 규모가 클수록 docker를 쓰면 좋다고 생각 • 규모가 작아도 해도 나쁠건 없지만 장점이 많이 사라지는 느낌이 듬
  86. Question?? • 오타나 잘못된 정보 그외 궁금한 내용이 있으시면 알려주세요

    : ) • https://twitter.com/negabaro • https://www.facebook.com/negabaro • [email protected]