Pod服务质量类别
在一个宿主机的内核之上可以运行多个容器,这些容器共享底层宿主机的内核,因此任何一个容器都可以请求占有这个内核管理的所有可用硬件资源。
但若是在多租户的环境下如果有人运行了恶意代码,那个这个容器会及大量的去占有宿主机上的资源,进而导致其他容器无法运行。
容器间的隔离默认情况下只是在内核的名称空间级别进行了隔离,但在进程运行时所用到的资源范围上没有做太多的隔离操作。
因而我们应该为每一个应用设定在其内部运行时的资源最小保证量(request)和最大保证量(limits)。
request:确保节点至少为Pod或容器预留的资源最小量。
limits:限制pod或容器的最大使用量。
计算资源k8s中的计算资源有2种,CPU、Memory。
CPU是一种可压缩资源,一个应用在不运行时不会调度到CPU上。
memory是不可压缩资源。其所申请的资源会被占用的。任何一种扩缩容都可能导致程序的崩溃或者OOM的发生。
k8s中CPU不是按照占用百分比来分配的。 而是指定容器可以占用多少个核心。1核等于1000m核。
k8s的memery分配和一般的分配没有区别,1Ki、1Mi。i表示为1024进制的 ...
Pod资源需求和资源限制
在一个宿主机的内核之上可以运行多个容器,这些容器共享底层宿主机的内核,因此任何一个容器都可以请求占有这个内核管理的所有可用硬件资源。
但若是在多租户的环境下如果有人运行了恶意代码,那个这个容器会及大量的去占有宿主机上的资源,进而导致其他容器无法运行。
容器间的隔离默认情况下只是在内核的名称空间级别进行了隔离,但在进程运行时所用到的资源范围上没有做太多的隔离操作。
因而我们应该为每一个应用设定在其内部运行时的资源最小保证量(request)和最大保证量(limits)。
request:确保节点至少为Pod或容器预留的资源最小量。
limits:限制pod或容器的最大使用量。
计算资源k8s中的计算资源有2种,CPU、Memory。
CPU是一种可压缩资源,一个应用在不运行时不会调度到CPU上。
memory是不可压缩资源。其所申请的资源会被占用的。任何一种扩缩容都可能导致程序的崩溃或者OOM的发生。
k8s中CPU不是按照占用百分比来分配的。 而是指定容器可以占用多少个核心。1核等于1000m核。
k8s的memery分配和一般的分配没有区别,1Ki、1Mi。i表示为1024进制的 ...
多容器Pod
容器设计模式中的单节点多容器模式支持三种多容器模式:
SideCar:为主容器提供辅助功能,如为主容器提供代理服务,为主容器提供数据收集。
Adapter:若某个pod内数据输出格式与某个规定的引用接受数据的格式不兼容,用适配器来将其转换以达到兼容的目的。
Ambassador:主容器中的引用不方便对外联络,可以专门制作一个容器来实现对外联络的功能。如redis集群联络其他节点可以专门做一个大使来进行联络
SideCar示例1.编写配置清单
123456789101112131415161718192021222324root@k8s-master01:~/yaml/chapter04# vim sidecar-container-demo.yamlapiVersion: v1kind: Podmetadata: name: sidecar-container-demo namespace: defaultspec: containers: - name: proxy image: envoyproxy/envoy-alpine:v1.14.1 command: ...
Pod初始化容器
在启动主容器之前还存在一个初始化容器(init containers)。初始化容器的特点在于其若是启动失败,后续的主容器将不会执行。
初始化容器可以存在多个,他们之间依次执行,当多有初始化容器执行完毕后,主容器开始执行。
在之前post start hook示例中,由于需要将送往8080的请求转发给80端口,不得不给主容器授予特权级别,用来让其在postStart中执行iptables规则,但是规则执行完毕后,主容器依旧拥有特权操作的权限,这种操作是不合理的。
所以我们可以将需要执行特权级别的操作放到初始化容器中,当初始化容器执行完毕就退出。免得主容器一直拥有特殊权限。
初始化容器示例1.编写配置清单
123456789101112131415161718192021222324root@k8s-master01:~/yaml/chapter04# vim init-container-demo.yamlapiVersion: v1kind: Podmetadata: name: init-container-demo namespace: defaultspec: initCo ...
Pod钩子
Pod中的钩子分为启动后钩子post start hook和结束前钩子pre stop hook。
post start hook:主要是为了容器启动后做一些初始化工作。只有post start hook启动成功了main container才能正常工作。
pre stop hook:一般在主进程结束之前做一些清理操作。清理操作可能会有一些要求,只有清理完成了pod才会终止,所以一定要确保pre stop hook的任务正常结束了,容器才能正常结束。
pod钩子示例1.编写资源清单
1234567891011121314151617181920212223242526272829root@k8s-master01:~/yaml/chapter04# kubectl apply -f lifecycle-demo.yamlapiVersion: v1kind: Podmetadata: name: lifecycle-demo namespace: defaultspec: containers: - name: demo image: ikubernetes/demo ...
Pod探针
以镜像格式打包并托管运行于编排系统或容器引擎上的容器就是一个黑盒,因此想要探测容器内部引用进程到底运行健康与否都被容器边界所阻挡,因此正常情况下任何一个为云原生环境所开发的应用都应该考虑到此问题,所以为了便于监测容器自身运行健康与否都应该拥有一个用于探测容器内部应用的探测接口。
一般而言一个云原生应用需要以下接口:
为了便于探测一个Pod内的容器运行健康与否,Pod在设计上直接在Pod级别或Pod内的容器级别就支持允许用户下探针的接口。
Pod内置的三种探针探测
LivenessProbe: 存活探针。周期性检测,检测未通过时,kubelet会更具restartPolicy的定义来决定是否会重启该容器;未定义时,kubelet认为容器未终止,即为健康;
ReadinessProbe: 就绪性探针。周期性检测,检测未通过时,与该Pod关联的Service,会将该Pod从Service的后端可用端点中删除;直到再次就绪,重新添加回来。未定义时,只要容器未终止,即未就绪;
StartupProbe: 启动状态检测。用于检测容器刚运行时,检测其启动是否成功。StartupProbe探针正常退 ...
容器的安全上下文
在容器上内嵌了containers字段,额外还定义了hostPort,就意味着可以像docker一样,让pod运行的那个主机打开一个DNAT的端口映射,把宿主机的某个请求做地址转换后转发至内部的容器之上。而hostNetwork所提供的功能是让pod直接共享了它所在的宿主机的网路名称空间。
以上的两个操作都属于特权操作,正常情况下,一个多租户的K8S,使用以上两种方式来让外部的流量进入k8s将会造成隔离级的开放。而k8s为了安全运行pod级容器专门设计了一种叫安全上下文的概念(SecurityContext)。
SecuritContext:安全上下文主要是允许用户和管理员定义容器或Pod的特权或访问控制机制,以配置容器、主机以及主机之上的其他容器之间的隔离方式或隔离级别。安全上下文就是一组决定容器如何创建和运行的约束条件,他们代表创建和运行容器时使用的运行时参数。
SecurityContext级别Pod上的SecurityContext有两个级别:
Pod级别:对Pod内的所有容器生效
容器级别:只对Pod内的单个容器生效
安全上下文相关资源定义12345678910111 ...
共享宿主机网络名称空间
使用hostPort引入外部流量存在着无法确定pod调度到后端的哪个节点的缺陷。
以下为另一种引入外部流量的实现方法,让容器共享宿主机的网络名称空间。
共享Network示例1.创建资源配置清单
12345678910111213141516root@k8s-master01:~/yaml/chapter01# vim mypod-host-network.yamlapiVersion: v1kind: Podmetadata: name: mypod-host-network labels: app: demoapp release: canaryspec: containers: - name: mypod-host-network image: ikubernetes/demoapp:v1.0 env: - name: PORT value: "8080" hostNetwork: true # 共享宿主机的网络名称空间,默认为false
2.创建容器
12root@k8s-master01:~/yam ...
暴露容器端口
在Docker中经常需要使用expose来暴露容器中的端口。但是在Pod上暴露端口看上去没有什么用,因为Pod与Pod之间跨主机能直接访问。而Pod与宿主机之外的流量也无法直接访问,除非使用宿主机的NodePort,或者与Service进行通信。
Pod向外部暴露端口1.创建配置清单
123456789101112131415161718root@k8s-master01:~/yaml/chapter01# vim mypod-with-ports.yamlapiVersion: v1kind: Podmetadata: name: mypod-with-ports labels: app: mypod release: canaryspec: containers: - name: demoapp image: ikubernetes/demoapp:v1.0 ports: - name: http containerPort: 80 # 指定容器内的监听的端口,可以不指定Pod在k8s内可以直接访问到 protocol: ...
向Pod中传递环境变量
环境变量是用来做容器配置的非常重要的环节,容器制作时,如果配置文件已经被固定,这就意味着容器只能适用于一种环境。所以在容器制作过程中如果需要向容器内部传送环境变量来改变配置,则需要使用卷挂载或使用enterypoint脚本来实现。否则k8s向容器中传递的变量除了能出现在容器内的printenv中之外,其他将毫无意义。
以下以ikubernetes/demoapp:v1.0镜像为例,此境支持HOST和PORT变量的接收。
变量传递HOST1.创建资源清单。
123456789101112131415root@k8s-master01:~/yaml/chapter01# vim mypod-with-env-var.yamlapiVersion: v1kind: Podmetadata: name: mypod-with-env-var labels: app: mypod release: canaryspec: containers: - name: demoapp image: ikubernetes/demoapp:v1.0 env: - na ...