K8s资源对象管理之YAML文件的方式(升级回滚扩容缩容)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了K8s资源对象管理之YAML文件的方式(升级回滚扩容缩容)相关的知识,希望对你有一定的参考价值。
一、YAML文件基础
YAML是专门用来配置文件的语言,非常简洁和强大。与了解的properties、XML、json等数据格式,习惯之后就会发现越来越好用。其实YAML就是结合了大部分的标记语言的特性,整合新开发的。
YAML文件的特点:
层次分明、结构清晰;
使用简单、上手容易;
功能强大、语义丰富;
需要特别注意的是:
大小写敏感;
严格要求缩进;
二、YAML文件使用
1)YAML文件的组成
**Kubernetes中的YAML文件主要由五个一级字段组成,分别是:**
* apiVersion:api版本信息;
* kind:指定创建资源对象的类型;
* metadata:元数据内部的嵌套字段,定义了资源对象的名称、名称空间等;
* spec:规范定义资源应该拥有什么样的特性,依靠控制器确保性能可以满足,满足用户期望的状态。
* status:显示资源的当前状态,K8s就是确保当前状态向目标状态无限靠近从而满足用户期望。代表资源当前的状态;
2)获取编写YAML文件的帮助
虽然知道了YAML文件中的一级字段都是什么,但是还是不知道应该怎么写。可以借助以下命令来获取一些帮助信息。
[root@master ~]# kubectl api-versions
//获取当前集群支持的 apiserver版本
[root@master ~]# kubectl api-resources
//获取全部的api资源对象
[root@master ~]# kubectl explain deployment
//查看k8s某个对象的配置清单格式,应该包含哪些字段及使用方法
[root@master ~]# kubectl explain deployment.spec
//这个命令是非常重要的,它可以一级一级来获取帮助
3)YAML文件的基本格式
[root@master ~]# cat web.yaml
kind: Deployment //指定要创建的资源对象
apiVersion: extensions/v1beta1 //指定deployment所对应的API版本信息
metadata:
name: web //定义deployment的名称
spec:
replicas: 2 //指定副本数量
template:
metadata:
labels: //指定pod的标签
app: web_server
spec:
containers:
- name: nginx //指定pod运行的容器的名称
image: nginx //指定运行容器所需的镜像
4)生成资源(容器)验证并查看:
[root@master yaml]# kubectl apply -f web.yaml
[root@master yaml]# kubectl create -f web.yaml
//以上两条命令都是用于生成资源的二选一
//apply可以指定多次,如果发现文件不同,则更新
//使用“-f”来指定yaml文件,根据yaml文件中定义的内容生成所需的资源
[root@master ~]# kubectl delete -f web.yaml
//如果想快速的删除定义的资源可以用此命令
//删除yaml文件中定义的资源
[root@master yaml]# kubectl get deployments. web //查看web控制器所产生的pod
NAME READY UP-TO-DATE AVAILABLE AGE
web 2/2 2 2 30s //可以看见已经生成了两台容器
[root@master ~]# kubectl describe deployments. web //用于查看web控制器的详细信息的
注:Kubernetes已经根据YAML文件生成了我们所需的pod资源,这里资源指的就是容器!
[root@master yaml]# kubectl get pod -o wide
//此命令用于查询生成的资源及IP
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
web-d6ff6c799-c7625 1/1 Running 0 4m2s 10.244.2.3 node01 <none> <none>
web-d6ff6c799-sgjc9 1/1 Running 0 4m2s 10.244.1.3 node02 <none> <none>
[root@master yaml]# curl -I 10.244.2.3
HTTP/1.1 200 OK
Server: nginx/1.19.1
Date: Thu, 13 Aug 2020 09:45:14 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 07 Jul 2020 15:52:25 GMT
Connection: keep-alive
ETag: "5f049a39-264"
Accept-Ranges: bytes
//k8s集群内部访问表示是没有问题的
//我们需解决一个问题pod的服务能够被外部访问到
三、创建YAML文件使K8s中pod的服务能够被外部访问
[root@master ~]# cat web-svc.yaml
kind: Service
apiVersion: v1
metadata:
name: web-svc
spec:
type: NodePort //指定类型为NodePort,可以让外部访问,否则默认情况下是cluster IP,仅限集群内部访问
selector:
app: web_server //必须与deployment资源对象的标签进行关联
ports:
- protocol: TCP
port: 80 //指定要映射到的Cluster IP的端口
targetPort: 80 //指定的是要映射pod中的端口
nodePort: 31000 //指定映射到宿主机的端口,范围是30000~32767
[root@master ~]# kubectl apply -f web-svc.yaml
//生成service的控制文件(yaml中已经定义其名称为web-svc)
[root@master ~]# kubectl get svc web-svc //查看service控制器
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
web-svc NodePort 10.100.154.1 <none> 80:31000/TCP 35s
//TYPE:为NodePort,可以使外部访问;
//PORT:映射出的端口与我们定义的一样
访问浏览器测试:
四、底层负载均衡实现原理简介
# [root@master ~]# kubectl describe svc web-svc
//查看service的详细信息
返回的信息如下:
[root@master ~]# kubectl get pod -o wide | awk ‘{print $6}‘
//提取后端pod的IP地址
IP
10.244.2.3
10.244.1.3
//与上述查询的结果一样!
我们知道service是有负载均衡的能力,那么是怎么实现的?
其实,背后的原理并没有那么高大上,kube-proxy通过iptables的转发机制来实现负载均衡的效果的,先定义目标IP是service提供的群集IP,然后使用“-j”选项转发到其他iptables规则,接下来验证一下:
[root@master ~]# kubectl get svc web-svc | awk ‘{print $3}‘
CLUSTER-IP
10.100.154.1
[root@master ~]# iptables-save | grep 10.100.154.1
-A KUBE-SERVICES ! -s 10.244.0.0/16 -d 10.100.154.1/32 -p tcp -m comment --comment "default/web-svc: cluster IP" -m tcp --dport 80 -j KUBE-MARK-MASQ
-A KUBE-SERVICES -d 10.100.154.1/32 -p tcp -m comment --comment "default/web-svc: cluster IP" -m tcp --dport 80 -j KUBE-SVC-3RBUQ3B6P3MTQ3S7
//从上述结果中可以看出,当目标地址是群集IP时,就会转发到KUBE-SVC-3RBUQ3B6P3MTQ3S7规则中
[root@master ~]# iptables-save | grep KUBE-SVC-3RBUQ3B6P3MTQ3S7
:KUBE-SVC-3RBUQ3B6P3MTQ3S7 - [0:0]
-A KUBE-NODEPORTS -p tcp -m comment --comment "default/web-svc:" -m tcp --dport 31000 -j KUBE-SVC-3RBUQ3B6P3MTQ3S7
-A KUBE-SERVICES -d 10.100.154.1/32 -p tcp -m comment --comment "default/web-svc: cluster IP" -m tcp --dport 80 -j KUBE-SVC-3RBUQ3B6P3MTQ3S7
-A KUBE-SVC-3RBUQ3B6P3MTQ3S7 -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-YZTKOTIFXSS7FVXI
-A KUBE-SVC-3RBUQ3B6P3MTQ3S7 -j KUBE-SEP-MP33GWHNEEMYWCYU
//从查询结果中可以看出其负载均衡的效果,因为后端只创建了两个pod,所以其概率为0.5
由此可以看出service实现负载均衡的效果:默认情况下使用iptables规则,当然还可以使用其他的方法,这里就不介绍了!
查看负载均衡的详细信息需根据cluster ip为切入口!
实现负载均衡最根本的原理就是i:iptables规则根据random(随机数)实现的负载均衡!
五、通过YAML配置清单实现服务回滚到指定的版本
[root@master yaml]# cat httpd01.deployment.yaml
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
name: httpd
spec:
revisionHistoryLimit: 10 //记录历史版本信息为10个
replicas: 3
template:
metadata:
labels:
app: httpd-server
spec:
containers:
- name: httpd
image: 192.168.45.129:5000/httpd:v1 //三个版本根据镜像进行区分
ports: //这个只是一个声名没有任何作用
- containerPort: 80
[root@master yaml]# cat httpd02.deployment.yaml
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
name: httpd
spec:
revisionHistoryLimit: 10
replicas: 3
template:
metadata:
labels:
app: httpd-server
spec:
containers:
- name: httpd
image: 192.168.45.129:5000/httpd:v2 //三个版本根据镜像进行区分
ports:
- containerPort: 80
[root@master yaml]# cat httpd03.deployment.yaml
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
name: httpd
spec:
revisionHistoryLimit: 10
replicas: 3
template:
metadata:
labels:
app: httpd-server
spec:
containers:
- name: httpd
image: 192.168.45.129:5000/httpd:v3 //三个版本根据镜像进行区分
ports:
- containerPort: 80
[root@master yaml]# kubectl apply -f httpd01.deployment.yaml --record
//--record的作用就是记录历史版本信息
[root@master yaml]# kubectl rollout history deployment httpd
//查看历史的版本信息
deployment.extensions/httpd
REVISION CHANGE-CAUSE
1 kubectl apply --filename=httpd01.deployment.yaml --record=true
//1,表示版本对应的编号,也可以看出其对应的yaml
[root@master yaml]# kubectl apply -f httpd02.deployment.yaml --record
[root@master yaml]# kubectl apply -f httpd03.deployment.yaml --record
//根据yaml文件进行两次升级
[root@master yaml]# kubectl rollout history deployment httpd
deployment.extensions/httpd
REVISION CHANGE-CAUSE
1 kubectl apply --filename=httpd01.deployment.yaml --record=true
2 kubectl apply --filename=httpd02.deployment.yaml --record=true
3 kubectl apply --filename=httpd03.deployment.yaml --record=true
//确认升级的版本信息已经记录
[root@master yaml]# vim httpd-svc.yaml
kind: Service
apiVersion: v1
metadata:
name: httpd-svc
spec:
type: NodePort
selector:
app: httpd-server
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 31000
[root@master yaml]# kubectl apply -f httpd-svc.yaml
//创建一个svc便于访问测试
[root@master yaml]# curl 127.0.0.1:31000
<h1>hello bjq:v3</h1>
//访问测试页面效果
[root@master yaml]# kubectl rollout undo deployment httpd --to-revision=1
//回滚到版本1,使用--to-revision=1表示,1表示查看历史版本的第一列编号
[root@master yaml]# curl 127.0.0.1:31000 //测试访问
<h1>hello bjq:v1</h1>
六、用label控制pod的位置
如果不指定pod的位置的话,默认情况下,是由K8s中scheduler这个组件来完成的,不能人为的干预。如果是业务需要手动指定的话,那么就需要以下方法:
[root@master yaml]# kubectl label nodes node02 disk=ssd
//手动给node02打上一个 disk=ssd的标签
[root@master yaml]# kubectl get nodes --show-labels | grep disk=ssd
//查看集群中各个节点的标签(包含disk=ssd)
node02 Ready <none> 5d22h v1.15.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,disk=ssd,kubernetes.io/arch=amd64,kubernetes.io/hostname=node02,kubernetes.io/os=linux
//从结果中可以可看出只有node02包含这个标签
[root@master yaml]# vim httpd.yaml
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
name: httpd
spec:
revisionHistoryLimit: 10
replicas: 3
template:
metadata:
labels:
app: httpd-server
spec:
containers:
- name: httpd
image: 192.168.45.129:5000/httpd:v1
ports:
- containerPort: 80
nodeSelector: //指定标签选择器
disk: ssd
[root@master yaml]# kubectl apply -f httpd.yaml
//根据yaml文件生成所需的pod资源
[root@master yaml]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
httpd-5895f5548b-6lb97 1/1 Running 0 12s 10.244.2.8 node02 <none> <none>
httpd-5895f5548b-gh8br 1/1 Running 0 10s 10.244.2.10 node02 <none> <none>
httpd-5895f5548b-llxh7 1/1 Running 0 12s 10.244.2.9 node02 <none> <none>
//从查询结果中可以看出三个pod资源都运行在node02节点上
以上是关于K8s资源对象管理之YAML文件的方式(升级回滚扩容缩容)的主要内容,如果未能解决你的问题,请参考以下文章