Nginx 基礎用途拾遺

本文使用「署名 4.0 國際 (CC BY 4.0)」許可協議,歡迎轉載、或從新修改使用,但須要註明來源。 署名 4.0 國際 (CC BY 4.0)html

本文做者: 蘇洋前端

建立時間: 2020年05月20日 統計字數: 5171字 閱讀時間: 11分鐘閱讀 本文連接: soulteary.com/2020/05/20/…nginx


Nginx 基礎用途拾遺

Nginx 是一款你們平常再熟悉不過的軟件,穩定高效是這款軟件的標籤。常見 Nginx 會作爲地址轉發服務或提供文件託管能力。可是 Nginx 的用法其實不止於此,原生 Nginx 還有許多實用的功能,可以實現一些業務中麻煩的小細節。git

本文將介紹三種基礎用法,若是你熟悉 Nginx 和容器,閱讀時間大概是五分鐘。github

寫在前面

本次使用的示例環境,均使用容器進行模擬。若是你對容器還不是很熟悉,歡迎瀏覽以前的Docker 相關文章內容。docker

配合 compose 輕鬆建立健康檢查

一些前端類的容器,自己並無服務能力,可是爲了可以享受容器服務的基礎健康檢查,以及提供給外部諸如負載均衡等服務使用,咱們可能不得不啓動一個語言運行時,好比 Node / PHP / Java,不過若是你使用 Nginx 做爲前端使用的 Web 服務軟件,他自己就自帶了基礎的路由功能和定製響應碼和內容的能量,能夠避免咱們引入龐大的語言運行時。shell

咱們只須要在配置內添加一個名爲 /health 的路由,而後配合 default_typereturn 指令就能夠完成咱們想要的「當服務健康時,返回HTTP CODE 200,並輸出一些內容」。編程

server {
  listen 80;

  location = /health {
    access_log off;
    default_type text/html;
    return 200 'alive';
  }
}
複製代碼

你或許會說,咱們可讓健康檢查軟件檢查業務路由,可是我想告訴你的是,當咱們把路由獨立以後,你會發現健康檢查的響應時間更快了,除此以外,咱們還能夠對日誌進行丟棄。若是你將健康檢查路由和業務路由放在一塊兒,海量的健康檢查日誌和業務日誌在一塊兒,會讓你調試的時候痛不欲生。跨域

配合 compose 進行健康檢查也很容易:bash

version: "3.6"

services:

  health.test.soulteary.com:
    image: nginx:1.18.0-alpine
    volumes:
      - ./default.conf:/etc/nginx/conf.d/default.conf:ro
    healthcheck:
      # 老版本使用
      # test: ["CMD-SHELL", "wget -q --spider --proxy off localhost:80/health || exit 1"]
      test: ["CMD-SHELL", "curl -f localhost/health || exit 1"]
      interval: 3s
      retries: 12
複製代碼

當你使用 docker ps 查看容器進程的時候,你會看到咱們的容器會標記爲「healthy」,以後能夠配合各類策略進行容器服務基礎容災等基本操做。

CONTAINER ID        IMAGE                           COMMAND                  CREATED             STATUS                    PORTS                                                  NAMES
2afd71cd562e        nginx:1.18.0-alpine             "nginx -g 'daemon of…"   10 minutes ago      Up 3 seconds (healthy)   80/tcp             health.test.soulteary.com_1
複製代碼

使用 Nginx 聚合不一樣站點內容

平常開發過程當中,在遇到「前端跨域」、「短信模版中連接固定」、「既有程序調用來源限制」等場景下,會遇到須要聚合站點域名或路徑的狀況。

咱們知道使用編程語言,能夠實現遠程內容獲取和轉寫,可是實際上使用 Nginx 的反向代理功能能夠更加輕鬆地作到內容聚合。

好比,在作內容聚合前,咱們須要訪問的內容在 apple.test.soulteary.combanana.test.soulteary.com ,而咱們但願聚合後的內容在 test.soulteary.com 中展現。

爲了方便模擬環境,咱們先建立一個 compose 配置文件:

version: "3.6"

services:

  test.soulteary.com:
    image: nginx:1.18.0-alpine
    ports:
      - 8080:8080
    volumes:
      - ./default.conf:/etc/nginx/conf.d/default.conf:ro

  apple.test.soulteary.com:
    image: nginx:1.18.0-alpine
    volumes:
      - ./apple.test.soulteary.com.conf:/etc/nginx/conf.d/default.conf:ro

  banana.test.soulteary.com:
    image: nginx:1.18.0-alpine
    volumes:
      - ./banana.test.soulteary.com.conf:/etc/nginx/conf.d/default.conf:ro
複製代碼

配置文件中的 services 的三個子項分別表明聚合後的站點,以及兩個須要被聚合的站點,能夠想象爲現實中網絡相通的三臺服務器。

繼續建立 apple.test.soulteary.com.conf 這個 Nginx 配置文件。

server {
    listen 80;
    server_name apple.test.soulteary.com;
    default_type text/html;

    location / {
        return 200 'apple.test.soulteary.com';
    }
}
複製代碼

能夠看到,站點功能很簡單,訪問 / 的時候,返回 HTTP CODE 200,並輸出文本內容 apple.test.soulteary.com,同理咱們建立另一個站點的 Nginx 配置文件 banana.test.soulteary.com

最後,建立用於聚合配置文件的 Nginx 配置。

server {
    listen 8080;
    server_name test.soulteary.com;

    location = / {
        return 302 /apple;
    }

    location /apple {
        proxy_pass http://apple.test.soulteary.com/;
        proxy_set_header Host "apple.test.soulteary.com";
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    location /banana {
        proxy_pass http://banana.test.soulteary.com/;
        proxy_set_header Host "banana.test.soulteary.com";
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
複製代碼

能夠看到配置十分簡單,經過 proxy_pass 配合 proxy_set_header 兩個指令,咱們就將不一樣站點聚合到了一塊。

test.soulteary.com 綁定至本地,而後啓動服務,使用命令行訪問站點,能夠看到配置符合預期。

# curl http://test.soulteary.com:8080/apple 
apple.test.soulteary.com

# curl http://test.soulteary.com:8080/banana
banana.test.soulteary.com
複製代碼

轉發 Git SSH 這類 TCP 請求

Nginx 除了可以處理 HTTP 請求外,對於 TCP 類型的數據同樣能作到聚合/轉發。好比這裏咱們想將生產環境的某臺 GitLab 的訪問權限限制到具體的 IP,除了使用雲平臺的防火牆規則外,使用 Nginx 同樣能夠作到。

這裏要使用的是 Nginx 的 ngx_stream_proxy_module 模塊。

Nginx 容器默認配置僅包含了 HTTP 服務模式,因此此次修改不能和上面同樣,僅修改 「vhost」 配置,須要修改 nginx.conf 主配置,在修改以前,咱們先使用腳本看看默認的配置長什麼樣。

docker run --rm -it nginx:1.18.0-alpine cat /etc/nginx/nginx.conf
複製代碼

執行上面的命令,能夠看到默認的配置很簡單:

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/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"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush on;

    keepalive_timeout  65;

    #gzip on;

    include /etc/nginx/conf.d/*.conf;
}
複製代碼

爲了可以讓讀者輕鬆驗證,咱們假設目標倉庫是 GitHub,在對配置文件簡單修改後:

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


stream{
    server{
        listen 2223;
        proxy_pass github.com:22;
        proxy_connect_timeout 10s;
        proxy_timeout 20s;
        proxy_buffer_size 512k;
    }
}
複製代碼

咱們繼續建立一個 compose 配置文件:

version: "3.6"

services:

  proxy-git.test.soulteary.com:
    image: nginx:1.18.0-alpine
    ports:
      - 2223:2223
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
複製代碼

使用 docker-compose up 將服務啓動以後,咱們使用經典的 Git 測試命令行對服務進行驗證:

# ssh -T git@127.0.0.1 -p 2223
The authenticity of host '[127.0.0.1]:2223 ([127.0.0.1]:2223)' can't be established. RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8. Are you sure you want to continue connecting (yes/no/[fingerprint])? yes Warning: Permanently added '[127.0.0.1]:2223' (RSA) to the list of known hosts. Hi soulteary! You've successfully authenticated, but GitHub does not provide shell access.
複製代碼

你會發現此刻咱們想要的目標已經達到了,不信的話,你可使用相同命令去測試下原始 Git 服務地址。

# ssh -T git@github.com 

Hi soulteary! You've successfully authenticated, but GitHub does not provide shell access. 複製代碼

小節開始前提過,想進行來源限制,能夠搭配 Nginx 原生的 allow / deny 指令來完成:

location / {
    deny  192.168.1.1;
    allow 192.168.1.0/24;
    allow 10.1.1.0/16;
    allow 2001:0db8::/32;
    deny  all;
}
複製代碼

最後

Nginx 好玩、實用的用法其實還有很多,時間緣由,就不在此展開了。

--EOF


我如今有一個小小的折騰羣,裏面彙集了一些喜歡折騰的小夥伴。

在不發廣告的狀況下,咱們在裏面會一塊兒聊聊軟件、HomeLab、編程上的一些問題,也會在羣裏不按期的分享一些技術沙龍的資料。

喜歡折騰的小夥伴歡迎掃碼添加好友。(請註明來源和目的,不然不會經過審覈)

關於折騰羣入羣的那些事

相關文章
相關標籤/搜索