一 简介
1 POD 介绍
kubernetes 中最小的运行单元是POD,kubernetes不是直接调度容器,而是直接作用于POD,POD可以理解为容器的外壳,给容器一个抽象的封装。 POD 内可以包含多个容器,多个容器共享同一个底层网络,同一个POD内的容器只能运行在同一个node上,POD 是通过标签来识别的,因为在每次容器重启后,其IP地址将会发生改变。其标签的选择需要通过标签选择器来实现
2 POD 分类
1 自主式POD:
一般的,直接使用命令行创建的POD成为自主式POD
2 控制管理器控制管理的POD
通过控制器管理器创建和删除工作 常见的控制器 Repbcationcontroller ,通过控制器控制其数量,当其数量不足时,会自动增加,可以在容器不够的情况下重新请求再次创建一个。可以实现滚动更新,允许在创建过程中临时超出,也支持回滚操作,早期只有一个POD控制器 Repbcationset Deployment : 只负责管理那些无状态的服务,支持二级 控制器 HPA,可 自动增加容器,随时按需增加进程数量 horizontalPODauto Scatefulset :有状态管理级 Job : 在指定节点上运行指定服务,可以进行定期停止的,确保不同的资源来符合用户需求的
二 POD 对象资源格式
1 资源配置清单
kubernetes API 仅接受及响应JSON 格式的数据(JSON对象),同时,为了便于使用,其允许用户提供YAML格式的POST对象,但API SERVER 需要事先自动将其转换为JSON格式后方可提交,API SERVER 接受和返回的所有JSON对象都遵循同一个模式,它们都具有kind和apiVersion字段,用于标识对象所属的资源类型、API群组及相关版本
# 示例:
apiVersion: v1
kind: Namespace
metadata:
creationTimestamp: 2019-03-08T01:40:20Z
name: kube-system
resourceVersion: "11"
selfLink: /api/v1/namespaces/kube-system
uid: 22419fa2-4143-11e9-bdd7-000c298d1528
spec:
finalizers:
- kubernetes
status:
phase: Active
apiVersion : 指定版本
kind :指定资源类型
metadata: 提供元数据信息,标签等
必选字段:
namespace : 指定当前对象隶属的名称空间,默认是default
name : 指定当前对象的名称,其在所属的名称空间中必须唯一
uid : 当前对象的唯一标识符,其唯一性仅发生在特定的时间段和名称空间中,此标识符主要是用于区分拥有相同名字的"已删除"和"重新创建的"同一个名称的对象
可选字段通常由kubernetes系统自行维护和设置,或者存在默认,或者本身允许控制类型字段
可选字段
labels : 设定用于标识当前对象的标签,键值数据,常被用作挑选条件
annotations : 非标识性键值数据,用来作为挑选条件,是labels的补充
resourceVersion : 当前对象的内部版本标识符,用于让客户端确定对象变动与否
generation : 用于标识当前对象目标状态的代别
creation Timestamp : 当前对象的创建日期的时间戳
deletion timestamp : 当前删除日期的时间戳
spec: 用于定义用户的期望状态,不同的资源类型,其状态的意义各有不同
其字段对于不同的资源类型其差别较大,因此不能一概而论
status : 用于记录活动对象的当前信息,由kubernetes系统自行维护,对用户只读
2 内建文档,查看资源书写方式
相关一级字段查看
[root@master ~]# kubectl explain pods
KIND: Pod
VERSION: v1
DESCRIPTION:
Pod is a collection of containers that can run on a host. This resource is
created by clients and scheduled onto hosts.
FIELDS:
apiVersion <string>
APIVersion defines the versioned schema of this representation of an
object. Servers should convert recognized schemas to the latest internal
value, and may reject unrecognized values. More info:
https://git.k8s.io/community/contributors/devel/api-conventions.md#resources
kind <string>
Kind is a string value representing the REST resource this object
represents. Servers may infer this from the endpoint the client submits
requests to. Cannot be updated. In CamelCase. More info:
https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds
metadata <Object>
Standard object's metadata. More info:
https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata
spec <Object>
Specification of the desired behavior of the pod. More info:
https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status
status <Object>
Most recently observed status of the pod. This data may not be up to date.
Populated by the system. Read-only. More info:
https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status
相关二级字段查询
[root@master ~]# kubectl explain pods.spec
KIND: Pod
VERSION: v1
RESOURCE: spec <Object>
DESCRIPTION:
Specification of the desired behavior of the pod. More info:
https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status
PodSpec is a description of a pod.
FIELDS:
activeDeadlineSeconds <integer>
Optional duration in seconds the pod may be active on the node relative to
StartTime before the system will actively try to mark it failed and kill
associated containers. Value must be a positive integer.
affinity <Object> (此字段为可选字段,其为key,value格式)
If specified, the pod's scheduling constraints
automountServiceAccountToken <boolean>
AutomountServiceAccountToken indicates whether a service account token
should be automatically mounted.
containers <[]Object> -required- #(此处为必选字段,且其为list列表形式)
List of containers belonging to the pod. Containers cannot currently be
added or removed. There must be at least one container in a Pod. Cannot be
updated.
.
.
.
tolerations <[]Object> #(此字段非必选,但其为列表格式)
If specified, the pod's tolerations.
volumes <[]Object> #(此字段非必选,但其为列表格式)
List of volumes that can be mounted by containers belonging to the pod.
More info: https://kubernetes.io/docs/concepts/storage/volumes
查看其三级字段
[root@master ~]# kubectl explain pods.spec.containers
KIND: Pod
VERSION: v1
RESOURCE: containers <[]Object>
DESCRIPTION:
List of containers belonging to the pod. Containers cannot currently be
added or removed. There must be at least one container in a Pod. Cannot be
updated.
A single application container that you want to run within a pod.
FIELDS:
args <[]string>
Arguments to the entrypoint. The docker image's CMD is used if this is not
provided. Variable references $(VAR_NAME) are expanded using the
container's environment. If a variable cannot be resolved, the reference in
the input string will be unchanged. The $(VAR_NAME) syntax can be escaped
with a double $$, ie: $$(VAR_NAME). Escaped references will never be
expanded, regardless of whether the variable exists or not. Cannot be
updated. More info:
https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell
command <[]string>
Entrypoint array. Not executed within a shell. The docker image's
ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME)
are expanded using the container's environment. If a variable cannot be
resolved, the reference in the input string will be unchanged. The
$(VAR_NAME) syntax can be escaped with a double $$, ie: $$(VAR_NAME).
Escaped references will never be expanded, regardless of whether the
variable exists or not. Cannot be updated. More info:
https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell
env <[]Object>
List of environment variables to set in the container. Cannot be updated.
envFrom <[]Object>
List of sources to populate environment variables in the container. The
keys defined within a source must be a C_IDENTIFIER. All invalid keys will
be reported as an event when the container is starting. When a key exists
in multiple sources, the value associated with the last source will take
precedence. Values defined by an Env with a duplicate key will take
precedence. Cannot be updated.
image <string> # 定义其镜像的镜像源
Docker image name. More info:
https://kubernetes.io/docs/concepts/containers/images This field is
optional to allow higher level config management to default or override
container images in workload controllers like Deployments and StatefulSets.
imagePullPolicy <string> # 定义镜像的策略
Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always
if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated.
More info:
https://kubernetes.io/docs/concepts/containers/images#updating-images
.
.
.
terminationMessagePolicy <string>
Indicate how the termination message should be populated. File will use the
contents of terminationMessagePath to populate the container status message
on both success and failure. FallbackToLogsOnError will use the last chunk
of container log output if the termination message file is empty and the
container exited with an error. The log output is limited to 2048 bytes or
80 lines, whichever is smaller. Defaults to File. Cannot be updated.
tty <boolean>
Whether this container should allocate a TTY for itself, also requires
'stdin' to be true. Default is false.
volumeDevices <[]Object>
volumeDevices is the list of block devices to be used by the container.
This is an alpha feature and may change in the future.
volumeMounts <[]Object>
Pod volumes to mount into the container's filesystem. Cannot be updated.
3 实例
1 [root@master ~]# cat demo.yaml
apiVersion: v1 # 定义版本(资源类型不同,其版本可能不同)
kind: Pod #(定义资源类型)
metadata: #(定义元数据)
name: demo-nginx #(定义pod名称)
namespace: default #(定义pod隶属的名称空间)
spec:
containers:
- name: demo-nginx #(定义容器名称,一个POD中可包含多个容器)
image: nginx:1.14 #(定义容器镜像名称)
ports: #(定义容器暴露端口)
- name: http #(暴露端口名称)
containerPort: 80 #(暴露端口)
- name: demo-tomcat
image: tomcat:8.5.35
ports:
- name: tomcat
containerPort: 8080
2 构建
kubectl apply -f demo.yaml
查看结果
[root@master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE
demo-nginx 2/2 Running 0 5m23s 10.244.0.27 master <none>
nginx 1/1 Running 3 44h 10.244.0.12 master <none>
pod1 1/1 Running 4 4d18h 10.244.0.20 master <none>
3 验证
#[root@master ~]# curl 10.244.0.27
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
Welcome to nginx!
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a rel="nofollow" href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a rel="nofollow" href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@master ~]# curl 10.244.0.27:8080
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Apache Tomcat/8.5.35</title>
<link href="favicon.ico" rel="icon" type="image/x-icon" />
<link href="favicon.ico" rel="shortcut icon" type="image/x-icon" />
<link href="tomcat.css" rel="stylesheet" type="text/css" />
.
.
.
三 资源对象管理方式
1 kubectl (api server客户端)命令分类:
1 陈述式命令
代码侧重于通过创建一种告诉计算机如何执行操作的算法类更改程序状态的语句来完成,如 run 、expose 、 delete 和 get等 陈述式管理方式包括 create delete 和 get 、replace 等,其通过资源配置清单读取需要管理的目标资源对象,陈述式对象的管理操作直接作用于活动对象,即便是修改极小的内容,使用replace命令进行更新操作也将导致整个对象被替换
2 陈述式对象配置
其缺单是同一目录下的配置文件必须同时进行同一种操作,要么都更新,要么都创建
3 声明式对象配置
kubernetes 的API server遵循声明式编程范式而设计,侧重于构建程序逻辑而无需关注程序实现流程,用户只需要设定期望状态,系统自行确定需要执行的操作以确保达到用户期望的状态。
2 kubectl 命令与资源管理
1 资源管理操作概述
资源的管理操作可归结为 增、删、改、查四种,kubectl 针对此中情况提供了命令,如 create、delete、patch、apply、replace、edit、get等,其中有些工具必须是基于清单来进行,如apply和replace命令,有些既可以是清单,也可以是实时作用于活动资源之上,如 create、get、patch 和 delete 等
kubectl 命令能读取任何以.yaml 、 .yml 或 .json 为后缀的文件,kubectl 的多数命令支持使用"-f"选项指定使用的清单文件路径或URL,也可以是存储有清单文件的目录。同一命令中可以重复使用多次,如果在指定的目录路径存在子目录时,可按需使用-R选项以递归的方式获取子目录中的配置清单
2 kubectl 基本用法
其提供了基于命令行访问kubernetes API 的简介方式,能够满足对kubernetes的绝大部分操作需求。
**语法 : kubectl [command] [TYPE] [NAME] [flags]
**
1 command : 对资源执行响应操作的子命令,如get(获取资源简要信息),create(根据资源清单创建资源)、delete(删除资源),run(启动运行资源)
2 TYPE: 要操作的资源对象类型,如 pods,services等,
3 NAME:对象名称,区分大小写,如果省略,则表示指定TYPE中的所有资源,也可"TYPE/NAME" 的格式来表示资源对象
4 flags:命令行选项,如"-s" 或 "--server
详情请参考 :http://docs.kubernetes.org.cn/683.html
3 管理名称空间资源
名称空间是kubernetes 集群级别的资源,用于将集群分隔为多个隔离的逻辑分区以配置给不同的用户、租户、环境或项目使用,
kubernetes 的绝大多数资源都隶属于名称空间级别,名称空间资源为这类资源名称提供了隔离的作用域,同一名称空间内的同一类型的资源名必须是唯一的,但跨名称空间时并无此限制。kubernetes中还有一些资源隶属于集群级别的,如Node,namespace 和persistentVolume等资源,其不属于任何名称空间,因此资源对象的名称必须是全局唯一。
kubernetes 的名称空间资源不能实现Pod之间的通信隔离,仅用于限制资源对象名称的作用域。 kubernetes 集群默认提供了几个名称空间用于特定的目的,kube-system主要用于运行系统级别的资源,而default则为那些为指定名称空间的资源操作提供默认值
1 查看名称空间及资源对象
1 查看名称空间
[root@master ~]# kubectl get namespaces
NAME STATUS AGE
default Active 12d
ingress-nginx Active 8d
kube-public Active 12d
kube-system Active 12d
prom Active 11d
web Active 2d
2 查看详细信息
[root@master ~]# kubectl describe namespace default
Name: default
Labels: <none>
Annotations: <none>
Status: Active
No resource quota.
No resource limits.
3 查看其它资源下的pod
[root@master ~]# kubectl get pods -n prom
NAME READY STATUS RESTARTS AGE
custom-metrics-apiserver-746485c45d-kjl9p 1/1 Running 5 5d
kube-state-metrics-68d7c699c6-lghtm 1/1 Running 5 5d
monitoring-grafana-7f99994bc4-kgqrq 1/1 Running 5 5d
prometheus-node-exporter-nxdls 1/1 Running 5 5d
prometheus-server-77c8c48b9-cvf6z 1/1 Running 5 5d
2 管理namespace
1 创建名称空间 kubectl create namespace web1 其仅支持字母、数字、连接线、下划线等字符组成。 文本创建:
# demonamespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: web2
创建
kubectl apply -f demonamespace.yaml
查看
[root@master ~]# kubectl get namespace
NAME STATUS AGE
default Active 12d
ingress-nginx Active 8d
kube-public Active 12d
kube-system Active 12d
prom Active 11d
web Active 2d
web1 Active 19m
web2 Active 6s
四 POD 资源的创建和管理
Pod是kubernetes API中的核心资源类型,其可以定义在JSON 或 YAML格式的资源清单中,由资源管理命令陈述式或声明式管理。
1 陈述式对象配置管理方式
用户创建配置文件指定要管理的目标资源对象,而后再由用户借助命令直接执行kubernetes系统要执行的管理操作的管理方式,常用命令有create、delete、replace、get 和 describe
1 创建POD
#[root@master all]# cat nginx.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx1
namespace: web1
spec:
containers:
- name: nginx-web
image: nginx:1.14
ports:
- name: http
containerPort: 80
运行pod
kubectl apply -f nginx.yaml
查看pod
#[root@master all]# kubectl get pods -n web1
NAME READY STATUS RESTARTS AGE
nginx1 1/1 Running 0 8s
指定输出格式
[root@master all]# kubectl get pods -n web1 -o yaml
[root@master all]# kubectl get pods -n web1 -o json
2 更新pod
对于活动对象,并非每个属性值都支持修改,如pod资源的metadata.name字段不支持修改,处分先delete删除后重新创建
更新
导出
kubectl get pods -n web1 -o yaml > nginx.yaml
修改
重新部署
kubectl replace -f nginx.yaml --force
删除POD
kubectl delete -f nginx.yaml
查看
[root@master all]# kubectl get pods -n web1
No resources found.
2 声明式对象配置管理方式
陈述式对象管理机制中,同时制定多个资源必须进行同一种操作,而且replace命令是通过完全替代现有的活动对象来进行资源的更新操作,对于生产环境来说,这并非理想选择,声明式对象配置操作在管理资源对象时将配置信息保存于目标对象的注解中,并通过比较活动对象的当前配置,前一次管理操作时存储于注解中的配置,以及当前命令提供的配置生成更新补丁从而完成活动对象的补丁式更新操作,此类管理操作的常用命令有apply和patch等。
更新
#[root@master all]# cat nginx.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx1
namespace: web1
spec:
containers:
- name: nginx-web
image: nginx:1.12
ports:
- name: http
containerPort: 80
[root@master all]# kubectl apply -f nginx.yaml
pod/nginx1 configured
[root@master all]# kubectl get pods -n web1
NAME READY STATUS RESTARTS AGE
nginx1 1/1 Running 1 19s
3 管理POD 对象容器
一个POD对象中至少要存在一个容器,因此containers字段是定义POD资源时spec的必选字段,用于为POD指定要创建的容器列表,进行容器配置时,name为必选字段,用于指定容器的名称,image为可选字段,以方便更高级别的管理类资源(如deployment)等能覆盖此字段,于是自主式的POD并不是可省略此字段
1 镜像及其或其策略
各工作节点负责运行POD对象,而POD的核心功能用在运行容器,因此工作节点上必须配置运行引擎,如docker,启动容器时,容器引擎将自动拉取镜像。拉取镜像的方式
[root@master all]# kubectl explain pods.spec.containers.imagePullPolicy
KIND: Pod
VERSION: v1
FIELD: imagePullPolicy <string>
DESCRIPTION:
Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always
if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated.
More info:
https://kubernetes.io/docs/concepts/containers/images#updating-images
Always: 镜像标签为"latest"或镜像不存在时总是从指定仓库获取镜像 IfNotPresent: 仅当本地镜像缺失时才从目标仓库下载镜像 Never: 禁止从仓库下载,仅使用本地镜像
注:对于镜像标签为latest的镜像,其默认策略为"Always",而对于其他标签,其默认策略为"IfNotPresent",如果使用私有仓库需要认证,则可通过imagePullSecretes 字段调用此认证信息完成。
2 暴露端口
kubernetes 系统的网络模型中,各POD的IP地址处于同一网络平面,无论是否为容器指定了要暴露的端口,都不会影响集群中其他节点之上的POD客户端对其访问,这就意味着,任何监听在非lo接口上的端口都可以通过POD网络直接被请求,显式的执行端口,只是为集群用户提供一个快速了解相关POD对象的可访问端口的途径,而显式指定容器端口,还能为其赋予名称以方便调用
kubectl explain pods.spec.containers.ports
FIELDS:
containerPort <integer> -required- #必选字段,指定在POD对象的IP地址上暴露的容器端口,其有效范围是(0,65536),使用时,应该总是指定容器应用正常监听者的端口
Number of port to expose on the pod's IP address. This must be a valid port
number, 0 < x < 65536.
hostIP <string>#
What host IP to bind the external port to.
hostPort <integer> # 主机端口,他将接受到的请求通过NAT机制转发至由containerPort字段指定的容器端口
Number of port to expose on the host. If specified, this must be a valid
port number, 0 < x < 65536. If HostNetwork is specified, this must match
ContainerPort. Most containers do not need this.
name <string> # 当前端口的名称,必须符合IANA_SVC_NAME规范且在当前POD内必须是唯一的,此端口名可被service资源调用
If specified, this must be an IANA_SVC_NAME and unique within the pod. Each
named port in a pod must have a unique name. Name for the port that can be
referred to by services.
protocol <string> # 端口相关协议,其值仅可为TCP或UDP,默认是TCP
Protocol for port. Must be UDP, TCP, or SCTP. Defaults to "TCP".
实例:
apiVersion: v1
kind: Pod
metadata:
name: nginx1
namespace: web1
spec:
containers:
- name: nginx-web
image: nginx:1.12
ports:
- name: http
containerPort: 80
hostPort: 89
protocol: TCP
外部访问
3 自定义运行容器化应用
容器的command字段能够指定不同于镜像默认运行的应用程序,并且可以同时为使用args字段进行参数传递,它们将覆盖镜像中默认定义,如果仅为容器定义了args字段,那么他将作为参数传递给镜像中默认指定运行的应用程序,如果仅指定了command字段,那么他将覆盖镜像中定义的程序及参数,并以无参数方式运行应用程序。
apiVersion: v1
kind: Pod
metadata:
name: demo
spec:
containers:
- name: demo
image: alpine:latest
command: ["/bin/sh"]
args: ["-c","while true; do sleep 30; done"]
4 环境变量
非容器化的传统管理方式中,复杂的应用程序的配置信息多数由配置文件进行指定,用户可借助文本完成配置,对于容器隔离出的环境中的应用程序,用户就需要穿透容器边界在容器内进行配置编辑并进行重载,这种方式复杂,环境变量的方式传递便成为一种潮流。
这种方式依赖于应用程序支持通过环境表示变量进行配置的能力,否则,用户在制作docker镜像时需要通过entrypoint脚本完成变量到程序配置文件的同步。
1 env
需要在容器配置端中嵌套使用env字段,他的值是一个由环境变 量构成的列表,通常包含name和value字段构成
[root@master1 ~]# kubectl explain pod.spec.containers.env
KIND: Pod
VERSION: v1
RESOURCE: env <[]Object>
DESCRIPTION:
List of environment variables to set in the container. Cannot be updated.
EnvVar represents an environment variable present in a Container.
FIELDS:
name <string> -required- #环境变量名称,必选字段
Name of the environment variable. Must be a C_IDENTIFIER.
value <string> #传递给环境变量的值,通过$(VAR_NAME)引用,逃逸格式为"$$(VAR_NAME)",默认为空
Variable references $(VAR_NAME) are expanded using the previous defined
environment variables in the container and any service environment
variables. If a variable cannot be resolved, the reference in the input
string will be unchanged. The $(VAR_NAME) syntax can be escaped with a
double $$, ie: $$(VAR_NAME). Escaped references will never be expanded,
regardless of whether the variable exists or not. Defaults to "".
valueFrom <Object>
Source for the environment variable's value. Cannot be used if value is not
empty.
实例
apiVersion: v1
kind: Pod
metadata:
name: demo-env
spec:
containers:
- name: demo-env
image: ikubernetes/filebeat:5.6.5-alpine
env:
- name: REDIS_HOST
value: redis.com
- name: LOG_LEVEL
value: info
此处传递主机名称和日志级别
查看,通过printenv即可获取环境变量和列表及其对应的值
5 共享节点的网络名称空间
kubectl explain pods.spec.hostNetwork 同一个POD对象的各个容器均运行在一个独立的、隔离的Network名称空间中,共享同一个网络协议栈及相关的网络设备,也有一些特殊的POD对象需要运行与所在节点的名称空间中,执行系统级的管理任务,如查看和操作节点的网络资源甚至是网络设备等,事实上,仅需要设置HostNetwork的属性位true即可创建共享节点网络名称空间的Pod对象
如下 配置配置结果
#[root@master1 all]# cat demohostnet.yaml
apiVersion: v1
kind: Pod
metadata:
name: demo-hostnet
spec:
containers:
- name: demo-hostnet
image: nginx:1.14
hostNetwork: true
验证结果
查看运行节点
node1节点结果:
6 设置Pod对象的安全上下文
pod 对象的安全上下文用于设定Pod或容器的权限和访问控制功能,其支持的常用属性有: 1 基于用户ID和组ID访问控制对象时的权限 2 以特权或非特权的方式运行 3 通过Linux capabities为其提供部分特权 4 基于seccomp过滤进程的系统调用 5 基于SELinux的安全标签 6 是否能够进行权限升级
POD 对象的安全上下文定义在spec.securityContext字段中,而容器的安全上下文则定义在spec.containers.securityContext字段中,且二者可嵌套使用的字段有所不同,
#[root@master1 all]# cat demosecu.yaml
apiVersion: v1
kind: Pod
metadata:
name: demo-sec
spec:
containers:
- name: demo-sec
image: busybox
command: ["/bin/sh","-c","sleep 86400"]
securityContext:
runAsNonRoot: true # 非特权模式运行
runAsUser: 1000 #设置其运行的UID为1000的可以访问
allowPrivilegeEscalation: false #设置其权限升级不允许
查看验证
4 标签与标签选择器
1 标签
标签时kubernetes的特色功能之一,其能够附加在kubernetes的任何字段之上,其是键值类型的数据,可用于资源创建时指定,也可按需添加于活动对象中,一个对象可拥有不止一个标签,一个标签也可加载在不止一个对象之上
不同类型的标签: 版本标签、环境标签、应用标签、架构层级标签、分区等
键名要求: 可使用字母、数字、连接号(-)、下划线(_)、点号(.)等字符,并且只能以字母或数字开头。键前缀必须为DNS子域名格式,且不能超过253字符,省略键前缀时,键将被视为用户的私有数据,不过由kubernetes系统组件或第三方组件自动为用户资源添加的键必须使用键前缀,而kubernetes.io/前缀则预留给kubernetes的核心组件使用。
键值要求: 标签中的键值必须不能多于63个字符,要么为空,要么,是字母或数字开头及结尾,且中间仅使用了字母、数字、链接号(-),下划线(_)或点号(.) 等字符的数据。
管理资源标签
创建资源时,可直接在其metadata中嵌套使用labels字段定义要附加的标签项。
#[root@master1 all]# cat demolab.yaml
apiVersion: v1
kind: Pod
metadata:
name: demo-lab
labels:
env: test
release: develop
spec:
containers:
- name: demo-lab
image: ikubernetes/filebeat:5.6.5-alpine
env:
- name: REDIS_HOST
value: redis.com
- name: LOG_LEVEL
value: info
查看标签 --show-labels 列出资源的标签
查看指定键的标签 -l 指定键的标签的资源。--show-labels 列出
添加动态标签
kubectl label pods/demo-lab service=db-mem
查看
修改标签
kubectl label pods/demo-lab env=formal --overwrite
查看
2 标签选择器
标签选择器用于表达标签的查询条件或选择标准,目前有两种标签选择器
1 基于等值关系
env=formal env!=test 三种操作符 = == != 其中前两者意义相同
2 基于集合关系
** env in (test,format) ** in : 指定的键名的值存在于给定的列表中即满足条件 kubectl get pods -l "env in (formal,test)" --show-labels
notin : 指定的键名不存在于给定的列表中满足条件 kubectl get pods -l "env notin (test)" --show-labels
KEY : 键名为此的资源
kubectl get pods -l env --show-labels
**!KEY : 键名非此的资源 **
kubectl get pods -l '!env' --show-labels
注: 此处必须使用单引号
使用标签选择器遵循的逻辑 1 同时指明多个标签选择器之前的关系是"与"操作 2 使用空值的标签选择器意味着每个字段对象都将被选中 3 空的标签选择器将无法选出任何资源
3 POD节点选择器
Pod节点选择器是标签及标签选择器的一种应用,它能够让Pod对象基于集群中工作节点的标签来挑选倾向运行的目标节点
#[root@master1 ~]# kubectl explain pods.spec.nodeSelector
KIND: Pod
VERSION: v1
FIELD: nodeSelector <map[string]string>
DESCRIPTION:
NodeSelector is a selector which must be true for the pod to fit on a node.
Selector which must match a node's labels for the pod to be scheduled on
that node. More info:
https://kubernetes.io/docs/concepts/configuration/assign-pod-node/
为节点打标签
配置pod资源
#[root@master1 all]# cat demonodesel.yaml
apiVersion: v1
kind: Pod
metadata:
name: demo-nodesel
spec:
containers:
- name: demo-nodesel
image: nginx:1.14
nodeSelector:
service: web
kubectl apply -f demonodesel.yaml
默认的,节点默认已经携带了一些标签,如kubernetes.io/hostname beta.kubernetes.io/os 和 beta.kubernetes.io/arch等,这些标签页可以直接由nodeselector使用,尤其是希望将Pod调度到某个特定的节点时,可以使用kubernetes.io/hostname直接绑定主机即可,当然也可直接使用nodeName字段直接指定目标主机
4 资源注解
用于为资源提供元数据信息,其大小不受限制,可大可小,可为结构化或非结构化,其可以是人工添加也可以是系统默认添加的 时间戳,发行ID,GIT分支,PR号码、镜像哈希及仓库信息等
查看
kubectl describe pods PODNAME
[root@master1 all]# kubectl describe pods demo-nodesel
Name: demo-nodesel
Namespace: default
Priority: 0
PriorityClassName: <none>
Node: 192.168.1.30/192.168.1.30
Start Time: Wed, 20 Mar 2019 22:49:02 +0800
Labels: <none>
Annotations: #资源注解 kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"name":"demo-nodesel","namespace":"default"},"spec":{"containers":[{"image":"nginx:1.14","...
Status: Running
IP: 172.17.50.9
管理资源注解 1 创建时在yaml文件中指定
apiVersion: v1
kind: Pod
metadata:
name: demo-annot
annotations:
name: nginx
spec:
containers:
- name: demo-annot
image: nginx:1.14
查看
#[root@master1 all]# kubectl describe pods demo-annot
Name: demo-annot
Namespace: default
Priority: 0
PriorityClassName: <none>
Node: 192.168.1.30/192.168.1.30
Start Time: Wed, 20 Mar 2019 23:04:33 +0800
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{"name":"nginx"},"name":"demo-annot","namespace":"default"},"spec":{"containers":[{"image":"n...
name=nginx
五 POD 生命周期
1 概述POD 对象生命周期
1 创建主容器 2 运行初始化容器 3 容器启动后钩子 4 容器存活性探测 5 容器就绪性探测 6 容器终止前钩子 7 容器退出
2 创建POD过程
1 通过kubelet 将yaml文件或命令行方式提交给API SERVER。 2 API server 通过认证和授权机制将其信息写入etcd。 3 api server 即刻返回确认信息至客户端。 4 api server 开始处理etcd 变化。 5 kubernetes 组件使用watch机制监控api server 变动。 6 kube-scheduler 通过及watch 机制察觉到API server 创建新POD但未绑定到节点。 7 kube-scheduler 为POD 根据资源调度相关机制调度至指定节点。 8 调度信息存储至etcd,api server反应调度结果。 9 POD 被调度到目标节点上的kubelet 尝试在当前节点调用docker容器,并启动,将其结果返回给api server。 10 api server 将POD 状态信息存入etcd。 12 在etcd 确认操作完成后,api server 将确认信息发送至kubelet,事件通过其被接受。
3 Pod生命周期的重要行为
1 初始化容器
初始化容器的两种典型操作。
1 初始化容器必须运行完成直至结束,若某初始化容器运行失败,则kubernetes要重启其知道成功完成 2 每个初始化容器都必须按照定义的顺序串行执行 应用场景: 1 用于运行特定的工具程序,处于安全方面的考虑,这些程序不适合在主容器中使用 2 提供主容器镜像中不具备的工具程序或自定义代码 3 为容器镜像的构建和部署人员提供了分离,独立工作途径,使得他们不必协同起来制作单个镜像文件 4 初始化容器和朱荣旗处于不同的文件系统视图,可分别安全的使用敏感资源 5 初始化容器要先于与应用容器串行启动并运行完成
kubectl explain pods.spec.initContainers
示例
#[root@master1 all]# cat demoinit.yaml
apiVersion: v1
kind: Pod
metadata:
name: demo-init
labels:
service: httpd
spec:
containers:
- name: myapp-container
image: ikubernetes/myapp:v1
initContainers:
- name: init-something
image: busybox
command: ["sh","-c","sleep 10"]
2 生命周期函数
生命周期函数实现了程序运行周期中关键时刻的可见性,并赋予用户为此采取某种行动的能力,类似的,容器生命手气钩子使用它能够感知自身声明周期管理中的事件,并在相应的时刻到来是运行由用户指定的处理程序代码, kubernetes为容器提供了两种声明周期钩子。
poststart: 于容器创建完成后立即执行的钩子处理器,不过kubernetes无法确保它一定会于容器中的ENTRYPOINT 之前运行
preStop: 于容器终止操作之前立即运行的钩子处理器,它以同步的方式调用,因此在其完成之前会阻塞删除容器的操作作用 钩子处理器实现方式有exec和http两种,前一种是在钩子事件触发直接在当前容器中运行的由用户定义的命令,后一种则是当前容器中向某URL发起http请求
poststart 和 prestop 的定义在pods.spec.containers.lifecycle
嵌套字段中,使用方式如下
#[root@master all]# cat demo-life.yaml
apiVersion: v1
kind: Pod
metadata:
name: lifecycle-demo
spec:
containers:
- name: lifecycle-demo
image: nginx:1.14
lifecycle:
postStart:
exec:
command: ["/bin/sh","-c","echo 'nginx-lifecycle-demo' >/usr/share/nginx/html/index.html"]
结果验证
3 容器探测
其是kubelet对容器周期性执行的健康状态诊断,诊断操作由容器的处理器(handler)进行定义。kubernetes 支持三种处理器用于Pod探测 ExecAction :在容器中执行一个命令,并根据其返回的状态码进行针对的操作成为exec探测,状态码为0表示成功,否则为不健康状态 TCPsocketAction:通过与容器的某TCP端口尝试建立连接进行诊断,端口能够成功打开及为正常,否则为不健康状态 httpGetAction:通过向容器IP地址的某指定端口的指定path 发HTTP GET 请求进行诊断,响应码为2xx或3xx即为成功,否则为失败。
任何一种探测都有三种结果: success (成功)、failure (失败)或 unknown (未知),只有第一种为正常 存活性探测:判定是否处于运行状态,一旦此类检测为通过,则kubelet 将杀死容器并根据其restartPlicy 决定是否将其重启,未定义存活性检测到的容器默认状态为"sucess"。 就绪性探测:用于判断容器是否准备就绪并可对外提供服务,未通过检测的容器意味着尚未准备就绪,端点控制器会将其IP从所有匹配到此Pod对象的service对象的端点列表中移除,检测通过后,会再次将其IP添加到端点列表中。 容器的重启策略 容器程序发生崩溃或者容器申请超出限制的资源等原因都会导致POD 对象的终止,此时是否应该重建该POD对象取决于其重启策略 1 always:但凡Pod对象终止就将其重启,此为默认设定 2 onfailure:仅在容器出现错误时将其重启 3 Never :从不重启
4pod 终止过程概述:
当用户提交删除请求后,系统会进行强制删除操作的宽限倒计时,并将TERM信息发送给POD对象的每一个容器的主进程,宽限倒计时结束后,这些进程将收到强制kill信号,POD对象随机也将由API server删除,如果在等待进程终止的过程中,kubelet或容器管理器发生了重启,那么终止操作会重新获取一个满额的删除宽限期限并重新执行删除操作。
4 POD 对象的终止流程
1 用户发送删除POD对象命令 2 api server 服务中的POD会随时间的推移而更新,在宽限期内(默认是30s)pod被视为dead 3 将pod 标记为terminating状态 4 与第三步同时进行,kubelet在监控到POD对象转换为terminaing状态的同时启动POD关闭过程 5 与第三步同行,端点控制器监控到POD对象的关闭行为时将其所有匹配到此端点的service资源的端点列表中的POD移除 6 如果当前POD对象定义了prestop钩子处理器,则将其标记为termingating 后及会以同步的方式启动执行,若宽限期结束后,prestop仍未结束,则第二部会被重新执行一个时长为2秒的小宽限期限 7 pod对象中的容器进程收到term信号 8 宽限期结束后,若存在任何一个仍在运行的进程,那么pod 对象及会收到sigkill 信号 9 kubelet请求api server 将次POD 资源的宽限期设置为0从而完成删除操作,他变得对用户不可见
5 POD 状态
1 pending:api server创建了POD,资源对象已经存储进入etcd中,但尚未完成调度 2 running: pod 已经被调度至某个节点,并且所有容器都已经被kubelet创建完成 3 failed:失败状态 4 suceeded:pod 中的所有容器已经成功终止并不会重启 5 unknown:未知状态,和节点的kubelet故障,联络中断,成了未知状态
4 POD 存活性探测
有不少应用程序长时间持续运行后会逐渐转为不可用状态,并且仅能通过重启回复,kubernetes 的容器存活性机制可发现此类问题,并依据探测结果结合重启策略触发过后需的行为,存活型探测是容器级别的配置,kubelet可基于他判断何时需要重启一个容器。
查询命令 kubectl explain pods.spec.containers.livenessProbe
1 execAction
exec 类型的探针通过在目标容器中执行由用户自定义的命令来判定容器的建康状态,若命令返回为0则表示其成功,其只有一个可用的command 命令,用于指定要执行的命令。
apiVersion: v1
kind: Pod
metadata:
name: test
spec:
containers:
- name: test
image: busybox
args: ["/bin/sh","-c","touch /tmp/healthy;sleep 60; rm -rf /tmp/healthy;sleep 600"]
livenessProbe:
exec:
command: ["test","-e","/tmp/healthy"]
上述实例中启用了一个创建文件的操作和删除文件后探测的操作, 查看结果
在此处被kill了,其原因是由于存活探测无法成功导致的kill掉,而后重新拉去后创建,又进行探针探测
2 设置HTTP探针
其目的是向目标服务器发送一个HTTP请求,若返回为2XX和3XX则表示检测通过,否则为检测不通过,相关字段如下所示 : kubectl explain pods.spec.containers.livenessProbe.httpGet 相关配置字段 host <string>: 请求的主机地址,默认是PodIP地址, port<string>:请求的端口,必选字段 httpHeaders<[]Object>: 自定义的请求报文首部 path<string>: 请求的HTTP资源路径,及URL path scheme: 建立连接使用的协议,仅可以是HTTP或HTTPS,默认是HTTP
apiVersion: v1
kind: Pod
metadata:
name: test1
spec:
containers:
- name: test1
image: nginx:1.12-alpine
lifecycle:
postStart:
exec:
command: ["/bin/sh","-c","echo Heall > /usr/share/nginx/html/heall"]
livenessProbe:
httpGet:
port: 80
path: /heall
查看结果
删除对应文件
kubectl exec test1 rm /usr/share/nginx/html/heall
一般的HTTP类型的探测操作应当针对专用URL路径进行处理,其仅能检测应用程序工作正常与否,但重启操作却无法解决其后端服务导致的故障(如数据库和缓存服务),此时,容器可能会被一次次重启,直到后端服务恢复正常为止,其余两种检测方式也存在类似问题。
3 设置TCP探针
基于TCP 的存活性检测用于向容器的特定端口发起TCP请求并尝试建立连接进行结果判定,连接建立成功即为通过检测,其更高效,但其精准度略低,建立连接成功并不意味着可用
kubectl explain pods.spec.containers.livenessProbe.tcpSocket
相关关键字
1 host :请求连接的目标IP地址,默认是POD ip 2 post: 请求连接的目标端口,必选字段
apiVersion: v1
kind: Pod
metadata:
name: test2
spec:
containers:
- name: test2
image: nginx:1.12-alpine
livenessProbe:
tcpSocket:
port: 80
查看结果
4 存活性探测行为属性
查询命令: kubectl explain pods.spec.containers.livenessProbe
failureThreshold : 处于成功状态时,探测操作至少连续多少次的失败才被认为是检测不通过,默认是3次,最少是1次 initialDelaySeconds:存活性探测延迟时长,及容器启动多久后再开始第一次探测操作,显示为delay,默认为0秒,及容器启动后立刻便开始进行探测 periodSeconds:存活性探测的频度,显示为period,默认是10s,最小值也是1s。 successThreshold:处于失败状态时,探测操作至少连续多少次的成功才被认为是通过检测,显示为#success属性,默认值为1,最小是1.
timeoutSeconds:存活性探测的超时时长,显示为timeout属性,默认为1s,最小为1s。
5 就绪性探测
因避免POD 对象启动后立即让其处理客户端请求,而是等待容器初始化工作执行完成并转为"就绪"状态再进行处理,便出现了就绪性探测
与存活性探测机制类似,就绪性探测是用来判断容器就绪与否的周期性操作,它用于探测容器是否已经初始化完成并可服务与客户端请求,探测操作返回success状态,即为传递容器已经"就绪"的信号。
与存活性探测机制相同,就绪性探测也支持EXEC、HTTPGET 和 TCP socket 三种探测方式,且各自定义机制相同,但与存活性探测不同的是,就绪性探测不会杀死或重启重启以保证其健康性,而是通知其尚未就绪,并触发以来与其就绪状态的操作,以确保不会有客户端请求接入此POD对象,不过,即便在运行过程中,Pod就绪性探测依然有存在的价值。
实例:
apiVersion: v1
kind: Pod
metadata:
name: test5
spec:
containers:
- name: test5
image: busybox
args: ["/bin/sh","-c","while true; do rm -rf /tmp/aaa; sleep 30 ;touch /tmp/aaa;sleep 40; done"]
readinessProbe:
exec:
command: ["test","-e","/tmp/aaa"]
initialDelaySeconds: 5
periodSeconds: 5
启动成功但未就绪
虽然有探测不过,但未重启
6 POD 资源需求及资源限制
1 简介
在kubernetes上,可由容器或POD请求或消费的"计算资源"是指CPU和内存(RAM),这是目前仅支持的两种类型。 1 可压缩类型 CPU 属于可压缩性资源,及资源额度可按需收缩。 2 不可压缩类型 内存是不可压缩资源,对其执行收缩操作可能会导致某种程度的问题 资源隔离尚且属于容器级别,CPU和内存资源的配置需要在POD中的容器上进行,每种资源均可由"requests"属性定义其请求的确保可用值,即使容器运行可能用不到这些额度的资源,但用到时必须要确保有如此多的资源可用,limits属性则用于限制资源可用的最大值,及硬限制, 资源配置称为POD资源的请求和限制的总和,只不过他是指POD内所有容器上某种类型资源的请求和限制的总和
2 资源类型单位
在kubernetes系统上,1个单位的CPU相当于虚拟机上的1颗虚拟CPU(vCPU)或物理机上的一个超线程(hyperthread,或称为一个逻辑CPU),它支持分数计算方式,一个核心(1core)相当于1000个微核心(millicores),因此500m相当于0.5个核心,即二分之一的核心,内存的计量方式与日常使用方式相同,默认单位是字节,也可以使用E、P、T、G、M和K作为单元后缀,或Ei、Pi、Ti、Gi、Mi和Ki 形式的单位后缀。
3 资源需求
内存是非可压缩型资源,一旦超过,有可能会被OMM杀死 对于压缩性资源CPU,未定义其请求用量以确保其最小的资源可用时,它可能会被其他POD资源压缩至极低水平,甚至会达到POD不能被调度运行的境地,而对于非压缩性资源来说,内存资源在任何原因导致的紧缺情形下都可能导致相关进程被杀死,因此,在kubernetes系统上运行关键型业务相关的Pod时必须使用requests属性为容器定义资源的确保可用性。
实例:
apiVersion: v1
kind: Pod
metadata:
name: test3
spec:
containers:
- name: test3
image: nginx:1.14
resources:
requests:
memory: "256Mi"
cpu: "512m"
查看其内存 kubectl exec test2 -- top
4 资源限制
limits 用于限制资源的最大可用量,资源分配时,可压缩型资源CPU的控制阀可自由调节,容器无法获得超出其CPU配额的可用时间,不过,如果进行申请分配超出其limits属性定义的硬限制的内存资源时,它将被OOM killer杀死。
实例 :
apiVersion: v1
kind: Pod
metadata:
name: test4
spec:
containers:
- name: test4
image: nginx:1.14
resources:
requests:
memory: "256Mi"
cpu: "256m"
limits:
memory: "256Mi"
cpu: "256m"
7 POD 的服务类别
1 总述
K8S 允许节点资源对limits 的过载使用,这意味着节点无法同时满足其上所有POD对象以资源满载的方式运行,于是,在内存资源紧缺时,需要借助于POD对象的优先级完成判定,根据POD对象的request和limits 属性,K8S将POD 对象归类到besteffort、burstable和 guaranteed 三个服务质量(quality of service,Qos) 类别如下
2 描述
1 guaranteed: 每个容器都为CPU 资源设置了具有相同值的request和limits 属性,以及每个容器都为内存资源设置了具有相同的requests 和 limits 属性的POD资源会自动属于此类别,这类POD 资源具有最高优先级
2 Burstable : 至少一个容器设置了CPU 或内存资源的requests 属性,但不满足guaranteed 类别要求的POD资源将自定归于此类,其具有中等优先级
3 Besteffort: 未为任何一个容器设置requests 或 limits 属性的POD 资源将自动归属于此类别,他们的优先级为最低级别。 内存资源紧缺时,besteffort 类别的容器将首当其中被终止,接下来是中等级别的被终止,依次类推