1. Pod的资源限制
K8S当中,对于Deployment控制器可以通过sepc.template.spec.containers.resource
配置去对单个容器所使用的资源进行限制。需要注意的是,这里配置的是容器的资源,而不是Pod的资源,因为一个Pod当中可能存在有多个容器。最终配置的格式应该参考如下:
spec:
template:
spec:
containers:
image: ...
imagePullPolicy: IfNotPresent
resources:
requests:
cpu: 100m
memory: 90Mi
limits:
cpu: 100m
memory: 90Mi
可以通过requests
去配置初始申请的CPU和内存资源的量,通过limits
去配置容器允许的最多使用的CPU和内存资源的量。
- 对于CPU,在K8S当中,将一核CPU拆分成为1000m,如果是100m,那么就代表0.1个CPU核心,500m就代表0.5个CPU核心。
- 对于内存,可以使用Mi和Gi单位,例如90Mi、5Gi。
2. HPA自动扩缩容配置
我们现在部署了一个Ingress服务,我们想要实现Ingress-Controller
可以根据机器的负载(比如CPU和内存)进行自动扩容机器,避免Ingress-Controller机器扛不住流量。
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.12.0-beta.0
name: ingress-nginx-controller
namespace: ingress-nginx
spec:
minReadySeconds: 0
revisionHistoryLimit: 10
selector:
matchLabels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
strategy:
rollingUpdate:
maxUnavailable: 1
type: RollingUpdate
template:
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.12.0-beta.0
spec:
containers:
- args:
- /nginx-ingress-controller
- --publish-service=$(POD_NAMESPACE)/ingress-nginx-controller
- --election-id=ingress-nginx-leader
- --controller-class=k8s.io/ingress-nginx
- --ingress-class=nginx
- --configmap=$(POD_NAMESPACE)/ingress-nginx-controller
- --validating-webhook=:8443
- --validating-webhook-certificate=/usr/local/certificates/cert
- --validating-webhook-key=/usr/local/certificates/key
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: LD_PRELOAD
value: /usr/local/lib/libmimalloc.so
image: wanna1314y.top:1443/library/nginx-ingress-controller:latest
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
exec:
command:
- /wait-shutdown
livenessProbe:
failureThreshold: 5
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
name: controller
ports:
- containerPort: 80
name: http
protocol: TCP
- containerPort: 443
name: https
protocol: TCP
- containerPort: 8443
name: webhook
protocol: TCP
readinessProbe:
failureThreshold: 3
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
cpu: 100m
memory: 90Mi
securityContext:
allowPrivilegeEscalation: false
capabilities:
add:
- NET_BIND_SERVICE
drop:
- ALL
readOnlyRootFilesystem: false
runAsGroup: 82
runAsNonRoot: true
runAsUser: 101
seccompProfile:
type: RuntimeDefault
volumeMounts:
- mountPath: /usr/local/certificates/
name: webhook-cert
readOnly: true
dnsPolicy: ClusterFirst
nodeSelector:
kubernetes.io/os: linux
serviceAccountName: ingress-nginx
terminationGracePeriodSeconds: 300
volumes:
- name: webhook-cert
secret:
secretName: ingress-nginx-admission
对于上述我们通过Deployment去部署的Ingress-Controller机器,我们通过如下的配置指定申请CPU的核心数是0.1个核心,内存为90M。我们想要实现,Pod的CPU使用量超过50%时,就自动将Ingress-Controller进行扩容,避免扛不住流量导致挂掉。
resources:
requests:
cpu: 100m
memory: 90Mi
我们可以基于K8S的HPA(HorizontalPodAutoscaler)去实现,我们定义如下的K8S的HPA资源,让ingress-nginx-controller
这个Deployment可以根据CPU的使用情况进行自动扩缩容。
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: ingress-controller-hpa
namespace: ingress-nginx
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: ingress-nginx-controller
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
我们限制最小副本数为2,最大副本数为10,扩容阈值是CPU使用情况超过50%,意味着当机器CPU超过50%时,HPA会自动帮我们进行扩容,当机器CPU使用低于50%时,K8S会帮我们进行缩容,最小只能缩容到2个副本。
K8S的HPA采用的扩缩容策略是,快扩慢缩的机制:
- 快扩:当CPU高于50%时,HPA立刻进行扩容。原因在于,CPU高于50%,意味着流量升高,必须很快把机器扩起来,才能注意应对新增的用户流量。
- 慢缩:当CPU使用率低于50%,HPA不立刻进行缩容,而是会等待一会儿才尝试进行缩容。原因在于,如果立刻根据CPU缩容,那么如果后面又来一个高峰期的流量,剩余的Pod可能是不足以应对流量的,可以暂时将之前扩容起来的Pod留着,等到高峰期已经过去时,再将机器缩容下去。
需要注意的是,在使用HPA之前,必须需要先安装K8S的metrics-server组件,用来支持去采集Node和Pod的CPU和内存使用情况,HPA会根据metrics-server提供的指标,进行HPA的扩容和缩容。
3. 资源限制ResourceQuota
在K8S当中,可以通过ResourceQuota去对单个Namespace的资源进行限制,借助ResourceQuota可以对Namespace下的POD数,CPU核数,内存空间,ConfigMap数量,Secret数量等进行限制。
资源清单参考如下的配置:
apiVersion: v1
kind: ResourceQuota
metadata:
name: ingress-quota
namespace: ingress-nginx
spec:
hard:
pods: 10 # 限制最多 10 个 Pod
requests.cpu: "2" # 总 CPU 请求最多 2 核
requests.memory: "4Gi" # 总内存请求最多 4 GiB
limits.cpu: "4" # 总 CPU 限制最多 4 核
limits.memory: "8Gi" # 总内存限制最多 8 GiB
persistentvolumeclaims: 5 # 限制最多 5 个 PVC
requests.storage: "50Gi" # 总存储请求最多 50 GiB
configmaps: 10 # 限制最多 10 个 ConfigMap
secrets: 10 # 限制最多 10 个 Secret
services: 5 # 限制最多 5 个 Service
services.nodeports: 2 # 限制最多 2 个 NodePort 类型的 Service
services.loadbalancers: 1 # 限制最多 1 个 LoadBalancer 类型的 Service