转自:https://www.cnblogs.com/RainingNight/p/first-aspnetcore-app-in-k8s.html
Kubernetes简介
Kubernetes是Google基于Borg开源的容器编排调度引擎,作为CNCF(Cloud Native Computing Foundation)最重要的组件之一,它的目标不仅仅是一个编排系统,而是提供一个规范,可以让你来描述集群的架构,定义服务的最终状态,Kubernetes可以帮你将系统自动得达到和维持在这个状态。
更直白的说,Kubernetes可以让用户通过编写一个yaml或者json格式的配置文件,也可以是通过工具/代码生成或者是直接请求Kubernetes API来创建应用,该配置文件中包含了用户想要应用程序保持的状态,不管整个Kubernetes集群中的个别主机发生什么问题,都不会影响应用程序的状态,你还可以通过改变该配置文件或请求Kubernetes API来改变应用程序的状态。
这意味着开发人员不需要在意节点的数目,也不需要在意从哪里运行容器以及如何与它们交流。开发人员也不需要管理硬件优化,或担心节点关闭(它们将遵循墨菲法则),因为新的节点会添加到Kubernetes集群,同时Kubernetes会在其他运行的节点中添加容器,Kubernetes会发挥最大的作用。
总结:Kubernetes是容器控制平台,可以抽象所有的底层基础设施(容器运行用到的基础设施)。
Kubernetes——让容器应用进入大规模工业生产。
Kubernetes另一个深入人心的特点是:它标准化了云服务提供商。比如,有一个Azure、Google云平台或其他云服务提供商的专家,他担任了一个搭建在全新的云服务提供商的项目。这可能引起很多后果,比如说:他可能无法在截止期限内完成;公司可能需要招聘更多相关的人员,等等。相对的,Kubernetes就没有这个问题。因为不论是哪家云服务提供商,你都可以在上面运行相同的命令,以既定的方式向Kubernetes API服务器发送请求,Kubernetes会负责抽象,并在不同的云服务商中实现。
对于公司来说,这意味着他们不需要绑定到任何一家云服务商。他们可以计算其他云服务商的开销,然后转移到别家,并依旧保留着原来的专家,原来的人员,他们还可以花更少的钱。
Pod
Kubernetes有很多技术概念,同时对应很多API对象,最重要的也是最基础的对象就是Pod。Pod是Kubernetes集群中运行部署应用的最小单元,并且是支持多个容器的。
Pod的设计理念是支持多个容器在一个Pod中共享网络地址和文件系统,可以通过进程间通信和文件共享这种简单高效的方式组合完成服务。Pod对多容器的支持是Kubernetes最基础的设计理念。比如你运行一个操作系统发行版的软件仓库,一个Nginx容器用来发布软件,另一个容器专门用来从源仓库做同步,这两个容器的镜像不太可能是一个团队开发的,但是他们一块儿工作才能提供一个微服务;这种情况下,不同的团队各自开发构建自己的容器镜像,在部署的时候组合成一个微服务对外提供服务。不过,在大多数情况下,我们只会在Pod中运行一个容器,本文中的例子也是这样的。
Pod 的另一个特征是:如果我们希望使用其他 RKE
等技术的话,我们可以做到不依赖Docker容器。
Docker是kubernetes中最常用的容器运行时,但是Pod也支持其他容器运行时。
总的来说,Pod的主要特征包括:
-
每个Pod可以在Kubernetes集群内拥有唯一的IP地址;
-
Pod可以拥有多个容器。这些容器共享同一个端口空间,所以他们可以通过
localhost
交流(可想而知它们无法使用相同的端口),与其他Pod内容器的交流可以通过结合Pod的IP来完成; -
一个Pod内的容器共享同一个卷、同一个 IP、端口空间、IPC 命名空间。
定义一个Pod
如下,我们定义一个最简单的Pod:
apiVersion: v1 kind: Pod # 定义Kubernetes资源的类型为Pod metadata: name: demo-web # 定义资源的名称 labels: # 为Pod贴上标签,后面会介绍其用处 app: demo-web spec: # 定义资源的状态,对于Pod来说,最重要属性就是containers containers: # containers一个数组类型,如果你希望部署多个容器,可以添加多项 - name: web # 定义本Pod中该容器的名称 image: rainingnight/aspnetcore-web # 定义Pod启动的容器镜像地址 ports: - containerPort: 80 # 定义容器监听的端口(与Dockerfile中的EXPOSE类似,只是为了提供文档信息)
然后保存,我这里命名为demo-web-pod.yaml
。
现在我们可以在终端中输入以下命令来创建该Pod:
kubectl create -f demo-web-pod.yaml
# 输出
# pod/demo-web created
可以使用如下命令,来查看kubernetes中的Pod列表:
kubectl get pods # 输出 # NAME READY STATUS RESTARTS AGE # demo-web 1/1 Running 0 65s
如果该Pod还处于ContainerCreating
状态的话,你可以在运行命令的时候加入--watch
参数,这样当Pod变成运行状态的时候,会自动显示在终端中。
访问应用程序
在上面,我们成功部署了一个ASP.NET Core Mvc程序的Pod,那么如何访问它呢?如果只是为了调试,我们可以使用转发端口的方式来快速访问:
kubectl port-forward demo-web 8080:80 # 输出 # Forwarding from 127.0.0.1:8080 -> 80
然后我们再浏览器中访问:127.0.0.1:8080,显示如下:
如上,还展示了Pod的主机名和IP,这是因为我在应用中添加了如下代码:
public void OnGet() { HostName = Dns.GetHostName(); HostIP = Dns.GetHostEntry(HostName).AddressList.FirstOrDefault(x => x.AddressFamily == AddressFamily.InterNetwork).ToString(); }
不过,端口转发的方式只能在本机访问,为了从外部访问应用程序,我们需要创建Kubernetes中的另外一种资源:Service。
Service
Kubernetes中的Service资源可以作为一组提供相同服务的Pod的入口,这个资源肩负发现服务和平衡Pod之间负荷的重任。
在Kubernetes集群中,我们拥有提供不同服务的Pod,那么Service如何知道该处理哪个Pod呢?
这个问题就用标签来解决的,具体分两个步骤:
- 给所有需要Service处理的对象Pod贴上标签。
- 在Service