K8s-Pod

K8S-POD由创建到深入

1、什么是pod

​ K8S pod是k8s中可以部署和管理的最小单元,pod运行着容器,可以是一个,也可以是多个,同一个pod中共享一组存储卷,且共享namespace的network、IPC以及UTS。

2、pod运行过程

​ pod启动后首先是运行的初始化容器,与主容器属于串行初始化启动,后面的其他容器包括sidecrt,adapater,ambanssador都是是并行启动的,在启动过程中有两个钩子用于设置参数,其中包括启动开始钩子postStart,用于启动之前设置参数,还有一个是prestop结束前钩子,用于设置关闭pod之前需要设置的参数。除了2钩还有3探针,包括就绪探针、健康探针、启动探针。三个探针可以针对不同状态就行容器应用配置等

3、pod的生命周期

取值 描述
Pending(悬决) Pod 已被 Kubernetes 系统接受,但有一个或者多个容器尚未创建亦未运行。此阶段包括等待 Pod 被调度的时间和通过网络下载镜像的时间。
Running(运行中) Pod 已经绑定到了某个节点,Pod 中所有的容器都已被创建。至少有一个容器仍在运行,或者正处于启动或重启状态。
Succeeded(成功) Pod 中的所有容器都已成功终止,并且不会再重启。
Failed(失败) Pod 中的所有容器都已终止,并且至少有一个容器是因为失败终止。也就是说,容器以非 0 状态退出或者被系统终止。
Unknown(未知) 因为某些原因无法取得 Pod 的状态。这种情况通常是因为与 Pod 所在主机通信失败。

如果某节点死掉或者与集群中其他节点失联,Kubernetes 会实施一种策略,将失去的节点上运行的所有 Pod 的 phase 设置为 Failed

4、创建一个简单的pod的格式

​ 使用yaml创建,k8s只识别json格式,所以编写完毕yaml文件后需要进行装换执行pod

apiVersion: v1##4api群组名称
kind: Pod ##资源类型
metadata: ##资源对象的原数据
  name: pod1 ##名称
  labele:##标签相关
  	app:
		release:
spec:
  containers:##所期望的状态
  - name: demoapp ##名称
    image: docker.io/ikubernetes/demoapp:v1.0##镜像
    env:##其指定信息配置
    - name: HOST
      value:  "127.0.0.1"
    - name: PORT
      value: "8088"

使用格式可以使用kubectl explain查看辅助文档

[root@k8sworkserver-node110 manifests]# kubectl explain pod.spec.containers.env
KIND:     Pod
VERSION:  v1

RESOURCE: env <[]Object>

DESCRIPTION:
     List of environment variables to set in the container. Cannot be updated.

     EnvVar represents an environment variable present in a Container.

FIELDS:
   name	<string> -required-
     Name of the environment variable. Must be a C_IDENTIFIER.

   value	<string>
     Variable references $(VAR_NAME) are expanded using the previously defined
     environment variables in the container and any service environment
     variables. If a variable cannot be resolved, the reference in the input
     string will be unchanged. Double $$ are reduced to a single $, which allows
     for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the
     string literal "$(VAR_NAME)". Escaped references will never be expanded,
     regardless of whether the variable exists or not. Defaults to "".

   valueFrom	<Object>
     Source for the environment variable's value. Cannot be used if value is not
     empty.

5、pod的安全上下文

SecurityContext:一组用于决定容器是如何创建和运行的约束条件,他们代表创建和运行容器时使用的运行时的参数;运行一个容器,只能给予最基础的安全运行环境!!!!

POD安全上下文支持两种级别,一种是基于pod级别,一种是基于containers级别

支持的控制项

privileged 运行特权容器
defaultAddCapabilities 可添加到容器的 Capabilities
requiredDropCapabilities 会从容器中删除的 Capabilities
allowedCapabilities 允许使用的 Capabilities 列表
volumes 控制容器可以使用哪些 volume
hostNetwork 允许使用 host 网络
hostPorts 允许的 host 端口列表
hostPID 使用 host PID namespace
hostIPC 使用 host IPC namespace
seLinux SELinux Context
runAsUser user ID
supplementalGroups 允许的补充用户组
fsGroup volume FSGroup
readOnlyRootFilesystem 只读根文件系统
allowedHostPaths 允许 hostPath 插件使用的路径列表
allowedFlexVolumes 允许使用的 flexVolume 插件列表
allowPrivilegeEscalation 允许容器进程设置
defaultAllowPrivilegeEscalation 默认是否允许特权升级

几个小栗子

配置pod为非root用户才能启动,在容器上配置为root用户启动,结果为pod启动失败,容器启动失败

apiVersion: v1
kind: Pod
metadata:
  name: pod-securitycontest
spec:
  securityContext:
    runAsNonRoot: True
  containers:
  - name: demo
    image: docker.io/ikubernetes/demoapp:v1.0
    imagePullPolicy: Never
    env:
    - name: PORT
      value: "8088"
    securityContext:
      runAsUser: 0
      runAsGroup: 0
      

  Normal   Pulled     4s (x11 over 117s)  kubelet            Container image "docker.io/ikubernetes/demoapp:v1.0" already present on machine
  Warning  Failed     4s (x11 over 117s)  kubelet            Error: container's runAsUser breaks non-root policy (pod: "pod-securitycontest_default(aa48e8f7-693d-49c7-a71b-7671168cb59a)", container: demo)
  ##查看日志
[root@k8sworkserver-node110 manifests]# kubectl logs pod-securitycontest
Error from server (BadRequest): container "demo" in pod "pod-securitycontest" is waiting to start: CreateContainerConfigError
[root@k8sworkserver-node110 manifests]# vim pod
pod1.yaml                 pod2.yaml                 pod3.yaml                 pod-securityContext.yaml


配置pod手动执行命令以及指定端口,授予端口指定权限和更改目录权限

apiVersion: v1
kind: Pod
metadata:
  name: pod-8080port-securitycontest1
spec:
  securityContext:
    runAsNonRoot: False
  containers:
  - name: demo
    image: docker.io/ikubernetes/demoapp:v1.0
    imagePullPolicy: Never
    command: ["/bin/sh","-c"]
    args: ["/sbin/iptables -t nat -A PREROUTING -p tcp --dport 8080 -j REDIRECT --to-port 80 && /usr/bin/python3 /usr/local/bin/demo.py"]
    securityContext:
      capabilities:
        add: ['NET_ADMIN']
        drop: ['CHOWN']

添加pod内核参数

每个节点都得更改,而且得重启kubelet
vim /etc/default/kubernets
KUBELETE_EXTRA_ARGS='--allowed-unsafe-sysctls=net.core.somaxconn,net.ipv4.ip_unprivileged_port_start'

添加完pod内核参数后建立一个新的pod

apiVersion: v1
kind: Pod
metadata:
  name: pod-port-sysctl
spec:
  securityContext:
    runAsNonRoot: False
    sysctls:
    - name: kernel.shm_rmid_forced
      value: "0"
    - name: net.ipv4.ip_unprivileged_port_start
      value: "0"
  containers:
  - name: demo
    image: docker.io/ikubernetes/demoapp:v1.0
    imagePullPolicy: Never
    securityContext:
      runAsUser: 1001
      runAsGroup: 1001

6、pod探针

pod 探针 一共有三种:

​ liveness probe 存活探针 监控是否处于正常存活状态,如果周期性检测未通过时,kubelet会根据restartpolicy的定义是否会重启该容器,如果没有定义,kubelet认为容器没有终止,即为健康。

​ readiness probe 就绪探针 判断容器内应用是否准备完成,能够接受请求。如果检测没有通过,与该pod关联的service会将改pod从service的后端可用端点中删除,直接在此就绪,重新添加。如未定义,只要容器没有终止,则为就绪。

​ startup probe 启动状态探针。单独的探针便于用户使用livenessprobe不通的参数或阈值。 如果定义了startup probe,只有执行完了才能进行livenessprobe。

三种探针都支持三种探针方式:

​ ExecAction:直接执行命令,命令成功返回表示探测成功。

​ TCPSocketAction:端口能正常打开对握手请求正常响应则表示成功

​ HTTPGetAction :向指定的path发送http请求,2xx ,3xx的响应码表示请求。

查看三种探针使用方式

kubectl explain pod.spec.containers.livenessProbe.httpGet

使用格式

spec:
	containers:
	- name:
	  image:
	  livenessProbe:
	  	exec<object>##命令式探针
	  	httpGet<object>##httpget探针
	  	tcpSocket<object>##tcpSocket类型探针
periodseconds<integer>##请求周期
initiailDelaySecends<integer>##发起初次探测请求的延后时长
timeoutSeconds<integer>##延时时长
successThreshold<integer>##成功阈值
failureThreshold<integer> ##失败阈值

命令式探针

vim liveness-exec-demo.yamlapiVersion: v1kind: Podmetadata:  name: liveness-exec-demo  namespace: defaultspec:  containers:  - name: demo    image: ikubernetes/demoapp:v1.0    imagePullPolicy: IfNotPresent    livenessProbe:      exec:        command: ['/bin/sh', '-c', '[ "$(curl -s 127.0.0.1/livez)" == "OK" ]']      initialDelaySeconds: 5      timeoutSeconds: 1      periodSeconds: 5	kubectl apply -f liveness-exec-demo.yaml	kubectl get podname -o wide	curl 10.244.1.102/livezOK[root@k8sworkserver-node110 manifests]####模拟更改命令判断[root@k8sworkserver-node110 manifests]#  curl -XPOST -d 'livez=DDDDD' 10.244.1.102/livez[root@k8sworkserver-node110 manifests]# curl 10.244.1.102/livezDDDDD[root@k8sworkserver-node110 manifests]#kubectl describe pods liveness-exec-demoEvents:  Type     Reason     Age                   From               Message  ----     ------     ----                  ----               -------  Normal   Scheduled  9m37s                 default-scheduler  Successfully assigned default/liveness-exec-demo to k8smasterserver-node107  Warning  Unhealthy  82s (x11 over 9m31s)  kubelet            Liveness probe failed:  Normal   Killing    82s (x3 over 6m32s)   kubelet            Container demo failed liveness probe, will be restarted  Normal   Pulled     52s (x4 over 9m37s)   kubelet            Container image "ikubernetes/demoapp:v1.0" already present on machine  Normal   Created    52s (x4 over 9m37s)   kubelet            Created container demo  Normal   Started    52s (x4 over 9m37s)   kubelet            Started container demo[root@k8sworkserver-node110 manifests]#  curl 10.244.1.102/livez[root@k8sworkserver-node110 manifests]###从上面可以看到命令式探针的效果

7、pod钩子

一共有两个:

post start hook:主要为容器启动后初始化操作。

pre stop hook:主要为容器关闭结束的清理操作

apiVersion: v1kind: Podmetadata:  name: lifecycle-demo  namespace: defaultspec:  containers:  - name: demo    image: ikubernetes/demoapp:v1.0    imagePullPolicy: IfNotPresent    securityContext:      capabilities:        add:        - NET_ADMIN    livenessProbe:      httpGet:        path: '/livez'        port: 80        scheme: HTTP      initialDelaySeconds: 5    lifecycle:      postStart:        exec:          command: ['/bin/sh','-c','iptables -t nat -A PREROUTING -p tcp --dport 8080 -j REDIRECT --to-ports 80']      preStop:        exec:          command: ['/bin/sh','-c','while killall python3; do sleep 1; done']  restartPolicy: Always

8、多容器pod

Sidecar:边车容器比如代理,外部更好的接入主容器

Adapater:适配容器,使主容器更适配外部环境,

Ambass:主容器更好适用或者接入外部环境,场景:代表主容器访问数据库。

启动前容器

apiVersion: v1kind: Podmetadata:  name: init-container-demo  namespace: defaultspec:  initContainers:  - name: iptables-init    image: ikubernetes/admin-box:latest    imagePullPolicy: IfNotPresent    command: ['/bin/sh','-c']    args: ['iptables -t nat -A PREROUTING -p tcp --dport 8080 -j REDIRECT --to-port 80']    securityContext:      capabilities:        add:        - NET_ADMIN  containers:  - name: demo    image: ikubernetes/demoapp:v1.0    imagePullPolicy: IfNotPresent    ports:    - name: http      containerPort: 80

sidecar容器

apiVersion: v1kind: Podmetadata:  name: sidecar-container-demo  namespace: defaultspec:  containers:  - name: proxy    image: envoyproxy/envoy-alpine:v1.14.1    command: ['/bin/sh','-c']    args: ['sleep 5 && envoy -c /etc/envoy/envoy.yaml']    lifecycle:      postStart:        exec:          command: ['/bin/sh','-c','wget -O /etc/envoy/envoy.yaml http://ilinux.io/envoy.yaml']  - name: demo    image: ikubernetes/demoapp:v1.0    imagePullPolicy: IfNotPresent    env:    - name: HOST      value: "127.0.0.1"    - name: PORT      value: "8080"

9、pod资源限制

上阈值:

下阈值:

apiVersion: v1kind: Podmetadata:  name: memleak-pod  labels:    app: memleakspec:  containers:  - name: simmemleak    image: ikubernetes/simmemleak    imagePullPolicy: IfNotPresent    resources:      requests:        memory: "64Mi"        cpu: "1"      limits:        memory: "64Mi"        cpu: "1"
posted @ 2022-05-01 11:13  老实人张彡  阅读(150)  评论(0编辑  收藏  举报