---
# System prepended metadata

title: '擴充OCP-v 的Demo, 包含VM與pod 微服務'

---

在現行的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)


