Pod
Pod的主要实现机制是基于:共享网络、共享存储。
共享网络:通过Pause容器,把其他业务容器加入到Pause容器里,让所有业务容器在同一个名称空间中,可以实现网络共享。
共享存储:引入数据卷Volumn,使用Volumn进行持久化存储。
Pod的镜像拉取策略有如下三种:
1、IfNotPresent:默认值,镜像在宿主机上不存在时才拉取。
2、Always:每次创建Pod都会重新拉取一次镜像。
3、Never:Pod永远不会主动拉取这个镜像。
可以通过spec - containers - imagePullPolicy 字段来设置镜像拉取策略。
Pod的资源请求和限制主要由以下几种字段设置:
spec.containers[].resources.requests.cpu
spec.containers[].resources.requests.memory
spec.containers[].resources.limits.cpu
spec.containers[].resources.limits.memory
需要注意的是,资源限制的功能本身还是由docker实现的,而不是Pod。
Pod重启机制有以下3种:
Always:当容器终止退出后,总是重启容器,默认策略。
OnFailure:当容器异常退出(状态码非0)时,才重启容器。
Never:当容器终止退出,从不重启容器。
重启机制通过 spec.restartPolicy 字段来设置。
Pod健康检查
因为使用 kubectl get pods 的方式检查容器状态是不准确的,容器状态可能在Running,但应用实际上已经不可提供服务了。如Java应用,发生堆内存溢出异常,虽然进程还在,但实际上已经不能提供服务了。因此K8S提供了2种健康检查机制:
1、livenessProbe(存活检查):如果检查失败,将杀死容器,根据Pod的restartPolicy操作。
2、readinessProbe(就绪检查):如果检查失败,K8S会把Pod从service endpoints中剔除。
Probe支持以下三种检查方法:
1、httpGet:发送http请求,返回200-400范围状态码为成功。
2、exec:执行shell命令返回状态码是0为成功。
3、tcpSocket:发起tcp socket建立成功。
健康检查通过 spec.containers[].livenessProbe 字段进行设置。
在使用 kubectl 时,对于大多数资源类型都有缩写,如 ReplicationController - rc,pods - po,service - svc,所以不必输入全名。
常用的Pod命令:
列出pod:kubectl get pods
查看有关pod的更多信息:kubectl describe pod
查看pod的YAML定义:kubectl get po -o yaml
列出pod ip、节点ip:kubectl get pods -o wide。-o wide 选项请求显示其他列。
列出pod的其他细节:kubectl describe pod 。
多个容器 VS 单个容器中包含多个进程
好的部署方式是,容器被设计为每个容器只运行一个进程(除非进程本身产生子进程)。如果在单个容器中运行多个不相关的进程,那么保持所有进程运行的工作需要我们自己来负责,我们需要自己实现进程崩溃时能够自动重启的机制。例如,若一个容器里有多个不相关的进程,其中一个进程挂了,使用容器来进行重启则会影响其他正常的进程。
标签
由于K8S里的资源非常多,为了方便的管理这些资源,可以利用标签这一特性。标签不仅可以组织pod,也可以组织所有其他的K8S资源。标签是可以附加到资源的任意键值对,用来通过标签选择器选择具有该标签的资源。
给现有的资源添加和修改标签语法:kubectl label <资源类型> <资源名> <key>=<value>
,
例如给名称为 kubia 的 pod 添加 creation_method=manual 标签:kubectl label po kubia creation_method_manual
。
查看资源时列出标签可使用 --show-labels 选项:kubectl get <资源名> --show-labels
。
更改现有标签时需要使用--overwrite
选项。
命名空间
命名空间用于对资源进行分组。与标签不同的是,命名空间用于将对象分割成完全独立且不重叠的组,它简单地为对象名称提供了一个作用域,这样可以在不同的命名空间使用相同的资源名称。
列入所有命名空间:kubectl get ns。
当使用 kubectl get 列出资源时,若不指定命名空间,则默认为 default 命名空间,只显示该命名空间下的对象。
列出指定命名空间下的 pod:kubectl get po -n 。(可用 --namespace 替代 -n)。
获取所有命名空间中的资源:kubectl get <资源名> --all-namespaces。
创建命名空间有2种方式:
1、从YAML创建命名空间,例如,创建一个custom-ns.yaml:
apiVersion: v1
kind: Namespace #表示定义一个命名空间
metadata:
name: custom-namespace #指定命名空间的名称
然后,使用 kubectl 将文件提交到 API 服务器:kubectl create -f custom-ns.yaml。
2、另一种方式是,使用 kubectl create namespace 命令创建命名空间,比前一种方式更便捷:
kubectl create namespace custom-namespace。
⚠注意:大多数对象的名称必须符合 RFC 1035(域名)中规定的命名规范,这意味着它们只能包含:字母、数字、横杠 - 、点号。但命名空间(和另外几个)不允许包含点号。
在命名空间下管理资源
若要在命名空间中创建资源,可选择在 metadata 字段中添加一个 namespace: 属性,或者在使用命令创建时指定:
kubectl create -f xxx.yaml -n 。
在列出、描述、修改、删除其他命名空间中的对象时,需要给 kubectl 传递 -n 选项。如果不指定则会在当前上下文中配置的默认命名空间中执行操作。而当前上下文的命名空间和当前上下文本身都可以通过 kubectl config 命令进行更改。
服务
服务(Service)是一种为一组功能相同的 pod 提供单一不变的接入点的资源。简单讲就是为了解决由于 pod 的 IP 地址变化的原因,导致客户端无法直接使用 pod IP的问题。服务的 IP 不会改变。
通过服务,能够让 pod 通过环境变量或DNS以及服务名来访问另一个服务。
服务使用标签选择器来指定哪些pod属于该服务。
创建服务
创建服务最简单的方法是通过 kubectl expose。另外还可以通过YAML文件来创建。
apiVersion: v1
kind: Service #类型为服务
metadata:
name: kubia #该服务资源的名称
spec:
#type: ClusterIP #类型默认就是ClusterIP,所以可以不指定
ports:
- port: 80 #该服务的可用端口
targetPort: 8080 #服务将连接转发到的容器端口
selector:
app: kubia #具有app=kubia标签的pod都属于该服务
然后使用 kubectl create -f xxx.yaml 创建服务。
查看当前名称空间下的服务:kubectl get svc。
Service其实依赖于CoreDNS组件。Service的名称解析依赖于此组件。
在K8S环境中有3类IP地址:node network(节点地址配置在节点接口之上)、pod network(配置在pod资源之上)、cluster network(也称为service network,这是虚拟的地址Virtual IP,这种IP没有配置在某个接口上,仅出现在Service的规则中)。
从某种程度上说,Service其实是kube-proxy,该组件始终监视(watch)API服务器上有关service资源的变动信息。kube-proxy会把service转换为当前节点上的能够实现Servcie的规则,如 iptables、ipvs,使用什么规则取决于service的实现方式。
Servcie的工作模式有3种:
- userspace
client pod请求某个服务时,一定先到达当前节点内核空间的 iptables 规则(其实就是service的规则) - iptables
- ipvs
Service有4种类型:ExternalName, ClusterIP, NodePort, and LoadBalancer。ClusterIP为默认类型,会分配一个集群IP,仅用于集群内部通信。ExternalName用于把集群外的服务引入到集群内部。
列出service:kubectl get services