文章目录
- K8s 常见问题处理、答疑
- [1] calico一直处于未就绪状态
- [2] 删除dashboard 一直卡在delete
- [3] k8s-dashboard 修改tocken-ttl避免频繁输入tocken
- [4] kubectl 快捷指令
- [5] 解决UTC时间问题
- [6] kubectl命令自动补全
- [7] kubectl exec进入pod
- [8] 使用hostpath解决容器UTC时间问题
- [9] 如何设置sc为default sc?
- 方法一
- 方法二
- 参考文档
- [10] pod一直pending是什么原因?
- [11] 查看集群整体状态
- [12] kubelet 无法启动原因
- [13] curl 访问k8s API报错
- [14] pod不能解析同namespace的kubernetes的 svc
- [15] 如何查看所有名称空间的所以容器?
- [16] service nodePort 报错
- [17] keepalived + nginx 搭建的高可用k8s集群 nginx为何没有log?
- [18] 有了service 为什么还需要ingress?
- [20] k8s创建的sc中,外部共享需要手动挂载吗?
- [21] k8s pod has unbound immediate PersistentVolumeClaims
- [22] pod readiness probe端口探测失败原因调查?
- [23] nfs权限问题导致的nginx不能访问问题
- [24] pod中的容器如何以root权限启动
- [25] pod 状态一直是CrashLoopBackOff
- CrashLoopBackOff in Kubernetes Pods: Common Causes
- 【26】kube-apiserver日志问题
- 1、开发脚本删除/var/log/kubernetes的日志
- 2、日志轮转工具
- 3、参考
- 【27】 NFS StorageClassName 有大小限制吗?
- 做个实验,nfs 作为sc,其大小限制是否生效?
- 【28】两个nfs sc引发的bug
- describe pvc
- describe pv
- nfs provisioner 版本
- 如何解决呢?
- 【29】startupprobe 和 livenessprobe的区别?
- 【30】Error状态的POD如何修复?
- 【31】如何查看某一个namespace下所有的资源?
K8s 常见问题处理、答疑
[1] calico一直处于未就绪状态
查看未就绪的calico pod 状态
~]#kubectl describe pod calico-node-vjchp -n kube-system
健康检查未通过
Warning Unhealthy 2m6s (x197171 over 22d) kubelet (combined from similar events): Readiness probe failed: 2022-05-19 06:10:31.276 [INFO][598] confd/health.go 180: Number of node(s) with BGP peering established = 0
calico/node is not ready: BIRD is not ready: BGP not established with 10.50.10.22,10.50.10.23
解决1:
ip a 查看k8s集群的ip是哪个网卡
在calico 的containers -> env 中添加如下内容
# Specify interface
- name: IP_AUTODETECTION_METHOD
value: "interface=eth1"
重启calico,问题解决
解决2:
kubectl set env daemonset/calico-node -n kube-system
IP_AUTODETECTION_METHOD=interface=eth1
参考: https://stackoverflow.com/questions/54465963/calico-node-is-not-ready-bird-is-not-ready-bgp-not-established
[2] 删除dashboard 一直卡在delete
问题 : 删除dashboard一直卡在delete,ctrl +c取消之后。执行apply报错。
~]#kubectl delete -f k8s-dashboard.yaml
namespace "kubernetes-dashboard" deleted
serviceaccount "kubernetes-dashboard" deleted
service "kubernetes-dashboard" deleted
secret "kubernetes-dashboard-certs" deleted
secret "kubernetes-dashboard-csrf" deleted
secret "kubernetes-dashboard-key-holder" deleted
configmap "kubernetes-dashboard-settings" deleted
role.rbac.authorization.k8s.io "kubernetes-dashboard" deleted
clusterrole.rbac.authorization.k8s.io "kubernetes-dashboard" deleted
rolebinding.rbac.authorization.k8s.io "kubernetes-dashboard" deleted
clusterrolebinding.rbac.authorization.k8s.io "kubernetes-dashboard" deleted
deployment.apps "kubernetes-dashboard" deleted
service "dashboard-metrics-scraper" deleted
deployment.apps "dashboard-metrics-scraper" deleted
^C
You have mail in /var/spool/mail/root
[root@hadoop100 ~]#
[root@hadoop100 ~]#
[root@hadoop100 ~]#kubectl apply -f k8s-dashboard.yaml
Warning: Detected changes to resource kubernetes-dashboard which is currently being deleted.
namespace/kubernetes-dashboard unchanged
clusterrole.rbac.authorization.k8s.io/kubernetes-dashboard created
clusterrolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
Error from server (Forbidden): error when creating "k8s-dashboard.yaml": serviceaccounts "kubernetes-dashboard" is forbidden: unable to create new content in namespace kubernetes-dashboard because it is being terminated
原因: dashboard的ns一直terminating. 因为dashboard 的spec字段有finalizers。目的是为了防止 volumnes 被意外删除。
~]#kubectl get ns
NAME STATUS AGE
kubernetes-dashboard Terminating 24d
Kubernetes 中的对象删除并不像表面上看起来那么简单,删除对象涉及一系列过程,例如对象的级联和非级联删除,在删除之前检查以确定是否可以安全删除对象等等。这些都是通过称为 Finalizers
(终结器)的 API 对象实现的。
Kubernetes 对象的删除过程
- 发出删除命令后 Kubernetes 会将该对象标记为待删除,但不会真的删除对象,具体做法是将对象的 metadata.deletionTimestamp 字段设置为当前时间戳,这使得对象处于只读状态(除了修改 finalizers 字段)。
- 当 metadata.deletionTimestamp 字段非空时,负责监视该对象的各个控制器会执行对应的 Finalizer 动作,每个 Finalizer 动作完成后,就会从 Finalizers 列表中删除对应的 Finalizer。
- 一旦 Finalizers 列表为空时,就意味着所有 Finalizer 都被执行过了,垃圾收集器会最终删除该对象。
像 ns 这种重要的api-resource 必须要通过Finalizers
来约束。
finalizers 不为空,代表是标记删除,如果置位空则直接删除.
解决:
– 2022年6月8日18:23:48
在etcd中删除
etcdctl del /registry/namespaces/rook-ceph
另外
1、kubectl get ns ingress-nginx -o json > tmp.json
2、删除spec中的Finalizers
字段
3、通过api-server 的restful删除
curl -k -H "Content-Type: application/json" -X PUT --data-binary @tmp.json http://127.0.0.1:8080/api/v1/namespaces/ingress-nginx/finalize
4、ns 被彻底删除
参考: https://kubernetes.io/zh/docs/concepts/overview/working-with-objects/finalizers/
1)运行以下命令以查看处于“Terminating”状态的namespace:
$ kubectl get namespaces
2)选择一个Terminating namespace,并查看namespace 中的finalizer。运行以下命令:
$ kubectl get namespace <terminating-namespace> -o yaml
输出信息如下:
apiVersion: v1
kind: Namespace
metadata:
creationTimestamp: "2019-11-20T15:18:06Z"
deletionTimestamp: "2020-01-16T02:50:02Z"
name: <terminating-namespace>
resourceVersion: "3249493"
selfLink: /api/v1/namespaces/knative-eventing
uid: f300ea38-c8c2-4653-b432-b66103e412db
spec:
finalizers:
- kubernetes
status:
3)导出json格式到文件
$ kubectl get namespace <terminating-namespace> -o json >tmp.json
4)编辑tmp.josn,删除finalizers 字段的值
{
"apiVersion": "v1",
"kind": "Namespace",
"metadata": {
"creationTimestamp": "2019-11-20T15:18:06Z",
"deletionTimestamp": "2020-01-16T02:50:02Z",
"name": "<terminating-namespace>",
"resourceVersion": "3249493",
"selfLink": "/api/v1/namespaces/knative-eventing",
"uid": "f300ea38-c8c2-4653-b432-b66103e412db"
},
"spec": { #从此行开始删除
"finalizers": []
}, # 删到此行
"status": {
"phase": "Terminating"
}
}
5)开启proxy
$ kubectl proxy
执行该命令后,当前终端会被卡住
6)打开新的一个窗口,执行以下命令
$ curl -k -H "Content-Type: application/json" -X PUT --data-binary @tmp.json http://127.0.0.1:8001/api/v1/namespaces/<terminating-namespace>/finalize
7)确认处于Terminating 状态的namespace已经被删除
[3] k8s-dashboard 修改tocken-ttl避免频繁输入tocken
1、向dashboard的yaml中增加args参数
spec:
containers:
- name: kubernetes-dashboard
image: kubernetesui/dashboard:v2.3.1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8443
protocol: TCP
args:
- --auto-generate-certificates
- --token-ttl=432000
2、kubectl apply -f .
[4] kubectl 快捷指令
alias kc='kubectl'
alias kgp='kubectl get pods'
alias kgs='kubectl get svc'
[5] 解决UTC时间问题
很多应用镜像时区都是UTC,而不是本机时间(当然,前提是本机时间是对的,云服务器不存在这个问题)
Pod设置挂载本地时间。
volumeMounts:
- name: localtime
mountPath: /etc/localtime
volumes:
- name: localtime
hostPath:
path: /usr/share/zoneinfo/Asia/Shanghai
[6] kubectl命令自动补全
master节点执行
echo "source <(kubectl completion bash)" >> ~/.bash_profile
source ~/.bash_profile
[7] kubectl exec进入pod
命令格式
kubectl exec pod名称 -n 命名空间 -it -c 容器名称 /bin/sh 在容器内部执行命令
[8] 使用hostpath解决容器UTC时间问题
在镜像中心拉去的镜像,时间基本上都是UTC时间,而我们使用的是CST时间。
没有挂载的时候,默认都是UTC时间
apiVersion: v1
kind: Pod
metadata:
name: busy-box-test
namespace: dev
spec:
restartPolicy: OnFailure
containers:
- name: busy-box-test
image: 10.50.10.185/harbortest/busybox:latest
imagePullPolicy: IfNotPresent
command: ["sleep", "60000"]
使用volumemount localtime 变为CST时间
apiVersion: v1
kind: Pod
metadata:
name: busy-box-test
namespace: dev
spec:
restartPolicy: OnFailure
containers:
- name: busy-box-test
image: 10.50.10.185/harbortest/busybox:latest
imagePullPolicy: IfNotPresent
volumeMounts:
- name: date-config
mountPath: /etc/localtime
command: ["sleep", "60000"]
volumes:
- name: date-config
hostPath:
path: /etc/localtime
[9] 如何设置sc为default sc?
查看sc
[root@k8s-master1 k8s]# kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
nfs-prod nfs-nfs-prod Delete WaitForFirstConsumer false 6d3h
rook-ceph-block rook-ceph.rbd.csi.ceph.com Delete Immediate true 3d19h
创建pv的时候需要声明使用的storageClassName。
方法一
kubectl edit sc nfs-prod
在yaml文件中添加metadata.annotation 字段中添加
storageclass.kubernetes.io/is-default-class: "true"
方法二
kubectl patch storageclass standard -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
其中standard为 sc的名字
查看sc
[root@master1 ~]# kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
nfs-prod (default) nfs-nfs-prod Delete WaitForFirstConsumer false 6d19h
rook-ceph-block rook-ceph.rbd.csi.ceph.com Delete Immediate true 4d11h
参考文档
https://kubernetes.io/zh-cn/docs/tasks/administer-cluster/change-default-storage-class/
[10] pod一直pending是什么原因?
搭建efk的过程中,创建了一个sts, 第一个pod一直pending。
创建高可用es的yaml文件如下
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: es
namespace: logging
spec:
serviceName: elasticsearch
replicas: 3
selector:
matchLabels:
app: elasticsearch
template:
metadata:
labels:
app: elasticsearch
spec:
nodeSelector:
es: log
initContainers:
- name: increase-vm-max-map
image: 10.50.10.185/harbortest/busybox:latest
command: ["sysctl", "-w", "vm.max_map_count=262144"]
securityContext:
privileged: true
- name: increase-fd-ulimit
image: 10.50.10.185/harbortest/busybox:latest
command: ["sh", "-c", "ulimit -n 65536"]
securityContext:
privileged: true
containers:
- name: elasticsearch
image: 10.50.10.185/efk/docker.elastic.co/elasticsearch/elasticsearch:7.6.2
ports:
- name: rest
containerPort: 9200
- name: inter
containerPort: 9300
resources:
limits:
cpu: 1000m
requests:
cpu: 1000m
volumeMounts:
- name: data
mountPath: /usr/share/elasticsearch/data
env:
- name: cluster.name
value: k8s-logs
- name: node.name
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: cluster.initial_master_nodes
value: "es-0,es-1,es-2"
- name: discovery.zen.minimum_master_nodes
value: "2"
- name: discovery.seed_hosts
value: "elasticsearch"
- name: ES_JAVA_OPTS
value: "-Xms512m -Xmx512m"
- name: network.host
value: "0.0.0.0"
volumeClaimTemplates:
- metadata:
name: data
labels:
app: elasticsearch
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 100Gi
describe po的event如下:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 56m default-scheduler 0/5 nodes are available: 5 pod has unbound immediate PersistentVolumeClaims.
Warning FailedScheduling 56m default-scheduler 0/5 nodes are available: 1 node(s) had taint {key2: master2}, that the pod didn't tolerate, 1 node(s) had taint {master1: master1}, that the pod didn't tolerate, 3 node(s) didn't match Pod's node affinity/selector.
Warning FailedScheduling 9m8s (x45 over 55m) default-scheduler 0/5 nodes are available: 1 node(s) had taint {key2: master2}, that the pod didn't tolerate, 1 node(s) had taint {master1: master1}, that the pod didn't tolerate, 3 node(s) didn't match Pod's node affinity/selector.
pending的原因是 : pod还没有调度到任何节点上。因为没有适合的节点,因为是我yaml文件中有nodeSelector ,修改这个nodeSelector为自己的机器即可,或者不指定也可以.
其实这个问题,我一开始被误导了,因为都是warning,我一直在找error,k8s的设计哲学中,认为pod pending只是waring而不是error,这正是声明式API的特征,如果是命令式的,那一定是fail,就会有error/fatal。
所以一直怀疑是sts没有挂上pv的问题,但是经过排查pvc和pv的状态都是好着的。
如果理解了k8s的哲学,那么pod的warning event也要分析。
此外借助dashboard上的warning 可以更快定位
[11] 查看集群整体状态
kubectl cluster-info
[root@master3 /etc/kubernetes]# kubectl cluster-info
Kubernetes control plane is running at https://10.50.10.31:6443
CoreDNS is running at https://10.50.10.31:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
查看组件健康状态
[root@master3 /etc/kubernetes]#kubectl get componentstatuses
Warning: v1 ComponentStatus is deprecated in v1.19+
NAME STATUS MESSAGE ERROR
scheduler Healthy ok
controller-manager Healthy ok
etcd-2 Healthy {"health":"true"}
etcd-0 Healthy {"health":"true"}
etcd-1 Healthy {"health":"true"}
[12] kubelet 无法启动原因
docker和k8s的 cgroupdriver必须一致才能启动.
vi /etc/docker/daemon.json
{
"registry-mirrors": ["https://10.50.10.185"],
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
}
[13] curl 访问k8s API报错
验证高可用集群时
[root@master1 /etc/kubernetes]#curl -k https://10.50.10.31:6443/version
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {},
"status": "Failure",
"message": "Unauthorized",
"reason": "Unauthorized",
"code": 401
}
解决:
401 权限不足,报错已经说的很明显了。关于k8s的鉴权是一个比较复杂的事情,按照我的理解简答解释一下:
当client 访问k8s 资源时,需要经历 认证、授权、准入控制三个步骤。
很明显是第一个步骤出了问题。
[root@master1 /etc/kubernetes]#curl --header "Authorization: Bearer $TOKEN" --insecure -X GET $APISERVER/version
{
"major": "1",
"minor": "23",
"gitVersion": "v1.23.8",
"gitCommit": "a12b886b1da059e0190c54d09c5eab5219dd7acf",
"gitTreeState": "clean",
"buildDate": "2022-06-16T05:51:36Z",
"goVersion": "go1.17.11",
"compiler": "gc",
"platform": "linux/amd64"
https://www.cnblogs.com/dudu/p/14485314.html
curl 操作k8s的api
https://www.jianshu.com/p/0a5976ce1ce4
[14] pod不能解析同namespace的kubernetes的 svc
同一个ns,不同pod的是否可以通过svc的域名访问?
[root@master1 /var/log/kubernetes]#kubectl get po
NAME READY STATUS RESTARTS AGE
busybox 1/1 Running 0 18m
[root@master1 /var/log/kubernetes]#kubectl get svc kubernetes
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 2d20h
[root@master1 /var/log/kubernetes]#kubectl exec busybox -n default -- nslookup 10.96.0.1
Server: 10.96.0.2
Address: 10.96.0.2:53
1.0.96.10.in-addr.arpa name = kubernetes.default.svc.cluster.local
[root@master1 /var/log/kubernetes]#
[root@master1 /var/log/kubernetes]#kubectl exec busybox -n default -- nslookup kubernetes
Server: 10.96.0.2
Address: 10.96.0.2:53
** server can't find kubernetes.default.svc.cluster.local: NXDOMAIN
*** Can't find kubernetes.svc.cluster.local: No answer
*** Can't find kubernetes.cluster.local: No answer
*** Can't find kubernetes.default.svc.cluster.local: No answer
*** Can't find kubernetes.svc.cluster.local: No answer
*** Can't find kubernetes.cluster.local: No answer
command terminated with exit code 1
[15] 如何查看所有名称空间的所以容器?
使用 -o jsonpath={..image}
参数,输出结果将格式化为只包含容器镜像名字的形式。该参数将递归地查找 JSON 数据中所有 image
字段,例如:
kubectl get pods --all-namespaces -o jsonpath={..image}
使用工具 tr
、sort
、uniq
格式化输出结果
- 使用
tr
将空格替换为新的行 - 使用
sort
对结果排序 - 使用
uniq
对镜像使用计数
kubectl get pods --all-namespaces -o jsonpath="{..image}" |\
tr -s '[[:space:]]' '\n' |\
sort |\
uniq -c
用 Pod 中 image 字段的绝对路径来查找容器的镜像名字,可以规避 image 字段重复出现的情况。
kubectl get pods --all-namespaces -o jsonpath="{.items[*].spec.containers[*].image}"
sonpath 的解析如下:
.items[*]
:每一个返回值.spec
: 获取 spec.containers[*]
: 每一个 container.image
:获取 image
注意
如果通过名字查找 Pod,例如
kubectl get pod nginx
,由于返回结果只有一个 Pod,此时,.items[*]
这一部分应该从 jsonpath 中移除。
[16] service nodePort 报错
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: dev
spec:
type: NodePort
ports:
- port: 80
protocol: TCP
targetPort: 80
nodePort: 30008
selector:
app: nginx
[root@master1 /opt/kubernetes/k8s/configmap]#kubectl apply -f nginx-cm-po-svc.yaml
The Service "nginx" is invalid: spec.clusterIPs[0]: Invalid value: "None": may not be set to 'None' for NodePort services
原因是svc重名了。 那个svc是clusterip:none。报错 直接说svc已存在不就好了么 。 K8s的这个报错真的是醉了。 或许是对其设计哲学理解太浅薄了吧
[root@master1 /opt/kubernetes/k8s/configmap]#kubectl get svc -n dev
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx ClusterIP None <none> 80/TCP 8d
[17] keepalived + nginx 搭建的高可用k8s集群 nginx为何没有log?
这个问题暂时还不知道是什么原因?
[18] 有了service 为什么还需要ingress?
- Service可以使用NodePort暴露集群外访问端口,但是性能低下不安全。 ingress 不用开nodeport,外部无法感知这个服务. ,端口方面很安全.
- 缺少Layer7的统一访问入口(可以理解为网关),可以负载均衡(基于7层的可以拆解包,例如vip用户访问哪些pod,普通用户访问哪些pod。这种负载在svc是无法完成的)、限流等
- Ingress 公开了从集群外部到集群内服务的 HTTP 和 HTTPS 路由。 流量路由 Ingress 资源上定义的规则控制。
- 我们使用Ingress作为整个集群统一的入口,配置Ingress规则转到对应的Service
update 2022年10月11日18:10:41
安装zk、kafka、rabbitmq外部访问的方式目前都是svc的nodeport方式。这种方式很不方便特别是对于需要暴露多个端口的rabbitmq来说极为不方便。
如何把ingress 用起来呢?
《kubernetes进阶实战》 16.2.1 说到:
若需要在Kubernetes集群之外访问Elasticsearch服务,建议为Elasticsearch集群启用认证功能之后修改协调器Service的类型为NodePort或LoadBalancer,或者使用Ingress将该服务暴露至Kubernetes集群外部。
Kubernetes on EKS - coredns vs external-dns
Can anyone explain the difference between these two components, please?
In our (undocumented) cluster I can see there is a kube-dns service, a coredns deployment with 2 replicas, and an external-dns deployment with 1 replica.
The kube-dns service has a ClusterIP for traffic into port 53 - and this is the port the coredns pods listen on.
I assume therefore the backend DNS within the cluster is handled via a combination of both the kube-dns service and the coredns pods.
Where does external-dns fit in?
What is the difference between these 3 components?
答案:
Core-DNS is the internal DNS service used by the cluster’s resources. It’s the component which registers pod/service DNS names. This is considered a critical component of Kubernetes.
https://coredns.io/plugins/kubernetes/
External-DNS is an add-on component which allows the deployment of DNS records in external DNS services such as Route53 based on the host field within ingress resources deployed to the cluater.
https://github.com/kubernetes-sigs/external-dns
[20] k8s创建的sc中,外部共享需要手动挂载吗?
k8s 使用nfs sc做动态存储。 pod所在主机需要挂载nfs吗?
答: 不需要,sc 会自动创建pv池。这个过程sc会自己去挂载到指定挂载点
nfs-subdir-external-provisioner是一个自动配置卷程序,它使用现有的和已配置的 NFS 服务器来支持通过持久卷声明动态配置 Kubernetes 持久卷
存储组件 NFS subdir external provisioner 是一个存储资源自动调配器,它可用将现有的 NFS 服务器通过持久卷声明来支持 Kubernetes 持久卷的动态分配。自动新建的文件夹将被命名为 n a m e s p a c e − {namespace}- namespace−{pvcName}-${pvName} ,由三个资源名称拼合而成。
[21] k8s pod has unbound immediate PersistentVolumeClaims
安装nexus,使用nfs sc。
使用managed-nfs-storage就没问题,使用另外一个就有问题。另外一个sc是通过kuboard创建的。
- 这个问题还要继续追踪为何sc不可用…
update 2022年10月11日14:31:55
启动pod报错:
pvc的waring:
waiting for a volume to be created, either by external provisioner "k8s-sigs.io/nfs-subdir-external-provisioner" or manually created by system administrator
pod的warning
为何sc会无法为pod自动绑定pv呢?检查了一下pvc没有任何问题。
解决: nfs-client-provisioner pod消失导致无法正常为pod绑定存储。手残不小心删掉了,我启动的pod名字和那个太像啦。最好将其部署为deploy且多个副本
nfs-subdir-external-provisioner是一个自动配置卷程序,它使用现有的和已配置的 NFS 服务器来支持通过持久卷声明动态配置 Kubernetes 持久卷
存储组件 NFS subdir external provisioner 是一个存储资源自动调配器,它可用将现有的 NFS 服务器通过持久卷声明来支持 Kubernetes 持久卷的动态分配。自动新建的文件夹将被命名为 n a m e s p a c e − {namespace}- namespace−{pvcName}-${pvName} ,由三个资源名称拼合而成。
参考问题[20]
[22] pod readiness probe端口探测失败原因调查?
问题: 安装nexus仓库时pod 的8081 端口一直访问不通
Readiness probe failed: Get "http://10.244.166.156:8081/": dial tcp 10.244.166.156:8081: connect: connection refused
探测的yaml
readinessProbe:
failureThreshold: 6
httpGet:
path: /
port: 8081
scheme: HTTP
initialDelaySeconds: 30
periodSeconds: 30
successThreshold: 1
timeoutSeconds: 10
解决: 这个问题的原因是超过了initialDelaySeconds的时间导致探测失败,适当调大这个参数,或者重启一下就好了。
[23] nfs权限问题导致的nginx不能访问问题
有两个sc,一个是nfs svr称为A sc,另外一个是nas存储称为B sc。
nas存储的sc nginx无法访问,报错是没有权限。
在A sc上创建nginx的index.html可以正常访问
在B sc上创建则无法访问没提示权限不足(“/usr/share/nginx/html/index.html” is forbidden (13: Permission denied))
[24] pod中的容器如何以root权限启动
containers:
- name: ...
image: ...
securityContext:
runAsUser: 0
helm chart中是runAsUser。 0代表root
[25] pod 状态一直是CrashLoopBackOff
今天启动rabbitmq的时候pod一直启动不起来。状态一直是CrashLoopBackOff ,无从下周。
pod状态流转图,个人感觉这个状态的pod最不好查问题。
CrashLoopBackOff in Kubernetes Pods: Common Causes
The CrashLoopBackOff
error can be caused by a variety of issues, including:
- Insufficient resources—lack of resources prevents the container from loading
- Locked file—a file was already locked by another container
- Locked database—the database is being used and locked by other pods
- Failed reference—reference to scripts or binaries that are not present on the container
- Setup error—an issue with the init-container setup in Kubernetes
- Config loading error—a server cannot load the configuration file
- Misconfigurations—a general file system misconfiguration
- Connection issues—DNS or kube-DNS is not able to connect to a third-party service
- Deploying failed services—an attempt to deploy services/applications that have already failed (e.g. due to a lack of access to other services)
https://komodor.com/learn/how-to-fix-crashloopbackoff-kubernetes-error/
【26】kube-apiserver日志问题
api-server的日志已经指向了目录,怎么还会在message中打印log呢
如何解决kube-apiserver日志轮转的问题。
对于这个问题目前的解决方法:
ansible k8s-all -m shell -a "find /var/log/ -maxdepth 1 -name 'messages-*' -type f -mtime +1 -print | xargs -I GG rm -rf GG
1、开发脚本删除/var/log/kubernetes的日志
这里脚本删除的时候需要注意一定不能按照时间一刀切的删除,要保留最近几个日志,因为有的日志可能很久都不更新。
#!/bin/bash
#==============================================================#
# File : clean-k8s-component--log
# Ctime : 2022年8月10日13:12:22
# Mtime : 2022年8月10日13:12:27
# Usage : clean k8s log
# author : ninesun
#==============================================================#
rm -rf >/tmp/no_clean_log.log
for log in `ls -l /var/log/kubernetes | grep lrw |awk '{print $9}'`;do
#no_clean_log=`stat /var/log/kubernetes/${log} | awk 'NR==1'|awk '{print $4}' | tr -d "‘"`
no_clean_log=`readlink /var/log/kubernetes/${log}`
echo ${no_clean_log} >> /tmp/no_clean_log.log
done
no_clean_log_foramt=`sed -r ':a;N;s/\n/|/;ba;' /tmp/no_clean_log.log`
find_list=`find /var/log/kubernetes/ -type f -mtime +1 -print`
echo ${find_list} |tr ' ' '\n'| egrep -v ${no_clean_log_foramt} | xargs -I GG echo "rm -rf GG"|bash
2、日志轮转工具
日志轮转工具 logrotate
/etc/logrotate.d more syslog
/var/log/cron
/var/log/maillog
/var/log/messages
/var/log/secure
/var/log/spooler
{
missingok
rotate 2 # 增加rotate 为2
sharedscripts
postrotate
/bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
endscript
}
执行 logrotate -f /etc/logrotate.d/syslog 结果
3、参考
【27】 NFS StorageClassName 有大小限制吗?
2022/10/30 因下游消费者异常 rabbirmq 消息发生大量堆积,直接把nfs server的空间撑爆了。
stroageClass限制的是50GB,怎么会把nfs 撑爆呢?难道这个限制根本限不住?
做个实验,nfs 作为sc,其大小限制是否生效?
【28】两个nfs sc引发的bug
集群初建时使用了一个较小的nfs svr作为k8s的后端存储,随着业务数量的增多, 新搭建了一个大的nfs server,共10TB。
在迁移业务时发现了意料之外的bug.
我的操作步骤是这样的:
step1 : 修改旧的 yaml部署文件中的storageclassname
step2: 删除旧的rabbitmq集群 (没有删除pvc.) -> 初步推测问题出在这一步,
step3:启动新的集群(启动新的sc作为后端存储)
问题: 新的nfs 存储上有建立pvc文件夹,但问题是没数据
这是什么原因呢?
经过调查发现, 两个sc 在 两个NFS svr 都创建了以pvc name 命名的文件夹, 数据还是存储在旧的上面. 新的sc 动态建立的文件夹是空的。 感觉好像如果是多个nfs 时nfs provisioner有bug.
如何解决呢?
将旧的sc 创建的pv 都删掉,nfs上以pvc 创建的文件夹名字也删掉。使用新的sc重新。
怪异的事情发生了,两个po 竟然的pv竟然分散在两个nfs上. (难道是智能高可用)
[root@node3 ~]#df -h | grep -E '179|184' | grep -i rabbitmq
10.50.10.179:/k8s-sc2-xfs/data/rabbitmq-data-chot-rabbitmq-1-pvc-eeade764-5a20-42e1-a71c-d3cf7a222224 10T 13G 10T 1% /var/lib/kubelet/pods/e2cc5043-5232-44f7-8ba8-9dc7096ec0df/volumes/kubernetes.io~nfs/pvc-eeade764-5a20-42e1-a71c-d3cf7a222224
[root@node3 ~]#
[root@node3 ~]#
[root@node3 ~]#exit
logout
Connection to node3 closed.
⚡ root@master1 /opt
⚡ root@master1 /opt ssh master3
Last login: Wed Nov 23 15:38:57 2022 from 10.50.10.31
[root@master3 ~]#
[root@master3 ~]#
[root@master3 ~]#df -h | grep -E '179|184' | grep -i rabbitmq
10.50.10.184:/spkshare1/data/rabbitmq-data-chot-rabbitmq-0-pvc-ea7912e4-b9bc-4940-b42e-43a667f741c8 493G 200G 268G 43% /var/lib/kubelet/pods/a1c182c7-5110-4481-b4c0-7166fad57d7a/volumes/kubernetes.io~nfs/pvc-ea7912e4-b9bc-4940-b42e-43a667f741c8
[root@master3 ~]#kubectl get pvc -n rabbitmq
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
data-chot-rabbitmq-0 Bound pvc-ea7912e4-b9bc-4940-b42e-43a667f741c8 200Gi RWO nfs-storage-179sc 20m
data-chot-rabbitmq-1 Bound pvc-eeade764-5a20-42e1-a71c-d3cf7a222224 200Gi RWO nfs-storage-179sc 20m
describe pvc
⚡ root@master1 /opt k describe pvc data-chot-rabbitmq-0 -n rabbitmq
Name: data-chot-rabbitmq-0
Namespace: rabbitmq
StorageClass: nfs-storage-179sc
Status: Bound
Volume: pvc-ea7912e4-b9bc-4940-b42e-43a667f741c8
Labels: app.kubernetes.io/instance=chot-rabbitmq
app.kubernetes.io/name=rabbitmq
Annotations: pv.kubernetes.io/bind-completed: yes
pv.kubernetes.io/bound-by-controller: yes
volume.beta.kubernetes.io/storage-provisioner: k8s-sigs.io/nfs-subdir-external-provisioner
volume.kubernetes.io/storage-provisioner: k8s-sigs.io/nfs-subdir-external-provisioner
Finalizers: [kubernetes.io/pvc-protection]
Capacity: 200Gi
Access Modes: RWO
VolumeMode: Filesystem
Used By: chot-rabbitmq-0
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ExternalProvisioning 29m (x2 over 29m) persistentvolume-controller waiting for a volume to be created, either by external provisioner "k8s-sigs.io/nfs-subdir-external-provisioner" or manually created by system administrator
Normal Provisioning 29m k8s-sigs.io/nfs-subdir-external-provisioner_nfs-client-provisioner-6fc564bf9d-gwct5_c033d3db-0c2f-4657-ac4d-506fc1beaf20 External provisioner is provisioning volume for claim "rabbitmq/data-chot-rabbitmq-0"
Normal Provisioning 29m k8s-sigs.io/nfs-subdir-external-provisioner_nfs-client-provisioner-sc179-8447d45564-tfxfd_d4b530f7-d1b2-4cc4-b47f-b1570376917b External provisioner is provisioning volume for claim "rabbitmq/data-chot-rabbitmq-0"
Normal ProvisioningSucceeded 29m k8s-sigs.io/nfs-subdir-external-provisioner_nfs-client-provisioner-6fc564bf9d-gwct5_c033d3db-0c2f-4657-ac4d-506fc1beaf20 Successfully provisioned volume pvc-ea7912e4-b9bc-4940-b42e-43a667f741c8
Normal ProvisioningSucceeded 29m k8s-sigs.io/nfs-subdir-external-provisioner_nfs-client-provisioner-sc179-8447d45564-tfxfd_d4b530f7-d1b2-4cc4-b47f-b1570376917b Successfully provisioned volume pvc-ea7912e4-b9bc-4940-b42e-43a667f741c8
describe pv
# pod1 的pv
⚡ root@master1 /opt k describe pv pvc-ea7912e4-b9bc-4940-b42e-43a667f741c8
Name: pvc-ea7912e4-b9bc-4940-b42e-43a667f741c8
Labels: <none>
Annotations: pv.kubernetes.io/provisioned-by: k8s-sigs.io/nfs-subdir-external-provisioner
Finalizers: [kubernetes.io/pv-protection]
StorageClass: nfs-storage-179sc
Status: Bound
Claim: rabbitmq/data-chot-rabbitmq-0
Reclaim Policy: Delete
Access Modes: RWO
VolumeMode: Filesystem
Capacity: 200Gi
Node Affinity: <none>
Message:
Source:
Type: NFS (an NFS mount that lasts the lifetime of a pod)
Server: 10.50.10.184
Path: /spkshare1/data/rabbitmq-data-chot-rabbitmq-0-pvc-ea7912e4-b9bc-4940-b42e-43a667f741c8
ReadOnly: false
Events: <none>
# pod2的pv
⚡ root@master1 /opt k describe pv pvc-eeade764-5a20-42e1-a71c-d3cf7a222224
Name: pvc-eeade764-5a20-42e1-a71c-d3cf7a222224
Labels: <none>
Annotations: pv.kubernetes.io/provisioned-by: k8s-sigs.io/nfs-subdir-external-provisioner
Finalizers: [kubernetes.io/pv-protection]
StorageClass: nfs-storage-179sc
Status: Bound
Claim: rabbitmq/data-chot-rabbitmq-1
Reclaim Policy: Delete
Access Modes: RWO
VolumeMode: Filesystem
Capacity: 200Gi
Node Affinity: <none>
Message:
Source:
Type: NFS (an NFS mount that lasts the lifetime of a pod)
Server: 10.50.10.179
Path: /k8s-sc2-xfs/data/rabbitmq-data-chot-rabbitmq-1-pvc-eeade764-5a20-42e1-a71c-d3cf7a222224
ReadOnly: false
nfs provisioner 版本
nfs-subdir-external-provisioner:v4.0.2
如何解决呢?
删除旧的存储类(SC), 只保留一个sc动态创建pv就不会有问题。
【29】startupprobe 和 livenessprobe的区别?
initdelay 是延迟检查,延迟多久呢? 这个时间不好把控。 如果设定很长 在延迟检查之后刚好崩了,这就检查表刅。如果设置较短,会频繁检查失败
多久做一次?每次间隔多少s?
startupprobe 可以每10s检查一下。 只是在启动阶段检查,启动成功后不再使用该probe会使用livebessprobe
【30】Error状态的POD如何修复?
在安装gitlab的时候,pod状态有一个error状态. 这说明pod在启动的时候就发生了异常。
通过describe pod 和log 并没有发现什么问题,一度陷入了迷茫。
一下子就定位到问题了,原因是redis 有密码验证,而gitlab的环境变量未设定该参数。redis是用helm安装的,直接enable=false先禁掉redis auth.
Pod 处于 Error 状态
通常处于 Error 状态说明 Pod 启动过程中发生了错误。常见的原因包括
- 依赖的 ConfigMap、Secret 或者 PV 等不存在
- 请求的资源超过了管理员设置的限制,比如超过了 LimitRange 等
- 违反集群的安全策略,比如违反了 PodSecurityPolicy 等
- 容器无权操作集群内的资源,比如开启 RBAC 后,需要为 ServiceAccount 配置角色绑定
【31】如何查看某一个namespace下所有的资源?
# 查看minio ns下所有的资源
# 解析: api-resource是查看所有ns下有什么资源类型,然后通过xargs 管道传给kubectl
kubectl api-resources --verbs=list --namespaced -o name | xargs -n 1 kubectl get --show-kind --ignore-not-found -n minio