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"