предисловие
Я обновил сервер несколько лет назад.Исходный сервер был комбинацией Nginx+Jenkins+Docker.Из-за моего сильного интереса к обновленным инструментам я хотел сосредоточиться на возне с новыми игрушками и начал использовать Traefik+DroneCi+Docker на замену оригинальной.Бросающая дорога комбинации.
После первоначального завершения настройки сервиса я хочу написать эту статью, чтобы оставить заметку о ямах, с которыми я столкнулся, и я надеюсь помочь другим людям, которые плохо знакомы с ямами.
Traefik
Traefik — это обратный прокси-сервер с открытым исходным кодом и инструмент балансировки нагрузки.Многие сравнивают его с Nginx.На самом деле, я лично считаю, что у обоих есть свои достоинства. Когда я использую его, поскольку traefik плохо поддерживает статические веб-сайты, я все еще использую его с Nginx. Но это не останавливает тот факт, что это отличный инструмент обратного прокси.
настройка и запуск
Конфигурация Traefik включает в себя статическую конфигурацию и динамическую конфигурацию. Статическая конфигурация — это конфигурация самого Traefik при запуске, и ее необходимо перезапустить, чтобы она вступила в силу. Динамическая конфигурация может рассматриваться как конфигурация прокси-службы и не требует перезапуска. после модификации. Поддерживается динамическая или статическая конфигурацияCli
form и конфигурационный файл form, но конфигурационный файл и параметры cli нельзя накладывать друг на друга.
-
статическая конфигурация
Взяв в качестве примера запуск службы Traefik в docker-compose, мы можем посмотреть на путь cli и файлов конфигурации:
services: traefik: restart: always image: traefik:latest ports: - "80:80" - "443:443" # command: # - "--providers.docker=true" # - "--providers.docker.exposedbydefault=false" volumes: - /var/run/docker.sock:/var/run/docker.sock - ./acme.json:/acme.json - ./traefik/:/etc/traefik # 如果有配置文件了,则command 失效 who: image: containous/whoami labels: - "traefik.enable=true" - "traefik.http.routers.whoa.rule=Host(`who.nefelibata.art)"
Мы настроили контейнер traefik и включили
traefik.toml
а такжеdynamic.toml
документ./traefik
каталог сопоставляется с контейнером/etc/traefik
каталог, который traefik будет читать при запуске/etc/traefik
в каталогеtraefik.toml
, если вы хотите использовать метод cli, вы передадите параметры конфигурации через команду. -
Динамическая конфигурация
-
Форма файла конфигурации
Сначала нам нужно
traefik.toml
Существуют следующие конфигурации:[providers] ## ... [providers.file] filename = "/etc/traefik/dynamic_conf.toml" watch = true
затем в
dynamic_conf.toml
Средняя конфигурацияrouters
а такжеservices
[http.routers] [http.routers.https-egg] rule = "Host(`egg.nefelibata.art`)" service = "egg-service" [http.routers.https-egg.tls] ## 开启https certresolver = "le" [http.routers.http-egg] rule = "Host(`egg.nefelibata.art`)" service = "egg-service" [http.services] [[http.services.egg-service.loadBalancer.servers]] url = "http://egg_server:9000"
http.routers
После пользовательского имени жестких требований нет, но дочерние элементы должны быть расширены на основе этого имени, например:http.routers.https-egg
Когда tls включен, он используетсяhttp.routers.https-egg.tls
Следует отметить, что мы
egg.nefelibata.art
Определены два маршрутизатора, это связано с тем, что если установленоtls
Если true, доступ по http больше не поддерживается. Если вы хотите поддерживать обаhttp
а такжеhttps
, необходимо определить不同名
маршрутизация -
Форма меток Docker
Если мы не хотим настраивать все это в файле динамической конфигурации, мы можем
traefik.toml
внутриproviders
Напишите следующую конфигурацию ниже:[providers] [providers.docker] # 以下均为可选项 network = "traefik" exposedByDefault = false defaultRule = "Host(`{{ normalize .Name }}.nefelibata.localhost`)" watch = true ## ... 其他配置
Взяв в качестве примера вышеупомянутый сервис яйца, если указанная выше динамическая конфигурация будет изменена на метки, она будет выглядеть следующим образом:
egg_server: build: ./egg_server expose: - "9000" networks: - default labels: - "traefik.enable=true" - "traefik.http.routes.egg_server.rule=Host(`egg.nefelibata.art`)"
Тогда конфигурация не требуется
services
Теперь просто откройте порт для контейнера.Обратите внимание, что если он отключен в конфигурации
exposedByDefault
опция, если она не определена в этикетках других контейнеровtraefik.enable=true
, служба контейнера будет игнорироваться traefik
-
Открыть информационную панель
Traefik поставляется с панелью инструментов.Если вы хотите включить службу и настроить для нее доменное имя, вы можете настроить ее с помощью описанного выше метода динамической настройки, взяв в качестве примера форму файла конфигурации:
## traefik.toml
### 其他配置...
[api]
### 其他配置... providers, ping .etc
## dynamic.toml
[http.routers.api]
rule = "Host(`traefik.nefelibata.art`)"
service = "api@internal"
middlewares = ["dashboard-auth"]
[http.middlewares]
[http.middlewares.dashboard-auth.basicAuth]
users = [
"evont: $xxxxxxxxxxx"
]
существуетtraefik.toml
открыть вapi
после опции (или в cli--api=true
), traefik будет иметь специальный сервис под названиемapi@internal
, после его настройки, как правило, для предотвращения доступа других, будет выполняться аутентификация, поэтомуmiddlewares
, используя предоставленный traefikbasicAuth
промежуточное ПО, использованиеhtpasswd
Сгенерируйте пользовательский ключ, обратите внимание, например, ваше имяevont
, пароль123456
, окончательный результатevont:$apr1$bL6G3wl2$HllalTsbNwJ/zhoBMhx541
, при открытии панели инструментов и входе в систему введенный пароль по-прежнему 123456 вместо ключевой строки.
После успешной настройки перезапустите службу, откройте доменное имя службы, и вы увидите интерфейс входа в систему.
После успешного входа в систему вы можете войти в интерфейс управления и увидеть настроенные нами правила маршрутизации.Статическая поддержка веб-сайта
У Traefik нет хорошей поддержки статических веб-сайтов (по крайней мере, я не нашел способа ее использовать), поэтому я могу использовать Nginx в качестве сервера только для статических веб-сайтов, но порты 443 и 80 не могут быть предоставлены двум обратным прокси-инструментам. в то же время, поэтому я могу передать только Traefik перенаправляет запрос на Nginx.Мы запускаем службу Nginx, указываем сети, чтобы Nginx и Traefik были в одной сети, а затем назначаем Nginx ограниченное доменное имя через метки.
services:
nginx:
restart: always
image: nginx
networks:
- default
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./html:/usr/share/nginx/html/
labels:
- traefik.enable=true
- traefik.http.routers.w3.rule=Host(`www.nefelibata.art`) || Host(`mock.nefelibata.art`)
- traefik.http.routers.w3.tls=true
- traefik.http.routers.w3.tls.certresolver=le
- traefik.http.routers.w3-http.rule=Host(`www.nefelibata.art`) || Host(`mock.nefelibata.art`)
в Nginxnginx.conf
В файле по-прежнему используется порт 80, а директория статического сайта может быть размещена в соответствии с server_name
http {
server {
listen 80;
server_name www.nefelibata.art;
root /usr/share/nginx/html/www1;
location / {
index index.html;
}
}
server {
listen 80;
server_name mock.nefelibata.art;
root /usr/share/nginx/html/www2;
location / {
index index.html;
}
}
}
поддержка https (также поддерживает http)
Ранее мы упоминали tls и https, естьcertresolver = "le"
, то этоle
Откуда он взялся и как был сгенерирован сертификат для сайта?
если вы хотите использоватьLet's Encrypt
Для автоматической генерации сертификатов traefik предоставляет нам очень удобное решение, нам нужно только использовать следующую конфигурацию в статической конфигурации:
## traefik.toml
### 其他配置...
[certificatesResolvers.le.acme]
email = "evontgoh@foxmail.com" # 你自己的邮箱
storage = "acme.json"
[certificatesResolvers.le.acme.httpChallenge]
entryPoint = "http"
и настроить в docker-composevolumes
карта местногоacme.json
в контейнер
Если у вас есть собственный сертификат, вы также можете пропустить вышеуказанные шаги, вdynamic.toml
Средняя конфигурация
[[tls.certificates]]
certFile = "/path/to/domain.cert"
keyFile = "/path/to/domain.key"
Эта часть может относиться кtls-конфигурация traefik
версия ямы
В начале настройки большинство онлайн-руководств по-прежнему основывались на v1, поэтому настройка не удалась. Позже выяснилось, что разница между версиями v1 и v2 слишком велика, элементы конфигурации были другими и дажеtraefik китайская документацияпо-прежнему основаны на конфигурации v1, например, при определении правил маршрутизации
## v1 规则如下:
[frontends] ## 规定前端进入规则
[frontends.frontend1]
backend = "backend1" # 指定后端服务
[frontends.frontend1.routes] ## 定义路由
[frontends.frontend1.routes.route0]
rule = "Host:test.localhost" ## 注意,这里写法也变了
[backends] ## 定义后端服务
[backends.backend1]
[backends.backend1.servers.server0]
url = "http://xx.xx.xx.xx:80"
## v2 规则弃用了frontend & backend
[http.routers] ## 用routers 规定路由规则
[http.routers.router0]
rule = "Host(`test.localhost`)" ## 写法变了
service = "my-service"
[http.services]
[[http.services.my-service.loadBalancer.servers]]
url = "http://xx.xx.xx.xx:80"
В то же время вышеперечисленные правила определены в v1[file]
Под полем, во v2, это в[providers]
вниз[providers.file]
определяется в и становится отдельным файлом динамической конфигурации
В связи с этим рекомендую прочитатьДокументация по миграции официальной версии, и на основе официальной документации (хотя она тоже вольно написана и не очень дружелюбна к людям с плохим английским языком).
Drone CI
Я всегда использовал Jenkins, стандартный отраслевой инструмент CI, но мне всегда казалось, что он немного громоздкий из-за его богатых функций Drone оптимизирован для контейнерных сред, таких как Docker и K8s, а также достаточно легкий и гибкий. Как выбрать можно посмотретьэта статья
OAuth
Во-первых, Drone поддерживает только Git.Взяв Github в качестве примера, чтобы вытащить код, вам нужноDeveloper settings(вы можете использовать другие хранилища git), чтобы создать новое приложение OAuth, заполните доменное имя вашего сервиса Drone, обратите внимание, что URL-адрес обратного вызова должен заполнить логин
Установить
Он по-прежнему основан на концепции, что все сервисы сервера находятся в Docker.docker-compose.yml
Создайте новый сервис Drone в , многие туториалы настроят клиент (агентов) агента Drone-runner, но это не обязательно, на самом деле вы можете полностью использовать сервер Drone для завершения сервиса
version: "3"
services:
drone-server:
image: drone/drone:latest
labels:
- traefik.http.routers.drone.rule=Host(`ci.nefelibata.art`)
- traefik.enable=true
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /etc/docker/:/etc/docker
- ./drone:/var/lib/drone/ # 注意设置这一目录,用于放置sqlite文件,如果用mysql 或其他数据库,酌情处理
restart: always
networks:
- default
environment:
- DRONE_OPEN=TRUE
- DRONE_ADMIN=xxx
- DRONE_USER_CREATE=username:xxx,admin:true
- DRONE_DATABASE_DATASOURCE=/var/lib/drone/drone.sqlite # 指向该目录
- DRONE_DATABASE_DRIVER=sqlite3 # 数据库引擎
- DRONE_RPC_SECRET=${DRONE_RPC_SECRET}
- DRONE_RPC_PROTO=${DRONE_RPC_PROTO}
- DRONE_AGENTS_DISABLED=true
- DRONE_GITHUB_CLIENT_ID=${DRONE_GITHUB_CLIENT_ID}
- DRONE_GITHUB_CLIENT_SECRET=${DRONE_GITHUB_CLIENT_SECRET}
- DRONE_SERVER_HOST=${DRONE_SERVER_HOST}
- DRONE_SERVER_PROTO=${DRONE_SERVER_PROTO}
networks:
default:
external:
name: traefik
В конфигурации, чтобы не хотеть некоторые из наших клавиш, которые будут выставлены, мы можем написать эту часть переменных в.env
Файл, Docker считывает файлы в том же каталоге, пишет указанная переменная $ {xxx} переменная:
DRONE_GITHUB_CLIENT_ID=xxxxx # 填入OAuth 生成的client id
DRONE_GITHUB_CLIENT_SECRET=xxxxx # 填入OAuth 生成的client secret
DRONE_RPC_SECRET=xxxxx # 可以通过openssl rand -hex 16 生成
DRONE_SERVER_HOST=ci.nefelibata.art
DRONE_SERVER_PROTO=http
DRONE_RPC_PROTO=http
Зарегистрированный дрон по умолчанию является общедоступным, то есть все те, у кого есть доступ к вашему адресу CI, могут зарегистрироваться и использовать вашу систему CI, если вы хотите ограничить пользователей, вы можете настроить среду- DRONE_USER_FILTER=evont, xxx
способ добавить пользователей, которым разрешено присоединиться (но ранее зарегистрированные пользователи не будут ограничены, странная логика).
Запустите службу, получите доступ к доменному имени службы и перейдите к Github, чтобы войти в систему. Если пользователь входа в систему ограничен на предыдущем шаге, а текущее имя учетной записи Github не входит в разрешенную учетную запись, при возврате к сервис.
В случае успеха вы можете увидеть список ваших проектов репозитория Github.
Войдите в проект и активируйте проект, если вошедший в систему пользователь является администратором, он будетProject settings
появляться вTrusted
вариант, иначе есть только одинProtected
вариант, толькоTrusted
Репозиторий может выполняться только с хостом в процессе сборкиVolumes
карта.
сборка проекта
Возьмем для примера мой проект, я надеюсь, что после отправки кода Drone поможет мне собрать образ и запушить его в зеркальный репозиторий.
Создайте новый проект, после завершения основного кода создайте новый в корневом каталоге проекта следующим образом..drone.yml
, с помощью DroneDockerПлагин, указывающий адрес зеркального репозитория и ветку.
Поскольку вы используете частный репозиторий, вам необходимо войти в систему. В это время мы можем использовать интерфейс CISecrets
Столбец может быть заполнен некоторыми переменными для использования в процессе сборки, и они не будут отображаться в.drone.yml
бинго. Как показано на предыдущем рисунке, вSecrets
Частично добавить обычайDOCKER_USERNAME
а такжеDOCKER_PASSWORD
поле, затем в.drone.yml
прошедшийfrom_secret
входящийusername
а такжеpassword
, его не нужно прописывать в конфигурационном файле, чтобы его не увидели другие, у которых есть доступ к коду.
Кроме того, из-за низкой скорости загрузки образов Docker вы можете установитьmirror
Указывает источник ускорения Docker.
---
kind: pipeline
type: docker
name: default
steps:
- name: egg-docker
image: plugins/docker
settings:
mirror: https://xxxx(自己的用户id).mirror.aliyuncs.com
username:
from_secret: DOCKER_USERNAME
password:
from_secret: DOCKER_PASSWORD
repo: registry.cn-hangzhou.aliyuncs.com/nefelibata/egg
registry: registry.cn-hangzhou.aliyuncs.com
auto_tag: true
trigger:
branch:
- master
event:
- push
После подтверждения отправьте код в проект, чтобы запустить сборку. Если версия дрона выше 1.4.0 и агент не включен, вы, вероятно, застряли в состоянии ожидания, как и я, потому что по умолчанию дрон находится в многомашинном режиме (multi-machine mode
), если он находится под одним сервером, прокси-сервер ставить не нужно. Многие конфигурации в Интернете преподаютсяDRONE_AGENTS_ENABLED=false
, однако на самом деле это должно бытьDRONE_AGENTS_DISABLED=true
включить автономный режим (single-machine mode
)
После его настройки и запуска сборки вы можете видеть, что в проекте есть процесс сборки, он вытащит код проекта во временный каталог, и этот каталог будет уничтожен после завершения сборки.
Сборка завершена, загнали на зеркальный склад, посыпаем цветами!
Docker
-
networks
Контейнеры между разными Docker Compose отличаются друг от друга.Каждый Docker Compose имеет свои сети.Вышеуказанные сервисы разделены по разным
docker-compose.yml
В файле, чтобы сделать их взаимосвязанными, нам нужно сделать их в одной сети, в это время мы можем сначала выполнитьdocker network create treaefik
Создайте общую сеть, а затем в каждойdocker-compose.yml
Настройте сети так, чтобы они указывали на эту вновь созданную сеть, и, наконец, укажите ее сети в контейнере.services: nginx: # ... image: nginx networks: - default # ... networks: default: external: name: treaefik
-
разное
Есть много статей, связанных с докером, и я пока не встречал никаких ям в проекте, которые нужно было бы записывать.