Проект автоматизированного развертывания Docker+Jenkins+Nginx+SpringBoot

Docker

Docker реализует изоляцию ресурсов через пространство имен linux, управление ресурсами через контрольные группы и эффективные операции с файлами с помощью механизма копирования при записи.В реальной разработке его можно использовать для предоставления одноразовой среды и построения микросервисной архитектуры. , Унифицированная среда развертывание.

предисловие

Хотя Docker уже является популярной контейнерной технологией во всем мире, одной из главных достопримечательностей Docker является унификация среды, чтобы избежать проблемы конфигурации среды, но при ее детальном использовании по-прежнему возникает много проблем.

  • Поскольку на официальном сайте Jenkins естьУстановите Дженкинс на Докерпроцесса, так как же мне использовать контейнер Jenkins?
  • Если вы используете контейнер Jenkins, как я могу развернуть проект SpringBoot через контейнер Jenkins? Взаимодействует ли развертывание проекта через контейнер Jenkins с файлами в контейнере SpringBoot? Можно ли это сделать? Либо положить проект SpringBoot в контейнер Jenkins для управления, а потом в Jenkins установить кучу всего типа git, maven и т.д., что вообще неудобно.
  • Используя подключаемый модуль IDEA Docker, вы можете напрямую подключаться к серверу Docker для создания образов и запуска контейнеров.Зачем вам нужен Jenkins?

Ответ, соответствующий приведенному выше, также был найден в реальной конструкции и развертывании:

  • Если вы используете контейнер Jenkins, это сделает развертывание более проблематичным, поскольку Jenkins часто требуется настроить ряд переменных, таких как Maven и git, и вам следует найти другой выход. Поскольку Jenkins — это скриптовый инструмент непрерывной интеграции, а у Docker есть собственные скрипты, мне следует подумать об интеграции скриптов Docker в Docker.
  • В реальной разработке Jenkins может потребоваться не только для развертывания проектов, но и для аутентификации разработчиков.Например, разработчик А может просматривать только указанные проекты развертывания, а администраторы могут просматривать и развертывать все проекты, но Docker в основном используется для сборка образов и контейнеры.Во время работы невозможно получить код github/gitlab, такой как Jenkins, и невозможно аутентифицировать разработчиков, поэтому Docker может играть роль в Jenkins только для упрощения процесса развертывания.
  • Хотя подключаемый модуль IDEA может напрямую развернуть локально упакованный проект на сервер Docker и создать образ для запуска контейнера, в целях безопасности необходимо создать контейнер.Сертификация Docker CAОчень неудобно качать на локалку и потом подключаться к докеру на сервере

Подготовка окружающей среды

Когда были изучены ответы на вопросы о себе, были определены основные обязанности компонентов:

  • Jenkins: получать информацию об обновлении проекта и выполнять упаковку проекта и выполнение скрипта Docker.
  • Docker: установите необходимый образ приложения и запустите контейнер
  • git: синхронизация информации о проекте

Процесс настройки окружения:

  1. Установить JDK

  2. Установить Мавен

  3. установить git

  4. Установите Jenkins (для справки перед этим шагомJenkins устанавливает и развертывает полный процесс проекта Java) Если у вас есть проблемы с правами доступа, вы можете поместить файл /etc/sysconfig/jenkinsJENKINS_USERМодифицировать до root или вручную авторизоваться

  5. Установите Docker на Centos (Установите Docker Engine — Сообщество)

  6. Установите Docker Compose

    sudo curl -L "https://github.com/docker/compose/releases/download/1.25.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
    sudo chmod +x /usr/local/bin/docker-compose
    sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
    docker-compose --version
    

    Использование DockerCompose может избавить вас от необходимости многократного выполнения docker run при увеличении количества контейнеров.

Конкретные шаги

  • конфигурационный файл

    1. Dockerfile проекта SpringBoot

    FROM java:8
    
    MAINTAINER Wilson
    
    # 统一容器与服务器时间
    ENV TZ=Asia/Shanghai
    RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
    
    #复制target/docker-spring-boot.jar到容器app目录下
    COPY ./target/docker-spring-boot.jar app/docker-spring-boot.jar
    EXPOSE 8080
    
    ENTRYPOINT ["java","-jar","app/docker-spring-boot.jar"]
    # docker build -t docker-spring-boot/latest .
    

    2. Настройте docker-compose.yml

    version: '3.7'
    services:
      app:
        restart: always
        build: ./
        hostname: docker-spring-boot
        container_name: docker-spring-boot
        image: docker-spring-boot/latest
    #    端口不对外开放
    #    ports:
    #      - 8080:8080
        volumes:
          - ./volumes/app:/app
      nginx:
        depends_on:
          - app
        container_name: docker-nginx
        hostname: docker-nginx
        image: nginx:1.17.6
        environment:
          TZ: Asia/Shanghai
        restart: always
        expose:
          - 80
        ports:
          - 80:80
        links:
          - app
        volumes:
          - ./volumes/nginx/nginx.conf:/etc/nginx/nginx.conf
          - ./volumes/nginx/conf.d:/etc/nginx/conf.d
          - ./volumes/nginx/logs:/var/log/nginx
    

    3. Nginx

    • ./volumes/nginx/nginx.conf

      user nginx;
      worker_processes 2; #设置值和CPU核心数一致
      error_log /etc/nginx/error.log crit; #日志位置和日志级别
      pid /etc/nginx/nginx.pid;
      
      events
      {
        use epoll;
        worker_connections 65535;
      }
      http{
          include mime.types;
          default_type application/octet-stream;
          log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for" "$http_cookie"';
      
          access_log  /var/log/nginx/access.log main;
          #charset utf8;
      
          server_names_hash_bucket_size 128;
          client_header_buffer_size 32k;
          large_client_header_buffers 4 32k;
          client_max_body_size 8m;
      
          sendfile on;
          tcp_nopush on;
          keepalive_timeout 60;
          tcp_nodelay on;
          fastcgi_connect_timeout 300;
          fastcgi_send_timeout 300;
          fastcgi_read_timeout 300;
          fastcgi_buffer_size 64k;
          fastcgi_buffers 4 64k;
          fastcgi_busy_buffers_size 128k;
          fastcgi_temp_file_write_size 128k;
          gzip on;
          gzip_min_length 1k;
          gzip_buffers 4 16k;
          gzip_http_version 1.0;
          gzip_comp_level 2;
          gzip_types text/plain application/x-javascript text/css application/xml;
          gzip_vary on;
      
          #limit_zone crawler $binary_remote_addr 10m;
          #server虚拟主机的配置
          include /etc/nginx/conf.d/*.conf;
      
      }
      
    • default.conf в каталоге ./volumes/nginx/conf.d

      upstream application {
         server docker-spring-boot:8080;
      }
      
      server{
        listen 80;#监听端口
        server_name localhost;#域名
        access_log /var/log/nginx/nginx-spring-boot.log;
        location / {
            proxy_pass   http://application;
            proxy_set_header Host $host:$server_port;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header REMOTE-HOST $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
      }
      
  • Процесс выполнения развертывания Jenkins

    • maven упаковывает проект Spring Boot как project.jar
    • В зависимости от того, развертывается ли проект в первый раз, выполняются следующие различные процессы:
      • Если текущий смонтированный том уже содержит jar проекта (то есть он запускается не первый раз), выполните следующие шаги:
      1. Скопируйте project.jar, чтобы перезаписать project.jar в смонтированном томе.
      2. Перезапустите контейнер проекта SpringBoot.
      • Если текущий смонтированный том не содержит jar проекта (то есть он не первый раз запускается), выполните следующие шаги:
      1. Создайте каталог смонтированного тома
      2. Скопируйте project.jar на подключенный том
      3. Создайте образ для запуска контейнера, прочитав конфигурацию docker-compose.yml через docker-compose.

    Скрипт Jenkins (если конфигурация Nginx сильно меняется, можно также добавить инструкцию перезапуска контейнера Nginx):

    cd /var/lib/jenkins/workspace/docker-spring-boot/spring-boot-nginx-docker-demo
    mvn clean package
    if [ -e "./volumes/app/docker-spring-boot.jar" ]
      then rm -f ./volumes/app/docker-spring-boot.jar \
            && cp ./target/docker-spring-boot.jar ./volumes/app/docker-spring-boot.jar \
    		&& docker restart docker-spring-boot \
            && echo "update restart success"
      else mkdir volumes/app -p \
            && cp ./target/docker-spring-boot.jar ./volumes/app/docker-spring-boot.jar \
    		&& docker-compose -p docker-spring-boot up -d \
            && echo "first start"
    fi
    

    Команда docker-compose up может установить образ, поэтому она также избавляет от необходимости заранее готовить команды, связанные с зеркалированием, при использовании только команды docker.

результат теста

  • Проверьте, все ли контейнеры запущены:docker ps
    在这里插入图片描述
  • Просмотрите результат работы контейнера SpringBoot: если контейнер открывает порт 8080, вы можете проверить его через http://url:8080/swagger-ui.html или проверить результат проверки журнала SpringBoot в /volumes/app в рабочая область Jenkins (SpringBoot. Конфигурация пути журнала установлена ​​​​в каталог app/logs, а каталог приложения в контейнере был смонтирован в каталог Volumes/App текущего проекта в предыдущей статье)
    在这里插入图片描述
  • Просмотрите результаты работы контейнера Nginx: посетите http://url/swagger-ui.html, чтобы проверить, успешно ли контейнер Nginx подключился к контейнеру SpringBoot и выполнил обратное проксирование. Вы также можете просмотреть Nginx в /volumes/nginx /logs в результатах проверки журнала рабочей области Jenkins
    在这里插入图片描述
  • Добавьте или удалите интерфейс контроллера и отправьте его в git, чтобы увидеть, доступен ли измененный интерфейс.

Создание кластера SpringBoot

Чтобы собрать SpringBoot через кластер контейнеров, просто внесите следующие изменения:

  • docker-compose.yml добавляет избыточность проекта SpringBoot, изменяет имя избыточного контейнера, различает путь подключения журнала и изменяет имя контейнера для избыточных проектов.

    version: '3.7'
    services:
      app:
        restart: always
        build: ./
        hostname: docker-spring-boot
        container_name: docker-spring-boot
        image: docker-spring-boot/latest
        volumes:
          - ./volumes/app/docker-spring-boot.jar:/app/docker-spring-boot.jar
          - ./volumes/app/logs:/app/logs
      app-bak:
        restart: always
        build: ./
        hostname: docker-spring-boot
        container_name: docker-spring-boot-bak
        image: docker-spring-boot/latest
        volumes:
          - ./volumes/app/docker-spring-boot.jar:/app/docker-spring-boot.jar
          - ./volumes/app/logs-bak:/app/logs
      nginx:
        depends_on:
          - app
        container_name: docker-nginx
        hostname: docker-nginx
        image: nginx:1.17.6
        environment:
          TZ: Asia/Shanghai
        restart: always
        expose:
          - 80
        ports:
          - 80:80
        links:
          - app
          - app-bak
        volumes:
          - ./volumes/nginx/nginx.conf:/etc/nginx/nginx.conf
          - ./volumes/nginx/conf.d:/etc/nginx/conf.d
          - ./volumes/nginx/logs:/var/log/nginx
    
  • nginx изменяет восходящий поток default.conf и добавляет избыточную конфигурацию контейнера.

    upstream application {
       server docker-spring-boot:8080 fail_timeout=2s max_fails=2 weight=1;
       server docker-spring-boot-bak:8080 fail_timeout=2s max_fails=2 weight=1;
    }
    
    server{
      listen 80;#监听端口
      server_name localhost;#域名
      access_log /var/log/nginx/nginx-spring-boot.log;
      location / {
          proxy_pass   http://application;
          proxy_connect_timeout 2s;
          proxy_set_header Host $host:$server_port;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header REMOTE-HOST $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      }
    }
    
  • Jenkins добавляет избыточные сценарии перезапуска контейнера

    BUILD_ID=DONTKILLME
    cd /var/lib/jenkins/workspace/docker-spring-boot/spring-boot-nginx-docker-demo
    mvn clean package
    if [ -e "./volumes/app/docker-spring-boot.jar" ]
      then rm -f ./volumes/app/docker-spring-boot.jar \
            && cp ./target/docker-spring-boot.jar ./volumes/app/docker-spring-boot.jar \
    		&& docker-compose -p docker-spring-boot up -d \
    		&& docker restart docker-spring-boot \
    		&& docker restart docker-spring-boot-bak \
    		&& docker restart docker-nginx \
            && echo "update restart success"
      else mkdir volumes/app -p \
            && cp ./target/docker-spring-boot.jar ./volumes/app/docker-spring-boot.jar \
    		&& docker-compose -p docker-spring-boot up -d \
            && echo "first start"
    fi
    

Эффект тестового кластера:

  • Volumes/app хранит журналы различных контейнеров, таких как журналы, logs-bak в этом примере
  • Остановить любой контейнер SpringBootdocker stop docker-spring-boot, по-прежнему доступен через Nginx через url/api

Можно увидеть следующие преимущества кластера конфигурации контейнера:

  • Высокий уровень безопасности, каждое приложение принадлежит только одному контейнеру и может взаимодействовать с хостом и другими контейнерами только через определенную конфигурацию.
  • Унифицированный файл конфигурации для простого и грубого решения проблем конфигурации, таких как порты, пути, версии и т. д. Например, даже если проект запускает два контейнера SpringBoot с портами 8080, не нужно беспокоиться о конфликтах портов и проблемы с экспозицией.Все решается в контейнере.
  • Ручная установка приложений опущена, которая легко мигрировать. Поскольку версия, конфигурация, среда и т. Д. Все настраиваются в файле конфигурации Docker, не нужно беспокоиться о различных проблемах конфигурации и окружающей среды после замены машины, и это Может быть опущено с помощью вытягивания и контейнера изображений. Установка и настройка приложений, таких как Nginx, Redis, MySQL и т. Д.
    在这里插入图片描述

Прикрепленный адрес проекта

spring-boot-nginx-docker-demo