龙空技术网

Kubernetes项目实战 十问十答

BespinGlobal 572

前言:

现时同学们对“ubuntu更新软件源无法解析域名”大体比较重视,同学们都需要分析一些“ubuntu更新软件源无法解析域名”的相关内容。那么小编也在网上汇集了一些关于“ubuntu更新软件源无法解析域名””的相关内容,希望我们能喜欢,朋友们快快来学习一下吧!

Kubernetes简介

Kubernetes是一个开源的,用于管理云平台中多个主机上的容器化的应用,Kubernetes的目标是让部署容器化的应用简单并且高效,Kubernetes提供了应用部署、规划、更新、维护的一种机制。通常,把Kubernetes看作Docker的上层架构,Kubernetes以Docker为基础打造了一个云计算时代的全新分布式系统架构。Kubernetes架构中不仅仅只支持Docker一种容器,还支持另一种容器技术Rocket。

Kubernetes的优势

1.易学:轻量级,简单,容易理解;

2.便携:支持公有云,私有云,混合云,以及多种云平台;

3.可扩展:模块化,可插拔,支持钩子,可任意组合;

4.自修复:自动重调度,自动重启,自动复制。

在项目实战中,贝斯平的技术专家整理了Kubernetes在使用中的一些常见问题,希望对您有所帮助。

01

在K8S集群中出现A节点无法访问B节点上的Pod,怎么办?

如果A节点无法ping通B节点上的Pod的IP地址,则在B节点上执行iptables -P FORWARD ACCEPT,反之则在A节点上执行iptables -P FORWARD ACCEPT即可。

02

在搭建Kubernetes集群过程中,安装了kube-dns插件后,运行一个ubuntu容器,发现容器内无法解析集群外域名,一开始可以解析集群内域名,一段时间后也无法解析集群内域名。

在Kubernetes集群中,kubelet是worker组建,负责管理Pod,根据Kubernetes文档,kubelet默认会从Node的/etc/resolv.conf文件读取DNS服务器地址,使得dnsPolicy是Default的Pod得以继承,kubelet中的--resolv-conf参数可以指定这个配置文件的地址。在Ubuntu 18.04中,将这个参数设置为systemd-resolved的DNS服务器配置文件/run/systemd/resolve/resolv.conf,Pod就会继承真正的外部DNS服务器。

03

DNS解析慢或超时如何解决?

DNS的解析结构:

<service_name>.<namespace>.svc.<domain>

myapp.default.svc.cluster.local

解析慢的时候或者解析超时的时候:

curl myapp.default.svc.cluster.local

#这种时候可能会出现解析慢或者解析超时的情况;

curl myapp.default.svc.cluster.local.

#这时在最后加上一个 “.” 解析就没有问题了

04

Pod无法成功创建,describe查看原因,显示:mount failed。

原因:指定与块设备不一致的文件系统类型。

05

Kubernetes 新加了个node,状态Ready, 但调度过去的任务都执行异常

Kubernetes集群原来机器的ip都在en1上,flannel节点启动设置的网卡都在en1, 新加的这台节点ip却在en2上,以en1启动则失败。

此时需要查看flannel的配置:

kubectl -n kube-system get ds kube-flannel-ds -o yaml

...

containers:

- args:

- --ip-masq

- --kube-subnet-mgr

- --iface=en1

06

Kubernetes 如何清空节点?

排干节点:kubectl drain 节点名称 --delete-local-data --force --ignore-daemonsets

删除节点:kubectl delete node 节点名称

07

KubernetesPod调度失败问题(INSUFFICIENT PODS)

Kubernetes的node默认最大pod数量为110个,所有node都达到110个时无法再调度,出现如下报错信息:

0/3 nodes are available: 1 node(s) had taints that the pod didn't tolerate, 2 Insufficient pods

解决办法:

修改/etc/sysconfig/kubelet配置文件,添加--max-pods配置,然后重启kubelet服务,修改后文件内容如下:

KUBELET_EXTRA_ARGS="--fail-swap-on=false --max-pods=300"

08

请求服务时返回⼤量502、503 错误该如何处理?

某些 java 服务更新时,由于健康检查设置的预估启动时间过短,会导致健康检查不通过,服务更新失败,此时访问服务就会有异常。⽽ nginx 配置默认设置了max_fails=1 (请求失败的最⼤尝试次数), fail_timeout=10s (请求失败的超时时长),服务异常时,会有 10s 的时间将后端节点标记为不可⽤,请求服务时就会返回 502、503 错误。

解决⽅案(任选一个):

1、将 nginx 的 max_fails 取值增大,增加请求失败的尝试次数,例如:配置的 upstream 字段为 max_fails=10 、 fail_timeout=10s ;

2、将健康检查的预估启动时间增长,避免因预估启动时间过短而导致健康检查不通过。

09

Node的隔离和恢复

如果A节点无法ping通B节点上的Pod的IP地址,则在B节点上执行iptables -P FORWARD ACCEPT,反之则在A节点上执行iptables -P FORWARD ACCEPT即可。

在硬件升级、硬件维护等情况下,需要将某些Node进行隔离,脱离Kubernetes集群的调度范围。Kubernetes提供了一种机制,既可以将Node纳入调度范围,也可以将Node脱离调度范围。

创建配置文件unschedule_node.yaml,在spec部分指定unschedulable为true:

apiVersion: v1

kind: Node

metadata:

name: kubernetes-minion1

labels:

kubernetes.io/hostname: kubernetes-minion1

spec:

unschedulable: true

然后,通过kubectl replace命令完成对Node状态的修改:

$ kubectl replace -f unschedule_node.yaml

nodes/kubernetes-minion1

查看Node的状态,可以观察到在Node的状态中增加了一项SchedulingDisabled:

$ kubectl get nodes

NAME LABELS STATUS

kubernetes-minion1 kubernetes.io/hostname=kubernetes-minion1 Ready, SchedulingDisabled

对于后续创建的Pod,系统将不会再向该Node进行调度。另一种方法是不使用配置文件,直接使用kubectl patch命令完成:

$ kubectl patch node kubernetes-minion1 -p '{"spec":{"unschedulable":true}}'

需要注意的是,将某个Node脱离调度范围时,在其上运行的Pod并不会自动停止,管理员需要手动停止在该Node上运行的Pod。

同样,如果需要将某个Node重新纳入集群调度范围,则将unschedulable设置为false,再次执行kubectl replace或kubectl patch命令就能恢复系统对该Node的调度。

10

将Pod调度到指定的Node

我们知道,Kubernetes的Scheduler服务(kube-scheduler进程)负责实现Pod的调度,整个调度过程通过执行一系列复杂的算法最终为每个Pod计算出一个最佳的目标节点,这一过程是自动完成的,我们无法知道Pod最终会被调度到哪个节点上。有时我们可能需要将Pod调度到一个指定的Node上,此时,我们可以通过Node的标签(Label)和Pod的nodeSelector属性相匹配,来达到上述目的。

首先,我们可以通过kubectl label命令给目标Node打上一个特定的标签,下面是此命令的完整用法:

kubectl label nodes <node-name> <label-key>=<label-value>

这里,我们为kubernetes-minion1节点打上一个zone=north的标签,表明它是“北方”的一个节点:

$ kubectl label nodes kubernetes-minion1 zone=north

NAME LABELS STATUS

kubernetes-minion1 kubernetes.io/hostname=kubernetes-minion1,zone=north Ready

上述命令行操作也可以通过修改资源定义文件的方式,并执行kubectl replace -f xxx.yaml命令来完成。

然后,在Pod的配置文件中加入nodeSelector定义,以redis-master-controller.yaml为例:

apiVersion: v1

kind: ReplicationController

metadata:

name: redis-master

labels:

name: redis-master

spec:

replicas: 1

selector:

name: redis-master

template:

metadata:

labels:

name: redis-master

spec:

containers:

- name: master

image: kubeguide/redis-master

ports:

- containerPort: 6379

nodeSelector:

zone: north

运行kubectl create -f命令创建Pod,scheduler就会将该Pod调度到拥有zone=north标签的Node上去。

# kubectl get pods -o wide

NAME READY STATUS RESTARTS AGE NODE

redis-master-f0rqj 1/1 Running 0 19s kubernetes-minion1

如果我们给多个Node都定义了相同的标签(例如zone=north),则scheduler将会根据调度算法从这组Node中挑选一个可用的Node进行Pod调度。

这种基于Node标签的调度方式灵活性很高,比如我们可以把一组Node分别贴上“开发环境”“测试验证环境”“用户验收环境”这三组标签中的一种,此时一个Kubernetes集群就承载了3个环境,这将大大提高开发效率。

需要注意的是,如果我们指定了Pod的nodeSelector条件,且集群中不存在包含相应标签的Node时,即使还有其他可供调度的Node,这个Pod也最终会调度失败。

标签: #ubuntu更新软件源无法解析域名