Kubernetes

7 阅读47分钟

1.入门

特点

1.自我修复:一旦某一个容器崩溃,能够在1秒左右迅速启动新的容器
2.弹性伸缩:可以根据需要,自动对集群中正在运行的容器数量进行调整
3.服务发现:服务可以通过自动发现的形式找到它所依赖的服务
4.负载均衡:如果一个服务起动了多个容器,能够自动实现请求的负载均衡
5.滚动更新/回滚:实现金丝雀发布/回滚

组件

k8s 集群由"控制节点(master)"和"工作节点(node)"组成

master:
api-server(接口):资源操作的唯一入口,接收用户的命令
scheduler(调度器):负责集群资源调度,按照预定的调度策略将Pod调度到相应的node节点上
controller-manager(控制器):实现对pod的管理,比如部署启动、弹性伸缩、滚动更新等
etcd(存储):键值对类型的分布式存储系统,存储集群相关数据

node:
pod:k8s的最小控制单元,容器都是运行在pod中的,一个pod中可以有1个或者多个容器
kubelet:负责维护pod的生命周期,即创建、更新、销毁容器
container-runtime:容器运行时的环境,例如:docker、containerd、CRI-O
Kube-proxy:节点的网络代理,负责为service实现服务发现和负载均衡

其他:
service:实现集群内部服务的网络调用、负载均衡
ingress:将k8s集群内部的服务暴露给外网访问,功能类似于nginx

2.资源清单

编写规则

大小写敏感
使用 "#" 标识注释
冒号 ":" 后必须有空格
"---" 表示一个开始新文件
低版本只允许使用空格缩进,不支持tab键缩进
使用空格作为缩进 缩进的空格数目不重要 只要相同层级的元素左侧对齐即可
# 纯量:一个简单的值,字符串、布尔值、整数、浮点数、null、时间、日期。
# 布尔类型
c1: true (或者True)
# 整型
c2: 234
# 浮点型
c3: 3.14
# null类型 
c4: ~    # 使用"~"表示null
# 日期类型
c5: 2018-02-17    # 日期必须使用ISO 8601格式,即yyyy-MM-dd
# 时间类型
c6: 2018-02-17T15:02:31+08:00  # 时间使用ISO 8601格式,时间和日期之间使用T连接,最后使用+代表时区
# 字符串类型
c7: heima     # 如果字符串中间有特殊字符,必须使用双引号或者单引号包裹 
c8: line1
    line2     # 字符串过多的情况可以拆成多行,每一行会被转化成一个空格
    
# 对象:键值对的集合
people:
  name: Tom
  age: 18
# 也允许另一种写法,将所有键值对写成一个行内对象
people: {name: Tom, age: 18}

# 数组:一组连词线开头的行,构成一个数组。
People
  - Tom
  - Jack
# 数组也可以采用行内表示法:
People: [Tom, Jack]

常用命令

执行资源清单文件

kubectl apply -f 文件名

查看已存在资源的资源清单

kubectl get pod pod名 -o yaml

编辑已存在资源的资源清单

kubectl edit pod pod名

生成资源清单,不执行该命令

kubectl create deployment web --image=nginx -o yaml --dry-run

生成资源清单并存储,不执行该命令

kubectl create deployment web --image=nginx -o yaml --dry-run > 路径/文件名

将已部署资源生成资源清单并存储

kubectl get deploy nginx -o yaml --export > 路径/文件名

查看指定资源可配置子项

kubectl explain pod.spec.containers

3.namespace

介绍
1.namespace主要作用是用来实现资源的相互隔离
2.通过将集群内部的资源分配到不同的namespace中,可以形成逻辑上的"组",以方便不同的组的资源进行隔离使用和管理
资源清单
apiVersion: v1
kind: Namespace # 资源类型,命名空间
metadata:
  name: dev # 命名空间名

创建

kubectl create -f 资源清单名

删除

kubectl delete -f 资源清单名
常用命令

查看指定ns下所有资源

kubectl get all -n ns名

查看所有的ns

kubectl get ns

查看指定ns

kubectl get ns ns名

指定查看格式例如wide、json、yaml等

kubectl get ns ns名 -o yaml

查看ns详情

kubectl describe ns ns名

创建ns

kubectl create ns ns名

删除ns

kubectl delete ns ns名

4.label

介绍
1.label的作用就是在资源上添加标识,用来对它们进行区分和选择
2.一个Label会以"key=value"键值对的形式附加到各种资源上,如node、pod、service等等
3.一个资源对象可以定义任意数量的label,同一个label也可以被添加到任意数量的资源对象上去
资源清单

资源清单

apiVersion: v1
kind: Pod
metadata:
  name: myapp
  namespace: dev
  labels:
    version: "3.0" # key和value 都是自定义
    env: "test" # key和value 都是自定义
spec:
  containers:
  - name: myapp
    image: nginx:latest
    ports:
    - name: nginx-port
      containerPort: 80

执行

kubectl apply -f 资源清单文件
常用命令

给资源添加label

kubectl label nodes node名 key=value

查看label

kubectl get pod pod名 --show-labels

查看version等于2.0的资源

kubectl get pod pod名 -l version=2.0 --show-labels

删除label

kubectl label pod pod名 key-

修改label

kubectl label pod pod名 key=value --overwrite
查询条件

根据label查找资源

kuctl get pod -l '查询条件'

查询条件

等式:
name = slave # 选择所有包含Label中ke等于"name"且value等于"slave"的对象。
env != production # 选择所有包括Label中的key等于"env"且value不等于"production"的对象。
集合:
name in (master, slave) # 选择所有包含Label中的key等于"name"且value等于"master"或"slave"的对象
name not in (frontend) # 选择所有包含Label中的key等于"name"且value不等于"frontend"的对象
组合:
name=slave,env!=production # key等于"name",value等于"slave" 并且 key等于"env",value不等于"production"。
name not in (frontend),env!=production # key等于"name",value不等于"frontend" 并且 key等于"env",value不等于"production"。

5.pod

介绍

概念

pod是k8s的最小控制单元,容器都是运行在pod中的,一个pod中可以有1个或者多个容器

分类

在kubernetes中,按照pod的创建方式可以将其分为两类:
1.自主式pod:kubernetes直接创建出来的Pod,这种pod删除后就没有了,也不会重建
2.工作负载创建的pod:kubernetes通过工作负载创建的pod,这种pod删除了之后还会自动重建,即自我修复

资源清单

资源清单

apiVersion: v1 # 版本号
kind: Pod # 类型 pod
metadata:
  name: myapp # pod名
  namespace: dev # 命名空间
spec:
  containers:
  - name: myapp # 容器名
    image: nginx:1.17.1 # 镜像
    imagePullPolicy: IfNotPresent # 镜像拉取策略
    ports: # 容器暴露端口列表
    - name: pod-port # 端口号名称
      containerPort: 80 # 容器监听的端口

参数说明

imagePullPolicy:  # 镜像拉取策略
    Always:默认值,每次都会尝试拉取最新的镜像
    IfNotPresent:如果本地已有镜像,则使用本地镜像,否则才从仓库拉取
    Never:仅使用本地镜像,不尝试从仓库拉取

创建

kubectl create -f 资源清单名

删除

kubectl delete -f 资源清单名

常用命令

查看所有pod

kubectl get pod

查看指定pod

kubectl get pod pod名

查看pod更多信息

kubectl get pod -o wide

查看pod详细信息

kubectl describe pod pod名

监听所有pod状态变化

kubectl get pod -w

删除pod

kubectl delete pod pod名 -n 命名空间

进入pod中的容器内部

kubectl exec -it pod名 -c 容器名 /bin/sh

探针

介绍

容器探测用于检测容器中的应用实例是否正常工作

startupProbes:启动探针,检测容器是否启动成功;如果没有,k8s不会运行pod
readinessProbe:就绪性探针,检测应用实例当前是否可以接收请求;如果不能,k8s不会转发流量
livenessProbe:存活性探针,检测应用实例当前是否处于正常运行状态;如果不是,k8s会重启容器

启动探针检测启动成功,就绪探针和存活探针才会生效

执行一次命令配置(如果命令执行的退出码为0,则认为程序正常,否则不正常)

spec: 
  startupProbes:
    exec:
      command:
      - cat
      - /tmp/healthy
    initialDelaySeconds: 10  # 容器启动后等待多少秒执行第一次探测
    timeoutSeconds: 10  # 超时时间,默认1秒,最小1秒
    periodSeconds: 10  # 执行探测的频率 默认是10秒,最小1秒
    failureThreshold: 10  # 连续探测失败多少次才被认定为失败 默认是3,最小值是1
    successThreshold: 10  # 连续探测成功多少次才被认定为成功 默认是1

访问指定socket配置

spec: 
  readinessProbe:
    tcpSocket:
      port: 8080

发起http请求配置

spec: 
  livenessProbe:
    httpGet:
      path: /live # URI地址
      port: 80 # 端口号
      host: 127.0.0.1 # 主机地址
      scheme: HTTP # 支持的协议,http或者https

钩子函数

介绍

postStart:容器创建之后执行,如果失败了会重启容器
preStop:容器终止之前执行,执行完成之后容器将成功终止,在其完成之前会阻塞删除容器的操作

访问socket配置

spec:
  containers:
    lifecycle: # 生命周期配置
      postStart:
        tcpSocket:
          port: 8080

执行一次命令配置(如果命令执行的退出码为0,则认为程序正常,否则不正常)

spec:
  containers:
    lifecycle:
      postStart: 
        exec:
          command:
          - touch
          - /home/start.txt

发起http请求配置

spec:
  containers:
    lifecycle:
      preStop:
        httpGet:
          path: /stop # URI地址
          port: 80 # 端口号
          host: 192.168.5.3 # 主机地址
          scheme: HTTP # 支持的协议,http或者https

init容器

概念

优先于其他应用容器启动,用于pod初始化工作或执行指定操作的容器

特点

1.它们总是运行到完成
2.每个都必须在下一个启动之前成功完成

资源清单

apiVersion: v1 # 版本
kind: Pod # 资源类型pod
metadata: # 元数据
  name: myapp-pod # pod名
  labels: # pod标签
    app.kubernetes.io/name: MyApp # 标签key - value
spec: # pod详细描述
  containers: # pod中容器
  - name: myapp-container # 容器名
    image: busybox:1.28 # 容器镜像
    command: ['sh', '-c', 'echo The app is running! && sleep 3600'] # 容器终端执行命令
  initContainers: # 初始化容器列表
  - name: init-myservice # 第一个初始化容器名
    image: busybox:1.28 # 第一个初始化容器镜像
    command: ['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"]
  - name: init-mydb # 第二个初始化容器名
    image: busybox:1.28 # 第二个初始化容器镜像
    command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]

生命周期

pod的生命周期

1.pod初始化阶段:运行初始化容器、运行pause容器、运行主容器
2.执行启动钩子函数(post start)
3.执行启动探针(startup probe)、就绪探针(readiness probe)
4.执行存活探针(liveness probe)
5.执行终止钩子函数(pre stop)
6.pod终止结束

在整个生命周期终,pod会出现5种状态:

挂起:已经创建了pod资源对象,但未被调度完成或处于下载镜像的过程中
运行中:pod已经被调度至某节点,并且所有容器都已经被kubectl创建完成
成功:pod中所有的容器都成功终止并且不会被重启
失败:所有容器都已经终止,但至少有一个容器终止失败,即容器返回了非0值的退出状态
未知:无法正常获取到pod对象的状态信息,通常由网络通信失败所导致

6.工作负载

介绍

概念

1.Pod控制器是管理pod的中间层,使用Pod控制器之后,只需要告诉Pod控制器,想要多少个什么样的Pod就可以了
2.Pod控制器会创建出满足条件的Pod并确保每一个Pod资源处于用户期望的目标状态
3.如果Pod资源在运行中出现故障,Pod控制器会基于指定策略重新编排Pod

分类

在k8s中,有很多类型的pod控制器,每种都有自己的适合的场景,常见的有下面这些:
1.ReplicaSet:保证副本数量一直维持在期望值,并支持pod数量扩缩容,镜像版本升级
2.Deployment:通过控制ReplicaSet来控制Pod,并支持滚动更新、版本回退
3.StatefulSet:管理有状态应用,支持滚动更新
4.DaemonSet:在集群中的指定Node上运行且仅运行一个副本,一般用于守护进程类的任务
5.Horizontal Pod Autoscaler:可以根据集群负载自动水平调整Pod的数量,实现削峰填谷
6.Job:创建出来的pod只要完成任务就立即退出,用于执行一次性任务
7.Cronjob:创建的Pod负责周期性执行任务,不需要持续后台运行

ReplicaSet

介绍

应用场景

部署无状态服务,推荐 Deployment 控制器

概念

1.ReplicaSet可以保证一定数量的pod正常运行,持续监听这些Pod的运行状态,一旦Pod发生故障,就会重启或重建
2.ReplicaSet还支持对pod数量的扩缩容和镜像版本的升降级
资源清单

资源清单

apiVersion: apps/v1 # 版本号
kind: ReplicaSet # 资源类型:ReplicaSet
metadata: # 元数据
  name: rs-demo # ReplicaSet名
  labels: # 标签
    app: guestbook # 标签key-value
    tier: frontend # 标签key-value
spec:
  replicas: 3 # 副本数量
  selector: # 选择器,通过它指定该控制器管理哪些pod
    matchLabels: # 标签匹配pod
      tier: frontend # 标签键值对
  template: # 模板,当副本数量不足时,会根据下面的模板创建pod副本
    metadata:
      labels: # 模板pod标签
        tier: frontend # 模板pod标签键值对 与spec.selector.matchLabels值相同
    spec: # 模板pod详情
      containers:
      - name: nginx
        image: nginx:1.17.1

创建

kubectl create -f 资源清单名
常用命令

查看

kubectl get rs rs名 -n 命名空间 -o wide

扩缩容 (也可以修改资源清单中"spec.replicas",然后执行资源清单来完成)

kubectl scale rs rs名 --replicas=3 -n 命名空间

镜像更新(也可以修改资源清单中"spec.template.spec.image",然后执行资源清单来完成)

kubectl set image rs rs名 nginx=nginx:1.17.1  -n 命名空间 --record '更新commit'

删除

kubectl delete rs 命名空间 -n 命名空间
kubectl delete -f 资源清单

删除rs但保留pod

kubectl delete rs 命名空间 -n 命名空间 --cascade=false

Deployment

介绍

应用场景

部署无状态的服务

概念

1.Deployment的功能: ReplicaSet的所有功能; 支持滚动升级和回滚版本; 支持更新的停止、继续
2.Deployment管理ReplicaSet,ReplicaSet管理Pod

操作分类

1.status 显示当前升级状态
2.history 显示升级历史记录
3.pause 暂停版本升级过程
4.resume 继续已经暂停的版本升级过程
5.restart 重启版本升级过程
6.undo 回滚版本(可以使用--to-revision回滚到指定版本)
资源清单

资源清单

apiVersion: apps/v1 # 版本号
kind: Deployment # 资源类型:Deployment
metadata: # 元数据
  name: my-app-deployment # Deployment负载名称
  namespace: dev # 命名空间
  labels: # 标签
    deployment: my-app-deployment # 标签键值对
spec: # 详情描述
  replicas: 3 # 副本数量
  revisionHistoryLimit: 3 # 保留历史版本
  paused: false # 暂停部署,默认是false,开启则不部署
  progressDeadlineSeconds: 600 # 部署超时时间 默认是600 单位秒
  strategy: # 更新策略
    type: RollingUpdate # 滚动更新
    rollingUpdate: # 滚动更新配置
      maxSurge: 30% # 最大额外可以存在的副本数,可以为百分比,也可以为整数
      maxUnavailable: 30% # 最大不可用状态的 Pod 的最大值,可以为百分比,也可以为整数
  selector: # 选择器,通过它指定该控制器管理哪些pod
    matchLabels: # 按标签匹配
      app: my-app # 标签匹配的key-value
  template: # 模板,当副本数量不足时,会根据下面的模板创建pod副本
    metadata:
      labels: # 模板pod标签
        app: my-app # 模板pod标签键值对 与spec.selector.matchLabels值相同
    spec: # 模板pod详情
      containers: # 模板中容器
      - name: my-app-containers # 容器名
        image: vczs/go-app:latest # 镜像
        ports: # 容器端口列表
        - containerPort: 8080 # 容器监听端口

创建deployment

kubectl create -f 资源清单
常用命令

创建一个deployment

kubectl create deploy deploy名 --image=vczs/go-app:latest --port=8080 --replicas=3 -n dev

查看所有deployment

kubectl get deploy -n 命名空间

查看指定deployment更多信息

kubectl get deploy deploy名 -n 命名空间 -o wide

查看deployment的详细信息

kubectl describe deploy deploy名 -n 命名空间

删除deployment,其下的rs和pod也将被删除

kubectl delete deploy deploy名 -n 命名空间
kubectl delete -f 资源清单

删除deployment但保留pod

kubectl delete deploy deploy名 --cascade=false
扩缩容

方法一:命令行

kubectl scale deploy deploy名 --replicas=5

方法二:资源清单

1.编辑资源清单,修改deployment的副本数量,即修改 "spec.replicas:5"

2.执行资源清单

kubectl apply -f 资源清单
镜像更新

介绍

deployment支持两种更新策略:"重建更新(Recreate)""滚动更新(RollingUpdate)"

滚动更新(推荐)

spec:
  strategy: # 更新策略
    type: RollingUpdate # 滚动更新:就是杀死一部分,就启动一部分,在更新过程中,存在两个版本Pod
    rollingUpdate: # 当type为RollingUpdate时生效,用于为RollingUpdate设置参数,支持两个属性:
      maxSurge: 25% # 用来指定在升级过程中可以超过期望的Pod的最大数量,默认为25%
      maxUnavailable: 25% # 用来指定在升级过程中不可用Pod的最大数量,默认为25%

重建更新

spec:
  strategy: # 更新策略
    type: Recreate # 重建更新:在创建出新的Pod之前会先杀掉所有已存在的Pod

镜像更新 (也可以通过修改资源清单,然后执行资源清单来完成)

kubectl set image deployment deploy名 nginx=nginx:1.17.2 -n 命名空间 --record '更新commit'
版本回退

查看版本更新历史记录

kubectl rollout history deploy deploy名 -n 命名空间

查看指定版本更新信息

kubectl rollout history deploy deploy名 --revision=版本号

回滚到上一版本

kubectl rollout undo deployment deploy名 -n 命名空间

回滚到指定版本

kubectl rollout undo deployment deploy名 --to-revision=版本号 -n 命名空间

查看当前版本的状态

kubectl rollout status deploy deploy名 -n 命名空间
暂停与恢复

介绍

由于每次修改资源清单中 "template" 都会触发deployment更新操作,那此时多次修改会频繁的更新;实际只要执行最后一次更新即可,这是就可以使用更新暂停与恢复来解决这一问题。

暂停更新,使用后修改资源清单k8s不会执行更新

kubectl rollout pause deployment deploy名

继续更新,使用后恢复"修改资源清单k8s执行更新"机制

kubectl rollout resume deploy deploy名

StatefulSet

介绍

应用场景

部署有状态的服务

概念

1.StatefulSet和Deployment一样,可以保证集群中运行指定个数的pod,也支持横向扩展。
2.StatefulSet中每一个pod会分配一个内部标记用来区分。尽管StatefulSet的pod确实是从同一个pod模板创建的,但每个pod都是不可互换的。
3.无论pod被怎样调度,它们的标记都不会改变。StatefulSet的这个特性,使得其下管理的每个pod具有不同的网络标识(可以指定发送请求到具体哪个pod,这些pod之间也可以相互通信),也可以绑定不同的持久化存储(pod重新调度之后,和它绑定的存储仍然是原先那个)。

细节

1.删除StatefulSet或者是减小StatefulSet的副本,k8s不会自动删除和已终止运行的pod绑定的数据卷。这样做是为了保证数据安全
2.为了确保StatefulSet管理的每个pod的网络标识不同,需要创建对应的 service
3.当StatefulSet被删除的时候,它不能保证所有被管理的pod都停止运行。因此,在删除StatefulSet之前,需要先将它scale到0个pod
资源清单

资源清单

apiVersion: v1
kind: Service # 创建一个Service资源类型
metadata:
  name: nginx # Service名
  labels:
    app: nginx # Service标签
spec:
  ports:
  - port: 80 # Service暴露端口80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: StatefulSet # 创建一个StatefulSet类型的资源
metadata:
  name: web # StatefulSet资源名
spec:
  selector:
    matchLabels: # 按标签匹配
      app: nginx # 标签匹配的key-value
  serviceName: "nginx"
  replicas: 3 # 3个副本
  template:
    metadata:
      labels:
        app: nginx # 模板标签
    spec:
      terminationGracePeriodSeconds: 10 # 容器删除后宽容时间
      containers:
      - name: nginx
        image: nginx:1.17.1
        ports: # 容器暴露端口列表
        - containerPort: 80 # 容器暴露端口号
          name: web # 该端口配置名字
  updateStrategy:
    type: RollingUpdate # 如果发生pod更新 StatefulSet会挨个删除并重新创建pod 操作的顺序为从pod n-1 到 pod0
    rollingUpdate:
      partition: 2 # 更新时,序号大于等于partition的pod会更新,所有序号小于partition的pod不会更新。即使将pod删除,小于该值的pod也会按之前版本恢复

创建statefulset

kubectl create -f 资源清单
常用命令

查看所有statefulset

kubectl get sts

扩缩容

kubectl scale sts statefulset名 --replicas=5

查看版本更新历史记录

kubectl rollout history sts statefulset名

查看statefulset详细信息

kubectl describe sts statefulset名

删除statefulset (对应的Service资源需要手动删除)

kubectl delete sts statefulset名
kubectl delete -f 资源清单

删除statefulset 但保留pod

kubectl delete sts statefulset名 --cascade=false
镜像更新

RollingUpdate(推荐)

spec:
  updateStrategy:
    type: RollingUpdate # 如果发生pod更新 StatefulSet会挨个删除并重新创建pod 操作的顺序为从pod n-1 到 pod0

OnDelete

spec:
  updateStrategy:
    type: OnDelete # 如果pod发生更新,StatefulSet不会更新已经运行的pod,必须将这些pod手工删除。新创建出来的pod是已更新过的pod
金丝雀发布

介绍

1.仅对集群中的一小部分pod进行版本更新,主体部分还是旧版本
2.筛选一小部分的用户请求路由到新版本的pod,观察能否稳定地按期望的方式运行
3.确定没问题之后再继续完成余下的pod资源滚动更新,否则立即回滚更新操作。这就是所谓的金丝雀发布

实现:通过资源清单 "partition" 配置项实现

spec:
  updateStrategy:
    type: RollingUpdate # 如果发生pod更新 StatefulSet会挨个删除并重新创建pod 操作的顺序为从pod n-1 到 pod0
    rollingUpdate:
      partition: 2 # 更新时,序号大于等于partition的pod会更新,所有序号小于partition的pod不会更新。即使将pod删除,小于该值的pod也会按之前版本恢复

DaemonSet

介绍

概念

服务守护进程,它的主要作用是在Kubernetes集群的所有节点中运行我们部署的守护进程,相当于在集群节点上分别部署Pod副本,如果有新节点加入集群,Daemonset会自动的在该节点上运行我们需要部署的Pod副本,相反如果有节点退出集群,Daemonset也会移除掉部署在旧节点的Pod副本。

应用场景

1.DaemonSet类型的控制器可以保证在集群中的每一台(或指定)节点上都运行一个副本。一般适用于日志收集、节点监控等场景。
2.如果一个Pod提供的功能是节点级别的(每个节点都需要且只需要一个),那么这类Pod就适合使用DaemonSet类型的控制器创建。

原理

1.DaemonSet的控制器模型DaemonSet Controller先从 Etcd 里获取所有的 Node 列表
2.然后遍历所有的 Node检查,当前这个 Node节点上是不是有一个携带了我们定义标签的 Pod 在运行
3.如果没有定义的 Pod,那么就意味着要在这个 Node 上创建这样一个 Pod
4.如果有定义的 Pod,但是数量大于 1,那就说明要调用 Kubernetes API 把多余的 Pod 从这个 Node 上删除掉
5.如果正好只有一个定义的 Pod,那说明这个节点是正常的

细节

因为DaemonSet创建的pod是节点级别的,所以没有 "replicas" 这个属性,也不具有扩缩容的性质
资源清单

资源清单

apiVersion: apps/v1 # 版本号
kind: DaemonSet # 资源类型:daemonset
metadata:
  name: fluentd-elasticsearch # daemonset名
  namespace: kube-system # 命名空间
  labels:
    k8s-app: fluentd-logging # 标签
spec:
  selector: # 选择器
    matchLabels: # 按标签匹配
      name: fluentd-elasticsearch # 要匹配的标签
  template: # 模板
    metadata: # 模板元数据
      name: DaemonSet-pod # pod名
      labels: # 标签
        name: fluentd-elasticsearch # 模板标签
    spec:
      terminationGracePeriodSeconds: 30 # 容器删除后宽限时间
      containers: # 容器
      - name: fluentd-elasticsearch # 容器名
        image: k8s.gcr.io/fluentd-elasticsearch:1.20 # 镜像
        volumeMounts: # 加载数据卷,避免数据丢失
        - name: varlog # 数据卷的名字
          mountPath: /var/log # 将数据卷挂载到容器哪个目录
        - name: varlibdockercontainers
          mountPath: /var/lib/docker/containers
      volumes: # 数据卷
      - name: varlog # 数据卷名称,容器模板根据该名称加载数据卷
        hostPath: # 数据卷类型,主机路径模式,即与宿主机共享目录
          path: /var/log # 数据卷挂载到宿主机的目录
      - name: varlibdockercontainers
        hostPath:
          path: /var/lib/docker/containers

创建

kubectl create -f 资源清单

删除

kubectl delete -f 资源清单
常用命令

查看

kubectl get ds ds名 -n 命名空间

查看更多信息

kubectl get ds ds名 -n 命名空间 -o wide

查看详细信息

kubectl describe ds ds名 -n 命名空间

删除

kubectl delete -f 资源清单
镜像更新

OnDelete(推荐)

spec:
  updateStrategy:
    type: OnDelete # 如果pod发生更新,StatefulSet不会更新已经运行的pod,必须将这些pod手工删除。新创建出来的pod是已更新过的pod

RollingUpdate

spec:
  updateStrategy:
    type: RollingUpdate # 如果发生pod更新 StatefulSet会挨个删除并重新创建pod 操作的顺序为从pod n-1 到 pod0

HPA

介绍

概念

Horizontal Pod Autoscaler(HPA):通过监测Pod的使用情况,实现pod数量的自动调整

细节

1.hpa只能加载具有动态扩缩容机制的资源上
2.添加hpa的资源必须配置 "resources.limits""resources.requests" 配置项
资源清单

资源清单

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: dev
spec:
  strategy: # 策略
    type: RollingUpdate # 滚动更新策略
  replicas: 1
  selector:
    matchLabels: # 按标签匹配
      app: nginx-pod
  template:
    metadata:
      labels:
        app: nginx-pod
    spec:
      containers:
      - name: nginx
        image: nginx:1.17.1
        resources: # 资源配额
          limits:  # 限制资源(上限)
            cpu: "10m" # CPU限制,单位是core数
            memory: "10Mi"   # 内存限制,单位可以为Mib/Gib
          requests: # 请求资源(下限)
            cpu: "10m"   # CPU限制,单位是core数
            memory: "10Mi"  # 内存限制,单位可以为Mib/Gib
---
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  name: pc-hpa
  namespace: dev
spec:
  minReplicas: 1  #最小pod数量
  maxReplicas: 10 #最大pod数量
  targetCPUUtilizationPercentage: 3 # CPU使用率指标
  scaleTargetRef:   # 指定要控制的资源信息
    apiVersion: apps/v1
    kind: Deployment
    name: nginx

创建

kubectl create -f 资源清单

删除

kubectl delete -f 资源清单
常用命令

查看

kubectl get hpa

查看pod资源占用

kubectl top pods

给指定资源加hpa

kubectl autoscale deployment deploy名 --cpu-percent=触发hpa的cpu占用率百分比 --min=最小副本数 --max=最大副本数

Job

介绍
job创建出来的pod只要完成任务就立即退出,用于执行一次性任务
资源清单

资源清单:计算 π 到小数点后 2000 位,并将结果打印出来

apiVersion: batch/v1
kind: Job # 资源类型为job
metadata:
  name: job-demo # job名
spec:
  template:
    spec:
      containers:
      - name: job-demo-pod # pod名
        image: perl:5.34.0
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never # 当Pod失败时,Job控制器会启动一个新的Pod

参数说明

restartPolicy: # pod失效策略
    Never: 当Pod失败时,Job控制器会启动一个新的Pod
    OnFailure: Pod 则继续留在当前节点,但容器会被重新运行

创建

kubectl create -f 资源清单
常用命令

查看

kubectl get job 

查看更多信息

kubectl get job -o wide

查看详细信息

kubectl describe job job名

CronJob

介绍
CronJob创建的Pod负责周期性执行任务,不需要持续后台运行
资源清单

资源清单:每分钟打印出当前时间和问候消息

apiVersion: batch/v1
kind: CronJob # 资源类型为CronJob
metadata:
  name: cj-demo # CronJob名
spec:
  suspend: false # 是否挂起任务 挂起则不执行CronJob任务
  concurrencyPolicy: Allow # 并发规则 允许并发执行任务
  schedule: "* * * * *" # 每分钟执行
  jobTemplate: # 定时执行的job模板
    spec:
      template:
        spec:
          containers:
          - name: cj-demo-pod # pod名
            image: busybox:1.28
            imagePullPolicy: IfNotPresent # 拉取策略
            command:
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster
          restartPolicy: OnFailure

参数说明

concurrencyPolicy: # 并发规则
Allow:默认规则,允许并发任务执行
Forbid:不允许并发任务执行;如果新任务的执行时间到了而老任务没有执行完,CronJob会忽略新任务的执行
Replace:如果新任务的执行时间到了而老任务没有执行完,CronJob会用新任务替换当前正在运行的任务

创建

kubectl create -f 资源清单
常用命令

查看

kubectl get cj 

查看更多信息

kubectl get cj -o wide

查看详细信息

kubectl describe cj cj名

7.服务发现

service

介绍

概念

service会对提供同一个服务的多个pod进行聚合,并且提供一个统一的入口地址; 通过访问Service的入口地址就能访问到后面的pod服务,借助Service,应用可以方便地实现服务发现和负载均衡。

原理

1.service通过Endpoint实现所有功能
2.Endpoint是k8s中的一个资源对象,存储在etcd中,用来记录一个service对应的所有pod的访问地址
3.Endpoint是根据service配置文件中selector描述产生的,service和pod之间的联系是通过endpoints实现的

service类型

1.ClusterIP:默认值,K8s系统自动分配一个虚拟ip,这个ip只能在集群内部访问
2.NodePort:将service在所有的node上暴露一个端口给外部,通过此方法,就可以在集群外部访问服务
3.LoadBalancer:使用外接负载均衡器完成到服务的负载分发,注意此模式需要外部云环境支持
4.ExternalName:把集群外部的服务引入集群内部,直接使用
资源清单
apiVersion: v1 # 版本号
kind: Service # 资源类型 service
metadata:
  name: my-go-svc # service名
  namespace: dev # 命名空间
  labels: 
    app: my-app-svc # service本身的标签
spec:
  selector: # 选择哪些pod会被该service代理
    app: my-app # 所有匹配该标签的pod都会被该service代理
  ports: # 端口映射列表
  - port: 80 # service监听的端口,service暴露的端口
    targetPort: 8080 # 目标pod的端口,映射到目标pod的端口
    name: my-app-deployment-port # 端口名
  type: ClusterIP # K8s系统自动分配一个虚拟ip,这个ip只能在集群内部访问
常用命令

创建Service

kubectl create -f 资源清单
kubectl expose deploy deploy名 --name=svc名 --type=ClusterIP --port=暴露端口 --target-port=目标pod端口

删除Service

kubectl delete -f 资源清单
kubectl delete svc svc名

查看所有Service

kubectl get svc -n 命名空间

查看Service更多信息

kubectl get svc -o wide

查看Service详细信息

kubectl describe svc svc名

创建外部可以访问的Service

kubectl expose deploy deploy名 --name=svc名 --type=NodePort --port=暴露端口 --target-port=目标pod端口

查看Endpoint

kubectl get ep

查看Endpoint更多信息

kubectl get ep -o wide

查看指定Endpoint详细信息

kubectl describe ep ep名
NodePort

概念

将service在所有的node上暴露一个端口给外部,通过此方法,就可以在集群外部访问服务

资源清单

apiVersion: v1 # 版本号
kind: Service # 资源类型 service
metadata:
  name: my-go-svc # service名
  namespace: dev # 命名空间
  labels: 
    app: my-go-svc # service本身的标签
spec:
  selector: # 选择哪些pod会被该service代理
    app: my-app # 所有匹配该标签的pod都会被该service代理
  ports: # 端口映射列表
  - port: 8080 # service监听的端口,service暴露的端口
    targetPort: 8080 # 目标pod的端口,映射到目标pod的端口
    name: my-go-svc-port # 端口名
    nodePort: 32000 # 指定在所有node上暴露的端口
  type: NodePort # 随机给一个(范围30000-32767)或指定一个端口暴露在所有node上,集群外部可以通过任意node地址加端口访问service
ExternalName

概念

ExternalName通过`externalName`属性指定外部一个服务的地址,然后在集群内部访问此service就可以访问到外部的服务了

资源清单 ("externalName"类型的service不配置"selector"项;因为他是代理外部服务,无需去匹配pod)

apiVersion: v1
kind: Service
metadata:
  name: service-externalname
  namespace: dev
spec:
  type: ExternalName # service类型
  externalName: www.baidu.com  # 需要代理的外部服务 地址 或 域名

Ingress

介绍

概念

ingress:相当于一个7层的负载均衡器,是k8s中对反向代理的一个抽象;作用是定义请求如何转发到service的规则,它的工作原理类似于Nginx
ingress controller:具体实现反向代理及负载均衡的程序,对ingress定义的规则进行解析并转化成Nginx的反向代理配置来实现请求转发

原理

1.编写Ingress规则,说明哪个域名对应kubernetes集群中的哪个Service
2.Ingress controller动态感知Ingress服务规则的变化,然后生成一段对应的Nginx反向代理配置
3.Ingress controller会将生成的Nginx配置写入到一个运行着的Nginx服务中,并动态更新
4.最后真正在工作的就是一个Nginx,内部配置了用户定义的请求转发规则

细节

1.ingress默认监听80和443端口
安装

1.获取ingress-nginx

wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml

2.改mandatory.yaml文件

修改前:quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0
修改后:quay-mirror.qiniu.com/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0

3.创建ingress-nginx

kubectl apply -f ./

4.查看ingress-nginx

kubectl get svc -n ingress-nginx
kubectl get pod -n ingress-nginx
常用命令

创建

kubectl create -f 资源清单

查看

kubectl get ing ing名 -n 命名空间

查看更多信息

kubectl get ing ing名 -o wide -n 命名空间

查看详情

kubectl describe ing ing名 -n 命名空间
Http代理

1.编写资源清单

apiVersion: networking.k8s.io/v1
kind: Ingress # 资源类型 Ingress
metadata:  # 元数据
  name: ingress-http # Ingress名
  namespace: dev # 命名空间
spec:
  rules:
  - host: k8s.vczs.top
    http:
      paths:
      - path: / # 请求路径
        pathType: ImplementationSpecific
        backend:
          service:
            name: my-go-svc # 代理的服务名
            port:
              number: 8080 # 服务的端口

2.创建资源

kubectl create -f 资源清单

3.查看效果

1.在本地电脑上配置host文件,解析上面的两个域名到集群中任意节点上
2.分别访问 vczs-one.com 和 api.bar.com 查看效果
Https代理

1.生成证书

openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/C=CN/ST=BJ/L=BJ/O=nginx/CN=itheima.com"

2.创建密钥

kubectl create secret tls tls-secret --key tls.key --cert tls.crt

3.编写资源清单

apiVersion: networking.k8s.io/v1
kind: Ingress # 资源类型 Ingress
metadata: # 元数据
  name: ingress-https # Ingress名
spec:
  tls: # https 配置
    - hosts:
      - api.bar.com # 要使用https的域名 
      - api.foo.com # 要使用https的域名 
      secretName: tls-secret # 指定秘钥
  rules:
  - host: "api.bar.com" # 请求域名
    http:
      paths:
      - pathType: Prefix
        path: "/" # 请求路径
        backend:
          service:
            name: service-bar # 代理的服务名
            port:
              number: 8080 # 服务的端口
  - host: "api.foo.com" # 请求域名
    http:
      paths:
      - pathType: Prefix
        path: "/" # 请求路径
        backend:
          service:
            name: service-foo # 代理的服务名
            port:
              number: 8080 # 服务的端口

4.创建资源

kubectl create -f 资源清单

3.查看效果

1.在本地电脑上配置host文件,解析上面的两个域名到集群中任意节点上
2.浏览器访问 https://api.bar.com 和 https://api.bar.com 来查看了

8.存储

介绍

概念
1.Volumn是Pod中能够被多个容器访问的共享目录
2.K8s的Volume定义在pod上,然后被一个pod里的多个容器挂载到具体的文件目录下
3.k8s通过Volume实现同一个pod中不同容器之间的数据共享和数据持久化存储
4.Volume的生命周期不与pod中单个容器的生命周期相关,当容器终止或重启的时候,Volume中的数据也不会被丢失
分类
配置存储:ConfigMap、Secret
简单存储:EmptyDir、HostPath、NFS
高级存储:PV、PVC
使用
使用Volume时, 在.spec.volumes字段中设置为Pod提供的卷,并在.spec.containers.volumeMounts字段中声明卷在容器中的挂载位置

配置存储

ConfigMap

介绍
ConfigMap:用来将非机密性的数据保存到键值对中,Pod可以将其用作环境变量、命令行参数或者存储卷中的配置文件。
资源清单
apiVersion: v1
kind: ConfigMap
metadata:
  name: cm-demo
data:
  # 类属性键;每一个键都映射到一个简单的值
  player_initial_lives: "3"
  ui_properties_file_name: "user-interface.properties"

  # 类文件键
  game.properties: |
    enemy.types=aliens,monsters
    player.maximum-lives=5    
  user-interface.properties: |
    color.good=purple
    color.bad=yellow
    allow.textmode=true    
常用命令

创建

kubectl create -f 资源清单

使用config文件创建configmap

kubectl create cm cm名 --from-file=文件

查看

kubectl get cm

查看详情

kubectl describe cm cm名

删除

kubectl delete cm cm名
使用

pod使用ConfigMap

apiVersion: v1
kind: Pod
metadata:
  name: cm-demo-pod
spec:
  containers:
    - name: demo
      image: alpine
      command: ["sleep", "3600"]
      env: # 环境变量使用ConfigMap
        - name: PLAYER_INITIAL_LIVES # 请注意这里和 ConfigMap 中的键名是不一样的
          valueFrom:
            configMapKeyRef:
              name: cm-demo           # 这个值来自 ConfigMap
              key: player_initial_lives # 需要取值的键
        - name: UI_PROPERTIES_FILE_NAME
          valueFrom:
            configMapKeyRef:
              name: cm-demo  # 这个值来自 ConfigMap
              key: ui_properties_file_name # 需要取值的键
      volumeMounts:   # 容器内挂载 volumes
      - name: config # 引用的volumes名
        mountPath: "/config" # 将数据卷中文件加载到容器该目录下
        readOnly: true # 是否只读
  volumes:  # 数据卷
  - name: config # volumes名
    configMap: # 数据卷类型为 configMap
      name: cm-demo  # 提供你想要挂载的 ConfigMap 的名字
      items: # 来自 ConfigMap 的一组键,将被创建为文件
      - key: "game.properties" # ConfigMap中的key
        path: "game.properties" # 将该 key 转为文件
      - key: "user-interface.properties"
        path: "user-interface.properties"

Secret

介绍
Secret:与ConfigMap非常类似的对象,它主要用于存储敏感信息,例如密码、秘钥、证书等等。
资源清单
apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  username: admin
  password: 123456
stringData:
  username: root
常用命令

创建

kubectl create -f 资源清单

查看

kubectl get secret

查看详情

kubectl describe secret secret名

删除

kubectl delete secret secret名
使用

pod使用Secret

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: redis
    volumeMounts: # 容器内挂载 ConfigMap
    - name: foo
      mountPath: "/etc/foo" # 将数据卷中文件加载到容器该目录下
      readOnly: true # 只读
  volumes:
  - name: foo
    secret:
      secretName: mysecret # secret名
      optional: true # secret是否可选  如果可选,当Secret不存在,k8s将忽略它
拉取私有镜像

配置

kubectl create secret docker-registry docker-secret --docker-username=admin --docker-password-123456 --docker-email=admin@gmail.com --docker-server=dockerhub.com

资源清单

spec: 
imagePullSecrets: 
- name: docker-secret

简单存储

EmptyDir

概念

1.EmptyDir是在Pod被分配到Node时创建的,它的初始内容为空,并且无须指定宿主机上对应的目录文件,因为k8s会自动分配一个目录
2.当Pod销毁时,EmptyDir中的数据也会被永久删除

使用场景

pod中多容器共享目录,且无需持久化

资源清单

apiVersion: v1
kind: Pod
metadata:
  name: volume-emptydir
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    ports:
    - containerPort: 80
    volumeMounts:  # 挂载数据卷
    - name: logs-volume # 数据卷
      mountPath: /var/log/nginx # 挂载目录
  - name: busybox
    image: busybox:1.30
    command: ["/bin/sh","-c","tail -f /logs/access.log"] # 初始命令,动态读取指定文件中内容
    volumeMounts:  # 挂载数据卷
    - name: logs-volume
      mountPath: /logs
  volumes: # 数据卷
  - name: logs-volume # 数据卷名
    emptyDir: {} # 数据卷类型emptyDir: Pod销毁时 EmptyDir中的数据也会被永久删除

HostPath

概念

将Node主机中一个实际目录挂在到Pod中,供容器使用,这样就可以保证Pod销毁了,但是数据依据可以存在于Node主机上,实现数据持久化存储

资源清单

apiVersion: v1
kind: Pod
metadata:
  name: volume-hostpath
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    ports:
    - containerPort: 80
    volumeMounts:
    - name: logs-volume
      mountPath: /var/log/nginx
  - name: busybox
    image: busybox:1.30
    command: ["/bin/sh","-c","tail -f /logs/access.log"]
    volumeMounts:
    - name: logs-volume
      mountPath: /logs
  volumes:
  - name: logs-volume
    hostPath:  # 数据卷类型hostPath
      path: /root/logs # 挂载到宿主机上的目录
      type: DirectoryOrCreate  # 目录存在就使用,不存在就先创建后使用

数据卷类型

DirectoryOrCreate # 目录存在就使用,不存在就先创建后使用
Directory   # 目录必须存在
FileOrCreate  # 文件存在就使用,不存在就先创建后使用
File # 文件必须存在 
Socket  # unix套接字必须存在
CharDevice  # 字符设备必须存在
BlockDevice # 块设备必须存在

NFS

概念

 1.NFS是一个网络文件存储系统,可以搭建一台NFS服务器,然后将Pod中的存储直接连接到NFS系统上
 2.这样的话,无论Pod在节点上怎么转移,只要Node跟NFS的对接没问题,数据就可以成功访问

安装nfs服务 (node节点也需安装,用来驱动nfs)

yum install nfs-utils -y

启动nfs服务

systemctl restart nfs

资源清单

apiVersion: v1
kind: Pod
metadata:
  name: volume-nfs
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    ports:
    - containerPort: 80
    volumeMounts:
    - name: logs-volume
      mountPath: /var/log/nginx
  - name: busybox
    image: busybox:1.30
    command: ["/bin/sh","-c","tail -f /logs/access.log"] 
    volumeMounts:
    - name: logs-volume
      mountPath: /logs
  volumes:
  - name: logs-volume
    nfs:
      server: 192.168.5.6  # nfs服务器地址
      path: /root/data/nfs # nfs服务器的共享文件路径

高级存储

PV

介绍

概念

1.pv是集群中由kubernetes管理员配置的一个网络存储,是集群中的存储资源,不隶属于任何namespace
2.PV的数据最终存储在硬件存储上,PV不负责数据持久化,持久化由pv所关联的NFS、Cehp等特定存储等来完成
3.PV需要绑定给PVC并最终由pod挂载PVC来使用
4.PV的生命周期独立于pod,即在使用PV的pod被删除后,PV中的数据不受影响

状态(pv的4种不同状态)

Available(可用): 表示可用状态,还未被任何 PVC 绑定
Bound(已绑定): 表示 PV 已经被 PVC 绑定
Released(已释放): 表示 PVC 被删除,但是资源还未被集群重新声明
Failed(失败): 表示该 PV 的自动回收失败
资源清单

资源清单

apiVersion: v1
kind: PersistentVolume # 资源类型类型 pv
metadata:
  name: pv
spec:
  volumeMode: Filesystem # 存储类型为文件系统
  storageClassName: slow # 存储类名 必须与pvc相同 否则不能绑定
  persistentVolumeReclaimPolicy: Retain # 回收策略 保留数据,需要管理员手工清理数据
  capacity:  # 存储能力,目前只支持存储空间的设置
    storage: 1Gi # 存储空间大小
  accessModes: # 访问模式
  - ReadWriteMany # 读写权限,可以被多个节点挂载
  nfs: # 存储类型,与底层真正存储对应;kubernetes支持多种存储类型,每种存储类型的配置都有所差异
    server: 192.168.5.6 # 存储服务器地址
    path: /root/data/pv1 # 存储服务器共享文件路径

pv的参数说明

存储能力(capacity):目前只支持存储空间的设置(storage: 1Gi),不过未来可能会加入IOPS、吞吐量等指标的配置

访问模式(accessModes):用于描述用户应用对存储资源的访问权限,访问权限包括下面几种方式:
            ReadWriteOnce(RWO):读写权限,但是只能被单个节点挂载
            ReadOnlyMany(ROX): 只读权限,可以被多个节点挂载
            ReadWriteMany(RWX):读写权限,可以被多个节点挂载
            需要注意的是,底层不同的存储类型可能支持的访问模式不同

回收策略(persistentVolumeReclaimPolicy):当PV不再被使用了之后,对其的处理方式。目前支持三种策略:
            Retain (保留) 保留数据,需要管理员手工清理数据
            Recycle(回收) 清除 PV 中的数据,效果相当于执行 rm -rf /thevolume/*
            Delete (删除) 与 PV 相连的后端存储完成 volume 的删除操作,当然这常见于云服务商的存储服务
            需要注意的是,底层不同的存储类型可能支持的回收策略不同
            
存储类名(storageClassName):PV可以通过storageClassName参数指定一个存储类名,具有特定类名的PV只能与请求了该类名的PVC进行绑定,未设定类名的PV则只能与不请求任何类名的PVC进行绑定
常用命令

创建pv

kubectl create -f pv.yaml

查看pv

kubectl get pv -o wide

PVC

介绍

概念

1.pvc是pod对存储的请求,pod挂载pvc并将数据存储在PVC,而pvc需要绑定到pv才能使用
2.pvc在使用的时候需要指定namespace,即pod要和pvc运行在一个namespace
3.使用pvc的pod被删除时,pvc中的数据无影响

细节

pvc的存储大小不能大于pv
资源清单

资源清单

apiVersion: v1
kind: PersistentVolumeClaim # 资源类型为pvc
metadata:
  name: pvc-test
spec:
  volumeMode: Filesystem # 存储类型为文件系统
  accessModes: # 访问模式
    - ReadWriteOnce # 读写权限,但是只能被单个节点挂载
  resources: # 描述对存储资源的请求
    requests: # 请求空间
      storage: 8Gi # 存储空间大小 不能大于pv的大小
  storageClassName: slow  # 存储类名 根据此配置找到相同类名的pv进行绑定
  selector:
    matchLabels: # 匹配pv标签
      release: "stable" # pv标签的 key - value
    matchExpressions: # 表达式匹配pv标签
      - {key: environment, operator: In, values: [dev]} # 表达式

pvc的参数说明

访问模式(accessModes):用于描述用户应用对存储资源的访问权限,访问权限包括下面几种方式:
            ReadWriteOnce(RWO):读写权限,但是只能被单个节点挂载
            ReadOnlyMany(ROX): 只读权限,可以被多个节点挂载
            ReadWriteMany(RWX):读写权限,可以被多个节点挂载
            需要注意的是,底层不同的存储类型可能支持的访问模式不同
常用命令

创建pvc

kubectl create -f pvc.yaml

查看pvc

kubectl get pvc -o wide
使用

pod使用pvc

apiVersion: v1
kind: Pod
metadata:
  name: pod-demo
  namespace: dev
spec:
  containers:
  - name: busybox
    image: busybox:1.30
    volumeMounts: # 挂载数据卷
    - name: pod-pvc # 数据卷名
      mountPath: /root/ # 加载到容器内目录
  volumes: # 数据卷
    - name: pod-pvc # 数据卷名
      persistentVolumeClaim: # 关联pvc
        claimName: pvc-test # pvc资源名
        readOnly: false # 关闭只读模式

生命周期

资源供应:管理员手动创建底层存储和PV

资源绑定:用户创建PVC,kubernetes负责根据PVC的声明去寻找PV并绑定

在用户定义好PVC之后,系统将根据PVC对存储资源的请求在已存在的PV中选择一个满足条件的
一旦找到,就将该PV与用户定义的PVC进行绑定,用户的应用就可以使用这个PVC了
如果找不到,PVC则会无限期处于Pending状态,直到等到系统管理员创建了一个符合其要求的PV
PV一旦绑定到某个PVC上,就会被这个PVC独占,不能再与其他PVC进行绑定了

资源使用:用户可在pod中像volume一样使用pvc

Pod使用Volume的定义 将PVC挂载到容器内的某个路径进行使用

资源释放:用户删除pvc来释放pv

当存储资源使用完毕后,用户可以删除PVC,与该PVC绑定的PV将会被标记为“已释放”,但还不能立刻与其他PVC进行绑定。通过之前PVC写入的数据可能还被留在存储设备上,只有在清除之后该PV才能再次使用。

资源回收:kubernetes根据pv设置的回收策略进行资源的回收

对于PV,管理员可以设定回收策略,用于设置与之绑定的PVC释放资源之后如何处理遗留数据的问题。只有PV的存储空间完成回收,才能供新的PVC绑定和使用

9.调度器

介绍

概念

默认情况下,一个Pod在哪个Node节点上运行,由Scheduler组件采用相应的算法计算出来的,这个过程是不受人工控制的;通过调度器可以约束一个 Pod 只能在特定的节点上运行, 或优先在特定的节点上运行

分类

1.自动调度:由Scheduler经过一系列的算法计算得出pod在哪个节点运行
2.定向调度:NodeName、NodeSelector
3.亲和性:NodeAffinity、PodAffinity、PodAntiAffinity
4.污点和容忍:Taints、Toleration

定向调度

概念

概念

利用在pod上声明nodeName或者nodeSelector,以此将Pod调度到期望的node节点上

细节

定向调度是强制的,这就意味着即使要调度的目标Node不存在,也会向上面进行调度,只不过pod运行失败而已
NodeName

利用在pod上声明nodeName或者nodeSelector,以此将Pod调度到期望的node节点上

apiVersion: v1
kind: Pod
metadata:
  name: pod-nodename
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
  nodeName: node1 # 指定调度到节点名为 node1 的节点上
NodeSelector

将pod调度到添加了指定标签的node节点上

apiVersion: v1
kind: Pod
metadata:
  name: pod-nodeselector
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
  nodeSelector: # 节点选择器
    nodeenv: pro # 指定将pod调度到具有 nodeenv=pro 标签的节点上

污点和容忍

污点

介绍

概念

1.前面的调度方式都是站在Pod的角度上,通过在Pod上添加属性,来确定Pod是否要调度到指定的Node上
2.我们也可以站在Node的角度上,通过在Node上添加污点属性,来决定是否允许Pod调度过来
3.Node被设置上污点之后就和Pod之间存在了一种相斥的关系,进而拒绝Pod调度进来,甚至可以将已经存在的Pod驱逐出去

分类

污点的格式为:"key=value:effect", key和value是污点的标签,effect描述污点的作用,支持如下三个选项:
1.PreferNoSchedule:kubernetes将尽量避免把Pod调度到具有该污点的Node上,除非没有其他节点可调度
2.NoSchedule:kubernetes将不会把Pod调度到具有该污点的Node上,但不会影响当前Node上已存在的Pod
3.NoExecute:kubernetes将不会把Pod调度到具有该污点的Node上,同时也会将Node上已存在的Pod驱离

细节

使用kubeadm搭建的集群,默认就会给master节点添加一个污点标记,所以pod就不会调度到master节点上
常用命令

设置污点

kubectl taint nodes 节点名 key=value:effect

去除污点

kubectl taint nodes node1 key:effect-

去除所有污点

kubectl taint nodes node1 key-

容忍

介绍
1.我们可以在node上添加污点用于拒绝pod调度上来。如果就是想将一个pod调度到一个有污点的node上去,这时就要使用到容忍
2.污点就是拒绝,容忍就是忽略,Node通过污点拒绝pod调度上去,Pod通过容忍忽略拒绝
使用

资源清单

apiVersion: v1
kind: Pod
metadata:
  name: pod-demo
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
  tolerations:      # 添加容忍
  - key: "tag"        # 要容忍的污点的键,空意味着匹配所有的键
    operator: "Equal" # 键值对的运算符
    value: "heima"    # 要容忍的污点的值
    effect: "NoExecute"   # 对应污点的effect,这里必须和标记的污点规则相同才可用容忍,空表示匹配所有effect
    tolerationSeconds: 0   # 容忍时间, 当effect为NoExecute时生效,表示pod在Node上的停留时间  不配置表示可以一直容忍

参数说明

operator:
	Equal: key和value必须相同才可以容忍,默认值
    Exists: key相同就可以容忍,无需配置value

亲和性

介绍

分类

1.nodeAffinity(node亲和性): 以node为目标,解决pod可以调度到哪些node的问题
2.podAffinity(pod亲和性): 以pod为目标,解决pod可以和哪些已存在的pod部署在同一个节点中的问题
3.podAntiAffinity(pod反亲和性): 以pod为目标,解决pod不能和哪些已存在pod部署在同一个节点中的问题

使用场景

亲和性:如果两个应用频繁交互,那就有必要利用亲和性让两个应用的尽可能的靠近,这样可以减少因网络通信而带来的性能损耗
反亲和性:当应用采用多副本部署时,有必要采用反亲和性让各个应用实例打散分布在各个node上,这样可以提高服务的高可用性

NodeAffinity

概念

PodAffinity:以node为参照,实现让新创建的Pod调度到符合条件的node上

硬限制

apiVersion: v1
kind: Pod
metadata:
  name: pod-nodeaffinity-required
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
  affinity:  # 亲和性设置
    nodeAffinity: # 设置node亲和性
      requiredDuringSchedulingIgnoredDuringExecution: # node亲和性硬限制:Node节点必须满足指定的所有规则 pod才会调度到该node上
        nodeSelectorTerms: # 节点选择器
        - matchExpressions: # 表达式匹配标签
          - key: nodeenv
            operator: In
            values: ["abc","bcz"] # 标签key等于nodeenv value等于"abc" 或 "bcz" 都符合条件

软限制

apiVersion: v1
kind: Pod
metadata:
  name: with-affinity-anti-affinity
spec:
  affinity: # 亲和性设置
    nodeAffinity: # node亲和性
      requiredDuringSchedulingIgnoredDuringExecution: # node亲和性硬限制:Node节点必须满足指定的所有规则 pod才会调度到该node上
        nodeSelectorTerms: # 节点选择器
        - matchExpressions: # 表达式匹配标签
          - key: kubernetes.io/os
            operator: In
            values:
            - linux  # 标签key等于'kubernetes.io/os'  value等于linux 
      preferredDuringSchedulingIgnoredDuringExecution:  # node亲和性软限制:pod优先调度到满足指定规则的Node上 (倾向)
      # 优先调度到满足条件且权重高的node上
      - weight: 1 # 权重 范围1-100
        preference: # 权重偏向
          matchExpressions: # 表达式匹配标签
          - key: label-1
            operator: In
            values:
            - key-1
      - weight: 50 # 权重 范围1-100
        preference: # 权重偏向
          matchExpressions: # 表达式匹配标签
          - key: label-2
            operator: In
            values:
            - key-2
  containers:
  - name: with-node-affinity
    image: registry.k8s.io/pause:2.0

细节

1.如果同时定义了nodeSelector和nodeAffinity,那么必须两个条件都得到满足,Pod才能运行在指定的Node上
2.如果nodeAffinity指定了多个nodeSelectorTerms,那么只需要其中一个能够匹配成功即可
3.如果一个nodeSelectorTerms中有多个matchExpressions ,则一个节点必须满足所有的才能匹配成功
4.如果一个pod所在的Node在Pod运行期间其标签发生了改变,不再符合该Pod的节点亲和性需求,则系统将忽略此变化

PodAffinity

概念

PodAffinity:以已经运行的Pod为参照,实现让新创建的Pod跟参照pod在一个node上

资源清单

apiVersion: v1
kind: Pod
metadata:
  name: with-pod-affinity
spec:
  affinity: # 亲和性设置
    podAffinity: # pod亲和性
      requiredDuringSchedulingIgnoredDuringExecution: # pod亲和性硬限制:pod必须符合所有规则,新建的pod才能调度到他所在的区域
      - labelSelector: # 标签选择器
          matchExpressions: # 表达式匹配标签
          - key: security
            operator: In
            values:
            - S1
        topologyKey: topology.kubernetes.io/zone # 约束筛选对象范围
      preferredDuringSchedulingIgnoredDuringExecution: # pod亲和性软限制:新建pod尽量调度到符合下面规则的pod所在的区域
      - labelSelector: # 标签选择器
          matchExpressions: # 表达式匹配标签
          - key: security
            operator: In
            values:
            - S1
        topologyKey: topology.kubernetes.io/zone # 约束筛选对象范围
  containers:
  - name: with-pod-affinity
    image: registry.k8s.io/pause:2.0

PodAntiAffinity

概念

PodAntiAffinity:以运行的Pod为参照,让新创建的Pod跟参照pod不在一个node中

资源清单

apiVersion: v1
kind: Pod
metadata:
  name: with-pod-affinity
spec:
  affinity: # 亲和性设置
    podAntiAffinity: # pod反亲和性
      requiredDuringSchedulingIgnoredDuringExecution: # pod反亲和性硬限制:新建的pod绝对不会调度到 符合下面规则的pod所在的区域
      - labelSelector: # 标签选择器
          matchExpressions: # 表达式匹配标签
          - key: security
            operator: In
            values:
            - S1
        topologyKey: topology.kubernetes.io/zone
      preferredDuringSchedulingIgnoredDuringExecution: # pod反亲和性软限制:新建pod尽量远离符合规则的pod所在的区域
      - weight: 100 # 权重 范围1-100
        podAffinityTerm: # pod选项
          labelSelector: # 标签选择器
            matchExpressions: # 表达式匹配标签
            - key: security
              operator: In
              values:
              - S2
          topologyKey: topology.kubernetes.io/zone # 约束筛选对象范围
  containers:
  - name: with-pod-affinity
    image: registry.k8s.io/pause:2.0

10.安全

windows

安装kubectl

1.修改配置

 set-executionpolicy remotesigned

2.安装choco

iwr https://chocolatey.org/install.ps1 -UseBasicParsing | iex

3.安装kubectl

choco install kubernetes-cli
加入集群

1.进入w10用户目录创建 ".kube"目录

2.将k8s集群的配置文件复制到该目录,文件名为 "config"

3.测试配置

kubectl get node