目录
一.YAML文件分析
YAML简介
对象
数组
对象与数组的复合结构
纯量
特殊用法
二.deployment.yaml文件详解
三.Pod YAML文件详解
四.Service yaml文件详解
五.ingress:HTTP七层路由机制
六.YAML文件相关测试命令
一.YAML文件分析
YAML简介
- YAML语言的设计目标,就是方便读写,它实质是一种通用数据串行化格式,YAML是一种简洁非标记语言。YAML以数据为中心,使用空白、缩进,分行组织数据。
- 它的基本语法规则如下:
- 大小写敏感
- 使用缩进表示层级关系
- 缩进时不允许使用Tab键,只允许使用空格键
- 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可,(通常开头缩进两格)
- #表示注释,这个字符一直到行尾都会被解析器忽略
- 字符后缩进一个空格,如冒号,逗号。短横杠等
- YAML的组织结构
YAML文件可以由一个或者多个文档组成(也即相对独立的组织结构组成),文档间使用“---”(三个横线)在每个文档开始作为分隔符。同时,文档也可以使用“...”作为结束符(可选)。如果只是单个文档,分隔符“---”可省略
- YAML支持的数据结构有三种
- 对象:键值对的集合,又称为映射(mapping)/哈希(hashes)/字典(dictionary)
- 数组:一组按次序排列的值,又称为序列(sequence)/列表(list)
- 纯量(scalars):单个的、不可再分的值
- 在kubernetes中支持YAML和JSON格式创建资源对象;JSON格式用于接口之间的消息的传递(适用于开发);YAML格式用于配置和管理(适用于云平台运维);YAML是一种简洁的非标记性语言
对象
- 对象的一组键值对,使用冒号结构表示
animal:pets
- YAML也允许另外一种写法,将所有键值对写成一个行内对象
hash:{name:Steve,foo:bar}
数组
- 一组连词线开头的行,构成一个数组
- Cat
- Dog
- Goldfish
- 数据结构的子成员是一个数组,则可以在该项下面缩进一个空格
-
-Cat
-Dog
-Goldfish
- 数组也可以使用行内表示法
animal:[Cat,Dog]
对象与数组的复合结构
- 对象和数组可以结合使用,形成复合结构
languaes:
-Ruby
-Perl
-Python
websites:
YAML:yaml.org
Ruby:ruby-lang.org
Python:python.org
Perl:use.perl.org
纯量
- 整数、浮点、字符串、布尔、Null、时间、日期
#整数
age: 10
#浮点
price: 1.48
#字符串
name: Bob
address: Beijing
#布尔值
online:true
#Null
car:-
#时间(IS08601 格式)
time:2019-02-28t21:59:43.10-05:00
#日期(iso8601 格式的年、月、日)
date:2020-05-03
特殊用法
- !!YAML中使用!!做类型强行转换
yamlbeans包一般用!(单叹号)做类型转换,snakeyyaml包一般用!!(双叹号)做类型转换
string:
- !!str 54321
- !!str ture
#上述命令相当于把数字和布尔类型转为字符串。此外允许转换的类型很多,如下:
---!!list
-Mark McGwire: 65
-Sammy Sosa: 63
-Sammy Sosa: 63
-Ken Griffy: 58
将数组解析为set,转化的内容就是:[{ken Griffy=58},{Mark McGwire=65},{Sammy Sosa=63}],重复的Sammy Sosa自动去掉;
- 字符串默认不使用引号表示
str:这是一行字符串
- 字符串之中包含空格或者特殊字符,需要放在引号之中
如果字符串之中包含空格或者特殊字符,需要引导之中,单引号和双引号都可以用
str:'内容:字符串'
- 双引号不会对特殊字符转义
s1:'内容\字符串'
s2:"内容\字符串"
- 单引号之中如果还有单引号,必须连续使用两个单引号转义
str:'labor''s day'
- 多行字符串可以使用|保留换行符,也可以使用>折叠换行
this: |
Foo
Bar
that: >
Foo
bar
- +表示保留文字块末尾的换行,-表示删除字符串末尾的换行
s1: |
Foo
s2: |+
Foo
s3: |-
Foo
- 布尔值用ture或者flase表示
NULL 用~表示
- 锚点&和别名*,可以来引用,定义数据的复用
第一步:使用"&"定义数据的锚点(即要复制的数据)
第二步:使用"*"引用上述锚点数据(即数据的复制目的地)
defaults: &defaults
adapter: postgres
host: localhost
development:
database: myapp_development
<<: *defaults
test:
database: myapp_test
<<: *defaults
## <<表示合并到当前数据,*用来引用锚点
二.deployment.yaml文件详解
- 查看api版本
[root@master ~]# kubectl api-versions
admissionregistration.k8s.io/v1beta1
apiextensions.k8s.io/v1beta1
apiregistration.k8s.io/v1
apiregistration.k8s.io/v1beta1
apps/v1 ##应用服务
apps/v1beta1 ##beta1为测试版本
apps/v1beta2
authentication.k8s.io/v1
authentication.k8s.io/v1beta1
authorization.k8s.io/v1
authorization.k8s.io/v1beta1
autoscaling/v1 ##弹性伸缩
autoscaling/v2beta1
autoscaling/v2beta2
batch/v1
batch/v1beta1
certificates.k8s.io/v1beta1
coordination.k8s.io/v1beta1
events.k8s.io/v1beta1
extensions/v1beta1
networking.k8s.io/v1
policy/v1beta1
rbac.authorization.k8s.io/v1 ##权限控制
rbac.authorization.k8s.io/v1beta1
scheduling.k8s.io/v1beta1
storage.k8s.io/v1
storage.k8s.io/v1beta1
v1
[root@master ~]#
- 实例,编辑YAML文件
##编辑yaml文件时,注意空格数,开头空出两个
[root@master demo]# cat nginx-deployment.yaml
apiVersion: apps/v1 #指定api版本
kind: Deployment #指定创建资源的角色/类型,Deployment表示控制器
metadata: #定义资源的元数据/属性
name:nginx-deployment #资源的名字,在同一个namespace中必须唯一
labels: #定义资源的标签
app: nginx
spec: #指定该资源的内容
replicas: 1 #指定副本数
selector: #选择器
matchLabels: #匹配标签
app: nginx #匹配模板名称
template:
metadata:
labels:
app: nginx
spec: #定义容器模板
containers: #定义容器信息
- name: nginx #容器名,符合label名
image: nginx:1.15.4 #容器使用的镜像以及版本
ports:
- containerPort: 80 # - 表示参数,容器对外开放的端口
[root@master demo]#
- 使用YAML文件创建资源
#-f指定yaml文件
[root@master demo]# kubectl create -f nginx-deployment.yaml
deployment.apps/nginx-deployment created
[root@master demo]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-deployment-d55b94fd-smrwb 1/1 Running 0 55s
[root@master demo]#
三.Pod YAML文件详解
- pod yaml文件解析
# yaml格式的pod定义文件完整内容:
# string,表示字符型数据
apiVersion: v1 #必选,版本号,例如v1
kind: Pod #必选,Pod
metadata: #必选,元数据
name: string #必选,Pod名称
namespace: string #必选,Pod所属的命名空间
labels: #自定义标签
- name: string #自定义标签名字
annotations: #自定义注释列表
- name: string
spec: #必选,Pod中容器的详细定义
containers: #必选,Pod中容器列表
- name: string #必选,容器名称
image: string #必选,容器的镜像名称
imagePullPolicy: [Always | Never | IfNotPresent] #获取镜像的策略 Alawys表示下载镜像 IfnotPresent表示优先使用本地镜像,否则下载镜像,Nerver表示仅使用本地镜像
command: [string] #容器的启动命令列表,如不指定,使用打包时使用的启动命令
args: [string] #容器的启动命令参数列表
workingDir: string #容器的工作目录
volumeMounts: #挂载到容器内部的存储卷配置
- name: string #引用pod定义的共享存储卷的名称,需用volumes[]部分定义的的卷名
mountPath: string #存储卷在容器内mount的绝对路径,应少于512字符
readOnly: boolean #是否为只读模式
ports: #需要暴露的端口库号列表
- name: string #端口号名称
containerPort: int #容器需要监听的端口号
hostPort: int #容器所在主机需要监听的端口号,默认与Container相同
protocol: string #端口协议,支持TCP和UDP,默认TCP
env: #容器运行前需设置的环境变量列表
- name: string #环境变量名称
value: string #环境变量的值
resources: #资源限制和请求的设置
limits: #资源限制的设置
cpu: string #Cpu的限制,单位为core数,将用于docker run --cpu-shares参数
memory: string #内存限制,单位可以为Mib/Gib,将用于docker run --memory参数
requests: #资源请求的设置
cpu: string #Cpu请求,容器启动的初始可用数量
memory: string #内存清楚,容器启动的初始可用数量
livenessProbe: #对Pod内个容器健康检查的设置,当探测无响应几次后将自动重启该容器,检查方法有exec、httpGet和tcpSocket,对一个容器只需设置其中一种方法即可
exec: #对Pod容器内检查方式设置为exec方式
command: [string] #exec方式需要制定的命令或脚本
httpGet: #对Pod内个容器健康检查方法设置为HttpGet,需要制定Path、port
path: string
port: number
host: string
scheme: string
HttpHeaders:
- name: string
value: string
tcpSocket: #对Pod内个容器健康检查方式设置为tcpSocket方式
port: number
initialDelaySeconds: 0 #容器启动完成后首次探测的时间,单位为秒
timeoutSeconds: 0 #对容器健康检查探测等待响应的超时时间,单位秒,默认1秒
periodSeconds: 0 #对容器监控检查的定期探测时间设置,单位秒,默认10秒一次
successThreshold: 0
failureThreshold: 0
securityContext:
privileged:false
restartPolicy: [Always | Never | OnFailure]#Pod的重启策略,Always表示一旦不管以何种方式终止运行,kubelet都将重启,OnFailure表示只有Pod以非0退出码退出才重启,Nerver表示不再重启该Pod
nodeSelector: obeject #设置NodeSelector表示将该Pod调度到包含这个label的node上,以key:value的格式指定
imagePullSecrets: #Pull镜像时使用的secret名称,以key:secretkey格式指定
- name: string
hostNetwork:false #是否使用主机网络模式,默认为false,如果设置为true,表示使用宿主机网络
volumes: #在该pod上定义共享存储卷列表
- name: string #共享存储卷名称 (volumes类型有很多种)
emptyDir: {} #类型为emtyDir的存储卷,与Pod同生命周期的一个临时目录。为空值
hostPath: string #类型为hostPath的存储卷,表示挂载Pod所在宿主机的目录
path: string #Pod所在宿主机的目录,将被用于同期中mount的目录
secret: #类型为secret的存储卷,挂载集群与定义的secre对象到容器内部
scretname: string
items:
- key: string
path: string
configMap: #类型为configMap的存储卷,挂载预定义的configMap对象到容器内部
name: string
items:
- key: string
path: string
四.Service yaml文件详解
- service是kubernetes中的核心概念,通过创建service,可以为一组具有相同功能的容器应用提供一个统一的入口地址,并且将请求负载分发到后端的各个容器应用之上。
- service YAML文件的相关属性列表
属性名称 | 取值类型 | 是否必选 | 取值说明 |
version | string | Required | v1 |
kind | string | Required | Service |
metadata | object | Required | 元数据 |
metadata.name | string | Required | service名称,需要符合RFC 1035规范 |
metadata.namespace | string | Required | 命名空间,不指定系统时将使用名为default的命名空间 |
metadata.labels[] | list | 自定义标签属性列表 | |
metadata.annotation[] | list | 自定义注解属性列表 | |
spec | object | Required | 详细描述 |
spec.selector[] | list | Requried | Label Selector的配置,将选择具有指定label标签的Pod作为管理范围 |
spec.type | string | Required | service的类型,指定service的访问方式,默认值为ClusterIP。 1.ClusterIP:虚拟的服务IP地址,该地址用于kuernetes集群内部的pod访问,在node上的kube-proxy通过设置iptables规则转发。 2.NodePort:使用宿主机的端口,使得能够访问各个Node的外部客户端通过Node的IP地址和端口号就能访问到服务。 3.LoadBalancer:使用外接负载均衡器完成到服务的负载分发,需要在spec.status.loadBalancer字段指定外部负载均衡器的IP地址,并且同时定义nodePort和clusterIp,用于公有云环境 |
spec.clusterIP | string | 虚拟服务IP地址,当type=ClusterIP时,如果不指定,系统自动分配,也可以手工指定;当type=Balancer时,则需要指定。 | |
spec.sessionAffinity | string | 是否支持Session,可选值为ClientIP,默认值为空。 ClientIP:表示将同一个客户端(根据客户端的IP地址决定)的访问请求都转发到同一个后端Pod | |
spec.ports[] | list | Service需要暴露的端口列表 | |
spec.ports[].name | string | 端口名称 | |
spec.ports[].protocol | string | 端口协议,支持TCP和UDP,默认值为TCP | |
spec.ports[].port | int | 服务监听的端口号 | |
spec.ports[].targetPort | int | 需要转发到后端Pod的端口号 | |
spec.ports[].nodePort | int | 当spec.type=NodePort时,指定映射到物理机的端口号 | |
Status | object | 当spec.type=LoadBalancer时,设置外部负载均衡地址,用于公有云环境 | |
status.loadBalancer | object | 外部负载均衡器 | |
status.loadBalancer.ingress | object | 外部负载均衡器 | |
status.loadBalancer.ingress.ip | string | 外部负载均衡器的IP地址 | |
status.loadBalncer.ingress.hostname | string | 外部负载均衡器的主机名 |
- 一般来说,对外提供服务的应用程序需要通过某种机制来实现,对于容器应用最简单的方式就是通过TCP/IP机制以及监听IP和端口号来实现
- 编辑service的YAML文件,发布pod资源
[root@master demo]# ls
nginx-deployment.yaml nginx-service.yaml
[root@master demo]# cat nginx-service.yaml
apiVersion: v1
kind: Service
metadata: #元数据
name: nginx-service #service的名称
# namespace: nginx-servcei #命名空间
labels: #自定义标签属性
app: nginx
spec: #详细描述
type: NodePort #service的类型默认为ClusterIP
ports: #service需要暴露的端口列表
- port: 80 #内部开放端口
targetPort: 80 #需要转发到后台的端口号
selector: #选择器
app: nginx ##发布app中的nginx,pod资源的名称
#status: #当spce.type=LoadBalancer时,设置外部负载均衡器的地址
# loadBalancer: #外部负载均衡器
# ingress: #外部负载均衡器
# ip: string #外部负载均衡器的Ip地址值
# hostname: string #外部负载均衡器的主机名
- 使用YAML文件创建service
[root@master demo]# kubectl create -f nginx-service.yaml
service/nginx-service created
[root@master demo]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 7d17h
nginx-service NodePort 10.0.0.187 <none> 80:33856/TCP 8s
[root@master demo]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE
nginx-deployment-d55b94fd-smrwb 1/1 Running 0 18m 172.17.60.2 192.168.43.103 <none>
目前kubernetes提供了两种分发策略:RoundRobin和SessionAffinity
RoundRobin:轮询模式,即轮询将请求转发到后端的各个pod之上
SessionAffinity:基于客户端IP地址进行会话保持的模式,第一次客户端访问后端某个pod之上,之后的请求都转发到这个pod之上
默认是RoundRobin模式
在某些场景之中,开发人员希望自己控制负载均衡的策略,不使用service提供的默认负载,kubernetes通过Headless Service的概念来实现。
五.ingress:HTTP七层路由机制
- 通常情况下,service和pod仅仅在集群内部网络中通过IP地址访问,所有到达边界路由器的流量或被丢弃或者转发到其他地方,
- Ingress是授权入站连接到达集群服务的规则集合
- 我们可以给Ingress配置提供外部访问的URL、负载均衡、SSL、基于名称的虚拟主机,用户通过POST Ingress资源到API Server的方式来请求ingress。Ingress controller负责实现ingress,通常使用负载平衡器,它还可以配置边界路由和其他前端,这有助于以HA的方式处理流量
- 如下最简化的ingress配置
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test-ingress
spec: # Ingress spec 中包含配置一个loadbalancer或proxy server
rules: # 的所有信息。最重要的是,它包含了一个匹配所有入站请求的规
- http: # 则列表。目前ingress只支持http规则。
paths:
- path: /testpath # 每条http规则包含以下信息:一个host配置项(比如
# for.bar.com,在这个例子中默认是*),path列表(比
# 如:/testpath),每个path都关联一个backend(比如
# test:80)。在loadbalancer将流量转发到backend之前,所有的
# 入站请求都要先匹配host和path。
backend:
serviceName: test # backend是一个service:port的组合。Ingress的流量被转发到
servicePort: 80 # 它所匹配的backend
- 定义Ingress策略之前需要先部署Ingress Controller,以实现为所有后端Server都提供一个统一的入口。Ingress Controller需要实现基于不同HTTP URL向后转发的负载分发规则,并且可以灵活的设置7层负载分发策略。如果公有云服务商能够提供该类型的HTTP路由LoadBalancer,则可以设置其为Ingress Controller。
- 在kubernetes中,Ingress Controller将以Pod的形式运行,监控API Server的/ingress接口后端的backend services,如果Service发生变化,则ingress controller应自动更新其转发规则
- 为了让ingress Controller正常启动,还需要为它配置一个默认backend,用于在客户端访问的URL地址不存在时,返回一个正确的404应答。这个backend服务应用任何应用实现都可以,只要满足对根路径”/“的访问返回404应答,并且提供/healthz路径以使得kubelet完成对它的健康检查。
- 对于controller和backend我们暂不创建
- ingress.yaml文件实例
[root@master demo]# cat ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test-ingress
spec:
rules:
- host: mywebsite.com
http:
paths:
- path: /demo
backend:
serviceName: testsvc
servicePort: 8080
[root@master demo]#
这个Ingress的定义,说明对目标地址http://mywebsite.com/demo的访问将被转发到集群中的service webapp即webapp:8080/demos上。
在Ingress生效之前,需要将webapp服务部署完成。同时需要注意Ingress中的Path的定义,需要与后端真实Service提供的Path一致,否则将被转转发到一个不存在的path上,引发错误。
六.YAML文件相关测试命令
- 自动测试命令的正确性,并且不执行创建
[root@master demo]# ls
ingress.yaml nginx-deployment.yaml nginx-service.yaml
#--dry-run测试命令语法,防止语法错误
[root@master demo]# kubectl run nginx-deployment --image=nginx --port=80 --replicas=2 --dry-run
kubectl run --generator=deployment/apps.v1beta1 is DEPRECATED and will be removed in a future version. Use kubectl create instead.
deployment.apps/nginx-deployment created (dry run)
[root@master demo]#
- 生成yaml文件格式,检测
[root@master demo]# kubectl run nginx-deployment --image=nginx --port=80 --replicas=2 --dry-run -o yaml
kubectl run --generator=deployment/apps.v1beta1 is DEPRECATED and will be removed in a future version. Use kubectl create instead.
apiVersion: apps/v1beta1
kind: Deployment
metadata:
creationTimestamp: null
labels:
run: nginx-deployment
name: nginx-deployment
spec:
replicas: 2
selector:
matchLabels:
run: nginx-deployment
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
run: nginx-deployment
spec:
containers:
- image: nginx
name: nginx-deployment
ports:
- containerPort: 80
resources: {}
status: {}
[root@master demo]#
- 查看生成的json格式
[root@master demo]# kubectl run nginx-deployment --image=nginx --port=80 --replicas=2 --dry-run -o json
kubectl run --generator=deployment/apps.v1beta1 is DEPRECATED and will be removed in a future version. Use kubectl create instead.
{
"kind": "Deployment",
"apiVersion": "apps/v1beta1",
"metadata": {
"name": "nginx-deployment",
"creationTimestamp": null,
"labels": {
"run": "nginx-deployment"
}
},
"spec": {
"replicas": 2,
"selector": {
"matchLabels": {
"run": "nginx-deployment"
}
},
"template": {
"metadata": {
"creationTimestamp": null,
"labels": {
"run": "nginx-deployment"
}
},
"spec": {
"containers": [
{
"name": "nginx-deployment",
"image": "nginx",
"ports": [
{
"containerPort": 80
}
],
"resources": {}
}
]
}
},
"strategy": {}
},
"status": {}
}
[root@master demo]#
- 将现有的资源生成yaml文件,在终端上打印出来
##在k8s平台上的业务可以先备份YAML文件
##--export表示到处
[root@master demo]# kubectl get deploy/nginx-deployment --export -o yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "1"
creationTimestamp: null
generation: 1
labels:
app: nginx
name: nginx-deployment
selfLink: /apis/extensions/v1beta1/namespaces/default/deployments/nginx-deployment
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: nginx
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
creationTimestamp: null
labels:
app: nginx
spec:
containers:
- image: nginx:1.15.4
imagePullPolicy: IfNotPresent
name: nginx
ports:
- containerPort: 80
protocol: TCP
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
status: {}
[root@master demo]#
##使用>保存到文件中去
- 查看字段帮助信息,它的格式为: 资源.属性.子属性,如下实例:
kubectl explain pods.spec.containers