在現行的OCV-v的demo中,當我們將VM從vmware透過MTV移轉到OCP-v後,我們可以透過service來將程式expose出來。這個demo我們將VM的程式重新封裝成container,運行成pod,透過相同的service name可以將客戶的請求繞送到後端的VM與pods,達成虛擬機器與容器共用相同網路。 ##架構圖 ![截圖 2025-04-28 下午1.37.47](https://hackmd.io/_uploads/HJ7KH52kge.png) ## index.php ```php <?php $my = new mysqli("database", "root", "R3dh4t1!", "visitors"); // 檢查連線是否成功 if ($my->connect_error) { die("Database connection failed: " . $my->connect_error); } // 取得訪客數 $results = $my->query("SELECT * FROM visitors"); $row = $results->fetch_array(); echo "You are the visitor number: " . $row['number'] . "<br />"; // 更新訪客數 $my->query("UPDATE visitors SET number=number+1"); // 顯示容器名稱 echo "I'm the container: " . getenv('HOSTNAME'); ?> ``` ## Dockerfile ```yaml # 使用 Red Hat UBI 9 Minimal 作為基底映像 FROM registry.access.redhat.com/ubi9/php-81 # 設定環境變數 ENV DOCUMENT_ROOT=/var/www/html # 設定工作目錄 WORKDIR $DOCUMENT_ROOT # 複製 PHP 程式碼到容器內 COPY index.php $DOCUMENT_ROOT/index.php # 調整權限 # RUN chown -R 1001:0 $DOCUMENT_ROOT && # chmod -R 755 $DOCUMENT_ROOT # 設定 Apache 伺服器執行 CMD ["php", "-S", "0.0.0.0:80", "-t", "/var/www/html"] # 監聽 80 端口 EXPOSE 80 ``` ## 在OCP上建立 (1) 建立 BuildConfig ```yaml oc new-build --name=php-webapp --binary --strategy=docker -n vmexamples-user1 oc start-build php-webapp --from-dir=. --follow -n vmexamples-user1 ``` (2) 部署應用 (DeploymentConfig) 如果要讓pod run 在port 80,要加入service account OCP 提供一個 Security Context Constraint (SCC),叫做 anyuid,可以讓 Pod 以 root 執行,這樣它就可以綁定 port 80。 **步驟 1:將 Service Account 加入 anyuid SCC** 允許 default ServiceAccount 使用 anyuid: ```yaml oc adm policy add-scc-to-user anyuid -z default -n myproject ``` 或者,你可以為這個 Deployment 指定特定ServiceAccount: ```yaml oc create sa php-service-account -n myproject oc adm policy add-scc-to-user anyuid -z php-service-account -n myproject ``` ```yaml oc apply -f deployment.yaml -n vmexamples-user1 ``` Deployment.yaml ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: webapp namespace: vmexamples-user1 spec: replicas: 2 selector: matchLabels: env: webapp template: metadata: labels: env: webapp spec: serviceAccountName: php-service-account # 指定 ServiceAccount securityContext: runAsUser: 0 # 以 root 執行 containers: - name: php-webapp image: image-registry.openshift-image-registry.svc:5000/vmexamples-user1/php-webapp:latest ports: - containerPort: 80 env: - name: DB_HOST value: "database" - name: DB_USER value: "root" - name: DB_PASS value: "R3dh4t1!" - name: DB_NAME value: "visitors" --- apiVersion: v1 kind: Service metadata: name: webapp namespace: vmexamples-user1 spec: selector: env: webapp ports: - protocol: TCP port: 8080 targetPort: 80 --- apiVersion: route.openshift.io/v1 kind: Route metadata: name: webapp-route namespace: vmexamples-user1 spec: to: kind: Service name: webapp port: targetPort: 80 ``` ## 成果展示 使用以下指令檢示結果 ``` while true; do curl -s https://route-webapp-vmexamples-user1.apps.cluster-h8j87.dynamic.redhatworkshops.io; echo ""; sleep 1;done ``` ![截圖 2025-04-28 下午1.46.31](https://hackmd.io/_uploads/rk9TI5nJge.png)