无状态服务
无状态服务不会在本地存储持久化数据。多个服务实例对于同一个用户请求的响应结果是完全一致的。这种多服务实例之间是没有依赖关系,比如web应用,在k8s控制器中动态启停无状态服务的pod并不会对其它的pod产生影响。
有状态服务
有状态服务需要在本地存储持久化数据,典型的是分布式数据库的应用,分布式节点实例之间有依赖的拓扑关系。比如,主从关系。如果K8S停止分布式集群中任一实例pod,就可能会导致数据丢失或者集群的crash。
Deployment控制器被设计用来管理无状态服务的pod,每个pod完全一致。即:
vim load-balancer-example.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app.kubernetes.io/name: load-balancer-example
name: hello-world
spec:
replicas: 5
selector:
matchLabels:
app.kubernetes.io/name: load-balancer-example
template:
metadata:
labels:
app.kubernetes.io/name: load-balancer-example
spec:
containers:
- image: gcr.io/google-samples/node-hello:1.0
name: hello-world
ports:
- containerPort: 8080
可以看到yaml文件中,kind的类型为Deployment,replicas个数为5。
kubectl apply -f load-balancer-example.yaml
此yaml文件由k8s官方提供,因此也可以通过执行以下命令来进行部署。
kubectl apply -f https://k8s.io/examples/service/load-balancer-example.yaml
kubectl get deployments hello-world
kubectl describe deployments hello-world
当然也可以执行 kubectl get pods
查看已经部署的5个hello-world pods。
此时,可以看到STATUS显示ContainerCreating。
可以执行kubectl get pod hello-world-7476585d6-4f9w8
在Events中可以看到,失败的原因是拉取镜像失败。我们这边采用的镜像是gcr.io/google-samples/node-hello:1.0。k8s再拉取镜像时是通过调用Docker进行拉取。所以这时候,我们可以通过docker search node-hello:1.0
先执行kubectl delete -f load-balancer-example.yaml
将之前的pod删除掉。
替换yaml文件中的image
image: tomtsang/dockerlibraryk8s-node-hello
或者使用其他镜像;或者采用科学🪜手段,先docker pull 下来。
READY 是当前已经创建成功的pod数量和需要创建的总数。
kubectl get replicasets
kubectl describe replicasets
kubectl expose deployment hello-world --type=LoadBalancer --name=my-service
kubectl get services my-service
由于我此处使用的是minikube,因此EXTERNAL-IP 显示pending。
如果用的多节点形式。大概会输出类似:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-service LoadBalancer 10.3.245.137 104.198.205.71 8080/TCP 54s
kubectl describe services my-service
----
Name: my-service
Namespace: default
Labels: app.kubernetes.io/name=load-balancer-example
Annotations: <none>
Selector: app.kubernetes.io/name=load-balancer-example
Type: LoadBalancer
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.97.24.45
IPs: 10.97.24.45
Port: <unset> 8080/TCP
TargetPort: 8080/TCP
NodePort: <unset> 30386/TCP
Endpoints: 10.244.0.10:8080,10.244.1.18:8080,10.244.1.19:8080 + 2 more...
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
NodePort: 30386/TCP
curl http://<external-ip>:<port>
由于本文使用的是minikube ,因此可以执行minikube service my-service
成功请求的响应是一条 hello 消息:
Hello Kubernetes!
要删除服务,输入以下命令:
kubectl delete services my-service
要删除 Deployment、ReplicaSet 和运行 Hello World 应用程序的 Pod, 输入以下命令:
kubectl delete deployment hello-world
走完所有的流程,就完成了无状态应用的部署与删除。是不是so easy~
下一篇将会介绍有状态应用的部署。