持续更新-20190306-k8s常见方法及错误解决
k8s常见方法及错误解决方法
如果kubectl get nodes状态为notready
可以查看kubelet服务是否开启
容器之间使用flanneld通信,可以ping通docker0,容器之间无法ping通的时候
iptables -F
iptables -X
iptables -Z
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
运行iptables关闭
system:anonymous” cannot proxy services in the namespace “kube-system
浏览器访问 URL:
https://192.168.100.80:6443/api/v1/proxy/namespaces/kube-system/services/kubernetes-dashboard(浏览器会提示证书验证,因为通过加密通道,以改⽅式访问的话,需要提前导⼊证书到你的计算机中)。不然会提示User
“system:anonymous” cannot proxy services in the namespace “kube-system”.
导⼊证书
将⽣成的admin.pem证书转换格式(/etc/kubernetes/ssl目录下)
openssl pkcs12 -export -in admin.pem -out admin.p12 -inkey admin-key.pem
将⽣成的 admin.p12
证书导⼊的你的电脑的浏览器,导出的时候记住你设置的密码,导⼊的时候还要⽤到
拉取国外镜像方法
首先你要有GitHub和dockerhub的账号,将两个进行关联,关联请百度
Docker 新建仓库关联github,这里是关联后的显示了我的github下有这四个项目
然后选择一个进行关联,在进行创建
然后在关联的github下建立一个Dockerfile
Dockerfile的内容就写一个你要拉取的国外镜像
这样就会关联过来一个,我这里只是举例,关联的并不是jenkin那个github项目
设置构建操作,点击那个trigger按键即可开始根据Dockerfile内容构建
查看构建状态
然后即可看到成功构建这个镜像了,你只需要pull到你本地,然后tag改下名字就是了,原理就是国内没法pull镜像,我们就利用dockerhub可以访问国外镜像来帮我们拉取,我们再从dockerhub去拉取
Error: ‘dial tcp 172.30.13.5:9090: getsockopt: no route to host’
Trying to reach: ‘http://172.30.13.5:9090/'
flanneld服务停止了;
flanneld服务运行正常,在排查iptables防火墙
iptables -F
iptables -X
iptables -Z
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables-save > /etc/iptables.rules
或者是否是具体服务的pod ip变了;
检查master和node是否都有安装flanneld服务
集群ip无法访问,节点可以访问
集群ip是提供给集群访问的,比如你的master节点只是安装了api,controller,scheduler,并未安装kubelet和kube-proxy他是不能使用集群ip进行测试访问服务的
未解决*device or resource busy
FailedMount MountVolume.SetUp failed for volume
“kubernetes.io/configmap/fc973baa-6d50-11e8-8999-000c296e73e7-influxdb-config”
(spec.Name: “influxdb-config”) pod “fc973baa-6d50-11e8-8999-000c296e73e7” (UID:
“fc973baa-6d50-11e8-8999-000c296e73e7”) with: remove
/var/lib/kubelet/pods/fc973baa-6d50-11e8-8999-000c296e73e7/volumes/kubernetes.io~configmap/influxdb-config/resolv.conf:
device or resource busy
kibana报错Request Timeout after 30000ms
加大elasticsearch内存。Node节点内存不足
或者修改kibana的检测时间
sed -i ‘/# elasticsearch.requestTimeout:
30000/a\\elasticsearch.requestTimeout: 100000’ /kibana/config/kibana.yml
我的最无语的是:
配置的kube-dns因为iptables防火墙的原因被堵塞了。导致无法解析ip地址。
Unable to connect to Elasticsearch at http://elasticsearch-logging:9200.
因为我的 elasticsearch镜像建立错了,导致 elasticsearch实际没有运行
pod处于pending状态
如果master节点运⾏的是kuberentes1.1.或更⾼版本,⽽node节点的版本低于1.1版本,则API
server将也可以接受新的特权模式的pod,但是⽆法启动,pod将处于pending状态。
执⾏ kubectl describe pod FooPodName
,可以看到为什么pod处于pending状态。输出的event列表中将显示:
Error validating pod”FooPodName”.”FooPodNamespace” from api,
ignoring:spec.containers[0].securityContext.privileged: forbidden
‘<*>(0xc2089d3248)true’
如果master节点的版本低于1.1,⽆法创建特权模式的pod。如果你仍然试图去创建的话,你得到如下错误:
The Pod “FooPodName” is invalid.spec.containers[0].securityContext.privileged:
forbidden ‘<*>(0xc20b222db0)true’
K8s共用仓库私有项目认证账户
kubernetes.io/dockerconfigjson
可以直接用 kubectl 命令来创建用于docker registry认证的secret:
$ kubectl create secret docker-registry myregistrykey \
--docker-server=DOCKER_REGISTRY_SERVER \
--docker-username=DOCKER_USER –docker-password=DOCKER_PASSWORD \
--docker-email=DOCKER_EMAIL
secret “myregistrykey” created.
这种方式需要你已经定义上述的环境变量,如果没有定义,则无法获取变量值,会失败。
也可以直接读取 ~/.docker/config.json 的内容来创建:
可以查看到你的docker服务已经存储的仓库认证信息
$ cat ~/.docker/config.json
进行base64编码格式加密转换
$ cat ~/.docker/config.json | base64
也可将显示的密文使用解密进行查看
echo “你的密文” | base64 –decode
$ vim myregistrykey.yaml
apiVersion: v1
kind: Secret
metadata:
name: myregistrykey
data:
.dockerconfigjson: 密文是连续的,不能分开
type: kubernetes.io/dockerconfigjson
$ kubectl create -f myregistrykey.yaml
建立一个pod;来测试,我这里是测试拉取本地的仓库中私有项目的image,这里就需要用到认证
vim testreg.yaml
apiVersion: v1
kind: Pod
metadata:
name: testreg
spec:
containers:
- name: foo
image: 172.16.3.55:8000/kubernetes/kibana:v4.6.1-1
imagePullSecrets:
- name: myregistrykey
~
Influxdb数据库web无法访问
0 error - Could not connect to http://172.30.32.2:8086
Hint: the InfluxDB API runs on port 8086 by default
当使用http方式访问的时间输入node ip:映射的端口即可访问,使用https方式就不行
Secret/configmap更新后pod中以环境变量的值并没跟着更新
secret挂载到里面去使用的是挂载方式的支持自动更新的,使用环境变量方式的是不支持自动更新的
K8s中同一个namespace中的所有pod使用私有docker registry的认证信息
$ cat ~/.docker/config.json
进行base64编码格式加密转换
$ cat ~/.docker/config.json | base64
也可将显示的密文使用解密进行查看
echo “你的密文” | base64 –decode
$ vim myregistrykey.yaml
apiVersion: v1
kind: Secret
metadata:
name: myregistrykey
data:
.dockerconfigjson: 密文是连续的,不能分开
type: kubernetes.io/dockerconfigjson
$ kubectl create -f myregistrykey.yaml
1.命令方式
建立好后,在ServiceAccount中新增imagePullSecrets
的Secret为myregistrykey(这里使用的是ServiceAccount名为default的。)
kubectl patch serviceaccount default -p ‘{“imagePullSecrets”: [{“name”:
“myregistrykey”}]}’
2.yaml文件方式
$ kubectl get serviceaccounts default -o yaml > ./sa.yaml
$ cat sa.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
creationTimestamp: 2015-08-07T22:02:39Z
name: default
namespace: default
resourceVersion: “243024”
selfLink: /api/v1/namespaces/default/serviceaccounts/default
uid: 052fb0f4-3d50-11e5-b066-42010af0d7b6
secrets:
- name: default-token-uudge
$ vi sa.yaml(这里是新增和删除的部分)
[editor session not shown]
[delete line with key “resourceVersion”]
[add lines with “imagePullSecret:”]
$ cat sa.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
creationTimestamp: 2015-08-07T22:02:39Z
name: default
namespace: default
selfLink: /api/v1/namespaces/default/serviceaccounts/default
uid: 052fb0f4-3d50-11e5-b066-42010af0d7b6
secrets:
- name: default-token-uudge
imagePullSecrets:
- name: myregistrykey
$ kubectl replace serviceaccount default -f ./sa.yaml
新建的ServiceAccount会默认使用secret的token
每个namespace都有一个默认的serviceaccount(default)
uid : unable to do port forwarding: socat not found
Kubectl port-forward实现使用localhost_ip访问并且可以进行pod调度
在节点上需要安装socat
yum –y install socat
flannel不能随意重启,因为会导致每个节点从etcd获取的网段不同。
Flanneld维护整个容器
Flanneld是容器的路由表,所以就算是你使用了nodeip加上映射后的端口访问也是要经过flannel的,当关闭flannel的时候,docker也关闭了,这是因为在flannel.service服务文件中定义的。
Ingree的path加了后提示404找不到
-path的路径会带入后端服务中,比如:
Nginx容器的根目录为/usr/share/nginx/html/
而我的ingree定义是这样的
- path: /nginx
backend:
serviceName: my-nginx
servicePort: web
那么我需要在nginx容器的根目录下新建一个nginx文件夹
mkdir –p /usr/share/nginx/html/nginx 然后将网页放在这里,不然会提示找不到404
treafik的web显示
是以一个kind:ingree的yaml文件中第一个出现的host作为前端名FRONTENDS显示,这样其实不够严谨,没法区分前后端。
PodExceedsFreeMemory
Node内存不足,无法调度
Error from server (ServerTimeout)
重启apiserver服务
解决heapster无法连接报错
E1101 08:56:05.014891 1 summary.go:97] error while getting metrics summary from
Kubelet kube-node2(192.168.100.82:10255): Get
http://192.168.100.82:10255/stats/summary/: dial tcp 192.168.100.82:10255:
getsockopt: connection refused
第一种方式
参考https://github.com/kubernetes/heapster/issues/1586
是不是覆盖网络的问题,优化calico网络组件
第二种方式,可以成功运行
因为默认10250端口号是kubelet的只读端口,版本高以后默认是关闭的,首先确认kubelet服务是否正常运行
[root@kube-node1 ~]# netstat -lntp | grep kubelet
tcp 0 0 127.0.0.1:10248 0.0.0.0:* LISTEN 74042/kubelet
tcp 0 0 127.0.0.1:43411 0.0.0.0:* LISTEN 74042/kubelet
tcp6 0 0 :::10250 :::* LISTEN 74042/kubelet
明显看到上面没有运行10255端口,这时我们修改kubelet的配置文件,从哪里获取配置文件位置呢?
使用命令systemctl status kubelet
-l可以获取kubelet启动加了哪些参数,列如我这里就获取到是
编辑配置文件,看其中是否有下面的配置,没有就新加,为了方面查看就加到port的下面,然后重启服务就可以查看到10255端口启用了。所有的node都需要修改
readOnlyPort: 10255
第三种方式
修改heapster的启动参数 -
–source=kubernetes:https://kubernetes.default?kubeletHttps=true&kubeletPort=10250
提示下面的错误
E1101 09:17:05.022691 1 kubelet.go:231] error while getting containers from
Kubelet: failed to get all container stats from Kubelet URL
“https://192.168.100.82:10250/stats/container/": Post
https://192.168.100.82:10250/stats/container/: x509: cannot validate certificate
for 192.168.100.82 because it doesn’t contain any IP SANs
第四种方式
-
–source=kubernetes:https://kubernetes.default?inClusterConfig=false&useServiceAccount=true&auth=
提示下面的错误
E1101 09:49:48.557497 1 reflector.go:190]
k8s.io/heapster/metrics/processors/namespace_based_enricher.go:84: Failed to
list *v1.Namespace: Get
https://kubernetes.default/api/v1/namespaces?resourceVersion=0: x509:
certificate signed by unknown authority
E1101 09:49:48.558574 1 reflector.go:190]
k8s.io/heapster/metrics/heapster.go:322: Failed to list *v1.Pod: Get
https://kubernetes.default/api/v1/pods?resourceVersion=0: x509: certificate
signed by unknown authority
E1101 09:49:48.592681 1 reflector.go:190]
k8s.io/heapster/metrics/util/util.go:51: Failed to list *v1.Node: Get
https://kubernetes.default/api/v1/nodes?resourceVersion=0: x509: certificate
signed by unknown authority
Invalid Kubernetes API v1 endpoint https://10.254.0.1:443/api: SSL_connect returned=1 errno=0 state=error: certificate verify failed
docker run –rm -it –entrypoint=”cat” huisebug/fluentd-elasticsearch:1.22
/etc/td-agent/td-agent.conf > td-agent.conf
修改文件内容
在td-agent.conf的配置文件的中增加两条配置配置:(注意是新加两条,不是新建)
<filter kubernetes.**>
type kubernetes_metadata
kubernetes_url kubeapi地址:8080
verify_ssl false
</filter>
创建ConfigMap
kubectl create configmap td-agent-config –from-file=./td-agent.conf -n
kube-system
在fluend.yaml中新加configmap
- name: td-agent-config
mountPath: /etc/td-agent
…
volumes:
- name: td-agent-config
configMap:
name: td-agent-config
efk提示open /var/run/secrets/kubernetes.io/serviceaccount/token: no such file or directory
efk的建立中e的建立确保你的k8s支持serviceaccout是否开启,不然会导致token没建立,/elasticsearch_logging_discovery无法访问API
Server导致 /elasticsearch/config/elasticsearch.yml没有被正确生成造成的,
Grafana在Pods仪表板不显示终止的pod
默认的pod查询语句是这样的
我们需要在influxdb中新建一个采样数据,然后将其指向采样数据,这样就会过滤掉失效的pod
Influxdb建立时需要开启web UI默认访问端口是8083,
我这里使用获取的svc经过nodeport方式后进行访问
http://服务器ip:31899
连接数据库中可能会提示找不到数据库,因为系统会有一个默认配置,如果你发现配置错误,比如我这里是服务器ip:31004,连接成功后即可show
database。
然后在query栏执行以下两句influxdb sql
CREATE RETENTION POLICY “2hours” ON “k8s” DURATION 2h REPLICATION 1
CREATE CONTINUOUS QUERY current_pods_query ON k8s BEGIN SELECT max(value) AS
value INTO k8s.”2hours”.current_pods FROM k8s.”default”.uptime WHERE type =
‘pod’ GROUP BY time(5m), namespace_name, nodename, pod_name END
执行完毕后切换回grafana配置界面,修改query语句
SHOW TAG VALUES FROM k8s.”2hours”.current_pods WITH KEY = “pod_name” WHERE
“namespace_name” =~ /$namespace$/
保存修改,一段时间后即可看到失效pod就没有了
pod.Spec.SecurityContext.RunAsUser is forbidden容器不调度
是因为apiserver开启了SecurityConrextDeny,将其去除