ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • docker 환경에서 nginx 로 jenkins ssl 적용
    docker 2022. 2. 9. 15:00
    반응형

    jenkins 를 외부에 공개해야 할 필요가 있다면 nginx 를 프록시로 사용하여 ssl 을 비롯한 각종 처리를 하게 하는 것도 괜찮은 방법이다. 그런 상황이 생겨서 한 번 적용해 보았다.


    환경

    • CentOS 7.9
    • docker 20.10.12
      • 참고: nginx 컨테이너 내부에서 jenkins 컨테이너를 호출할 수 있어야 한다. run 시 --link 옵션을 사용하여 해결하도록 한다.
    • nginx 1.20.2
      • 직접 설치해서 사용해도 되지만 여기서는 docker 로 실행해보려고 한다.
    • jenkins 2.289.3
      • 8080 포트로 열려있는 상태이다. 실습에서는 docker 로 띄웠는데, 도커를 이용하지 않아도 상관없다. jenkins 를 도커로 구동하는 것에 대해서는 https://bitgadak.tistory.com/3 를 참고한다.
      • nginx 에서 해당 컨테이너를 찾을 수 있어야 한다. 이름으로 찾을 수 있는데, jenkins 라는 이름으로 추가되어 있다고 한다.
    • 이 글에서는 임의로 젠킨스 서버 도메인을 my-jenkins.com 정하고, 해당 도메인으로 요청하면 젠킨스로 전달한다.
    • ssl 인증서: nginx 로 ssl 를 적용할 것이기 때문에 필요하다.

    아래와 같은 형식이 될 것이다.


    1. Nginx docker image

    nginx docker image 사용에 대해서는 docker hub 를 참고하였다: https://hub.docker.com/_/nginx

     

    Nginx - Official Image | Docker Hub

    Quick reference Supported tags and respective Dockerfile links 1.21.6, mainline, 1, 1.21, latest 1.21.6-perl, mainline-perl, 1-perl, 1.21-perl, perl 1.21.6-alpine, mainline-alpine, 1-alpine, 1.21-alpine, alpine 1.21.6-alpine-perl, mainline-alpine-perl, 1-a

    hub.docker.com

    여기서 nginx 설정을 하는 방법을 여러 가지 소개하고 있는데, 그 중에 하나는 컨테이너 내부의 설정파일을 직접 수정 추가 하는 것이다.

    1.20.2 기준으로 Docker run 을 통해 컨테이너를 시작하면 nginx 가 시작하면서, /etc/nginx/nginx.conf 를 불러온다.

    여기서 /etc/nginx/nginx.conf 를 직접 수정해도 되지만, 기본 nginx.conf 파일에서는 include /etc/nginx/conf.d/*.conf; 라는 항목이 있어서 /etc/nginx/conf.d 디렉토리의 *.conf 의 설정 정보들을 불러온다.

    그래서 해당 디렉토리에 필요한 설정파일을 *.conf 라는 이름으로 추가하는 방식을 통해 설정할 수 있다.

    컨테이너 실행시 명령어로 -v 옵션을 주어 추가하는 방법도 있겠지만, Dockerfile 을 통해 필요한 파일이 들어가 있는 새로운 이미지를 만드는 것이 깔끔할 것 같아서 그렇게 실행하려고 한다.

    1.1 jenkins.conf

    컨테이너 실행시 /etc/nginx/conf.d/ 디렉토리 내부에 들어갈 젠킨스를 위한 설정 파일이다.

    jenkins 를 위한 nginx 설정에 대해서는 참고할 만한 정보가 있다.

    https://www.jenkins.io/doc/book/system-administration/reverse-proxy-configuration-nginx/

     

    Reverse proxy - Nginx

    In situations where you have existing web sites on your server, you may find it useful to run Jenkins (or the servlet container that Jenkins runs in) behind Nginx, so that you can bind Jenkins to the part of a bigger website that you may have. This section

    www.jenkins.io

    여기를 참고하지만 불필요한 부분을 제거하고 필요한 부분을 추가해서 수정한다.

    upstream jenkins {
        server jenkins:8080; # docker 로 띄운 jenkins 컨테이너의 이름이다.
        keepalive 32;
    }
    
    # websocket 을 위한 설정
    map $http_upgrade $connection_upgrade {
      default upgrade;
      '' close;
    }
    
    server {
        listen       80;
        listen       443 ssl;
        server_name  my-jenkins.com; # 요청이 my-jenkins.com 으로 온다면 처리
    
        ssl_certificate     /etc/nginx/jenkins-chained.crt;
        ssl_certificate_key /etc/nginx/jenkins.key;
    
        # Jenkins 가 추가로 필요한 header 가 있다면 허용
        ignore_invalid_headers off;
    
        location / {
            proxy_pass         http://jenkins;
            proxy_redirect     default;
            proxy_http_version 1.1;
    
            # websocket 을 위한 설정
            proxy_set_header   Connection        $connection_upgrade;
            proxy_set_header   Upgrade           $http_upgrade;
    
            proxy_set_header   Host              $host;
            proxy_set_header   X-Real-IP         $remote_addr;
            proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;
            proxy_set_header   X-Forwarded-Proto $scheme;
            proxy_max_temp_file_size 0;
    
            #this is the maximum upload size
            client_max_body_size       10m;
            client_body_buffer_size    128k;
    
            proxy_connect_timeout      90;
            proxy_send_timeout         90;
            proxy_read_timeout         90;
            proxy_buffering            off;
            proxy_request_buffering    off; # HTTP CLI commands
        }
    }
    • 서버 도메인은 my-jenkins.com 이다.
    • 인증서를 추가한다.
      • jenkins-chained.crt 와 jenkins.key 를 /etc/nginx 에 넣을 것이다.
    • jenkins 에서 websocket 을 사용해서 관련 처리가 있다: http://nginx.org/en/docs/http/websocket.html
      • websoket 을 사용하기 위해서는 Connection 헤더와 Upgrade 헤더가 젠킨스까지 잘 타고 가야 한다. 이를 위한 처리이다.
      • map 블록: Upgrade 가 헤더가 들어오면 기본적으로 `$connection_upgrade` 변수에 upgrade 를 넣어서 전달하지만, Upgrade 헤더가 없으면 변수에 close 를 넣어서 전달한다.
      • `$connection_upgrade` 변수는 젠킨스에 Connection 헤더를 통해 전달된다.
    • proxy_max_temp_file_size: 이걸 딱히 수정 안하면 1024MB(default) 이상 파일 다운로드가 안된다고 한다. 0 은 제한하지 않는다는 의미이다.
    • $remote_addr: nginx 변수이다. 클라이언트 주소가 전달된다. 참고
    • $proxy_add_x_forwarded_for: nginx 변수이다. 들어오는 X-Forwarded-For 헤더에 $remote_addr 이 콤마로 추가된다. 참고
    • 참고한 페이지 에는 있었지만 제거한 설정
      • sendfile 은 파일 전달 시 버퍼에 저장할지 말지에 대한 것인데 userContent 를 사용하지 않을 것이라 불필요하다.
      • /static: 굳이 나눌 필요가 없을 것 같아서 제거
      • /userContent: 젠킨스의 userContent 기능 역시 사용하지 않기 때문에 아예 제거 (userContent: https://www.jenkins.io/doc/book/managing/user-content/)

    1.2 Dockerfile 및 이미지 생성

    ssl 에 대한 파일과, 위에서 만든 jenkins.conf 설정파일을 넣어 새로운 이미지를 만든다.

    아래와 같은 구조이다.

    /jenkins
    +- Dockerfile
    +- jenkins-chained.crt
    +- jenkins.key
    +- conf.d/
       +- jenkins.conf

    Dockerfile 은 다음과 같다.

    FROM nginx:1.20.2
    
    COPY *.crt /etc/nginx/
    COPY *.key /etc/nginx/
    COPY conf.d/ /etc/nginx/conf.d/

    이미지를 만든다.

    docker build -t my-nginx:0.1 .

    2. 실행

    새로 만든 이미지로 컨테이너를 실행한다.

    docker run -d --name nginx -p 80:80 -p 443:443 --link jenkins:jenkins my-nginx:0.1

    nginx 컨테이너 내부에서 jenkins 컨테이너에 접근이 가능해야 하기 때문에 link 옵션을 주었다. 아니면 docker network 를 따로 만들어서 두 컨테이너가 공유하는 방법도 있다.

     

    이제 https 로 jenkins 에 접근이 가능하다.

    hosts 를 고치고 https://my-jenkins.com 으로 접근해 보자.

    반응형

    댓글

Designed by Tistory.