2020년 7월 12일 일요일

젠킨스 자동배포 연습해보기

까먹지말자. 메모!


CI/CD?

  • 애플리케이션 개발 단계를 자동화하여 새로운 코드 통합으로 인한 문제를 해결할 수 있다.
  • 빌드, 테스트, 배포 프로세스에 대해 자동화와 모니터링이 가능하다.

CI란? (Continuous Integration)

  • 지속적 통합
  • 개발한 소스를 특정 시점에 통합(빌드, 테스트 등)하는 것이 아닌, 지속적으로 통합을 진행한다. (자동화 프로세스!)
  • 어플리케이션을 변경할 때 자동으로 빌드 및 테스트 가능
  • 유명한 CI 툴은 Jenkins 가 있다.

CD란? (Continuous Deploy or Delivery)

  • 지속적 배포
  • 변경사항을 저장소에서 테스트서버나 운영서버에 자동으로 반영한다.

Travis VS Jenkins

Travis
  • 장점

    • 전용 서버가 필요하지 않다. (자체 호스팅)
    • github과 연동이 편하다.
  • 단점

    • 제한된 옵션 제공
    • 느린 속도
    • private 유료

Jenkins
  • 장점

    • 많은 플러그인 제공
  • 단점

    • 별도의 서버가 필요함
    • 젠킨스에 대한 관리 필요

  • 간단히 혼자 해보기는 travis가 재미있을 것 같지만, 학습과 실습이 목적이니 Jenkins를 선택한다!

  • 일단 로컬로 도커를 이용해서 연습해보자.

  • 학습목적이니 일단 내장서버를 이용해서 실행해보자

    Once the spring-boot plugin has been applied to your project it will automatically attempt to rewrite archives to make them executable using the bootRepackage task. You should configure your project to build a jar or war (as appropriate) in the usual way.

    // build.gradle 에 다음 내용을 추가해준다.
    // plugin, 생성할 war명 과 실행할 메인 클래스 명을 넣는다.
    apply plugin: 'war'
    
    
    ...
    
    
    war {
        baseName = 'NoN'
        version =  '0.0.1-SNAPSHOT'
        manifest{
            attributes(
                    'Main-Class': 'com.edu.EduApplication'
            )
        }
    }
    


설치과정 메모


  • 도커에 jenkins 설치하기

    • 명령어로 설치할 수 도 있지만, Docker가 제공해주는 관리도구(Kitematic)로 쉽게 설치할 수 있다.


    • 도커 설치 중..


    • 설치 후 다음 명령어로 어떤 포트로 실행되고있는 지 볼 수 있다.


    • 물론 Kitematic에서도 확인 가능


    • 중간에 패스워드 입력화면은 Kitematic 로그 자세히 보면 패스워드가 있다. 그걸 입력하자.

      • 못봤다면... 도커에서 비밀번호에서 확인해보자

        docker exec -it jenkins /bin/bash
        
        
        cat /var/jenkins_home/secrets/initialAdminPassword

    • localhost:32819 로 접속 (잘 모를때는 추천 플러그인을 설치해보자)


    • 플러그인들이 모두 설치실패한다?


    • 젠킨스 버전 문제라고한다. 높은 버전으로 변경하자.

      docker exec -it -u 0 jenkins bash
      
      
      wget http://updates.jenkins-ci.org/download/war/2.235.1/jenkins.war
      
      
      mv ./jenkins.war /usr/share/jenkins/
      
      
      chown jenkins:jenkins /usr/share/jenkins/jenkins.war
      
      
      도커 젠킨스 재시작

    • 새로운 Item 클릭 


    • 소스관리 탭에서 자신의 프로젝트 git 주소와 Credentials - Add 자신의 git 정보를 입력한다.


    • build 유발 - GitHub hook trigger for GITScm polling 체크


    • 빌드 후 배포를 하기위해 다음 작업을 추가한다. Build - Add build step - Execute Shell - 다음 쉘 추가


  • 현재 젠킨스를 도커에 띄웠으므로 접속주소가 localhost 이다. github에서 요청을 보내야한다. 외부에서 로컬에 접속가능하게 하기 위해 ngrok 을 사용한다.

    • 설치 후 다음 명령어로 사용 가능

      ngrok http 32819
      
      
      // 세션만료 없애기 (기본 8시간), AuthToken 은 ngrok 홈페이지에서 로그인 후 받을 수있다.
      ngrok http 32819 --authtoken={AuthToken}
      
    • 생성된 주소를 사용하면 된다!!


  • Github에 이벤트가 있을 때 젠킨스로 요청을 보내야하므로 Webhooks를 설정해준다.

    • Gibhub - Settings - Webhooks - Add Webhook
    • 젠킨스 주소 뒤에 /github-webhook/ 를 붙여준다. (ngrok에서 생성된 주소 사용하면 됨)

  • README.md 파일에 build 상태 보여주기

    • 젠킨스 플러그인에서 Embeddable Build Status Plugin 다운로드
      • Item - Embeddable Build Status - MarkDown 부분 복사 - github README.md 파일에 입력

      • 다음과 같이 README.md 파일에 표시되는 것을 확인할 수 있다! (빌드상태가 계속 반영된다. 다만, ngrok을 사용하고 있기때문에 주소가 자꾸 바뀐다. 별도의 젠킨스 서버가 필요할 듯하다.)

  • 이제 저장소에 푸시가 있을 때 젠킨스가 자동으로 빌드하는 것을 볼 수 있다. 이를 활용해서 서버에 설치하고 배포작업을 상세화, 단계화하여 적용하면 될 것 같다. (실무에선 어떤 프로세스로 사용할까? ㅠ)


참고

2020년 7월 8일 수요일

학교에서 알려주지 않는 17가지 실무기술 책 메모

학교에서 알려주지 않는 17가지 실무기술 책 메모

  • 해커와 화가라는 책을 읽다가 너~무 재미없어서 책을 변경했다. (너무 옛날 이야기같기도 하고, 지루했다.) 
    벌써 6권째 전자책 완독이다! 리디북스 베스트 셀러에 보이길래 목차보고 흥미로워서 구매했다. 
    책 제목처럼 정말 학교에서는 배우지 않은 내용들이지만 업무하면서 어디선가 필요한 내용이었다. 나같은 기초가 부족한 주니어 개발자 혹은 취준생이 읽으면 아주 좋을 것 같다. 

    물론 책에서 해당 내용에 대해 깊게 설명하진 않지만, 해당 기술이 어디서 필요한지, 실무에선 어떻게 사용하는 것이 좋을지, 심화적으로 공부해보면 좋을 것을 소개해주고 있어 가볍게 보기 좋은 것 같다. 
    파이썬을 통해 예제 또한 제공하여 이해를 돕고있다. 
    특히 HTTPS, OAuth 부분은 직접 깊게 찾아보지 않는 이상 잘 정리된 내용을 접하기 힘든데, 쉽고 빠르게 설명해주어서 흥미롭게 읽었다!!

  • 문자열 인코딩

    • UTF - 8

      • 오늘날 가장 많이 사용하는 문자열 인코딩(최소 1바이트, 최대 6바이트, 대부분 4바이트 이내로 처리)
      • 아스키 코드와 호환 가능
      • JSON은 UTF-8 인코딩만 사용한다.
    • MySQL에서 UTF-8과 완벽히 호환되는 문자 집합을 쓰고 싶다면 utf8mb4를 써야한다.

  • 날짜와 시간

    • 서버 개발자라면 ETCD나 주키퍼를 사용해보는 것도 좋다.
  • 정규표현식

    • 특수문자를 찾을 때는 프로그래밍 언어가 한 번, 정규식 표현식이 한 번 문자를 이스케이프해서 해석할 수 있도록 역슬래시 두 개를 사용해야 한다.
    • 정규표현식 검사로 인해 처리속도가 늦어질 수 있다. 성능을 생각한다면 parser 라이브러리를 사용하는 것이 좋다.
  • 범용 고유 식별자

    • UUID는 충돌 가능성이 낮아서 범용적인 고유 식별자로 사용하기 좋다. 하지만 16바이트나 필요하고 UUID만으로는 정보를 식별하기 어렵다.
  • 해시 함수

    • 해시 함수는 임의의 입력값을 고정된 길이의 해시 값으로 변환하는 함수다.

    • 암호학적으로 안전한 해시 함수는 다음의 조건들을 만족해야한다.

      • 해시 값으로 입력 값을 복원하는 방법이 불가능해야 한다.
      • 서로 다른 입력값으로 같거나 비슷한 해시 값을 찾는 방법이 불가능해야 한다.
    • 대규모 사용자를 기반으로 한 서비스를 개발할 때는 SHA-2 해시 함수를 사용하는 대신 멀티 코어를 사용할 수 있는 Blake2b 해시 함수를 사용해야 한다. (SHA-256 또는 SHA-512 해시함수는 비밀번호와 같은 민감한 데이터를 안전하게 저장할 수 있으나, 해시 값을 계산하는 비용이 매우 크다)

    • 거의 모든 경우 클라이언트에서 평문으로 된 비밀번호를 보내고, 서버에서 가능한 빨리 해시 값으로 변환한 후 사용하는 게 이상적이다. 평문으로 된 비밀번호가 유출되는 상황은 높은 수준의 암호화 방식을 적용한 HTTPS를 사용하는 것으로 쉽게 방지할 수 있다.

  • JSON

    • JSON은 숫자, 문자, 참 또는 거짓 등 여러 형태 데이터를 키와 값으로 구조화 된 객체에 담아 처리하는 규격이다.
    • JSON 메시지가 예측할 수 없는 외부 (사용자 입력, HTML 폼요청 등)로부터 온 데이터인 경우에는 앞서 본 예제 코드와 같이 읽기 전에 키가 존재하는지 검사하는 게 좋다.
    • JSON 객체와 배열을 읽을 때는 객체 내부 또는 배열 요소가 정렬됐다는 가정을 하지 않는게 좋다.
    • 실무환경에서 JSON 메시지를 만들 때 null을 사용하지 않는 게 좋다. (그 키가 어떤 데이터를 담고있는지 알수 없다)
    • JSON 규격의 데이터는 읽기 쉽지만, 텍스트 기반이기 때문에 데이터를 표현하는데 비용이 크다는 단점이 있다.
  • YAML

    • JSON과 비슷하지만 YAML만의 고유한 특징으로 차세대 설정 파일 표준 규격으로 영역을 넓히고 있음
    • 주석지원, 앵커, 별칭 기능
    • 앵커는 & 으로 시작하는 식별자, 별칭은 * 로 시작하는 식별자
    • YAML은 텍스트 기반 데이터 규격으로 읽기 쉬우면서 중괄호나 큰 따옴표를 사용하지 않음. 바이너리 규격에 비해 비효적임
  • XML

    • 웹에서 규격화된 데이터를 효율적으로 주고받기 위해 만든 마크업 언어
    • 데이터 직렬화를 위한 규격이 필요하고 반드시 xml을 써야할 이유가 없다면 JSON 또는 바이너리 기반 프로토콜 버퍼를 고려할 것.
    • 애플리케이션 설정 파일을 만들기 위한 규격이 필요하면 YAML을 고려할 것
  • 프로토콜 버퍼

    • 구글에서 만든 데이터 직렬화 규격
    • 바이너리 기반 규격이기 때문에 더 빠르고 효율적으로 데이터 가공, 처리 가능
    • 메시지를 받은 소프트웨어도 데이터를 가공하고 보낸 곳과 같은 메시지 규격을 사용해야만 메시지 복원, 읽기 가능
    • 인터페이스 코드 : 컴파일러가 스키마를 읽어 만들어낸 결과물. 모든 프로그램은 이 코드를 통해서만 데이터 직렬화/역직렬화 가능
    • 프로토콜 버퍼는 메시지만 정의하면 검증, 누락과 관련된 인터페이스를 자동으로 생성하기 때문에 관리의 필요성이 줄어든다. 메시지 크기도 작고 빠름.
  • Base64

    • 바이너리 데이터를 아스키 코드 일부와 일대일로 매칭되는 문자열. 단순 치환하는 인코딩 방식
    • 바이너리 데이터를 문자열 기반 데이터로 취급할 수 있어 많은 곳에서 사용됨.
    • Base64는 XML, JSON, RESTfull API 처럼 문자열을 기반으로 데이터를 주고 받는 환경에서 바이너리 데이터를 취급할 떄 사용.
    • HTTP로 큰 파일을 보내야한다면 HTTP 멀티파트 기능을 살펴보는 게 도움이 된다.
  • zlib

    • zip파일을 압축할 때는 DEFLATE 알고리즘 사용 (INFLATE는 압축 해제)
    • 데이터 크기가 가변적인 환경에서는 모든 데이터를 압축하지 않는 게 좋다.
    • 웹 서비스의 경우 브라우저가 DEFLATE를 지원하지 않을 수 있음. 일반적으로 Nginx와 같은 서버가 알아서 처리하겠지만 웹소켓, HTTP 서버에서 항상 DEFLATE를 사용하지 않게 설정해두는 것이 좋다.
  • HTTP

    • 서버와 클라이언트가 텍스트, 이미지, 동영상 등의 데이터를 주고 받을 때 사용하는 프로토콜
    • 데이터를 안전하게 주고받기 위해 HTTP에 전송계층보안 TLS을 더해 만든 HTTPS를 사용함.
    • HTTP는 요청 메시지를 보내기 직전까지 대상 컴퓨터가 연결 가능한지 메시지를 응답할 수 있는 상태인지 알 수 없다.(stateless 프로토콜)
    • TCP는 HTTP 보다 빠르지만 연결상태를 직접 관리해야해서 로직이 복잡함. (TCP는 실시간 멀티플레이 게임이나, 금융서비스처럼 메시지 처리시간이 로직 처리보다 오래걸리는 경우에만 사용하는 것이 좋음)
    • HTTP요청
      • GET : 웹 브라우저가 서버에 웹 페이지를 요청할 때 사용
      • POST : 클라이언트에서 서버로 데이터가 포함된 요청을 보낼 때 사용
      • DELETE, PUT : DELETE는 데이터 삭제, PUT은 이미 존재하는 데이터의 업데이트 요청을 의미하며 기술적으로는 POST와 큰 차이는 없다.
    • URL과 달리 URI는 특정 문서, 영상 등과 같은 자원의 위치를 가리킬 때 사용하는 용어임. (XML에서도 사용)
    • 로드밸런스 서비스는 사용자가 접속했을 때 부하가 가장 적은 웹 서버로 연결해주고 동작하지 않는 서버를 발견하면 서버 목록에서 자동으로 제외됨.
    • 스티키 세션 : 하나의 브라우저는 하나의 웹 서버에만 연결하게 됨
    • 교차 출처 리소스 공유(CORS) : HTTP 서버의 웹 페이지, 이미지 파일이나 API 등을 특정 호스트로 접속한 웹 브라우저만 사용할 수 있게 제현하는 정책
      • 동일 출처 정책 : 사전에 정의하지 않은 다른 곳에서 웹 페이지, API와 같은 리소스 요청을 차단하는 방어 장치 (다른 웹사이트에서 이미지, 동영상과 같은 리소스를 무단으로 가져가는 상황을 방지할 수 있음 - 다른 도메인간 리소스 공유가 필요한 경우 있기 때문에 CORS가 생김)
    • 웹서버는 요청 처리 외에도 정적 파일 캐시, 로드 밸런스, 압축 및 보안 기능 등 고려해야할 것이 많음
      • HTTP 표준에서 정의하는 기능을 바로 사용할 수있는 웹서버 소프트웨어가 있음
      • Nginx : 아파치 보다 뛰어난 성능과 가벼운 구조로 인기를 끌고 있다.
      • Nginx는 단일 스레드와 이벤트 기반으로 동작하고, 아파치보다 많은 사용자를 처리할 수 있다. (사용 권장)
    • 비동기 통신을 지원하는 표준은 HTTP 2.0과 웹소켓이 있음. HTTP 2.0은 하나의 요청에 대한 응답을 병렬로 보내는 데 초점. 웹소켓은 웹상에서 TCP처럼 데이터를 양방향으로 주고받음
  • RESTful API

    • 서버와 클라이언트가 메시지를 주고 받을 때 가장 많이 사용하는 통신 규격
    • 요청 주소와 메서드(GET,POST 등) JSON 규격을 이용하여 API를 정의하고 읽기 쉬운 형태임
    • 정해진 표준이나 규격이 없기 때문에 커뮤니티나 기업에서 제공하는 관례를 따르자.
    • API를 사용하는 입장에서 호환성을 고려할 수있도록 API 버전을 명시하자.
    • 대상을 어떻게 할 것인지는 메서드로 결정하자. (POST, PUT, PATCH, DELETE 등) (객체의 행동을 요청 주소에 정의하면 메서드 역할이 축소된다. 좋은 디자인이라고 볼 수 없음)
    • GET은 HTTP 표준에 따라 메시지 바디를 사용할 수 없는데, RESTful API에서 요청 주소 경로에 식별자를 넣는 것이 관례이다
    • 조회 시 단일 객체, 복수 객체 조회를 구분하지 않고 같은 형식으로 응답 메시지를 구성하면 API를 만드는 입장, 사용하는 입장 모두 유지보수가 쉬워진디. (재사용 가능)
    • API를 만들 때는 인수받는 방법 과 응답 규격을 최대한 일관성 있게 만들어 모두 재사용이 쉽게 하자
  • HTTPS

    • 안전하게 메시지를 주고 받기 위해 만든 프로토콜. TLS 프로토콜 기반으로 하는 HTTP
    • TLS이 등장하기 전까진 보안 소켓 계층 SSL 을 사용했음. SSL은 많은 취약점으로 더 이상 사용하지 않지만, SSL의 이름을 계속 사용중임
    • HTTPS를 사용하면 서버와 클라이언트가 주고 받는 메시지를 암호화한다. 메시지를 암호화 복호화하는 키는 HTTPS로 메시지를 주고 받는 두 컴퓨터만 안다.
    • HTTPS는 TLS를 기반으로하여 TLS버전에 따라 사용가능한 암호화 목록과 안정성이 달라진다.
    • HTTPS 통신을 하기 위해서는 반드시 인증서가 필요함.
      • 클라이언트는 키를 교환하기 전에 이 서버가 신뢰할 수 있는 서버인지 검증하는 작업이 필요한데, 클라이언트는 이 과정에서 서버가 보내는 인증서를 통해 검증함.
    • HTTPS를 소프트웨어 프레임워크에서 설정하는 것보다 Nginx나 아파치와 같은 웹서버에서 설정하는것이 안전함.
  • OAuth 2.0

    • OAuth는 데이터를 간편하고 안전하게 주고받기 위해 만들어진 표준.
    • ID와 비밀번호 대신 엑세스 토큰 기반으로 사용자 식별. 토큰은 API를 제공하는 리소스 서버만 발급.
    • 엑세스 토큰을 요청할 때 가능하면 유효 기간을 짧게 설정하고 자주 갱신하는 게 좋음.
    • 엑세스 토큰으로 RESTful API를 사용할 때는 반드시 HTTPS를 사용하는 지 확인해야 보안 위협을 방지할 수 있다.
    • JSON Web Token(JWT)을 사용하면 인가 서버를 통해 토큰을 검증하는 대신 인가 정보를 포함해 사용하기 때문에 인가 서버의 부하를 줄일 수 있음.