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