Flutter
云原生
心情随笔
Golang
AI编程
技术分享
K8S-常见问题汇总[个人笔记]
type
status
date
slug
summary
tags
category
icon
password
网址
这里写文章的前言:
这个是我的个人笔记,仅做笔记所用,非分享知识类文章……
📝 主旨内容
常见问题汇总:
0.413是proxy-boby小了,需要注释增大
annotations:
nginx.ingress.kubernetes.io/client-max-body-size: 1024m //主要是这个
nginx.ingress.kubernetes.io/limit-connections: "100"
alb-ingress不支持调整,以下配置不对 proxy-connect-timeout默认就5s,读写默认最大600s:requestime有注解调整
alb.ingress.kubernetes.io/proxy-connect-timeout: '30'
alb.ingress.kubernetes.io/proxy-read-timeout: '1800'
alb.ingress.kubernetes.io/proxy-send-timeout: '1800'
nignx配置的报文限制nginx.ingress.kubernetes.io/client-body-buffer-size
alb不支持,默认60G;不支持调整
1.高并发访问ingress域名报错:
502 bad gateway
解决思路:一般出现在svc+后端pod环节,由upstream抛出
kubectl get svc -n kube-system nginx-ingress-lb -oyaml找到slb实例ID:
负载均衡和eip的压力监控看一下
过滤pod和ingress控制器的日志查询502的来源;看看请求的是那个pod;看看podID的pod还在不在
解决方案:升规格或者pod副本增加后再压测;配置hpa
【如果您自行排查,可以按照以下思路先排查下。
- ingress路由502,分析ingress请求日志。根据日志中记录的upstream addr 、uptream response time 以及 upstream status确认到上游业务pod地址 以及 状态。
- 进入上游Pod内检查自身监听,以及请求测试curl 127.0.0.1:port确认上游本身是否正常提供服务。
- 如果上游不正常,从业务层面自行分析debug下; 如果上游正常,检查下集群内所有节点 是否处于集群默认安全组, 集群默认安全组是否有放行Pod网段以及Node网段的所有协议入站允许。】
实验:改svc的targetport ---> 然后看ingress日志,会报502
2.504 gateway timeout问题 是后端响应超时了,建议可以调大一下ingress 的后端超时时间看一下
常用配置:
proxy_connect_timeout 600s; proxy_read_timeout 3000s; proxy_send_timeout 6000s;
nginx.ingress.kubernetes.io/proxy-connect-timeout: "86400"
nginx.ingress.kubernetes.io/server-snippet: |
fastcgi_connect_timeout 30s;
fastcgi_read_timeout 30s;
fastcgi_send_timeout 30s;
https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/https://blog.csdn.net/weixin_41020960/article/details/127123189?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166651766216800184110447%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=166651766216800184110447&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-1-127123189-null-null.142^v59^pc_rank_34_queryrelevant25,201^v3^control_1&utm_term= nginx Annotations的中文版&spm=1018.2226.3001.4187
Connection reset by peer的常见原因及解决办法:
https://cloud.tencent.com/developer/article/1406546
3.503问题:
一般出现在svc之前,也就是ingress抛出;访问请求没有到svc层,排查是否svc后端pod实际没有,所以故障到不了;大多是后端业务不通,可以链路都排查,也看看alb的path问题
alb path要精确匹配的,例如要请求/xx/xx这些资源。path您需要修改为类似 /*就行了
实验:svc后端pod副本为0时:
还有可能是slb规格上限了,导致有被丢弃的请求,需要诊断
4.专有版的master节点api调用报错问题
问题表现
1.客户用yaml文件在某空间下创建ingress报错是:Error from server: error when creating "prometheus-ingress.yaml": Get "https://[::1]:6443/api/v1/namespaces/monitoring/resourcequotas": x509: certificate has expired or is not yet valid: current time 2022-10-24T07:55:30+08:00 is after 2022-06-23T14:24:21Z2.
集群有3个master节点,master01创建ns会报错,而master02创建ns则正常进展:让客户测试了控制台;在default名字空间下创建deploy成功;但在monitoring下失败;然后建议创建一个ns再部署看看;提示创建ns失败报错是6443端口相关问题,但不确实是哪个环节调用apiserver失败
处理方案:在方便的时候将异常master的api组件pod重建,步骤如下
(1) 您登录故障的master节点。在/etc/kubernetes/manifests/ 找到 api server的yaml文件,把它先移动到/root目录下,这样api server pod会临时清理掉 【api组件pod是kubelet启动的】
(2)稍等一分钟左右,再mv移动到/etc/kubernetes/manifests/ 目录下
5.自定义错误页
https://chulinx.github.io/2020/09/18/ingress-Nginx如何自定义错误页面/自定义错误页需要配置注释nginx.ingress.kubernetes.io/server-snippet:string
还需要更改cm的custom-http-errors:加入想要配置的错误码
总结:
- -default-backend-service=ingress-nginx/ssgeek-errors # deployment修改成自定义的默认后端服务 custom-http-errors: 403,404,500,502,503,504 # cm添加此行
6.ip泄漏
低版本的flannel和containerd的节点可能出现ip泄露问题
是否有泄漏可以这么判断 :
● 执行kubectl get pods -A -o wide |grep -i "nodename" |wc -l 统计看看有多少个pod 2
● 然后在/var/lib/cni/networks/cb0 文件里面的IP个数多对比,如果/var/lib/cni/networks/cb0里面多很多,基本就是之前老版本泄漏导致的,可以排水移除节点后再重新加入集群一下【先升级flannel看看是否能解决】
crictl pods | awk '{ print $1 }' | xargs -n1 -I {} bash -c 'echo {};crictl inspectp {} | grep 10.72.125.178 '
crictl inspectp 308d4d3f0fe83 | grep netns
circtl stopp/rmp 停止和删除对应的pod即可
7.节点磁盘压力
磁盘占用最大的可能是临时目录和老旧镜像;前者会在pod重建后失效后者需要清理
● docker清理磁盘的方法是docker system prune实现一键清理
● containerd没有自动清理的方案,只能手动清理,命令参见:https://help.aliyun.com/document_detail/160313.html?spm=5176.21213303.J_6028563670.12.29553edatYxN6I&scm=20140722.S_help%40%40文档%40%40160313.S_0.ID_160313-OR_s%2Bhelpmain-V_1-P0_1
● 另外节点的kubelet是有压力驱逐机制的,默认是写入到了/etc/kubernetes/kubelet-customized-args.conf https://kubernetes.io/zh-cn/docs/concepts/scheduling-eviction/node-pressure-eviction/
8.security context 对nas存储的影响
https://blog.csdn.net/catoop/article/details/119383243https://blog.csdn.net/agonie201218/article/details/122064390?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166730317216782395362689%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=166730317216782395362689&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-2-122064390-null-null.142^v62^pc_search_tree,201^v3^control_1,213^v1^t3_control2&utm_term=securityContext%3A fsGroup%3A 0&spm=1018.2226.3001.4187https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/security-context/
spec:
securityContext: //只能rwonece
fsGroup: 0
此字段是在定义pod内的文件归属组;nas的pvc数据较多时,挂载到pod内会执行chmod;导致pod有临时报错或重启现象
其他操作:
1.如果是主机目录,直接chown改主机目录权限;如果是pv 则fsgroup就好
9.nginx-ingress 获取真实IP
https://help.aliyun.com/document_detail/42205.html?spm=a2c4g.107442.0.i3#section-jcr-plo-9gn
compute-full-forwarded-for: "true"
forwarded-for-header: "X-Forwarded-For"
use-forwarded-headers: "true"
enable-real-ip: "true"
proxy-real-ip-cidr: <您从WAF获取到的回源IP段>
前提:组件的svc对外流量策略为local+
● nginx日志解析:nginx-日志解析
request_time:指的就是从接受用户请求的第一个字节到发送完响应数据的时间,即包括接收请求数据时间、程序响应时间、输出响应数据时间。
upstream_response_time:是指从Nginx向后端php-fpm建立连接开始到接受完数据然后关闭连接为止的时间。
● X-Forwarded-for:https://developer.aliyun.com/article/699074?spm=a2c6h.14164896.0.0.6a004396NKvjTN
ingress透传客户端IP给服务器:
https://help.aliyun.com/document_detail/196889.htm?spm=a2c4g.11186623.0.0.22935bbfuPU9TT#section-ril-3ys-j8u
ingress日志的key-value的采集方案
https://help.aliyun.com/document_detail/184949.html
2.集群前面自建nginx同时还使用了cdn或者waf产品的时候的配置:
https://help.aliyun.com/zh/waf/web-application-firewall-2-0/user-guide/retrieve-the-originating-ip-addresses-of-clients?spm=a2c4g.11186623.0.i3
set_real_ip_from 100.64.0.0/10;作用是防伪造
3.nginx转发到后端加入自己的IP
https://developer.aliyun.com/article/1448517
10.ingress更改端口---即slb增加自定义监听端口 配置成功后的参数:
1.proxy_timeout默认600s;此参数暂时没有找到可更改的地方
2.生效方式:全局和单个路由生效
3.#添加特殊配置片段nginx.ingress.kubernetes.io/configuration-snippet: keepalive_timeout 0;
方案:https://developer.aliyun.com/article/603225
12.ingress限制文件大小
需要配置大小限制和超时时间:
annotations:
kubernetes.io/ingress.class: nginx-dev
不生效原因可能是cdn等前置产品的限制
2.清理请求头,使后端业务pod无法接受到
置空:
nginx.ingress.kubernetes.io/configuration-snippet: |
proxy_set_header User-Agent "";
proxy_set_header Sec-Ch-Ua-Platform "";
清理:
nginx.ingress.kubernetes.io/configuration-snippet: |
more_clear_input_headers "User-Agent" "Sec-Ch-Ua-Platform";
16.跨域问题
alb的标配:
测试命令: curl -I http://alb-xxxxxxxxxxqdbu.cn-beijing.alb.aliyuncs.com -H 'Host: myapp.example.com ' -H 'Origin: https://www.baidu.com' -X GET 【必须有Origin】
alb.ingress.kubernetes.io/cors-allow-credentials: 'true'
alb.ingress.kubernetes.io/cors-allow-headers: >-
DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization
alb.ingress.kubernetes.io/cors-allow-methods: 'PUT, GET, POST, OPTIONS'
alb.ingress.kubernetes.io/cors-allow-origin: 'http://www.52ritao.com'
alb.ingress.kubernetes.io/cors-expose-headers: ''
alb.ingress.kubernetes.io/cors-max-age: '600'
alb.ingress.kubernetes.io/enable-cors: 'true'
nginx配置:
annotations:
nginx.ingress.kubernetes.io/cors-allow-headers: >-
DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization
nginx.ingress.kubernetes.io/cors-allow-methods: 'PUT, GET, POST, OPTIONS'
nginx.ingress.kubernetes.io/cors-allow-origin: ''
nginx.ingress.kubernetes.io/enable-cors: 'true'
nginx.ingress.kubernetes.io/Access-Control-Allow-Origin: ''
nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
nginx.ingress.kubernetes.io/cors-allow-headers: DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Auth
nginx.ingress.kubernetes.io/cors-allow-methods: PUT, GET, POST, DELETE, PATCH,
OPTIONS
nginx.ingress.kubernetes.io/cors-allow-origin: ''
nginx.ingress.kubernetes.io/enable-cors: "true"
https://maomao.ink/index.php/IT/1587.html
如果还报前置请求失败 那就是前端有问题
验证是否生效:curl -I 域名[适用与的场景]
特殊用法:给option的跨域配置返回码
nginx.ingress.kubernetes.io/configuration-snippet: |
if ($request_method = 'OPTIONS') {
more_set_headers 'Access-Control-Allow-Origin: *';
more_set_headers 'Access-Control-Allow-Credentials: true';
more_set_headers 'Access-Control-Allow-Methods: GET, PUT, POST, DELETE, PATCH, OPTIONS';
more_set_headers 'Access-Control-Allow-Headers: DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
more_set_headers 'Access-Control-Max-Age: 1728000';
more_set_headers 'Content-Type: text/plain charset=UTF-8';
more_set_headers 'Content-Length: 0';
return 200;
}
more_set_headers 'Access-Control-Allow-Origin: *';
more_set_headers 'Access-Control-Allow-Credentials: true';
跨域涉及到的注释项
17.ingress支持websocket
18.ingress支持 Websocket的方案
https://segmentfault.com/a/1190000038197038
在 nginx-ingress-controller 中默认已经支持websocket访问,官方文档中说明websocket不需要特别的配置,但需要在注解中配置以下两项:
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
19.节点异常后pod的驱逐时间调整
方案一:https://docs.ucloud.cn/uk8s/bestpractice/taint_base_eviction
方案二:直接控制器里配置就好:在字段terminationGracePeriodSeconds: 30下面加
tolerations:
- effect: NoExecute
key: node.kubernetes.io/not-ready
operator: Exists
tolerationSeconds: 10
- effect: NoExecute
key: node.kubernetes.io/unreachable
operator: Exists
tolerationSeconds: 10
20.常用注解案例:
一.域名跳转
https://www.malema.net/nginx-ingress/annotations/custom-redirection.htmlnginx.ingress.kubernetes.io/server-snippet: rewrite ^.* https://dayanyanglao.com/ 【301】或者
nginx.ingress.kubernetes.io/permanent-redirect: 'https://www.google.com' 【301】
域名跳转案例:
自定义响应头和请求头
nginx.ingress.kubernetes.io/configuration-snippet: |
more_set_headers "Request-Id: $req_id"; //这个是实现自定义响应头
nginx.ingress.kubernetes.io/configuration-snippet: |
proxy_set_header X-Custom-Header "CustomValue"; //这个是实现自定义请求头
nginx.ingress.kubernetes.io/configuration-snippet: |
add_header Cache-Control "no-cache, no-store, must-revalidate"; //这个是实现自定义响应头,说明不缓存
禁用缓存
nginx.ingress.kubernetes.io/configuration-snippet: |
more_set_headers "Cache-Control: no-store";
#开启缓存并设置缓存1小时;此时访问304
nginx.ingress.kubernetes.io/configuration-snippet: |
more_set_headers "Cache-Control: max-age=3600";
对/路径的请求进行不缓存,/路径的建议拿出来单独创建
nginx.ingress.kubernetes.io/configuration-snippet: |
if ($request_uri = "/") {
add_header add_header Cache-Control "private, no-store, no-cache, must-revalidate, proxy-revalidate";
}
总结:nginx.ingress.kubernetes.io/rewrite-target: /实现的是单个ingress内的路径调整;而server-snippet和configuration-snippet是跨ingress跳转
rewrite-target一般只针对不带域名的纯路径跳转;即:
nginx.ingress.kubernetes.io/rewrite-target: /
【实现的是这个ingress的域名+路经访问时依然是访问这个ingress只是改变了path部分;ingress还是这个】
如果是要调整域名【包括域名不变只变path但是要跳到另一个ingress的时候】 则要使用server-snippet
nginx.ingress.kubernetes.io/configuration-snippet: rewrite ^.* /liveindex permanent;
【将/路径的所有请求重定向到/liveindex,此时必须有同域名且path为/liveindex转发的svc和当前配置注解的是同个svc的其他ingress条目,否则报重定向次数过多】
nginx.ingress.kubernetes.io/server-snippet: rewrite ^/a/1.html https://help.baidu.com/search1 permanent;
【访问域名/a/1.html跳到百度的某域名,^表示匹配字符串的开始位置】
nginx.ingress.kubernetes.io/server-snippet: rewrite ^.* https://help.baidu.com/search1 permanent;
【访问域名及域名/url 都跳到指定位置】
nginx.ingress.kubernetes.io/server-snippet: rewrite ^.* https://help.baidu.com/$uri permanent;
【访问域名及域名/url 跳到对应域名后加访问的url】注意:server-snippet不能设置configuration-snippet级别 否则报错
nginx.ingress.kubernetes.io/server-snippet: |
location /logstores/survey-prod/track {
}
【访问域名及域名/logstores/survey-prod/track的请求转发到https://track-mm.ap-southeast-1.log.aliyuncs.com/logstores/survey-prod/track;这个是转发,proxy是转发不是重定向,重定向是不能完成post请求的参数一起重定向的,所以要用proxy,proxy只能用在server下面】
案例:nginx.ingress.kubernetes.io/server-snippet: 'location /insure-yza/1 {proxy_pass https:/IP:port/;}'
nginx.ingress.kubernetes.io/configuration-snippet: |
rewrite ^/stylesheets/(.)$ /app/stylesheets/$1 redirect; # 添加 /app 前缀
rewrite ^/images/(.)$ /app/images/$1 redirect; # 添加 /app 前缀
【添加指定前缀】
其他案例:
【基于源ip做转发】
server {
listen 80;
server_name your_domain.com;
location / {
if ($http_x_forwarded_for = "27.154.235.62") {
proxy_pass http://1.2.3.4;
}}}
【拒绝某个url访问;以及灰度 ~是不区分大小写的正则表达式】
nginx.ingress.kubernetes.io/configuration-snippet: |
if ($request_uri ~ "^/abc.") {
return 403;
}
nginx.ingress.kubernetes.io/service-weight: 'coffee-svc: 100, tea-svc: 100'
【基于域名判断转发】
location /login {
if ($host = 'zelinai.com') {
rewrite ^/(.)$ https://www.zelinai.com/$1 redirect;
}
if ($host != 'www.zelinai.com') {
rewrite ^/(.*)$ https://$host/sso_login redirect;
}
root /home/kangkang.han/work/zelinai/dist;
try_files $uri $uri/ /index.html;
index index.html index.htm;
}
location = / {
if ($host = 'zelinai.com') {
rewrite ^/(.*)$ https://www.zelinai.com/$1 redirect;
}
if ($host != 'www.zelinai.com') {
rewrite ^/(.*)$ https://$host/sso_login redirect;
}
root /home/kangkang.han/work/zelinai/dist;
try_files $uri $uri/ /index.html;
index index.html index.htm;
}
location / {
if ($host ~ 'www\.(.)\.zelinai.com') {
set $host_without_www $1;
rewrite ^/(.)$ https://$host_without_www.zelinai.com/$1 redirect;
}
这个配置的意义是,如果请求的主机名为"www.example.zelinai.com",则将请求重定向到"https://example.zelinai.com",保持URI路径不变。这样可以去除主机名中的"www"前缀。
rewrite ^/(.*)$ https://zelinai.com/$1;
if ($host = 'zelinai.com') {
rewrite ^/(.*)$ https://www.zelinai.com/$1 redirect;
}
root /home/kangkang.han/work/zelinai/dist;
try_files $uri $uri/ /index.html;
index index.html index.htm;
}
整体来说,这个配置的意义是,如果请求的主机名为"zelinai.com",则将请求重定向到"https://www.zelinai.com",保持URI路径不变。同时,配置了根目录和静态文件的查找方式。
对/路径的请求镜像不缓存,/路径的建议拿出来单独创建
nginx.ingress.kubernetes.io/configuration-snippet: |
if ($request_uri = "/") {
add_header add_header Cache-Control "private, no-store, no-cache, must-revalidate, proxy-revalidate";
}
案例:configuration-snippet和server-snippet的作用范围区别:
url跳rewrite到/的时候,需要用configuration-snippet方式,且将path: /单独写;使用server-snippet方式无效
如果是域名代理也可以使用Endpoints方式:
apiVersion: v1
kind: Service
metadata:
name: e1
spec:
ports:
- name: app2 port: 80 clusterIP: None type: ClusterIP
apiVersion: v1
kind: Endpoints
metadata:
name: e1
subsets:
- addresses:
- ip: 153.3.238.102 ports:
- name: app2 port: 443 protocol: TCP
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test
namespace: default
annotations:
nginx.ingress.kubernetes.io/backend-protocol: HTTPS
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/upstream-vhost: www.baidu.com
spec:
ingressClassName: nginx
tls:
- hosts:
- test.laziji.cc
secretName: test.laziji.cc
rules:
- host: test.laziji.cc http: paths:
- pathType: Prefix path: / backend: service: name: e1 port: number: 80
【根据请求终端判断rewrite
● !:表示逻辑非,即不匹配。
● ~:表示进行大小写不敏感的正则表达式匹配。
● nginx的优先级顺序通常是:=、^~、普通字符串、~(区分大小写的正则匹配)、~(不区分大小写的正则匹配)。
案例:请求 /about.jpg,我们可以逐步分析各个 location 规则,以确定匹配的结果。
匹配顺序
根据 NGINX 的匹配顺序,你的配置如下:
location = /api:
精确匹配。如果请求 URI 完全是 /api,则此规则匹配。不匹配 /about.jpg。
location ^~ /images/:
前缀匹配。如果请求 URI 以 /images/ 开头,则此规则匹配。不匹配 /about.jpg。
location /:
普通字符串前缀匹配。该规则会匹配任何以 / 开头的请求,即满足 /about.jpg。
location ~ \.php$:
区分大小写的正则匹配。该规则会匹配任何以 .php 结尾的请求。不匹配 /about.jpg。
location ~* \.jpg$:
不区分大小写的正则匹配。该规则会匹配任何以 .jpg 结尾的请求。虽然它可以匹配 /about.jpg,但由于普通前缀匹配规则(location /)的优先顺序更高,因此该规则不会被执行。
结论
请求 /about.jpg 将匹配 location / 这条规则。因此,响应将是 200 "Default catch-all"。
如果没有 location / 这条规则,那么 /about.jpg 会匹配 location ~* \.jpg$,并返回 200 "Matched JPG files"。但在这里,location / 的优先级更高,因此最终响应将是 200 "Default catch-all"。
因此,!~*可以理解为不进行大小写不敏感的正则表达式匹配。】
21.limitrange和resourcequota问题
● resourcequota是对名字空间进行配额,规定能用多少,其中limitcpu/mem是指该名字空间的pod总的资源limit之和不能超过此值,所以所有pod都需要配置limit值;如果不配置,则默认使用limitrange值
22.ingress支持http2的方法:
https://www.jobcher.com/nginx01/
查看当前域名访问是否是http2的方法有两种:
1.logs查看组件日志
2.开发者工具可以查看
配置方法就是给组件cm添加:use-http2: "true"
https://zhuanlan.zhihu.com/p/372803374
23.节点oom时总pod的资源使用量不高
可以执行echo 3 > /proc/sys/vm/drop_caches清理;但需要先执行sync
https://www.jianshu.com/p/016f7cf0380d
https://developer.aliyun.com/article/749727?spm=a2c9r.12641821.0.0.26c45e3bBrniqf
释放缓存区内存的方法
1、清理pagecache(页面缓存)
[root@localhost ~]#echo 1 > /proc/sys/vm/drop_caches 或者 [root@localhost ~]# sysctl -w vm.drop_caches=1
2、清理dentries(目录缓存)和inodes
[root@localhost ~]# echo 2 > /proc/sys/vm/drop_caches 或者 [root@localhost ~]# sysctl -w vm.drop_caches=2
3、清理pagecache、dentries和inodes
[root@localhost ~]# echo 3 > /proc/sys/vm/drop_caches 或者 [root@localhost ~]# sysctl -w vm.drop_caches=3
这个文件可以设置的值分别为1、2、3。它们所表示的含义为:
echo 1 > /proc/sys/vm/drop_caches:表示清除pagecache。
echo 2 > /proc/sys/vm/drop_caches:表示清除回收slab分配器中的对象(包括目录项缓存和inode缓存)。slab分配器是内核中管理内存的一种机制,其中很多缓存数据实现都是用的pagecache。
echo 3 > /proc/sys/vm/drop_caches:表示清除pagecache和slab分配器中的缓存对象。
25.499状态码
组件日志能看到,是客户端关闭了链接;可以跳过nginx-ignrss,直接访问pod
HTTP 499 (Http Status Code 499) 状态是HTTP协议的一种响应码,是我们请求访问网站时,服务器端返回的4xx 客户端错误系列响应码之一。 状态详细说明:HTTP 499 表示nginx使用非标准状态码。 表明当nginx正在处理请求时,客户端关闭了连接。
26.设置ingres验证访问账号及密码
https://kubernetes.github.io/ingress-nginx/examples/auth/basic/
配置:
annotations:
设置认证类型
关联账号和密码
nginx.ingress.kubernetes.io/auth-secret: basic-auth
显示认证提示信息
nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required for web.nginxbar.org'
验证方法:curl -v http://k8s.qikqiak.com -H 'Host: foo.bar.com' -u 'foo:foo'
27.设置SSL/TLS版本
配置:https://help.aliyun.com/document_detail/196889.html#section-gsi-4n0-lsd
检测命令:
nmap --host-timeout 3000mS --max-rtt-timeout 3000ms --script ssl-enum-ciphers -p 443 47.109.48.109
28.备份问题:
命令:
kubectl get ApplicationBackup -n csdr
kubectl get backuplocation -n csdr
kubectl get applicationrestore -A //恢复任务
describe看backuplocation,是否报backet no ok,这时候应该授权oss权限,然后重建oss-bucket,然后重建仓库
注意bucket的名字需要符合要求
29.kube-proxy问题:
https://blog.frognew.com/2018/12/kubernetes-ipvs-long-connection-optimize.html
1.kube-proxy的模式切换时更改cm后重启组件pod
2.svc暴露的服务如果遇到Connection reset by peer;可能是”客户端----ipvs----客户端“这个ipvs环节出问题了;ipvs环节的超时时间应该比系统内核参数net.ipv4.tcp_keepalive_time长【 vim /etc/sysctl.conf net.ipv4.tcp_keepalive_time = 600 ;sysctl -p】;以ipvs为准
● ipvs的tcptimeout配置长一点,可以避免Connection reset by peer
● ipvs的udptimeout配置短一点,可以避coredns重启导致udp异常问题
● 更改后重启组件pod验证:ipvsadm -l --timeout
● 并且查看是否大于节点内核:sysctl net.ipv4.tcp_keepalive_time net.ipv4.tcp_keepalive_probes net.ipv4.tcp_keepalive_intvl
● 负载算法
rr: round-robin lc: least connection dh: destination hashing sh: source hashing sed: shortest expected delay nq: never queue
30.pod共享内存的默认是64M 提升方法如下
https://ieevee.com/tech/2019/11/10/shm.html#最终的设计
总结:临时目录为内存性质时调度器无法监控到这部分内存 ;建议设置sizelizelimit
巨页(HugePages)挂载不能用mount:
https://blog.csdn.net/wen328/article/details/126411896https://kubernetes.io/zh-cn/docs/tasks/manage-hugepages/scheduling-hugepages/
31.内核优化
net.ipv4.tcp_timestamp=0 如果有一个用户的时间戳大于这个链接发出的syn中的时间戳,服务器上就会忽略掉这个syn,不返会syn-ack消息,表现为用户无法正常完成tcp3次握手,从而不能打开web页面
net.ipv4.tcp_tw_reuse 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认值为0,表示关闭。 该参数对应系统路径为:/proc/sys/net/ipv4/tcp_tw_reuse 0
net.ipv4.tcp_tw_recycle 表示开启TCP连接中TIME-WAIT sockets的快速回收。 该参数对应系统路径为:/proc/sys/net/ipv4/tcp_tw_recycle,默认为0,表示关闭。 提示:reuse和recycle这两个参数是为防止生产环境下服务器time_wait网络状态数量过多设置的
参考问题0002H7TXCX,客户的同节点上的两个pod访问某接口,其中一个总是超时
https://blog.csdn.net/timonium/article/details/120156022?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167940625316800217242213%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=167940625316800217242213&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~pc_rank_34-1-120156022-null-null.142^v75^pc_new_rank,201^v4^add_ask,239^v2^insert_chatgpt&utm_term=net.ipv4.tcp_tw_recyc&spm=1018.2226.3001.4187
32.kubelet无法启动
数据盘使用达到了100%;即/var/lib/container数据满了
这个目录下是containerd/docker kubelet log lost+found 几个目录;引导客户删除了docker目录下所有文件,但是这样会报错;此时必须重启docker才行,需要重建需要的依赖文件;但是更准确的方法应该是看kubelet日志:https://aone.alibaba-inc.com/v2/project/460851/bug/47849183
33.源IP问题
pod内出现某个ip一直在访问业务;需要注意两个点,一是这个记录时真实IP还是xff;真实IP是需要svc的模式是local模式的;cluster模式下,记录的真实IP是pod所在节点的ip;xff会记录每一跳代理的ip,slb的ip也会记录,七层协议的slb在xff内的表现是记录的100网段的两个交替IP
33.Ingress日志收集问题
问题1.post具体请求内容采集,配置$request_body即可
log-format-upstream: $remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $request_length $request_time [$proxy_upstream_name] [$proxy_alternative_upstream_name] $upstream_addr $upstream_response_length $upstream_response_time $upstream_status $req_id $request_body
$request_bodybody部分如果要在sls侧采集 则要修改:
^(\S+)\s-\s\[([^]]+)]\s-\s(\S+)\s\[(\S+)\s\S+\s"(\w+)\s(\S+)\s([^"]+)"\s(\d+)\s(\d+)\s"([^"])"\s"([^"])"\s(\S+)\s(\S+)\s\[([^]])]\s(\S+)(\S+)(\S+)(\S+)(\S+)\s(\S*)\s*\[([^]])\]\s(.*)$
问题2.$request_body获取到的内容是16进制,如何修改正常?
日志改为json格式:
log-format-escape-json: "true"
log-format-upstream: '{"time": "$time_iso8601","remote_addr": "$remote_addr","x-forward-for": "$proxy_add_x_forwarded_for","request_id": "$req_id","remote_user": "$remote_user","bytes_sent": "$bytes_sent","request_time": "$request_time","status": "$status", "req_boby": "$request_body","vhost": "$host","request_proto": "$server_protocol","path": "$uri","request_query": "$args","request_length": "$request_length","duration": "$request_time","method": "$request_method","http_referrer": "$http_referer","http_user_agent": "$http_user_agent"}'
问题2.获取自定义head和cookie字段
log-format-upstream: $remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $request_length $request_time [$proxy_upstream_name] [$proxy_alternative_upstream_name] $upstream_addr $upstream_response_length $upstream_response_time $upstream_status $req_id $request_body $http_<headname> //比如$http_xiejiajia $http_cookie //日志打印cookie内容
会话亲和只需要nginx.ingress.kubernetes.io/affinity:cookie
36.acr命令行获取/v2数据
*获取auth地址: curl -X GET https://xiejiaj-registry.cn-chengdu.cr.aliyuncs.com/v2/_catalog -i
*获取token,用一个值就好:
curl -u "xjj9898@cloud-gts-ylm:99011198Xjj." -k https://dockerauth-cn-chengdu.aliyuncs.com/auth\\?service\\="registry.aliyuncs.com:cn-chengdu:china:cri-l1osl5dm3qwk559t"\\&scope="registry:*/*:*"
- 获取数据 37.高并发响应慢问题【内核优化】 https://maao.cloud/2021/01/15/深入kube-proxy ipvs模式的conn_reuse_mode问题/ node系统参数,可能会有一个坑存在,详细情况是:在高并发、短连接的场景下,kube-proxy ipvs 链接复用引发问题 1.18版本的kube-proxy 会自动关闭内核的conn_reuse_mode 参数,1.20 以后版本的kube-proxy会校验内核版本再关。 由于centos 7.9 用的 3.10 内核,kube-proxy 认为其内核默认是没有这个参数的,所以默认就没有关闭。 解决方法: 1、参考文章里面的步骤,设置一下操作系统内核参数conn_reuse_mode https://github.com/kubernetes/kubernetes/issues/81775 net.ipv4.vs.conntrack=0 net.ipv4.vs.conn_reuse_mode=1 net.ipv4.vs.expire_nodest_conn=1 2、建议节点改成使用Alibaba linux 操作系统(比较推荐这个方案,您可以临时扩容两个aliyun linux的系统,您把程序跑上去,您压测下看看效果)
节点性能优化:
initContainers:
● command:
● /bin/sh
● '-c'
● if [“POD_IP”!="HOST_IP" ]; then
mount -o remount rw /proc/sys
sysctl -w net.core.somaxconn=65535
sysctl -w net.ipv4.ip_local_port_range="1024 65535"
sysctl -w kernel.core_uses_pid=0
fi
env:
● name: POD_IP
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: status.podIP
● name: HOST_IP
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: status.hostIP
image: 'registry-cn-beijing-vpc.ack.aliyuncs.com/acs/busybox:v1.29.2'
imagePullPolicy: IfNotPresent
name: init-sysctl
参数一知半解瞎解释:
net.ipv4.vs.conntrack=0 忽略重传,不会产生1s延迟
net.ipv4.vs.conn_reuse_mode=1 继续端口复用
net.ipv4.vs.expire_nodest_conn=1 控制结束和drop
kernel.core_uses_pid=0 控制core文件的文件名是否添加pid作为扩展
net.core.somaxconn=65535 表示socket监听(listen)的backlog上限,默认为128
net.ipv4.ip_local_port_range = 1024 65535 对外连接端口范围,默认为32768-61000
详解kube-proxy的优雅下线逻辑:
当net.ipv4.vs.conn_reuse_mode=0时,ipvs不会对新连接进行重新负载,而是复用之前的负载结果,将新连接转发到原来的rs上;当net.ipv4.vs.conn_reuse_mode=1时,ipvs则会对新连接进行重新调度。当net.ipv4.vs.conn_reuse_mode=1时,根据ip_vs_in()的处理逻辑,当开启了net.ipv4.vs.conntrack时,会DROP掉第一个SYN包,导致SYN的重传,有1S延迟
net.ipv4.vs.expire_nodest_conn,用于控制连接的rs不可用时的处理。在开启时,如果后端rs不可用,会立即结束掉该连接,使客户端重新发起新的连接请求;否则将数据包silently drop,也就是DROP掉数据包但不结束连接,等待客户端的重试
net.ipv4.vs.conntrack=0
net.ipv4.vs.conn_reuse_mode=1
net.ipv4.vs.expire_nodest_conn=1
https://blog.csdn.net/alex_yangchuansheng/article/details/116725192?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522168199888616800180678133%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=168199888616800180678133&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-1-116725192-null-null.142^v85^pc_search_v2,239^v2^insert_chatgpt&utm_term=conn_reuse_mode&spm=1018.2226.3001.4187https://blog.csdn.net/zhangxueleishamo/article/details/121418602?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522168200074916800222821168%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=168200074916800222821168&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-1-121418602-null-null.142^v85^pc_search_v2,239^v2^insert_chatgpt&utm_term=kernel.core_uses_pid&spm=1018.2226.3001.4187
38.自定义rbac权限案例:
https://kubernetes.io/zh-cn/docs/reference/access-authn-authz/rbac/
相关命令:
kubectl api-versions 获取版本,v1可省略不写
kubectl api-resources -owide 获取资源对象
verb内容:[createdelete deletecollection get list patch update watch]
39.内存问题
内存差异:
https://www.alibabacloud.com/help/zh/arms/application-monitoring/memory-metrics
container_memory_working_set_bytes是容器真实使用的内存量,也是资源限制limit时的重启判断依据
promethous监控显示的use=rss+cache
案例:查看一个容器占用的内存
crictl ps | grep centos
crictl inspect 容器id | grep -i pid
cat /proc/容器进程id/cgroup | grep memory
cat /sys/fs/cgroup/memory/xxxxxxxxx(上面过滤的地址)
1.top的mem%是进程占用系统内存的百分比;这里的系统内存可以通过free -h或cat /proc/meminfo查看
2.buff/cache较大 需要怎么排查:
vmstat -s查看 "pages" 和 "PageTables" 相关的信息,如果这些数值过大,可能说明系统在使用大量
缓存和缓冲区。如果这些数值过大,可以尝试调整系统的内核参数来限制缓存和缓冲区的使用。
3.手动释放缓存和缓冲区:sudo sync && sudo sysctl -w vm.drop_caches=3[清理后top pod就减小了]
kubectl top pod命令查询到的Memory Usage = Memory WorkingSet = memory.usage_in_bytes - memory.stat[total_inactive_file]。
然后可参考Prometheus比对;这里需要注意Prometheus的监控数值:
total_cache + total_rss + memory.kmem.usage_in_bytes = memory.usage_in_bytes
Prometheus的rss和wss区别就在于wss加了缓存的,top pod看到的就是wss;kubelet禁用了kmem特性的话,则memory.kmem.usage_in_bytes应该为0才对
https://z.itpub.net/article/detail/8D5D8B8F3B0BC25B956577305BA7F8A2
Prometheus监控节点和pod都没有缓存数据;这部分
kubectl get pod -Aowide | grep cn-hangzhou.172.16.21.16 | awk -F " " '{print $1, $2}' | while read -r namespace podname; do kubectl -n "$namespace" top pod "$podname"; done|grep -v MEMORY|awk '{sum += $2} END {print sum}'得到的值与节点可用量比值就是Prometheus的监控值;但实际节点侧数据是大于这个的
1.java内存排查案例:
启动参数:ps -aux
但是pod报错137后没有采集到dump日志
排查发现是Xmx写大了,实际oom时jvm没有异常
oom问题 有点复杂 做了一下观察和总结 供您参考:
1.您指定的参数java -javaagent:/usr/local/skywalking-agent/skywalking-agent.jar=agent.service_name=nuohui-tower,collector.backend_service=skywalking-oap.skywalking.svc.cluster.local:11800 -Xmx1500m -XX:MaxPermSize=128M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/oom/dump-nuohui-tower.hprof -jar /usr/local/LIMS/nuohui-tower.jar 这个指定了-Xmx1500m 所以您的业务应该是堆内存使用超过1500m之后就会触发oom信号 产生dump文件
2.此时您的业务通过1号进程可以看到真实使用内存是VmRSS: 603828 kB;但是这个不光是堆内存;它是此时该进程实际使用的物理内存量,包括了 Java 堆(Heap)、元数据(元空间 MetaSpace 或永久代 PermGen,取决于 Java 版本)、栈(Stack)等3.所以要准确知道堆内存才行;借助jstat -gc 命令可以看到如图数据 其中堆的使用量为:S0U + S1U + EU + OU = 0.0 + 8308.9 + 57092.4 + 164496.1 = 228897.4 KB (堆的当前使用大小);也就是您此时VmRSS: 603828 kB;堆内存却只占了228897.4 KB ;所以您之前设置限制Xmx为500M的时候 您的rss可能已经超了 但堆还没超呢;HeapDump是要堆内存异常才会触发;所以之前没触发正常的总结:您需要多测试下;在频发oom时登入pod内找到实际oom前堆内存使用情况;不然只是指定Xmx但实际不知道使用了多少;就不知道为啥没dump文件了 感谢
另外:启动命令设置的jvm参数在 -jar的后面,需要调整到前面才行
40.nginx反向代理动态解析
41.用sa访问kubeconfig
1.如果是专有版集群,集群的master的/etc/kubernetes/pki 下面有公钥/私钥/ca证书,直接使用即可
参考命令:curl --cacert ca.crt --cert apiserver.crt --key apiserver.key https://$server/api
2.可以通过使用ClusterRoleBinding:admin中用到的sa的token访问集群,可以kubectl get clusterrolebinding admin -oyaml获取到
但是1.24的集群默认没有自动生成token,用sa手动生成就好
kubectl apply -f 1.yalm
apiVersion: v1
kind: Secret
metadata:
name: admin-kubeapi
namespace: kube-system
annotations:
kubernetes.io/service-account.name: "admin"
type: kubernetes.io/service-account-token
data:
然后再使用token验证:
kubectl get secret admin-kubeapi -n kube-system -o jsonpath={".data.token"} | base64 -d
curl -k -H "Authorization: Bearer $token" https://$server/apihttps://developer.aliyun.com/article/672460
43.hpa指标问题
延长就绪探测的init 资源使用稳定再探测 可行
https://imroc.cc/k8s/best-practice/hpa-velocity/https://developer.aliyun.com/article/1061326
● --horizontal-pod-autoscaler-initial-readiness-delay默认值为 30 秒;是给pod就绪的30s时间 //已经废弃
新版本集群加个这个参数minReadySeconds: 30 这个能让hpa在pod就绪最低多长时间开始探测 ;同时建议readness的init设置长一些让业务真正就绪
sync-period 是指伸缩器每隔一定时间自动检查 CPU 使用率是否符合要求,用于自动调整 Pod 数量。
initialization-period 是指伸缩器在启动时等待一定时间以获取足够的 CPU 使用率数据,以便更准确地调整 Pod 数量。
以上都是kcm上调整;但实际托管版不支持调整
hpa自身去配置;yaml里设置:
44.coredump采集
45.svc使用ipv6的slb:
46.pod使用自建nfs
常见报错1:Operation not permitted 这个可以在服务器上mount 43.143.99.36:/home/k8s-nfs /tmp测试;应该也会报这个错;这个需要到nfs服务器 cat /etc/exports检查下 如果是(rw,sync,no_root_squash)则不对,因为 nfs 默认配置选项是 secure,不允许客户端通过非特权端口访问。如果客户端必须要 mount -o noresvport 访问,那么就需要 nfs 服务器配置允许非特权端口访问。需要修改 /etc/exports,设置 insecure 选项。正确配置:
cat /etc/exports
/home/k8s-nfs *(rw,sync,insecure)
然后exportfs -r使配置生效
常见报错2:describe pod报错No such file or directory;则是pv的挂载点不是/etc/exports内已有的挂载点
apiVersion: apps/v1
kind: Deployment
metadata:
name: nfs-busybox
spec:
replicas: 1
template:
metadata:
labels:
name: nfs-busybox
spec:
containers:
- name: busybox
image: busybox
command:
- sh
- -c
- 'while true; do date > /mnt/index.html; hostname >> /mnt/index.html; sleep $(($RANDOM % 5 + 5)); done'
imagePullPolicy: IfNotPresent
volumeMounts:
- name: nfs
mountPath: "/mnt"
volumes:
- name: nfs
persistentVolumeClaim:
claimName: nfs
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs
spec:
accessModes:
- ReadWriteMany
storageClassName: ""
resources:
requests:
storage: 1Gi
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
nfs:
server: 43.143.99.36
path: "/home/k8s-nfs"
https://blog.csdn.net/Datura_qing/article/details/122987327?ops_request_misc=&request_id=&biz_id=102&utm_term=K8S使用自建nfs&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-2-122987327.142^v88^control_2,239^v2^insert_chatgpt&spm=1018.2226.3001.4187
48.cookie灰度
1.ninx-ingress的灰度:
灰度的新版本svc不能被其他ingress复用,否则流量会进入老版本;同时灰度路由的path必须在老版本的ingress里是包含的,否则新版本存在而老版本不存在的path流量进入老版本后将404;老版本对的path数量无限制;顺序无限制
测试:
2.alb-ingress灰度的配置:
https://help.aliyun.com/zh/ack/ack-managed-and-ack-dedicated/user-guide/advanced-alb-ingress-configurations?spm=a2c4g.11186623.0.0.607892e3gA2RjM#section-h2c-ose-pqh
50.pvc/pv存储监控
查询语句:avg(node_volume_capacity_bytes_available{namespace="shaoke-prod",type="nas",pvc="logstash-logs-1"})<102410241024
51.版本1.26无法pingsvc的slb
1.节点上是ping不通svc的slbIP和clusterIP的;
2.iptables -L --line-numbers | grep -i icmp -C5 然后iptables -D INPUT <规则编号> ;这样删除后就可以节点上ping通slb了但是依然ping不通clusterip
3.pod里面默认是ping不通svc的slb的;除非关了防火墙的第2步骤;或者集群使用了ipvlan模式
4.pod内ping clusterIP 或者svc的域名 都需要先删除规则 否则不通
52.pod使用节点的磁盘空间大小盘查
1.节点看到的这个信息;此处的overlay是联合文件系统类型;指向同一个挂载点,即/ 使用19G是指整个/下使用了19G;
[root@iZ2vca5oa0cov59kjubokbZ k8s.io]# df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 3.7G 0 3.7G 0% /dev
tmpfs 3.7G 0 3.7G 0% /dev/shm
tmpfs 3.7G 6.6M 3.7G 1% /run
tmpfs 3.7G 0 3.7G 0% /sys/fs/cgroup
/dev/vda1 40G 20G 19G 52% /
tmpfs 5.4G 4.0K 5.4G 1% /var/lib/kubelet/pods/72101a8f-cf91-455d-b8c8-8cf9eece4608/volumes/kubernetes.io~secret/addon-token
tmpfs 4.0G 4.0K 4.0G 1% /var/lib/kubelet/pods/939cf75c-6834-43a3-bff0-2a577dd704fc/volumes/kubernetes.io~secret/addon-token
tmpfs 2.0G 4.0K 2.0G 1% /var/lib/kubelet/pods/49d02850-c9cc-44df-865e-6d052dd26656/volumes/kubernetes.io~secret/addon-token
tmpfs 1.9G 12K 1.9G 1% /var/lib/kubelet/pods/237db279-a53a-4375-b3df-edc3386d18d4/volumes/kubernetes.io~projected/kube-api-access-j9q7l
shm 64M 0 64M 0% /run/containerd/io.containerd.grpc.v1.cri/sandboxes/b97ac1dab4a08e28a9da2bccf595c68efafbb63c4fcc43818510d72be9c2c5ad/shm
overlay 40G 20G 19G 52% /run/containerd/io.containerd.runtime.v2.task/k8s.io/b97ac1dab4a08e28a9da2bccf595c68efafbb63c4fcc43818510d72be9c2c5ad/rootfs
tmpfs 5.4G 12K 5.4G 1% /var/lib/kubelet/pods/eea1b562-a531-48ad-bdd5-0cc992be18c4/volumes/kubernetes.io~projected/kube-api-access-dw4vm
shm 64M 0 64M 0% /run/containerd/io.containerd.grpc.v1.cri/sandboxes/6a85bbde59d7a3df731c91f7026819658e01758bba6d06c1feb61e63bb2bedcb/shm
overlay 40G 20G 19G 52% /run/containerd/io.containerd.runtime.v2.task/k8s.io/6a85bbde59d7a3df731c91f7026819658e01758bba6d06c1feb61e63bb2bedcb/rootfs
tmpfs 220M 12K 220M 1% /var/lib/kubelet/pods/baba6cc2-cc1f-4a55-b341-0635ff1e3a4c/volumes/kubernetes.io~projected/kube-api-access-8ps86
shm 64M 0 64M 0% /run/containerd/io.containerd.grpc.v1.cri/sandboxes/78d1144afc3156469f6ff299daf2d5cb46d74b2ed3f19551da30d5bc881ccc51/shm
overlay 40G 20G 19G 52% /run/containerd/io.containerd.runtime.v2.task/k8s.io/78d1144afc3156469f6ff299daf2d5cb46d74b2ed3f19551da30d5bc881ccc51/rootfs
tmpfs 2.0G 12K 2.0G 1% /var/lib/kubelet/pods/49d02850-c9cc-44df-865e-6d052dd26656/volumes/kubernetes.io~projected/kube-api-access-2mtpm
tmpfs 4.0G 12K 4.0G 1% /var/lib/kubelet/pods/939cf75c-6834-43a3-bff0-2a577dd704fc/volumes/kubernetes.io~projected/kube-api-access-f9zd9
overlay 40G 20G 19G 52% /run/containerd/io.containerd.runtime.v2.task/k8s.io/0f2d3ca96caa4e451efdc92978c7e5cd702f7b3f34bbe98df3d34e9b231b2d62/rootfs
shm 64M 0 64M 0% /run/containerd/io.containerd.grpc.v1.cri/sandboxes/1e937793e885b601269bfbca86fd2f86889b6c0c78b1c6c4d0681e0713f5dab9/shm
overlay 40G 20G 19G 52% /run/containerd/io.containerd.runtime.v2.task/k8s.io/1e937793e885b601269bfbca86fd2f86889b6c0c78b1c6c4d0681e0713f5dab9/rootfs
tmpfs 1.0G 12K 1.0G 1% /var/lib/kubelet/pods/0d146822-9cd4-45e0-8fa5-51318ba6e503/volumes/kubernetes.io~projected/kube-api-access-nw7h6
tmpfs 5.4G 12K 5.4G 1% /var/lib/kubelet/pods/72101a8f-cf91-455d-b8c8-8cf9eece4608/volumes/kubernetes.io~projected/kube-api-access-lhmph
shm 64M 0 64M 0% /run/containerd/io.containerd.grpc.v1.cri/sandboxes/4673a6ca91ebff4ae1d9b36b9eb9632a82c352a78f7f9dee3062f2f7813f8b38/shm
shm 64M 0 64M 0% /run/containerd/io.containerd.grpc.v1.cri/sandboxes/0f6158aa4e28c4e0111e309c27f3d4e0d0520ec3686bc0fc10cfeef14ff9a909/shm
overlay 40G 20G 19G 52% /run/containerd/io.containerd.runtime.v2.task/k8s.io/0f6158aa4e28c4e0111e309c27f3d4e0d0520ec3686bc0fc10cfeef14ff9a909/rootfs
overlay 40G 20G 19G 52% /run/containerd/io.containerd.runtime.v2.task/k8s.io/4673a6ca91ebff4ae1d9b36b9eb9632a82c352a78f7f9dee3062f2f7813f8b38/rootfs
overlay 40G 20G 19G 52% /run/containerd/io.containerd.runtime.v2.task/k8s.io/efdc2452cda2aface5ebcb2455067453735938a1bbf13e7a7cf89fb46d5e2514/rootfs
overlay 40G 20G 19G 52% /run/containerd/io.containerd.runtime.v2.task/k8s.io/d902e5e49dc85a9fe83ebe8758f040ddacac80409aa2e1ebd37fa51744b803bf/rootfs
2.要知道具体的pod使用多少
cd /run/containerd/io.containerd.runtime.v2.task/k8s.io/ 然后执行
find . -mindepth 1 -maxdepth 1 -type d -exec du -sh {} \; 此时看到的就是各个容器ID对应的容器运行使用的磁盘大小了;只与/下的大盘查;需要借助du命令去做更细致的排查
3.docker inspect pod-name | grep /var/lib/docker/container看目录,然后执行du -sh /var/lib/docker/containers/<container_id>/
4.PVC通常会被挂载到/var/lib/kubelet/pods/<pod_uid>/volumes/kubernetes.io~<storage_class_name>/<pvc_name>这样的路径下
54.多集群管理
https://kubernetes.io/zh-cn/docs/concepts/configuration/organize-cluster-access-kubeconfig/ 配置环境变量如图 55.coredns自定义正则解析
apiVersion: v1
data:
Corefile: |
.:53 {
errors
health {
lameduck 15s
}
ready
hosts {
192.168.11.14 esb.guaranty.com.cn
192.168.11.12 rating.guaranty.com.cn
192.168.11.12 das.guaranty.com.cn
fallthrough
}
template IN A guaranty.com.cn {
match ^(?!oa|esb|igitfile)\.guaranty\.com\.cn$
answer "{{ .Name }} 60 IN A 192.168.11.12"
fallthrough
}
rewrite配置及正则:
rewrite name suffix .oss-cn-hangzhou.aliyuncs.com. .oss-cn-hangzhou-internal.aliyuncs.com.
56.注册集群
1.自建集群:
下载sealer:wget -c https://sealer.oss-cn-beijing.aliyuncs.com/sealer-latest.tar.gz && tar -xvf sealer-latest.tar.gz -C /usr/bin
一键部署集群:sealer run kubernetes:v1.19.8 --masters 192.168.100.212,192.168.100.209,192.168.100.210 --nodes 192.168.100.211 --user root --passwd 990111Xjj.
一键卸载:sealer delete --all
2.接入注册集群
北京建议集群,通过操作文档一键接入杭州地域注册集群即可
3.测试注册集群使用ccm是否能创建clb类型的svc
结论:不行;svc在cluster模式下,后端服务器只能挂载为后端服务器为云上节点的服务器,只能手动加入ecs到slb后端
4.测试alb-ingress
当ecs的线下节点和alb实例不在同一vpc时,无法使用alb-ingress暴露业务
同一vpc也不行;但是没有事件抛出;总之只能是
58.NLB-获取源ip
https://developer.aliyun.com/article/1448517
1.nlb获取源ip时,客户端是ipv4的时候,配置外部流量策略未local,以及配置注解:service.beta.kubernetes.io/alibaba-cloud-loadbalancer-preserve-client-ip: "on" 就好;
2.当客户端时ipv6的ip访问,需要满足前提条件集群开启了ipv6双栈,nlb也是双栈类型,及有这个注解:
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-ip-version: "DualStack"
然后后端业务监听还得是ipv6监听生效,以上满足后,还需要确认产品支持了没
3.clb的场景也需要加白
可以实现用slb的ipv6访问;但是获取到的源IP是slb的
如果业务可以改造的话,参考:
https://help.aliyun.com/zh/slb/network-load-balancer/use-cases/obtain-client-ip-addresses?spm=a2c4g.11186623.0.0.1db7692aoXKyw8
4.proxy方式需要业务改造
2.nginx在监听中开启 proxy_protocol 同时,可以修改nginx的 proxy set header 真实IP 。
proxy_set_header X-Real-IP $proxy_protocol_addr;
proxy_set_header X-Forwarded-For $proxy_protocol_addr;
如果nginx开启了proxy_protocol 那么客户端不能直接请求nginx了,需要通过类似反向代理的设备,例如nlb clb等等,开启proxy_protocol 的信息,这样nlb把请求转发给nginx的时候 会携带proxy_protocol 的header信息,nginx收到完整的proxy_protocol 后,就可以正常处理请求了,不然的会,直接会影响到业务,也就是咱们遇到的,请求失败。
2.双栈集群nginx-ingress获取真实IPV6客户端地址
问题:IPV6客户端访问ingress时,客户端地址显示为slb的私网地址;非客户端真实ip
解决方法:
1.slb不支持双栈;所以集群在ipv4的基础上还需要有一套ipv6的slb;可以安装另一套nginx-ingress或者多部署一个ipv6的svc后端挂载nginx-ingress组件pod;这个新的svc需要时ipv6的slb;即增加注解:
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-ip-version: ipv6
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-protocol-port: http:80 // 七层SLB会把x_forwarded_for请求头传递给后端
2.然后nginx-ingress的configmap nginx-configuration 里增加:
compute-full-forwarded-for: "true"
forwarded-for-header: "X-Forwarded-For"
use-forwarded-headers: "true"
enable-real-ip: "true"
3.nginx-ingress的configmap nginx-configuration 里增加log-format-upstream: $http_x_forwarded_for ...字段
4.此时ipv6地址请求业务即可获取到真实ip
根因总结:
如图;从nginx-ingress组件使用的ipv6类型的slb侧看到;虽然slb实例是ipv6类型的,但是后端挂载的pod的ip是ipv4的;此时集群是双栈集群,但是ipv6地址并没有挂载到slb后端;这个是产品限制,目前slb还不支持挂载ipv6后端
因此和后端pod实际三次握手的$remote_addr是slb的ipv4私网地址,$remote_addr记录的是实际服务器握手的客户端地址;通过它无法再获取到ipv6客户端地址;所以要借助七层的slb特性;从$http_x_forwarded_for里拿;但是需要注意;$http_x_forwarded_for是可以伪造的
比如:curl -H "X-Forwarded-For: <IP地址>" http://服务器地址
63.argocd操作问题
1.E1129 12:39:22.200218 5354 portforward.go:378] error copying from remote stream to local connection: readfrom tcp4 127.0.0.1:36825->127.0.0.1:38004: write tcp4 127.0.0.1:36825->127.0.0.1:38004: write: broken pipe
是containerd版本已知问题https://github.com/kubernetes/kubernetes/issues/74551
2.argocd login报错:
FATA[0000] cannot find pod with selector: [app.kubernetes.io/name=] - use the --{component}-name flag in this command or set the environmental variable (Refer to https://argo-cd.readthedocs.io/en/stable/user-guide/environment-variables), to change the Argo CD component name in the CLI argocd
客户端版本建议使用v2.8.7版本
3.argocd添加仓库并设置ssh验证信息,ssh-keygen生成密钥对;公钥放github
可以执行ssh -T git@github.com验证
/root/.ssh/id_rsa需要是600权限
argocd repo add git@git.example.com:repos/repo --insecure-ignore-host-key --ssh-private-key-path ~/id_rsa
如果报错:FATA[0006] rpc error: code = InvalidArgument desc = existing repository spec is different; use upsert flag to force update; difference in keys "SSHPrivateKey"
加参数: --upsert
4.git tag -a v1 -m test1 对git commit -m之后的版本打标签
5.git push origin --tags 推送所有标签
1.合并分支:
git branch -a //展示所有分支
//git checkout命令加上-b参数表示创建并切换,相当于以下两条命令
git branch dev //创建分支
git checkout dev //切换分支
git branch -d dev //删除分支
git merge dev //这个是把dev分支内容合并到master分支;执行命令时要在master分支执行
2.克隆指定分支
git clone -b passwordless-auth --single-branch git@github.com:BolajiAyodeji/nextjs-blog.git
3.clone所有分支到本地
git clone https://github.com/xiejiajia1/gitops-demo.git //克隆仓库,默认克隆下来的是master
for i in
git branch -a | grep remote | grep -v HEAD | grep -v master; do git branch --track ${i#remotes/origin/} $i; done //取所有分支并创建本地分支和远程分支的联系
git fetch --all && git pull --all //最后一步将所有分支更新到最新状态4.git push如果一直账号密码错误
.git/config里地址改为ssh地址再push就好
66.ossfs进程形式运行在节点,内存异常问题
ps aux --sort=-%mem | head -n 10 获取占用内存最高的进程,看下是否是ossfs
strace -p pid 进程调用的资源
pmap pid 进程内存分析
ossfs访问bucket的User-Agent是aliyun-sdk-http/1.0()/ossfs1.7.9.1
headobject 是获取元数据
68.flannel的节点上pod跨节点通信要经过安全组的原因
72.eci实例内的资源查看
常规ack节点上执行free和pod执行free数值一致是因为pod共享宿主机的操作系统内核的;但是eci不同
cat /sys/fs/cgroup/memory/memory.stat 这个命令看到的内存使用情况在eci内查看实际是准确的
top 看到的cpu使用情况也是准确的;这里看到的比Prometheus看到的还准确,因为Prometheus实际无法监控内核态的网络IO占用的cpu
74.nas数据
1.如果您得回收策略是retain 则您删除pvc得时候页面会提示您是否关联删除pv 如果一起删除 则数据也就删除了
2.如果回收策略是retain 只删除pvc 不删除pv 则数据还在 后续用得时候创建一个pvc关联这个pv 数据可以继续使用
3.如果回收策略是delete 则删除pvc是默认一起删除pv了 总结:数据留不留 取决于pv留不留 只要pv不在了 数据就不在了 如图是同一nas 只要pv不在 则数据不在
76.grpc部署测试
1.grpc需要开启use-http2: "true"
2.grpc需要注解指定协议:nginx.ingress.kubernetes.io/backend-protocol: "GRPC"
或者将proto文件放置apipost访问
77.poststart异常点
docker节点上,如poststart执行失败,不会影响pod正常创建,是非阻塞的
containerd节点上,如果poststart执行失败,则实际容器在节点上看起来是running的,但是pod的状态是contaierndcreateing
78.监控检查脚本方案:
nohub while true;do curl -I --max-time 3 x.x.x.x:port/path 2>>/tmp/1.txt && sleep 3 ||break;done &
1.ingress登录访问:
https://kubernetes.github.io/ingress-nginx/examples/auth/basic/
或者 nginx.ingress.kubernetes.io/whitelist-source-range: '192.168.8.0/24' 这个注解,您配置到ingress里面,那么这个路由就只能被 192.168.8.0/24 所访问到,其余网段都不行的 注意前提是您nginx-ingress-controller 可以获取到客户端真实IP,如果集群是flannel,那么nginx-ingress-lb的外部流量策略 就不能是cluster cluster 这个外部流量策略,再flannel网络插件下,获取不到真实IP的。
已读
81.代理外部网站
cat 1.yaml
apiVersion: v1
kind: Service
metadata:
name: e1
spec:
ports:
- name: app2 port: 80 clusterIP: None type: ClusterIP
apiVersion: v1
kind: Endpoints
metadata:
name: e1
subsets:
- addresses:
- ip: 153.3.238.102 ports:
- name: app2 port: 443 protocol: TCP
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test
namespace: default
annotations:
nginx.ingress.kubernetes.io/backend-protocol: HTTPS
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/upstream-vhost: www.baidu.com
spec:
ingressClassName: nginx
tls:
- hosts:
- test.laziji.cc
secretName: test.laziji.cc
rules:
- host: test.laziji.cc http: paths:
- pathType: Prefix path: / backend: service: name: e1 port: number: 80 apiVersion: v1 kind: Service metadata: name: pipeline spec: externalName: www.baidu.com type: ExternalName
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/backend-protocol: HTTPS #https 得要这个 http的话这行可以注释掉
nginx.ingress.kubernetes.io/upstream-vhost: www.baidu.com
name: pipeline-ingress
spec:
ingressClassName: nginx
tls:
- hosts:
- a.malema.net secretName: test-ingress-tls rules:
- host: test.laziji.cc http: paths:
- pathType: Prefix path: / backend: service: name: pipeline port: number: 443
84.Nginx缓存问题
nginx资源缓存存不存,存多久:http://www.net-add.com/devops/sre/cdn/29.html
案例:https://help.aliyun.com/zh/cen/how-to-configure-cache-expiration-rules-for-nginx-origin-serversdns
缓存则默认10天:https://qzy.im/blog/2020/03/cache-problem-of-dns-in-nginx/
85.孤儿/僵尸POD处理方案
86.dns解析超时5s问题
非alpine的镜像可以通过 single-request-reope 这个参数解决绝大部分偶发的5s解析抖动问题。
Caused by: io.netty.resolver.dns.DnsNameResolverTimeoutException: [/192.168.0.10:53] query timed out after 5000 milliseconds (no stack trace available) 从这段日志来看有5s偶发超时,一般和A、4A记录并发请求有关。
配置:
Minimum configuration required for DNS resolution
nameserver 8.8.8.8 # Google DNS
nameserver 8.8.4.4 # Google DNS
options timeout:2 attempts:3 rotate single-request-reopen
87.抓包常见报错
TCP out-of-order segment TCP乱序或丢包
2.被标记了“TCP segment of a reassembled PDU”的是分片包,如果中间异常则标记为Previous segment not captured 前一个TCP分段没有抓到
3.TCP Spurious Retransmission TCP虚假重传;可能是服务端未收到上行响应
4.TCP Retransmission TCP重传
5.TCP fast Retransmission TCP快速重传(会看到tcp dup ack #2的请求包)
6.TCP acked unseen segment 反馈ACK指向了一个未知的TCP片段。
88.容器级别视图【决定pod内free看到的资源是否是实例级别的】
89.vue项目, history模式, 添加以下配置后刷新不会404(待验证)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: frontend-beta
namespace: commodity-center
annotations:
nginx.ingress.kubernetes.io/configuration-snippet: |
try_files $uri $uri/ /index.html;
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
ingressClassName: nginx
rules:
- host: nginx.laziji.cc http: paths:
- path: / pathType: Prefix backend: service: name: frontend-beta port: number: 80 90.绑定1024以下端口的pod配置参考nginx-ingress的即可 91.kubelet修改cpuManagerPolicy验证是否生效 参考文档:https://help.aliyun.com/zh/ack/ack-managed-and-ack-dedicated/user-guide/customize-the-kubelet-configurations-of-a-node-pool?spm=a2c4g.11186623.help-menu-search-85222.d_0 修改cpuManagerPolicy为static模式之后;如何验证是否生效 验证步骤: 1.根据文档操作修改kubelet配置后登录节点执行 cat /var/lib/kubelet/cpu_manager_statec 是否为static模式 2.在 Kubernetes 中,Pod 的资源请求和限制(CPU 和内存)可以分为三种类型之一:Guaranteed、Burstable 和 BestEffort。Guaranteed 是最严格的 QoS 类别;只有Guaranteed模式下static才会生效;可查看pod的yaml得qosClass验证当前是什么类型 3.在pod节点上可以crictl ps拿到容器ID后insepect|grep uid 以及grep cgoupsPath 4.然后查看cd /sys/fs/cgroup/cpuset/kubepods.slice/准备查看容器实际绑定的cpu,这个目录下可以看到上述提到的三种类型资源限制都在这里了:Guaranteed、Burstable 和 BestEffort: 5.步骤4目录下的cgroup目录可以执行 systemctl status cri-containerd-75c005da11b7795111ce4104f3d48f623923d8cfaadb9b0f27de66286d90188b.scope 可以看到对应的容器名字 注意: crictl ps -a实际看不到pause容器的;ctr -n k8s.io container ls可以看到 static策略只有节点开启static策略并且pod是guaranteed类型的才可以使用成功
🤗 总结归纳
不总结文章的内容
📎 参考文章
https://dash.cloudflare.com/
https://boce.aliyun.com/home
https://gokratos.dev/docs/intro/design/
https://github.phodal.com/#/chapter/Github漫游指南https://myssl.com/www.laziji.cc?domain=www.laziji.cc&status=q 【证书链】
欢迎您在底部评论区留言,一起交流~
Loading...
Last update: 2025-04-05
一个喜欢瞎折腾的运维人~
你可以这样找到我:
抖音:运维技术手帐
ios商店app:小白单词 / timewell
微信公众号:运维开发手帐