【云原生】Kubernetes-----声明式管理之YAML文件
在Kubernetes(K8s)的世界里,声明式管理是一种强大的资源管理方式,它允许我们定义集群中所需的状态,并让Kubernetes自动地保持这个状态。这种管理方式的核心是YAML文件,它提供了一种简洁、可读的方式来描述Kubernetes中的资源
目录
引言
在Kubernetes(K8s)的世界里,声明式管理是一种强大的资源管理方式,它允许我们定义集群中所需的状态,并让Kubernetes自动地保持这个状态。这种管理方式的核心是YAML文件,它提供了一种简洁、可读的方式来描述Kubernetes中的资源
一、声明式管理简介
(一)什么是声明式管理
声明式管理是一种编程范式,它关注的是目标状态,而不是如何达到这个状态。在Kubernetes中,我们通过编写YAML文件来声明所需的目标状态,如部署一个Web应用、配置网络策略或管理存储等。然后,Kubernetes的控制器会负责确保集群的实际状态与这些声明保持一致
(二)支持格式
Kubernetes 支持 YAML 和 JSON 格式管理资源对象
JSON 格式:主要用于 api 接口之间消息的传递
YAML 格式:用于配置和管理,YAML 是一种简洁的非标记性语言,内容格式人性化,较易读
二、YAML文件
YAML文件(YAML Ain't Markup Language)是一种常用的数据序列化格式,其设计目标是易于人类阅读和编写,同时也易于机器解析和生成。在Kubernetes中,YAML文件被广泛用于定义和描述集群中的资源对象
(一)YAML文件基本格式
1.缩进
YAML使用缩进来表示层级关系,而不像JSON那样使用大括号{}和中括号[]。
标准的YAML缩进是两个空格,不要使用制表符(tab)。
2.键值对
使用冒号:来分隔键和值,并且冒号后面必须有一个空格。
字符串值不需要引号,但如果包含特殊字符或需要多行字符串,则可以使用引号。
3.列表
使用连字符-来表示列表项,列表项之间使用换行符分隔。
列表项可以是简单的值,也可以是复杂的键值对结构。
4.数据类型
YAML支持多种数据类型,包括字符串、整数、浮点数、布尔值、空值(null)、列表(数组)、字典(哈希表/映射)等。
大小写敏感
5.多行字符串
如果字符串值需要跨越多行,可以使用|或>来标识。
|保留换行符,>将换行符转换为空格。
6.特殊字符
“---” 表示YAML格式,一个文件的开始,用于分隔文件间
如果字符串值中包含特殊字符(如冒号:、连字符-等),并且这些字符不是作为键或列表项的一部分,则需要使用引号将其括起来。
#表示注释,从#开始到行尾的内容都会被解析器忽略。
(二)YAML文件实践
结构清晰:保持YAML文件的结构清晰,使用适当的缩进和空行来分隔不同的部分。
使用注释:在YAML文件中添加注释可以帮助其他开发者或未来的自己理解代码的作用和目的。
验证YAML:在应用到集群之前,使用在线工具或本地工具验证YAML文件的语法是否正确。
版本控制:将YAML文件保存在版本控制系统中(如Git),以便跟踪更改历史并进行协作。
重用模板:使用模板和变量来重用常见的YAML模式,减少重复工作
三、YAML文件创建方式
(一)手动编辑
可以使用kubectl explain指令,根据Kubernetes的API文档和资源清单文件(resource manifest)的规范,手动编写YAML文件来定义你的资源
基本语法为:kubectl explain <资源类型......>
KIND: Deployment
VERSION: apps/v1
#这表示正在查看的资源类型是 Deployment 表示该资源类型的版本是 apps/v1
DESCRIPTION:
#描述了Deployment的功能,即它允许对Pods和 ReplicaSets进行声明式更新。
FIELDS: #以下是Deployment资源的各个字段:
apiVersion
#定义了此对象表示的版本的架构。服务器应将其识别的模式转换为最新的内部值,并可能拒绝未识别的值。
kind
#表示此对象表示的REST资源类型。服务器可以从客户端提交请求的端点推断出这一点。不能更新。
metadata
#标准的对象元数据,如名称、命名空间、标签和注释等。
spec
#指定了Deployment的期望行为。这包括要运行的Pod的模板、副本数量、选择器等。
status
#最近观察到的Deployment的状态。这是由Kubernetes系统自动设置的,通常不需要直接修改它。
例如:
[root@master01 data]#cat http.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
spec:
定义好大方向之后,再添加子字段
同样可以使用kubectl explain 资源类型.资源字段查看下一级资源可添加的内容
[root@master01 data]#cat http.yaml
apiVersion: apps/v1
kind: Deployment
......
metadata:
name: http
namespace: china
......
spec:
replicas: 3
......
一次类推, 直到yaml文件所有内容书写完毕
(二)指令生成
指令生成的yaml文件,可以有两种生成方式
1.基于现有资源创建
[root@master01 data]#kubectl get pod
NAME READY STATUS RESTARTS AGE
http 1/1 Running 0 66s
[root@master01 data]#kubectl get pod -o yaml > httpd.yaml
#将现有的pod实例,以yaml文件格式显示信息,并将信息重定向到新的yaml文件当中
#而后进入新的yaml文件修改内容
修该yaml文件内容
[root@master01 data]#cat httpd.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
run: http-01 #修改标签值
name: http-01 #修改名称
namespace: default
spec:
containers:
- image: httpd:latest
imagePullPolicy: Always
name: http-01 #修改名称
#删除不需要的字段,修改名称与标签
指定yaml文件生成pod
[root@master01 data]#kubectl create -f httpd.yaml
pod/http-01 created
[root@master01 data]#kubectl get pod
NAME READY STATUS RESTARTS AGE
http 1/1 Running 0 8m56s
http-01 1/1 Running 0 19s
2.使用指令创建
使用--dry-run选项。在Kubernetes 中,dryRun 参数通过设置 dryRun 查询参数来触发空运行。该参数是一个字符串枚举,用于指示 Kubernetes API 服务器执行请求的模拟版本,而不实际创建、更新或删除资源。
[root@master01 data]#kubectl run http-02 --image=httpd:latest -n china --dry-run=client -o yaml >httpd-02.yaml
#--dry-run=client:只会在客户端模拟请求,不会与服务器进行通信
#-o yaml:以yaml格式显示,用于保存到新的文件当中
[root@master01 data]#cat httpd-02.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null #删除该行
labels:
run: http-02
name: http-02
namespace: china
spec:
containers:
- image: httpd:latest
name: http-02
resources: {} #删除该行
dnsPolicy: ClusterFirst #删除该行
restartPolicy: Always
status: {} #删除该行
(三)网络下载
可以从官网或者其它第三方平台,将yaml文件下载下来之后进行修改
官网获取网址:Pods | Kubernetes
GITHUB获取地址:kubernetes/hack/testdata at master · kubernetes/kubernetes · GitHub
其它第三方平台:ChatGpt、Helm Chart仓库、博客、百度等
四、使用YAML文件创建资源
(一)声明式指令
1.kubectl create
语法格式:kubectl create -f xxxx.yaml
• 用途:用于从 YAML 文件中创建新的 Kubernetes 资源。
• 行为:如果资源不存在,Kubernetes 会新建该资源。如果资源已经存在,create命令会报错,因为它不支持资源的更新。
• 用途:当你知道一个资源完全不存在于集群中,并且你只想简单地根据 YAML 文件创建它时,使用 create 是合适的。它是一个幂等操作,多次执行相同命令不会改变已创建资源的状态
2.kubectl apply
语法格式:kubectl apply -f xxxx.yaml
• 用途:用于根据 YAML 文件创建或更新 Kubernetes 资源。
• 行为:apply 命令使用 "three-way merge" 策略来确定资源的变化。它首先读取集群中的当前状态,然后读取 YAML 文件中的定义,并计算两者之间的差异。
然后,它应用这些差异来更新集群中的资源。如果资源不存在,apply 会创建它。
• 优势:apply 可以用于增量更新。可以修改 YAML 文件并重新运行 apply,以应用更改,而不是每次都重新创建整个资源。
apply 支持使用 --record 标志来记录每次更改的原因,这在审计和回滚时非常有用。
• 用途:当你想要创建或更新一个资源,并且希望保留对资源更改的跟踪时,使用 apply 是合适的。
3.kubectl delete
语法格式:kubectl delete -f xxxx.yaml
• 用途:用于根据 YAML 文件中定义的资源类型和名称来删除 Kubernetes 资源。
• 行为:它会删除与 YAML 文件中指定的资源类型和名称匹配的所有资源。如果 YAML 文件中有多个资源定义,则会删除所有这些资源。
• 警告:delete 命令是破坏性的,因为它会永久删除资源。在运行 delete 命令之前,请确保你真正想要删除这些资源。
• 用途:当你想要从集群中删除由某个 YAML 文件定义的资源时,使用 delete 是合适的。
(二)创建deployment控制器
1.编写文件
编写deployment控制器yaml文件
首先定义一个简单的yaml文件,去创建一个deployment控制器
[root@master01 data]#cat nginx.yaml
apiVersion: apps/v1 #指定了API的版本。对于Deployment资源,常用的版本是apps/v1
kind: Deployment #定义了要创建的资源的类型为Deployment
metadata: #定义Deployment的元数据信息
name: nginx #元数据信息:名称为nginx
namespace: china #元数据信息:创建Deployment所在命名空间名称为china
labels: #元数据信息:定义标签为app:nginx
app: nginx
spec: #定义了Deployment的规格
replicas: 3 #运行的Pod的副本数为3个
selector: #选择由Deployment管理的Pod的标签选择器
matchLabels: #指定用于匹配的标签
app: nginx #指定标签为app:nginx
template: #定义了要创建的Pod的模板,deployment管理的pod实例,都由此模板定义
metadata: #Pod的元数据
labels: #定义Pod的标签
app: nginx
spec: #Pod的规格
containers: #Pod中要运行的容器列表
- name: nginx #容器的名称
image: nginx:1.18.0 #容器要使用的镜像名称和标签
ports: #容器要暴露的端口列表
- containerPort: 80 #容器内部监听的端口号
2.生成资源
使用kubectl apply指令生成资源
[root@master01 data]#kubectl apply -f nginx.yaml
deployment.apps/nginx created
[root@master01 data]#kubectl get pod -n my-ky35
NAME READY STATUS RESTARTS AGE
my-mysql-ky35-68988f757d-q5pnj 1/1 Running 0 33m
my-nginx-ky35 1/1 Running 1 79m
[root@master01 data]#kubectl get pod -owide -n china
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-67dfd6c8f9-8rqpn 1/1 Running 0 120m 10.244.2.108 node02 <none> <none>
nginx-67dfd6c8f9-bq2vg 1/1 Running 0 120m 10.244.1.92 node01 <none> <none>
nginx-67dfd6c8f9-pw9bt 1/1 Running 0 120m 10.244.1.91 node01 <none> <none>
(三)创建Service
创建Service资源,用于pod实例对外提供服务
1.编写文件
[root@master01 data]#cat nginx-service.yaml
apiVersion: v1 #这指定了Kubernetes API的版本
kind: Service #创建的资源类型为service
metadata: #定义资源的元数据信息
name: nginx-service #指定资源名称
namespace: china #指定命名空间
labels: #指定标签
app: nginx #定义标签为app:nginx的pod实例为service所关联
spec: #定义service规格
type: NodePort #type类型为NodePort,用于对外提供服务
ports: #定义了Service将监听哪些端口以及如何将流量路由到Pods
- port: 80 #service监听的端口为80
targetPort: 80 #这是Pods上的端口,Service将流量路由到此端口,为pod中containerPort:定义的端口
selector: #选择标签,用于选择与该Service关联的Pods
app: nginx #所有带有app: nginx标签的Pods都会关联,可以设置子标签,用来区分不同的pod
2.生成service资源
[root@master01 data]#kubectl apply -f nginx-service.yaml #创建资源
service/nginx-service created
[root@master01 data]#kubectl get svc -n china #查看后端关联节点
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-service NodePort 10.96.20.238 <none> 80:30731/TCP 13s
[root@master01 data]#kubectl get endpoints nginx-service -n china
NAME ENDPOINTS AGE
nginx-service 10.244.1.91:80,10.244.1.92:80,10.244.2.108:80 2m41s
3.访问页面
查看版本
修改访问页面
查看负载均衡
(四)创建自主式pod
自主式Pod(Ad-Hoc Pod或Non-Controller Managed Pod)是指那些由用户直接创建但不受任何控制器管理的Pod。它们通常通过kubectl run命令或直接向API Server提交YAML/JSON配置文件的方式来创建。自主式Pod一旦创建,除非手动删除,否则不会自动消失或者被重建。这类Pod没有与之关联的控制器,所以如果Pod出现故障,不会像受控制器管理的Pod那样自动恢复到期望状态
1.编写文件
将pod创建内容与service创建内容,写在同一个文件当中
[root@master01 data]#cat nginx-run.yaml
#创建命名空间,名称为nginx-pod
apiVersion: v1
kind: Namespace
metadata:
name: nginx-pod
--- #使用"---" 进行分隔。表示另一个文档的开始
#创建自主式pod
apiVersion: v1
kind: Pod #指定资源类型为Pod,则为自主式pod
metadata:
name: nginx-01
namespace: nginx-pod
labels:
run: nginx-run
spec:
containers:
- image: nginx:1.18
name: nginx-pod
ports:
- containerPort: 80 #容器端口
protocol: TCP
restartPolicy: Always #重启策略,总是重启
---
#创建service
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
namespace: nginx-pod
labels:
run: nginx-run
spec:
type: NodePort
ports:
- port: 8080 #service端口
targetPort: 80 #目标端口,与容器端口相同
selector:
run: nginx-run
2.生成资源
[root@master01 data]#kubectl apply -f nginx-run.yaml
namespace/nginx-pod created
pod/nginx-01 created
service/nginx-svc created
[root@master01 data]#kubectl get pod,svc -n nginx-pod -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/nginx-01 1/1 Running 0 8s 10.244.1.99 node01 <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/nginx-svc NodePort 10.96.132.156 <none> 8080:32176/TCP 8s run=nginx-run
3.访问验证
[root@master01 data]#curl 192.168.83.30:32176 -I
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Wed, 22 May 2024 09:43:25 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 21 Apr 2020 14:09:01 GMT
Connection: keep-alive
ETag: "5e9efe7d-264"
Accept-Ranges: bytes
[root@master01 data]#kubectl get endpoints nginx-svc -n nginx-pod
NAME ENDPOINTS AGE
nginx-svc 10.244.1.99:80 49s
五、实战------编写MySQL的yaml文件
(一)编写文件
[root@master01 data]#cat /data/mysql.yaml
apiVersion: v1
kind: Namespace
metadata:
name: mysql-server
---
apiVersion: apps/v1
kind: Deployment #mysql为动态服务器,其pod控制器应当设置为StatefulSet,为便于理解基础,先设置为Deployment
metadata:
labels:
apps: mysql
name: mysql-db
namespace: mysql-server
spec:
replicas: 1
selector:
matchLabels:
apps: mysql
template:
metadata:
labels:
apps: mysql
spec:
containers:
- name: mysql
image: mysql:latest #使用MySQL的官方镜像
ports:
- containerPort: 3306
env: #定义环境变量列表
- name: MYSQL_ROOT_PASSWORD #环境变量的名称
value: password #设置MySQL的root密码,也就是环境变量的值
#当MySQL容器首次启动时,它会检查数据库是否已经初始化,并且如果没有提供密码相关的环境变量,它会报错并退出
volumeMounts: #定义如何挂载卷到容器中
- name: mysql-data #引用的卷的名称
mountPath: /var/lib/mysql #卷在容器中的挂载路径
volumes: #定义Pod中使用的卷列表
- name: mysql-data #卷的名称,与volumeMounts中的name相对应
emptyDir: {} #一个空目录卷。这种类型的卷在Pod首次被调度到节点上时创建,并在Pod被删除时销毁。它不持久化数据,仅用于临时存储
---
apiVersion: v1
kind: Service
metadata:
name: mysql-service
namespace: mysql-server
labels:
apps: mysql
spec:
type: NodePort
ports:
- port: 3306
targetPort: 3306
selector:
apps: mysql
如果不设置环境变量会出现如下报错
[root@master01 data]#kubectl apply -f /data/mysql.yaml
namespace/mysql-server created
deployment.apps/mysql-db created
service/mysql-service created
[root@master01 data]#kubectl get pod,svc -n mysql-server -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/mysql-db-7ff7676c56-kpstg 0/1 CrashLoopBackOff 1 14s 10.244.2.112 node02 <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/mysql-service NodePort 10.96.172.68 <none> 3306:30829/TCP 14s apps=mysql
[root@master01 data]#kubectl logs mysql-db-7ff7676c56-kpstg -n mysql-server
2024-05-22 10:13:06+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.27-1debian10 started.
2024-05-22 10:13:06+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2024-05-22 10:13:06+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.27-1debian10 started.
2024-05-22 10:13:06+00:00 [ERROR] [Entrypoint]: Database is uninitialized and password option is not specified
You need to specify one of the following:
- MYSQL_ROOT_PASSWORD
- MYSQL_ALLOW_EMPTY_PASSWORD
- MYSQL_RANDOM_ROOT_PASSWORD
#错误日志表示在MySQL容器的初始化过程,表明MySQL数据库是未初始化的,并且没有指定root用户的密码
(二)生成资源
[root@master01 data]#kubectl apply -f mysql.yaml
namespace/mysql-server created
deployment.apps/mysql-db created
service/mysql-service created
[root@master01 data]#kubectl get pod,svc -n mysql-server -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/mysql-db-f458bd548-cx6jr 1/1 Running 0 90s 10.244.2.113 node02 <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/mysql-service NodePort 10.96.108.30 <none> 3306:30185/TCP 91s apps=mysql
(三)访问验证
登录mysql容器进行操作
[root@master01 data]#kubectl exec -it mysql-db-f458bd548-cx6jr -n mysql-server bash
#进入mysql容器
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@mysql-db-f458bd548-cx6jr:/# mysql -uroot -p'password'
#登录mysql服务
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.27 MySQL Community Server - GPL
Copyright (c) 2000, 2021, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)
更多推荐
所有评论(0)