[프로그래머스] 웹 개발 파이프라인 구축(1)

Lina Hongbi Ko·2024년 12월 2일
0

Programmers_BootCamp

목록 보기
67/76
post-thumbnail

2024년 12월 2일

✏️ 웹 개발 파이프라인

✏️ 배포 - 인도 자동화의 중요성

  • 전통적 인도 프로세스

    • 전통적 인도 프로세스의 한계점

      • 느린 인도 기간 : 개발 요구 사항이 정의된 때로부터 제품 전달이 완료 되기 전까지 긴 시간 소요
    • 느린 피드백 주기

      • 개발팀의 효율성 향상에 걸림돌로 작용
    • 자동화 미비

      • 릴리스 회수가 적으므로 자동화 필요 감소 → 릴리스 기간 예측 어려워짐
    • 핫픽스 위험성

      • 긴급한 코드 변경에 대하여 충분한 테스트가 이루어질 수 없는 위험
    • 개발문화 건정성 제한

      • 팀 스트레스, 의사소통 부족, 책임의 분산, 낮은 업무 만족도, …
    • 해결책 : 지속적 인도 / 배포 방식

      • 변경 내용이 단지 코드 한 줄이라고 할 때,

        • 이를 배포하는데 어느 정도 시간이 소요 되는가?
        • 이 배포 작업을 반복해서 안정적으로 수행할 수 있는가?
      • 해결안 : 프로세스의 각 단계를 자동화

        • 빠른 제품 인도
        • 짧은 피드백 주기
        • 위험도가 낮은 릴리스: 반복과 롤백
        • 유연한 릴리스 정책 결정 가능
        • Git을 활용한 SCM에서 논리적 연관성이 있는 변경사항을 묶어 잘게 자주 커밋하는 것과 유사
    • 자동 배포 파이프 라인

      • 코드의 통합, 테스트, 배포는 (전통적 인도 방식에서와 마찬가지로) 매우 중요한 단계들임
      • 각 단계를 유지하면서 동시에 자동화하는 것이 필요, 또한 지속적 모니터링도 필수
    • 지속적 통합(CI; Continuous Intergration)

      • 코드가 올바르게 빌드 및 통합 되는지를 자동으로 확인
        • 리포지토리에서 코드를 체크 아웃
        • 빌드(컴파일 및 링크 등을)를 수행하고 단위 테스트(UT; Unit Test)를 행함
          • 테스트 커버리지(test coverage) 리포트 생성
        • 코드 품질 검증
          • 정적 검증을 통합 규칙 검사
          • 코드 규약 등의 준수 여부 검사
    • 개발팀에 1차적인 피드백 제공

    • 인수 테스트(UAT; User Acceptance Test)

      • 제품이 릴리스할 준비가 되었는지 사용자 요구사하에 견주어 확인
      • 전통적으로 QA팀의 역할
      • 통합 테스트, 인수 테스트, 비기능적 분석(성능, 확장성, 보안…) 등 포함
      • CD 파이프 라인에 통합
        • 품질 점검을 나중에 하는 것이 아니라 개발 중에 제품에 내재 시키자는 것
        • 개발자가 구현을 마치는 즉시 고객이 원하는 제품인지를 검증
        • 소프트웨어의 인도 결정을 자동화한다는 뜻
    • 구성 관리 (Configuration Management)

      • 소프트웨어와 환경 변화를 추적하고 제어
      • 전통적으로 운영(Operation)팀의 역할
      • 필수 도구 준비와 설치
      • 응용의 배포와 관련한 다양한 서비스 인스턴스와 배포 버전 관리
      • CD 파이프 라인에 통합
        • 프로덕션 환경의 응용을 자동으로 구성하고 배포
        • 구성 관리 도구를 이용해 구성 관리 파일을 버전 관리 시스템에 저장하고 변경 이력 추적
    • CD (Continuous Delivery) 를 위한 기술적 전제 조건

      • 자동 빌드, 테스트, 패키징, 배포
        • 전체 프로세스 중 자동화 되지 않는 부분이 있다면 지속적 인도 불가능
      • 신속한 파이프라인 실행
        • 리포지토리에 커밋 발생할 때마다 실행되어야 하므로 소요시간이 길면 안됨
      • 신속한 장애 복구
        • 신속한 롤백이 가능해야하며, 그렇지 못할 경우 잦은 릴리스에 따른 위험도 높아짐
      • 무중단 배포
        • 잦은 배포가 이루어지므로 배포 중 서비스 다운 타임이 발생하면 안됨
      • 트렁크 기반 개발
        • 로컬 브랜치에만 코드 체크인하면 코드 통합 검증이 이루어지지 않고 릴리스 회수가 줄어듬

✏️ 웹 개발 파이프라인 구성 도구

  • 컨테이너 가상화 및 클러스터 운용

    • Docker + Kubernetes
  • 소프트웨어 개발 파이프라인 자동화 서버

    • Jenkins
  • 구성 관리 자동화

    • Ansible
  • 소프트웨어 버전 관리(SCM; Source Code Management)

    • Github
  • 그 외

    • 빌드 도구 (자동화 지원), 단위 테스트 프레임 워크, 정적 코드 분석기ㅣ, 인수 테스트 프레임워크, …
  • 컨테이너화

    • 응용 프로그램, 설정 파일, 라비르러리, 그리고 이들 사이의 의존성 관계를 한 군데 묶어 (컨테이너 안에 넣어) 관리
      • 소프트웨어 개발 및 배포 효율과 안정성 향상시킴
      • 시스템 의존성이 최소화되어 소프트웨어 시스템의 이식이 용이해짐
      • 예측 가능하고 유연한 소프트웨어 실행 환경을 제공해 클라우드 컴퓨팅 인프라에서 활용도가 높음
  • 지속적 통합 파이프 라인 (CI Pipeline)

    • 리포지토리에 코드 커밋이 발생할때마다 빌드, 단위 테스트, 정적 분석 등을 행함
    • Docker와 Jenkins를 결합해 인수 테스트 환경을 만들고 테스트 수행
    • Docker Host 대신 Kubernetes Cluster 가 연결된 형태
    • 다중 환경을 생성, 미러링하여 테스트 환경과 프로덕션 환경을 미러링

✏️ 컨테이너 가상화와 도커

  • 도커 공부하다 찾은 좋은 글 : https://zinirun.github.io/2020/08/15/how-to-use-docker/

  • 가상화

    • 컴퓨팅 자원 (리소스;resource) 의 추상화를 일컫는 광범위한 용어
    • 물리적 컴퓨팅 자원의 특징을 다른 시스템, 응용 프로그램, 최종 사용자들이 자원과 상호 작용하는 방식으로부터 감추는 기술
    • 컴퓨터 안에 또 다른, 가상의 컴퓨터가 존재하도록 하는 기술
  • 가상화 컴퓨팅의 이점

    • 시스템 측면

      • 시스템 이용률의 향상
      • 설정의 구성과 복원 용이
    • 비즈니스 측면

      • 자본 및 운영 비용 절감
      • 다운 타임 최소화
      • 비즈니스 연속성 및 재해 복구 향상
      • 테이터 센터 관리 간소화
    • 우리의 관심

      • 개발한 소프트웨어의 배포, 테스트, 구성 관리 등에 (실제 물리적 하드웨어에 상관 없이) 통일된 환경을 제공할 수 있음
      • 따라서 소프트웨어 통합 / 인도 프로세스의 자동화에 적용하기가 좋음
  • 서버 가상화 기술의 진화

    • 가상화 기술에서의 호스트 : 다른 시스템을 가상화하여 실행하는 컴퓨터

    • 가상화 기술에서의 게스트 : 호스트 시스템 위에 가상화 되어 제공되는 (가상) 시스템

    • 가상 기계(VM; Virtual Machine) 기반

      • 하이퍼바이저(hypervisor)이용
      • type 1: 네이티브 또는 베어메탈형
      • type 2: 호스트형
    • 컨테이너 (container) 기반

      • 호스트 OS의 컨테이너 기술을 이용
  • 컨테이너 사용의 이점

    • 응용 프로그램, 설정 파일, 라이브러리, 그리고 이들 사이의 의존성 관계를 한데 묶어 관리 → 이 묶음 컨테이너라고 부름
    • 컨테이너 엔진의 도움으로 시스템 의존성이 최소화되어 소프트웨어 시스템의 이식이 용이해짐
  • 도커(Docker)

    • 널리 이용되고 있는 컨테이너 기반 가상화 플랫폼

      • LInux, Window, MacOS 상에 실행되는 컨테이너 엔진 제공
      • AWS, GCP, AZure 등의 클라우드 컴퓨팅 인프라와 결합하면 더욱 유연한 운영이 가능
    • 도커를 이용한 소프트웨어 개발 / 배포

  • 도커허브(Docker Hub)

    • 컨테이너 이미지들에 대해 원격 저장, 유지 관리, 공유, 권한 등 관리 등을 효율적으로 행할 수 있는 온라인 서비스 제공 → 소프트웨어 개발, 배포 프로세스의 효율성 크기 증대
  • 도커의 구성 요소

✏️ 도커 이미지와 도커 컨테이너

  • 도커 이미지

    • 응용을 실행하는데 필요한 모든 파일들과 그것을 실행하는 방법을 한데 묶어 놓은 것
    • 상태를 저장하지 않는 (statless) 방식 - 네트워크로 전송, 레지스트리에 저장, 이름 및 버전 지정 가능
    • 계층화되어 있다는 특징을 갖고 있으며, 어떤 이미지로부터 다른 이미지를 만드는 것이 가능
  • 도커 컨테이너

    • 이미지의 실행 인스턴스 (이미지를 이용해 만들어진, 응용소프트웨어를 실제로 실행하는 격리된 환경)
    • 하나의 이미지로부터 여러 컨테이너를 만들어 동일한 응용을 여러개 실행할 수 있음(각각은 독립)
    • 상태를 저장하는 (satefull) 방식 - 컨테이너를 사용하면서 상태를 변경할 수 있음
      • 그러나 컨테이너가 소멸하면 이 상태도 잊어버림
    • 도커 엔진에 의해서 관리되며 마치 컴퓨터 하나가 새로 생겨서 정해진 일을 수행하는 것과 같은 모습을 보여줌
  • 이미지의 계층 구조

  • 컨테이너와 이미지 관련 명령어 요약

    • docker run <이미지 이름>

      • 이름이 주어진 이미지를 로컬에서 또는 레지스트리에서 가져다가 컨테이너를 만들어 실행
    • docker start <컨테이너 이름>

      • 컨테이너 실행
    • docker ps, docker ps - a

      • 현재 실행 중인 (또는 중단되어 있는 것까지 포함하여) 컨테이너들의 정보 조회
    • docker images

      • 로컬 컴퓨터에 가지고 있는 이미지들의 정보 조회
    • docker stop <컨테이너 이름 / ID>

      • 현재 실행중인 컨테이너의 실행 중단
      • 컨테이너 없어지지 않음
    • docker rm <컨테이너 이름 / ID>

      • 컨테이너 삭제
    • docker rmi <이미지 이름/ ID>

      • 이미지 삭제

✏️ 도커 이미지 만들기

  • 도커 실행 및 이미지 생성 관련글 for macos : https://adjh54.tistory.com/350

  • mac os에서 httpd 이미지 받아서 apache 서버 띄우기

    1. 도커 이미지 받아오기

      docker pull httpd

    2. 컨테이너 만들어 실행

      docker run —name apachehhtp -p 8080:80 httpd

      • —name apachehttp : 해당 서버 이름 (컨테이너 이름)
      • -p 8080:80 : host의 8080포트와 httpd 이미지로 만든 컨테이너 80포트 연결 (앞부분이 host)
      • http://localhost:8080 접속

    3. 컨테이너 쉘 연결 → 컨테이너에서 작업 가능 (= 상태 변경 가능)

      docker exec -it apachehhtp /bin/bash

    4. 기본 페이지 It works! →> new page 로 변경

      grep DocumentRoot /usr/local/apache2/conf/httpd.conf

      pwd (현재 위치 확인)

      ls -l (파일 리스트 확인 → htdocs)

      cd htdocs (htdocs 이동)

      ls -l (파일 리스트 확인 → index.html)

      cat index.html

      // 파일 내용 확인
      <html><body><h1>It works!</h1></body></html>

      cat > index.html

      // 파일 내용 수정
      <html><body><h1>new page</h1></body></html>)

      빠져나오기 : control + D

      httpd-foreground (웹 서버 수동 실행)

      바뀐거 확인

    1. 쉘 빠져나오기
      exit
  • 컨테이너를 가지고 이미지 생성 → 새로운 이미지가 로컬 컴퓨터에 생성됨(아직 레지스트리에는 없고 내 컴퓨터에만 있음)
    docker commit 8c034b18f952<컨테이너 ID> my_httpd:0.1
    docker images
  • 이미지 실행 docker run --name apachehhtp2 -p 8081:80 my_httpd:0.1
    새로운 이미지의 컨테이너 접속 확인
  • 이미지 생성 자동화

    • Dockerfile
    • 계층 구조를 이용해 도커 이미지를 만드는 절차를 기술하는 파일 (텍스트)
    // 형태
    
     FROM [—platform=<platform>] <image> [AS <name>
    
     RUN <command>
    
     ENTRYPOINT [”executable”, “param1”, “param2”]
    
    • example → vim Dockerfile 로 입력해서 아래 빌드 명령어 실행함
    // Dockerfile 내에 아래내용을 적음
    
    FROM httpd:latest
    
    RUN echo "<html><body><h1>Docker build test</h1></body></html>" > /usr/local/apache2/htdocs/index.html
    
    ENTRYPOINT /usr/local/httpd-foreground
    • 이미지 빌드 명령어
      - docker cat Dockerfile (도커 파일 불러내서 읽고)
      - docker build [OPTIONS] PATH | URL | - (빌드시킴)
      - example
      docker build -t my_httpd:0.2 .
      • 이미지 생성됨
  • 이미지를 레지스트리에 올리기

    • 도커 허브에 로그인 (도커 허브에 계정이 만들어져 있어야함)
      • docker login
    • 조금 전 만들었던 이미지에 태그를 붙이기
      // 형태
      <docker_hub_id> / <image name>
      • docker tag my_httpd:0.2 내계정아이디/my_httpd:0.2
    • 레지스트리에 올리기
      • docker push 내계정아이디/my_httpd:0.2
  • 도커의 편리함(CI /CD 관점에서 생각해보기)

    • 응용을 실행하는데 이용되는 실제 (물리적) 컴퓨터 환경과 독립적으로 통일된 실행 환경 제공 가능
    • 이미지로부터 여러 개의 동일한 컨테이너 인스턴스를 만고 실행 가능
    • 필요한 소프트웨어 도구 및 설정 파일 등을 사전에 지정해두고 알려진 상태로 컨테이너 생성 가능 (자동화)
  • 과제 실습
    hello.py 파일 만들어서 아래 내용 적고 위에 실습한것처럼 빌드해서 이미지 만든 다음 레포지토리에 올리고 다시 런해서 컨테이너 실행

✏️ 컨테이너 다루기

  • 도커 환경 변수 이용

    • 파일들 설정 후

      • hello.py

      • Dockerfile

      • docker build -t hello:0.2 .

      • hello:0.2 이미지생성됨

      • 환경 변수에 다른 값 넣기

        • docker run -e NAME=Programmers hello:0.2
  • 실행이 끝난 컨테이너의 자동 삭제

    • docker run —rm
  • 호스트의 포트와 컨테이너 포트를 연결

    • 호스트의 외부로부터도 접속 가능하도록 설정하려면? : 호스트의 특정 포트를 특정 컨테이너의 특정 포트와 연결하는 방법이 필요함

      • docker run -d —rm -p 8888:8080 tomcat (-d : 백그라운드 실행 —rm: 실행 끝나면 컨테이너 종료 -p: 포트번호)
  • 컨테이너 이름 지정하기

    • 도커 컨테이너는 이름과 ID(고유 해시 값)에 의하여 식별
      • 이름을 지정하지 않으면 docker가 컨테이너를 만들때 이름을 자동 부여
      • 그러나 관리 편의 및 자동화를 위해서 이름을 지정하는 것이 필요해짐
    • docker run —name <컨테이너 이름><이미지>
      e.g) docker run —rm -d my_tomcat tomcat
  • 도커 클린업

    • 컨테이너 삭제
      - docker rm <컨테이너>

    • 이미지 삭제
      - docker rmi <이미지>

    • 컨테이너 전체 삭제
      - docker container prune

    • 이미지 전체 삭제
      - docker image prune -a

✏️ 컨테이너 안의 파일들과 도커 볼륨

  • 컨테이너 안의 파일들에 접근하는 방법

    • 실행하고 있는 컨테이너와 호스트 사이의 파일 복사

      • 명령어 docker cp를 이용(copy)
    • 이미지 빌드할 때 호스트로부터 파일을 컨테이너에 추가

      • Dockerfile 안에 ADD 지시자 활용
    • 바인드 마운트

      • docker -v 옵션으로 호스트의 특정 디렉토리를 컨테이너와 공유
    • 도커 볼륨

      • docker -v 옵션으로 호스트와 공유하는 것은 비슷하지만 컨테이너가 마운트하는 것은 추상화된 볼륨
  • 실습(실행하고 있는 컨테이너와 호스트 사이의 파일 복사)

    • niginix 이미지 생성 및 포트 연결, 쉘 연결해서 Index.html 파일 확인

      • docker run --rm -d -p 8080:80 --name my_nginix nginx:latest

      • docker exec -it my_nginix /bin/bash

      • ls -l /usr/share/nginx/html

      • cat /usr/share/nginx/html/index.html

      • http://localhost:8080 접속

    • 파일 컨테이너 index.html 덮어쓰기(호스트의 파일을 컨테이너 파일로 덮어쓰기)

      • index.html 파일 생성
      • docker cp index.html my_nginix:/usr/share/nginx/html
    • 컨테이터 파일을 가져와서 호스트의 파일로 덮어쓰기

      • docker cp my_nginix:/usr/share/nginx/html/50x.html .
  • 실습 (Dockerfile 내에 ADD 지시자를 이용해서 호스트가 제공하는 파일을 특정 위치에 둠)

  • ADD <호스트 내 source 파일의 경로> <컨테이너 내에 배치할 파일의 경로>

    • ADD ./index.html /usr/share/nginx/html/new.html

      // Dockerfile
      
      FROM nginx:latest
      
      ADD ./index.html /usr/share/nginx/html/new.html
      CMD ["nginx", "-g", "daemon off;"]
    • cat Dokerfile

    • docker build -t your_nginx .

    • docker run —rm -d -p 8888:80 —name my_nginx your_nginx

    • http://localhost:8888/new.html 접속

  • 실습 (바인드 마운트)

    • 바인드 마운트(bind mount)
      - 명령어 (경로 공유)
      - docker run -v <호스트 경로>:<컨테이너 경로> <이미지>
  • 호스트가 원하는 폴더에서 파일 만들고, 컨테이너에 폴더 파일 복사하기

    • cat > A.txt
    • This is a test file called A.txt.
    • ctrl + c (나오고)
    • docker run -it -v ~/desktop/example:/host_directory ubuntu:22.04 /bin/bash
    • ls -l /host_directory (컨테이너에 host_directory가 바인드 마운트 되었음을 확인→ host_directory라는 폴더에 파일들 진짜 복사되었는지 확인)
    • cat /host_directory/A.txt (디렉토리내에 A.txt 내용 확인)
    • cat > /host_directory/B.txt (컨테이너에서 B.txt 생성)
      • This is a test file called B.txt
      • ctrl + d
      • exit (컨테이너 쉘 빠져나오고)
    • 호스트에서 확인
  • 실습 (볼륨 생성 명령어)

    • 형태 : docker volume create <볼륨 이름>

      • docker volume create my-volume (볼륨 생성)

      • docker inspect my-volume (볼륨 보기)

      • docker run —rm -d -p 8888:80 -v my-volume:/usr/share/nginx/html —name my_nginx nginx:latest

        • 볼륨의 내용 조회 (컨테이너 내부에 있는 파일들이 동기화 되어 있음) 및 파일 생성

          • 바인드 마운트와는 다름 → 마운트 했을 때 이미 컨테이너에 해당 경로가 있었으면 호스트가 바인드 마운트 한걸 덮어써줘서 없어짐(컨테이너에 있던 것들 삭제됨) but 볼륨을 마운트 하면 컨테이너 내부에 이미 있었던 것들이 삭제되지 않음

          • 참조 : https://okbear3.tistory.com/entry/docker-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EA%B4%80%EB%A6%AC

            • docker exec -it my_nginx /bin/bash

            • cd /usr/share/nginx/html

            • cat > new.html

            • This file is created inside the container.

            • cat new.html → 잘 생성된 파일 확인

            • exit

            • sudo ls -l /var/lib/docker/volumes/my-voulme/_data -> 경로에 파일 없다고 뜸

*여기서 inspect한 볼륨의 위치에 생성된 파일을 확인할 수 없었는데, 맥은 VM 상에서 도커가 실행되기 때문에 경로가 다르다고 한다. (이 부분은 다시 참고해서 해봐야겠다.)

참조글 :
https://mycodings.fly.dev/blog/2024-04-06-docker-volume-usage-and-principles
https://toast1ng.tistory.com/4

profile
프론트엔드개발자가 되고 싶어서 열심히 땅굴 파는 자

0개의 댓글