457 lines
15 KiB
Markdown
457 lines
15 KiB
Markdown
# WordPress with Nginx Helm Chart
|
||
|
||
このHelmチャートは、Nginx + WordPress (PHP-FPM) 構成をKubernetes上にデプロイします。
|
||
**bitnami/wordpress**のように、デプロイ後すぐに使用可能な状態で起動します。
|
||
|
||
## 主な機能
|
||
|
||
✅ **自動インストール**: 初回デプロイ時にWordPressを自動セットアップ
|
||
✅ **自動パスワード生成**: 管理者パスワードを指定しない場合は自動生成
|
||
✅ **アップデート対応**: 既存のDBがある場合は初期化をスキップ
|
||
✅ **ads.txt対応**: values.yamlから ads.txt を配置可能
|
||
✅ **セキュアな構成**: WordPress本体は使い捨て、wp-contentのみ永続化
|
||
✅ **本番環境対応**: セキュアなSecret管理、HA構成
|
||
|
||
## アーキテクチャとセキュリティ
|
||
|
||
### ストレージ構成
|
||
|
||
```
|
||
/var/www/html/ ← emptyDir(使い捨て、Pod再起動で消える)
|
||
├── index.php ← WordPress本体ファイル
|
||
├── wp-admin/ ← 管理画面(使い捨て)
|
||
├── wp-includes/ ← WordPressコア(使い捨て)
|
||
├── wp-config.php ← Secretから毎回生成
|
||
├── ads.txt ← values.yamlから生成
|
||
└── wp-content/ ← シンボリックリンク → PVC
|
||
|
||
/var/www/html-persistent/ ← PVC(永続化)
|
||
└── wp-content/ ← テーマ、プラグイン、アップロード
|
||
├── themes/
|
||
├── plugins/
|
||
└── uploads/
|
||
```
|
||
|
||
### セキュリティ上の利点
|
||
|
||
1. **WordPress本体の改ざん防止**: 毎回クリーンな状態から起動
|
||
2. **脆弱性への迅速な対応**: イメージ更新のみでコアファイル更新
|
||
3. **設定の一元管理**: wp-config.phpはvalues.yamlとSecretから生成
|
||
4. **ユーザーデータの保護**: wp-contentのみ永続化で管理が容易
|
||
|
||
## アーキテクチャ
|
||
|
||
- **Nginx**: リバースプロキシおよび静的ファイル配信
|
||
- **WordPress (PHP-FPM)**: WordPressアプリケーション実行
|
||
- **共有ボリューム**: Nginx と WordPress 間でファイルを共有
|
||
|
||
## 前提条件
|
||
|
||
- Kubernetes 1.19+
|
||
- Helm 3.0+
|
||
- PersistentVolume プロビジョナー(永続化を有効にする場合)
|
||
- MySQL/MariaDB データベース(別途デプロイが必要)
|
||
|
||
## インストール方法
|
||
|
||
### 1. チャートの準備
|
||
|
||
```bash
|
||
# チャートディレクトリの作成
|
||
mkdir -p wordpress-nginx/templates
|
||
|
||
# 必要なファイルをコピー
|
||
# Chart.yaml, values.yaml, templates/*
|
||
```
|
||
|
||
### 2. MySQLのデプロイ(必要な場合)
|
||
|
||
```bash
|
||
# Helm を使用して MySQL をデプロイ
|
||
helm repo add bitnami https://charts.bitnami.com/bitnami
|
||
helm install mysql bitnami/mysql \
|
||
--set auth.rootPassword=rootpassword \
|
||
--set auth.database=wordpress \
|
||
--set auth.username=wordpress \
|
||
--set auth.password=changeme
|
||
```
|
||
|
||
### 3. WordPressのデプロイ
|
||
|
||
```bash
|
||
# デフォルト値でインストール
|
||
helm install my-wordpress ./wordpress-nginx
|
||
|
||
# カスタム値でインストール
|
||
helm install my-wordpress ./wordpress-nginx \
|
||
--set wordpress.dbPassword=your-secure-password \
|
||
--set service.type=LoadBalancer
|
||
|
||
# values.yaml を使用
|
||
helm install my-wordpress ./wordpress-nginx -f custom-values.yaml
|
||
```
|
||
|
||
## 設定パラメータ
|
||
|
||
### 基本設定
|
||
|
||
| パラメータ | 説明 | デフォルト値 |
|
||
|-----------|------|-------------|
|
||
| `replicaCount` | レプリカ数 | `2` |
|
||
| `image.nginx.registry` | Nginxイメージレジストリ | `docker.io` |
|
||
| `image.nginx.repository` | Nginxイメージリポジトリ | `nginx` |
|
||
| `image.nginx.tag` | Nginxイメージタグ | `1.29.3-alpine-perl` |
|
||
| `image.wordpress.registry` | WordPressイメージレジストリ | `docker.io` |
|
||
| `image.wordpress.repository` | WordPressイメージリポジトリ | `wordpress` |
|
||
| `image.wordpress.tag` | WordPressイメージタグ | `6.8.3-php8.4-fpm-alpine` |
|
||
|
||
### WordPress設定
|
||
|
||
| パラメータ | 説明 | デフォルト値 |
|
||
|-----------|------|-------------|
|
||
| `wordpress.dbHost` | データベースホスト | `mysql-service` |
|
||
| `wordpress.dbName` | データベース名 | `wordpress` |
|
||
| `wordpress.dbUser` | データベースユーザー | `wordpress` |
|
||
| `wordpress.dbPassword` | データベースパスワード | `changeme` |
|
||
| `wordpress.tablePrefix` | テーブルプレフィックス | `wp_` |
|
||
| `wordpress.siteTitle` | サイトタイトル | `My WordPress Site` |
|
||
| `wordpress.siteUrl` | サイトURL | `http://localhost` |
|
||
| `wordpress.adminUser` | 管理者ユーザー名 | `admin` |
|
||
| `wordpress.adminPassword` | 管理者パスワード(空=自動生成) | `""` |
|
||
| `wordpress.adminEmail` | 管理者メール | `admin@example.com` |
|
||
| `wordpress.adsTxt.enabled` | ads.txtを有効化 | `false` |
|
||
| `wordpress.adsTxt.content` | ads.txtの内容 | `""` |
|
||
|
||
### Service設定
|
||
|
||
| パラメータ | 説明 | デフォルト値 |
|
||
|-----------|------|-------------|
|
||
| `service.type` | Serviceタイプ | `LoadBalancer` |
|
||
| `service.port` | Serviceポート | `80` |
|
||
|
||
### Ingress設定
|
||
|
||
| パラメータ | 説明 | デフォルト値 |
|
||
|-----------|------|-------------|
|
||
| `ingress.enabled` | Ingressを有効化 | `false` |
|
||
| `ingress.className` | IngressClass名 | `nginx` |
|
||
| `ingress.annotations` | Ingressアノテーション | `{}` |
|
||
| `ingress.hostname` | プライマリホスト名 | `wordpress.example.com` |
|
||
| `ingress.path` | パス | `/` |
|
||
| `ingress.pathType` | パスタイプ | `Prefix` |
|
||
| `ingress.tls` | TLS有効化(自動設定) | `false` |
|
||
| `ingress.extraHosts` | 追加ホスト設定 | `[]` |
|
||
| `ingress.extraTls` | 追加TLS設定 | `[]` |
|
||
|
||
**TLS自動設定**: `tls: true` にすると、`hostname` を使用して自動的に以下が設定されます:
|
||
- hosts: `[hostname]`
|
||
- secretName: `{hostname-with-dash}-tls`(例: `example-com-tls`)
|
||
|
||
### 永続化設定
|
||
|
||
| パラメータ | 説明 | デフォルト値 |
|
||
|-----------|------|-------------|
|
||
| `persistence.enabled` | 永続化を有効化(wp-contentのみ) | `true` |
|
||
| `persistence.storageClass` | StorageClass | `""` |
|
||
| `persistence.accessMode` | アクセスモード | `ReadWriteOnce` |
|
||
| `persistence.size` | ストレージサイズ(wp-content用) | `10Gi` |
|
||
|
||
**注意**: WordPress本体ファイル(wp-admin、wp-includesなど)はemptyDirに配置され、Pod再起動時に破棄されます。ユーザーデータ(wp-content)のみがPVCに永続化されます。
|
||
|
||
## 使用例
|
||
|
||
### 基本的なインストール(パスワード自動生成)
|
||
|
||
```bash
|
||
helm install my-wordpress ./wordpress-nginx \
|
||
--set wordpress.dbPassword=SecurePassword123 \
|
||
--set wordpress.siteUrl=http://my-wordpress.example.com \
|
||
--set wordpress.siteTitle="My Blog" \
|
||
--set wordpress.adminEmail=admin@example.com
|
||
|
||
# パスワードの取得
|
||
kubectl get secret my-wordpress-wordpress-nginx-secret \
|
||
-o jsonpath='{.data.admin-password}' | base64 -d
|
||
echo
|
||
```
|
||
|
||
### パスワードを指定してインストール
|
||
|
||
```bash
|
||
helm install my-wordpress ./wordpress-nginx \
|
||
--set wordpress.dbPassword=SecurePassword123 \
|
||
--set wordpress.adminPassword=AdminPass456 \
|
||
--set wordpress.siteUrl=https://blog.example.com \
|
||
--set wordpress.adminUser=myadmin
|
||
```
|
||
|
||
### ads.txt を配置
|
||
|
||
```bash
|
||
helm install my-wordpress ./wordpress-nginx \
|
||
--set wordpress.dbPassword=SecurePassword123 \
|
||
--set wordpress.adsTxt.enabled=true \
|
||
--set-string wordpress.adsTxt.content="google.com, pub-1234567890, DIRECT, f08c47fec0942fa0"
|
||
```
|
||
|
||
または values.yaml に記述:
|
||
|
||
```yaml
|
||
wordpress:
|
||
adsTxt:
|
||
enabled: true
|
||
content: |
|
||
google.com, pub-1234567890, DIRECT, f08c47fec0942fa0
|
||
adserver.com, 9876, RESELLER
|
||
```
|
||
|
||
### LoadBalancerでの公開
|
||
|
||
```bash
|
||
helm install my-wordpress ./wordpress-nginx \
|
||
--set service.type=LoadBalancer \
|
||
--set wordpress.dbPassword=SecurePassword123
|
||
```
|
||
|
||
### Ingressでの公開
|
||
|
||
#### 基本的なIngress(HTTPのみ)
|
||
|
||
```bash
|
||
helm install my-wordpress ./wordpress-nginx \
|
||
--set ingress.enabled=true \
|
||
--set ingress.hostname=wordpress.example.com \
|
||
--set service.type=ClusterIP
|
||
```
|
||
|
||
#### TLS有効化(自動設定)
|
||
|
||
```bash
|
||
helm install my-wordpress ./wordpress-nginx \
|
||
--set ingress.enabled=true \
|
||
--set ingress.hostname=wordpress.example.com \
|
||
--set ingress.tls=true \
|
||
--set service.type=ClusterIP
|
||
```
|
||
|
||
これで自動的に以下が設定されます:
|
||
- TLS Secret名: `wordpress-example-com-tls`
|
||
- TLS対象ホスト: `wordpress.example.com`
|
||
|
||
#### cert-managerと組み合わせ
|
||
|
||
```bash
|
||
helm install my-wordpress ./wordpress-nginx \
|
||
--set ingress.enabled=true \
|
||
--set ingress.hostname=blog.example.com \
|
||
--set ingress.tls=true \
|
||
--set ingress.annotations."cert-manager\.io/cluster-issuer"=letsencrypt-issuer \
|
||
--set ingress.annotations."acme\.cert-manager\.io/http01-ingress-class"=nginx
|
||
```
|
||
|
||
または values.yaml で:
|
||
|
||
```yaml
|
||
ingress:
|
||
enabled: true
|
||
hostname: blog.example.com
|
||
tls: true
|
||
annotations:
|
||
cert-manager.io/cluster-issuer: "letsencrypt-issuer"
|
||
acme.cert-manager.io/http01-ingress-class: "nginx"
|
||
nginx.ingress.kubernetes.io/from-to-www-redirect: "true"
|
||
nginx.ingress.kubernetes.io/proxy-body-size: "100m"
|
||
```
|
||
|
||
#### 複数ホスト設定
|
||
|
||
```bash
|
||
helm install my-wordpress ./wordpress-nginx -f - <<EOF
|
||
ingress:
|
||
enabled: true
|
||
hostname: www.example.com
|
||
tls: true
|
||
extraHosts:
|
||
- name: blog.example.com
|
||
path: /
|
||
- name: news.example.com
|
||
path: /
|
||
extraTls:
|
||
- hosts:
|
||
- blog.example.com
|
||
- news.example.com
|
||
secretName: multi-domain-tls
|
||
annotations:
|
||
cert-manager.io/cluster-issuer: "letsencrypt-issuer"
|
||
nginx.ingress.kubernetes.io/proxy-body-size: "100m"
|
||
EOF
|
||
```
|
||
|
||
### リソース制限のカスタマイズ
|
||
|
||
```bash
|
||
helm install my-wordpress ./wordpress-nginx \
|
||
--set resources.nginx.limits.memory=1Gi \
|
||
--set resources.wordpress.limits.memory=2Gi
|
||
```
|
||
|
||
## 初期化の動作
|
||
|
||
### 新規インストール時
|
||
1. WordPress本体ファイルをemptyDirにコピー(使い捨て領域)
|
||
2. wp-contentディレクトリをPVCに作成(永続化領域)
|
||
3. シンボリックリンクで wp-content を接続
|
||
4. wp-config.phpをSecretから生成
|
||
5. データベース接続を確認
|
||
6. テーブルが存在しない場合:
|
||
- WP-CLIを使用してWordPressをインストール
|
||
- 管理者アカウントを作成
|
||
- パスワードが未指定の場合は16文字のランダム生成
|
||
7. ads.txtが有効な場合は配置(使い捨て領域)
|
||
|
||
### アップデート/再起動時
|
||
1. WordPress本体ファイルを新しくコピー(常にクリーン)
|
||
2. 既存のwp-content(PVC)をシンボリックリンクで接続
|
||
3. wp-config.phpを再生成
|
||
4. データベーステーブルの存在を確認
|
||
5. テーブルが存在する場合:
|
||
- 初期化処理をスキップ
|
||
- コアバージョンの更新確認
|
||
- 必要に応じてデータベーススキーマをアップデート
|
||
6. 既存データ(wp-content)を保持したまま起動
|
||
|
||
### セキュリティ更新の適用方法
|
||
|
||
```bash
|
||
# イメージタグを更新して再デプロイするだけ
|
||
helm upgrade my-wordpress ./wordpress-nginx \
|
||
--set image.wordpress.tag=6.8.4-php8.4-fpm-alpine
|
||
|
||
# Pod再起動で自動的にクリーンなWordPress本体に置き換わる
|
||
kubectl rollout restart deployment/my-wordpress-wordpress-nginx
|
||
```
|
||
|
||
### ファイル構成の確認
|
||
|
||
```bash
|
||
# WordPress本体(emptyDir - 使い捨て)
|
||
kubectl exec -it <pod-name> -c wordpress -- ls -la /var/www/html/
|
||
|
||
# wp-content(PVC - 永続化)
|
||
kubectl exec -it <pod-name> -c wordpress -- ls -la /var/www/html-persistent/wp-content/
|
||
|
||
# シンボリックリンクの確認
|
||
kubectl exec -it <pod-name> -c wordpress -- ls -la /var/www/html/ | grep wp-content
|
||
```
|
||
|
||
### 管理者パスワードの確認方法
|
||
|
||
```bash
|
||
# Secretから取得
|
||
kubectl get secret <release-name>-wordpress-nginx-secret \
|
||
-o jsonpath='{.data.admin-password}' | base64 -d
|
||
|
||
# または initContainer のログから確認(初回のみ)
|
||
kubectl logs <pod-name> -c wordpress-init
|
||
```
|
||
|
||
```bash
|
||
# 設定を変更してアップグレード
|
||
helm upgrade my-wordpress ./wordpress-nginx \
|
||
--set wordpress.dbPassword=NewPassword
|
||
|
||
# values.yamlを使用してアップグレード
|
||
helm upgrade my-wordpress ./wordpress-nginx -f custom-values.yaml
|
||
```
|
||
|
||
## アンインストール
|
||
|
||
```bash
|
||
helm uninstall my-wordpress
|
||
```
|
||
|
||
## トラブルシューティング
|
||
|
||
### 初期化ログの確認
|
||
|
||
```bash
|
||
# initContainer のログを確認
|
||
kubectl logs <pod-name> -c wordpress-init
|
||
|
||
# メインコンテナのログ
|
||
kubectl logs <pod-name> -c nginx
|
||
kubectl logs <pod-name> -c wordpress
|
||
```
|
||
|
||
### 管理者パスワードの再確認
|
||
|
||
```bash
|
||
# Secretから取得
|
||
kubectl get secret my-wordpress-wordpress-nginx-secret \
|
||
-o jsonpath='{.data.admin-password}' | base64 -d && echo
|
||
```
|
||
|
||
### データベース接続の確認
|
||
|
||
```bash
|
||
# WordPress コンテナで WP-CLI を実行
|
||
kubectl exec -it <pod-name> -c wordpress -- wp db check
|
||
kubectl exec -it <pod-name> -c wordpress -- wp db tables
|
||
```
|
||
|
||
### 再初期化が必要な場合
|
||
|
||
```bash
|
||
# wp-contentのみを保持して再インストール
|
||
# (データベースをクリアすれば再初期化される)
|
||
kubectl exec -it <pod-name> -c wordpress -- wp db reset --yes
|
||
|
||
# 完全なクリーンインストール(PVCごと削除)
|
||
kubectl delete pvc <pvc-name>
|
||
helm uninstall my-wordpress
|
||
helm install my-wordpress ./wordpress-nginx
|
||
```
|
||
|
||
### ストレージの確認
|
||
|
||
```bash
|
||
# PVCの確認(wp-contentのみ)
|
||
kubectl get pvc
|
||
kubectl exec -it <pod-name> -c wordpress -- du -sh /var/www/html-persistent/wp-content/
|
||
|
||
# emptyDirの使用量確認
|
||
kubectl exec -it <pod-name> -c wordpress -- du -sh /var/www/html/
|
||
```
|
||
|
||
### ads.txt の確認
|
||
|
||
```bash
|
||
# Pod内でファイルを確認
|
||
kubectl exec -it <pod-name> -c nginx -- cat /var/www/html/ads.txt
|
||
|
||
# ブラウザまたはcurlでアクセス
|
||
curl http://your-site.com/ads.txt
|
||
```
|
||
|
||
## セキュリティ考慮事項
|
||
|
||
本番環境では以下を必ず実施してください:
|
||
|
||
1. **データベースパスワードの保護**: Kubernetes Secretを使用
|
||
2. **HTTPS の有効化**: cert-manager等でTLS証明書を設定
|
||
3. **リソース制限の設定**: 適切なresources設定
|
||
4. **定期的なバックアップ**: wp-content(PVC)とデータベースのバックアップ
|
||
5. **セキュリティアップデート**:
|
||
- WordPress本体: イメージタグ更新 → Pod再起動で自動適用
|
||
- プラグイン/テーマ: WordPress管理画面から更新
|
||
6. **wp-config.phpのセキュリティ**: Secretに保存され、Pod再起動時に再生成
|
||
7. **読み取り専用ファイルシステム**: WordPress本体は毎回クリーン、改ざん不可
|
||
|
||
### この構成のセキュリティメリット
|
||
|
||
- ✅ WordPress本体への不正な変更を防止(Pod再起動で復元)
|
||
- ✅ wp-config.phpへの直接アクセス不可(Secretから生成)
|
||
- ✅ 脆弱性対応が容易(イメージ更新のみ)
|
||
- ✅ ユーザーデータのみを管理(wp-contentのみバックアップ)
|
||
- ✅ 設定の一元管理(values.yaml + Secret)
|