版权声明:本文为博主原创文章,如需转载请发邮件至[email protected]申请。 https://blog.csdn.net/denglelai123/article/details/80871430
使用kubectl来管理Kubernetes集群。
摘要
使用kubectl来管理Kubernetes集群。
kubectl
选项
--
alsologtostderr
[=
false
]:
同时输出日志到标准错误控制台和文件。
--
api
-
version
=
""
:
和服务端交互使用的
API
版本。
--
certificate
-
authority
=
""
:
用以进行认证授权的.
cert
文件路径。
--
client
-
certificate
=
""
:
TLS
使用的客户端证书路径。
--
client
-
key
=
""
:
TLS
使用的客户端密钥路径。
--
cluster
=
""
:
指定使用的
kubeconfig
配置文件中的集群名。
--
context
=
""
:
指定使用的
kubeconfig
配置文件中的环境名。
--
insecure
-
skip
-
tls
-
verify
[=
false
]:
如果为
true
,将不会检查服务器凭证的有效性,这会导致你的
HTTPS
链接变得不安全。
--
kubeconfig
=
""
:
命令行请求使用的配置文件路径。
--
log
-
backtrace
-
at
=:
0
:
当日志长度超过定义的行数时,忽略堆栈信息。
--
log
-
dir
=
""
:
如果不为空,将日志文件写入此目录。
--
log
-
flush
-
frequency
=
5s
:
刷新日志的最大时间间隔。
--
logtostderr
[=
true
]:
输出日志到标准错误控制台,不输出到文件。
--
match
-
server
-
version
[=
false
]:
要求服务端和客户端版本匹配。
--
namespace
=
""
:
如果不为空,命令将使用此
namespace
。
--
password
=
""
:
API
Server
进行简单认证使用的密码。
-
s
,
--
server
=
""
:
Kubernetes
API
Server
的地址和端口号。
--
stderrthreshold
=
2
:
高于此级别的日志将被输出到错误控制台。
--
token
=
""
:
认证到
API
Server
使用的令牌。
--
user
=
""
:
指定使用的
kubeconfig
配置文件中的用户名。
--
username
=
""
:
API
Server
进行简单认证使用的用户名。
--
v
=
0
:
指定输出日志的级别。
--
vmodule
=:
指定输出日志的模块,格式如下:
pattern
=
N
,使用逗号分隔。
参见
-
kubectl annotate – 更新资源的注解。
更新一个活多个资源的注解。 注解是一个键值对,它可以包含比label更多的信息,并且可能是机读数据。 注解用来存储那些辅助的,非区分性的信息,特别是那些为外部工具或系统扩展插件使用的数据。 如果–overwrite设为true,将会覆盖现有的注解,否则试图修改一个注解的值将会抛出错误。 如果设置了–resource-version,那么将会使用指定的这个版本,否则将使用当前版本。
支持的资源包括但不限于(大小写不限):pods (po)、services (svc)、 replicationcontrollers (rc)、nodes (no)、events (ev)、componentstatuses (cs)、 limitranges (limits)、persistentvolumes (pv)、persistentvolumeclaims (pvc)、 resourcequotas (quota)和secrets。
kubectl annotate
[--
overwrite
]
(-
f FILENAME
|
TYPE NAME
)
KEY_1
=
VAL_1
...
KEY_N
=
VAL_N
[--
resource
-
version
=
version
]
示例
# 更新pod “foo”,设置其注解description的值为my frontend。
# 如果同一个注解被赋值了多次,只保存最后一次设置的值。
$ kubectl annotate pods foo description
='my frontend'
# 更新“pod.json”文件中type和name字段指定的pod的注解。
$ kubectl annotate
-
f pod
.
json description
=
'my frontend'
# 更新pod “foo”,设置其注解description的值为my frontend running nginx,已有的值将被覆盖。
$ kubectl annotate
--
overwrite pods foo description
=
'my frontend running nginx'
# 更新同一namespace下所有的pod。
$ kubectl annotate pods
--
all description
=
'my frontend running nginx'
# 仅当pod “foo”当前版本为1时,更新其注解
$ kubectl annotate pods foo description
=
'my frontend running nginx'
--
resource
-
version
=
1
# 更新pod “foo”,删除其注解description。
# 不需要--override选项。
$ kubectl annotate pods foo description
-
-
kubectl api-versions – 以“组/版本”的格式输出服务端支持的API版本。
以“组/版本”的格式输出服务端支持的API版本。
kubectl api
-
versions
-
kubectl apply – 通过文件名或控制台输入,对资源进行配置。
通过文件名或控制台输入,对资源进行配置。
接受JSON和YAML格式的描述文件。
kubectl apply
-
f FILENAME
示例
# 将pod.json中的配置应用到pod
$ kubectl apply
-
f
./
pod
.
json
# 将控制台输入的JSON配置应用到Pod
$ cat pod
.
json
|
kubectl apply
-
f
-
选项
-
f
,
--
filename
=[]:
包含配置信息的文件名,目录名或者
URL
。
-
o
,
--
output
=
""
:
输出格式,使用“-
o name
”来输出简短格式(资源类型/资源名)。
--
schema
-
cache
-
dir
=
"/tmp/kubectl.schema"
:
如果不为空,将
API schema
缓存为指定文件,默认缓存到“/
tmp
/
kubectl
.
schema
”。
--
validate
[=
true
]:
如果为
true
,在发送到服务端前先使用
schema
来验证输入。
-
kubectl attach – 连接到一个正在运行的容器。
连接到一个正在运行的容器。
摘要
连接到现有容器中一个正在运行的进程。
kubectl attach POD
-
c CONTAINER
示例
# 获取正在运行中的pod 123456-7890的输出,默认连接到第一个容器
$ kubectl attach
123456
-
7890
# 获取pod 123456-7890中ruby-container的输出
$ kubectl attach
123456
-
7890
-
c ruby
-
container date
# 切换到终端模式,将控制台输入发送到pod 123456-7890的ruby-container的“bash”命令,并将其输出到控制台/
# 错误控制台的信息发送回客户端。
$ kubectl attach
123456
-
7890
-
c ruby
-
container
-
i
-
t
选项
-
c
,
--
container
=
""
:
容器名。
-
i
,
--
stdin
[=
false
]:
将控制台输入发送到容器。
-
t
,
--
tty
[=
false
]:
将标准输入控制台作为容器的控制台输入。
-
kubectl autoscale – 对replication controller进行自动伸缩。
-
kubectl cluster-info – 输出集群信息。
显示master节点的地址和包含kubernetes.io/cluster-service=true的service(系统service)。
kubectl cluster
-
info
-
kubectl config – 修改kubeconfig配置文件。
修改kubeconfig配置文件。
摘要
使用config的子命令修改kubeconfig配置文件,如“kubectl config set current-context my-context”。
配置文件的读取遵循如下规则:
The loading order follows these rules:
1.
如果指定了--
kubeconfig
选项,那么只有指定的文件被加载。此选项只能被设置一次,并且不会合并其他文件。
If
the
--
kubeconfig flag
is
set
,
then
only that file
is
loaded
.
The
flag may only be
set
once
and
no
merging takes place
.
2.
如果设置了
$KUBECONFIG
环境变量,将同时使用此环境变量指定的所有文件列表(使用操作系统默认的顺序),所有文件将被合并。当修改一个值时,将修改设置了该值的文件。当创建一个值时,将在列表的首个文件创建该值。若列表中所有的文件都不存在,将创建列表中的最后一个文件。
3.
如果前两项都没有设置,将使用
$
{
HOME
}/.
kube
/
config
,并且不会合并其他文件。
kubectl config SUBCOMMAND
选项
--
kubeconfig
=
""
:
使用特定的配置文件。
示例
# 仅设置e2e集群项中的server字段,不影响其他字段
$ kubectl config
set
-
cluster e2e
--
server
=
https
:
//1.2.3.4
# 向e2e集群项中添加认证鉴权数据
$ kubectl config
set
-
cluster e2e
--
certificate
-
authority
=~/.
kube
/
e2e
/
kubernetes
.
ca
.
crt
# 取消dev集群项中的证书检查
$ kubectl config
set
-
cluster e2e
--
insecure
-
skip
-
tls
-
verify
=
true
选项
--
api
-
version
=
""
:
设置
kuebconfig
配置文件中集群选项中的
api
-
version
。
--
certificate
-
authority
=
""
:
设置
kuebconfig
配置文件中集群选项中的
certificate
-
authority
路径。
--
embed
-
certs
=
false
:
设置
kuebconfig
配置文件中集群选项中的
embed
-
certs
开关。
--
insecure
-
skip
-
tls
-
verify
=
false
:
设置
kuebconfig
配置文件中集群选项中的
insecure
-
skip
-
tls
-
verify
开关。
--
server
=
""
:
设置
kuebconfig
配置文件中集群选项中的
server
。
在kubeconfig配置文件中设置一个环境项。 如果指定了一个已存在的名字,将合并新字段并覆盖旧字段。
kubectl config
set
-
context NAME
[--
cluster
=
cluster_nickname
]
[--
user
=
user_nickname
]
[--
namespace
=
namespace
]
示例
# 设置gce环境项中的user字段,不影响其他字段。
$ kubectl config
set
-
context gce
--
user
=
cluster
-
admin
选项
--
cluster
=
""
:
设置
kuebconfig
配置文件中环境选项中的集群。
--
namespace
=
""
:
设置
kuebconfig
配置文件中环境选项中的命名空间。
--
user
=
""
:
设置
kuebconfig
配置文件中环境选项中的用户。
在kubeconfig配置文件中设置一个单独的值
PROPERTY_NAME 使用“.”进行分隔,每段代表一个属性名或者map的键,map的键不能包含“.”。 PROPERTY_VALUE 需要设置的新值。
kubectl config
set
PROPERTY_NAME PROPERTY_VALUE
在kubeconfig配置文件中清除一个单独的值。 PROPERTY_NAME 使用“.”进行分隔,每段代表一个属性名或者map的键,map的键不能包含“.”。
kubectl config unset PROPERTY_NAME
使用kubeconfig中的一个环境项作为当前配置。
摘要
使用kubeconfig中的一个环境项作为当前配置。
kubectl config
use
-
context CONTEXT_NAME
摘要
显示合并后的kubeconfig设置,或者一个指定的kubeconfig配置文件。 用户可使用–output=template –template=TEMPLATE来选择输出指定的值。
kubectl config view
示例
# 显示合并后的kubeconfig设置
$ kubectl config view
# 获取e2e用户的密码
$ kubectl config view
-
o
template
--
template
=
'{{range .users}}{{ if eq .name "e2e" }}{{ index .user.password }}{{end}}{{end}}'
选项
--
flatten
[=
false
]:
将读取的
kubeconfig
配置文件扁平输出为自包含的结构(对创建可迁移的
kubeconfig
配置文件有帮助)
--
merge
=
true
:
按照继承关系合并所有的
kubeconfig
配置文件。
--
minify
[=
false
]:
如果为
true
,不显示目前环境未使用到的任何信息。
--
no
-
headers
[=
false
]:
当使用默认输出格式时不打印标题栏。
-
o
,
--
output
=
""
:
输出格式,只能使用
json
|
yaml
|
wide
|
name
|
go
-
template
=...|
go
-
template
-
file
=...|
jsonpath
=...|
jsonpath
-
file
=...中的一种。参见
golang
模板[
http
:
//
golang.org/pkg/text/template/#pkg-overview
]和jsonpath模板[
http://releases.k8s.io/release-1.1/docs/user-guide/jsonpath.md
]。
--
output
-
version
=
""
:
输出资源使用的
API
版本(默认使用
api
-
version
)。
--
raw
[=
false
]:
显示未经格式化的字节信息。
-
a
,
--
show
-
all
[=
false
]:
打印输出时,显示所有的资源(默认隐藏状态为
terminated
的
pod
)。
--
sort
-
by
=
""
:
如果不为空,对输出的多个结果根据指定字段进行排序。该字段使用
jsonpath
表达式(如“
ObjectMeta
.
Name
”)描述,并且该字段只能为字符串或者整数类型。
--
template
=
""
:
当指定了-
o
=
go
-
template
或-
o
=
go
-
template
-
file
时使用的模板字符串或者模板文件。模板的格式为
golang
模板[
http
:
//
golang.org/pkg/text/template/#pkg-overview
]。
-
kubectl create – 通过文件名或控制台输入,创建资源。
通过文件名或控制台输入,创建资源。
摘要
通过文件名或控制台输入,创建资源。
接受JSON和YAML格式的描述文件。
kubectl create
-
f FILENAME
示例
# 使用pod.json文件创建一个pod
$ kubectl create
-
f
./
pod
.
json
# 通过控制台输入的JSON创建一个pod
$ cat pod
.
json
|
kubectl create
-
f
-
选项
-
f
,
--
filename
=[]:
用以创建资源的文件名,目录名或者
URL
。
-
o
,
--
output
=
""
:
输出格式,使用“-
o name
”来输出简短格式(资源类型/资源名)。
--
schema
-
cache
-
dir
=
"/tmp/kubectl.schema"
:
如果不为空,将
API schema
缓存为指定文件,默认缓存到“/
tmp
/
kubectl
.
schema
”。
--
validate
[=
true
]:
如果为
true
,在发送到服务端前先使用
schema
来验证输入。
-
kubectl delete – 通过文件名、控制台输入、资源名或者label selector删除资源。
通过文件名、控制台输入、资源名或者label selector删除资源。
摘要
通过文件名、控制台输入、资源名或者label selector删除资源。 接受JSON和YAML格式的描述文件。
只能指定以下参数类型中的一种:文件名、资源类型和名称、资源类型和label selector。 注意:delete命令不检查资源版本,如果有人在你进行删除操作的同时进行更新操作,他所做的更新将随资源同时被删除。
kubectl
delete
([-
f FILENAME
]
|
TYPE
[(
NAME
|
-
l label
|
--
all
)])
示例
# 通过pod.json文件中指定的资源类型和名称删除一个pod
$ kubectl
delete
-
f
./
pod
.
json
# 通过控制台输入的JSON所指定的资源类型和名称删除一个pod
$ cat pod
.
json
|
kubectl
delete
-
f
-
# 删除所有名为“baz”和“foo”的pod和service
$ kubectl
delete
pod
,
service baz foo
# 删除所有带有lable name=myLabel的pod和service
$ kubectl
delete
pods
,
services
-
l name
=
myLabel
# 删除UID为1234-56-7890-234234-456456的pod
$ kubectl
delete
pod
1234
-
56
-
7890
-
234234
-
456456
# 删除所有的pod
$ kubectl
delete
pods
--
all
选项
--
all
[=
false
]:
使用[-
all
]选择所有指定的资源。
--
cascade
[=
true
]:
如果为
true
,级联删除指定资源所管理的其他资源(例如:被
replication controller
管理的所有
pod
)。默认为
true
。
-
f
,
--
filename
=[]:
用以指定待删除资源的文件名,目录名或者
URL
。
--
grace
-
period
=-
1
:
安全删除资源前等待的秒数。如果为负值则忽略该选项。
--
ignore
-
not
-
found
[=
false
]:
当待删除资源未找到时,也认为删除成功。如果设置了--
all
选项,则默认为
true
。
-
o
,
--
output
=
""
:
输出格式,使用“-
o name
”来输出简短格式(资源类型/资源名)。
-
l
,
--
selector
=
""
:
用于过滤资源的
Label
。
--
timeout
=
0
:
删除资源的超时设置,
0
表示根据待删除资源的大
小由系统决定。
-
kubectl describe – 输出指定的一个/多个资源的详细信息。
输出指定的一个/多个资源的详细信息。
摘要
输出指定的一个/多个资源的详细信息。
此命令组合调用多条API,输出指定的一个或者一组资源的详细描述。
$ kubectl describe TYPE NAME_PREFIX
首先检查是否有精确匹配TYPE和NAME_PREFIX的资源,如果没有,将会输出所有名称以NAME_PREFIX开头的资源详细信息。
支持的资源包括但不限于(大小写不限):pods (po)、services (svc)、 replicationcontrollers (rc)、nodes (no)、events (ev)、componentstatuses (cs)、 limitranges (limits)、persistentvolumes (pv)、persistentvolumeclaims (pvc)、 resourcequotas (quota)和secrets。
kubectl describe
(-
f FILENAME
|
TYPE
[
NAME_PREFIX
|
-
l label
]
|
TYPE
/
NAME
)
示例
# 描述一个node
$ kubectl describe nodes kubernetes
-
minion
-
emt8
.
c
.
myproject
.
internal
# 描述一个pod
$ kubectl describe pods
/
nginx
# 描述pod.json中的资源类型和名称指定的pod
$ kubectl describe
-
f pod
.
json
# 描述所有的pod
$ kubectl describe pods
# 描述所有包含label name=myLabel的pod
$ kubectl describe po
-
l name
=
myLabel
# 描述所有被replication controller “frontend”管理的pod(rc创建的pod都以rc的名字作为前缀)
$ kubectl describe pods frontend
选项
-
f
,
--
filename
=[]:
用来指定待描述资源的文件名,目录名或者
URL
。
-
l
,
--
selector
=
""
:
用于过滤资源的
Label
。
-
kubectl edit – 编辑服务端的资源。
编辑服务端的资源。
摘要
使用系统默认编辑器编辑服务端的资源。
edit命令允许你直接编辑使用命令行工具获取的任何资源。此命令将打开你通过KUBE_EDITOR,GIT_EDITOR 或者EDITOR环境变量定义的编辑器,或者直接使用“vi”。你可以同时编辑多个资源,但所有的变更都只会一次性 提交。除了命令行参数外,此命令也接受文件名,但所直指定的文件必须使用早于当前的资源版本。
所编辑的文件将使用默认的API版本输出,或者通过–output-version选项显式指定。默认的输出格式是YAML, 如果你需要使用JSON格式编辑,使用-o json选项。
如果当更新资源的时候出现错误,将会在磁盘上创建一个临时文件,记录未成功的更新。更新资源时最常见的错误 是其他人也在更新服务端的资源。当这种情况发生时,你需要将你所作的更改应用到最新版本的资源上,或者编辑 保存的临时文件,使用最新的资源版本。
kubectl edit
(
RESOURCE
/
NAME
|
-
f FILENAME
)
示例
# 编辑名为“docker-registry”的service
$ kubectl edit svc
/
docker
-
registry
# 使用一个不同的编辑器
$ KUBE_EDITOR
=
"nano"
kubectl edit svc
/
docker
-
registry
# 编辑名为“docker-registry”的service,使用JSON格式、v1 API版本
$ kubectl edit svc
/
docker
-
registry
--
output
-
version
=
v1
-
o json
选项
-
f
,
--
filename
=[]:
用来指定待编辑资源的文件名,目录名或者
URL
。
-
o
,
--
output
=
"yaml"
:
输出格式,可选
yaml
或者
json
中的一种。
--
output
-
version
=
""
:
输出资源使用的
API
版本(默认使用
api
-
version
)。
-
kubectl exec – 在容器内部执行命令。
摘要
在容器内部执行命令。
kubectl
exec
POD
[-
c CONTAINER
]
--
COMMAND
[
args
...]
示例
# 默认在pod 123456-7890的第一个容器中运行“date”并获取输出
$ kubectl
exec
123456
-
7890
date
# 在pod 123456-7890的容器ruby-container中运行“date”并获取输出
$ kubectl
exec
123456
-
7890
-
c ruby
-
container date
# 切换到终端模式,将控制台输入发送到pod 123456-7890的ruby-container的“bash”命令,并将其输出到控制台/
# 错误控制台的信息发送回客户端。
$ kubectl
exec
123456
-
7890
-
c ruby
-
container
-
i
-
t
--
bash
-
il
选项
-
c
,
--
container
=
""
:
容器名。如果未指定,使用
pod
中的一个容器。
-
p
,
--
pod
=
""
:
Pod
名。
-
i
,
--
stdin
[=
false
]:
将控制台输入发送到容器。
-
t
,
--
tty
[=
false
]:
将标准输入控制台作为容器的控制台输入。
-
kubectl expose – 输入replication controller,service或者pod,并将其暴露为新的kubernetes service。
-
kubectl get – 输出一个/多个资源。
-
kubectl label – 更新资源的label。
-
kubectl logs – 输出pod中一个容器的日志。
输出pod中一个容器的日志。
摘要
输出pod中一个容器的日志。如果pod只包含一个容器则可以省略容器名。
kubectl logs
[-
f
]
[-
p
]
POD
[-
c CONTAINER
]
示例
# 返回仅包含一个容器的pod nginx的日志快照
$ kubectl logs nginx
# 返回pod ruby中已经停止的容器web-1的日志快照
$ kubectl logs
-
p
-
c ruby web
-
1
# 持续输出pod ruby中的容器web-1的日志
$ kubectl logs
-
f
-
c ruby web
-
1
# 仅输出pod nginx中最近的20条日志
$ kubectl logs
--
tail
=
20
nginx
# 输出pod nginx中最近一小时内产生的所有日志
$ kubectl logs
--
since
=
1h
nginx
选项
-
c
,
--
container
=
""
:
容器名。
-
f
,
--
follow
[=
false
]:
指定是否持续输出日志。
--
interactive
[=
true
]:
如果为
true
,当需要时提示用户进行输入。默认为
true
。
--
limit
-
bytes
=
0
:
输出日志的最大字节数。默认无限制。
-
p
,
--
previous
[=
false
]:
如果为
true
,输出
pod
中曾经运行过,但目前已终止的容器的日志。
--
since
=
0
:
仅返回相对时间范围,如
5s
、
2m
或
3h
,之内的日志。默认返回所有日志。只能同时使用
since
和
since
-
time
中的一种。
--
since
-
time
=
""
:
仅返回指定时间(
RFC3339
格式)之后的日志。默认返回所有日志。只能同时使用
since
和
since
-
time
中的一种。
--
tail
=-
1
:
要显示的最新的日志条数。默认为-
1
,显示所有的日志。
--
timestamps
[=
false
]:
在日志中包含时间戳。
-
kubectl namespace -(已停用)设置或查看当前使用的namespace。
-
kubectl patch – 通过控制台输入更新资源中的字段。
-
kubectl port-forward – 将本地端口转发到Pod。
-
kubectl proxy – 为Kubernetes API server启动代理服务器。
-
kubectl replace – 通过文件名或控制台输入替换资源。
-
kubectl rolling-update – 对指定的replication controller执行滚动升级。
-
kubectl run – 在集群中使用指定镜像启动容器。
-
kubectl scale – 为replication controller设置新的副本数。
-
kubectl stop – (已停用)通过资源名或控制台输入安全删除资源。
-
kubectl version – 输出服务端和客户端的版本信息。
输出服务端和客户端的版本信息。
摘要
输出服务端和客户端的版本信息。
kubectl version
选项
-
c
,
--
client
[=
false
]:
仅输出客户端版本(无需连接服务器)。
常见故障排查
这个小节将帮助读者调试部署在Kubernetes的应用程序运行不正常的情况。本篇并不会包含如何调试集群组建过程中出现错误的问题,这些内容在文档的下一节中进行介绍。
内容提要
-
应用程序故障排查
-
常见问题
-
故障诊断
-
排查Pods的故障
-
Pod始终处于Pending状态
-
Pod始终处于Waiting状态
-
Pod一直崩溃或运行不正常
-
Pod在运行但没有如预期工作
-
-
排查Replication Controllers的故障
-
排查Services的故障
-
服务没有端点信息
-
网络流量没有正确的转发
-
其他问题
-
-
-
常见问题
故障诊断
故障排查的第一步是对故障进行分类。一般来说,应用程序的故障可以分为下面几个方面:
-
Pods的故障
-
ReplicationControllers的故障
-
Services的故障
排查Pods的故障
检查Pod的问题首先应该了解Pod所处的状况。下面这个命令能够获得Pod当前的状态和近期的事件列表:
$ kubectl describe pods $
{
POD_NAME
}
确认清楚在Pod以及其中每一个容器的状态,是否都处于
Runing
?通过观察容器的已运行时间判断它是否刚刚才重新启动过?
根据不同的运行状态,用户应该采取不同的调查措施。
Pod始终处于Pending状态
如果Pod保持在
Pending
的状态,这意味着它无法被正常的调度到一个节点上。通常来说,这是由于某种系统资源无法满足Pod运行的需求。观察刚才
kubectl describe
命令的输出内容,其中应该包括了能够判断错误原因的消息。常见的原因有以下这些:
-
用户指定了 hostPort :通过 hostPort 用户能够将服务暴露到指定的主机端口上,但这样会限制Pod能够被调度运行的节点。在大多数情况下, hostPort 配置都是没有必要的,用户应该采用Service的方式暴露其对外的服务。如果用户确实必须使用 hostPort 的功能,那么此Pod最多只能部署到和集群节点相同的数目。
Pod始终处于Waiting状态
Pod处在
Waiting
的状态,说明它已经被调度分配到了一个工作节点,然而它无法在那个节点上运行。同样的,在刚才
kubectl describe
命令的输出内容中,应该包含有更详细的错误信息。最经常导致Pod始终
Waiting
的原因是无法下载所需的镜像(译者注:由于国内特殊的网络环境,这类问题出现得特别普遍)。用户可以从下面三个方面进行排查:
-
请确保正确书写了镜像的名称
-
请检查所需镜像是否已经推送到了仓库中
-
手工的在节点上运行一次 docker pull <镜像名称> 检测镜像能否被正确的拉取下来
Pod一直崩溃或运行不正常
首先,查看正在运行容器的日志。
$ kubectl logs
<
Pod
名称>
<
Pod
中的容器名称>
如果容器之前已经崩溃过,通过以下命令可以获得容器前一次运行的日志内容。
$ kubectl logs
--
previous
<
Pod
名称>
<
Pod
中的容器名称>
此外,还可以使用
exec
命令在指定的容器中运行任意的调试命令。
$ kubectl
exec
<
Pod
名称>
-
c
<
Pod
中的容器名称>
--
<任意命令>
<命令参数列表...>
值得指出的是,对于只有一个容器的Pod情况,
-c <Pod中的容器名称>
这个参数是可以省略的。
例如查看一个运行中的Cassandra日志文件内容,可以参考下面这个命令:
$ kubectl
exec
cassandra
--
cat
/
var
/
log
/
cassandra
/
system
.
log
要是上面的这些办法都不奏效,你也可以找到正在运行该Pod的主机地址,然后使用SSH登陆进去检测。但这是在确实迫不得已的情况下才会采用的措施,通常使用Kubernetes暴露的API应该足够获得所需的环境信息。因此,如果当你发现自己不得不登陆到主机上去获取必要的信息数据时,不妨到Kubernetes的GitHub页面中给我们提一个功能需求(Feature Request),在需求中附上详细的使用场景以及为什么当前Kubernetes所提供的工具不能够满足需要。
Pod在运行但没有如预期工作
如果Pod没有按照预期的功能运行,有可能是由于在Pod描述文件中(例如你本地机器的
mypod.yaml
文件)存在一些错误,这些配置中的错误在Pod时创建并没有引起致命的故障。这些错误通常包括Pod描述的某些元素嵌套层级不正确,或是属性的名称书写有误(这些错误属性在运行时会被忽略掉)。举例来说,如果你把
command
属性误写为了
commnd
,Pod仍然会启动,但用户所期待运行的命令则不会被执行。
对于这种情况,首先应该尝试删掉正在运行的Pod,然后使用
--validate
参数重新运行一次。继续之前的例子,当执行
kubectl create --validate -f mypod.yaml
命令时,被误写为
commnd
的
command
指令会导致下面这样的错误:
I0805
10
:
43
:
25.129850
46757
schema
.
go
:
126
]
unknown field
:
commnd
I0805
10
:
43
:
25.129973
46757
schema
.
go
:
129
]
this
may be a
false
alarm
,
see https
:
//github.com/kubernetes/kubernetes/issues/6842
pods
/
mypod
下一件事是检查当前apiserver运行Pod所使用的Pod描述文件内容是否与你想要创建的Pod内容(用户本地主机的那个yaml文件)一致。比如,执行
kubectl get pods/mypod -o yaml > mypod-on-apiserver.yaml
命令将正在运行的Pod描述文件内容导出来保存为
mypod-on-apiserver.yaml
,并将它和用户自己的Pod描述文件
mypod.yaml
进行对比。由于apiserver会尝试自动补全一些缺失的Pod属性,在apiserver导出的Pod描述文件中有可能比本地的Pod描述文件多出若干行,这是正常的,但反之如果本地的Pod描述文件比apiserver导出的Pod描述文件多出了新的内容,则很可能暗示着当前运行的Pod使用了不正确的内容。
排查Replication Controllers的故障
Replication Controllers的逻辑十分直白,它的作用只是创建新的Pod副本,仅仅可能出现的错误便是它无法创建正确的Pod,对于这种情况,应该参考上面的『排查Pods的故障』部分进行检查。
也可以使用
kubectl describe rc <控制器名称>
来显示与指定Replication Controllers相关的事件信息。
排查Services的故障
Service为一系列后端Pod提供负载均衡的功能。有些十分常见的故障都可能导致Service无法正常工作,以下将提供对调试Service相关问题的参考。
首先,检查Service连接的服务提供端点(endpoint),对于任意一个Service对象,apiserver都会为其创建一个端点资源(译者注:即提供服务的IP地址和端口号)。
这个命令可以查看到Service的端口资源:
$ kubectl
get
endpoints
<
Service
名称>
请检查这个命令输出端点信息中的端口号与实际容器提供服务的端口号是否一致。例如,如果你的Service使用了三个Nginx容器的副本(replicas),这个命令应该输出三个不同的IP地址的端点信息。
服务没有端点信息
如果刚刚的命令显示Service没有端点信息,请尝试通过Service的选择器找到具有相应标签的所有Pod。假设你的Service描述选择器内容如下:
...
spec
:
-
selector
:
name
:
nginx
type
:
frontend
可以使用以下命令找出相应的Pod:
$ kubectl
get
pods
--
selector
=
name
=
nginx
,
type
=
frontend
找到了符合标签的Pod后,首先确认这些被选中的Pod是正确,有无错选、漏选的情况。
如果被选中的Pod没有问题,则问题很可能出在这些Pod暴露的端口没有被正确的配置好。要是一个Service指定了
containerPort
,但被选中的Pod并没有在配置中列出相应的端口,它们就不会出现在端点列表中。
请确保所用Pod的
containerPort
与Service的
containerPort
配置信息是一致的。
网络流量没有正确的转发
如果你能够连接到Service,但每次连接上就立即被断开,同时Service的端点列表内容是正确的,很可能是因为Kubernetes的kube-proxy服务无法连接到相应的Pod。
请检查以下几个方面:
-
Pod是否在正常工作?从每个Pod的自动重启动次数可以作为有用的参考信息,前面介绍过的Pod错误排查也介绍了更详细的方法
-
能够直接连接到Pod提供的服务端口上吗?不妨获取到Pod的IP地址,然后尝试直接连接它,以验证Pod本身十分运行正确。
-
容器中的应用程序是否监听在Pod和Service中配置的那个端口?Kubernetes不会自动的映射端口号,因此如果应用程序监听在8080端口,务必保证Service和Pod的 containerPort 都配置为了8080。
其他问题
如果上述的这些步骤还不足以解答你所遇到的问题,也就是说你已经确认了相应的Service正在运行,并且具有恰当的端点资源,相应的Pod能够提供正确的服务,集群的DNS域名服务没有问题,IPtable的防火墙配置没有问题,kube-proxy服务也都运转正常。