Pod资源限制
在学习docker的时候我们知道容器可以使用Linux系统的CGroup技术限制内存和CPU的使用率,那么POD应该如何限制容器的CPU和内存资源
资源限制官方文档
https://kubernetes.io/zh/docs/concepts/configuration/manage-resources-containers/
resources 资源的意思
[root@master ~/k8s_yml/resources]# vim nginx-pod.yml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
resources:
requests:
memory: 50Mi
cpu: 100m
limits:
memory: 100Mi
cpu: 500m
request 请求 容器被调度的最低资源
memory 内存
cpu 处理器
limit 极限 容器使用的最高资源
注意:
如果只设置了limits,则requests默认和limits的值是一样的
如果只设置了requests,则limits默认和requests的值是一样的
数值的转换
1 CPU = 1000m
0.5 CPU = 500m
1 Mib = 1024 Kib
1 MB = 1000 KB
pod资源限制创建的pod分三类
有保证的
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
resources:
requests:
memory: 50Mi
cpu: 100m
limits:
memory: 100Mi
cpu: 500m
当一个pod里面起两个容器,有一个资源限制配置不完整也是不稳定
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx-v1
image: nginx:1.14.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
resources:
requests:
memory: 50Mi
cpu: 100m
limits:
memory: 100Mi
cpu: 500m
- name: nginx-v2
image: nginx:1.14.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
resources:
requests:
cpu: 100m
limits:
memory: 100Mi
不稳定的----配了资源限制但是不完整-cpu或内存有一个没有配置--cpu用超了不会被杀掉最多限制,但是内存用超了肯定会被杀掉
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
resources:
requests:
memory: 50Mi
limits:
cpu: 500m
尽最大努力-最不靠墙-最先被杀掉的---就是没有配置pod资源限制
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
HPA介绍
HAP通过收集来的监控指标分析所有Pod的负载情况,并且根据我们设定好的标准来自动扩容收缩 ReplicationController、 Deployment、ReplicaSet 或 StatefulSet 中的 Pod 数量
参考文档
https://kubernetes.io/zh/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/
使用之前要安装一个一个组建,Metrics Server(度量)
设置触发条件
POD cpu超过50%
最大数量:10个
当cpu超过70%,让deployment创建3个pod----》当cpu超过60%,让deployment创建4个pod-----》当cpu超过55%,让deployment创建6个pod------如果降低50%就不创建pod
---------------------------最多只能创建10个pod
测试步骤;
先下载镜像,但是镜像在国外地址
下载完成后
所有的node节点都要导入这个镜像到宿主机上,包括master主机
0.安装Metrics Server
先下载项目的yaml文件
wget https://github.com/kubernetes-sigs/metrics- server/releases/download/v0.4.0/components.yaml
由于默认的镜像是从google云下载的,所以需要一些手段先下载下来,然后再导入本地的节点中。components 组成 ,构成意思
修改配置文件:
spec:
hostNetwork: true #使用host网络模式
containers:
- args:
- --cert-dir=/tmp
- --secure-port=4443
- --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
- --kubelet-use-node-status-port
- --kubelet-insecure-tls #跳过证书检查
image: metrics-server:v0.4.0 #修改本地镜像
imagePullPolicy: IfNotPresent
创建资源:
kubectl apply -f components.yaml
这一块是往apiserver注册一些信息,用我这里面指令,官方写的不需要深究
因为它是namespac(命名空间)资源类型,且属于系统层所以这个命令查看不了
常用的资源类型({$resourceType})有:
po(pod)
ns(命名空间namespace)
instance(实例)
svc(service服务):定义了一个 Pod 的逻辑分组,一种可以访问它们的策略(微服务)。
cm(configMap):存储全局配置变量的,将分布式系统中不同模块的环境变量统一到一个对象中管理。
ds(deamonSet):在每台计算节点上运行一个守护进程(如日志采集等),有时pod处于pending可能是因为某个deamonSet没起来。
deploy(deployment):用于启动(上线/部署)一个Pod或者ReplicaSet。这个如果有问题,那么其他依赖它来部署的资源就肯定不会正常了。
kubectl get 列出资源!
接下来进入正题,首先来了解一下 k8s 中最最最常用的命令kubectl get,要记住,k8s 把所有的东西都抽象成了资源,而kubectl get就是用来查看这些资源的。最常见的资源就是 pod 。
什么是 pod?pod(豆荚)。pod 的概念其实和docker中的容器非常相似。他是 k8s 中的最小工作单位。你可以把 pod 理解成一个一个的小机器人,而 k8s 抽象出来的大资源池就是他们的工厂。
pod 和 docker 容器的关系?pod 将一个或多个docker容器封装成一个统一的整体进行管理并对外提供服务。
不仅我们自己的服务是要包装成 pod 的,就连 k8s 自己也是运行在一堆 pod 上。接下来就让我们查看一下 k8s 的 pod :
kubectl get pod -n kube-system-n参数指定了要查看哪个命名空间下的 pod 。k8s 所有的 pod 都被放置在kube-system命名空间下。
什么是命名空间?命名空间namespace,是 k8s 中”组“的概念,提供同一服务的 pod 就应该被放置同一命名空间下,而不是混杂在一起。k8s 可以用命名空间来做权限控制。如果不指定的话, pod 将被放置在默认的命名空间default下。
在master节点上执行
执行了kubectl get pod -n kube-system命令后,你就可以看到如下内容:
配置清单里面,配置了master节点上运行
1.定制一个压测的镜像
创建目录
mkdir HPA
cd HPA
创建首页文件
cat > index.php << 'EOF'
<?php
$x = 0.0001;
for ($i = 0; $i <= 1000000; $i++) {
$x += sqrt($x);
}
echo "OK!";
?>
EOF
创建dockerfile
cat > dockerfile << 'EOF'
FROM php:5-apache
ADD index.php /var/www/html/index.php
RUN chmod a+rx index.php
EOF
构建镜像
docker build -t php:v1 .
发送到其他节点
docker save php:v1 > php.tar
scp php.tar 10.0.0.11:/opt/
scp php.tar 10.0.0.12:/opt/
并导入镜像
节点导入镜像
docker load < /opt/php.tar
2.创建deployment类型的压测镜像
cat >php-dp.yaml<< 'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: php-apache
spec:
replicas: 1
selector:
matchLabels:
run: php-apache
template:
metadata:
labels:
run: php-apache
spec:
containers:
- image: php:v1
imagePullPolicy: IfNotPresent
name: php-apache
ports:
- containerPort: 80
protocol: TCP
resources:
requests:
cpu: 200m
apiVersion: v1
kind: Service
metadata:
name: php-apache
labels:
run: php-apache
spec:
ports:
-
port: 80
selector:
run: php-apache
EOF
3.创建HPA资源
cat > php-hpa.yaml <<EOF
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: php-apache
spec:
maxReplicas: 10
minReplicas: 1
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: php-apache
targetCPUUtilizationPercentage: 50
EOF
查看所有的资源类型--因为安装了hpa组件
压测步骤:
1.定制一个压测的镜像
2.创建deployment类型的压测镜像
3.创建hpa资源
4.压测
5.观察pod创建情况
kubectl get hpa
kubectl describe hpa php-apache
4.压测
while true; do wget -q -O- http://10.1.138.77; done
IP地址是clusterIP
5.观察POD创建情况
结果:发现创建不能超过10个pod,结束压测就会销毁压测(5分钟左右销毁)
Ingress服务
NodePort缺点
1.没有ingress之前,pod对外提供服务只能通过NodeIP:NodePort的形式,但是这种形式有缺点, 一个节点上的PORT不能重复利用。比如某个服务占用了80,那么其他服务就不能在用这个端口了。
2.NodePort是4层代理,不能解析7层的http,不能通过域名区分流量
3.为了解决这个问题,我们需要用到资源控制器叫Ingress,作用就是提供一个统一的访问入口。工作 在7层
4.虽然我们可以使用nginx/haproxy来实现类似的效果,但是传统部署不能动态的发现我们新创建的 资源,必须手动修改配置文件并重启。
5.适用于k8s的ingress控制器主流的有nginx-ingress和traefik
安装部署nginx-ingress
我们可以直接使用kubernetes官方自带的nginx-ingress控制清单来部署
wget https://raw.githubusercontent.com/kubernetes/ingress- nginx/master/deploy/static/provider/baremetal/deploy.yaml -O nginx- ingress.yaml
3.修改资源配置文件
这里我们主要修改三个地方
1.Deployment类型修改为Demoset类型
2.Pod网络修改为HostPort
3.镜像地址修改为阿里云
294 kind: DaemonSet
323 image: registry.aliyuncs.com/google_containers/nginx-ingress-controller:v0.48.1@sha256:e9fb216ace49dfa4a5983b183067e97496e7a8b307d2093f4278cd550c303899
377 ports:
378 - name: http
379 containerPort: 80
380 protocol: TCP
381 hostPort: 80
382 - name: https
383 containerPort: 443
384 protocol: TCP
385 hostPort: 443
386 - name: webhook
387 containerPort: 8443
388 protocol: TCP
389 hostPort: 8443
390 volumeMounts:
391 - name: webhook-cert
392 mountPath: /usr/local/certificates/
393 readOnly: true
kubectl apply -f nginx-ingrss-20210810.yml
经过查询不在这个命名空间里
但是他有一个专门命名空间
kubectl get pod -n ingress-nginx
先创建一个nginx-dp.yml
[root@master ~/k8s_yml/ingress]# cat nginx-dp.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-dp
labels:
app: nginx-dp
spec:
replicas: 2
selector:
matchLabels:
app: nginx-dp
template:
metadata:
name: nginx-dp
labels:
app: nginx-dp
spec:
containers:
- name: nginx
image: nginx:1.16.0
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
再创建一个nginx-ingress.yaml
[root@master ~/k8s_yml/ingress]# cat nginx-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
spec:
rules:
- host: nginx.k8s.com
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: nginx-svc
port:
number: 80
再次创建一个nginx-svc-cluster.yaml
[root@master ~/k8s_yml/ingress]# cat nginx-svc-cluster.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
labels:
app: nginx-svc
spec:
selector:
app: nginx-dp
ports:
- name: nginx
port: 80
targetPort: 80
type: ClusterIP
图示
window电脑添加host解析
任意一个node节点主机名
浏览器测试访问