Cách sử dụng Traefik làm Reverse Proxy cho Docker Containers trên Ubuntu 16.04
Docker có thể là một cách hiệu quả để chạy các ứng dụng web trong production , nhưng bạn có thể cần chạy nhiều ứng dụng trên cùng một server Docker. Trong trường hợp này, bạn cần cài đặt Reverse Proxy vì bạn chỉ muốn hiển thị cổng80
và 443
với phần còn lại của thế giới. Traefik là một Reverse Proxy nhận biết Docker bao gồm console giám sát của riêng nó. Trong hướng dẫn này, bạn sẽ sử dụng Traefik để định tuyến các yêu cầu đến hai containers ứng dụng web khác nhau: containers Wordpress và vùng chứa Adminer , mỗi vùng nói chuyện với database MySQL. Bạn sẽ cấu hình Traefik để phân phát mọi thứ qua HTTPS bằng Let's Encrypt .
Yêu cầu
Để làm theo hướng dẫn này, bạn cần những thứ sau:
Một server Ubuntu 16.04 được cài đặt theo hướng dẫn cài đặt server ban đầu Ubuntu 16.04 , bao gồm user không phải root có quyền sudo và firewall .
Docker được cài đặt trên server của bạn, bạn có thể thực hiện việc này theo Cách cài đặt và sử dụng Docker trên Ubuntu 16.04 .
Docker Compose được cài đặt theo hướng dẫn từ Cách cài đặt Docker Compose trên Ubuntu 16.04 .
Một domain và ba bản ghi A,
db-admin
,blog
vàmonitor
, mỗi bản ghi trỏ đến địa chỉ IP của server của bạn. Bạn có thể tìm hiểu cách trỏ domain tới DigitalOcean Server bằng cách đọc qua tài liệu DNS và Tên domain của DigitalOcean. Trong suốt hướng dẫn này, hãy thay thế domain của bạn choexample.com
trong các file cấu hình và ví dụ.
Bước 1 - Cấu hình và chạy Traefik
Dự án Traefik có Docker image chính thức , vì vậy ta sẽ sử dụng hình ảnh đó để chạy Traefik trong containers Docker.
Nhưng trước khi cài đặt và chạy containers Traefik, ta cần tạo file cấu hình và cài đặt password được mã hóa để có thể truy cập trang tổng quan giám sát.
Ta sẽ sử dụng trình htpasswd
để tạo password được mã hóa này. Đầu tiên, hãy cài đặt tiện ích có trong gói apache2-utils
:
- sudo apt-get install apache2-utils
Sau đó tạo password bằng htpasswd
. Thay thế secure_password
bằng password bạn muốn sử dụng cho admin-user Traefik:
- htpasswd -nb admin secure_password
Kết quả kết quả từ chương trình sẽ như sau:
Outputadmin:$apr1$ruca84Hq$mbjdMZBAG.KWn7vfN/SNK/
Bạn sẽ sử dụng kết quả này trong file cấu hình Traefic để cài đặt Xác thực cơ bản HTTP cho trang tổng quan giám sát và kiểm tra tình trạng Traefik. Sao chép toàn bộ dòng kết quả để bạn có thể dán nó sau này.
Để cấu hình server Traefik, ta sẽ tạo file cấu hình mới có tên traefik.toml
bằng định dạng TOML. TOML là một ngôn ngữ cấu hình tương tự như các file INI, nhưng nó được chuẩn hóa. Tệp này cho phép ta cấu hình server Traefik và các tích hợp khác nhau hoặc các nhà cung cấp mà ta muốn sử dụng. Trong hướng dẫn này, ta sẽ sử dụng ba trong số các nhà cung cấp có sẵn của Traefik: web
, docker
và acme
, được sử dụng để hỗ trợ TLS bằng Let's Encrypt.
- nano traefik.toml
Đầu tiên, hãy thêm hai điểm vào được đặt tên, http
và https
, mà tất cả các phần backend sẽ có quyền truy cập theo mặc định:
defaultEntryPoints = ["http", "https"]
Ta sẽ cấu hình các điểm nhập http
và https
sau trong file này.
Tiếp theo, cấu hình nhà cung cấp web
, cung cấp cho bạn quyền truy cập vào giao diện console . Đây là nơi bạn sẽ dán kết quả từ lệnh htpasswd
:
... [web] address = ":8080" [web.auth.basic] users = ["admin:your_encrypted_password"]
Trang tổng quan là một ứng dụng web riêng biệt sẽ chạy trong containers Traefik. Ta đặt console để chạy trên cổng 8080
.
Phần web.auth.basic
cấu hình Xác thực Cơ bản HTTP cho trang tổng quan. Sử dụng kết quả từ lệnh htpasswd
mà bạn vừa chạy cho giá trị của mục nhập users
. Bạn có thể chỉ định thông tin đăng nhập bổ sung bằng cách phân tách chúng bằng dấu phẩy.
Tiếp theo, xác định các điểm vào. Phần entryPoints
cấu hình các địa chỉ mà Traefik và các containers được ủy quyền có thể lắng nghe. Thêm các dòng này vào file :
... [entryPoints] [entryPoints.http] address = ":80" [entryPoints.http.redirect] entryPoint = "https" [entryPoints.https] address = ":443" [entryPoints.https.tls]
Điểm nhập http
xử lý cổng 80
, trong khi điểm nhập https
sử dụng cổng 443
cho TLS / SSL. Ta tự động chuyển hướng tất cả lưu lượng trên cổng 80
đến điểm nhập https
để buộc kết nối an toàn cho tất cả các yêu cầu.
Cuối cùng, thêm phần này để cấu hình hỗ trợ certificate Let's Encrypt cho Traefik:
... [acme] email = "your_email@example.com" storage = "acme.json" entryPoint = "https" onHostRule = true onDemand = false
Phần này được gọi là acme
vì ACME là tên của giao thức được sử dụng để giao tiếp với Let's Encrypt để quản lý certificate . Để có Traefik tạo certificate cho server của ta , ta cài đặt các email
quan trọng để địa chỉ email của bạn. Sau đó, ta chỉ định rằng ta sẽ lưu trữ thông tin mà ta sẽ nhận được từ Let's Encrypt trong một file JSON có tên là acme.json
. Khóa entryPoint
cần trỏ đến cổng xử lý điểm nhập 443
, trong trường hợp của ta là điểm nhập https
.
Hai khóa cuối cùng, onHostRule
và onDemand
, chỉ định cách Traefik tiến hành tạo certificate . Ta muốn tìm nạp certificate của bạn ngay sau khi các containers của ta có tên server được chỉ định được tạo và đó là những gì cài đặt onHostRule
sẽ thực hiện. Cài đặt onDemand
sẽ cố gắng tạo certificate lần đầu tiên khi một yêu cầu được thực hiện. Điều này sẽ làm chậm yêu cầu đầu tiên và rất đáng chú ý đối với khách truy cập, vì vậy ta sẽ tránh điều đó.
Lưu file và thoát khỏi editor . Với tất cả cấu hình này, ta có thể kích hoạt Traefik.
Bước 2 - Chạy Traefik Container
Tiếp theo, tạo một mạng Docker để proxy chia sẻ với các containers . Mạng Docker là cần thiết để ta có thể sử dụng nó với các ứng dụng đang chạy bằng Docker Compose. Hãy gọi đây là proxy
mạng.
- docker network create proxy
Khi containers Traefik bắt đầu, ta sẽ thêm nó vào mạng này. Sau đó, ta có thể thêm các containers bổ sung vào mạng này sau đó để Traefik ủy quyền.
Tiếp theo, tạo một file trống chứa thông tin Let's Encrypt của ta . Ta sẽ chia sẻ cái này vào containers để Traefik có thể sử dụng nó:
- touch acme.json
Traefik sẽ chỉ có thể sử dụng file này nếu user root bên trong containers có quyền truy cập đọc và ghi duy nhất vào nó. Để thực hiện việc này, hãy khóa các quyền trên acme.json
để chỉ chủ sở hữu của file mới có quyền đọc và ghi.
- chmod 600 acme.json
Khi file được chuyển đến Docker, chủ sở hữu sẽ tự động thay đổi thành user root bên trong containers .
Cuối cùng, tạo containers Traefik bằng lệnh này:
- docker run -d \
- -v /var/run/docker.sock:/var/run/docker.sock \
- -v $PWD/traefik.toml:/traefik.toml \
- -v $PWD/acme.json:/acme.json \
- -p 80:80 \
- -p 443:443 \
- -l traefik.frontend.rule=Host:monitor.example.com \
- -l traefik.port=8080 \
- --network proxy \
- --name traefik \
- traefik:1.3.6-alpine --docker
Lệnh hơi dài nên hãy chia nhỏ nó ra.
Ta sử dụng cờ -d
để chạy containers trong nền dưới dạng daemon. Sau đó, ta chia sẻ file docker.sock
của docker.sock
vào containers để quy trình Traefik có thể lắng nghe các thay đổi đối với containers . Ta cũng chia sẻ file cấu hình traefik.toml
và file acme.json
mà ta đã tạo vào containers .
Tiếp theo, ta ánh xạ các cổng :80
và :443
của server Docker của ta với các cổng giống nhau trong containers Traefik để Traefik nhận tất cả truy cập HTTP và HTTPS đến server .
Sau đó, ta cài đặt hai nhãn Docker yêu cầu Traefik hướng lưu lượng truy cập đến trình monitor. example.com
tên server monitor. example.com
đến cổng :8080
trong containers Traefik, hiển thị console giám sát.
Ta đặt mạng của containers thành proxy
và ta đặt tên là traefik
containers .
Cuối cùng, ta sử dụng hình ảnh traefik:1.3.6-alpine
cho containers này, vì nó nhỏ.
ENTRYPOINT
của Docker image là lệnh luôn chạy khi containers được tạo từ hình ảnh. Trong trường hợp này, lệnh là binary traefik
trong containers . Bạn có thể chuyển các đối số bổ sung cho lệnh đó khi chạy containers . Trong trường hợp của ta , ta vượt qua đối số --docker
đến ENTRYPOINT
đảm bảo docker
cung cấp dịch vụ được đăng ký với các cài đặt mặc định. Các docker
cung cấp dịch vụ cho phép Traefik để hoạt động như một proxy trước container Docker. Cấu hình mặc định của nhà cung cấp Docker hoạt động tốt cho ta , vì vậy ta sẽ không cần phải cấu hình nó trong traefik.toml
của traefik.toml
.
Khi containers được khởi động, bây giờ bạn có một trang tổng quan mà bạn có thể truy cập để xem tình trạng của containers của bạn . Bạn cũng có thể sử dụng console này để trực quan hóa các giao diện user và backend mà Traefik đã đăng ký. Truy cập trang tổng quan giám sát bằng cách trỏ trình duyệt của bạn tới https://monitor. example.com
. Bạn sẽ được yêu cầu nhập tên user và password của bạn , đó là administrator và password bạn đã cấu hình ở Bước 1.
Sau khi đăng nhập ,. bạn sẽ thấy một giao diện tương tự như sau:
Vẫn chưa có nhiều thứ để xem, nhưng hãy để cửa sổ này mở và bạn sẽ thấy nội dung thay đổi khi bạn thêm các containers để Traefik làm việc.
Bây giờ ta có proxy Traefik của bạn đang chạy, được cấu hình để hoạt động với Docker và sẵn sàng theo dõi các containers Docker khác. Hãy bắt đầu một số containers để Traefik hoạt động như một proxy.
Bước 3 - Đăng ký containers với Traefik
Với containers Traefik đang chạy, bạn đã sẵn sàng chạy các ứng dụng đằng sau nó. Hãy chạy các cotainers sau Traefik:
- Một blog sử dụng hình ảnh Wordpress chính thức .
- Server quản lý database sử dụng hình ảnh Adminer chính thức .
Ta sẽ quản lý cả hai ứng dụng này bằng Docker Compose bằng cách sử dụng file docker-compose.yml
:
- nano docker-compose.yml
Thêm các dòng sau vào file để chỉ định version và mạng ta sẽ sử dụng:
version: "3" networks: proxy: external: true internal: external: false
Ta sử dụng Docker Compose version 3
vì đây là version chính mới nhất của định dạng file Compose.
Để Traefik nhận ra các ứng dụng của ta , chúng phải là một phần của cùng một mạng và vì ta đã tạo mạng theo cách thủ công, ta kéo nó vào bằng cách chỉ định tên mạng của proxy
và đặt external
thành true
. Sau đó, ta xác định một mạng khác để ta có thể kết nối các containers được tiếp xúc với một containers database mà ta sẽ không hiển thị thông qua Traefik. Ta sẽ gọi mạng này là mạng internal
.
Tiếp theo, ta sẽ xác định từng services
của ta , từng services
một. Hãy bắt đầu với containers blog
, ta sẽ dựa trên hình ảnh WordPress chính thức. Thêm cấu hình này vào file :
version: "3" ... services: blog: image: wordpress:4.7.5-apache environment: WORDPRESS_DB_PASSWORD: labels: - traefik.backend=blog - traefik.frontend.rule=Host:blog.example.com - traefik.docker.network=proxy - traefik.port=80 networks: - internal - proxy depends_on: - mysql
Khóa environment
cho phép bạn chỉ định các biến môi trường sẽ được đặt bên trong containers . Bằng cách không đặt giá trị cho WORDPRESS_DB_PASSWORD
, ta đang yêu cầu Docker Compose lấy giá trị từ shell của ta và chuyển nó qua khi ta tạo containers . Ta sẽ xác định biến môi trường này trong shell của ta trước khi bắt đầu các containers . Bằng cách này, ta không đặt password vào file cấu hình.
Phần labels
là nơi bạn chỉ định các giá trị cấu hình cho Traefik. Các nhãn Docker không tự làm bất cứ điều gì, nhưng Traefik đọc những thứ này để biết cách xử lý containers . Đây là những gì mỗi nhãn này thực hiện:
-
traefik.backend
chỉ định tên của dịch vụ backend trong Traefik (trỏ đến containersblog
thực tế). -
traefik.frontend.rule=Host:blog. example.com
yêu cầu Traefik kiểm tra server được yêu cầu và server có trùng với mẫublog. example.com
nó sẽ định tuyến lưu lượng truy cập đến containersblog
. -
traefik.docker.network=proxy
chỉ định mạng nào cần xem để Traefik tìm IP nội bộ cho containers này. Vì containers Traefik của ta có quyền truy cập vào tất cả thông tin Docker, nên nó có khả năng lấy IP cho mạnginternal
nếu ta không chỉ định điều này. -
traefik.port
chỉ định cổng tiếp xúc mà Traefik nên sử dụng để định tuyến lưu lượng truy cập đến containers này.
Với cấu hình này, tất cả truy cập được gửi đến cổng 80
của server lưu trữ Docker của ta sẽ được chuyển đến containers blog
.
Ta gán containers này cho hai mạng khác nhau để Traefik có thể tìm thấy nó thông qua mạng proxy
và nó có thể giao tiếp với containers database thông qua mạng internal
.
Cuối cùng, khóa depends_on
nói với Docker Compose rằng containers này cần bắt đầu sau khi các depends_on
phụ thuộc của nó đang chạy. Vì WordPress cần một database để chạy, ta phải chạy containers mysql
trước khi bắt đầu containers blog
của ta .
Tiếp theo, cấu hình dịch vụ MySQL bằng cách thêm cấu hình này vào file của bạn:
services: ... mysql: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: networks: - internal labels: - traefik.enable=false
Ta đang sử dụng hình ảnh MySQL 5.7 chính thức cho containers này. Bạn sẽ nhận thấy rằng ta đang sử dụng một mục environment
mà không có giá trị. Các MYSQL_ROOT_PASSWORD
và WORDPRESS_DB_PASSWORD
cần được đặt thành cùng một giá trị đảm bảo rằng containers WordPress của ta có thể giao tiếp với MySQL. Ta không muốn hiển thị containers mysql
với Traefik hoặc thế giới bên ngoài, vì vậy ta chỉ gán containers này cho mạng internal
. Vì Traefik có quyền truy cập vào Docker socket, theo mặc định, quy trình sẽ vẫn hiển thị giao diện user cho containers mysql
, vì vậy ta sẽ thêm nhãn traefik.enable=false
để chỉ định rằng Traefik sẽ không hiển thị containers này.
Cuối cùng, thêm cấu hình này để xác định containers Adminer:
services: ... adminer: image: adminer:4.3.1-standalone labels: - traefik.backend=adminer - traefik.frontend.rule=Host:db-admin.example.com - traefik.docker.network=proxy - traefik.port=8080 networks: - internal - proxy depends_on: - mysql
Vùng chứa này dựa trên hình ảnh Adminer chính thức. Cấu hình network
và depends_on
cho containers này khớp chính xác với những gì ta đang sử dụng cho containers blog
.
Tuy nhiên, vì ta đang hướng tất cả lưu lượng truy cập đến cổng 80
trên server Docker của ta trực tiếp đến containers blog
, ta cần cấu hình containers này theo cách khác để lưu lượng truy cập đến adminer
chứa adminer
của ta . Dòng traefik.frontend.rule=Host:db-admin. example.com
yêu cầu Traefik kiểm tra server được yêu cầu. Nếu nó trùng với mẫu của db-admin. example.com
Traefik sẽ định tuyến lưu lượng truy cập đến containers adminer
.
Lưu file và thoát khỏi editor .
Tiếp theo, đặt giá trị trong shell của bạn cho các WORDPRESS_DB_PASSWORD
và MYSQL_ROOT_PASSWORD
trước khi bạn bắt đầu các containers của bạn :
- export WORDPRESS_DB_PASSWORD=secure_database_password
- export MYSQL_ROOT_PASSWORD=secure_database_password
Thay thế secure_database_password
bằng password database mong muốn của bạn.
Với các biến này đã được đặt, hãy chạy các containers bằng cách sử dụng docker-compose
:
- docker-compose up -d
Bây giờ hãy xem xét console quản trị Traefik. Bạn sẽ thấy rằng bây giờ có một chương trình backend
và một frontend
cho hai server được tiếp xúc:
Điều hướng đến blog. example.com
, thay thế example.com
bằng domain của bạn. Bạn sẽ được chuyển hướng đến kết nối TLS và bây giờ có thể hoàn tất cài đặt Wordpress:
Bây giờ truy cập Adminer bằng cách truy cập db-admin. example.com
trong trình duyệt của bạn, lại thay thế example.com
bằng domain của bạn. Vùng chứa mysql
không được tiếp xúc với thế giới bên ngoài, nhưng containers adminer
có quyền truy cập vào nó thông qua mạng Docker internal
mà chúng chia sẻ bằng cách sử dụng tên containers mysql
làm tên server .
Trên màn hình đăng nhập Adminer, sử dụng tên user root , sử dụng mysql
cho server và sử dụng giá trị bạn đặt cho MYSQL_ROOT_PASSWORD
cho password . Sau khi đăng nhập, bạn sẽ thấy giao diện user Adminer:
Cả hai trang web hiện đang hoạt động và bạn có thể sử dụng console tại monitor. example.com
để theo dõi các ứng dụng của bạn.
Kết luận
Trong hướng dẫn này, bạn đã cấu hình Traefik cho các yêu cầu proxy tới các ứng dụng khác trong containers Docker.
Cấu hình khai báo của Traefik ở cấp containers ứng dụng giúp bạn dễ dàng cấu hình nhiều dịch vụ hơn và không cần khởi động lại containers traefik
khi bạn thêm ứng dụng mới vào lưu lượng proxy vì Traefik nhận thấy các thay đổi ngay lập tức thông qua file socket Docker mà nó đang theo dõi.
Để tìm hiểu thêm về những gì bạn có thể làm với Traefik, hãy xem tài liệu Traefik chính thức.
Các tin liên quan
Cách tập trung log Docker của bạn với Fluentd và ElasticSearch trên Ubuntu 16.042016-12-16
Cách làm việc với Docker Data Volumes trên Ubuntu 14.04
2016-11-17
Làm việc với Docker Containers
2016-11-04
Cách cấu hình môi trường kiểm tra tích hợp liên tục với Docker và Docker Compose trên Ubuntu 14.04
2016-11-03
Cách cấu hình môi trường kiểm tra tích hợp liên tục với Docker và Docker Compose trên Ubuntu 16.04
2016-11-03
Cách cài đặt và sử dụng Docker trên CentOS 7
2016-11-02
Cách gỡ lỗi và khắc phục các sự cố thường gặp của Docker
2016-10-20
Cách cài đặt Prometheus bằng Docker trên CentOS 7
2016-01-15
Cách cài đặt Prometheus bằng Docker trên Ubuntu 14.04
2016-01-12
Cách cài đặt Wordpress và PhpMyAdmin với Docker Compose trên Ubuntu 14.04
2015-11-19