在Kubernetes上运行一个程序
基础运行环境
当前的运行环境为使用虚拟机构建的单master集群。
[root@k8s-master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master Ready control-plane 109d v1.27.1
k8s-node1 Ready <none> 109d v1.27.1
k8s-node2 Ready <none> 109d v1.27.1
Note
kubectl get nodes命令可以查看当前kubernetes集群中的节点信息。
kubectl是kubernetes的命令行工具(CLI),是Kubernetes必备的管理工具。
kubectl提供了大量的子命令,方便管理kubenetes集群中的各种功能。目前只需知道简单用法即可。
部署Node.js应用
部署应用最简单的方式是使用kubectl run命令,该命令可以创建所有必要组件而无需JSON或者YAML文件
kubectl run kubia --image=luksa/kubia --port=8080
运行命令
[root@k8s-master ~]# kubectl run kubia --image=luksa/kubia --port=8080
pod/kubia created
运行结果如下,可以看出有一个pod被调度运行。
[root@k8s-master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
kubia 1/1 Running 0 18m
幕后发生的事情
访问Web应用
如何访问正在运行的pod?每个pod都有自己的IP地址,但是这个地址是集群内部的,不能从集群外部访问。要让pod能从外部访问,需要通过服务对象公开它,要创建一个特殊的LoadBalancer类型的服务。通过创建LoadBalancer类型的服务,将创建一个外部的负载均衡,通过负载均衡的公共IP访问pod。
创建一个服务对象
[root@k8s-master ~]# kubectl expose pod kubia --type=LoadBalancer --name kubia-http
service/kubia-http exposed
[root@k8s-master ~]# kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 109d
kubia ClusterIP 10.106.169.192 <none> 80/TCP 85d
kubia-http LoadBalancer 10.110.255.201 <pending> 8080:32095/TCP 18s
可以看到kubia-http服务已被创建,但是还没有外部IP地址,因为Kubernetes运行的云基础设施创建负载均衡需要一段时间。稍等一会就会有IP。
有了外部IP就可以通过IP和端口访问
[root@k8s-master ~]# curl 10.244.169.154:8080
You've hit kubia
ReplicationController、pod和服务是如何组合到一起的?
原书中kubia的类型是ReplicationController;
Kubernetes的基本结构是pod,但是并没有真的创建pod。原书中通过kubectl run命令创建的是一个ReplicationController(原书中的命令被废弃),它用于创建pod实例。为了使该pod能够从集群外部访问,需要让Kubernetes将该ReplicationController管理的所有pod通过一个服务向外暴露,结果如下图
ReplicationController的角色
通常,ReplicationController用于复制pod(即创建pod的多个副本)并让他们保持运行。实例中没有指定需要多少pod,所以ReplicationController创建了一个副本。如果pod因为任何原因消失,那么将会重新创建一个pod用来替换消失的pod。
为什么需要服务
要理解为什么需要服务,需要学习有关pod的关键细节。pod的存在是短暂的,一个pod可能会在任何时候消失。当消失时,消失的pod会被ReplicationController替换为新的pod。新的pod与替换他的pod具有不同的IP。这就是需要服务的地方-解决不断变化的pod IP地址的问题,以及在一个固定的IP和端口上对外暴露多个pod。
当一个服务被创建时,它会得到一个静态的IP,在服务的生命周期中这个IP不会发生改变。客户端应该通过固定IP地址连接到服务,而不是直接连接pod。服务会确保其中一个pod接收连接,而不关心pod当前运行在哪里
服务表示一组或多组提供相同服务的pod的静态地址。到达服务IP和端口的请求将会被转发到属于该服务的一个容器的IP和端口。