8.2 利用 Traefik 部署自己的映像檔儲存庫
購買完網域後,部署自己的映像檔儲存庫之前,我想介紹這一個非常好用的 反向代理伺服器,也是我最近不論是在個人的 Side Project 或是公司的專案都很常使用的工具。
原因是其對於 Docker 的支援度之高,基本上可以說是無腦使用,用起來非常的舒服。
什麼是反向代理伺服器?
我們可以看到下方的圖片:

當我們透過網際網路要存取某個 Web 應用程式的服務時,會先經過一個守門員叫做 反向代理伺服器,將由它來幫我們去拿取服務的內容,而使用這個服務有什麼好處呢?
第一個,內容的 Cache,實現網站加速,反向代理伺服器可以檢視每一次的請求,並且設定 Cache 的機制,讓我們的 App 伺服器不需要每次都和資料庫做請求,大幅地降低 App 伺服器的負擔。
第二個,流量清洗,杜絕惡意攻擊,可以透過觀察單一守門員的紀錄,來整理出某些惡意的請求,並且進行封鎖,反向代理伺服器也支援白名單的功能,當我們發現某些請求過度頻繁時,可以直接封鎖來自該 IP 的請求某段時間。
第三個,隱藏IP位置,避免遭受攻擊,有一個守門員擋在最前面,在後面的所有服務都不需要公開 IP 位置到網際網路之中,等於是整個龐大的 Web 應用程式,只公開反向代理伺服器的 IP 位置以及 Port,這樣可以大幅度地降低被攻擊的風險。
第四個,負載平衡,避免伺服器過載,反向代理伺服器都具備基本的負載平衡功能,也就是其可以分配請求到比較閒的 App 伺服器,避免單一伺服器的工作負擔太重導致伺服器崩潰,放在 Docker 的世界中,Traefik 可以平均分配流量到同一個 Service 的容器中,非常好用。
在介紹完 反向代理伺服器 的好處後,我們直接開始使用 Traefik 部署自己的映像檔儲存庫吧,關於 Traefik 的詳細使用方式, Traefik 官方的手冊上都有非常詳盡的文件說明,本書只會針對部署流程上會使用到的參數以及指令解釋,不會詳細探討 Traefik 如何做到這些事情。
先釐清應用程式的架構
在部署前,可以先用簡單的紙筆記錄一下整個服務會需要使用到的映像檔,以最簡單地部署映像檔儲存庫來說,架構會像是下方的圖片一樣:

但在 Docker 映像檔篇 有提過,官方的映像檔儲存庫是沒有 UI 介面的,而我們可以使用開源的儲存庫 UI 一起加入這個架構之中,就會變成下圖:

接著就可以建立 docker-compose.yml 並開始撰寫,準備部署這整個應用程式。
這邊因為映像檔儲存庫並不需要應付過多的請求,我們就先使用單台的伺服器搭配 Docker Compose 進行單體式部署,而後面的章節將會使用 Docker Swarm 來部署前後端分離的應用程式。
首先是 Traefik 服務的建立,如下面的檔案所示:
# docker-compose.yml
version: '3.9'
x-networks: &network
networks:
- registry
x-restart: &restart-always
restart: always
services:
proxy:
image: traefik:v2.8
container_name: traefik
<<: *network
<<: *restart-always
ports:
- 80:80
- 443:443
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./acme.json:/acme.json:rw
command:
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --entrypoints.web.http.redirections.entrypoints.scheme=https
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --certificatesresolvers.letencrypt=true
- --certificatesresolvers.letencrypt.acme.httpchallenge=true
- --certificatesresolvers.letencrypt.acme.email=robert@5xcampus.com
- --certificatesresolvers.letencrypt.acme.storage=acme.json
- --certificatesresolvers.letencrypt.acme.httpchallenge.entrypoint=web
networks:
registry:
external: true
撇除下方關於 Traefik 指令的輸入,其餘的部分都是在 Docker Compose 篇 有提過的參數,有幾 個有疑慮的部分,我會一個一個解釋。
在 volumes 參數中,/var/run/docker.sock:/var/run/docker.sock:ro 這段,代表的是 Traefik 也需要監聽 docker.sock 這個 Unix Socket 上的事件,來掌握同一個虛擬網路中是否有容器被建立或是或是移除,而最後面的 :ro 則代表了 read only,也就是把伺服器的 docker.sock 交給 Traefik 去監聽,但他只能讀取資訊,而不能夠修改內容。
而 ./acme.json:/acme.json:rw 這段參數,則是 Traefik 一個非常厲害的功能,就是它會替您自動申請 SSL 的憑證,也就是在上網時,安全的網站旁邊都會有一個小鎖頭;而這個 acme.json 檔案,需要自己手動建立,並且將其權限設定為 600 來讓 Traefik 能夠寫入憑證資訊,結尾的 :rw 則是 read & write 都可以的意思。
root@ubuntu-s-1vcpu-512mb-10gb-sgp1-01:~# touch acme.json
root@ubuntu-s-1vcpu-512mb-10gb-sgp1-01:~# chmod 600 acme.json