# Running Nginx with Kubernetes Restricted Pod Security Standards ## 1. 先決條件 - K8s 已安裝完畢 - 請使用 `kubernetes-admin` 的 user 操作 K8s - 作業系統已安裝 `podman`,並且可以上網 ## 2. 建立 Nginx App Container Image 1. 創建並切換工作目錄 ``` mkdir -p "$HOME"/wulin/nginx; cd "$HOME"/wulin/nginx ``` 2. 撰寫 Dockerfile ``` nano Dockerfile ``` 檔案內容: ``` # 使用輕量版 Alpine 且包含 OpenTelemetry 支援的 Nginx 基礎映像 FROM docker.io/library/nginx:1.29.3-alpine-otel # 定義參數 ARG user=bigred ARG uid=1001 ARG gid=1001 ARG port=8080 # 合併 RUN 指令以減少圖層 (Layers) 並縮小體積 # 使用 set -e 確保任何指令失敗時停止建置 RUN set -e && \ # 1. 新增使用者與群組 addgroup -g ${gid} -S ${user} && \ adduser -u ${uid} -S -G ${user} ${user} && \ # 2. 建立必要的暫存與 PID 目錄 mkdir -p /var/run/nginx \ /var/cache/nginx/client_temp \ /var/cache/nginx/proxy_temp \ /var/cache/nginx/fastcgi_temp \ /var/cache/nginx/scgi_temp \ /var/cache/nginx/uwsgi_temp && \ # 3. 修改設定檔 sed -i -E "s/listen\s+80;/listen ${port};/g" /etc/nginx/conf.d/default.conf && \ sed -i "s|/var/run/nginx.pid|/var/run/nginx/nginx.pid|g" /etc/nginx/nginx.conf && \ # 4. 權限調整 chown -R ${uid}:${gid} \ /var/cache/nginx \ /var/run/nginx \ /var/log/nginx \ /run && \ # 5. 清理不必要的暫存檔 (Alpine 特性,若有安裝套件時使用) rm -rf /tmp/* # 定義 run 成 app container 後內定執行的使用者 USER ${user} # 宣告對外開的 tcp port number EXPOSE ${port} # 定義 run 成 app container 後內定執行的啟動命令 CMD ["nginx", "-g", "daemon off;"] ``` 3. 建立 App Container Image ``` podman build --build-arg user=bigred \ --build-arg uid=1001 \ --build-arg gid=1001 \ --build-arg port=8080 \ --squash \ --tag nginx:1.29.3-alpine-otel-nonroot . ``` 4. 執行 Nginx App Container ``` podman run --name nginx \ --detach \ --publish 8080:8080 \ localhost/nginx:1.29.3-alpine-otel-nonroot ``` 5. 檢視 App Container 運作狀態 ``` podman ps -a ``` 執行結果: ``` CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 28bde4893f9b localhost/nginx:1.29.3-alpine-otel-nonroot nginx -g daemon o... 1 second ago Up 2 seconds 0.0.0.0:8080->8080/tcp nginx ``` 6. 驗證 Nginx 網站是否可以正常連接 ``` curl -sI localhost:8080 | head -n 1 ``` 執行結果: ``` HTTP/1.1 200 OK ``` 7. 登入 quay.io ``` podman login quay.io ``` 8. 修改 Nginx Image tag ``` podman tag localhost/nginx:1.29.3-alpine-otel-nonroot quay.io/hahappyman/nginx:1.29.3-alpine-otel-nonroot ``` 9. 將 Nginx Image 上傳到 quay.io ``` podman push quay.io/hahappyman/nginx:1.29.3-alpine-otel-nonroot ``` ## 3. 設定 Namespace 強制執行 `Restricted` Pod Security Standards (PSS) 1. 建立 namespace ``` kubectl create ns mytest ``` 2. 設定 Namespace 強制執行 `Restricted` Pod Security Standards ``` kubectl label --overwrite ns mytest \ pod-security.kubernetes.io/enforce=restricted \ pod-security.kubernetes.io/enforce-version=v1.34 ``` 3. 檢視是否成功 ``` kubectl describe ns mytest ``` 執行結果: ``` Name: mytest Labels: kubernetes.io/metadata.name=mytest pod-security.kubernetes.io/enforce=restricted pod-security.kubernetes.io/enforce-version=v1.34 Annotations: <none> Status: Active No resource quota. No LimitRange resource. ``` ## 4. 將 Nginx 部署至強制執行 `Restricted` PSS 的 namespace 1. 撰寫 nginx pod yaml ``` nano nginx-pod.yaml ``` 檔案內容如下: ``` apiVersion: v1 kind: Pod metadata: name: restricted-nginx-pod namespace: mytest labels: app: restricted-nginx spec: containers: - name: restricted-nginx-container image: quay.io/hahappyman/nginx:1.29.3-alpine-otel-nonroot securityContext: privileged: false allowPrivilegeEscalation: false capabilities: drop: - "ALL" runAsNonRoot: true runAsUser: 1001 seccompProfile: type: "RuntimeDefault" ``` > <font color=red>注意,`runAsNonRoot` 會用 user id 判斷 App Container 是否有透過非 root 的帳號去執行,所以當 App Container image 內定執行的使用者指定的是 user name 不是 user id,就必須要再額外設定 `runAsUser` 指定 `uid` 去執行,否則你會遇到以下錯誤訊息: > ```! > Error: container has runAsNonRoot and image has non-numeric user (bigred), cannot verify user is non-root (pod: "restricted-nginx-pod_mytest(d40b3343-1027-48c2-9b7d-e9acac1c7524)", container: restricted-nginx-container) > ``` </font> 2. 部署 Nginx Pod ``` kubectl apply -f nginx-pod.yaml ``` 執行結果: ``` pod/restricted-nginx-pod created ``` 3. 確認 Nginx Pod 運作狀態是否正常 ``` kubectl -n mytest get pods -o wide ``` 執行結果: ``` NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES restricted-nginx-pod 1/1 Running 0 22s 10.244.3.113 kubeadm-w1 <none> <none> ``` 4. 驗證網站是否能正常連線 ``` curl -sI http://10.244.3.113:8080 | head -n 1 ``` 執行結果: ``` HTTP/1.1 200 OK ``` 5. 在 nginx 所在的 worker node 上查詢 container user uid ``` sudo crictl inspect --name restricted-nginx-container | jq '.info.runtimeSpec.process.user.uid' ``` 執行結果: ``` 1001 ```
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up