도커는 빌드한 이미지를 서버에 배포하기 위해 직접 파일을 복사하는 방법 대신 도커 레지스트리(Docker Registr)y라는 이미지 저장소를 사용한다.
도커 명령어를 이용하여 이미지를 레지스트리에 push 하고 다른 서버에서 pull 받아 사용하는 구조로 git과 비슷하다고 생각하면 될 것 같다.
도커 레지스트리는 오픈소스로 무료로 설치할 수 있고 설치형이 싫다면 도커(Docker Inc.)에서 서비스 중인 도커 허브Docker Hub를 사용할 수 있다.
도커 허브는 도커에서 제공하는 기본 이미지 저장소로 ubuntu, centos, debian등의 베이스 이미지와 ruby, golang, java, python 등의 공식 이미지가 저장되어 있다.
일반 사용자들이 만든 이미지도 50만 개가 넘게 저장되어 있고 다운로드 횟수는 80억 회를 넘는다고 한다.
이전에 만들었던 Ruby 웹 어플리케이션 이미지를 docker hub에 저장해보자.
이전 게시물 → [Docker] Docker 이미지 만들고 컨테이너 생성하기
나는 이전에 만들었던 웹 어플리케이션 (이름 : app)을 가상머신에서 도커허브로 올린 다음
회사에서 할당받은 서버에서 내려 받으려고 한다.
할당받은 서버에서도 app.rb가 똑같이 작성되어 있고 컨테이너 이미지가 모두 존재하기 때문에
만일 하나를 대비하여 차이점을 주기 위해 app.rb 의 코드를 수정하여 다시 이미지 빌드를 하였다.
require 'sinatra'
require 'socket'
get '/' do
"Hello World! This is #{Socket.gethostname}"
end
docker build -t app .
다음 DockerHub 도커허브 사이트에 접속해서 회원가입을 먼저 해주자.
도커에서 도커 허브 계정을 사용하려면 로그인을 해야 한다.
docker login
Docker ID 또는 이메일 주소로 로그인하여 Docker Hub에서 이미지를 푸시하고 가져오세요. Docker ID가 없으면 https://hub.docker.com/으로 이동하여 ID를 만드세요.
비밀번호나 PAT(Personal Access Token)를 사용하여 로그인할 수 있습니다. 제한된 범위의 PAT를 사용하면 보안이 강화되며 SSO를 사용하는 조직에 필요합니다. https://docs.docker.com/go/access-tokens/에서 자세히 알아보세요.
사용자 이름: dksek3050
비밀번호:
경고! 귀하의 비밀번호는 /home/user/.docker/config.json에 암호화되지 않은 상태로 저장됩니다.
이 경고를 제거하려면 자격 증명 도우미를 구성하십시오. 보다
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
로그인 성공
영어 울렁증 있는 나는 냅다 번역기 돌려버림
비밀번호가 config.json 파일에 무려 암호화가 되지 않은 상태로 저장된다고 한다.
비밀번호를 통합해서 쓰는 나는 간단 비밀번호로 바꿔주었다.
그리고 config.json 당장 들어가버림.
어라 암호화 안되어 있다고 했는데 인코딩만 되어 있는거 같다. 디코딩해보자
헉 바로 바로 보인다. 비밀번호 또 바꾸러가야지 총총 ..
회사 서버를 쓰거나 공용으로 접속할 수 있는 서버에서 실습을 진행하는 사람들은 본인이 자주 쓰는 비밀번호는 사용하지 않으며 비밀번호가 노출되지 않도록 주의해야 할 것 같다.
config.json 파일에 저장된 정보가 로그아웃하기 전 까지 로그인 정보가 유지된다.
추가적으로 로그아웃 하게 되면 config.json에 있는 내용은 지워진다 !
도커 이미지 이름은 다음과 같은 형태로 구성된다.
[Registry URL]/[사용자 ID]/[이미지명]:[tag]
Registry Url은 기본적으로 도커 허브를 바라보고 있고 사용자 ID를 지정하지 않으면 기본 값(library)을 사용한다. 따라서 ubuntu = library/ubuntu = doker.io/library/ubuntu 는 모두 동일한 표현이다.
도커의 tag 명령어를 이용하여 기존에 만든 이미지를 추가로 이름을 지어 줄 수 있다.
docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
이전에 만든 app 이미지에 계정 정보와 버전 정보를 추가해보자.
docker tag app anna/anna-app:1
“anna 라는 ID를 사용”하고 이미지 이름을 anna-app으로 변경하였다.
첫번째 버전이므로 태그는 1로 지정하였다.
이미지 목록을출력해보면 app 과 anna/anna-app이 모두 존재함을 알 수 있는데 image를 보니 같은 아이디를 가지고 있는 걸로 보아 같은 이미지를 참조하고 있음을 확인 할 수 있었다.
이제 push
라는 명령어를 이용하여 도커 허브에 이미지를 올려보자.
docker push anna/anna-app:1
어라 ? 거부됐다 왜지 ?
찾아보니 **Docker Hub에 로그인한 ID외 이미지의 유저 ID가 달라서**
이다.
이미지 태그를 재설정해주자.
docker tag app dksek3050/anna-app:1
docker push dksek3050/anna-app:1
성공 !
이제 도커 허브에 저장된 50만 개의 이미지에 새로운 이미지가 하나 추가되었다.
이제 어디서든 dksek3050/anna-app:1
이미지를 사용할 수 있다.
도커 이미지를 비공개로 저장하려면 Docker Cloud를 유료로 사용하거나
도커 Registry 서버를 자체적으로 구축해야합니다.
나는 도커 레지스트리 서버를 구축해서 그 서버에 이미지를 저장해보겠다.
도커 레지스트리 서버도 도커 이미지를 다운받아 컨테이너를 띄어서 구축할 수 있다.
도커 레지스트리에 저장된 이미지는 파일로 저장되기 때문에 호스트(로컬)의 디렉토리를 마운트 해야한다. (S3 저장소를 사용할 수도 있다.)
docker run -d \
-v $PWD/registry:/var/lib/registry \
-p 5000:5000 \
distribution/registry:2.6.0
-v $PWD/registry:/var/lib/registry
: 호스트 시스템의 현재 디렉토리에 있는 registry
디렉토리를 컨테이너 내부의 /var/lib/registry
디렉토리와 연결한다.-p 5000:5000
: 호스트의 포트 5000과 컨테이너의 포트 5000을 매핑distribution/registry:2.6.0
: 사용할 Docker 이미지를 지정한다.이제 레지스트리 서버의 아이피와 포트 정보를 이미지 명에 추가하면 바로 사용할 수 있다.
docker tag app localhost:5000/dksek3050/anna-app:1
app
이라는 이름의 Docker 이미지를 localhost:5000/dksek3050/anna-app:1
이라는 태그로 다시 태그app
: 이미지의 현재 이름이며, 빌드된 Docker 이미지의 이름이다.localhost:5000/dksek3050/anna-app:1
: 새 태그로, 이것은 레지스트리 호스트 localhost
의 포트 5000에 있는 Docker 레지스트리의 dksek3050
네임스페이스 아래에 anna-app
리포지토리의 버전 1을 나타낸다.docker push localhost:5000/**dksek3050**/**anna**-app:1
localhost:5000/dksek3050/anna-app:1
: 푸시 할 이미지의 목적지이다. 앞서 태그한 이미지인 localhost:5000/dksek3050/anna-app:1
을 로컬 Docker 레지스트리에 푸시한다.이제 레지스트리 서버에 이미지가 파일로 잘 저장되었는지 마운트 된 디렉토리를 살펴보자.
tree registry
user@user-VirtualBox:~$ tree registry
registry
└── docker
└── registry
└── v2
├── blobs
│ └── sha256
│ ├── 20
│ │ └── 20b669cab462d559d98bcf239b5af8845b32ea3b0eade1cf37d1f0a08748c14f
│ │ └── data
│ ├── 26
│ │ └── 262c764cde3bf49fbbe7b12253dfeb14cd14eec4ac7ee11309946c8423777833
│ │ └── data
│ ├── 4f
│ │ └── 4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1
│ │ └── data
│ ├── 6c
│ │ ├── 6ccac03c405d0a8003c6e7681d43ead31346aec0bcf66f2e022e1aab3b7ed1b6
│ │ │ └── data
│ │ └── 6cdaa9e5748ae6aae5c76730ad8c34dd0594aa3c1e165ea9970475d817335cee
│ │ └── data
│ ├── a0
│ │ └── a07bfac88e40c4c6a1c139d31f41c8af375e5028c51cdb5cecb86032117d4621
│ │ └── data
│ ├── b2
│ │ └── b2a4edb7bfbd9b5d00fb86ecd4df90e3d723a984320d1818fcb3a6b387131e8c
│ │ └── data
│ ├── df
│ │ └── df2fac849a4581b035132d99e203fd83dc65590ea565435a266cb0e14a508838
│ │ └── data
│ ├── f9
│ │ └── f9841d926cf5e1a20e500f332b6c93dc294f09f6e5b876e3d994946d53b6c40a
│ │ └── data
│ └── fb
│ └── fbfce4c3047e0b27a1007eaa604026ffa41592fe5f3e60582b52345864cb3abd
│ └── data
└── repositories
├── dksek3050
│ └── anna-app
│ ├── _layers
│ │ └── sha256
│ │ ├── 20b669cab462d559d98bcf239b5af8845b32ea3b0eade1cf37d1f0a08748c14f
│ │ │ └── link
│ │ ├── 262c764cde3bf49fbbe7b12253dfeb14cd14eec4ac7ee11309946c8423777833
│ │ │ └── link
│ │ ├── 4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1
│ │ │ └── link
│ │ ├── 6ccac03c405d0a8003c6e7681d43ead31346aec0bcf66f2e022e1aab3b7ed1b6
│ │ │ └── link
│ │ ├── 6cdaa9e5748ae6aae5c76730ad8c34dd0594aa3c1e165ea9970475d817335cee
│ │ │ └── link
│ │ ├── a07bfac88e40c4c6a1c139d31f41c8af375e5028c51cdb5cecb86032117d4621
│ │ │ └── link
│ │ ├── b2a4edb7bfbd9b5d00fb86ecd4df90e3d723a984320d1818fcb3a6b387131e8c
│ │ │ └── link
│ │ ├── df2fac849a4581b035132d99e203fd83dc65590ea565435a266cb0e14a508838
│ │ │ └── link
│ │ └── fbfce4c3047e0b27a1007eaa604026ffa41592fe5f3e60582b52345864cb3abd
│ │ └── link
│ ├── _manifests
│ │ ├── revisions
│ │ │ └── sha256
│ │ │ └── f9841d926cf5e1a20e500f332b6c93dc294f09f6e5b876e3d994946d53b6c40a
│ │ │ └── link
│ │ └── tags
│ │ └── 1
│ │ ├── current
│ │ │ └── link
│ │ └── index
│ │ └── sha256
│ │ └── f9841d926cf5e1a20e500f332b6c93dc294f09f6e5b876e3d994946d53b6c40a
│ │ └── link
│ └── _uploads
73 directories, 34 files
이미지가 레이어 별로 예쁘게 저장된걸 확인할 수 있다.
도커 레지스트리는 일반적인 HTTP 프로토콜을 사용하여 이미지를 전송한다. 따라서 SSL(HTTPS)을 사용하지 않으면 이미지 내용이 유출될 수 있다. 이런 보안 이슈 때문에 도커는 기본적으로 로컬(localhost) 서버를 제외하곤 HTTP 사용을 금지하고 있으며 이런 보안위험을 무시하려면 도커 엔진을 실행할 때 허용 옵션을 넣어야 한다.
관련 설정은 문서를 참고
개인 저장소를 만드는 법은 매우 간단했다.
이제 내부적으로 이미지를 관리하고 여러 서버에 배포 할 수 있다.
드디어 드디어 서버 관리의 꽃! 배포deploy를 해보겠다!
기존에 어플리케이션을 배포할때는 사용하는 언어, 프레임워크, 웹, 리눅스 배포판, 개발자의 취향등에 따라서 각각 다른 방식을 사용하였다.
새로운 서버를 세팅하고 한번에 배포를 성공한다는건 힘든 일이었고 검증하기도 어려웠다.
그러나 컨테이너를사용하면 어떤 언어, 어떤 프레임워크를 쓰든 상관없이 배포 방식이 동일해지고 단순해진다.
그냥 이미지를 받고 컨테이너를 실행하면 끝이다. !
docker pull dksek3050/anna-app:1
docker run -d -p 8080:4567 dksek3050/anna-app:1
차란 배포 성공 ! 이제 저 ip랑 구매한 도메인이랑 연결 시켜주면 우리가 사용하는 웹서비스가 완성되는것이다. (대충)
도커를 사용하면 업데이트 방식도 배포와 큰 차이는 없다.
최신 이미지를 기반으로 새 컨테이너를 만들고 이전 컨테이너를 중지 및 삭제를 하면 된다.
최신 소스를 어떻게 복사할지 서버 프로세스는 어떻게 재시작을 할지 고민할 필요가 없다.
그냥 통째로 바꾼다.
이런 방식은 매우 단순하지만, 컨테이너가 멈추는 순간 실행 중인 프로세스가 종료되고 프로세스가 종료되면 고객들은 접속이 안 되고 접속이 안 되면 매출이 떨어지고 매출이 떨어지면 월급이 안나오기 때문에 무중단을 고려한 nginx나 HAProxy같은 로드 발란서Load Balancer와 2대 이상의 컨테이너를 사용해야 한다.
그것에 대해서는 다음에 알아보자.
이렇게 해서 초보 Docker 입문은 끝이 났다.
다음번에는 프로젝트로 만들었던 spring을 한번 띄워보자..
📎 참고 링크
https://subicura.com/2017/02/10/docker-guide-for-beginners-create-image-and-deploy.html