侧边栏壁纸
博主头像
风华科技 博主等级

行动起来,活在当下

  • 累计撰写 268 篇文章
  • 累计创建 25 个标签
  • 累计收到 4 条评论

目 录CONTENT

文章目录

基于K8Sv1.30.0 部署开源项目huasenjio-compose

风华
2025-04-11 / 0 评论 / 0 点赞 / 16 阅读 / 0 字
广告 广告

基于K8Sv1.30.0 部署开源项目:huasenjio-compose

1、部署前本地需要支持的环境

### k8s环境   本次部署采用k8sv1.30.0 高可用,集群需要支持拉取dockerhub镜像
root@k8s-master01:~# kubectl get nodes
NAME           STATUS   ROLES           AGE     VERSION
k8s-master01   Ready    control-plane   3d23h   v1.30.0   ## 不允许调度pod
k8s-master02   Ready    control-plane   3d23h   v1.30.0   ## 不允许调度pod
k8s-master03   Ready    control-plane   3d23h   v1.30.0   ## 不允许调度pod
k8s-node01     Ready    worker          3d23h   v1.30.0
k8s-node02     Ready    worker          3d23h   v1.30.0

### k8s存储环境 至少需要有一个默认存储,nfs ceph都行,本次已rook部署的ceph为例,root部署ceph存储参考链接:https://www.xxjstl.cn/archives/3571e068-1faa-46d0-9a86-37bfee685508
root@k8s-master01:~# kubectl get storageclasses.storage.k8s.io 
NAME                        PROVISIONER                                   RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
nfs-client                  k8s-sigs.io/nfs-subdir-external-provisioner   Delete          Immediate           false                  2d7h
rook-ceph-block (default)   rook-ceph.rbd.csi.ceph.com                    Delete          Immediate           true                   3d1h
rook-cephfs                 rook-ceph.cephfs.csi.ceph.com                 Delete          Immediate           true                   3d1h
root@k8s-master01:~# 

### k8s环境集群网络暴露方式,可选LoadBalancer,本次k8s工作负载暴露的方式为:LoadBalancer    LoadBalancer部署参考https://www.xxjstl.cn/archives/jiu-kuberneteshe-xin-gai-nian-zhi-service#5loadbalancer%E7%B1%BB%E5%9E%8B


其他解释

  • 集群nginx采用LoadBalancer暴露方式,这种方式会给工作负载应用暴露一个和集群同段的IP地址,这个ip地址是LoadBalancer地址池中可用的。

  • 在k8s中server 连接mongo和redis采用域名方式,同理nginx代理server也是如此,具体是如下

    mongo.huasenjio.svc.cluster.local    ## mongo的地址
    redis.huasenjio.svc.cluster.local    ## redis的地址
    
    ## 以下是nginx configmap配置文件片段,里面写明了如何连接server,详细参考2.4 nginx中的configmap文件
                upstream ajax_service {
                        server server.huasenjio.svc.cluster.local:3000;   ## 定义了连接名
                }
                upstream webs_service {
                        server server.huasenjio.svc.cluster.local:8181;  ## 定义了连接名
                }     			
    
  • nginx和server容器需要重新打包,打包后在工作负载节点(node节点)导入

    ctr -n=k8s.io images import service.tar
    ctr -n=k8s.io images import huasen-nginx.tar
    

2、准备各项yaml文件

2.1、部署huasenjio-namespace

## 创建huasenjio所需的命名空间资源等
apiVersion: v1
kind: Namespace
metadata:
  name: huasenjio

执行

root@k8s-master01:~/note/huasenjio# kubectl apply -f 01-huasenjio-namespace.yaml 
namespace/huasenjio created

验证

root@k8s-master01:~/note/huasenjio# kubectl get ns | grep huasenjio
huasenjio         Active   38s

2.2、部署huasenjio-mongo

# ConfigMap 定义(保持不变)
apiVersion: v1
kind: ConfigMap
metadata:
  name: init-mongo-config
  namespace: huasenjio
data:
  init-mongo-open.js: |
    /*
    * @Description: 初始化数据库
    */
    
    // 创建应用数据库用户
    const huasenDB = db.getSiblingDB("huasen");
    if (!huasenDB.getUser("huasenjio")) {
      print("Creating huasenjio user...");
      huasenDB.createUser({
        user: "huasenjio",
        pwd: "Mongo12345*",
        roles: [{ role: "readWrite", db: "huasen" }],
      });
    }

---
# PVC 定义(保持不变)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mongo-pvc
  namespace: huasenjio
spec:
  accessModes: [ "ReadWriteOnce" ]
  storageClassName: "rook-ceph-block"
  resources:
    requests:
      storage: 10Gi

---
# Deployment 定义(替换原来的 Pod)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mongo
  namespace: huasenjio
  labels:
    app: mongo
spec:
  replicas: 1  # 单节点部署,如需高可用可改为3
  selector:
    matchLabels:
      app: mongo
  strategy:
    type: Recreate  # 有状态服务使用Recreate策略
  template:
    metadata:
      labels:
        app: mongo
    spec:
      containers:
      - name: mongo
        image: mongo:4.2.2
        ports:
          - containerPort: 27017
        env:
          - name: TZ
            value: Asia/Shanghai
          - name: MONGO_INITDB_ROOT_USERNAME
            value: "root"
          - name: MONGO_INITDB_ROOT_PASSWORD
            value: "Mongo12345*"
        volumeMounts:
          - name: mongo-db
            mountPath: /data/db
          - name: mongo-config
            mountPath: /docker-entrypoint-initdb.d/
        readinessProbe:
          exec:
            command:
              - mongo
              - --eval
              - "db.adminCommand('ping')"
          initialDelaySeconds: 5
          periodSeconds: 10
        livenessProbe:
          exec:
            command:
              - mongo
              - --eval
              - "db.adminCommand('ping')"
          initialDelaySeconds: 30
          periodSeconds: 10
      volumes:
        - name: mongo-db
          persistentVolumeClaim:
            claimName: mongo-pvc
        - name: mongo-config
          configMap:
            name: init-mongo-config
            items:
              - key: init-mongo-open.js
                path: init-mongo-open.js

---
# Service 定义(保持不变)
apiVersion: v1
kind: Service
metadata:
  name: mongo
  namespace: huasenjio
  labels:
    app: mongo
spec:
  ports:
  - port: 27017
    name: mongo
  clusterIP: None
  selector:
    app: mongo
  type: ClusterIP

执行

root@k8s-master01:~/note/huasenjio# kubectl apply -f 02-huasenjio-mongo.yaml 
configmap/init-mongo-config created
persistentvolumeclaim/mongo-pvc created
deployment.apps/mongo created
service/mongo created

验证

root@k8s-master01:~/note/huasenjio# kubectl get pod,svc -n huasenjio 
NAME                         READY   STATUS    RESTARTS   AGE
pod/mongo-66bb8654d5-446b2   1/1     Running   0          28s

NAME            TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)     AGE
service/mongo   ClusterIP   None         <none>        27017/TCP   28s

root@k8s-master01:~/note/huasenjio# kubectl logs -n huasenjio mongo-66bb8654d5-446b2 | tail -6
### 以下是日志片段
2025-04-11T17:44:32.451+0800 I  NETWORK  [listener] connection accepted from 127.0.0.1:42206 #7 (1 connection now open)
2025-04-11T17:44:32.452+0800 I  NETWORK  [conn7] received client metadata from 127.0.0.1:42206 conn7: { application: { name: "MongoDB Shell" }, driver: { name: "MongoDB Internal Client", version: "4.2.2" }, os: { type: "Linux", name: "Ubuntu", architecture: "x86_64", version: "18.04" } }
2025-04-11T17:44:32.454+0800 I  NETWORK  [listener] connection accepted from 127.0.0.1:42214 #8 (2 connections now open)
2025-04-11T17:44:32.454+0800 I  NETWORK  [conn8] received client metadata from 127.0.0.1:42214 conn8: { application: { name: "MongoDB Shell" }, driver: { name: "MongoDB Internal Client", version: "4.2.2" }, os: { type: "Linux", name: "Ubuntu", architecture: "x86_64", version: "18.04" } }
2025-04-11T17:44:32.455+0800 I  NETWORK  [conn7] end connection 127.0.0.1:42206 (1 connection now open)
2025-04-11T17:44:32.458+0800 I  NETWORK  [conn8] end connection 127.0.0.1:42214 (0 connections now open)

2.3、部署huasenjio-redis

# redis-all-in-one.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: redis-config
  namespace: huasenjio
data:
  redis.conf: |
    requirepass Redis12345*
    bind 0.0.0.0
    appendonly yes
    maxmemory 1024MB
    maxmemory-policy allkeys-lru
    # 性能优化参数
    tcp-keepalive 300
    timeout 0
    tcp-backlog 511
    # 安全建议
    protected-mode yes
    rename-command FLUSHDB ""
    rename-command FLUSHALL ""
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: redis-pvc
  namespace: huasenjio
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  storageClassName: rook-ceph-block  # 使用集群默认的Rook Ceph Block存储
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis
  namespace: huasenjio
  labels:
    app: redis
spec:
  replicas: 1
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      securityContext:
        runAsUser: 1000
        fsGroup: 1000
      containers:
      - name: redis
        image: redis:6.2-alpine
        command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
        ports:
        - containerPort: 6379
          name: redis
        env:
        - name: TZ
          value: Asia/Shanghai
        resources:
          limits:
            memory: "1536Mi"
            cpu: "1"
          requests:
            memory: "1Gi"
            cpu: "500m"
        volumeMounts:
        - name: redis-config
          mountPath: /usr/local/etc/redis/redis.conf
          subPath: redis.conf
        - name: redis-data
          mountPath: /data
        livenessProbe:
          exec:
            command:
            - redis-cli
            - -a
            - Redis12345*
            - PING
          initialDelaySeconds: 30
          periodSeconds: 10
          timeoutSeconds: 5
        readinessProbe:
          exec:
            command:
            - redis-cli
            - -a
            - Redis12345*
            - PING
          initialDelaySeconds: 5
          periodSeconds: 5
      volumes:
      - name: redis-config
        configMap:
          name: redis-config
      - name: redis-data
        persistentVolumeClaim:
          claimName: redis-pvc
---
apiVersion: v1
kind: Service
metadata:
  name: redis
  namespace: huasenjio
  labels:
    app: redis
spec:
  selector:
    app: redis
  ports:
    - name: redis
      protocol: TCP
      port: 6379
      targetPort: 6379
  type: ClusterIP

执行

root@k8s-master01:~/note/huasenjio# kubectl apply -f 03-huasen-redis.yaml 
configmap/redis-config created
persistentvolumeclaim/redis-pvc created
deployment.apps/redis created
service/redis created

验证

root@k8s-master01:~/note/huasenjio# kubectl get pod -n huasenjio 
NAME                     READY   STATUS    RESTARTS   AGE
mongo-66bb8654d5-446b2   1/1     Running   0          3m45s
redis-597d744f8-5rbh6    1/1     Running   0          51s

root@k8s-master01:~/note/huasenjio# kubectl logs -n huasenjio redis-597d744f8-5rbh6  
1:C 11 Apr 2025 17:46:41.893 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1:C 11 Apr 2025 17:46:41.893 # Redis version=6.2.17, bits=64, commit=00000000, modified=0, pid=1, just started
1:C 11 Apr 2025 17:46:41.893 # Configuration loaded
1:M 11 Apr 2025 17:46:41.894 * monotonic clock: POSIX clock_gettime
1:M 11 Apr 2025 17:46:41.895 * Running mode=standalone, port=6379.
1:M 11 Apr 2025 17:46:41.895 # Server initialized
1:M 11 Apr 2025 17:46:41.896 * Ready to accept connections

2.4、部署huasenjio-nginx

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-config
  namespace: huasenjio
data:
  nginx.conf: |  # 修改为子配置文件名称
    user nginx;
    worker_processes auto;
    error_log /var/log/nginx/error.log notice;
    pid /var/run/nginx.pid;

    events {
      worker_connections  1024;
    }

    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;
            keepalive_timeout 65;
            # 请求体最大限制10m
            client_max_body_size 10m;
            # 哈希桶大小参数与处理器的缓存行大小对齐
            server_names_hash_bucket_size 64;
            # docker容器别名访问
            upstream ajax_service {
                    server server.huasenjio.svc.cluster.local:3000;
            }
            upstream webs_service {
                    server server.huasenjio.svc.cluster.local:8181;
            }
            # http重定向到https
            # server {
            #       listen 80;
            #       server_name localhost;
            #       return 301 https://$host$request_uri;
            # }
            # 设置缓存目录
            proxy_cache_path /usr/local/nginx-cache levels=1:2 keys_zone=nginx-cache:20m max_size=50g inactive=72h;

            # IP、单域名访问配置,即:分别通过"域名/portal/"、"域名/admin/"访问花森主页及后台管理界面
            server {
                    gzip  on;
                    gzip_min_length  1k;
                    gzip_buffers  4 16k;
                    gzip_http_version  1.1;
                    gzip_comp_level  8;
                    gzip_types  text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php application/javascript application/json;
                    gzip_disable  "MSIE [1-6]\.";
                    gzip_vary  on;
                    # listen       443 ssl;
                    listen       80; # 支持IPV4访问80端口
                    # listen  [::]:80; # 支持IPV6访问80端口
                    server_name localhost;
                    # ohttps申请的证书文件fullchain.cer(PEM格式)
                    # ssl_certificate /etc/nginx/certificates/cert-***.cer;
                    # ohttps申请的私钥文件cert.key(PEM格式)
        # ssl_certificate_key /etc/nginx/certificates/cert-***/cert.key;
                    location /api/ {
                            proxy_pass http://ajax_service/;
                            # 配置显示客户端真实ip
                            proxy_set_header Host $host;
                            proxy_set_header X-Real-IP $remote_addr;
                            proxy_set_header REMOTE-HOST $remote_addr;
                            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                    }
                    location /ws/ {
                            proxy_pass http://webs_service/;
                            proxy_set_header Connection "upgrade";
                            proxy_set_header Upgrade $http_upgrade;
                            proxy_set_header Host $host;
                            proxy_set_header X-Real-IP $remote_addr; 
                            proxy_set_header REMOTE-HOST $remote_addr;
                            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                    }
                    location /portal/ {
                            add_header 'Cache-Control' "no-cache";
                            proxy_pass http://ajax_service/public/webapp/portal/;
                    }
                    location /admin/ {
                            add_header 'Cache-Control' "no-cache";
                            proxy_pass http://ajax_service/public/webapp/admin/;
                    }
                    location ~ ^/(portal|admin|portal\/css|admin\/css)/huasen-store/ {
                            add_header 'Cache-Control' "no-cache";
                            rewrite ^/(portal|admin|portal\/css|admin\/css)/huasen-store/(.*) /huasen-store/$2 break;
            proxy_pass http://ajax_service;
                    }
                    location / {
                            add_header 'Cache-Control' "no-cache";
                            proxy_pass http://ajax_service/;
                    }
                    error_page   500 502 503 504  /50x.html;
                    location = /50x.html {
                            root   /usr/share/nginx/html;
                    }
            }

            # 单独配置个人页访问,即:支持huasenjio.top直接访问
            server {
                    gzip  on;
                    gzip_min_length  1k;
                    gzip_buffers  4 16k;
                    gzip_http_version  1.1;
                    gzip_comp_level  8;
                    gzip_types  text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php application/javascript application/json;
                    gzip_disable  "MSIE [1-6]\.";
                    gzip_vary  on;
                    # listen       443 ssl;
                    listen       80;
                    server_name huasenjio.top;
                    # ohttps申请的证书文件fullchain.cer(PEM格式)
                    # ssl_certificate /etc/nginx/certificates/cert-***.cer;
                    # ohttps申请的私钥文件cert.key(PEM格式)
        # ssl_certificate_key /etc/nginx/certificates/cert-***/cert.key;
                    location / {
                            add_header 'Cache-Control' "no-cache";
                            proxy_pass http://ajax_service/huasen-store/webapp/guide/;
                    }
            }

            # 单独配置花森主页访问,即:支持n.huasenjio.top、www.huasenjio.top直接访问
            server {
        gzip  on;
                    gzip_min_length  1k;
                    gzip_buffers  4 16k;
                    gzip_http_version  1.1;
                    gzip_comp_level  8;
                    gzip_types  text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php application/javascript application/json;
                    gzip_disable  "MSIE [1-6]\.";
                    gzip_vary  on;
                    # listen       443 ssl;
                    listen       80;
                    server_name n.huasenjio.top www.huasenjio.top;
                    # ohttps申请的证书文件fullchain.cer(PEM格式)
                    # ssl_certificate /etc/nginx/certificates/cert-***.cer;
                    # ohttps申请的私钥文件cert.key(PEM格式)
        # ssl_certificate_key /etc/nginx/certificates/cert-***/cert.key;
                    location /api/ {
                            proxy_pass http://ajax_service/;
                            proxy_set_header Host $host;
                            proxy_set_header X-Real-IP $remote_addr; 
                            proxy_set_header REMOTE-HOST $remote_addr;
                            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                    }
                    location /ws/ {
                            proxy_pass http://webs_service/;
                            proxy_set_header Connection "upgrade";
                            proxy_set_header Upgrade $http_upgrade;
                            proxy_set_header Host $host;
                            proxy_set_header X-Real-IP $remote_addr; 
                            proxy_set_header REMOTE-HOST $remote_addr;
                            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                    }
                    location ~ ^/(css\/huasen-store|huasen-store)/ {
                            add_header 'Cache-Control' "no-cache";
                            rewrite ^/(css\/huasen-store|huasen-store)/(.*) /huasen-store/$2 break;
                    proxy_pass http://ajax_service;
                    }
                    location / {
                            add_header 'Cache-Control' "no-cache";
                            proxy_pass http://ajax_service/public/webapp/portal/;
                    }
            }

            # 单独配置后台管理界面访问,即:支持a.huasenjio.top直接访问
            server {
                    gzip  on;
                    gzip_min_length  1k;
                    gzip_buffers  4 16k;
                    gzip_http_version  1.1;
                    gzip_comp_level  8;
                    gzip_types  text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php application/javascript application/json;
                    gzip_disable  "MSIE [1-6]\.";
                    gzip_vary  on;
                    # listen       443 ssl;
                    listen       80;
                    server_name a.huasenjio.top;
                    # ohttps申请的证书文件fullchain.cer(PEM格式)
                    # ssl_certificate /etc/nginx/certificates/cert-***.cer;
                    # ohttps申请的私钥文件cert.key(PEM格式)
        # ssl_certificate_key /etc/nginx/certificates/cert-***/cert.key;
                    location /api/ {
                            proxy_pass http://ajax_service/;
                            proxy_set_header Host $host;
                            proxy_set_header X-Real-IP $remote_addr; 
                            proxy_set_header REMOTE-HOST $remote_addr;
                            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                    }
                    location /ws/ {
                            proxy_pass http://webs_service/;
                            proxy_set_header Connection "upgrade";
                            proxy_set_header Upgrade $http_upgrade;
                            proxy_set_header Host $host;
                            proxy_set_header X-Real-IP $remote_addr; 
                            proxy_set_header REMOTE-HOST $remote_addr;
                            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                    }
                    location ~ ^/(css\/huasen-store|huasen-store)/ {
                            add_header 'Cache-Control' "no-cache";
                            rewrite ^/(css\/huasen-store|huasen-store)/(.*) /huasen-store/$2 break;
                    proxy_pass http://ajax_service;
                    }
                    location / {
                            add_header 'Cache-Control' "no-cache";
                            proxy_pass http://ajax_service/public/webapp/admin/;
                    }
            }

            # 引入默认配置
      include /etc/nginx/conf.d/*.conf;
    }
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nginx-pvc
  namespace: huasenjio
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: rook-ceph-block
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nginx-logs-pvc
  namespace: huasenjio
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: rook-ceph-block
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: huasenjio
  labels:
    app: nginx
spec:
  replicas: 1
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      # 安全上下文(根据镜像实际情况调整)
      securityContext:
        fsGroup: 1000
      containers:
      - name: nginx
        image: docker.io/library/huasen-nginx:1.23.1
        imagePullPolicy: Never
        ports:
        - containerPort: 80
          name: http
        # 配置文件挂载(作为子配置)
        volumeMounts:
        - name: nginx-config
          mountPath: /etc/nginx/nginx.conf
          subPath: nginx.conf
        - name: nginx-storage
          mountPath: /home/www
        - name: nginx-logs
          mountPath: /var/log/nginx
        # 健康检查(使用有效路径)
        livenessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 5
        # 资源限制(建议添加)
        resources:
          requests:
            cpu: "100m"
            memory: "128Mi"
          limits:
            cpu: "500m"
            memory: "512Mi"
      volumes:
      - name: nginx-config
        configMap:
          name: nginx-config
          items:
          - key: nginx.conf
            path: nginx.conf
      - name: nginx-storage
        persistentVolumeClaim:
          claimName: nginx-pvc
      - name: nginx-logs
        persistentVolumeClaim:
          claimName: nginx-logs-pvc

---
apiVersion: v1
kind: Service
metadata:
  name: nginx
  namespace: huasenjio
  labels:
    app: nginx
spec:
  selector:
    app: nginx
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 80
  type: LoadBalancer

执行

root@k8s-master01:~/note/huasenjio# kubectl apply -f 04-huasen-nginx.yaml 
configmap/nginx-config created
persistentvolumeclaim/nginx-pvc created
persistentvolumeclaim/nginx-logs-pvc created
deployment.apps/nginx created
service/nginx created

验证

root@k8s-master01:~/note/huasenjio# kubectl get pod -n huasenjio 
NAME                     READY   STATUS             RESTARTS      AGE
mongo-66bb8654d5-446b2   1/1     Running            0             7m4s
nginx-69fb49758c-bwqgh   0/1     CrashLoopBackOff   3 (23s ago)   79s   ## 不影响,因为没有部署server
redis-597d744f8-5rbh6    1/1     Running            0             4m10s

root@k8s-master01:~/note/huasenjio# kubectl logs -n huasenjio nginx-69fb49758c-bwqgh 
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
nginx: [emerg] host not found in upstream "server.huasenjio.svc.cluster.local:3000" in /etc/nginx/nginx.conf:25   ## 报错原因无法解析,因为没有部署server,不影响

2.5、部署huasenjio-server

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: server-setting
  namespace: huasenjio
data:
  setting.json: |  # 修改setting.json
    {
      "site": {
        "brandName": "花森",
        "brandUrl": "https://n.huasenjio.top/huasen-store/icon/favicon.svg",
        "brandDescription": "花森起始页由可自定义网址导航、文章博客、后台管理模块组成的开源项目,专注于收录互联网优秀站点,涵盖了生活、娱乐、学习、影视、考研、工作、科技、工具等领域,提供一个信息聚合的空间,让用户高效上网冲浪的综合性平台!",
        "brandKeywords": "huasenjio.top,花森起始页,花森主页,花森导航,花森博客,花生起始页,花生主页,花生网址导航,花生博客,综合门户,网址导航,实用工具",
        "redirectUrl": "https://huasenjio.top/",
        "origin": "",
        "headHtml": "",
        "bodyHtml": "",
        "footerHtml": "",
        "openLabelClassification": false,
        "autoIconPatch": true,
        "jwt": "",
        "jwtLiveTime": 604800,
        "cityCode": 101210101,
        "notifyArticleId": null
      },
      "theme": {
        "pure": [
          {
            "color": "#ffffff",
            "background": "#000000"
          },
          {
            "color": "#ffffff",
            "background": "#000000"
          },
          {
            "color": "#ffffff",
            "background": "#5522FF"
          }
        ],
        "wallpaper": [
          {
            "headerFontColor": "#FFFFFF",
            "background": "https://s2.loli.net/2023/03/31/oSz3nJB84dC5ueh.jpg"
          },
          {
            "headerFontColor": "#000000",
            "background": "https://s2.loli.net/2023/03/31/W9n7RoFvhtlpg6U.jpg"
          },
          {
            "headerFontColor": "#FFFFFF",
            "background": "huasen-store/img/1698771433825.jpg"
          },
          {
            "headerFontColor": "#FFFFFF",
            "background": "huasen-store/img/1699075427945.jpg"
          },
          {
            "headerFontColor": "#FFFFFF",
            "background": "huasen-store/img/1700315475749.jpg"
          }
        ],
        "default": {
          "order": 0,
          "bg": "https://s2.loli.net/2023/03/31/oSz3nJB84dC5ueh.jpg",
          "color": "#FFFFFF"
        }
      },
      "mail": {
        "host": "smtp.163.com",
        "port": 465,
        "user": "huasenjio@163.com",
        "mtp": ""
      },
      "nav": [
        {
          "label": "花森小窝",
          "type": "link",
          "typeConfig": {
            "url": "https://huasenjio.top/",
            "target": "_blank"
          },
          "icon": "iconfont icon-md-home"
        },
        {
          "label": "更新日志",
          "type": "article",
          "typeConfig": {
            "articleId": ""
          },
          "icon": "iconfont icon-md-stats"
        },
        {
          "label": "关于我们",
          "type": "article",
          "typeConfig": {
            "articleId": ""
          },
          "icon": "iconfont icon-md-at"
        }
      ],
      "aside": [
        {
          "label": "微信二维码",
          "type": "html",
          "typeConfig": {
            "domStr": "<img src=\"https://a.huasenjio.top/huasen-store/default/1668990565457.png\" style=\"width: 64px; height: 64px\"/>"
          },
          "icon": "iconfont icon-weixin"
        },
        {
          "label": "帮助文档",
          "type": "article",
          "typeConfig": {
            "articleId": "67828ab45ecb62738adbf096"
          },
          "icon": "iconfont icon-md-help-circle"
        }
      ],
      "search": [
        {
          "url": "https://www.baidu.com/s",
          "key": "word",
          "params": {},
          "name": "百度",
          "icon": "iconfont icon-baidu"
        },
        {
          "url": "https://www.google.com/search",
          "key": "q",
          "params": {},
          "name": "谷歌",
          "icon": "iconfont icon-chrome"
        },
        {
          "url": "https://cn.bing.com/search",
          "key": "q",
          "params": {},
          "name": "必应",
          "icon": "iconfont icon-bing"
        },
        {
          "url": "localhost",
          "key": "instation",
          "params": {},
          "name": "站内",
          "icon": "iconfont icon-md-planet"
        },
        {
          "url": "https://metaso.cn/",
          "key": "q",
          "params": {},
          "name": "秘塔",
          "icon": "iconfont icon-mita"
        },
        {
          "url": "https://dict.youdao.com/search",
          "key": "q",
          "params": {},
          "name": "翻译",
          "icon": "iconfont icon-translate"
        },
        {
          "url": "https://xueshu.baidu.com/s",
          "key": "wd",
          "params": {},
          "name": "学术",
          "icon": "iconfont icon-md-school"
        },
        {
          "url": "https://ya.ru/images/search",
          "key": "text",
          "params": {},
          "name": "图搜",
          "icon": "huasen-store/default/yaru-20241229235108.png"
        }
      ]
    }
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: server-config
  namespace: huasenjio
data:
  config.js: |  # 修改config.js
    /*
    * @Autor: huasenjio
    * @Date: 2021-10-04 11:39:03
    * @LastEditors: huasenjio
    * @LastEditTime: 2023-02-04 14:29:05
    * @Description: 后端服务配置文件
    */

    const path = require('path');
    const _ = require('lodash');

    // 解析动态配置
    let setting = {};
    try {
      setting = require('./setting.json');
    } catch (err) {
      console.error('配置解析失败', err);
    }

    // 获取命令行传递的参数集合
    let args = process.argv.find(row => {
      return /^MODE=(dev|pro)$/.test(row);
    });

    // 运行环境常量(dev | pro)
    const MODE = args ? args.split('=')[1] : 'dev';
    console.log('[Huasen Log]:运行模式 MODE =', MODE);

    // 服务启动端口
    const PORT_SERVER = 3000;

    // 黑名单资源池
    const POOL_BLACKLIST = 'POOL_BLACKLIST';
    // 用户信息池
    const POOL_ACCESS = 'POOL_ACCESS';
    // 邮箱验证码池
    const POOL_MAIL = 'POOL_MAIL';
    // 令牌池
    const POOL_TOKEN = 'POOL_TOKEN';

    // 数据库连接配置
    const DB = {
      name: 'huasenjio',                         // MongoDB 角色名
      password: 'Mongo12345*',                   // MongoDB 角色密码
      ip: MODE === 'dev' ? '127.0.0.1' : 'mongo.huasenjio.svc.cluster.local', // 动态选择地址
      port: 27017,                               // MongoDB 端口
      dbName: 'huasen',                          // 数据库名
      // 生成完整的 MongoDB 连接字符串(包含认证和参数)
      get uri() {
        return `mongodb://${this.name}:${encodeURIComponent(this.password)}@${this.ip}:${this.port}/${this.dbName}?authSource=admin`;
      }
    };

    // Redis 连接配置
    const REDIS = {
      port: 6379,                                // Redis 端口
      host: MODE === 'dev' ? '127.0.0.1' : 'redis.huasenjio.svc.cluster.local', // 动态选择地址
      password: 'Redis12345*',                   // Redis 密码
      // 生成完整的 Redis 连接字符串(可选)
      get uri() {
        return `redis://:${encodeURIComponent(this.password)}@${this.host}:${this.port}`;
      }
    };


    // websocket配置
    const WS = {
      port: 8181,
      interval: 15000,
    };


    // QQ邮箱服务配置示例
    const QQ_MAIL = {
      host: 'smtp.qq.com', // QQ邮箱厂商
      port: 465,
      secure: true,
      auth: {
        user: 'QQ邮箱', //  QQ邮箱地址
        pass: 'QQ邮箱mtp', //  QQ邮箱地址的mtp通行码
      },
    };

    // 网易邮箱服务配置示例
    const WY_MAIL = {
      host: 'smtp.163.com',
      port: 465,
      secure: true,
      auth: {
        user: '163邮箱',
        pass: '163邮箱mtp',
      },
    };

    // 必须配置项目的邮箱服务,否则无法发送验证码
    const MAIL = {
      host: _.get(setting, 'mail.host') || QQ_MAIL.host,
      port: _.get(setting, 'mail.port') || QQ_MAIL.port,
      secure: true,
      auth: {
        user: _.get(setting, 'mail.user') || QQ_MAIL.auth.user,
        pass: _.get(setting, 'mail.mtp') || QQ_MAIL.auth.pass,
      },
    };

    // 重定向站点,当用户访问不正确的链接时,将会重定向到以下配置的站点
    const SITE = {
      redirectURL: _.get(setting, 'site.redirectUrl') || 'https://huasenjio.top/',
    };

    /**
    * 令牌密钥配置
    * 密钥格式:32位数子/字母
    */
    const JWT = {
      screat: _.get(setting, 'site.jwt') || 'abcdefghyjklmnobqrstuvwhyz123456', // jwt加密密钥
      expiresIn: _.get(setting, 'site.jwtLiveTime') || 604800, // 7天失效时间
    };

    // 会话
    const SESSION = {
      secret: '4008208820',
      cookie: { maxAge: 60 * 60 * 1000 * 24 * 7 },
      resave: true,
      saveUninitialized: false,
    };

    // 文件上传配置
    const STORE = {
      // 文件默认允许的类型,仅支持MIME
      acceptTypes: {
        ".jpg": "image/jpg",
        ".jpeg": "image/jpeg",
        ".png": "image/png",
        ".gif": "image/gif",
        ".svg": "image/svg+xml",
        ".ico": "image/vnd.microsoft.icon",
        ".html": "text/html",
        ".css": "text/css",
        ".js": "text/javascript",
        ".mp3": "audio/mpeg",
        ".aac": "audio/aac",
        ".mp4": "video/mp4",
        ".mpeg": "video/mpeg",
        ".webm": "audio/webm",
        ".webp": "image/webp",
        ".json": "application/json",
        ".pdf": "application/pdf",
        ".rar": "application/vnd.rar",
        ".tar": "application/x-tar",
        ".zip": "application/zip",
        ".7z": "application/x-7z-compressed",
        ".bz": "application/x-bzip",
        ".sh": "application/x-sh",
        ".bin": "application/octet-stream",
        ".csv": "text/csv",
        ".doc": "application/msword",
        ".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
        ".xls": "application/vnd.ms-excel",
        ".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
        ".ppt": "application/vnd.ms-powerpoint",
        ".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation"
      },

      fileSize: 1024 * 1024 * 10, // 限制10m大小
      target: 'file', // 获取前端上传文件的key值
      encoding: 'utf-8', // 传输的编码格式
      maxFieldsSize: 1024 * 1024 * 2, // 传输类型为text的字段的大小默认不超过2m
      maxFields: 10, // 默认支持1000个字段的解析
      maxFilesSize: 1024 * 1024 * 10, // 传输类型为file文件的大小不超过5m
      autoFiles: true, //控制是否可以上传文件
      uploadPath: path.resolve(__dirname, '../huasen-store/default'), // 默认上传文件路径
    };

    const TASK = {
      // 任务执行的时间间隔
      interval: 10000,
    };

    // 返回状态码
    const STATUS = {
      SUCCESS: 200, // 正常返回
      ERROR: 400, // 服务器内部错误
      FORBIDDEN: 403, // 权限不足
      AUTH: 401, // 无法认证,重新登录
    };

    /**
    * 对称密钥
    * 密钥格式:16位数子/字母
    * 特别注意:需要部署之前修改,否则数据无法解析
    */
    const SECRET_AES = ['dj38Ca8F8hag23nD', 'k4h9HdcXmEr83nsF'];

    /**
    * 非对称密钥要求:
    * 密钥位数:2048位(bit)
    * 密钥格式:PKCS#8
    * 输出格式:PEM/Base64
    * 推荐在线生成站点:https://try8.cn/tool/cipher/rsa
    */

    // 非对称公钥
    const SECRET_RSA_PUBLIC = `-----BEGIN PUBLIC KEY-----
    MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAykOjPXYErze4pX/r6au/
    cHOpnWlyP5AO1qXblDbQ7ZbTO2QG4MLVqz938mCstV+urDfySTHBVbeA0iwg7iye
    WULR7+IHHdE7QQRCNpV3t+EPq4xbKvGv9m7U6E6vh+z4SRJDuX0rWzxhbdYsIQZd
    VDs8eqfbLVMjS1+BEB/S8tFsgjWpIMfMQYF1Ale3GQjy1kLturpeAVQCnAA5dXpM
    KU4I4sFpDPL58DBHziPc0UkyJCt5Y9xhEvqSaTInqzFoHKnjx1xw6bM7brsZveRT
    +x8PIqepeHpI2cxjRcLKl3v/hO1qOk2a4OrY+K3z36o7KS4DZQrN/7YBWx2p3ThL
    pQIDAQAB
    -----END PUBLIC KEY-----
    `;

    // 非对称私钥
    const SECRET_RSA_PRIVATE = `-----BEGIN PRIVATE KEY-----
    MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDKQ6M9dgSvN7il
    f+vpq79wc6mdaXI/kA7WpduUNtDtltM7ZAbgwtWrP3fyYKy1X66sN/JJMcFVt4DS
    LCDuLJ5ZQtHv4gcd0TtBBEI2lXe34Q+rjFsq8a/2btToTq+H7PhJEkO5fStbPGFt
    1iwhBl1UOzx6p9stUyNLX4EQH9Ly0WyCNakgx8xBgXUCV7cZCPLWQu26ul4BVAKc
    ADl1ekwpTgjiwWkM8vnwMEfOI9zRSTIkK3lj3GES+pJpMierMWgcqePHXHDpsztu
    uxm95FP7Hw8ip6l4ekjZzGNFwsqXe/+E7Wo6TZrg6tj4rfPfqjspLgNlCs3/tgFb
    HandOEulAgMBAAECggEAVkkgfHm6ad1FgiTeSWMhWiGdfC+ds4wLKHq8/6+a1aCA
    IFf9ryiu6k07KEUhqIZXB9UeISd+qMiNxhtZOQID02R0Fve/vXKi6ouci5ib5++1
    NaO8yMcuH90MKsZWj5ACI3oNNjY1pshNcAPr83K5odNba5/sGpva9K6banuJDFiU
    pwWn1+MsqiZ74tLRlPKteyvGw0b6OWjxMeIr7/G1O30wd6MiAKObKK/ODO9CQlC2
    wUAIbFqewudv26ZzkMDjpVsI42p0/xRGBQDt4vGGfKiBj05fofPl3kn7kLmY+edn
    /yfvONhdHjnQVzITa9DSU1IXY8lVFHEGxuWM+V3OyQKBgQDu3YFTlsiHNTcTgs/f
    LgLaMtVnjFtqu01j6F6HL9mO5ytFCE9GtaEnbNVy1z5BoAm3JgVcd63sArKFiuUn
    GuaVglCKbjhgFgwnGPI11QAvPAOB2Qu19XrTwVQa4C0lJ6JrGuZe+1gLbbF+7bLV
    +LMUOEU9o6YFWcMQ7fRrcLguAwKBgQDYxf624LgU0ThS301Y78O5r5g2ePZ/F1W6
    M1XTlSWgllYBeDezOAH12tisYCrbEpniATfhN9Lc4qlXWz+yGVNfC2PbyfTCTdhL
    kwPsf/GXM8WWe4Nid+LV5bmy5loq8dCpgXzB8w4LoFuE2ZFxr57q+32Pg04taNGP
    txajinQjNwKBgAwqiA3D3k7UrQt3XDMX2tlWQXxWr8lN5PEzwqzMCR64M4H+nFsT
    oTOq3WxN/kPFbPlBHIDLL7aXpJQcsPM+8YOn8YY7eu+Z7+CF6sBHKw0810jjzy7j
    Y/ApJql/xYzg6ereoeEwmBls6t92J+eyFRzwiMZM8YXQPpk8JXjbcuYVAoGAZrWJ
    doULM3HeSgXb1CPmjPiSGl0+DgG0cMEaDWJBrdENdyzK13PWGfNTbnkyVRJ/LwJ8
    w417r4UFz4pAp9YwFnyDGAScn+PadBR4a3pDseyp1h83pVRAejCayBU069wfjfD4
    d7z+DqwwMMYVj9QybAw09ea1B/b+NCX/6AUV+gkCgYEAqlrfNpXSaFbxCtDy4oA3
    kHRrmwkjlGj07cSBCCInw5yL1qnSPaLVaK+l4fN68+Ac0ZvH9XFYiXYLWV8vGLUm
    DyeS4WrWYM2tCoqSp/JnwReRiJPYx3lSfaB1qERyTRxKyFoMgcdybyTvIDTXiOqr
    sHAMEhW3k0BqdsBQ9KSbExU=
    -----END PRIVATE KEY-----
    `;

    module.exports = {
      MODE,
      DB,
      REDIS,
      WS,
      JWT,
      TASK,
      SESSION,
      STORE,
      STATUS,

      MAIL,
      QQ_MAIL,
      WY_MAIL,

      SITE,

      PORT_SERVER,

      POOL_BLACKLIST,
      POOL_ACCESS,
      POOL_MAIL,
      POOL_TOKEN,

      SECRET_AES,
      SECRET_RSA_PUBLIC,
      SECRET_RSA_PRIVATE,
    };
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: huasen-store
  namespace: huasenjio
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: rook-ceph-block
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: huasen-log
  namespace: huasenjio
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: rook-ceph-block
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: server
  namespace: huasenjio
  labels:
    app: server
spec:
  replicas: 1
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: server
  template:
    metadata:
      labels:
        app: server
    spec:
      securityContext:
        runAsUser: 1000
        runAsGroup: 1000
        fsGroup: 1000
      initContainers:
        - name: init-setting
          image: busybox
          command: ["sh", "-c", "cp /configmap-source/setting.json /app/huasen-server/setting.json"]
          volumeMounts:
            - name: server-setting  # 可写 emptyDir
              mountPath: /app/huasen-server
            - name: configmap-source  # 临时的 ConfigMap 挂载(只读)
              mountPath: /configmap-source
              readOnly: true
      containers:
        - name: server
          image: docker.io/library/server:latest
          imagePullPolicy: Never
          ports:
            - containerPort: 3000
              name: http01
            - containerPort: 8181
              name: http02
          volumeMounts:
            - name: huasen-store
              mountPath: /app/huasen-store      
            - name: server-setting  # 可写 emptyDir
              mountPath: /app/huasen-server/setting.json
              subPath: setting.json
            - name: server-config  # 只读 ConfigMap
              mountPath: /app/huasen-server/config.js
              subPath: config.js
            - name: huasen-log
              mountPath: /app/huasen-server/log
      volumes:
        - name: huasen-store
          persistentVolumeClaim:
            claimName: huasen-store
        - name: huasen-log
          persistentVolumeClaim:
            claimName: huasen-log
        - name: server-setting  # 改用 emptyDir(可写)
          emptyDir: {}
        - name: server-config  # 保持 ConfigMap(只读)
          configMap:
            name: server-config
        - name: configmap-source  # 临时的 ConfigMap 挂载(用于 initContainer)
          configMap:
            name: server-setting

---
apiVersion: v1
kind: Service
metadata:
  name: server
  namespace: huasenjio
  labels:
    app: server
spec:
  selector:
    app: server
  ports:
    - name: http01
      protocol: TCP
      port: 3000
      targetPort: 3000
    - name: http02
      protocol: TCP
      port: 8181
      targetPort: 8181
  type: ClusterIP

执行

root@k8s-master01:~/note/huasenjio# kubectl apply -f 05-huasen-server.yaml 
configmap/server-setting created
configmap/server-config created
persistentvolumeclaim/huasen-store created
persistentvolumeclaim/huasen-log created
deployment.apps/server created
service/server created

验证

root@k8s-master01:~/note/huasenjio# kubectl get pod -n huasenjio 
NAME                      READY   STATUS             RESTARTS      AGE
mongo-66bb8654d5-446b2    1/1     Running            0             8m59s
nginx-69fb49758c-bwqgh    0/1     CrashLoopBackOff   4 (91s ago)   3m14s
redis-597d744f8-5rbh6     1/1     Running            0             6m5s
server-796cbff887-z4qx4   1/1     Running            0             22s

## 查看日志
root@k8s-master01:~/note/huasenjio# kubectl logs -n huasenjio server-796cbff887-z4qx4 
Defaulted container "server" out of: server, init-setting (init)

> server@1.0.0 pm2-in-docker
> pm2-runtime start ecosystem.config.js

2025-04-11T09:52:24: PM2 log: Launching in no daemon mode
2025-04-11T09:52:24: PM2 log: [Watch] Start watching app
2025-04-11T09:52:24: PM2 log: App [app:0] starting in -fork mode-
2025-04-11T09:52:24: PM2 log: App [app:0] online
[Huasen Log]:运行模式 MODE = pro
[Huasen Log]:headHtml请输入
[Huasen Log]:bodyHtml请输入
[Huasen Log]:初始化网站入口失败 Error: EACCES: permission denied, open '/app/huasen-server/public/webapp/portal/index.html'
    at Object.openSync (node:fs:590:3)
    at Object.writeFileSync (node:fs:2202:35)
    at /app/huasen-server/plugin/initialize-site.js:113:8
    at Object.<anonymous> (/app/huasen-server/plugin/initialize-site.js:118:3)
    at Module._compile (node:internal/modules/cjs/loader:1198:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1252:10)
    at Module.load (node:internal/modules/cjs/loader:1076:32)
    at Function.Module._load (node:internal/modules/cjs/loader:911:12)
    at Module.require (node:internal/modules/cjs/loader:1100:19)
    at Module.Hook._require.Module.require (/app/huasen-server/node_modules/require-in-the-middle/index.js:101:39) {
  errno: -13,
  syscall: 'open',
  code: 'EACCES',
  path: '/app/huasen-server/public/webapp/portal/index.html'
}
[Huasen Log]:即将连接数据库...
[Huasen Log]:websocket 服务端口为8181
[Huasen Log]:express 服务端口为3000
[Huasen Log]:ioredis 服务端口为6379
[Huasen Log]:mongodb 服务端口为27017
初始化文章成功: {

## 再次检查nginx pod情况,server起来后,运行正常
root@k8s-master01:~/note/huasenjio# kubectl get pod -n huasenjio 
NAME                      READY   STATUS    RESTARTS        AGE
mongo-66bb8654d5-446b2    1/1     Running   0               10m
nginx-69fb49758c-bwqgh    1/1     Running   5 (2m44s ago)   4m27s
redis-597d744f8-5rbh6     1/1     Running   0               7m18s
server-796cbff887-z4qx4   1/1     Running   0               95s
root@k8s-master01:~/note/huasenjio# kubectl logs -n huasenjio nginx-69fb49758c-bwqgh 
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
nginx: [warn] conflicting server name "localhost" on 0.0.0.0:80, ignored

2.6、最后验证

查看service

root@k8s-master01:~/note/huasenjio# kubectl get svc -n huasenjio 
NAME     TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)             AGE
mongo    ClusterIP      None            <none>           27017/TCP           21m
nginx    LoadBalancer   10.233.47.213   192.168.12.100   80:30195/TCP        15m  ## 192.168.12.100 暴露的工作负载ip,可以通过该IP进行访问
redis    ClusterIP      10.233.12.19    <none>           6379/TCP            18m
server   ClusterIP      10.233.7.3      <none>           3000/TCP,8181/TCP   13m

浏览器访问

http://192.168.12.100/portal/#/home

登录测试

修改重定向,简单配置信息后访问:

2.7、从docker迁移数据到k8s

备份mongo数据

### 进入mongo容器
docker exec -it mongo /bin/
### 备份数据
mongodump --db huasen --out /path/to/save/dump
### 将数据拷贝到物理节点上
docker cp mongo:/path/to/save/dump/huasen /root/.
### 将数据发送到k8smaster节点
scp -r ./huasen/ root@192.168.12.21:/root/

从k8s节点恢复数据

### 复制数据到容器
kubectl cp /root/huasen mongo-66bb8654d5-jh98h:/path/huasen -n huasenjio
### 恢复数据到mongo
mongorestore \
 --username="huasenjio" \
 --password="Mongo12345*" \
 --authenticationDatabase="huasen" \
 --db=huasen \
 --dir=/path/huasen/
0
k8s
广告 广告

评论区