Kubernetes 中的 uWSGI 配置
uWSGI configuration in Kubernetes
我是 运行 我的后端,使用 Python 和 Django 与 uWSGI。我们最近将它迁移到 Kubernetes (GKE) 并且我们的 pods 正在消耗大量内存,而集群的其余部分正急需资源。我们认为这可能与uWSGI配置有关。
这是 pods:
的 yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: my-pod
namespace: my-namespace
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 10
maxUnavailable: 10
selector:
matchLabels:
app: my-pod
template:
metadata:
labels:
app: my-pod
spec:
containers:
- name: web
image: my-img:{{VERSION}}
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8000
protocol: TCP
command: ["uwsgi", "--http", ":8000", "--wsgi-file", "onyo/wsgi.py", "--workers", "5", "--max-requests", "10", "--master", "--vacuum", "--enable-threads"]
resources:
requests:
memory: "300Mi"
cpu: 150m
limits:
memory: "2Gi"
cpu: 1
livenessProbe:
httpGet:
httpHeaders:
- name: Accept
value: application/json
path: "/healthcheck"
port: 8000
initialDelaySeconds: 15
timeoutSeconds: 5
periodSeconds: 30
readinessProbe:
httpGet:
httpHeaders:
- name: Accept
value: application/json
path: "/healthcheck"
port: 8000
initialDelaySeconds: 15
timeoutSeconds: 5
periodSeconds: 30
envFrom:
- configMapRef:
name: configmap
- secretRef:
name: secrets
volumeMounts:
- name: service-account-storage-credentials-volume
mountPath: /credentials
readOnly: true
- name: csql-proxy
image: gcr.io/cloudsql-docker/gce-proxy:1.11
command: ["/cloud_sql_proxy",
"-instances=my-project:region:backend=tcp:1234",
"-credential_file=/secrets/credentials.json"]
ports:
- containerPort: 1234
name: sql
securityContext:
runAsUser: 2 # non-root user
allowPrivilegeEscalation: false
volumeMounts:
- name: credentials
mountPath: /secrets/sql
readOnly: true
volumes:
- name: credentials
secret:
secretName: credentials
- name: volume
secret:
secretName: production
items:
- key: APPLICATION_CREDENTIALS_CONTENT
path: key.json
我们正在使用迁移前的相同 uWSGI 配置(当后端在 VM 中执行时)。
K8s 中 运行 uWSGI 是否有最佳实践配置?或者我在这个特定配置中做错了什么?
您在 uwsgi 中激活了 5 个 worker,如果您的应用程序使用延迟加载技术,这可能意味着需要 5 倍的内存(我的建议:在启动时加载所有内容并信任预分叉 check this)。但是,您可以尝试减少工作人员数量,而不是增加线程数量。
此外,您应该放弃最大请求,这会使您的应用每 10 个请求重新加载一次,这在生产环境中是没有意义的 (doc)。如果您遇到内存泄漏问题,请改用 reload-on-rss。
我会做这样的事情,每个工作线程可能更少或更多线程,具体取决于您的应用程序如何使用它(根据生产中每个 pod 的 cpu usage/availability 进行调整):
command: ["uwsgi", "--http", ":8000", "--wsgi-file", "onyo/wsgi.py", "--workers", "2", "--threads", "10", "--master", "--vacuum", "--enable-threads"]
ps:正如 zerg 在评论中所说,你当然应该确保你的应用程序不是 运行 DEBUG 模式,以及低日志输出。
我是 运行 我的后端,使用 Python 和 Django 与 uWSGI。我们最近将它迁移到 Kubernetes (GKE) 并且我们的 pods 正在消耗大量内存,而集群的其余部分正急需资源。我们认为这可能与uWSGI配置有关。
这是 pods:
的 yamlapiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: my-pod
namespace: my-namespace
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 10
maxUnavailable: 10
selector:
matchLabels:
app: my-pod
template:
metadata:
labels:
app: my-pod
spec:
containers:
- name: web
image: my-img:{{VERSION}}
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8000
protocol: TCP
command: ["uwsgi", "--http", ":8000", "--wsgi-file", "onyo/wsgi.py", "--workers", "5", "--max-requests", "10", "--master", "--vacuum", "--enable-threads"]
resources:
requests:
memory: "300Mi"
cpu: 150m
limits:
memory: "2Gi"
cpu: 1
livenessProbe:
httpGet:
httpHeaders:
- name: Accept
value: application/json
path: "/healthcheck"
port: 8000
initialDelaySeconds: 15
timeoutSeconds: 5
periodSeconds: 30
readinessProbe:
httpGet:
httpHeaders:
- name: Accept
value: application/json
path: "/healthcheck"
port: 8000
initialDelaySeconds: 15
timeoutSeconds: 5
periodSeconds: 30
envFrom:
- configMapRef:
name: configmap
- secretRef:
name: secrets
volumeMounts:
- name: service-account-storage-credentials-volume
mountPath: /credentials
readOnly: true
- name: csql-proxy
image: gcr.io/cloudsql-docker/gce-proxy:1.11
command: ["/cloud_sql_proxy",
"-instances=my-project:region:backend=tcp:1234",
"-credential_file=/secrets/credentials.json"]
ports:
- containerPort: 1234
name: sql
securityContext:
runAsUser: 2 # non-root user
allowPrivilegeEscalation: false
volumeMounts:
- name: credentials
mountPath: /secrets/sql
readOnly: true
volumes:
- name: credentials
secret:
secretName: credentials
- name: volume
secret:
secretName: production
items:
- key: APPLICATION_CREDENTIALS_CONTENT
path: key.json
我们正在使用迁移前的相同 uWSGI 配置(当后端在 VM 中执行时)。
K8s 中 运行 uWSGI 是否有最佳实践配置?或者我在这个特定配置中做错了什么?
您在 uwsgi 中激活了 5 个 worker,如果您的应用程序使用延迟加载技术,这可能意味着需要 5 倍的内存(我的建议:在启动时加载所有内容并信任预分叉 check this)。但是,您可以尝试减少工作人员数量,而不是增加线程数量。
此外,您应该放弃最大请求,这会使您的应用每 10 个请求重新加载一次,这在生产环境中是没有意义的 (doc)。如果您遇到内存泄漏问题,请改用 reload-on-rss。
我会做这样的事情,每个工作线程可能更少或更多线程,具体取决于您的应用程序如何使用它(根据生产中每个 pod 的 cpu usage/availability 进行调整):
command: ["uwsgi", "--http", ":8000", "--wsgi-file", "onyo/wsgi.py", "--workers", "2", "--threads", "10", "--master", "--vacuum", "--enable-threads"]
ps:正如 zerg 在评论中所说,你当然应该确保你的应用程序不是 运行 DEBUG 模式,以及低日志输出。