도커/쿠버네티스 컨테이너 개발 실전 입문 · · 9 min read
CH02. 도커 컨테이너 배포
1. 컨테이너로 어플리케이션 실행하기
도커 이미지 : 도커 컨테이너를 구성하는 파일 시스템과 실행할 어플리케이션 설정을 하나로 합친 것으로 컨테이너를 생성하는 템플릿 역할을 한다.
도커 컨테이너 : 도커 이미지를 기반으로 생성되며, 파일 시스템과 어플리케이션이 구체화되어 실행되는 상태
도커 이미지와 도커 컨테이너
- 테스트 이미지 받아오기
$ docker image pull gihyodocker/echo:latest $ docker image list - 받아온 이미지를 기반으로 컨테이너 생성 및 포트포워딩
$ docker container run -t -p 9000:8080 gihyodocker/echo:latest - 터미널을 하나 더 띄워 테스트
$ curl http://localhost:9000/ - 컨테이너 정지
- 컨테이너의 아이디를 알아온다.
$ docker container list - 알아온 컨테이너 아이디를 stop 시킨다.
$ docker container stop [container id]
- 컨테이너의 아이디를 알아온다.
- 테스트 이미지 받아오기
간단한 애플리케이션과 도커 이미지 만들기
- main.go 작성
package main import ( "fmt" "log" "net/http" ) func main() { http.HandleFunc("/", func(w http.ResponseWriter, r * http.Request){ log.Println("received request") fmt.Fprintf(w, "Hello Docker!!") }) log.Println("start server") server: = & http.Server { Addr:":8000" } if err: = server.ListenAndServe(); err != nil { log.Println(err) } } - Dockerfile 작성
FROM golang:1.9 RUN mkdir /echo COPY main.go /echo CMD ["go", "run", "/echo/main.go"] - 도커 이미지 빌드
$ docker image build -t [이미지명]:[태그명] [Dockerfile의 경로] $ docker image build -t test:test . - 빌드된 이미지 확인
$ docker image list $ docker image ls - 빌드한 이미지로 컨테이너 생성
$ docker container run test:test # 일반 실행 $ docker container run -d test:test # 데몬으로 실행 - 포트포워딩
- 8080포트로 요청을 보내도 Connection refused로 나온다.
- 컨테이너(가상)에서 열어준 포트를 호스트 머신에 연결을 시켜주어야 한다.
- 컨테이너의 아이디를 알아와서 stop을 실시한다.
- 다음 명령을 실행시킨다.(컨테이너의 포트와 호스트 머신의 포트를 연결해준다.)
$ docker container run -p 9000:8080 test:test $ docker container run -d -p 9000:8080 test:test
- main.go 작성
Dockerfile 인스트럭션
- FROM : 도커 이미지의 바탕이 될 베이스 이미지를 지정
- RUN : 도커 이미지를 실행할 때 컨테이너 안에서 실행할 명령을 정의하는 인스트럭션
- COPY : 도커가 동작중인 호스트 머신의 파일이나 디렉터리를 도커 컨테이너 안으로 복사하는 인스트럭션
- CMD : 도커 컨테이너를 실행할 때 컨테이너 안에서 실행할 프로세스를 지정한다.
- RUN 인스트럭션은 이미지를 빌드할때 실행되고 CMD 인스트럭션은 컨테이너를 시작할 때 한 번 실행된다.
- ENTRYPOINT : 컨테이너의 명령 실행 방식을 조정할 수 있으며, CMD와 마찬가지로 컨테이너 안에서 실행할 프로세스를 지정하는 인스트럭션이다.
- ENTRYPOINT를 지정하면 CMD의 인자가 ENTRYPOINT에서 실행하는 파일에 인자로 주어진다.
- LABEL : 이미지를 만든 사람의 이름 등을 적을 수 있다. 전에는 MAINTAINER라는 인스트럭션도 있었으나 더 이상 사용하지 않는다.
- ENV : 도커 컨테이너 안에서 사용할 수 있는 환경변수를 지정한다.
- ARG : 이미지를 빌드할 때 정보를 함께 넣기 위해 사용한다. 이미지를 빌드할 때만 사용할 수 있는 일시적인 환경변수이다.
2. 도커 이미지 다루기
docker image 에서 사용할 수 있는 명령어 list
$ docker image --help build # 이미지 빌드 history # history를 보여준다 inspect # 임포트 load # 로드한다. ls # 이미지 리스트를 보여준다. prune # 사용하지 않는 이미지를 제거 pull # 저장소에서 이미지를 받아온다. push # 저장소에 이미지를 올린다. rm # 제거한다. save # tar로 이미지를 저장한다. tag # 태그를 생성한다.docker image build : 이미지 빌드
docker image build -t 이미지명[:태그명] Dockerfile경로: -t 옵션을 사용하여 태그명을 사용할 수 있다.docker image build -f Dockerfile-test -t 이미지명[:태그명] Dockerfile경로: 기본으로 Dockerfile을 찾으나 -f옵션을 사용하여 다른이름의 Dockerfile을 사용할 수 있다.docker image build --pull=true 이미지명[:태그명] Dockerfile경로: –pull옵션을 사용하면 매번 베이스 이미지를 강제로 새로 받아온다.
docker search : 이미지 검색
docker search [option] 검색키워드docker search --limit 5 mysql- 리포지토리는 검색할 수 있지만 태그까지는 검색할 수 없다.
- 리포지토리에 공개된 이미지의 태그를 알고 싶다면 도커 허브의 해당 리포지토리 페이지에서 Tags를 보는 방법이나 API를 사용하는 방법 중 하나를 사용하면 된다.
- API :
curl -s 'https://hub.docker.com/v2/repositories/library/golang/tags/?page_size=10' | jq -r '.results[].name'
- API :
docker image pull : 이미지 내려받기
docker image pull [options] 리포지토리명[:태그명]
docker image ls : 보유한 도커 이미지 목록 보기
docker image [options] ls
docker image tag : 이미지에 태그 붙이기
- 도커 이미지의 버전을 구별하기 위한 것이다.
- IMAGE ID는 도커 이미지의 버전 넘버 역할을 한다. 어플리케이션을 수정하고 이미지를 빌드하면 매번 다른 이미지가 된다.
- Dockerfile을 편집했을 때뿐만 아니라 COPY 대상이 되는 파일의 내용이 바뀌어도 IMAGE ID 값이 바뀐다.
- 이미지 ID에 태그 부여하기
- 도커 이미지에 태그를 지정하지 않고 빌드한 이미지는 기본적으로 latest 태그가 부여된다.
docker image tage 기반이미지명[:태그] 새이미지명[:태그]
- 도커 이미지의 버전을 구별하기 위한 것이다.
docker image push : 이미지 외부에 공개하기
docker image push [options] 리포지토리명[:태그]: 지정된 리포지토리에 업로드된다.
3. 도커 컨테이너 다루기
도커 컨테이너의 생애주기
- 실행 중 상태
- docker container run 명령으로 이미지를 기반으로 컨테이너를 생성한 상태
- 정지 상태
- 실행 중 상태에 있는 컨테이너를 사용자가 명시적으로 정지하거나 컨테이너에서 실행된 어플리케이션이 정상/오류 여부를 막론하고 종료된 경우
- 디스크에 컨테이너가 종료되던 시점의 상태가 저장되어 남는다.
- 정지시킨 컨테이너를 다시 실행시킬 수 있다.
- 파기 상태
- 정지 상태의 컨테이너는 명시적으로 파기하지 않는 이상 디스크에 그대로 남아 있다.
- 디스크를 차지하는 용량이 점점 늘어나므로 불필요한 컨테이너를 완전히 삭제하는 것이 바람직하다.
- 한 번 파기한 컨테이너는 다시 실행할 수 없다는 점에 유의해야한다.
- 실행 중 상태
docker container run : 컨테이너 생성 및 실행
docker container run [options] 이미지명[:태그] [명령] [명령인자...]docker container run [options] 이미지ID [명령] [명령인자...]- -d 옵션 : 백그라운드에서 실행
- -p 옵션 : 포트포워딩
- -it 옵션 : /bin/sh로 쉘을 실행할 수 있다.
- 컨테이너에 이름 붙이기
$ docker container run --name [컨테이너명] 이미지명[:태그] - 도커 명령에서 자주 사용되는 옵션
- -i 옵션 : 컨테이너를 실행할 때 컨테이너 쪽 표준 입력과의 연결을 그대로 유지한다.
- -t 옵션 : 유사 터미널 기능을 활성화하는 옵션. -i 옵션과 함께 -it로 쓴다.
- –rm 옵션 : 컨테이너를 종료할 때 컨테이너를 파기하도록 하는 옵션
- -v 옵션 : 호스트와 컨테이너 간에 디렉터리나 파일을 공유하기 위해 사용하는 옵션
docker container ls : 도커 컨테이너 목록 보기
docker conatiner ls [options]- 조회시 각 항목의 의미
- CONTAINER ID : 컨테이너 식별자
- IMAGE : 컨테이너를 만드는데 사용된 도커 이미지
- COMMAND : 컨테이너에서 실행되는 어플리케이션 프로세스
- CREATED : 컨테이너 생성 후 경과된 시간
- STATUS : Up(실행중), Exited(종료) 등 컨테이너의 실행 상태
- PORTS : 호스트 포트와 컨테이너 포트의 연결 관계(포트포워딩)
- NAME : 컨테이너의 이름
- 컨테이너 ID만 추출하기
docker container ls -q
- 컨테이너 목록 필터링하기
docker container ls --filter "필터명=값"
- 종료된 컨테이너 목록 보기
docker container ls -a
docker container stop : 컨테이너 정지하기
docker container stop [컨테이너ID 또는 컨테이너명]
docker container restart : 컨테이너 재시작
docker container restart [컨테이너ID 또는 컨테이너명]
docker container rm : 컨테이너 파기
docker container rm [컨테이너ID 또는 컨테이너명]- docker container run –rm를 사용하여 컨테이너를 정지할 때 함께 삭제할 수 있다.
docker container logs : 표준 출력 연결하기
- 현재 실행 중인 특정 도커 컨테이너의 표준 출력 내용을 확인할 수 있다.
docker container logs [options] [컨테이너ID 또는 컨테이너명]- -f 옵션 : 새로 출력되는 표준 출력 내용을 계속 보여준다.
docker container exec : 실행 중인 컨테이너에서 명령 실행하기
docker container exec [options] [컨테이너ID 또는 컨테이너명] [컨테이너에서 실행할 명령]
docker container cp : 파일 복사하기
- 컨테이너 끼리 혹은 컨테이너와 호스트 간에 파일을 복사하기 위한 명령
- COPY 인스트럭션은 이미지를 빌드할 때, cp 명령은 실행 중인 컨테이너와 파일을 주고 받을 때
docker container cp [options] [컨테이너ID 또는 컨테이너명]:[원보파일] [대상파일]docker container cp [options] [호스트_원본파일] [컨테이너ID 또는 컨테이너명]:[대상파일]
4. 운영과 관리를 위한 명령
prune : 컨테이너 및 이미지 파기
docker container prune [options]- 실행중이 아닌 모든 컨테이너를 삭제하는 명령
docker image prune [options]- 태그가 붙지 않은 모든 이미지를 삭제한다.
docker system prune- 사용하지 않는 도커 이미지 및 컨테이너, 볼륨 네트워크 등 모든 도커 리소스를 일괄적으로 삭제
docker conatiner stats : 사용 현황 확인하기
- 시스템 리소스 사용 현황을 컨테이너 단위로 확인
docker container stats [options] [대상_컨테이너ID ...]
5. 도커 컴포즈로 여러 컨테이너 실행하기
도커는 어플리케이션 배포에 특화된 컨테이너이다.
- 도커 컨테이너 = 단일 어플리케이션
- 어플리케이션 간의 연동 없이는 실용적 수준의 시스템을 구축할 수 없다. 다시말해, 도커 컨테이너로 시스템을 구축하면 하나 이상의 컨테이너가 서로 통신하면, 그 사이에 의존관계가 생긴다.
- 컨테이너 동작을 제어하기 위한 설정 파일이나 환경 변수를 어떻게 전달할지, 컨테이너 의존관계를 고려할 때 포트 포워딩을 어떻게 설정해야 하는지 등의 요소를 적절히 관리해야 한다.
docker-compose 명령으로 컨테이너 실행하기
- compose는 yaml 포멧으로 기술된 설정 파일로, 여러 컨테이너의 실행을 한 번에 관리할 수 있게 해준다.
docker-compose version- ubunut :
sudo yum install -y docker-compose - centos7 :
sudo apt install -y docker-compose
- ubunut :
- docker-compose.yml 작성
docker container run -d -p 9000:8080 example/echo:latest- docker-compose.yml
version: "3" servicese: echo: image: example/echo:latest ports: - 9000:8080 docker-compose up -d
- 실행 확인
docker container ls
- 컨테이너 정지
docker-compose down
image 속성 대신 build 속성 사용
version: "3" servicese: echo: build: . ports: - 9000:8080–build 옵션
docker-compose up명령에서도 도커 이미지를 강제로 다시 빌드하게 할 수 있다. 개발 과정에서 이미지가 자주 수정되는 경우에 사용하는 것이 좋다.
6. 컴포즈로 여러 컨테이너 실행하기
- 젠킨스 master-slave 노드 구성
- docker-compose.yml
version: "3" services: master: container_name: master image: jenkinsci/jenkins:latest ports: - 8080:8080 - 50000:50000 volumes: - ./jenkins_home:/var/jenkins_home links: - slave01 slave01: container_name: slave01 image: jenkinsci/ssh-slave:latest - 도커 컴포즈 실행
$ docker-compose up -d $ docker container ls - 젠킨스 시작
- http://localhost:8080/ 으로 접속하여 로그인 후 플러그인 설치 및 사용자 생성
- 초기 admin 비밀번호 확인
$ cat jenkins_home/secrets/initialAdminPassword - 초기 설정이 완료되면 젠킨스관리>플러그인관리 에서 Node and Label parameter plugin을 설치한다.
- master 노드에서 ssh 키 생성 및 확인
$ docker container exec -it master ssh-keygen -t rsa -C "" $ ls -al jenkins_home/.ssh/id_ras # 프라이빗 키 $ ls -al jenkins_home/.ssh/id_ras.pub # 퍼블릭 키 - docker-compose.yml 수정 및 재시작
version: "3" services: master: container_name: master image: jenkinsci/jenkins:latest ports: - 8080:8080 - 50000:50000 volumes: - ./jenkins_home:/var/jenkins_home links: - slave01 slave01: container_name: slave01 image: jenkinsci/ssh-slave:latest environment: - JENKINS_SLAVE_SSH_PUBKEY=ssh-ras AAAA... # 퍼블릭키를 입력해준다.$ docker-compose up -d - slave 노드 추가
- 젠킨스관리>노드관리>신규노드로 들어간다.
- 노드명을 slave01로 하고 Permanent Agent를 선택한후 OK를 누른다.
- Name은 slave01로 하고 Remote root directory를 /home/jenkins로 한다.
- Launch method는 Launch agents via ssh로 설정한다.
- HOST를 slave01로 하고 credentials 생성으로 넘어간다.
- Credential 생성
- Kind : SSH Username with private key
- Username : jenkins
- ID : jenkins
- Private Key : Enter directly를 체크하고 프라이빗 키를 넣어준다.
- 이후 세이브를 진행한다.
- Credential을 방금 만든 것으로 선택하고 세이브 한다.
- Java 위치 잡아주기
- slave01로 접속하여 java의 위치를 잡아준다.
$ docker container exec -it slave /bin/bash $ cp -rf /usr/local/openjdk-8 /usr/local/java - 대쉬보드에서 master-slave 노드의 상태를 확인한다.