1、Container和Pod概念
1、容器是一种便携式,轻量级别的虚拟化技术,使用linux cggroup技术实现各种资源的隔离,如cpu, memory, pid,mount,IPC等,相比于虚拟化技术如KVM,容器技术更加轻易级,它的产⽣主要解决环境的环境发布的问题,⽬前主流的容器技术是docker,说到容器,⼀ 般都等同于docker。
要运⾏容器⾸先需要有镜像,应⽤和应⽤依赖的环境运⾏在容器中,在kubernetes中不会直接 运⾏container,⽽是运⾏pod,⼀个pod⾥⾯包含多个container,container之间共享相同的namespace,network,storage等。镜像存储在私有镜像或有公有镜像中,运行时通过docker pull 的方式拉取到本地运⾏,images的拉取策略包含有两种:
- ImagePullPolicy为Always,不管本地是否有直接下载
- ImagePullPolicy为IfNotPresent,默认镜像拉取得策略,本地不存在再拉取
Pods是kubernetes中最⼩的调度单位,Pods内运⾏⼀个或者多个container,container之间共 享pod的⽹络ip资源,存储volume资源,计算等资源,⽅便pod内部的container之间能够实现 快速的访问和交互。
如上图所示,Pod的使用方式通常包含两种:
- Pod中运⾏⼀个容器,最经常使⽤的模式,container封装在pod中调度,两者⼏乎等同, 但k8s不直接管理容器
- Pod中运⾏多个容器,多个容器封装在pod中⼀起调度,适⽤于容器之间有数据交互和调 ⽤的场景,如app+redis,pod内部共享相同的⽹络命名空间,存储命名空间,进程命名 空间等
2 、如何创建pod
kubernetes交互的⽅式通常分为四种:
- 命令行,kubectl 和 kubernetes交互,完成资源的管理,命令行入门简单,但只能支持部分资源创建
- API,通过restfulAPI以http的方式和kubernetes交互,适用于基于API做二次开发
- SDK,提供各种语言原生的SDK,实现各种语言编程接入
- YAML,通过易于理解的YAML文件格式,描述资源的定义,功能最丰富,最终转换为json格式
kubernetes中通过定义生申明式的方式定义资源,即通过在yaml文件中定义所需的资源,kubernete通过controller-manager按照yaml文件中定义的资源去生成所需的资源(match the current state to desired state)。通常在kubernetes中通过yaml文件的⽅式定义资源,然后通 过kubectl create -f ⽂件.yaml的⽅式应⽤配置,如下演示创建⼀个nginx应⽤的操作。
1、编写yaml文件,定义一个pod资源
[root@node-1 demo]# cat nginx.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-demo
labels:
name: nginx-demo
spec:
containers:
- name: nginx-demo
image: nginx:1.7.9
imagePullPolicy: IfNotPresent
ports:
- name: nginx-port-80
protocol: TCP
containerPort: 80
关于配置文件 ,说明如下:
- apiVersion api使用的版本,kubectl api-versions可查看到当前系统能支持的版本列表
- kind 指定资源类型,表示为Pod的资源类型
- metadata 指定Pod的元数据,metadata.name指定名称,metadata.labels指定Pod的所 属的标签
- spec 指定Pod的模版属性,spec.containers配置容器的信息,spec.containers.name指定 名字,spec.containers.image指定容器镜像的名称,spec.containers.imagePullPolicy是 镜像的下载⽅式,IfNotPresent表示当镜像不存在时下载,spec.containers.ports.name指 定port的名称,spec.containers.ports.protocol协议类型为TCP, spec.containers.ports.containerPort为容器端⼝。
2、创建pod应用
[root@node-1 demo]# kubectl apply -f nginx.yaml
pod/nginx-demo created
3、访问应用
#获取容器的IP地址
[root@node-1 demo]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP
NODE NOMINATED NODE READINESS GATES
demo-7b86696648-8bq7h 1/1 Running 0 8h 10.244.1.11
node-2 <none> <none>
demo-7b86696648-8qp46 1/1 Running 0 8h 10.244.1.10
node-2 <none> <none>
demo-7b86696648-d6hfw 1/1 Running 0 8h 10.244.1.12
node-2 <none> <none>
nginx-demo 1/1 Running 0 50s 10.244.2.11
node-3 <none> <none>
#访问站点内容:
[root@node-1 demo]# curl http://10.244.2.11
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installe
d and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
kubernetes⽀持滚动升级RollingUpdate,弹性扩容replicas等特性,如何 给Pod做滚动升级保障业务不中断,如何提⾼Pod的副本个数保障⾼可⽤呢?答案是:不⽀ 持。Pod是单个,⽆法⽀持⼀些⾼级特性,⾼级特性需要通过⾼级的副本控制器如 ReplicaSets,Deployments,StatefulSets,DaemonSets等才能⽀持。Pod在实际应⽤中很少 ⽤,除了测试和运⾏⼀些简单的功能外,实际使⽤建议使⽤Deployments代替,Pod的定义以 Template的⽅式嵌⼊在副本控制器中。
3、如何编写yaml文件
前⾯我们提到过kubernetse是申明式的⽅式部署应⽤,应⽤的部署都定义在yaml⽂件中来实 现,如何来编写应⽤的yaml⽂件呢,下⾯我来分享两个实际使⽤的技巧:
1、通过定义模版快速生成,kubectl create apps -o yaml --dry-run的⽅式⽣成,--dry-run仅仅 是试运⾏,并不实际在k8s集群中运⾏,通过指定-o yaml输出yaml格式⽂件,⽣成后给基于模 版修改即可,如下:
[root@node-1 demo]# kubectl create deployment demo --image=nginx:latest --dry-run -o yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: demo
name: demo
spec:
replicas: 1
selector:
matchLabels:
app: demo
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: demo
spec:
containers:
- image: nginx:latest
name: nginx
resources: {}
status: {}
2、explain命令,explain命令堪称是语法查询器,可以查到每个字段的含义,,使⽤说明和使⽤ ⽅式,如想要查看Pod的spec中containers其他⽀持的字段,可以通过kubectl explain Pod.spec.containers的⽅式查询,如下:
[root@node-1 demo]# kubectl explain Pods.spec.containers
KIND: Pod
VERSION: v1
RESOURCE: containers <[]Object>
DESCRIPTION:
List of containers belonging to the pod. Containers cannot currently be
added or removed. There must be at least one container in a Pod. Cannot be
updated.
A single application container that you want to run within a pod.
FIELDS:
args <[]string> #命令参数
Arguments to the entrypoint. The docker image's CMD is used if this is not
provided. Variable references $(VAR_NAME) are expanded using the
container's environment. If a variable cannot be resolved, the reference in
the input string will be unchanged. The $(VAR_NAME) syntax can be escaped
with a double $$, ie: $$(VAR_NAME). Escaped references will never be
expanded, regardless of whether the variable exists or not. Cannot be
updated. More info:
https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell
image <string> #镜像定义
Docker image name. More info:
https://kubernetes.io/docs/concepts/containers/images This field is
optional to allow higher level config management to default or override
container images in workload controllers like Deployments and StatefulSets.
ports <[]Object> #端⼝定义
List of ports to expose from the container. Exposing a port here gives the
system additional information about the network connections a container
uses, but is primarily informational. Not specifying a port here DOES NOT
prevent that port from being exposed. Any port which is listening on the
default "0.0.0.0" address inside a container will be accessible from the
network. Cannot be updated.
readinessProbe <Object> #可⽤健康检查
Periodic probe of container service readiness. Container will be removed
from service endpoints if the probe fails. Cannot be updated. More info:
https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
resources <Object> #资源设置
Compute Resources required by this container. Cannot be updated. More info:
https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/
...省略部分输出...
volumeMounts <[]Object> #挂载存储
Pod volumes to mount into the container's filesystem. Cannot be updated
……
如继续上⾯的内容,如果需要查看resource资源定义,可以通过explain pods.spec.containers.resource来查看具体的使⽤⽅法。
通过上⾯两个⼯具的介绍,平时在⽇常⼯作中找到编写yaml⽂件部署应⽤的地图,建议 ⼿⼯多写⼏次,注意语法锁进,多写⼏次就熟悉了。Pod中设计到有很多的特性,如资源 分配,健康检查,存储挂载等,Pod将以 Template的⽅式嵌⼊到副本控制器如Deployments中。
4、容器镜像摘取策略
容器镜像拉取策略包含有两种:
- IfNotPresent,判断本地是否存在,如果不存在则拉取镜像,默认策略
- Always,总是拉取镜像,不论本地是否存在都会拉取镜像
Always根据镜像的设定类型,在如下场景会设置为镜像拉取策略为Always:
- 镜像的版本强制设置为latest,如image: nginx:latest
- 未设置镜像的版本,如image: nginx,这种场景和场景1类似,默认会采⽤latest的镜 像版本
- 强制指定镜像的策略为Always,如imagePullPolicy: Always
apiVersion: v1
kind: Pod
metadata:
name: happycloudlab-pod
annotations:
poduse: "demo for the first pod"
labels:
app: nginx
version: 1.7.9
spec:
containers:
- name: happycloudlab-nginx
image: nginx:1.7.9
imagePullPolicy: IfNotPresent
ports:
- name: http-80
containerPort: 80
protocol: TCP
5、容器启动命令和参数
Docker 启动的时候会有一个默认的启动进程,启动方式在dockerfile中包含有两种
- CMD
- EntryPoint
EntryPoint通常定义的是启动的命令,CMD定义的是启动参数,当然CMD也可以定义启动的命令+参数,在Kubernetes中command对应的是EntryPoint,args对应的是CMD。
- 未指定command和args,则使用容器默认的EntryPoint和CMD
- 使⽤command未指定args,则将command替换EntryPoint
- 使⽤args未使⽤command,则args替换CMD参数
- 使⽤command和args,则使⽤command替换EntryPoint,args替换CMD参数
6、容器失败重启策略
Pod中可以定义容器失败重启策略,默认是Always,通常包含三种策略:
- Always,总是重启,不管容器内部正常退出还是异常退出,一旦检测到容器进程运行异常,就会重启Pod中的所有容器;
- OnFailure,当检测到容器进程失败时,重启容器;
- Never,不重启,不管什么场景,都不重启,适用于批处理任务Jobs和CronJobs;
apiVersion: v1
kind: Pod
metadata:
name: pod-restart-demo
labels:
run: pod-restart-demo
spec:
containers:
- name: pod-restart-demo
image: busybox:latest
imagePullPolicy: IfNotPresent
command: ["cat"]
args: ["/etc/passwd"]
restartPolicy: OnFailure
7、Pod运行多个容器
Pod中可以定义运行多个容器,不同容器之间使用列表的方式分割,多个容器内部共享相同的网络命名空间,存储命名空间。适用于容器之间具有相互配合的业务场景。
附录
容器镜像介绍:https://kubernetes.io/docs/concepts/containers/images/
Pod介绍:https://kubernetes.io/docs/concepts/workloads/pods/pod-overview/ Resource
限定内存资源:https://kubernetes.io/docs/tasks/configure-podcontainer/assign-memory-resource/ Resource
限定CPU资源:https://kubernetes.io/docs/tasks/configure-podcontainer/assign-cpu-resource/ Pod挂载存储:https://kubernetes.io/docs/tasks/configure-pod-container/configurevolume-storage/ Pod
配置健康检查:https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes