目录
一、k8s核心资源pod介绍
1.pod是什么?
2.Pod如何管理多个容器?
3.Pod网络
4.Pod存储
5.Pod工作方式
二、创建Pod资源
1.如何创建一个Pod资源
2.资源清单YAML文件书写技巧
3.通过资源清单文件创建第一个Pod
一、k8s核心资源pod介绍
1.pod是什么?
Pod是Kubernetes中的最小调度单元,k8s是通过定义一个Pod的资源,然后在Pod里面运行容器,容器需要指定一个镜像,这样就可以用来运行具体的服务。一个Pod封装一个容器(也可以封装多个容器),Pod里的容器共享存储、网络等。也就是说,应该把整个pod看作虚拟机,然后每个容器相当于运行在虚拟机的进程。
Pod是需要调度到k8s集群的工作节点来运行的,具体调度到那个节点,是根据scheduler调度器实现的
2.Pod如何管理多个容器?
pod中可以同时运行多个容器。同一个Pod的容器会自动的分配到同一个node上。同一个Pod中的容器共享资源你、网络环境,它们总是被动同时调度,在一个Pod中同时运行多个容器是一种比较高级的用法,只有当你的容器需要紧密配合协作的时候才考虑用这种模式。例如,你有一个容器作为web服务器运行,需要用到共享的volume,有另一个“sidecar”容器来从远端获取资源更新这些文件。一些Pod有init容器和应用容器。 在应用程序容器启动之前,运行初始化容器。
3.Pod网络
Pod是有IP地址的,每个pod都被分配唯一的IP地址(IP地址是靠网络插件calico、flannel、weave等分配的),POD中的容器共享网络名称空间,包括IP地址和网络端口。 Pod内部的容器可以使用localhost相互通信。 Pod中的容器也可以通过网络插件calico与其他节点的Pod通信。
4.Pod存储
创建Pod的时候可以指定挂载的存储卷。 POD中的所有容器都可以访问共享卷,允许这些容器共享数据。 Pod只要挂载持久化数据卷,Pod重启之后数据还是会存在的。
5.Pod工作方式
在K8s中,所有的资源都可以使用一个yaml文件来创建,创建Pod也可以使用yaml配置文件。或者使用kubectl run在命令行创建Pod(不常用)。
二、创建Pod资源
1.如何创建一个Pod资源
创建pod流程:
master节点:kubectl -> kube-api -> kubelet -> CRI容器环境初始化
第一步:
客户端提交创建Pod的请求,可以通过调用API Server的Rest API接口,也可以通过kubectl命令行工具。如kubectl apply -f filename.yaml(资源清单文件)
第二步:
apiserver接收到pod创建请求后,会将yaml中的属性信息(metadata)写入etcd。
第三步:
apiserver触发watch机制准备创建pod,信息转发给调度器scheduler,调度器使用调度算法选择node,调度器将node信息给apiserver,
apiserver将绑定的node信息写入etcd
调度器用一组规则过滤掉不符合要求的主机。比如Pod指定了所需要的资源量,那么可用资源比Pod需要的资源量少的主机会被过滤掉。
第四步:
apiserver又通过watch机制,调用kubelet,指定pod信息,调用Docker API创建并启动pod内的容器。
第五步:
创建完成之后反馈给kubelet, kubelet又将pod的状态信息给apiserver,
apiserver又将pod的状态信息写入etcd。
2.资源清单YAML文件书写技巧
[root@hd1com ~]#vim pod-tomcat.yaml
apiVersion: v1 #api版本
kind:Pod #创建的资源
metadata:
name: tomcat-test #Pod的名字
namespace: default #Pod所在的名称空间
labels:
app: tomcat #Pod具有的标签
spec:
containers:
- name: tomcat-java #Pod里容器的名字
prots:
- containerPort: 8080 #容器暴露的端口
image: tomcat-8.5-jre8:v1 #容器使用的镜像
imagePullPolicy: IfNotPresent #镜像拉取策略
#更新资源清单文件
[root@hd1.com ~]# kubectl apply -f pod-tomcat.yaml
# Pod资源清单编写技巧
通过kubectl explain 查看定义Pod资源包含哪些字段。
[root@hd1.com ~]# kubectl explain pod
FIELDS:
apiVersion <string>
[APIVersion定义了对象,代表了一个版本。]
kind <string>
[Kind是字符串类型的值,代表了要创建的资源。服务器可以从客户端提交的请求推断出这个资源。]
metadata <Object>
[metadata是对象,定义元数据属性信息的]
spec <Object>
[spec制定了定义Pod的规格,里面包含容器的信息]
status <Object>
[status表示状态,这个不可以修改,定义pod的时候也不需要定义这个字段]
#查看pod.metadata字段如何定义
[root@hd1.com ~]# kubectl explain pod.metadata
# metadata是对象<Object>,下面可以有多个字段
FIELDS:
labels <map[string]string> #创建的资源具有的标签
name <string> #创建的资源的名字
namespace <string> #创建的资源所属的名称空间
# namespaces划分了一个空间,在同一个namesace下的资源名字是唯一的,默认的名称空间是default。
#查看pod.spec字段如何定义
[root@hd1.com ~]# kubectl explain pod.spec
#Pod的spec字段是用来描述Pod的
FIELDS:
activeDeadlineSeconds <integer>
#表示Pod可以运行的最长时间,达到设置的值后,Pod会自动停止。
affinity <Object>
#定义亲和性的
containers <[]Object> -required-
#containers是对象列表,用来定义容器的,是必须字段。对象列表 表示下面有很多对象,对象列表下面的内容用 - 连接。
dnsConfig <Object>
dnsPolicy <string>
enableServiceLinks <boolean>
ephemeralContainers <[]Object>
hostAliases <[]Object>
hostIPC <boolean>
hostNetwork <boolean>
hostPID <boolean>
hostname <string>
imagePullSecrets <[]Object>
initContainers <[]Object>
nodeName <string>
nodeSelector <map[string]string>
overhead <map[string]string>
preemptionPolicy <string>
priority <integer>
priorityClassName <string>
readinessGates <[]Object>
restartPolicy <string>
runtimeClassName <string>
schedulerName <string>
securityContext <Object>
serviceAccount <string>
serviceAccountName <string>
setHostnameAsFQDN <boolean>
shareProcessNamespace <boolean>
subdomain <string>
terminationGracePeriodSeconds<integer>
tolerations <[]Object>
topologySpreadConstraints<[]Object>
volumes <[]Object>
#查看pod.spec.containers字段如何定义
[root@hd1.com ~]# kubectl explain pod.spec.containers
FIELDS:
args <[]string>
command <[]string>
env <[]Object>
envFrom <[]Object>
image <string>
#image是用来指定容器需要的镜像的
imagePullPolicy <string>
#镜像拉取策略,pod是要调度到node节点的,那pod启动需要镜像,可以根据这个字段设置镜像拉取策略,支持如下三种:
Always:不管本地是否存在镜像,都要重新拉取镜像
Never: 从不拉取镜像
IfNotPresent:如果本地存在,使用本地的镜像,本地不存在,从官方拉取镜像
name <string> -required-
#name是必须字段,用来指定容器名字的
ports <[]Object>
#port是端口,属于对象列表
#查看pod.spec.container.ports字段如何定义
[root@hd1.com ~]# kubectl explain pod.spec.containers.ports
FIELDS:
containerPort <integer> -required-
Number of port to expose on the pod's IP address. This must be a valid port
number, 0 < x < 65536.
#containerPort是必须字段, pod中的容器需要暴露的端口。
hostIP <string>
What host IP to bind the external port to.
#将容器中的服务暴露到宿主机的端口上时,可以指定绑定的宿主机 IP。
hostPort <integer>
Number of port to expose on the host. If specified, this must be a valid
port number, 0 < x < 65536. If HostNetwork is specified, this must match
ContainerPort. Most containers do not need this.
#容器中的服务在宿主机上映射的端口
name <string>
If specified, this must be an IANA_SVC_NAME and unique within the pod. Each
named port in a pod must have a unique name. Name for the port that can be
referred to by services.
#端口的名字
protocol <string>
Protocol for port. Must be UDP, TCP, or SCTP. Defaults to "TCP".
3.通过资源清单文件创建第一个Pod
[root@hd1 ~]# cat pod-first.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-first
namespace: default
labels:
app: tomcat-pod-first
spec:
containers:
- name: tomcat-first
ports:
- containerPort: 8080
image: tomcat:8.5-jre8-alpine
imagePullPolicy: IfNotPresent
#更新资源清单文件
[root@hd1.com ~]# kubectl apply -f pod-first.yaml
#查看pod是否创建成功
[root@hd1.com ~]# kubectl get pods -o wide -l app= tomcat-pod-first
NAME READY STATUS IP NODE
pod-first 1/1 Running 10.244.121.45 hd2.com
#查看pod日志
kubectl logs pod-first
#查看pod里指定容器的日志
kubectl logs pod-first -c tomcat-first
#进入到刚才创建的pod
kubectl exec -it pod-first -- /bin/bash
#假如pod里有多个容器,进入到pod里的指定容器,按如下命令:
kubectl exec -it pod-first -c tomcat-first -- /bin/bash
我们上面创建的pod是一个自主式pod,也就是通过pod创建一个应用程序,如果pod出现故障停掉,那么我们通过pod部署的应用也就会停掉,不安全, 还有一种控制器管理的pod,通过控制器创建pod,可以对pod的生命周期做管理,可以定义pod的副本数,如果有一个pod意外停掉,那么会自动起来一个pod替代之前的pod,之后会讲解pod的控制器