본문 바로가기
카테고리 없음

도커와 쿠버네티스 -Docker1(기초 생성)

by mizuiro 2024. 10. 13.

doker & k8s

java (spring boot) + jpa + h2 ⇒ docker 기반으로 위를 합쳐서 image, containter ⇒ 간단한 spring cloud기반의 웹 애플리케이션(api server)

k8s

  • 가상화, 리눅스 설치, k8s(교재)
  • kind를 사용한 수업 환경 구현
  • 클라우드 네이티브 애플리케이션 구현
    • application(spring boot, jpa, h2) + infa( 컨테이너 실행 환경 ⇒ 설계)
    • 인프라 설게 (컨테이너으 ㅣ설게 ⇒ 서비스 분할 ⇒ MSA 아키텍쳐)

spring cloud native application

  • doker, K8s(mini cube : 경량 컨테이너 오케스트레이션)

0. 흐름

자바 웹 app 개발

→ image 로 빌드 (dokcer 에서 사용할 수 있는 image ⇒ container 용도 )

→ 실행

  • 도커를 이용해서 실행
  • k8s 에서 사용할 수 있도록 image를 배포
  • docker hub (public image registry, image 저장소)

→ docker, k8s EKS 에서 pull 해서 사용할 수 있는 것

1. docker 설치

  • WSL2(Windows Subsystem For Linus) 활성화제어판 ⇒ 프로그램 및 기능 → 윈도우기능 켜기/끄기 → 리눅스용 윈도우 하위 시스템, 가상 머신 플랫폼 체크 → 재시작
  • docker 는 Linux 에서만 호환이 되기에 윈도우에서 리눅스처럼 사용하기 위해 설정
  • docker 설치https://docs.docker.com/desktop/install/windows-install/
  • docker Desktop download, install

2. Container

장점

  • 하이퍼바이저와 Guest OS 가 없기 때문에 가볍다
  • 경량이기 때문에 만들어진 이미지 복제, 이관, 배포가 쉽다
  • Guest OS를 부팅하지 않기 때문에 애플리케이션 시작 시간이 빠르다
  • 가상머신( Virtual Box, VMware ) 보다 경량이므로 더 많은 application을 실행 할 수 있다

3. Docker clinet, server, registry

  • client : 도커 명령을 받고, 결과를 출력하는 역할client를 이용해서 컨테이너, 이미지 등의 관리를 요청 가능
  • 도커에 명령을 내릴 수 있는 CLI 도구를 의미
  • server : 도커 엔진, 즉 도커 데몬을 이용해 컨테이너 시작, 운영, 정지 등 담당
  • registry : 도커 이미지를 저장하거나 배포하는 시스템
  • docker hub ⇒ 가장 유명한 public registry

4. Docker image, container

  • image : 컨테이너 형태로 소프트웨어를 배포하기 위해 필요한 모든 요소 ( 코드, 라이브러리, 설정..)를 실행 할 수 있는 포맷이자, 컴파일 및 빌드한 패키지
  • container : 도커 이미지를 실행 할 수 있는 인스턴스컨테이너는 도커 엔진과 운영체제를 공유함 ⇒ 컨테이너는 도커 엔진이 설치되어 있는 호스트 운영체제를 이용한다는 뜻
  • 도커 컨테이너는 도커 이미지로부터 생성되며, 도커 컨테이너에 대해 실행, 중지, 삭제 등의 명령을 내린다

5. K8s

서비스가 점점 커짐에 따라 하나의 모듈로 서비스를 관리 할 수 없게 되었다

하나의 모듈을 잘게 쪼개서 서비스를 시작 하였고, 이것이 마이크로 서비스이다

이 마이크로 서비스는 각각의 애플리케이션이 따로따로 존재하는데 각각을 관리하기 위해 컨테이너로 관리를 하였다

그러나 이 컨테이너의 수가 점점 늘어남에 따라 개발자들이 하나 하나 씩 관리하기 힘들어 졌고, 이 전체 컨테이너들을 체계적으로 관리할 수 있는 시스템이 필요해졌다

이러한 컨테이너를 관리하기 위해 오케스트레이션 도구인 kubernetes가 나왔다

⇒ 쿠버네티스는 대규모 클러스터 환경의 수많은 컨테이너를 쉽고 빠르게 확장, 배포, 관리하는 작업을 자동화 해주는 플랫폼

⇒ 비슷한 서비스 : AWS EKS, Azure AKS, Google GKE

장점

  • 온프레미스 환경에서 수행하는 서버 업그레이드, 패치, 백업 등의 작업을 자동화 ( 오토 스케일링, 로드 밸런싱 등) 하여 인프라 관리보다는 서비스 관리에 집중할 수 있다
  • 컨테이너 장애 발생 시 자기 회복 기능을 통해 복제 컨테이너를 생성하여 서비스를 지속 할 수 있다⇒ 레플리카셋 ⇒ 24/7/365 서비스
  • ⇒ 무중단 서비스, 무중단 배포 (업그레이드)
  • 컨테이너화를 통해 소프트웨어를 패키지화 하면 점직적 업데이트를 통해 다운타임 없이 쉽고 빠르게 릴리즈 및 업데이트를 할 수 있다
  • ⇒ 무중단 배포(업그레이드) ⇒ k8s의 레플리카셋 이용

6. Docker container 서비스

docker network+ h2 db container

docker pull busy box // docker hub 이미지 가져오기
docker images        // 로컬 이미지 목록 조회
docker run busybox   // 이미지를 컨테이너로 실행
docker ps            // ps(proccess statuas ) 실행중인 것만 표시
docker ps -a         // 실행 중, 실행 종료 모두 표시
docker run -it busybox sh
// run : 이미지를 컨테이너로 실행
// -it : i => stdin open, t => terminal 할당 it => 명령어 입력을 터미널로 요청
// busybox : 이미지
// sh : shell 이용
// busybox 라는 이미지를 컨테이너로 실행해서 sh를 이용하여 명령어를 실행
docker run busybox echo 'Hello world'
  • docker clinet 에서 명령어 입력, 실행 요청
    • 도커 데몬과 통신하는데 사용
    • Docker cli 에서 docker 명령어를 실행하는데 사용
  • ⇒ docker server 명령어를 받음 ⇒ dockered(demon) 이 명령어를 받음 ⇒ Unix socket 을 통해서 컨테이너에게 명령어 전달
  • 컨테이너에서 echo ‘Hello world’ 실행
  • 실행된 결과가 docker clinet로 전달
docker rmi 'IMAGE ID'
docker rmi -f 'IMAGE ID'
  • 이미지 삭제
    • 이미지 강제 삭제 시 -f 추가
docker network create msa-network
docker network ls
docker network inspect msa-network
  • 실행해야 할 이미지가 10개가 있을 때 하나의 네트워크에 담아서 사용하고 싶을 때 네트워크 생성
  • 네트워트 상태 확인
docker run -p 1521:1521 -p 8081:8082 -e H2_OPTIONS="-ifNotExists" --name=h2 oscarfonts/h2

docker run --network msa-network -d -p 1521:1521 -p 8081:81 -e H2_OPTIONS="-ifNotExists" --name=h2 oscarfonts/h2
  • 실행할 컨네이너 생성
    • 네트워크를 생성하지 않고 도커가 자동으로 할당하는 방식
    • 생성한 네트워크 범위에 컨테이너의 네트워크를 할당하는 방식
    • -d : 데몬으로 실행
    • -p : 1521:1521 할당된 네트워크의 port number
    • -P 8081:81 : host os에서 h2 접속할 때 사용할 port number
    • -e : 컨테이너를 생성할 때 전달할 환경 변수
    • 환경변수가 여러개라면 -e 옵션을 여러번 사용
    • H2_OPTIONS=”-ifNotExists” : h2 데이터베이스 생성을 위한 옵션
    • —name=h2 : 생성할 컨테이너 이름
    • oscarfonts/h2 : 생성할 컨테이너로 사용될 이미지
docker images
  • h2 images 가 생성되었는지 확인
docker exec -it h2 /bin/bash
cd /opt/h2/bin
ls
java -cp h2-2.1.214.jar org.h2.tools.Shell
  • h2 컨테이너에 들어가서 h2 데이터베이스를 쉘로 실행
    • 초기 설정 확인
    • 데이터베이스가 cli에서 실행
  • 웹에서 localhost:8081 로 접속
  • h2 로 접속 가능

7. 6번의 작업을 clear

  • docker network 생성
  • h2 image pull
  • h2 image container

삭제 순서

container → network → image

  • container, image 삭제
docker images
docker rmi -f 'IMAGE ID' // running 중이라서 강제 삭제 불가 => 컨네이너 종료
Error response from daemon: conflict: unable to delete 7816f131ef42 (cannot be forced) - image is being used by running container 46134943dd5f
docker stop 46134943dd5f // container ID
  • network 삭제
docker network rm msa-network

8. Docker Conatiner 서비스 2

h2 db containter (docker network 사용 X)

docker run -d -p 8082:81 -e H2_OPTIONS="-ifNotExists" --name=h2-1 oscarfonts/h2
docker run -d -p 8081:82 -e H2_OPTIONS="-ifNotExists" --name=h2 oscarfonts/h2
  • 에러
    • container에서 같은 이름을 허용하지 않으므로 name 설정을 바꾸어서 실행하였다
    • 포트 번호 8081은 사용하고 있는 것이므로 포트 번호를 8082로 변경하였다
  • 그 이후 과정은 6번과 같음
docker exec -it h2-1 /bin/bash
cd /opt/h2-1/bin
ls -al
java -cp h2-1.1.214.jar org.h2.tools.Shell

MSA 할 때 중요한 고려 사항

MSA 구성 요소는 결국 java 로 빌드된 여러 개의 jar 이고, 이 여러 개의 jar 가 각각의 docker image 로 만들어지게 되고, 그리고, 이 docker image 를 각각의 컨테이너로 실행을 해야 함으로 위에서 컨테이너 명 중복, 포트 번호 중복에 대한 이해가 반드시 필요함.

9. 웹 서비스 실행을 위한 Nginx 컨테이너 실행

docker run --name webserver1 -d -p 8001:80 nginx:1.25
  • 각 옵션 설명
    • -d : 컨테이너를 백그라운드에서 실행
    • -p : 컨테이너의 80번 포트를 Host Os 포트 8001 포트로 연결해 오픈해서 포트포워딩
docker stats webserver1 // nignx의 상태를 보기
docker logs -f webserver1 // nginx의 접속 로그 보기
docker stop webserver1 // 컨테이너종료 , 웹 서버 종료

10. 코드로 개발하는 컨테이너 인프라

Dockerfile ⇒ Iac(Infrastructure as Code)

  • 원하는 개발 환경을 코드로 구성하는 방법을 제공하는 것이 Dokerfile

필요성

  • 커맨드 기반 (CLI)의 인프라 구성 시 사용자의 실수 등의 휴먼 오류 가능성이 높기 때문
  • 설치 순서와 상호 연관성을 고려하여 각종 라이브러리와 함께 복잡한 명령어를 작성
  • 설치 이후에 잘못된 설정이 있을 시 수정해야 하고, 때로는 유지 보수( 재설치 등)도 불가피
  • 인프라 공유(배포)가 편리해짐

장점

  • 프로그래밍 형 인프라 개발은 탄력성, 확장성, 반복성을 부여할 수 있음
  • 민첩성, 비효율적인 구성, 위험 감소
  • 인프라 가독성이 증가
  • 개발 업무에 집중 가능 ⇒ 수정 사항을 코드 베이스로 변경이 용이
    • Dockerfile 작성 → build → docker image 생성 → run → docker container → Dockerfile 명령어

Dockerfile codebase build

로컬에 dockerfile 작성

cli에서 dockerfile 이 있는 위치로 이동

아래의 명령어를 입력

docker build -t mynginxapp:1.0 . 
docker run -d -p 8085:80 --name=mynginxapp mynginxapp:1.0

Linux의 foreground, background

demon off; =. foreground process

demon on; ⇒ background process

리눅스에서 foreground 와 background 프로세스는 터미널과의 연결여부에 따라 구분됨

  • foreground : 터미널에 연결된 프로세스
    • 실행 시 키보드 입력을 내릴 수 있음
  • boackground : 터미널에 연결되지 않은 프로세스
    • 실행 시 키보드 입력을 내릴 수 없음
  • 실습
    • dockerfile 의 demon off; 를 demon on; 으로 변경 후 build 를 진행
    docker build -t mynginxapp:2.0 .
    docker run -d -p 8086:80 --name=mynginxapp2 mynginxapp:2.0
    
    • 두 개의 다른 dockerfile 세팅 비교
    docker exec -it mynginxapp bash 
    docker exec -it mynginxapp2 
    

명령어

  • Dockerfile 명령어 FROM : 생성하려는 이미지의 베이스 이미지를 지정. 태그를 지정하지 않으면, lastest 로 지정됨. LABEL : 이미지 작성 목적(버전, 타이틀, 설명, 라이센스 등)을 작성. RUN : 설정된 베이스 이지지에 업데이트, 설치, 명령 실행등을 작성. RUN apt update RUN apt -y install nginx : 예로 베이스 이미지가 ubuntu. CMD : 생성된 이미지를 컨테이너로 실행할 때 실행되는 명령. ENTRYPOINT : 설정된 명령어는 Docker 컨테이너가 시잘될 때 마다 실행이됨.
      따라서, 반드시 실행할 명령어는 ENTRYPOINT 로 지정을 하고,
      변경가능성이 있는 명령어는 CMD 로 사용.
    
    
    COPY : 호스트 환경의 파일, 디렉토리를 이미지 안에 복사. 예로 개발된 자바 소스를 이미지에 복사하는 경우. => 이런 경우라면 베이스 이미지가 openjdk 이미지를 사용. build.gradle 파일등을 이미지에 복사하는 경우. => RUN ./gradlew bootJar EXPOSE : 컨테이너 호스스 네트워크를 통해서 들어오는 트래픽을 리스닝하는 포트와 프로토콜을 지정. EXPOSE 80, EXPOSE 80/tcp, EXPOSE 80/update
  • CMD 와 ENTRYPOINT 의 차이점 Docker 컨테이너를 실행할 때 인자를 전달할 수 있음. 전달되는 정보가 CMD 에서는 지덩된 명령어는 무시되고, 전달된 새로운 인자를 이용한 새로운 명령어가 실행됨.
  • multi stage build a. docker image 내부에서 빌드해서 실행가능한 jar 파일로 패키징 b. docker container 가 실행이 될 때, jar 파일을 실행
  • multi stage build 사용 이유 a. 빌드 도구와 런타임 환경을 분리 b. 최소한의 구성만 포함하여 이미지 크기를 최소화 c. 빌드 도구와 관련된 정보들을 외부에 노출시키지 않음 d. 중복된 작업을 피하고 이전 단계의 캐시를 활용하기 때문에 빌드 속도가 향상됨