没有想到用k8s搭https版的wordpress能耗时这么久,还搭上了我的基友slash先生,既然这么费事,就记录下来吧。欢迎转载,转载请注明出处,谢谢。至于为什么我们的网站已经隐藏了server的版本,但是本文却大方地给出了实际版本,理由:任性,哈哈。
首先选用了kubeadm来启动一个单节点的k8s,runtime采用的是containerd,这样比较轻量,随着k8s进一步解耦docker,我也随波逐流,初始化的镜像仓库选择了docker.io/gotok8s,更新还是很及时的,本次采用了阿里云的镜像加速,下面是本次部署的大致架构图,图片来自slash,网站入口的nginx也是容器部署,采用hostnetwork。
wordpress镜像选用docker.io/library/wordpress:5.8.3-fpm,镜像默认不自带nginx,这里手动添加了nginx的镜像,wordpress用到数据库,这里选用了mysql,镜像为docker.io/library/mysql:5.7,服务用到的pvc均来自自建nfs做了stroageclass。网站的证书直接在腾讯云申请的,流程简单,免费好用(白嫖最香),缺点是有效期一年,一年后要重新申请。开始吧!
一、首先是mysql,采用无头的方式,单节点deployment部署,密码env挂载secret,secret有多种创建方式,如命令行
kubectl create secret mysql-pass --password='xxxxxx'
apiVersion: v1
kind: Service
metadata:
name: mysql
labels:
app: mysql
spec:
ports:
- port: 3306
selector:
app: mysql
clusterIP: None
apiVersion: v1
kind: Service
metadata:
name: mysql
labels:
app: mysql
spec:
ports:
- port: 3306
selector:
app: mysql
clusterIP: None
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
annotations:
volume.beta.kubernetes.io/storage-class: “nfs-storage”
labels:
app: mysql
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
labels:
app: mysql
spec:
selector:
matchLabels:
app: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: mysql
spec:
containers:
- image: docker.io/library/mysql:5.7
imagePullPolicy: IfNotPresent
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-pass
key: password
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-storage
persistentVolumeClaim:
claimName: mysql-pv-claim
apply后进入mysql的pod创建数据库wordpress
二、wordpress的相关yaml
wordpress的pod中加入了nginx的容器,做了configmap挂载替换默认default.conf,nginx的configmap如下
apiVersion: v1
kind: ConfigMap
metadata:
name: wordpress-configs
data:
default.conf: |
server {
listen 80 default_server;
client_max_body_size 20m;
root /var/www/html;
index index.php index.html index.htm;
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
wordpress中的环境变量以secret的方式挂载,secret的yaml文件如下,自行修改user和password
apiVersion: v1
kind: Secret
metadata:
name: wordpress-secrets
stringData:
WORDPRESS_DB_HOST: "wordpress-mysql"
WORDPRESS_DB_USER: "xxxxx"
WORDPRESS_DB_PASSWORD: "xxxxx"
下面是wordpress相关的svc、pvc、deployment
apiVersion: v1
kind: Service
metadata:
name: wordpress
labels:
app: wordpress
spec:
ports:
- name: http
port: 80
targetPort: http
selector:
app: wordpress
type: ClusterIP
apiVersion: v1
kind: Service
metadata:
name: wordpress
labels:
app: wordpress
spec:
ports:
- name: http
port: 80
targetPort: http
selector:
app: wordpress
type: ClusterIP
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: wp-pv-claim
annotations:
volume.beta.kubernetes.io/storage-class: “nfs-storage”
labels:
app: wordpress
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress
labels:
app: wordpress
spec:
selector:
matchLabels:
app: wordpress
strategy:
type: Recreate
template:
metadata:
labels:
app: wordpress
spec:
containers:
- image: docker.io/library/wordpress:5.8.3-fpm
name: wordpress
envFrom:
- secretRef:
name: wordpress-secrets
volumeMounts:
- mountPath: /var/www/html
name: storage
- image: docker.io/nginx:1.21.0
name: nginx
ports:
- containerPort: 80
name: http
volumeMounts:
- mountPath: /etc/nginx/conf.d
name: configs
- mountPath: /var/www/html
name: storage
volumes:
- name: storage
persistentVolumeClaim:
claimName: wp-pv-claim
- name: configs
configMap:
name: wordpress-configs
三、用于反向代理的nginx,配置文件也用configmap挂载,包括主配置文件nginx.conf和虚拟主机配置文件haifeihai.com.conf。
注意wordpress经过代理以后使用https时,静态资源还是http的方式请求,会导致无限跳转,所以可以在代理的nginx处加入 proxy_set_header X-Forwarded-Proto $scheme; 以解决这个问题,在wordpress的官方文档也提到了这个特性https://wordpress.org/support/article/administration-over-ssl/#using-a-reverse-proxy
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-configs
data:
nginx.conf: |
user www-data;
worker_processes auto;
#error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 10240;
use epoll;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
server_names_hash_bucket_size 512;
server_tokens off;
sendfile on;
tcp_nopush on;
keepalive_timeout 65;
types_hash_max_size 4096;
gzip on;
gzip_min_length 1k;
gzip_buffers 16 8k;
gzip_comp_level 4;
gzip_proxied any;
gzip_types
text/xml application/xml application/atom+xml application/rss+xml application/xhtml+xml
text/javascript application/javascript application/x-javascript
text/x-json application/json application/x-web-app-manifest+json
text/css text/plain text/x-component
font/opentype application/x-font-ttf application/vnd.ms-fontobject
image/x-icon image/svg+xml;
gzip_disable "MSIE [1-6]\.(?!.*SV1)";
include /etc/nginx/mime.types;
default_type application/octet-stream;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
include /etc/nginx/conf.d/*.conf;
}
haifeihai.com.conf: |
server {
listen 80;
listen 443 ssl;
server_name www.haifeihai.com haifeihai.com;
ssl_certificate ssl/tls.crt;
ssl_certificate_key ssl/tls.key;
resolver 10.2.0.10;
location /favicon.ico {
return 204;
}
location / {
if ($host ~ "^hai") {
return 301 https://www.$http_host$request_uri;
}
if ($ssl_protocol = "") {
return 301 https://$http_host$request_uri;
}
set $upstream_name wordpress.default.svc.cluster.local;
proxy_pass http://$upstream_name;
}
}
本次使用了https,所以将申请的免费证书以secret的形式挂载,创建tls类型的secret,自行修改获得的证书路径和私钥路径,tls类型的secret创建时会自动将key修改为tls.key和tls.crt的。
kubectl create secret tls haifeihai-secret --cert=haifeihai.com_bundle.crt --key=haifeihai.com.key
反向代理ngixn的deployment,之前也提到了,为了方便解析,使用hostnetwork。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
selector:
matchLabels:
app: nginx
strategy:
type: Recreate
template:
metadata:
labels:
app: nginx
spec:
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet
containers:
- image: docker.io/nginx:1.21.0
name: nginx
volumeMounts:
- mountPath: /etc/nginx/nginx.conf
name: configs
subPath: nginx.conf
- mountPath: /etc/nginx/conf.d/default.conf
name: configs
subPath: haifeihai.com.conf
- mountPath: /etc/nginx/ssl/tls.crt
name: certs
subPath: tls.crt
- mountPath: /etc/nginx/ssl/tls.key
name: certs
subPath: tls.key
volumes:
- name: configs
configMap:
name: nginx-configs
- name: certs
secret:
secretName: haifeihai-secrets
到此便已完成了使用k8s部署https的wordpress。