k8s ready 不调度_从零开始学K8s: 10.在K8s上运行应用

上一节我们学习了如何使用Minikube搭建一个k8s环境,这一节开始我们来学习如何将之前创建的Node.js应用程序部署到这个k8s环境里

在部署之前,通常我们都会先准备好YAML或者JSON格式的清单(k8s中称作manifest),这个清单详细说明了我们想要部署的组件。但是为了让大家更快进入到k8s的世界,我还不打算讲解k8s中的组件类型,先让我们通过一个简单的例子来了解如何让程序先运行起来。我的个人学习理念是先窥全貌、动手实践再深入了解,你都不知道困住你的这个庞然大物是个什么东西,就想去先去了解内部细节,只会让自己一头雾水、理解缓慢。

1.kubectl run命令

现在开始运行之前已经发布到阿里云的镜像,执行如下命令让其在k8s中运行:

kubectl run test1 --image=registry.cn-shanghai.aliyuncs.com/david-ns01/test1:1.0 --port=8080

86f656874d31c1e287d68c8f05788a5c.png

kubectl run命令会为我们创建一个名为test1的Pod(关于pod下面有介绍)。

查看Pod的状态:

kubectl get pods
d3d19a77adbee0fc8f455c58bc706449.png

可以看到当前状态为ContainerCreating,意味着正在创建容器。

过一会儿再执行这个命令,可以看到状态变为Running了:

13eb4a02d66ed74e766367e8b796ee48.png

之所以Pod的状态没有立刻变成Running,是因为Pod所在的工作节点需要先下载容器镜像,当下载完成后就会在Pod中创建容器,然后才会变成Running状态。

可能到此处有些同学会有些疑惑,这个Pod是什么?我们的程序是运行在容器里吗?那么容器在哪里可以看到?能不能有个命令显示所有正在运行的容器?然而kubenetes并不是以容器为单位来进行管理的,它不会直接与容器打交道,而是使用Pod。

2.什么是Pod

Pod就是一组紧密关联的容器的集合,它可以包含一个或者多个容器,还包含了存储、网络等各个容器可以共享的资源。这些容器总是在同一个Linux命名空间下运行在同一台工作节点上。

一个Pod只包含一个容器是最常用的应用方式。除非特别需要,比如应用之间耦合度比较高,一般都不推荐使用多容器Pod的方式。不过对于包含多个容器的Pod,Kubernetes能够保证这些容器都运行在同一台物理主机或虚拟主机中。Pod就像一个独立的逻辑机器,它有自己的IP、主机名和进程等等。同一个Pod中的容器共享IP地址和端口范围,容器之间可以通过 localhost 互相访问。

更多关于Pod的知识,后面我们再专门进行介绍。

通过执行如下命令可以列出:

kubectl get pods
0d795038b45818061a84949612549209.png

上图中的READY列显示的就是这个名为test1的Pod中的容器数,以及处于READY状态的容器数。因为当前这个Pod只有一个容器,所以显示的都是1。

如果想要探查Pod更多的信息,可以使用如下命令:

kubectl describe pod

如果Pod的状态一直未变成Running,就可以通过这个命令查看具体的原因,有可能就是Kubernetes在拉取镜像的时候出错了。

3.背后的原理

上面通过kubectl run命令创建了一个Pod,可以通过下图来了解具体的原理:

99e4b78e4831824bddf076f9afa955ae.png
  • 1.开发人员在本地机器上执行推送镜像test1:1.0的命令
  • 2.镜像被推送到镜像仓库(Docker Hub、阿里云等等)
  • 3.开发人员在本地机器上运行kubectl run命令
  • 4.Kubectl向k8s的API Server发送REST HTTP请求
  • 5.创建一个Pod并通过Scheduler分配到某个工作节点
  • 6.发送消息给Kubelet
  • 7.某个工作节点上的Kubelet发现新创建的Pod被分配给了自己,于是通知Docker去拉取镜像
  • 8.Docker去镜像仓库拉取镜像并在这个Pod中创建和运行容器

4.访问应用

Pod已经运行起来了,那如何才能访问到我们创建的Node.js应用程序呢?我们知道每个Pod其实都是有自己独立的网络环境,有自己的IP地址和主机名,但是这个地址是K8s集群内部的地址,无法在集群外部访问。因此需要想办法将我们的应用对外暴露出去。

可以使用一个叫做Service的Kubernetes对象来完成这个任务。为了演示,现在我们创建一个类型为LoadBalancer的Service对象:

kubectl expose pod test1 --type=LoadBalancer --name test1-http
c987f565a47011b93d36f720fa6dd828.png

通过如下命令可以查看刚创建的Service对象:

kubectl get services
3112e1b74a1ae16b30a9a29e649319c0.png

创建类型为LoadBalancer的Service会自动创建一个外部的负载均衡器(load balancer),我们可以通过这个负载均衡器的公共IP访问Pod。

test1-http就是我们刚才创建的服务。EXTERNAL-IP列显示的是pending状态,因为创建负载均衡器需要花些时间。一旦负载均衡器创建好了之后,EXTERNAL-IP列就会显示分配的外部IP地址。但是我们发现EXTERNAL-IP的状态似乎一直是pending。

cb2e0c6a19f59eda5904242ad5cf660b.png

因为我们当前使用的是Minikube,它是不支持LoadBalancer类型的Service的,所以上面的test1-http一直获取不到外部IP地址。但是我们也可以发现PORT(S)列其实是有端口映射的,说明通过30768端口是可以访问到这个服务的。

可以通过如下命令来获取外部IP地址:

minikube service test1-http
6b507f36adb525d914b90804d4046cf5.png

这里的172.17.0.3其实就是名为minikube的节点的地址

f3eafe374671a720884875d145e9e898.png
a8c3d6c75a9f1d1bc035b7f453917ed2.png

通过curl命令来向我们的应用程序发送请求:

curl http://172.17.0.3:30768
b0d19d3e997ec7a61901ee944c6a99e1.png

如果将service删除掉后再访问就会失败:

kubectl delete service test1-http
8154c52a4a22c432cd828ac61bf795be.png

[谢谢]如果觉得本文对您有帮助,欢迎关注我的头条号订阅更新,我会不断推出更多高质量的文章。您的支持是我持续创作的最大动力![谢谢]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值