开发者学堂课程【Kubernetes 入门实战演练2020版:Service、EmptyDir、HostPath】学习笔记,与课程紧密连接,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/656/detail/10866
Service 、 EmptyDir 、 HostPath
内容介绍
一、Service
二、volume
三、EmptyDir
四、HostPath
一、Service
(1)如何将 pod 暴露外部
怎么样能够把这个 pod 暴露给外部。一些服务进行调用,所以这个就是为什么会成 service。
Pod 在重启之后地址一般不会变,除非他换主机。
那么 pod 更换主机创建之后,或者在做完代码升级之后,那么 pod 一定会被重建,重建之后地址一定会变。
因为他换主机了,每个宿主机的 k8s 里面都会有一个独立的方法。所以说, 要是通过IP地址进行访问的话,这个直接通过地址访问,肯定就会出现这种地址不能访问的问题,所以说 K8s 是不可能通过IP地址在在里面对 pod 进行被迫调用。
所以说 要通过 service 来突破,来成为第二个是思维的功能。
就是它的功能是解耦了服务和应用,解耦服务和应用是很明显的。
A服调B 服的时候,不用直接通过E服。
这个地址是固定的,而且再一个就是这个B服的话, 可能多个APP,这个E服还在写对方的,包括地址和端口,肯定不方便。
所以说 在调动的时候,就是直接通过 A 服去通过 B 服搜一次,然后可以扫完B 服,它会自动从这类标签里挑出来,获得到这些pod。在进行B服调用的时候, 只要通过 service 就能找到。
找到套路,这样的话就简化了服务之间的调用,简化了服务费用。所以这时假设 NDS 想要把用户的请求转给他 开头的话。 就仅需要写个他看到的service name,就可以通过所有内容把请求转发给这两个方向去了。
所以说,解耦了的服务和应用。
(2)怎么实现?
要生一个思维对象,一般是有两种,一种是集群内部的,还有一个外部的。
内部就是 在创建一个 service 的时候,它默认的那个类型叫做cluster ip ,这个cluster ip 就是它默认的类型叫做科,叫做k8s 内部的service ,只在 k8s 公司内部生效。
但是不能从外部访问。
在内部 service 的时候,会发现这个里面有很多 cluster ip ,就是它内部的一种体现,它会在开发商内部为每个 service 生成一个ip地址。然后再通过 kubectl get一下 ep 。就会发现 调用它的话只需要通过 service name 调用。
只在k8s内部生效。
另一个就是外部的service 。手动创建一个Endpoints ,指定到外部服务的 ip 。然后 就可以通过这个 ip 地址和端口来访问这个service 了。然后再通过它所对应的端口去访问所对应的 pod 。
(3)怎么去创建
第一个是我们创建一个控制器的pod,把它运行起来。
这个kube proxy 与service关系,有客户来维护,监听的端口范围的地址,那么如果说 在创建service 的时候,指定说 这个 service 的端口是多少,那么有 kube proxy 会监听 apiserver ,然后apiserver 会返回一个数据,就是 要创建的哪些pod。
然后这个pod有对应的端口,端口又是多少会在 的副主机创建一些网络规则,把这些IP端口指向相应service的位置,然后来实现服务的访问。
kube proxy 会监听着 k8s apiserver ,一旦service 资源发生变化,这个变化就是调整了k8s api 修改service 服务信息,kube proxy就会生成对应的负载调度的调整,这样就保证 service 的最新状态。其实就是无论在k8s master 上,创建了service 还是修改了service 参数最终的话,这个service 最终会被 kube proxy 传递给各个节点。
kube proxy 的实现方式根据k8s 更新来说有三种调度模型。第一种是 userspace 它是在k8s 1.1之前会有,目前被淘汰了。第二种是 iptables 这个是在k8s1.10之前的版本,现在来说也不太用了,它在节点多的时候会有线的影响,目前来说还能用。现在最推荐的就是 ipvs ,它是在 k8s 1.11之后出现的版本,但是如果在装 k8s 的时候没有开启 ipvs ,那么就会自动降级为 iptables 。
这个是起来之后的话,如何访问呢?
(4)进行访问
后面有两个文件,一个是service ,这个service 类型 没有分配,这个就属于默认的类型。
这个属于内部访问,也就是说同一个name service 支持其他容器访问。
在net testl中进去去测试。先看一下 kubectl 地址是多少,service 可以简写成svc ,进到linux 39看看有没有。get svc 会发现缺少东西,就把它删了,kubectl delete -f 2,删除之后把 namespace 加上,指向linux 39 ,创建好之后再重新get svc ,再用ng 地址在另外一个pod 进行访问,直接curl service ,可以在内部访问。再 ping 一下 service 的名称。
起个别的容器,让这个容器跑到 linux 39之内,这个容器 这有个测试,叫 busybox ,把它传上来,也跑到linux39里面。
这个busybox 文件 后面再说,现在先把测试一下。假设要测试一下这个域名通不通,怎么测呢
而且 还不想在那个容器本身测,另外容器本身测这个效果不明显,看不出来效果。所以说在这个busybox 测起来。
这是一个专门用于测试的小盒子,里面会有很多工具,所以说 需要有个镜像,这个镜像去哪下,直去dockor pull。直接把镜像导进去。导进去之后用docker 套一下,把tag号改成自己的镜像地址。Tag 号挂了看看域名解析对不对,试一下这个域名解析能不能通。
同一个服务全在同一个 name service ,都在 linux 39之内。
假设app1 是busybox , app2 是刚才那个,它要通过 name service 访问的话,看看能不能通。删除成功,删除成功之后的话,把这个改一下, busybox .yml 。
这个pod 创建的时候,name service 放在linux39,然后再把它创建一下,这个pod就放到了linux39 ,属于同一个ngs 。再进到busybox 的时候进行测试。要进到linux39 busybox 这个容器。这个命名比较多, 需要ping ,在刚才能ngs name service 它是不通的。 可以在这使用 kubectl get service -n linux39 。只要能解析就是能访问的。
在同一个name service 之内, 想要跨pod 访问对方,那么 仅需要访问对方的 service ,而且这个 service,还是直接在 外面文件夹当中直接 service name ,不需要再写其它的,这个service name 直接写就行。
直接通过访问name 之内的service。跨service 后面再说。也就是说 这个linux39 的pod相仿linux40 里面的 service 这个怎么整。
现在虽然可以在同一个name 里去访问service,但是ngs是不对外的。也就是说 这个服务是微服,可以直接这么做。在 创建service 的时候,直接给它分一个kasip ,不用对外。如果想对外怎么办,把service 应试到一个副主机的nod pod 上。然后就可以通过这个 nod pod 去访问这个service 。
service转化到pod上。所以说就是第三个,把第二个删了。第三个就是在 创建这个 service 的时候, 给分两个pod ,只要在下面这个资料里面给它加个类型, 给它正常 pod 并且给它在这个pod 里面给定一个pod 。如果 的service 不通,把它改回去 delete-f 3,需要 在 name service 文件里面,加个name service ,然后再把它创建,它就通了。
二、volume
容器的话,已经对外提供访问了,但是,在访问的时候,这个容器的数据怎么整?
所以说 k8s 为了解决容器的数据的这种持久性,可以通过选项把三个容器的数据通过岗位到容器,然后容器里产生的数据就会直接写,但是这种方式在k8s 里面不是用了。
因为里面的容器来来回回变化特别多,而且也不是通过到转正超前的。数据 怎么办,这个数据的话呢,在k8s 里面有有多种不同的解决方案,用于实现 的容器里面的数据的。把速度提到这种持有关系,所以说为什么会是volume ?
它会进行数据和镜像的解耦,以及容器之间的数据共享。镜像里只是代码,不包含任何数据,因为数据量太大了。所以 的数据不要打镜像。
具体就看 这个数据是要在多个容器间共享,假如服务有两个,一个COS1,COS2这个数据要不要一样。有些可能不一样,有些可以不一样,什么不一样呢?
就是那种日志,容器的日志等等, 这个日志可以不一样。比如说这个容器甚至都可以不带一个容器,一个在弄1 ,可以一个单独的2,这个没问题。那么这个容器的话,把这个日志写到单上,所以这种情况不需要数据一样,但是有一种是必须要一样的,就是静态资源,这个C的话呢,可能是个前端服务。
或者是后端服务,无论前端还是后端都会,前端服务会存储读出去。所以说这个C1和C2,这两容器的数据一定是一样的,那如果是后端服,要接受用户的上传数据,那个数据一定要写个共同的地方,就是C1的数据,写数据写完之后, 得能够被c2看到。
如果说 写的地方都不一样,这个数据上完之后,难道不就不想让人看嘛,或者说就不用看嘛,用户访问的话会通过 NGS ,访问会通过 NGS 。
再把这个请求转给他 看,无论是 上传数据也好,还是要到 NGS ,或者要做什么操作也好,所以说 看出来的话, 的读取数据直接从NAS 里面的返回。后端服务的数据一定要写到一个共同的位置,让其他的服务或者其他组件能够读到这些数据。所以就会产生几种不同的数据优化方式。
如何使用的话就是k8s会抽象出一个对象,这个对象用来保存数据,做存储用。
有这么集中方式,一个是emptyDir 本地临时卷, 的数据会产生一个临时数据,这个数据的话又不用长期持化,也就是这个数据会随着数据的删除而被删除,那么 就可以给它创建这个emptyDir ,这个不用做映射本来就在容器里产生的数据,如果 想实现数据在文件里删除但还想在副主机保存,那么 就需要使用hostPath 本地卷,把这个容器保存在当前所使用的副主机,注意这两个都是容积和思路绑定的,这个就为了东西不能跨主机迁移,一旦跨主机迁移的话,那么之前那个里面的数据内容就看不到了。
容易会再产生新的数据,再把它写到新的基点上。所以说这两个,其实用的并不是很多,host 还有可能会用得上。Nfs 等共享卷, 的容器,想要实现数据共享,那么无论是哪个容器写出去, 都希望写到存储。这种的话一定会用到nfs 。
其实有两种实现方式,第一个就是 把存储,当然是那个商业的,或者是分布式的那种存储,都可以通过nfs 的协议。所有支持都可以通过WiFi 协议直接挂到 的东西。
或者是对象存储也行,然后直接在容器里,通过某一天用 的对象存储,把这个数据上传上去。把这个数据往里面写好,或者是容器通过那个对象存储调用,还有一种是什么呢?
后面的PV和PVC,也是基于这种这种存储实现的一种更加高级的方式,比如说那个啊,发的一个发展为例,那么 的容器不让它直接挂的nfs,而是给每个容器分一pc 和 pvc 的这种卷,这样的话 能后实现更加细致的划分。configmap配置文件这个就是通过文件的方式去定义它,定义好之后把它挂到 pod里面。
三、emptyDir
当 Pod 被分配给节点时,首先创建 emptyDir 卷,并且只要该 Pod在该节点上运行,该卷就会存在。
正如卷的名字所述,它最初是空的。Pod 中的容器可以读取和写入 emptyDir 卷中的相同文件,尽管该卷可以挂载到每个容器中的相同或不同路径上。当出于任何原因从节点中删除 Pod 时,emptyDir 中的数据将被永久删除。
所以说这个只是适用于数据的临时存储,一旦pod删除, 的数据也会被删除,那怎么去定义呢,就在 pod示例里,在contains下面所对应的 给它加个 volums 平级指令。在这个volums指令下面给他加个 - ,而且可以写多个。这个就是 相当于给目录起了个名称cache volums ,在 的容器下面加个 volums Mounts ,把这个安排在dr。 这两个name必须一样。这个 可以演示一下,在 的示例里有个k3 。
这个就是 把 的dr挂到 的根源的开始,所以说 直接把它创建下来就好,把支持的东西删掉,get 一下pod。然后再重新创建就行了。
先退出一下这个容器,看这个容器在哪个主机。去找所针对的主机上,这个文件在什么地方,这个路径都是固定的。
除了这个路径之外其他的都是固定的。
四、hostPath
hostPath 会将主机节点的文件系统中的文件或目录挂载到集群中,pod删除的时候,卷不会被删除。
回到 刚才的代码,把ket3 删除,或者说进到ket4 。删除的话尽量不要手动删除。
注意这个地方改成了hostPath。
后面的名称需要改成和定义卷的名称一样,后面这个moutMath 需要挂到容易的某个地方。
这个路径不用去创建,k8s 会自动去创建,能自动创建会更好。对于hostpast 卷官方也有介绍,能直接挂载pod 上。
然后在副主机上去看,是不是这个数据过来了。这个好处就是在刚才那个再找的化肯定没有了,会随着 pod 被删除,这个目录也会被删除。
不单单是这个目录,带着这个id 的目录也就会被删除。所以整个目录就被删了,更不要说那些缓存数据了。
但hostpost 里的数据会留下来, 的pod被删除,它会留下来。
有些pod, 会想方设法让它跑在固定的副主机上是可以实现的,就是 这个里面有一些服务器,是 要跑数据库,可以让数据库跑在k8s 里面,但是 这个数据是要持续化的。
这个数据的话,要么是保存到思路上,要么挂到副主机,就这种方式,首先 通过一种方式把这个碰到固定运行的数据,通过hosts的方式,把容器的数据写到数据副主机上,其实就是写到数据的更新到data里面的mark,然后,把这个代码再挂到容器的里面去。
这个是可以控制的,但是这个方式用的不多, 会有更好的解决方式,把数据放到存储上更好,这个 pod 无论在哪个节点去运行,都可以挂到这个数据,因为 是直接 pod , 要把这个 pod 绑定到这个主机上,pod被破坏了,那么K8s 在执行容器的修复的时候,他一看pod ,它只应该包含有它的工号,只有只有这个标签,那么才符合条件。
但是这个计划没有符合条件的机器,有条件的就意味着 写过这个,这个 pod 就没有办法被重建,没有办法为重建,就用了 的服务化的服务化,所以说 要是使用的话就好了,无论 跑得到哪个节点都行,只要 能挂到存储就行。
这个往哪创建没关系,主要看 内存了。它会综合考量筛选出一个机器。
Hostpost讲述完了 ,这时把它删了,创建完只有看那个数据库有没有,创建一个date 下的,一旦在这创建的话,数据就会保存在副主机的date 路径。
这就是它的使用场景,但NFS更常用,NFS是可以被多个写入者同时挂载。