Docker overview

서버 교양 2015. 6. 13. 13:54

Docker

  1. DockerFile
    1. 이 파일로 부터 instance image를 만든다.
    2. 어떤 파일을 복사해둘지, 어떤 패키지를 인스톨 할것인지, 어떤 명령어로 서버를 실행할지 설정을 해둔다.
    3. 여기서 expose와 run할때 expose는 그 의미가 좀 다르다.
    4. 여기서 expose는 이 instance의 특정 ip를 내부 컨테이너에 한정해서 열어두겠다. 이고 run할때 expose는 host로 어느 포트를 열어줄 것인가를 정의하는 것이다.
    5. 기본적으로 exposed되지 않은 포트로는 host에서 접속할 수 없다.
    6. volume도 마찬가지

  2. Image
    1. Container instance로 띄울수 있는 Image다. (아마존 AMI같은거라고 볼수 있다.)
  3. Container
    1. Image로 실행된 instance
    2. 각 프로세스라고 볼 수 있다.
    3. container안에 접속해서 새로운 패키지를 설치했을때 이 변경사항을 commit하여 새로운 이미지로 만들수도있다. 하지만 이걸 다시 docfile로 빼는것은 없는것 같다.

  4. Run
    1. expose
      1. run할 인스턴스에 특정 포트를 여는의미 -p 이용 (publish)
    2. link
      1. link는 container간에 container 이름이나 특정 ailias이름으로 접근하기 위해서 사용. 딱히 link를 안해주어도 하나의 host안에 떠있는 container들은 서로의 ip만 알면 접근가능하다. 하지만 ip는 설치할때마다 동적이므로 코드레벨에서 이름으로 지정해놓고 쓰려면 link를 이용하는게 좋다.
    3. volume
      1. expose와 비슷한 개념으로 폴더를 공유할 수있게 해준다. 좀더 특이한점은 여러 Container가 하나의 폴더를 공유할 수 있게도 해준다.
  5. Ambassador
    1. docker를 분산환경에 셋팅 할 수 도 있는데, 이때 서로 exposed된 port, ip에 name으로만 붙고싶은데 이때 붙었던 instance의 ip가 변경되면(스케일업을 한다던지) 여기 붙고있던 instance들의 hosts파일을 변경해준다던지 하는 추가 작업을 해줘야한다. 이때 Ambassador를 이용하면 mongos처럼 docker앞쪽에 network잡을 대신 처리해줄 수 있다.


  • Docker의 장점은 일단 local환경이나 개발환경에서 OS에 국한되지 않는 여러가지 셋팅이 가능하게 해준다는 점과 이를 Image로 관리해서 쉽게 개발환경을 구축할수있다는점.

====== 유용한 docker command =========
- docker file로 image 만들기: docker build -t name . (docker file 이 있는곳에서)
- 실행중 & 스탑된 container 목록: docker ps -a
- 실행중 & 스탑된 container 제거: docker rm container_id
- container image 목록: docker images
- container image 제거: docker rmi image_id
 
- docker command 실행이 끝나도 프로세스가 남아있어서 attach가능하도록
: docker run -dit container_name /bin/sh (그냥 docker run -it container_name 이라고 하고 써도 된다. 바로 접속해서 쓸꺼면.)
- host port mapping: docker run -p 8080:8080 (-P 대문자옵션은 dockerfile에서 미리 exposed된 것들을 맵핑하겠다는것이고 아니면 -p를 써야한다)
- host directory mount: -v host절대경로:docker절대경로
- docker container process로 shell 접속: docker attach contrainer_id (detatch 는 ctl p ctl q)
- docker container save: docker commit container_id image_name
(docker commit 2c08332 arena)
- docker container stop: docker stop container_id
- 각 docker file line당 disk증가량 보려면: docker history image_name

* 아 그리고 이게 명령어 마다 layer라서 실행하고 다른 라인으로 RUN rm 해봤자 용량이 줄지않는다. && 으로 연결해서 rm 해야 image 용량이 늘어나지 않는다!

* 참고로 dockerfile RUN하나당 disk layer하나다 무슨말인고 하니,

RUN wget something (200MB)

RUN rm something 

이렇게 하면 이미지 사이즈에 200메가는 반영되지 않기를 바라지만 200메가는 고스란히 반영된다.

RUN wget something && rm something 이라고 해야된다.

'서버 교양' 카테고리의 다른 글

Logstash install  (0) 2017.03.17
[펌] 인증 암호화와 해쉬  (0) 2016.10.29
SSL 인증서 발급  (0) 2015.03.04
글로벌 푸시 시스템 구성하기  (0) 2015.01.16
글로벌 푸시 보내기  (0) 2014.11.27
블로그 이미지

시간을 거스르는자

ytkang86@gmail.com

,

가이드: https://www.openssl.org/docs/HOWTO/certificates.txt

이 문서에서 2, 3번 항목 참조


Terminal 에서 다음순서로 생성

2. Relationship with keys: $openssl genrsa -out privkey.pem 2048 (default는 1024)
3. Creating a certificate request: $openssl req -new -key privkey.pem -out csr.pem

Country Name (2 letter code) [AU]:KR

State or Province Name (full name) [Some-State]:Seoul

Locality Name (eg, city) []:Seoul

Organization Name (eg, company) [Internet Widgits Pty Ltd]:Makamoye

Organizational Unit Name (eg, section) []:Mytoon

Common Name (e.g. server FQDN or YOUR name) []:contents.mytoon.com

Email Address []:ytkang86@gmail.com


Please enter the following 'extra' attributes

to be sent with your certificate request

A challenge password []:

An optional company name []:


이렇게 csr.pem을 생성해서 CA기관에 인증 요청을 한다.

가비아에 요청해서 codomo인증을 받았는데 아래와 같은 파일들을 보내줬다.

1. RootCA_ChainCAs_Basic.zip

2. Seal_sample.zip

3. contents_mytoon_com_csr.pem

4. contents_mytoon_com_cert.pem

여기서 2번은 인증마크 홈페이지에 붙이는샘플이고, 1번은 chain파일과 rootCA파일이 있다. 본인은 처음에 rootCA인증서는 뭐지? 했는데 이건 선택한 CA기관이 이 rootCA에 의해서 믿을만 한것이란 의미라고 한다. 아무튼 우리는 4번을 signed certificate으로 이용하면되고. 필요에 따라서 chainCA를 같이 쓰면되겠다.


  • self signed certificate 생성 명령어

$openssl x509 -req -days 365 -in csr.pem -signkey privkey.pem -out self-cert.pem

'서버 교양' 카테고리의 다른 글

[펌] 인증 암호화와 해쉬  (0) 2016.10.29
Docker overview  (0) 2015.06.13
글로벌 푸시 시스템 구성하기  (0) 2015.01.16
글로벌 푸시 보내기  (0) 2014.11.27
mongodb만 쓰면 mysql을 과연 안써도 될까?  (0) 2014.04.23
블로그 이미지

시간을 거스르는자

ytkang86@gmail.com

,

그놈의 timezone 그리고 망할 DST때문에 한동안 머리가 아팠다.

하지만 결국 답을 얻었다. 컴퓨터는 항상 답이 있다. 정말 좋다. I love it!

아무튼. 방법이 뭐냐면

일단 뭐 frequency를 어떻게 하냐는 자기 맘이겠지만, 일단 하루로 하고

1. 하루에 한번씩 모든 timezone name(예를 들어 Asia/Seoul)을 쭉 가져와서 각각의 offset을 테이블로 저장해서 redis나 memory 변수에 들고 있는다.

뭐 대강 이런 느낌일 것이다.

{

"+0900": ['Asia/Seoul', 'Asia/..', '...']

"+0830": [....],

....

}

이렇게 해보면 약 40개정도의 offset키에 모든 타임존 리스트가 정리되어진다.


2. 이제 우리에게 필요한 것은 푸시 예약이다.

푸시 예약은 두가지 방법으로 할 수 있다. 첫번째는 UTC기준 두번째는 각 지역기준.

만약 UTC기준이라면 전체 타임존에 동일한 시점에 일괄 발송하겠다는 것이다. 이때는 위에서 만든 타임존 오프셋 테이블을 쓸 필요없이 그냥 그 UTC시간이 되었을떄 일괄 발송하면된다.

두번째가 관건이다. 이것을 위해 이짓을 하는거니까. 바로 지역시간 기준.

자 지역시간 기준 12:00. 각 지역이 12:00가 되었을때 푸시를 보내는 것이다.

일단 12시를 UTC로 저장해 놓고 매 분 도는 스케줄러가 저 오프셋 테이블의 키값을 가져와서 UTC 시간에 오프셋을 더해서 그게 현재 시간이면 그에 해당하는 타임존 녀석들에게 푸시를 보내는 것이다. (물론 이것을 위해서는 유저정보에 타임존 네임이 있어야 할것이다)


자 나는 이렇게 구현할거고 서비스 할것이다. 으하하하 

'서버 교양' 카테고리의 다른 글

Docker overview  (0) 2015.06.13
SSL 인증서 발급  (0) 2015.03.04
글로벌 푸시 보내기  (0) 2014.11.27
mongodb만 쓰면 mysql을 과연 안써도 될까?  (0) 2014.04.23
쿠키런 서버사이드 이야기  (0) 2014.04.04
블로그 이미지

시간을 거스르는자

ytkang86@gmail.com

,

아직 구현된건 아니고 생각일뿐.

문제) 모든 유저에게 오후 1시에 푸시 메시지를 보내고 싶다. 그런데 세계의 각 지역은 당연히 시간이 다르거니와 같은 국가라도 시간이 다르며 또한 섬머타임으로 인해 같은 지역이라 해도 시간이 변동된다.


방법)

1. 유저는 회원가입할때 아래 정보를 서버에게 알려준다.

 - utc_offset(dst time적용되지 않았을때 offset), dst_offset(dst 적용되었을때 offset), dst_starttime, dst_endtime


2. 서버에서 푸시 예약 등록을 할때 13시 정보에 대해서 모든가능한 offset에 대해서 schedule 예약을 해둔다.

예) -12 ~ +14 까지.

이중에서 offset +2 가 보내질 시간이 되면 디비에서 다음에 해당하는 그룹을 가져와서 푸시를 보낸다.

그룹 1) utc_offset 이 2 이고 start, end time이 없는 유저 그룹

그룹 2) dst_offset 이 2 이고 now가 start, end time에 포함되는 그룹


근데 start end time 필드를 넣어놓고 쿼리 때리는게 넘 느려보인다.. 


블로그 이미지

시간을 거스르는자

ytkang86@gmail.com

,

물론 안써도 되게 만드는 방법이야 있겠지만 mysql을 쉽게 버릴수 없는 이유를 살펴보자.

mongoDB과 다르게 mysql의 장점은 트랜젝션이다.

트랜젝션은 atomic이 보장되고 중간에 실패하더라도 실질적인 영향을 미치지 않도록 할 수 있다. 하지만 mongodb같은 경우 각각의 쿼리들이 나눠있고 따로 불러야 하기 때문에 중간에 디비가 뻣거나 문제가 생길경우 대처하기가 어렵다.

그리고 atomic을 보장해야하는 상황을 예로들면 select하고 이 결과가 없다면 insert하는 하나의 트랜젝션은 중간에 다른 놈이 insert를 안했다는 보장을 받아야 한다. 하지만 nosql은 select와 insert가 나눠있기 때문에 select를 해왔을때는 없었지만 insert를 할때 없을거라는 보장을 할 수 없다. 

블로그 이미지

시간을 거스르는자

ytkang86@gmail.com

,
블로그 이미지

시간을 거스르는자

ytkang86@gmail.com

,

서버의 종류는 크게 두 종류로 본다.

Connectionless vs Connection

대부분의 웹서버는 소켓통신이 거의 없으므로 전자에 속하고, MMORPG와 같은 게임서버는 후자에 속하겠다. 물론 두가지를 섞어서 사용할 수 도 있지만 일단 이렇게 나눠본다.

첫번째 웹서버인 경우에 처리할 수 있는 유저수를 계산할때 전체 request의 평균 response time으로 시간을 계산한다고 한다. 그리고 후자인 경우는 몇몇 문제가 되는 악성? 해비한 유저들을 대상으로 시간을 계산한다고 한다.

본인은 웹서버를 개발하고 있기때문에, 한번 웹서버인 경우 하나의 머신으로 얼마나 유저를 받을 수 있을까 계산해보기로 한다.

예를들어 내가 서비스하고있는 모든 api들의 평균 응답속도가 30ms라고 하자.

이때, 모든 request가 sync request라면, 1초에 처리할 수 있는 request  수는 약 1000ms/30ms = 약 33개. async request 비율이 포함되어 있다면 33개 이상의 request를 처리할 수 있을 것이다.

33명이 1초에 한번씩 request를 날려도 무난한게 동작가능. 하지만 보통의경우 이렇게 미친듯이 날리지는 않으므로 실시간으로 1명의 유저가 약 5초에 한번씩 request날린다고 했을때,  33*5 = 165명 정도 실시간으로 처리 가능하다고 볼 수 있다. (물론 db시간과 그에 따른 io시간이 추가변수가 될수 있지만 30ms가 그것을 가만한 평균 request라고 가정)

또한 한개의 머신이 8코어를 쓴다고 가정하고 서버인스턴스를 8개 띄워놓았을경우 실시간으로 처리 가능한 유저수는 165*8 = 1320 이 된다. 

물론 이제 남은건 db병목이다. nosql만 쓴다고 가정하면 샤딩등으로 디비를 분할해서 문제를 해결할 수 있다. mongodb같은경우 profiler를 써서 어떤 request가 response time이 기준 응답속도를 벗어났는지 분석해서 문제를 해결하는것이 노하우가 되겠다.

번외) 실시간 1000명정도면 아마 DAU는 10만이상이 될것이다. 만약 이중 1%가 만원씩 결제한다고 한다면 1000만원! 뭐.. 그럴거 같다는 얘기다. 

'서버 교양' 카테고리의 다른 글

SSL 인증서 발급  (0) 2015.03.04
글로벌 푸시 시스템 구성하기  (0) 2015.01.16
글로벌 푸시 보내기  (0) 2014.11.27
mongodb만 쓰면 mysql을 과연 안써도 될까?  (0) 2014.04.23
쿠키런 서버사이드 이야기  (0) 2014.04.04
블로그 이미지

시간을 거스르는자

ytkang86@gmail.com

,