K8S-常见问题汇总[个人笔记]

type
status
date
slug
summary
tags
category
icon
password
网址
😀
这里写文章的前言: 这个是我的个人笔记,仅做笔记所用,非分享知识类文章……
 

📝 主旨内容

常见问题汇总:

0.413是proxy-boby小了,需要注释增大

annotations:
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'

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 【如果您自行排查,可以按照以下思路先排查下。
  1. ingress路由502,分析ingress请求日志。根据日志中记录的upstream addr 、uptream response time 以及 upstream status确认到上游业务pod地址 以及 状态。
  1. 进入上游Pod内检查自身监听,以及请求测试curl 127.0.0.1:port确认上游本身是否正常提供服务。
  1. 如果上游不正常,从业务层面自行分析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;

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.自定义错误页

还需要更改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存储的影响

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.生效方式:全局和单个路由生效

12.ingress限制文件大小

需要配置大小限制和超时时间: annotations:
不生效原因可能是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:
设置认证类型
关联账号和密码
显示认证提示信息
验证方法: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数据

  • 获取数据 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

48.cookie灰度

1.ninx-ingress的灰度: 灰度的新版本svc不能被其他ingress复用,否则流量会进入老版本;同时灰度路由的path必须在老版本的ingress里是包含的,否则新版本存在而老版本不存在的path流量进入老版本后将404;老版本对的path数量无限制;顺序无限制

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:
  • host: test.laziji.cc http: paths:
    • pathType: Prefix path: / backend: service: name: pipeline port: number: 443

84.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类型的才可以使用成功

🤗 总结归纳

不总结文章的内容

📎 参考文章

 
💡
欢迎您在底部评论区留言,一起交流~
helm常用命令和基础概念linux-k8s运维常用命令[个人笔记]
Loading...
目录