'docker'에 해당하는 글 8건

Kubernetes 란

Tool/Kubernetes 2019. 3. 12. 00:10


쿠버네티스는 운영 수준에서 컨테이너 오케스트레이션(컨테이너화된 애플리케이션을 자동으로 배포, 스케일링 및 관리) 기능을 하는 오픈소스 시스템이다. GO 언어로 구현이되었으며, 구글에서 설계를 했지만 오픈소스로서 특정 벤더나 플랫폼에 종속되지 않기 때문에, 대부분의 클라우드/온프레미스 등에 사용이 가능하다. 비슷한 기능을 하는 솔루션으로 Docker Swarm, Mesosphere, OpenStack, CloudFoundry 등이 있지만 Kubernetes 로 표준화되어 가고 있다. 쿠버네티스(Kubernetes) 는 K8s 라고도 하는데 K"ubernete"s 가운데 8글자를 "8"로 대체한 약어이다. 우선 쿠버네티스가 실전에서 어떻게 사용되는지를 먼저 보는 것이 쿠버네티스의 용도를 파악하기 쉬울 것 같다.


쿠버네티스를 사용한 어플리케이션 여러 배포 방법 중 하나의 과정을 적어봤다.


  1. 뚝딱뚝딱 서비스할 어플리케이션(A) 만들기.
  2. 쿠버네티스를 제공하는 클라우드 서비스에서 어플리케이션(A)가 운영될 클러스터 생성 및 리소스 설정
  3. 어플리케이션(A)을 컨테이너화하고 쿠버네티스에 배포 <- 운영 시작
  4. 스케일링 설정으로부터 파드(Pod) 수를 조절하며 업데이트 및 롤백 가능


큰 그림 위주의 단계만 적어놓아 이해에 부족함이 있을지도 모르겠다. 위 단계처럼 쿠버네티스는 배포 시스템이며, 안정적으로 운영을 하기 위한 여러 기능을 제공하고 있다. 기존 웹서버에 ELB 와 오토스케일링을 붙이는 방식보다 컨테이너 배포 시스템이 더 나은 점은 빠르고 안정적인 배포와 확장이다. 규모가 커질수록 컨테이너 방식이 월등하다. 다운될 일이 전혀 없는 작은 서비스를 운영하고 있고, 앞으로도 큰 서비스를 개발할 계획이 절대 없다면 이러한 컨테이너 서비스를 사용할 필요가 없다. 제대로 사용하기까지 드는 시간과 노력의 비용이 훨씬 많이 들기 때문이다. 쿠버네티스에 일찍 올라타진 못했지만 많은 사람들이 컨테이너 오케스트레이션 중에는 쿠버네티스를 가장 선호하고 있으며, GitKube 나 Jenkins X 등 Kubernetes 를 더 편리하게 사용할 수 있도록 많은 툴들이 확장되고 있다. 컨테이너 서비스에 관심이 많거나, 최소 트래픽 분산 환경의 웹서버를 운영하는 종사자, 또는 앞날이 창창한 신입 개발자들에게 반드시 도움이 되는 시스템이라고 생각한다.



* 더 도움이 되는 사이트

쿠버네티스 공식 문서(부분 한글) - https://kubernetes.io/docs/home/

조대협(조병욱) 님의 블로그 - https://bcho.tistory.com/1255




WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

트랙백  0 , 댓글  0개가 달렸습니다.
secret

운영 서버에서 docker 를 사용하다 보면 사용하지 않는 image 및 container 등이 늘어나 디스크 공간을 차지하기 마련이다. 그래서 아래의 명령을 cron 으로 스케줄링하여 무쓸모 image 및 container 는 삭제하는 것이 좋다. (참고로 AWS ECS 에서는 ECS 컨테이너 에이전트가 컨테이너 인스턴스에서 사용하지 않은 이미지/컨테이너 등을 자동으로 정리해 준다. 오홍~)


$ docker rm $(docker ps -a)

$ docker rmi $(docker images -a)


하지만 로컬 호스트의 경우 운영 서버와는 다르게 각종 이미지들이 쌓여 있을 것이고 지워야 할 것들과 지우지 말아야 할 것들을 구분해야 한다. 위 명령으로 실행중이지 않은 모든 이미지와 컨테이너를 삭제해도 큰 문제는 없지만 다시 필요한 이미지를 생성하거나 다운받아야 하는 불편함이 생길 수 있다. 혹여라도 대기 중인 image 를 삭제하지 않게 prune 명령을 사용하여 dangling 이미지, 컨테이너, 볼륨, 네트워크를 삭제하는 것이 좋다.


$ docker container prune -f

$ docker image prune -f



Prune images


$ docker image prune -f
cs


컨테이너에서 태그가 지정되지 않고 어느 컨테이너에서도 참조하지 않는 dangling image 를 삭제한다. 모든 이미지 리스트(docker images -a) 에서 repository 와 tag 가 <none> 으로 설정되어 있는 이미지 중 어느 컨테이너에서도 참조하고 있지 않은 이미지를 dangling image 라고 한다. 이 dangling image 는 별다른 설정이 없다면 다시 사용되지 않을 이미지들이며, 동일한 repository:tag 로 이미지가 생성되어 기존 이미지에 덮어씌워질 때 나타난다.

docker rmi $(docker images -f "dangling=true") 명령과 동일하다. 이 명령으로 이미지가 삭제되지 않았다면 다른 컨테이너에서 참조 중이거나 이미 실행중인 것이다. --force(-f) 플래그는 강제 삭제가 아닌 프롬프트 무시 플래그이다.


$ docker image prune -a -f
cs


컨테이너가 생성되지 않은(실행 및 중지 상태가 아닌) 모든 이미지를 삭제한다. 종료되었지만 프로세스에 남아있는 컨테이너의 이미지는 삭제하지 못한다. docker rmi -f $(docker images -a) 명령은 위 명령과 비슷하지만, 프로세스에 남아있는 종료된 컨테이너의 이미지도 삭제한다.


이미지가 많아서 필터링이 필요한 경우는 아래와 같이 --filter 플래그를 사용할 수 있다. --filter "key=value" 형식이며, 여러 개의 --filter 플래그를 같이 사용할 수 있다. 필터링에 사용할 수 있는 key 는 특정 시간 이전에 생성된 이미지를 지정하는 until 과 label 일치 여부로 비교하는 label 이 있다.


$ docker image prune -f -a --filter "until=24h"
$ docker image prune -a --force --filter "until=2017-01-04T00:00:00"
$ docker image prune --filter="label=deprecated"
$ docker image prune --filter="label=maintainer=john"
$ docker image prune --filter="label!=maintainer"
$ docker image prune --filter="label!=maintainer=john"
cs



Prune containers


컨테이너는 docker run 으로 시작할 때 --rm 플래그를 지정하지 않으면 컨테이너 중지시에 자동으로 제거되지 않는다. docker ps -a 명령으로 호스트의 모든 컨테이너, 실행 중이거나 중지된 모든 컨테이너를 확인할 수 있으며, 중지된 컨테이너의 디스크 공간을 확보하기 위해 docker container prune 명령을 사용할 수 있다. 위 docker image prune 과 마찬가지로 필터링을 사용할 수 있다.


$ docker container prune
$ docker container prune --filter "until=24h" 
cs


마찬가지로 volume 과 network 도 prune 명령으로 제거할 수 있다.




WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

트랙백  0 , 댓글  0개가 달렸습니다.
secret

ECS Task

Server/AWS 2018. 8. 17. 22:16

Image 를 푸시하고 Cluster 를 생성하면 Image 를 구동할 수 있는 것처럼 얘기했지만, 해야 할 것이 하나 더 있다.


Docker 저장소의 Image 는 ECS 에서 사용하기 위해 Task 라는 작업에 정의해야 한다. 이 task 정의에는 실행할 이미지, 컨테이너 사양, 포트 등을 설정할 수 있으며, 이러한 Task 정의로부터 특정 ECS Cluster 를 선택하여 실행시킬 수 있다. Image 는 여러 Task 정의에서 가져다 쓸 수 있으며 Task 정의 역시 여러 Cluster 에서 실행시킬 수 있다.


이번에는 Task 정의를 생성하여 사용할 Image 를 설정해 보겠다.



1. 아키텍처 설계


컨테이너 서비스인 ECS 를 사용하여 어플리케이션을 운영한다는 것은 아키텍처 면에서 기존 방식과 조금씩 차이가 있을 수 있다. (이건 각자 알아서 ㅜ) 하나의 이미지를 여러 인스턴스에서 실행할 것인지 하나의 인스턴스에 여러 이미지를 실행할 것인지 등을 생각해 보아야 한다. 일단 하나의 Docker 이미지로 웹 서버 2대를 사용한다고 했을 때 필요한 것은,


web Image:1 -> web Task 정의:1 -> web Cluster (EC2:2)


이렇게 구성하면 될 것이다. 2 대의 인스턴스를 로드 밸런서에 묶기 위해 Cluster 에 Service 라는 것도 추가해야 하지만 일단 생략했다. 공통 모듈을이나 구성 요소에 따라, 하나의 task 정의에 여러 컨테이너(Image) 를 정의할 수도 있을 것이고... 일단 가장 심플하게 가보자.



2. Task 정의 생성


먼저 콘솔의 ECS - Task Definitions - [Create new Task Definition] 을 선택한다. ECR 에서도 잠시 거론했지만, Task 정의도 가장 먼저 선택하는 것이 시작 유형이다. Fargate / EC2 인스턴스 시작 유형 중 하나를 가장 먼저 선택하게 되고, 선택한 시작유형에 따라 미세하게 설정에 차이는 있다. Network 모드나 Port 설정 등... ECS Document 에 보면 Task 정의를 Dockerfile 처럼 json 파일로 정의할 수 있게 만들어놨는데, 그걸 먼저 보면 토나온다. 설정하는 것은 몇개 안되는데 모든 항목들이 다 나와 있어서 매우 복잡해 보이지만, 콘솔 대신 json 파일로 작업해야 한다면 콘솔에서 제공하는 json 형태의 스크립트에서 설정할 항목만 뽑아서 가져다 쓰면 된다. EC2 인스턴스 시작 유형을 선택했다면 이것저것 설정할 항목이 많아 보이는데, 대부분 Default 로 두면 되고 설정할 것은 몇 개 안된다.


- Task 정의 이름

- Add container : 사용할 Image 의 Repository URI, 이 컨테이너에 할당할 메모리/CPU, Port 매핑


메모리와 CPU 는 사용할 인스턴스 사양과 추가할 컨테이너들을 고려하여 설정한다. 이게 끝이다. ㅋㅋ 컨테이너 Image 나 메모리/CPU, 포트 매핑 등을 수정하기 위해 task 를 업데이트 하면 새로운 리비전이 추가된다. 아마도 운영중에는 크게 수정할 일이 없을 것이다.



3. Task 실행


구동을 확인해 보고 싶다면, Task 정의 리스트에서 Task 정의를 선택하고 [Run Task] 를 클릭하여 실행할 Cluster 를 선택하고 Number of tasks 수를 입력하면 끝. 혹은 Cluster - Tasks 에서 [Run new Task] 를 선택해도 결과는 동일하다. Number of tasks 수를 2 로 지정하면 두 개의 인스턴스에서 Task 가 독립적으로 실행될 것이다. Cluster 에 지정된 인스턴스 수가 한 개라면 한 개의 Task 만 실행된다. Task 가 실행되고 나면 PENDING 상태에 돌입하고 수초내에 정상적인 인스턴스에서 실행되고 있다는 뜻의 RUNNING 상태가 된다. Cluster 에 등록된 인스턴스에서 Task 정의의 Image 를 실행시킬 것이고, Public DNS 를 통해 Image 구동을 확인할 수 있다. Task 를 Stop 시키면 인스턴스에의 task 도 곧 중지된다. 개발 중에는 이렇게 로드 밸런서를 통하지 않고 Task 정의를 클러스터에 다이렉트로 실행시켜서 바로 Image 를 확인할 수 있다.




WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

트랙백  0 , 댓글  0개가 달렸습니다.
secret

AWS ECR

Server/AWS 2018. 8. 15. 00:33

ECS 를 시작하기 전에 가장 먼저 어플리케이션을 이미지로 만들어 ECR(Elastic Container Registry) 에 등록을 해 보자. ECR 에 이미지를 등록하는 것은 ECS 와 연계되는 부분이 거의 없으므로 ECS 를 몰라도 상관없다. 이미지 등록에만 집중하자.


ECS 를 몰라도 상관없다고 말했지만, 꼭 집고 넘어가야 할게 있다. ㅜ ECS 를 사용할 때 사용자가 선택할 수 있는 두 가지 선택지가 있다. 하나는 인스턴스로서 EC2 를 사용할지 Fargate 를 사용할지이고 (이를 시작 유형이라고 함), 또 하나는 Docker Registry 를 공개용(public) 으로 구성할지 비공개용(private) 으로 구성할지 이다. Fargate 라는 것은 컨테이너를 위한 EC2 등의 인스턴스를 필요로 하지 않고 컨테이너 자체를 배포하는 아마존의 기술이다. 지금은 몰라도 된다. 하지만 알고 싶다면... EC2 에서 돌아가던 것이 EC2 없이도 어디선가 돌아간다 라고 생각하면 쉽다; 그만큼 EC2 등의 인스턴스를 관리하는 노력이 줄어드니까 더 좋다고도 볼 수 있다. EC2 를 컨트롤 하는 것 처럼 정밀한 제어는 힘들겠지만. 아무튼 좋아보이니 비싸기도 하다. EC2 시작 유형을 사용해보면 Fargate 설정은 훨씬 더 쉬우므로 EC2 시작 유형 기반으로 설명할 것이다. 아마도 대부분이 실전에서는 private 저장소를 사용하게 될텐데, 혹시라도 public 저장소를 사용하게 되면 EC2 인스턴스 유형을 사용할 수 없다. 즉 EC2 인스턴스 유형은 private 저장소만 지원한다. 이를 유념하도록 하고... ECS 에서 Docker Registry 는 ECR 말고도 아마 거의 다 지원할 것이다. Docker Hub, self-hosted registry 등...


여기서는 아마존 패밀리인 ECR 을 사용해 보도록 하겠다.



1. Docker 이미지 생성


docker 이미지를 생성하려면 Docker 를 설치하고 데몬을 실행시켜 docker cli 를 사용할 수 있어야 한다. (여기까지는 알아서 잘 해보자 ㅜ)

그리고 이미지 설정 파일인 dockerfile 을 만들어 필요에 맞게 구성한다.

나는 다음과 같이 tomcat 에서 구동하는 war 파일에 ssl 통신이 가능하도록 이미지화 하는 dockerfile 을 만들었다. (이것도 본인 필요에 맞게 알아서 잘 해보자;)


$ vi dockerfile
FROM tomcat:8.0-jre8-alpine
RUN ["rm""-rf""/usr/local/tomcat/webapps/ROOT"]
COPY ["./keystore""./server.xml""./web.xml""/usr/local/tomcat/conf/"]
COPY ./build/libs/WEB-0.0.1-SNAPSHOT.war /usr/local/tomcat/webapps/ROOT.war
cs


dockerfile 기반으로 hello-world 라는 이미지를 생성하고 확인한다.


$ docker build -t hello-world .
$ docker images --filter reference=hello-world
$ docker run -p 8080:8080 hello-world
cs


해당 포트의 반응이 없을 경우, 서버나 VirtualBox VM 에서 컨테이너 포트에 인바운드 트래픽이 허용되어 있는지 체크한다. 



2. ECR 에 저장소 생성


이미지가 정상적으로 생성되었다면, AWS Docker Registry 인 ECR 에 푸시를 해보자.

그 전에 ECR 에 이미지를 푸시하기 위해서는 AWS cli 가 반드시 필요하다. 로그인 및 푸시 명령이 AWS cli 으로만 가능하다. 알아서 cli 를 설치한다. ㅜ

먼저 콘솔이나 cli 로 ECR 에 특정 이름의 저장소를 생성한다.

cli 를 사용할 때는 root 계정을 사용하지 말고 ECS 용 IAM 계정을 새로 생성하고 profile 에 등록하는 편이 낫다. 해당 key 로 profile 에 자격증명 및 리전 등록하는 것은 생략.


$ aws ecr create-repository --repository-name hello-world-repo
{
    "repository": {
        "registryId": "aws_account_id",
        "repositoryName": "hello-world-repo",
        "repositoryArn": "arn:aws:ecr:us-east-1:aws_account_id:repository/hello-world-repo",
        "createdAt": 1505337806.0,
        "repositoryUri": "aws_account_id.dkr.ecr.us-east-1.amazonaws.com/hello-world-repo"
    }
}
cs


콘솔을 이용하던 cli 를 이용하던 저장소를 생성하고 나면 이미지를 푸시할 주소인 repositoryUri 를 확인할 수 있다.

repositoryUri 에는 12 자리 숫자의 aws_account_id, 리전, 저장소 이름이 포함되어 있다.



3. ECR 로 이미지 푸시


저장소를 생성했으면 이미지를 푸시하면 되는데, 그러기 위해서는 푸시할 이미지를 repositoryUri 값으로 태그 지정해야 한다.


$ docker tag hello-world aws_account_id.dkr.ecr.us-east-1.amazonaws.com/hello-world-repo
cs


태그 지정을 마쳤으면 푸시를 하기 전에 ECR 에 로그인 과정을 거쳐야 한다.(참 번거롭다.ㅜ)


$ aws ecr get-login --no-include-email
cs


위 명령을 입력하면 로그인에 필요한 명령어를 포함한 12시간 짜리 토큰이 발급된다.


docker login -u AWS -p ...base64 encoding token...very...long...  https://aws_account_id.dkr.ecr.us-east-1.amazonaws.com
cs


이와 같은 형태인데 이 부분을 그대로 복붙했다가는 프로세스 목록(ps) 에 토큰이 다 노출되게 되므로 패스워드 옵션(-p) 전까지만 입력하고 대화형 방식으로 토큰을 입력하던지 eval 명령을 사용한다.


$ eval $(aws ecr get-login --no-include-email)
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
Login Succeeded
cs


마지막으로 repositoryUri 태그가 달린 이미지를 푸시한다.


$ docker push aws_account_id.dkr.ecr.us-east-1.amazonaws.com/hello-world
cs


ECS - Repositories 에서 푸시된 이미지 확인.



나중에 어떤 식으로든 자동화를 해야겠지만 일단 이렇게 번거로운 과정을 거치면 비로소 ECR 에 이미지를 푸시할 수 있게 된다.

수정된 이미지를 다시 푸시할 경우에 토큰이 만료됐다면 위 로그인 과정을 다시 거쳐야 한다.

사실 ECR 이 다른 저장소에 비해 나은 점이나 편한 점은... 아직 못찾았다. 잘들 찾아보시길...




WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

트랙백  0 , 댓글  0개가 달렸습니다.
secret

Amazon ECS

Server/AWS 2018. 8. 13. 19:50

Amazon Elastic Container Service(ECS) 는 클러스터에서 도커 컨테이너를 손쉽게 실행, 중지 및 관리할 수 있게 해주는 컨테이너 관리 서비스이다.

도커 이미지로 Auto scaling, LB, EC2 등과 통합하여 서비스 하고자 할 때 좋은 선택이 될 수 있으며, 무중단 배포가 간편하다는 가장 큰 장점이 있다.





위 그림은 ECS 의 전반적인 아키텍처를 나타낸 것이다.

요점은 배포할 어플리케이션을 이미지 저장소로부터 가져와서 원하는 수 만큼의 인스턴스(EC2 등) 에 배포한다는 것이다.

Docker 의 Cluster, Stack, Service, Task 등과 거의 같은 기능들을 하지만, 비슷하면서도 다르다... ㅡ.ㅡ;


다시 어플리케이션을 ECS 를 통화 배포하는 세분화된 단계를 보자면,


1. 배포할 어플리케이션을 docker 이미지로 생성한다.

2. 해당 이미지를 어디서든 가져올 수 있도록 docker 레지스트리(ECR, docker hub 등) 에 등록한다.


여기까지는 주로 docker 에 관련된 내용이다. docker 레지스트리는 docker 이미지를 버전관리 할 수 있으며, 버전관리 측면에서 github 와 비슷한 기능을 한다.


3. ECS 의 최상위 리소스인 cluster 를 생성한다. 이 때 VPC 설정으로 네트워크의 영역을 정의하며, 사용할 인스턴스 타입/사양 등을 선택한다.

4. 가장 중요한 task 정의를 생성한다. 이 정의에는 사용할 이미지, 포트, 컨테이너 사양 등을 정의한다.

5. 특정 cluster 에서 task 를 효율적으로 관리할 service 를 생성한다. 이 service 구성에는 실행할 task 정의, 실행할 인스턴스 수, LB, Auto Scaling 등을 설정할 수 있다.


여기까지는 일반적으로 EC2 를 생성할 때 구성했었던 VPC, Subnet, Secure group, Key-pair, LB, Auto scaling 과 ECS 를 구성하는 Cluster, Service, Task 등을 설정했다. Cluster - Service - Task 의 상관 관계가 조금 복잡해 보일 수 있는데,


하나의 Cluster 에는 하나 이상의 Service 를 생성할 수 있으며, 생성된 Service 는 해당 Cluster 에서만 사용된다.

하나의 Service 에는 하나의 task 및 인스턴스 수를 관리할 수 있다.

생성된 Task 정의는 하나 이상의 Cluster 또는 하나 이상의 Service 에서 실행될 수 있다.


ECS 의 완성은 Cluster 에서 Task 정의를 실행하는 것이다. 이것이 곧 배포이다. task 정의는 Service 없이도 Cluster 에서 직접 실행 시킬 수 있지만, Service 를 생성하므로써 더 효율적으로 task 를 관리할 수 있다. LB, Auto scaling, 순차 배포 등. 많은 사용자들이 도커 이미지로 Auto scaling, LB, EC2 등과 통합하여 무중단 배포로 서비스 하기 위해 이 ECS 를 선택하게 될 것이다.




WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

트랙백  0 , 댓글  0개가 달렸습니다.
secret