[root@master1 ~]# kubectl get nodes The connection to the server 192.168.1.126:6443 was refused - did you specify the right host or port?
开机后启动,发现通信的6443没起来,
等一会
[root@master1 ~]# kubectl get nodes Unable to connect to the server: net/http: TLS handshake timeout
再等一会就可以,nodes状态上线
再等一会
flannel和proxy还没起来
还需要再等一会
看一下其中proxy的启动过程
为什么需要pod
假设kubernetes中调度的基本单元就是容器,对于一个非常简单的应用可以直接被调到直接使用,没什么问题,但是往往还有很多应用程序是由多个进程组成的,为什么不吧这些进程打包到一个容器里?但是docker容器进行时是pid=1的主进程,其他进程死掉了就会成为僵尸进程,没办法进行管理了,这种方式本省也不是容器推荐的运行方式,一个容器最好只干一件事情,所以真是环境不会使用这种方式。
为什么不吧这个应用进程拆分,一个个容器总可以吧,但是因此就会出现一个问题,拆分后,有可能一个应用的某个进程容器被调度到了不同的节点上。往往我们应用内部的进程间通讯,都是要求在本地进行的,也就是需要在一个节点上运行。
所以我们需要一个更高级别的结构来将这些容器绑定在一起,并将他们作为一个基本的调度单元进行管理,这样就可以保证这容器始终在一个节点上。
pod原理,
在一个pod下面运行几个关系非常密切的容器进程,这样一来这些进程本身又可以收到容器的管控,又具有几乎一致的运行环境。
其实pod也只是一个逻辑概念,真正起作用的还是linux容器的Namespace和Cgroup这两个最基本的概念,pod被创建出来其实是一组共享了一些资源的容器而已,首先pod里面的所有容器都是共享同一个NetworkNamespace但是涉及都文件系统的时候,默认情况下的pod里面的容器之间的文件系统是完全隔离的,但是我们可以通过声明来共享同一个volume
对于共享同一个NetworkNamespace这个概念是不是比较熟悉,我们之前在docker网络模式的章节中讲解了网络的container模式,我们可以指定新创建的容器和一个已经存在的容器共享一个NetworkNamespace在运行容器的时候只需要指定--net=container这个参数就可以了,但是这种模式有一个明显的问题那就是容器的启动有先后顺序问题,那么pod是怎么来处理这个问题呢,就是加入一个中间容器,infra容器,而且这个容器的pod中是永远第一个被创建出来的容器,这样其他的容器都加入到这个infra容器就可以了,这样就完全实现了pod中的所有容器都和infra容器共享同一个NetworkNamespace,也就是pause,我们部署完成kubernetes集群的部署时候,首先需要保证所有节点都可以拉取默认的infra镜像
kubelet --help | grep infra
从上面的可以看出普通的容器加入到infra容器的network namespace中,所以这个pod下面的所有容器就是共享共一个network namespace了,普通的容器创建自己的网卡,配置自己的ip,而是与infra容器共享ip,端口范围等,而且容器之间的进程可以通过IO网卡设备通信
也就是容器之间是可以直接使用localthost进行通信的
看到的网络设备信息都是个infra容器完全一样的
也就意味着同一个pod下面的容器运行的多个进程不能绑定相同的端口
而且pod的声明周期只跟infra容器一直,而与容器无关
对于文件系统kubernetes是怎么实现让一个pod中容器共享的呢?默认情况下容器的文件系统是相互隔离的,要实现共享只需要在pod的顶层声明一个volume,然后再需要共享这个volume的容器中声明挂载即可。
kubernetes中一个非常重要的设计模式,sidecar模式的常用方式,典型的场景就是容器日志收集,比如上面我们的这个应用,其中应用的日志是被传输到容器的log目录中,这个时候我们可以吧pod声明的数据卷挂载到容器的log目录上,然后这个pod里面同事运行一个sidecar容器,他也在声明挂载相同的数据卷到自己的log目录上,这样我们这个sidecar容器只需要从log目录下面不断发送日志到elk中存储起来,就完成最基本的应用日志收集工作了
除了这个应用场景之外还要更多的还是利用pod中所有容器共享一个networkNamespace这个特性,这样我们就可以吧pod网络相关的配置和管理也可以交给一个sidecar容器来完成,完全不需要干涉用户容器,这个特性service Mesh,典型应用就是istio。
如何划分pod
上面我们介绍了pod的实现原理,了解了应该吧关系紧密的容器划分到同一个pod中运行,那么怎么来区分关系紧密?举一个简单的示例,比如我们 WordPress应用,是一个典型的前端服务器和后端数据服务应用。
如果在通一个pod中同时运行服务器程序和后端数据库服务这两个容器,理论上肯定是可行的,但是不推荐。我们知道pod中所有容器都是同一个整体进行调度的。但是对于我们这个应用wordpress和mysql一定要运行在一起吗?
但是如果你非要强行部署到同一个pod中呢,比如我们的应用访问量非常大,一个pod已经满足不了我们的需求了,怎么办?扩容,但是扩容的目标也就是pod,并不是容器,比如我们再添加一个pod,这个时候我们就有两个wordpress的应用和两个mysql数据库,而且两个pod之间的数据是相互独立的,因为mysql数据库不是简单的增加副本就可以共享数据了。
将多个容器部署到同一个pod中最主要参考就是应用可能又一个主进程和一个或多个辅助进程组成,比如上面我们的日志收集pod,需要其他的sidecar容器来支持日志的采集,所以等我们判断是否需要在pod中使用多个容器时候,我们需要判断
这些容器是否一定需要运行一起,这些容器是一整体还是独立的组件,这些容器一起扩容会影响应用么?
下一节我们将pod的声明周期、



