K8S Pod配置进阶1 containers字段解释

k8s为什么需要Pod作为资源最小单位

容器本身的使用都是基于单进程(包括子进程),也就是命名空间里进程为1的,可以接受并处理信号,所以进程终止容器就退出了

  • IPC-进程间通讯:一般来说,一个app只有一个进程,但是在一些需要多进程的程序或者远程服务调用时,就需要跨进程通信
  • UTS-主机名:需要依赖于hostname的应用app
  • Network:需要容器拥有一样的IP、路由等网络资源

怎么考虑需要把多个容器放到一个Pod中

  • 辅助容器:作为辅助主应用的容器,比如收集log日志agent容器
  • 代理容器:主容器通过代理容器访问,比如一主多从的Redis主容器通过localhost访问通过Ambassador controller接口

实践中都应该把应用构建在单个Pod中,便于容器的亲量化设计,尤其是无状态应用

前提条件

Pod 本身并不能自愈,节点故障后也无法实现自动迁移,导致最终Pod被删除,而k8s引入Controller(控制器)的概念来管理 Pod 可以实现众多的功能(水平扩展、故障自愈、版本更新等等)
Kubernetes 中,广泛使用的控制器有:Deployment、StatefulSet、DaemonSet

自动生成Pod yaml文件方式

kubectl create deployment web --image=nginx -o yaml --dry-run > nginx.yaml
#创建一个deployment控制器的Pod,并不直接运行而是生成配置保存
kubectl get deployment nginx -o=yaml --export > ngnix1.yaml 
#获取已经运行的deployment控制器的Pod,导出yaml配置

生成基础配置说明

cat nginx.yaml 
apiVersion: extensions/v1beta1  
kind: Deployment                 
metadata:
  creationTimestamp: null
  labels:
    app: web
  name: web
spec:
  replicas: 1
  selector:
    matchLabels:
      app: web
  strategy: {
    
    }
#以上为控制层

  template:
    metadata:
      creationTimestamp: null
      labels:
        app: web
    spec:
      containers:
      - image: nginx
        name: nginx
        resources: {
    
    }
#以上为被控制层
status: {
    
    }

yaml结构

  • 控制层
    • 资源控制层(Deployment、RelicaSet、StatefulSet、Service、Pod等等)
    • labels标准选择器(控制Service映射选择,副本数控制选择、NodeSelector调度)
  • 被控制层(Pod、容器)

k8s系统将一切事物抽象成API资源,而“对象”就是“资源”的实例,是持久化的实体,实体表示整个集群的状态
可以这样理解: 资源控制层就是资源,被控制层就是对象

固定的5个第一层字段(3个嵌套字段)

可以使用命令帮助文档:kubectl explain deployment

apiVersion

  • 定义资源api版本,比如apps/v1,extensions/v1beta1(一些思考

kind

  • 定义资源类型,是在 URL 中使用的名称(Deployment、RelicaSet、StatefulSet、Service、Pod)

metadata(嵌套字段)

  • 定义资源对象元数据信息,比如名称、命名空间、标签

spec(嵌套字段)

  • 定义用户期望的状态,不同的资源,状态意义也不一样

status(嵌套字段)

  • 记录着活动对象的当前状态信息,由系统自行维护,维护 spec期望状态是否符合,不符合由系统进行补足修正

spec嵌套字段template的作用
在资源控器中才有template字段,定义对象实例而控制器通过其中配置的 Pod Template 信息来创建 Pod

selector和labels的作用关系
labels是定义资源对象的不同功能标签,为了使selector客户端/用户能够识别一组有共同特征或属性的资源对象(用标签给Pod进行分组,可以实现k8s不同服务的筛选器)
Service中通过selector筛选出Pod对象,Pod创建可以基于nodeSelector选择需要自己的节点等等

replicas:定义Pod副本数,提供Pod的冗余性,系统会尽量满足定义的数量,不排除资源不够用的场景,Pod会被驱逐

Pod对象实例容器(containers字段)

explain查看字段:kubectl explain deployment.spec.template.spec.containers

  • image:容器的文件名,用于拉取镜像,docker默认到 hub拉取镜像文件
    • 文件名由名称和标签组成,nginx:latest或者nginx都是代表拉取最新镜像,nginx:1.19.6本地没有镜像再从仓库拉取 docker hub
  • name:指定容器名称

imagePullPolicy

镜像拉取策略,默认docker是基于标签形式,而k8s存在3种方式

  • Always:镜像标签为latest或者镜像不存在时从指定的仓库拉取(默认策略
  • IfNotPresent:本地镜像缺失时从指定的仓库拉取
  • Never:仅使用本地镜像,禁止仓库拉取

ports(列表)

端口暴露

  • -containerPort:容器内部应用暴露端口,注意前面-(containerPort -required-)
    containerPort字段是必选,对于外部访问是通过service资源
  • name:端口名称:可以被service调度用
  • protocol:协议,TCP或UDP(记得要大写)
  • hostIP:端口绑定到节点上的地址,默认0.0.0.0,考虑到Pod都是基于控制器调度IP是无法确定的
  • hostPort:直接定义当前外部访问Pod,基于节点的IPport转发(区别于service的nodePort,nodePort是针对所有的节点)

explain查看字段:kubectl explain deployment.spec.template.spec.containers.ports

ReadinessProbe和LivenessProbe(列表)

用于Pod健康探测

  • ReadinessProbe:容器是否启动好并对外提供Service服务
  • LivenessProbe:运行期间容器是否故障,进入重启策略自愈

可以看之前写的文章:点击访问

args和command(列表)

指定容器启动时运行的命令和参数,要理解先要理解dockerfile中的CMD和ENTRYPOINT

在这里插入图片描述
dockerfile

  • CMD:dockerfile中指定的命令可以被docker run 末尾携带或者docker exec 末尾携带命令替换
  • ENTRYPOINT:dockerfile中指定的命令不可以被替换,docker run 末尾携带或者docker exec 末尾携带命令被追加到ENTRYPOINT中
  • 上面说的单独存在,如果2个都存在,CMD作为ENTRYPOINT的参数,CMD此时是参数集合的作用

command和args同时存在:覆盖dockerfile中默认定义,否则相反
command写了,args没有写:覆盖dockerfile中的CMD和ENTRYPOINT(如果都指定的话),自己作为无参数
command没写,args写了:那么Docker默认配置的ENTRYPOINT的命令行会被执行,args作为参数

env和envFrom

给容器注入环境变量,由于容器隔离性,容器的一些初步配置带来不便,而传入环境变量大大可以解决这种不便(系统要支持变量传入)

  • env:k8s通过env定义的名称和值
  • envFrom:ConfigMap定义的配置可以通过envFrom传入给容器(后续了解ConfigMap可以再看)

securityContext

安全上下文定义了Pod或容器的特权和访问控制设置,安全上下文是可以应用到Pod或者是具体哪一个容器中,参数存在一些区别(优先级为容器>Pod)

  • allowPrivilegeEscalation:控制进程是否可以获得超出其父进程的特权。 此布尔值直接控制是否为容器进程设置 no_new_privs标志。 当容器以特权模式运行或者具有 CAP_SYS_ADMIN 权能时,AllowPrivilegeEscalation 总是为 true(也就是为了防止提权的风险,privileged开启的话,就要删除这个字段)
  • capabilities: Linux 内核 2.2 之后引入的一个关于关联root超级用户特权的细分权限,权限分为不同的组
    • 在执行特权操作时,如果线程的有效身份不是 root,就去检查其是否具有该特权操作所对应的 capabilities,并以此为依据,决定是否可以执行特权操作
  • privileged:以特权运行容器,相当于root权限(默认为false,开启特权需要kubelet开启–allow-privileged=true )
  • readOnlyRootFilesystem:将容器的root文件系统挂载为只读,该策略有助于实施不可变的基础架构策略,可以极大的减轻恶意进程在容器内存储或操纵数据的风险
  • runAsNonRoot:容器必须以非根用户的身份运行(uid=0),不然启动就报错
  • runAsUser:容器运行用户
  • seLinuxOptions:为对象分配了安全标签

Linux 特殊权限 SUID,SGID,SBIT 点击访问
Linux capabilities 是基于SUID的安全的思考 点击访问
SELinux 点击访问
allow-privileged=true github
查看安全上下文说明kubectl explain deployment.spec.template.spec.containers.securityContext

例子

apiVersion: apps/v1
kind: Deployment
metadata:
  name: centos
  namespace: default
  labels:
    app: centos
    version: "7.6"
spec:
  replicas: 1
  selector:
    matchLabels:
     app: centos
     version: "7.6"
  template:
    metadata:
      labels:
        app: centos
        version: "7.6"
    spec:
      containers:
      - name: centos
        image: centos:7.6.1810
        imagePullPolicy: IfNotPresent
        command: [ /usr/sbin/init ]
        args: [ "echo 1111 > 1.txt","echo 2222 > 2.txt" ]
        ports:
        - containerPort: 80
          name: nginx
          protocol: TCP
          hostPort: 80
        securityContext:
          privileged: true
        env:
        - name: env1
          value: "11 22 33"
        - name: env2
          value: "44 55 66"

1、hostPort
在这里插入图片描述也就是docker run -p 80:80

2、command和args
在这里插入图片描述注意我随意写的args,其实是无效的参数,但是能正常启动,目前不知道什么原理
3、env
在这里插入图片描述
环境变量没有问题

4、privileged
在这里插入图片描述
普通权限 mount -a是会报错提示没有权限的,包括yum安装等等操作

目前就完成了最基本的简单实用,对于安全上下文理解有点难,暂未测试效果

猜你喜欢

转载自blog.csdn.net/yangshihuz/article/details/112599962
今日推荐