K8S 搭建 Halo 博客

搭建 Halo

创建 namespace

halo-namespace.yaml

apiVersion: v1
kind: Namespace  
metadata:
  name: halo  
  labels:
    name: halo  

创建 deployment

cat halo-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: halo
  name: halo-deployment
spec:
  selector:
    matchLabels:
      app: halo-blog
  replicas: 1
  template:
    metadata:
      labels:
        app: halo-blog
    spec:
      containers:
      - name: halo
        image: halohub/halo
        ports:
        - containerPort: 8090
        volumeMounts:
        - name: halo-path
          mountPath: /root/.halo
      volumes:
      - name: halo-path
        hostPath:
           path: /root/halo

创建 service

halo-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: halo-service
  namespace: halo
spec:
  selector:
    app: halo-blog
  ports:
  - protocol: TCP
    port: 8090
    targetPort: 8090

问题总结

为什么上传主题或者附件会失败?(413 Request Entity Too Large)

这可能是由于 Nginx 的上传大小限制所导致的。可以在 Nginx 的配置文件下的 server 节点加入 client_max_body_size 1024m; 即可解决,如果 1024m 还不够,请自行断定,详细配置参考如下:

server {
    listen       80;
    server_name  localhost;
    client_max_body_size 1024m;
}

如果想要禁用 client_max_body_size,请将值设置为 0。

nginx 报错 : [warn] the "ssl" directive is deprecated, use the "listen ... ssl" directive instead

应该把 ssl on 改成 listen 443 ssl 这样才对。

搭建 Nginx

通过 Secret 挂载 HTTPS 证书

将证书 base64 转码

cat server.crt | base64 -w 0
cat server.key | base64 -w 0

配置 Secret

halo-nginx-cert-secret.yaml

apiVersion: v1
kind: Secret
metadata:
  name: halo-nginx-cert
  namespace: halo
data:
  server.crt : "省略"
  server.key: "省略"

通过 ConfigMap 挂载 nginx.conf 配置文件

创建 nginx.conf 配置文件

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;

events {
    use epoll;
    worker_connections  1024;
    multi_accept on;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    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;

    sendfile        on;
    tcp_nopush     on;

    keepalive_timeout  65;

    gzip  on;
  
    upstream halo {
        server 10.96.112.99:8090;
    }

    server {
        listen 443 ssl http2 reuseport;
        server_name  localhost;
        client_max_body_size 10m;

        ssl_certificate /etc/nginx/cert/server.crt;
        ssl_certificate_key /etc/nginx/cert/server.key;
        ssl_session_timeout 5m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
        ssl_prefer_server_ciphers on;

        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
            proxy_pass http://halo;
            proxy_set_header HOST $host;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }
    }
}

创建 ConfigMap

在 nginx.conf 文件目录

kubectl create cm halo-nginx-conf --from-file=nginx.conf -n halo

导出 ConfigMap

将 ConfigMap 导出到 yaml 文件

kubectl get cm halo-nginx-conf -n halo -o yaml > halo-nginx-conf-configMap.yaml

创建 deployment

nginx-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: halo
  name: halo-nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: halo-nginx
  template:
    metadata:
      labels:
        app: halo-nginx
    spec:
      containers:
        - name: halo-nginx
          image: nginx:latest
          imagePullPolicy: IfNotPresent
          ports:
          - containerPort: 443 
          volumeMounts:
          - name: nginx-config-volume
            mountPath: /etc/nginx/nginx.conf
            subPath: nginx.conf
          - name: secret-cert-volume
            mountPath: /etc/nginx/cert
      volumes:
        - name: nginx-config-volume
          configMap:
            name: halo-nginx-conf 
            items:
            - key: nginx.conf
              path: nginx.conf
        - name: secret-cert-volume
          secret:
            secretName: halo-nginx-cert

创建 service

nginx-service.yaml

apiVersion: v1
kind: Service
metadata:
  namespace: halo
  name: halo-nginx-service
spec:
  selector:
    app: halo-nginx
  type: NodePort
  ports:
  - protocol: TCP
    port: 443
    targetPort: 443

搭建 Nginx(动静分离)

通过 hostPath 挂在 nginx.conf 配置文件

apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: halo
  name: halo-nginx-static
spec:
  replicas: 1
  selector:
    matchLabels:
      app: halo-nginx-static
  template:
    metadata:
      labels:
        app: halo-nginx-static
    spec:
      containers:
        - name: halo-nginx-static
          image: nginx:latest
          imagePullPolicy: IfNotPresent
          ports:
          - containerPort: 443
          volumeMounts:
          - name: nginx-config-static-volume
            mountPath: /etc/nginx/nginx.conf
            #subPath: nginx.conf
          - name: secret-cert-volume
            mountPath: /etc/nginx/cert
          - name: upload
            mountPath: /usr/share/nginx/html/upload/
      volumes:
        - name: nginx-config-static-volume
          hostPath:
            path: /root/halo/yaml/nginx/dongjingfenli/nginx.conf
            type: File
        - name: secret-cert-volume
          secret:
            secretName: halo-nginx-cert
        - name: upload
          hostPath:
            path: /root/halo/upload

Nginx 配置文件

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;

events {
    use epoll;
    worker_connections  1024;
    multi_accept on;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format main
                      '{"@timestamp":"$time_iso8601",'
                      '"host":"$hostname",'
                      '"server_ip":"$server_addr",'
                      '"client_ip":"$remote_addr",'
                      '"xff":"$http_x_forwarded_for",'
                      '"domain":"$host",'
                      '"url":"$uri",'
                      '"referer":"$http_referer",'
                      '"args":"$args",'
                      '"upstreamtime":"$upstream_response_time",'
                      '"responsetime":"$request_time",'
                      '"request_method":"$request_method",'
                      '"status":"$status",'
                      '"size":"$body_bytes_sent",'
                      '"request_body":"$request_body",'
                      '"request_length":"$request_length",'
                      '"protocol":"$server_protocol",'
                      '"upstreamhost":"$upstream_addr",'
                      '"file_dir":"$request_filename",'
                      '"http_user_agent":"$http_user_agent"'
    '}';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    tcp_nopush     on;

    keepalive_timeout  65;

    gzip  on;

    upstream halo {
        server halo-service:8090;
    }

    server {
        listen 443 ssl http2 reuseport;
        server_name  localhost;
        client_max_body_size 100m;

        ssl_certificate /etc/nginx/cert/server.crt;
        ssl_certificate_key /etc/nginx/cert/server.key;
        ssl_session_timeout 5m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
        ssl_prefer_server_ciphers on;

        location /upload/ {
            alias /usr/share/nginx/html/upload/;
        }

        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
            proxy_pass http://halo;
            proxy_set_header HOST $host;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }
    }
}

hostPath type

支持的 type 值如下:
|取值 |行为|
| - | - |
| |空字符串(默认)用于向后兼容,这意味着在安装 hostPath 卷之前不会执行任何检查。|
|DirectoryOrCreate |如果在给定路径上什么都不存在,那么将根据需要创建空目录,权限设置为 0755,具有与 Kubelet 相同的组和所有权。|
|Directory |在给定路径上必须存在的目录。|
|FileOrCreate |如果在给定路径上什么都不存在,那么将在那里根据需要创建空文件,权限设置为 0644,具有与 Kubelet 相同的组和所|有权。
|File |在给定路径上必须存在的文件。|
|Socket |在给定路径上必须存在的 UNIX 套接字。|
|CharDevice |在给定路径上必须存在的字符设备。|
|BlockDevice |在给定路径上必须存在的块设备。|

基础主机上创建的文件或目录只能由 root 用户写入。您需要在 特权容器 中以 root 身份运行进程,或者修改主机上的文件权限以便容器能够写入 hostPath 卷。

Nginx配置之root与alias区别

配置好后,无法访问后端 upload 中静态文件,将 root 改为 alias 恢复。

1.根路径与虚拟路径

如果访问站点http://location/c访问的就是/a/目录下的站点信息

location /c/ {
	alias /a/
}

如果访问站点http://location/c访问的就是/a/c目录下的站点信息

location /c/ {
	root /a/
}
2.根路径与虚拟路径

alias后面必须加 /
root结尾 / 可有可无

3.建议使用说明

一般情况下,在location / 中配置root,在location /other 中配置alias是一个好习惯