vi /etc/kubernets
在部署第一个应用程序 中,我们使用了 kubectl 命令行界面部署了 nginx 并且查看了 Deployment 和 Pod。kubectl 还有如下四个常用命令,在我们排查问题时可以提供帮助:
kubectl get - 显示资源列表
# kubectl get 资源类型
#获取类型为Deployment的资源列表
kubectl get deployments
#获取类型为Pod的资源列表
kubectl get pods
#获取类型为Node的资源列表
kubectl get nodes
名称空间
在命令后增加 -A 或 --all-namespaces 可查看所有 名称空间中 的对象,使用参数 -n 可查看指定名称空间的对象,例如
# 查看所有名称空间的
Deploymentkubectl get deployments -A
kubectl get deployments --all-namespaces
# 查看 kube-system 名称空间的
Deploymentkubectl get deployments -n kube-system
kubectl describe - 显示有关资源的详细信息
# kubectl describe 资源类型 资源名称
#查看名称为nginx-XXXXXX的Pod的信息
kubectl describe pod nginx-XXXXXX
#查看名称为nginx的Deployment的信息
kubectl describe deployment nginx
**kubectl logs** - 查看pod中的容器的打印日志(和命令docker logs 类似)
# kubectl logs Pod名称
#查看名称为nginx-pod-XXXXXXX的Pod内的容器打印的日志
本案例中的 nginx-pod 没有输出日志,所以您看到的结果是空的
kubectl logs -f nginx-pod-XXXXXXX
**kubectl exec** - 在pod中的容器环境内执行命令(和命令docker exec 类似)
kubectl exec Pod名称 操作命令# 在名称为nginx-pod-xxxxxx的Pod中运行bash
kubectl exec -it nginx-pod-xxxxxx /bin/bash
kubectl -n kube-system get po
kubectl -n kube-system get po -o wide
kubectl get node
journalctl -fu docker
journalctl -fu kubectl
kubectl get nodes
kubectl get pods
kubectl api-resources
docker logs -f <ID>
###查看namespace
kubectl get ns
###创建namespace
kubectl create ns nie
###配置好yaml,通过“one-pod.yaml”创建pod
kubectl create -f one-pod.yaml
在执行请求时设定namespace
执行 kubectl 命令时,可以使用 --namespace 参数指定名称空间,例如:
kubectl run nginx --image=nginx --namespace=<您的名称空间>
kubectl get pods --namespace=<您的名称空间>
设置名称空间偏好
可以通过 set-context
命令改变当前的名称空间,后续所有命令都默认在此名称空间下执行。
kubectl config set-context --current --namespace=<您的名称空间>
# 验证结果
kubectl config view --minify | grep namespace:
并非所有对象都在名称空间里
大部分的 Kubernetes 对象(例如,Pod、Service、Deployment、StatefulSet等)都必须在名称空间里。但是某些更低层级的对象,是不在任何名称空间中的,例如 [nodes]、[storageClass] 等
执行一下命令可查看哪些 Kubernetes 对象在名称空间里,哪些不在:
# 在名称空间里
kubectl api-resources --namespaced=true
# 不在名称空间里
kubectl api-resources --namespaced=false
查看名称空间
查看集群中的名称空间列表:
kubectl get namespaces
输出结果如下所示:
NAME STATUS AGE
default Active 11d
kube-system Active 11d
kube-public Active 11d
Kubernetes 安装成功后,默认有初始化了三个名称空间:
default 默认名称空间,如果 Kubernetes 对象中不定义 metadata.namespace 字段,该对象将放在此名称空间下
kube-system Kubernetes系统创建的对象放在此名称空间下
kube-public 此名称空间自动在安装集群是自动创建,并且所有用户都是可以读取的(即使是那些未登录的用户)。主要是为集群预留的,例如,某些情况下,某些Kubernetes对象应该被所有集群用户看到。
查看名称空间的概要信息:
kubectl describe namespaces <name>
输出结果如下所示:
Name: default
Labels: <none>
Annotations: <none>
Status: Active
No resource quota.
Resource Limits
Type Resource Min Max Default
---- -------- --- --- ---
Container cpu - - 100m
创建名称空间
使用 kubectl 有两种方式可以创建名称空间
1.通过 yaml 文件,创建文件 my-namespace.yaml 内容如下:
apiVersion: v1
kind: Namespace
metadata:
name: <名称空间的名字>
执行命令
```
kubectl create -f ./my-namespace.yaml
```
2.直接使用命令创建名称空间:
```
kubectl create namespace <名称空间的名字>
```
在 Kuboard 中创建名称空间,请参考 [名称空间管理]
删除名称空间
执行如下命令可删除名称空间:
kubectl delete namespaces <名称空间的名字>
WARNING
该操作将删除名称空间中的所有内容
此删除操作是异步的,您可能会观察到名称空间停留会在 Terminating
状态停留一段时间。
使用名称空间切分集群)使用名称空间切分集群
理解-default-名称空间)理解 default
名称空间
默认情况下,安装Kubernetes集群时,会初始化一个 default
名称空间,用来将承载那些未指定名称空间的 Pod、Service、Deployment等对象
创建新的名称空间)创建新的名称空间
在此练习中,我们将创建两个 Kubernetes 名称空间。
假设企业使用同一个集群作为开发环境和生产环境(注意:通常开发环境和生产环境是物理隔绝的):
- 开发团队期望有一个集群中的空间,以便他们可以查看查看和使用他们创建的 Pod、Service、Deployment等。在此空间中,Kubernetes对象被创建又被删除,为了适应敏捷开发的过程,团队中的许多人都可以在此空间内做他们想做的事情。
- 运维团队也期望有一个集群中的空间,在这里,将有严格的流程控制谁可以操作 Pod、Service、Deployment等对象,因为这些对象都直接服务于生产环境。
此时,该企业可以将一个Kubernetes集群切分成两个名称空间:development
和 production
。创建名称空间的 yaml 文件如下所示:
apiVersion: v1
kind: Namespace
metadata:
name: development
labels:
name: development
执行命令以创建 development
名称空间:
kubectl create -f https://kuboard.cn/statics/learning/namespace/dev.yaml
执行命令以创建 production
名称空间:
kubectl create -f https://kuboard.cn/statics/learning/namespace/prod.yaml
执行命令查看已创建的名称空间
kubectl get namespaces --show-labels
输出结果如下所示
NAME STATUS AGE LABELS
default Active 32m <none>
development Active 29s name=development
production Active 23s name=production
在每个名称空间中创建-pod)在每个名称空间中创建 Pod
Kubernetes名称空间为集群中的 Pod、Service、Deployment 提供了一个作用域。可以限定使用某个名称空间的用户不能看到另外一个名称空间中的内容。我们可以在 development
名称空间中创建一个简单的 Deployment 和 Pod 来演示这个特性。
-
首先,执行命令以检查当前的 [kubectl切换当前访问的集群)
kubectl config view
输出结果如下所示:
apiVersion: v1 clusters: - cluster: certificate-authority-data: REDACTED server: https://130.211.122.180 name: lithe-cocoa-92103_kubernetes contexts: - context: cluster: lithe-cocoa-92103_kubernetes user: lithe-cocoa-92103_kubernetes name: lithe-cocoa-92103_kubernetes current-context: lithe-cocoa-92103_kubernetes kind: Config preferences: {} users: - name: lithe-cocoa-92103_kubernetes user: client-certificate-data: REDACTED client-key-data: REDACTED token: 65rZW78y8HbwXXtSXuUw9DbP4FLjHi4b - name: lithe-cocoa-92103_kubernetes-basic-auth user: password: h5M0FtUUIflBSdI7 username: admin
执行命令
kubectl config current-context
输出结果如下所示
lithe-cocoa-92103_kubernetes
-
接下来,为 kubectl 定义一个上下文,以便在不同的名称空间中工作。
cluster
和user
字段的取值从前面的 current context 复制过来:kubectl config set-context dev --namespace=development --cluster=lithe-cocoa-92103_kubernetes --user=lithe-cocoa-92103_kubernetes kubectl config set-context prod --namespace=production --cluster=lithe-cocoa-92103_kubernetes --user=lithe-cocoa-92103_kubernetes
上面的命令创建了两个 kubectl 的上下文,使得您可以在两个不同的名称空间中工作:
-
切换到
development
名称空间:kubectl config use-context dev
验证
kubectl config current-context dev
此时,通过 kubectl 向 Kubernetes 集群发出的所有指令都限定在名称空间
development
里创建一个 nginx
kubectl run snowflake --image=nginx:1.7.9 --replicas=2
刚刚创建的 Deployment 副本数为 2,运行了一个 nginx 容器。
kubectl get deployment
输出结果如下
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE snowflake 2 2 2 2 2m
执行命令
kubectl get pods -l run=snowflake
输出结果如下
NAME READY STATUS RESTARTS AGE snowflake-3968820950-9dgr8 1/1 Running 0 2m snowflake-3968820950-vgc4n 1/1 Running 0 2m
此时,开发人员可以做任何他想要做的操作,所有操作都限定在名称空间
development
里,而无需担心影响到production
名称空间中的内容。 -
切换到
production
名称空间:kubectl config use-context prod
production
名称空间应该是空的,下面两个命令将返回的结果都应该为空:kubectl get deployment kubectl get pods
此时,我们在 production 名称空间运行另一个 deployment:
kubectl run cattle --image=nginx:1.7.9 --replicas=5 kubectl get deployment
输出结果如下所示:
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE cattle 5 5 5 5 10s
执行命令
kubectl get pods -l run=cattle
输出结果如下所示:
NAME READY STATUS RESTARTS AGE cattle-2263376956-41xy6 1/1 Running 0 34s cattle-2263376956-kw466 1/1 Running 0 34s cattle-2263376956-n4v97 1/1 Running 0 34s cattle-2263376956-p5p3i 1/1 Running 0 34s cattle-2263376956-sxpth 1/1 Running 0 34s
至此,我们可以了解到,用户在一个名称空间创建的内容对于另外一个名称空间来说是不可见的。
也可以为不同的名称空间定义不同的访问权限控制。敬请期待后续更新。
标签的 value 必须:
- 不能多于 63 个字符
- 可以为空字符串
- 如果不为空,则
- 必须由字母、数字开始和结尾
- 可以包含字母、数字、减号
-
、下划线_
、小数点.
例如,下面的例子中的Pod包含两个标签 environment: production
和 app:nginx
apiVersion: v1
kind: Pod
metadata:
name: label-demo
labels:
environment: production
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
标签选择器)标签选择器
与 [name 和 UID]不同,标签不一定是唯一的。通常来讲,会有多个Kubernetes对象包含相同的标签。通过使用标签选择器(label selector),用户/客户端可以选择一组对象。标签选择器(label selector)是 Kubernetes 中最主要的分类和筛选手段。
Kubernetes api server支持两种形式的标签选择器,equality-based 基于等式的
和 set-based 基于集合的
。标签选择器可以包含多个条件,并使用逗号分隔,此时只有满足所有条件的 Kubernetes 对象才会被选中。
如果使用空的标签选择器或者不指定选择器,其含义由具体的 API 接口决定。
基于等式的选择方式)基于等式的选择方式
Equality- 或者 inequality-based 选择器可以使用标签的名和值来执行过滤选择。只有匹配所有条件的对象才被选中(被选中的对象可以包含未指定的标签)。可以使用三种操作符 =
、==
、!=
。前两个操作符含义是一样的,都代表相等,后一个操作符代表不相等。例如:
# 选择了标签名为 `environment` 且 标签值为 `production` 的Kubernetes对象
environment = production
# 选择了标签名为 `tier` 且标签值不等于 `frontend` 的对象,以及不包含标签 `tier` 的对象
tier != frontend
也可以使用逗号分隔的两个等式 environment=production,tier!=frontend
,此时将选中所有 environment
为 production
且 tier
不为 frontend
的对象。
以 [Pod 的节点选择器]节点选择器-nodeselector) 为例,下面的 Pod 可以被调度到包含标签 accelerator=nvidia-tesla-p100
的节点上:
apiVersion: v1
kind: Pod
metadata:
name: cuda-test
spec:
containers:
- name: cuda-test
image: "k8s.gcr.io/cuda-vector-add:v0.1"
resources:
limits:
nvidia.com/gpu: 1
nodeSelector:
accelerator: nvidia-tesla-p100
基于集合的选择方式)基于集合的选择方式
Set-based 标签选择器可以根据标签名的一组值进行筛选。支持的操作符有三种:in
、notin
、exists
。例如:
# 选择所有的包含 `environment` 标签且值为 `production` 或 `qa` 的对象
environment in (production, qa)
# 选择所有的 `tier` 标签不为 `frontend` 和 `backend`的对象,或不含 `tier` 标签的对象
tier notin (frontend, backend)
# 选择所有包含 `partition` 标签的对象
partition
# 选择所有不包含 `partition` 标签的对象
!partition
可以组合多个选择器,用 ,
分隔,,
相当于 AND
操作符。例如:
# 选择包含 `partition` 标签(不检查标签值)且 `environment` 不是 `qa` 的对象
partition,environment notin (qa)
基于集合的选择方式是一个更宽泛的基于等式的选择方式,例如,environment=production
等价于 environment in (production)
;environment!=production
等价于 environment notin (production)
。
基于集合的选择方式可以和基于等式的选择方式可以混合使用,例如: partition in (customerA, customerB),environment!=qa
API
查询条件
LIST 和 WATCH 操作时,可指定标签选择器作为查询条件,以筛选指定的对象集合。两种选择方式都可以使用,但是要符合 URL 编码,例如:
- 基于等式的选择方式:
?labelSelector=environment%3Dproduction,tier%3Dfrontend
- 基于集合的选择方式:
?labelSelector=environment+in+%28production%2Cqa%29%2Ctier+in+%28frontend%29
两种选择方式都可以在 kubectl 的 list 和 watch 命令中使用,例如:
-
使用基于等式的选择方式
kubectl get pods -l environment=production,tier=frontend
-
使用基于集合的选择方式
kubectl get pods -l 'environment in (production),tier in (frontend)'
#Kubernetes对象引用
某些 Kubernetes 对象中(例如,Service和Deployment),使用标签选择器指定一组其他类型的 Kubernetes 对象(例如,Pod)
#Service
Service 中通过 spec.selector
字段来选择一组 Pod,并将服务请求转发到选中的 Pod 上。
在 yaml 或 json 文件中,标签选择器用一个 map 来定义,且支持基于等式的选择方式,例如:
"selector": {
"component" : "redis",
}
或
selector:
component: redis
上面的例子中定义的标签选择器等价于 component=redis
或 component in (redis)
#有些对象支持基于集合的选择方式
Job
、Deployment
、ReplicaSet
和 DaemonSet
同时支持基于等式的选择方式和基于集合的选择方式。例如:
selector:
matchLabels:
component: redis
matchExpressions:
- {key: tier, operator: In, values: [cache]}
- {key: environment, operator: NotIn, values: [dev]}
matchLabels
是一个 {key,value} 组成的 map。map 中的一个 {key,value} 条目相当于 matchExpressions
中的一个元素,其 key
为 map 的 key,operator
为 In
, values
数组则只包含 value
一个元素。matchExpression
等价于基于集合的选择方式,支持的 operator
有 In
、NotIn
、Exists
和 DoesNotExist
。当 operator
为 In
或 NotIn
时,values
数组不能为空。所有的选择条件都以 AND 的形式合并计算,即所有的条件都满足才可以算是匹配。
引用一组节点
可以通过标签选择器将 Pod 调度到指定的节点上,请参考 [将容器组调度到指定的节点]
向Kubernetes对象添加注解
Kubernetes 对象的 metadata 字段可以添加自定义的标签(label)或者注解(annotation)。标签用来选择对象或者用来查找符合指定条件的一组对象。与此相对,注解不是用来标记对象或者选择对象的。metadata 中的注解可以很大,也可以很小;可以是结构化的,也可以是非结构化的;还可以包括标签中不允许出现的字符。
与标签相似,注解也是 key/value map,例如:
metadata:
annotations:
key1: value1
key2: value2
类似于下面的信息可以记录在注解中:
声明式配置层用到的状态信息。
Build、release、image信息,例如 timestamp、release ID、git branch、PR number、image hash、registry address
日志、监控、分析、审计系统的参数
第三方工具所需要的信息,例如 name、version、build information、URL
轻量级的发布工具用到的信息,例如,config、checkpoint
负责人的联系方式,例如,电话号码、网址、电子信箱
用户用来记录备忘信息的说明,例如,对标准镜像做了什么样的修改、维护过程中有什么特殊信息需要记住
下面是一个来自于实际 Deployment 的注解:
metadata:
annotations:
deployment.kubernetes.io/revision: 7 # 由Deployment控制器添加,用于记录当前发布的修改次数
k8s.eip.work/displayName: busybox # Kuboard添加,Deployment显示在Kuboard界面上的名字
k8s.eip.work/ingress: false # Kuboard添加,根据此参数显示Deployment是否配置了Ingress
k8s.eip.work/service: none # Kuboard添加,根据此参数显示Deployment是否配置了Service
除了使用注解,您也可以将这类信息存放在一个外部的数据库,然而,在使用、分享这些信息的时候,可能会变得难以管理。
句法和字符集
注解是一组名值对。
注解的 key 有两个部分:可选的前缀和标签名,通过 / 分隔。
注解名:
标签名部分是必须的
不能多于 63 个字符
必须由字母、数字开始和结尾
可以包含字母、数字、减号-、下划线_、小数点.
注解前缀:
注解前缀部分是可选的
如果指定,必须是一个DNS的子域名,例如:k8s.eip.work
不能多于 253 个字符
使用 / 和标签名分隔
如果省略注解前缀,则注解的 key 将被认为是专属于用户的。Kubernetes的系统组件(例如,kube-scheduler、kube-controller-manager、kube-apiserver、kubectl 或其他第三方组件)向用户的Kubernetes对象添加注解时,必须指定一个前缀。
kubernetes.io/ 和 k8s.io/ 这两个前缀是 Kubernetes 核心组件预留的。Kuboard 使用 k8s.eip.work 这个前缀。
下面的例子中,Pod包含一个注解 imageregistry: https://hub.docker.com/
apiVersion: v1
kind: Pod
metadata:
name: annotations-demo
annotations:
imageregistry: "https://hub.docker.com/"
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
概述
字段选择器(Field Selector)可以用来基于的一个或多个字段的取值来选取一组Kubernetes对象。下面有一些示例性的字段选择器:
metadata.name=my-service
metadata.namespace!=default
status.phase=Pending
下面的 kubectl
命令选择了所有字段 status.phase
的取值为 Running
的 Pod:
kubectl get pods --field-selector status.phase=Running
字段选择器本质上是一个 filter
。默认情况下,没有添加 selector/filter 时,代表着指定资源类型的所有对象都被选中。下面个两个 kubectl 查询时等价的:
kubectl get pods
kubectl get pods --field-selector ""
#支持的字段
不同的 Kubernetes 对象类型,可以用来查询的字段不一样。所有的对象类型都支持的两个字段是 metadata.name
和 metadata.namespace
。在字段选择器中使用不支持的字段,将报错。例如:
kubectl get ingress --field-selector foo.bar=baz
输出结果为:
Error from server (BadRequest): Unable to find "ingresses" that match label selector "", field selector "foo.bar=baz": "foo.bar" is not a known field selector: only "metadata.name", "metadata.namespace"
支持的操作符
字段选择器中可以使用的操作符有 =
、==
、!=
(=
和 ==
含义相同)。例如,下面的 kubectl
命令,查询不在 default
名称空间中的 Service:
kubectl get services --all-namespaces --field-selector metadata.namespace!=default
多选择器
可以指定多个字段选择器,用逗号 ,
分隔。下面的 kubectl
命令查询所有的 status.phase
不等于 Running
且 spec.restartPolicy
等于 Always
的 Pod:
kubectl get pods --field-selector=status.phase!=Running,spec.restartPolicy=Always
多种对象类型
字段选择器可以跨资源类型使用。下面的 kubectl
命令查询所有的不在 default
名称空间的 StatefulSet 和 Service:
kubectl get statefulsets,services --all-namespaces --field-selector metadata.namespace!=default