-
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 를 적용할 것이기 때문에 필요하다.
- 이름은 jenkins-chained.crt, jenkins.key 로 준비
- 발급 방법에 대해서는 아래를 참고한다.
- openssl 로 self-signed certificate 만들기: https://bitgadak.tistory.com/5
- certbot 으로 let's encrypt 인증서 발급받기: https://bitgadak.tistory.com/6
아래와 같은 형식이 될 것이다.
1. Nginx docker image
nginx docker image 사용에 대해서는 docker hub 를 참고하였다: https://hub.docker.com/_/nginx
여기서 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/
여기를 참고하지만 불필요한 부분을 제거하고 필요한 부분을 추가해서 수정한다.
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 으로 접근해 보자.
반응형'docker' 카테고리의 다른 글
nexus3 docker image 로 private docker repository 만들기 (1) 2022.02.14 DooD (docker-outside-of-docker) 를 통해 Jenkins 컨테이너에서 docker 사용하기 (1) 2021.09.06