04 . kubernetes资源清单YAML入门

时间:2022-07-25
本文章向大家介绍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查看.