K8S 之 部署一个应用


theme: v-green highlight: a11y-dark

简单部署一个程序

# 拉取网络上的镜像来部署名称为mykubia的应用并运行
kubectl run mykubia --image=luksa/kubia --port=9999 --generator=run/v1

–image=luksa/kubia:指定一个要运行的容器镜像。
–port=9999:指的是我们指定服务运行的端口号是9999。
–generator=run/v1:加上这个标志指的是 让K8s集群创建一个ReplicationController ,而不是一个 Deployment

$ kubectl get pods
NAME      READY   STATUS    RESTARTS   AGE
mykubia   1/1     Running   0          63s

通过命令 kubectl logs -f mykubia 查看日志

从执行命令到容器运行背后都发生了哪些动作?

  1. 构建镜像,必须先要把 镜像推送到 Docker Hub 上面,这一步是 执行 docker push luksa/kubia
  2. Docker 服务器将镜像推送到 Docker Hub 中。
  3. Kubectl 收到指令,kubectl run mykubia --image=lukia/kubia --port=9999
  4. KubectlREST API 服务器发送请求,请求调度。
  5. 主节点收到请求后,创建 Pod ,并调度到工作节点。
  6. 工作节点收到主节点的调度通知。
  7. 工作节点 使用 Kubectl 指令告诉自己环境中 docker 要运行镜像了。
  8. 工作节点的 Docker 于是就向 Docker Hub 拉取镜像并运行。

最终通过指令 kubectl get pods 的时候,就可以看到我们的 Pod 运行信息。

外部如何访问 pod 中的服务?

通过指令:kubectl get pods -o wide 查看更多详细信息

虽然每一个 Pod 都有一个自己的 IP,但是这个IP只有在集群内部才可以访问的,在外部是没有办法访问的

使用curl 172.18.0.6:8080明显是访问不到的,但要从外部访问内部的 Pod 中的服务,我们可以创建一个特殊的LoadBalancer类型的服务(service)

创建一个服务对象

ClusterIP 类型的服务 是 K8s 内部默认的类型,默认只能在内部互相访问,外部是无法访问的。所以我们只能创建 LoadBalancer 类型的服务。

`kubectl expose rc mykubia --type=LoadBalancer --name kubia-http`
# rc mykubia: 指的是要告诉K8s我们之前创建的ReplicationController,此处的 rc 是 ReplicationController 的缩写
- # --type=LoadBalancer: 指定执行类型为`LoadBalancer`类型后,将会创建一个外部的负载均衡服务,外部可以通过这个服务的 `Ip` 来访问到内部的`Pod`

查看服务

我们可以通过 kubectl get services 来查看服务列表

查看服务列表的时候,我们可以看到 EXTERNAL-IP 部分,刚开始是显示,过一会 K8s 就会给我们分配好这个服务的外部 IP

ReplicationController Pod Service 本次关系

我们之前创建 Pod 的时候不是直接创建的,是通过docker run来创建的一个replicationController ,然后基于 rc 来创建的一个 Pod 实例

为了让Pod能够被外部访问到,所以我们需要让K8sreplicationController管理的所有Pod由一个服务对外暴露,因此有了 kubia-http

  • 服务是有对外暴露 IP 的,请求打到 service 上。
  • service 将请求转到 Pod 上面的 9999 端口上,然后 Pod 提供服务。

ReplicationController

通过上面的案例,我们应该知道 ReplicationController实际上是用于复制Pod来创建多个Pod副本, ReplicationController 始终确保存在一个运行中的 Pod 实例。

如果我们上面创建的 Pod 消失了,那么 ReplicationController 将会创建一个新的 Pod 来替换消失的 Pod

service的作用

service 也就是上面 kubia-http 服务,因为pod 消失之后, ReplicationController 会再创建一个新的将其替换,且每一个 Pod 都有自己的独立的主机名和 IPPod在环境中会因为任何原因直接挂掉和消失,然后又被新的Pod替换,这个时候 PodIP 变化了,那外部如何正确访问到我们的服务呢?

这个时候就需要service

  • service 可以解决不断变化的 Pod IP 问题。
  • service 可以在一个固定 IP 和端口上对外暴露多个Pod

当一个 service 被创建的时候,会得到一个静态的 IP,在 service 整个生命周期中,它的 IP 是不会变的,客户端只需要通过这个固定 IP 连接服务即可,服务会将请求转到 内部其中一个Pod

增加副本数量

当前的系统里面只有的一个副本,现在我们可以增加到 3 个副本

# 查看当前应用的副本数
kubectl get replicationcontrollers

将mykubia副本数调整至 3 个

kubectl scale rc mykubia --replicas=3

该指令只是告诉 K8s 系统中期望的副本数量,但没有告诉 K8S 需要如何去操作,如何去实现。

K8s 自身会去检查当前的状态是否和期望的状态一致,如果不一致就会进行调整。

最新的系统状态

通过执行上述的指令,系统中将 1 个副本,调整成了 3 个副本。这就是 K8s 可以轻易的做到水平伸缩,我们要扩充副本的时候,再也不需要手动的去安装和运行其他副本了,只用执行指令,修改期望数量即可。

当然我们放进 Pod 的服务,也需要做成无状态,可横向扩展的,这样才能更好的使用 K8s 的能力。

外部请求打到 service 上面,service 会将请求给到 任意一个 Pod ,对应的 Pod 即提供服务即可。


这是一个从 https://juejin.cn/post/7368079196445130763 下的原始话题分离的讨论话题