从Docker到Kubernetes——Kubernetes设计解读之Pod

2023-11-16

Kubernetes是个什么样的项目

简单的说,k8s是一个管理跨主机容器化应用的系统,实现了包括应用部署、高可用管理和弹性伸缩在内的一系列基础功能并封装成为一套完整、简单易用的RESTful API对外提供服务。

k8s的设计哲学之一就是维护应用容器集群一直处于用户所期待的状态,为了践行这一价值观,k8s建立了一套健壮的集群自恢复机制,包括容器的自动重启、自动重调度以及自动备份等等。

不难发现,k8s主要的服务对象是由多个容器组成而成的复杂应用,如弹性、分布式的服务架构。为此k8s引入了专门对容器进行分组管理的pod,从而建立了一套将非容器化应用平滑的迁入到容器云上的机制。

k8s对外提供容器服务的模式是这样的:用户提交容器集群运行所需资源的申请(通常是一个配置文件),然后由k8s负责完成这些容器的调度任务,即自动为这些容器选择运行的宿主机

Kubernetes的设计解读

典型案例:GuestBook

在这个例子重,Kubernets集群重会部署这样一个应用:

  • PHP网站,并运行3个副本来实现高可用。
  • PHP网站在Redis里存储了一个数据,不定期的进行读写。
  • Redis服务包含1个master和2个slave,读请求由slave处理,写请求交给master。

我们之前的Docker案例同样也能运行这样一个集群,然后使用负载均衡组建来完成多个Redis slave之间以及php实例之间的请求分配,当然这其中也会自己搭建一些服务发现的组件,来保证自动化管理的过程。

那么这样一个集群在k8s的管理下又是什么样的呢?

  • 在k8s下,所有容器(包括php和redis的节点)都会被分配到一个“副本控制器”(replication controller),并且指定了php副本的数量为3,redis salve数量为2,redis master的数量为1。
  • 用户在创建容器的时候,会给每个容器指定一个用来分组的标签label:比如所有php网站容器都属于name=frontend这个组。在调度的时候,k8s就可以根据这些标签来进行一些决策。比如,从高可用的角度除法,用户可以指定所有name=frontend标签的容器不会被调度在同一台node上。
  • 这些容器可以直接使用IP:Port的方式进行通信,但是由于重新调度或者重启之后Docker容器的IP会发生变化,所以k8s内置了一个名为service的代理组件。当为某些容器分配了一个service代理后,这些容器就可以被一个固定的ip(cluster IP)访问到,省去了用户自己搭建负载均衡的麻烦(当然也可以自己使用负载均衡的组件代替service)。
  • 最后,也是最重要的,上述replication controller、label以及service,真正的操作对象都是一个称为pod的逻辑对象,而非容器。pod可以想象成一个篮子,容器则是篮子里的鸡蛋,当k8s调度容器的时候,是把一个篮子连同里面的鸡蛋从一个宿主机调度到另一个宿主机。篮子和鸡蛋的关系表现如下:1.label是贴在篮子上的。2.IP分配给篮子而不是容器,篮子里的容器共享这个IP。3.哪怕只有一个鸡蛋(容器),k8s也会给它一个篮子。

pod设计解读

在k8s中,能被创建、调度和管理的最小单位是pod,而非单个容器。pod里的容器共享network namespace,并通过volume机制共享一部分存储。

  • pod是IP等网络资源的分配的基本单位,在IP及其对应的network namespace是有pod里的容器共享
  • pod内的所有容器共享volume。当又一个volume被挂载在同属一个pod的多个Docker容器的文件系统上时,该volume可以被这些容器共享

这样做的好处是,一是,通过k8s volume机制,在容器之间共享存储。二是,可以通过localhost直接访问另一个容器。

试想一下,之前我们单机部署容器的时候,说明了非单机下容器之间的联系十分麻烦,比如需要共享volume,需要知道PID等等,所以跨主机连接我们直接干脆没学。k8s提供的机制,就将上述难题迎刃而解了。

所以,当系统运行着数量庞大的pod的时候,用户或者系统管理员如何有效的定位与组织这些pod就成了一个重要问题。k8s的解决方案是label,每个pod都有一个属性"labels"的键值对,比如:

"labels":{
	"key1":"value1",
	"key2":"value2"
}

通过命令-l key=value参数,可以方便的实现定位。比如例举所有标签{“name”:“nginx”}的pod可以这么操作:

kubectl get pods -l name=nginx

pod使用实例

k8s的安装:云服务器下Kubernetes的安装和配置

使用k8s的客户端工具kubectl来创建pod,该命令行工具支持对k8s对象(pod、replication controller、service)的CRUD操作以及其他对集群的管理操作。

创建Kubernetes资源对象的一般方法如下所示。

[root@master kubernetes]# kubectl create -f obj.json

回过头来,再来看看命令中的obj.json,这个JSON文件可以是定义pod、replication controller、service等k8s对象的资源配置文件
这里说明一下obj.json的配置信息:

{
	"kind":"Pod",
	"apiVersion":"v1",
	"metadata":{
		"name":"podtest",
		"labels":{
			"name":"redis-master"
		}
	},
	"spec":{
		"containers":[{
			"name":"master1",
			"image":"k8stest/redis:test",
			"ports":[{
				"containerPort":6379,
				"hostPort":6388
			}]
		},
		{
			"name":"master2",
			"image":"k8stest/sshd:test",
			"ports":[{
				"containerPort":22,
				"hostPort":8888
			}]
		}]
	}
}

以上配置信息,描述了一个name是podtest的对象,而该配置信息的kind表明该对象是一个pod。apiVersion表明客户端使用的服务端API的版本是v1。labels字段即该pod的标签,该pod只有一个标签:redis-master。

spec:container描述了pod内容器的属性,包括name(容器名),image(镜像),ports(端口映射)等。

其中ports字段由两个属性值组成:containerPort(容器端口)和hostPort(主机端口)。这样k8s 自动实现了用户容器端口到宿主机端口的映射关系

这里说明下spec字段,所有资源对象都会在spec字段下告诉k8s系统自己的期望状态,而k8s负责收集该资源对象的当前状态与期望状态进行匹配。例如,当创建一个pod时,声明该pod容器正常运行所需的计算资源,那么k8s无论发生什么都要保证pod内容器的正常运行。如果没有正常运行,k8s就会不停的重新创建pod对象,直到使用者删除该pod,或者正常运行为止。

将以上内容写入obj.json,会创建出一个包含两个容器的pod。这里要注意两类端口冲突问题:

  • pod内部的端口冲突,即同一个pod内的容器端口不能重复。
  • 宿主机端口冲突,即同一个pod的不同容器的端口可能会映射到宿主机的同一个端口。

创建Pod:

[root@master ~]# vi obj.json
[root@master ~]# kubectl create -f obj.json 
pod/podtest created

查看创建的pod的信息:

[root@master ~]# kubectl get pod
NAME      READY   STATUS    RESTARTS   AGE
podtest   0/2     Pending   0          93s

Pending状态说明pod还在准备。我们使用kubectl describe pod <pod_name>来查看一下为什么一直在准备:

[root@master ~]# kubectl describe pod podtest
Name:         podtest
Namespace:    default
Priority:     0
Node:         <none>
Labels:       name=redis-master
Annotations:  <none>
Status:       Pending
中间一段信息跳过。。。
Events:
  Type     Reason            Age        From               Message
  ----     ------            ----       ----               -------
  Warning  FailedScheduling  <unknown>  default-scheduler  0/1 nodes are available: 1 node(s) had taints that the pod didn't tolerate.

在结尾处我们看到原来是没有主机节点来处理这个pod,因为我们这里是单机模式。使用下面这个命令让主机也能处理node。(默认情况下kubernetes中的master并不能运行用户的Pod. 因此需要删除 Train,允许master执行Pod)

[root@master ~]# kubectl taint nodes --all node-role.kubernetes.io/master-
node/master untainted

现在查询pod的情况:

[root@master ~]# kubectl get pod
NAME      READY   STATUS    RESTARTS   AGE
podtest   1/1     Running   0          5m36s

如果要查看pod容器中输出的log信息,可以使用kubectl log pod {container}来获取,比如以master1容器为例。

[root@master ~]# kubectl logs podtest master1
1:C 22 Oct 2019 07:07:36.644 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1:C 22 Oct 2019 07:07:36.644 # Redis version=5.0.6, bits=64, commit=00000000, modified=0, pid=1, just started
1:C 22 Oct 2019 07:07:36.644 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
1:M 22 Oct 2019 07:07:36.645 * Running mode=standalone, port=6379.
1:M 22 Oct 2019 07:07:36.645 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
1:M 22 Oct 2019 07:07:36.645 # Server initialized
1:M 22 Oct 2019 07:07:36.645 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
1:M 22 Oct 2019 07:07:36.645 * Ready to accept connections

pod内容器网络与通信

前面说过,pod内容器是共享network namespace的,那k8s是怎么做到这一点的呢?假设pod内一共有三个容器,那么这个pod对应的Dokcer容器信息应该如下图所示:
docker ps或者docker ps -a
在这里插入图片描述
其中上面两个是用户容器,第三个是k8s的网络容器,这就是关键。

只要保证每个pod都会自动运行这样一个网络容器,并且pod中其他容器都借助--net="container"的方式使用它间接定义自身的网络,就实现了这些容器network namespace的共享。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从Docker到Kubernetes——Kubernetes设计解读之Pod 的相关文章

  • k8s初级实战09--Secret

    k8s初级实战09 Secret 1 基础概念 2 常见用法 2 1 创建 secret 2 2 使用 secret 2 3 imagePullSecret 控制镜像访问权限 3 注意事项 4 说明 1 基础概念 Secret 对象类型用来
  • Kubernetes Pod 故障归类与排查方法

    1 Pod 概念 Pod是kubernetes集群中最小的部署和管理的基本单元 协同寻址 协同调度 Pod是一个或多个容器的集合 是一个或一组服务 进程 的抽象集合 Pod中可以共享网络和存储 可以简单理解为一个逻辑上的虚拟机 但并不是虚拟
  • k8s job机制初探

    博客作为学习笔记记录 若有理解或表述错误 欢迎指出 k8s的job机制 k8s官网参考 k8s的job是用来执行一次性任务的一类资源 相关的还有cronjob 用于执行以下周期性任务 部署job之后 k8s会起对应pod 当pod的状态为f
  • k8s Trouble Shooting 故障排除

    本文要讲的是k8s的故障排除 比较浅 最近刚入门 主要涵盖的内容是查看k8s对象的当前运行时信息 对于服务 容器的问题是如何诊断的 对于某些复杂的问题例如pod调度问题是如何排查的 1 查看系统的Event事件 在对象资源 pod serv
  • 基于hostpath的k8s pod日志持久化

    基于hostpath的k8s pod日志持久化 前置条件 step1 修改服务的yaml文件 step2 推送日志到minio版保存 step3 优化 附加 简单了解 前置条件 考虑到pod的多副本 但同时需要将日志集中收集起来 所以采用h
  • underlay和overlay? & 传统网络和数据中心网络 ?

    underlay和overlay 百度 Underlay 和 Overlay 是网络架构中两个常用的概念 用于描述不同层次或视角下的网络结构和通信方式 1 Underlay 底层网络 Underlay 是指基础网络层 即物理网络或基础网络架
  • 从Docker到Kubernetes——Kubernetes设计解读之Pod

    文章目录 Kubernetes是个什么样的项目 Kubernetes的设计解读 典型案例 GuestBook pod设计解读 pod使用实例 pod内容器网络与通信 Kubernetes是个什么样的项目 简单的说 k8s是一个管理跨主机容器
  • k8s安装遇到过的一些问题

    无法获取recomended yaml文件 root k8master1 wget https raw githubusercontent com kubernetes dashboard v2 7 0 aio deploy recomme
  • 二进制部署K8s

    一 环境需求 节点IP 节点名称 所需组件 192 168 248 11 k8s master docker etcd apiserver controller manager scheduler kube proxy flannel 19
  • k8s英伟达GPU插件(nvidia-device-plugin)

    安装方法 Installation Guide NVIDIA Cloud Native Technologies documentation 1 本地节点添加 NVIDIA 驱动程序 要求 NVIDIA drivers 384 81 先确保
  • wireshark 抓包学习TLS握手(ECDHE)

    首先放出经典的流程图 TLS 握手共分四个阶段 为了便于理解 我用wireshark抓了包来分析每一个阶段 Client Hello 第一次握手 客户端首先会发一个 Client Hello 消息 消息里面有客户端使用的 TLS 版本号 支
  • docker的联合文件系统(UnionFS)

    docker最大的贡献就是定义了容器镜像的分层的存储格式 docker镜像技术的基础是联合文件系统 UnionFS 其文件系统是分层的 这样既可以充分利用共享层 又可以减少存储空间占用 联合挂载系统的工作原理 读 如果文件在upperdir
  • 如何解决K8S节点显示NotReady

    文章目录 kubernetes节点断电重启 kubernetes节点断电重启 背景 运行的好好的k8s集群 某天断电 发现一个节点炸了 显示NotReady kubectl get nodes 那么如何查找问题呢 我们用它 journalc
  • Kubernetes 集群部署 ------ 二进制部署(二)

    单节点 https blog csdn net Yplayer001 article details 104234807 先具备单master1节点部署环境 三 master02部署 优先关闭防火墙和selinux服务 在master01上
  • kubectl常用命令

    alias k kubectl alias kc k create f alias kgp k get pods alias kdp k describe pods alias kdep k delete pods alias kl k l
  • Kubernetes + Dashboard 集群搭建

    1 环境说明 基于kubeadm工具部署k8s 集群 还有基于二进制的部署方式但是需要单独部署k8s的每个组件比较繁琐 kubeadm是 Kubernetes官 提供的 于快速部署Kubernetes集群的 具 基于Kubernetes v
  • 十二. Kubernetes Pod 与 探针

    目录 一 Pod Pod 中的多容器协同 Pod 的组成与paush 重要 Pod 的生命周期 Pod状态与重启策略 静态Pod 二 探针 1 livenessProbe存活探针 2 readinessProbe就绪探针 3 startup
  • K8S暴露服务的三种方式

    文章目录 暴露服务的三种方式 NodePort LoadBalane Ingress 内容参考 暴露服务的三种方式 NodePort 将服务的类型设置成NodePort 每个集群节点都会在节点上打 开 一 个端口 对于NodePort服务
  • k8s学习(五)ReplicaSet的使用

    ReplicaSet ReplicaSet 的目的是维护一组在任何时候都处于运行状态的 Pod 副本的稳定集合 可确保指定数量的pod在任何设定的时间运行 因此 它通常用来保证给定数量的 完全相同的 Pod 的可用性 示例 1 nginx
  • 基于minikube的k8s单机环境部署ThingsBoard

    1 minikube安装k8s单机版 https blog csdn net qq 39879126 article details 121587678 2 安装ThingsBoard 下载 https github com thingsb

随机推荐