antony@notes:~/kubernetes$ cat "Running-Nginx-with-Kubernetes-Restricted-Pod-Security-Standards.md"
Running Nginx with Kubernetes Restricted Pod Security Standards
Running Nginx with Kubernetes Restricted Pod Security Standards
1. 先決條件
- K8s 已安裝完畢
- 請使用
kubernetes-admin的 user 操作 K8s - 作業系統已安裝
podman,並且可以上網
2. 建立 Nginx App Container Image
創建並切換工作目錄
mkdir -p "$HOME"/wulin/nginx; cd "$HOME"/wulin/nginx撰寫 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;"]建立 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 .執行 Nginx App Container
podman run --name nginx \ --detach \ --publish 8080:8080 \ localhost/nginx:1.29.3-alpine-otel-nonroot檢視 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驗證 Nginx 網站是否可以正常連接
curl -sI localhost:8080 | head -n 1執行結果:
HTTP/1.1 200 OK登入 quay.io
podman login quay.io修改 Nginx Image tag
podman tag localhost/nginx:1.29.3-alpine-otel-nonroot quay.io/hahappyman/nginx:1.29.3-alpine-otel-nonroot將 Nginx Image 上傳到 quay.io
podman push quay.io/hahappyman/nginx:1.29.3-alpine-otel-nonroot
3. 設定 Namespace 強制執行 Restricted Pod Security Standards (PSS)
建立 namespace
kubectl create ns mytest設定 Namespace 強制執行
RestrictedPod Security Standardskubectl label --overwrite ns mytest \ pod-security.kubernetes.io/enforce=restricted \ pod-security.kubernetes.io/enforce-version=v1.34檢視是否成功
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
撰寫 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"注意,
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)部署 Nginx Pod
kubectl apply -f nginx-pod.yaml執行結果:
pod/restricted-nginx-pod created確認 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>驗證網站是否能正常連線
curl -sI http://10.244.3.113:8080 | head -n 1執行結果:
HTTP/1.1 200 OK在 nginx 所在的 worker node 上查詢 container user uid
sudo crictl inspect --name restricted-nginx-container | jq '.info.runtimeSpec.process.user.uid'執行結果:
1001