# 本机镜像导入集群的两种方式(无镜像仓库场景): # # 方式 A:集群就是执行 docker build 的这台机器(单节点或每台节点都构建) # docker save wuziqi:0.1.0 -o wuziqi-0.1.0.tar # ctr -n k8s.io images import wuziqi-0.1.0.tar # # 方式 B:集群在别的机器上 # docker save wuziqi:0.1.0 -o wuziqi-0.1.0.tar # scp wuziqi-0.1.0.tar :~/ # 在【每台可能被调度到的节点】上执行:ctr -n k8s.io images import ~/wuziqi-0.1.0.tar # # 导入后配合 imagePullPolicy: IfNotPresent 即可直接启动,无需任何 registry。 apiVersion: apps/v1 kind: Deployment metadata: name: wuziqi namespace: wuziqi labels: app: wuziqi spec: # 【必须保持为 1】 # 房间与棋局状态存放在进程内存(RoomManager),多副本会各自持有一份状态: # 两名玩家被 Ingress 分流到不同 Pod 时,第二个玩家会看到"房间不存在"。 # 若确实需要多副本,必须引入 Redis + Socket.IO Redis Adapter,并把房间状态外置。 replicas: 1 strategy: # Recreate:先终止旧 Pod 再创建新 Pod。 # 默认的 RollingUpdate 会让新旧两个 Pod 短暂并存,此时新 Pod 内存里没有旧 Pod 的房间, # 进行中的对局会"房间丢失"。 type: Recreate selector: matchLabels: app: wuziqi template: metadata: labels: app: wuziqi spec: securityContext: runAsNonRoot: true runAsUser: 1000 fsGroup: 1000 # 内存态服务,收到 SIGTERM 后推完最后一次状态即可退出 terminationGracePeriodSeconds: 15 containers: - name: wuziqi image: wuziqi:0.1.0 imagePullPolicy: IfNotPresent ports: - name: http containerPort: 3000 env: - name: PORT value: "3000" - name: NODE_ENV value: production readinessProbe: httpGet: path: /healthz port: http initialDelaySeconds: 2 periodSeconds: 10 timeoutSeconds: 3 livenessProbe: httpGet: path: /healthz port: http initialDelaySeconds: 5 periodSeconds: 20 timeoutSeconds: 3 failureThreshold: 3 resources: requests: cpu: 20m memory: 64Mi limits: cpu: 500m memory: 256Mi securityContext: allowPrivilegeEscalation: false # 进程不需要写文件系统,静态资源与构建产物都是只读的 readOnlyRootFilesystem: true capabilities: drop: - ALL