04 . kubernetes资源清单YAML入门
YAML
通过k8s操作yaml配置文件在node上创建资源,yaml配置文件就像船垛,用来操控docker这艘大船
yam是专门用来写配置文件的语言,非常简洁和强大。而实际上使用yaml配置文件创建这些操作对象的方式会比直接使用命令行更可取,因为这些文件可以进行版本控制,而且文件的变化和内容也可以进行审核,当使用及其复杂的配置来提供一个稳健、可靠和易维护的系统时,这些点就显得非常重要。
在声明定义配置文件的时候,所有的配置文件都存储在YAML或者JSON格式的文件中并且遵循k8s的资源配置方式。kubectl可以创建、更新、删除和获得API操作对象,当前apiVersion、kind和name会组成一个API Path以供kubectl来调用。
使用YAML用于K8s的定义带来的好处:
# 便捷性:不必添加大量的参数到命令行中执行命令
# 可维护性:YAML文件可以通过源头控制,跟踪每次操作
# 灵活性:YAML可以创建比命令行更加复杂的结构
YAML语法规则
# 1. 大小写敏感.
# 2. 使用缩进表示层级关系.
# 3. 缩进时不允许使用Tab键,只允许使用空格set ai.
# 4. 缩进的空格数不重要,只要相同层级的元素左侧对齐即可.
# 5. 表示注释,从这个字符一直到行尾,都会被解析器忽略.
# 在Kubernetes中,只需要知道两种结构类型:
# 例一.Maps: 映射即字典Kye: Value
---
apiVersion: v1
kind: Pod
# ---为可选的分隔符,当需要在一个文件中定义多个结构的时候就需要使用
# 例二.lists列表即数组
# python中的列表: args=[beijing,shaohai,shenzhen,guangzhou]
args:
- beijing
- shanghai
- shenzhen
- guangzhou
# 可以指定任何数量的项在列表中,每个项的定义以(-)开头,并且与父元素之间存在缩进
一个简单的Hello World容器Pod可以通过YAML这样定义
cat hello.yaml
---
apiVersion: v1
kind: Pod
metadata:
name: pod-demo
spec:
containers:
- name: hello
image: daocloud.io/library/centos:7
command: ["/bin/echo","hello","world"]
# apiVersion: v1
# API群组名称和版本,由组名+版本号组成: group/version,如果group省略表示核心组的定义: 可用$kubectl api-versions获取;
# 所有的映射数据都可以使用花括号,所有列表数据都得使用中括号.
# apiVersion:piserver版本,创建任何资源都是需要定义的,大部分用v1,但v1不支持deployment,用v1的扩展版extensions/v1beta1
# metadata.name: Pod名,该名称必须是唯一的.
# spec: 当前Pod内容的声明.
# restartPollcy: Never标识启动后运行一次就终止这个Pod
# containers: name为容器的名字
# container[1]: image为该启动容器的镜像
# containers[2]: command相当于Dockerfile中定义的Entrypoint,通过下列的方式来声明cmd的参数.
# command: ["/bin/echo"]
# args: ["hello","world"]
使用yaml发布一个容器化应用
项目描述
1、需要镜像,此镜像可以来自于官方,开发,或者是自己制作的镜像。
2、在k8s集群中按照 Kubernetes 项目的规范和要求,将镜像组织以它能够"认识"的方式部署此应用。考虑是否做副本,不做副本就以pod方式部署应用;做副本就需要以deployment方式部署应用,而且还需要部署一个service
什么叫Kubernetes项目能"认识"的方式?
就是使用YAML或者是JSON格式编写Kubernetes的配置文件,这是k8s的必备技能
Kubernetes跟Docker等很多项目最大的不同在于它虽然支持使用kubectl run这样的命令行方式运行容器,但它并不推荐使用此方式,而是希望用YAML文件的方式来运行容器,即把容器的定义、参数、配置,统统记录在一个 YAML 文件中,然后用kubectl create -f 配置文件的方式把它运行起来。这样部署应用还有一个最大的优点在于:文件中记录了Kubernetes到底"run"了什么。
部署过程
编写创建Pod的YAML文件
YAML 文件,对应到 k8s 中,就是一个API Object(API 对象)。当你为这个对象的各个字段填好值并提交给 k8s 之后,k8s 就会负责创建出这些对象所定义的容器或者其他类型的 API 资源.
cat pod-demo.yaml
---
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: web
spec:
containers:
- name: front-end
image: nginx
ports:
- containerPort: 80
- name: flaskapp-demo
image: jcdemo/flaskapp
ports:
- containerPort: 5000
kubectl apply -f pod-demo.yaml --validate
# kind:这里我们创建的是一个Pod,当然根据你的实际情况,这里的资源类型可以是Deployment,Job,ngress,Service等.
# metadata: 包含了我们定义的Pod的一些meta信息,比如名称namespace、标签等等信息.
# spec:包括一些containers,storage,volumes,或者其他Kubernetes需要知道的参数,以及诸如是否在容器失败时重新启动容器的属性,
# 你可以在特定KubernetesAP找到完整的Kubernetes Pod的属性让我们看一个典型容器的定义.
spec:
containers:
- name: front-end
image: nginx
ports:
- containerPort: 80
# 我们将上面内容保存成为Pod.yaml文件,来创建Pod
查询Pod的状态和生命周期事件
kubectl describe pod nginx
Name: nginx
Namespace: default
Priority: 0
Node: node2/172.19.0.54
Start Time: Thu, 19 Dec 2019 16:51:44 +0800
Labels: app=web
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"labels":{"app":"web"},"name":"nginx","namespace":"default"},"spec":{"contain...
Status: Running
IP: 10.244.1.4
IPs:
IP: 10.244.1.4
Containers:
front-end:
Container ID: docker://5b4895a1e08387557a02760b8c49513bc2728476d627677662605b1f09b4103c
Image: nginx
Image ID: docker-pullable://nginx@sha256:50cf965a6e08ec5784009d0fccb380fc479826b6e0e65684d9879170a9df8566
Port: 80/TCP
Host Port: 0/TCP
State: Running
Started: Thu, 19 Dec 2019 16:53:03 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-j9thc (ro)
flaskapp-demo:
Container ID: docker://7d2e0353226f5a36df8384244a8dbcd766bd356ca037a33eb481d4990986fcfc
Image: jcdemo/flaskapp
Image ID: docker-pullable://jcdemo/flaskapp@sha256:8dd21e8822e08414c0fe2531c22b575a33da3964e51d39cfa27e7b68520056af
Port: 5000/TCP
Host Port: 0/TCP
State: Running
Started: Thu, 19 Dec 2019 16:52:18 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-j9thc (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-j9thc:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-j9thc #(目标状态),以目标状态为准,k8s就用来确保当前状态无限向目标状态转移
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s # 容忍那些污点.
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled <unknown> default-scheduler Successfully assigned default/nginx to node2
Warning Failed 11m kubelet, node2 Failed to pull image "nginx": rpc error: code = Unknown desc = Get https://registry-1.docker.io/v2/library/nginx/manifests/sha256:189cce606b29fb2a33ebc2fcecfa8e33b0b99740da4737133cdbcee92f3aba0a: net/http: TLS handshake timeout
Normal Pulling 11m kubelet, node2 Pulling image "jcdemo/flaskapp"
Normal Pulled 10m kubelet, node2 Successfully pulled image "jcdemo/flaskapp"
Normal Created 10m kubelet, node2 Created container flaskapp-demo
Normal Started 10m kubelet, node2 Started container flaskapp-demo
Warning Failed 10m (x2 over 11m) kubelet, node2 Error: ErrImagePull
Warning Failed 10m kubelet, node2 Failed to pull image "nginx": rpc error: code = Unknown desc = Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: TLS handshake timeout
Normal BackOff 10m (x2 over 10m) kubelet, node2 Back-off pulling image "nginx"
Warning Failed 10m (x2 over 10m) kubelet, node2 Error: ImagePullBackOff
Normal Pulling 10m (x3 over 11m) kubelet, node2 Pulling image "nginx"
Normal Pulled 10m kubelet, node2 Successfully pulled image "nginx"
Normal Created 10m kubelet, node2 Created container front-end
Normal Started 10m kubelet, node2 Started container front-end
describe解释
# 名字段含义 (以Go Template方式过滤指定的信息—— 查询Pod的运行状态(类似docker的inspect))
kubectl get pods nginx --output=go-template --template={{.status.phase}}
Running
# 各字段含义
Name: Pod的名称
Namespace: Pod的Namespace。
Image(s): Pod使用的镜像
Node: Pod所在的Node。
Start Time: Pod的起始时间
Labels: Pod的Label。
Status: Pod的状态Running、Complete、Pending,就是pod的生命周期。
Reason: Pod处于当前状态的原因。
Message: Pod处于当前状态的信息。
IP: Pod的PodIP
Replication Controllers: Pod对应的Replication Controller。
Containers:Pod中容器的信息
Container ID: 容器的ID
Image: 容器的镜像
Image ID:镜像的ID
State: 容器的状态
Ready: 容器的准备状况(true表示准备就绪)。
Restart Count: 容器的重启次数统计
Environment Variables: 容器的环境变量
Conditions: Pod的条件,包含Pod准备状况(true表示准备就绪)
Volumes: Pod的数据卷
Events: 与Pod相关的事件列
创建一个简单的Pod
cat pod-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
# 如果需要更改这个Pod,修改这个配置文件要修改的信息,然后删除重建
kubectl replace -f pod-demo.yaml --force
kubectl apply -f pod-demo.yaml --force
进入Pod对应的容器内部
kubectl exec -it nginx /bin/bash
# 也可以去node端使用docker命令进入命令,并且exit对容器不会产生影响.
使用yaml创建一个名称空间
cat namespace.yml
---
apiVersion: v1
kind: Namespace
metadata:
name: ns-monitor
labels:
name: na-monitor
# 元数据习惯带name,查询时可以使用名字,但是labels可以不带,资源之间调用时使用标签.
# 创建该资源
kubectl apply -f namespace.yml
# 查看该资源
kubectl get namespaces
NAME STATUS AGE
default Active 47h
kube-node-lease Active 47h
kube-public Active 47h
kube-system Active 47h
ns-monitor Active 21s
kubectl describe namespace ns-monitor
Name: ns-monitor
Labels: name=na-monitor
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"Namespace","metadata":{"annotations":{},"labels":{"name":"na-monitor"},"name":"ns-monitor"}}
Status: Active
No resource quota.
No LimitRange resource.
# 删除该资源
kubectl delete -f namespace.yml
YAML创建deployment和service
创建deployment和pod
cat nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: daocloud.io/library/nginx
ports:
- containerPort: 80
创建service
cat nginx-service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service
labels:
app: nginx
spec:
ports:
- port: 80
targetPort: 80
selector:
app: nginx
YAML资源限制
cat pod-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: daocloud.io/library/nginx
resources:
requests:
memory: "64Mi" # 初始内存
cpu: "250m"
limits:
memory: "128Mi" # 最大内存
cpu: "500m"
# 其实此处的资源限制是跟docker差不多的,可以在docker用docker inspect查看.