Deployment组件是为无状态服务而设计的,其中的Pod名称,主机名,存储都是随机,不稳定的,并且Pod的创建与销毁也是无序的.这个设计决定了无状态服务并 不适合数据库领域的应用.
而Stateful管理有状态的应用,它的Pod有如下特征:
唯一性: 每个Pod会被分配一个唯一序号.
顺序性: Pod启动,更新,销毁是按顺序进行.
稳定的网络标识: Pod主机名,DNS地址不会随着Pod被重新调度而发生变化.
稳定的持久化存储: Pod被重新调度后,仍然能挂载原有的PV,从而保证了数据的完整性和一致性.
k8s中的service有几种类型:
ClusterType模式,只能对内服务:
apiVersion: v1
kind: Service
spec:
type: ClusterIP
NodePort模式,可以提供对外的IP和端口:
apiVersion: v1
kind: Service
spec:
type: NodePort
Headless模式,专门为有状态pod:
apiVersion: v1
kind: Service
spec:
clusterIP: None # 只需要将clusterIP设置为None即可
type: ClusterIP
LoadBalancer模式:
apiVersion: v1
kind: Service
metadata:
annotations: # annotations 部分需要根据不同厂商而定
service.kubernetes.io/loadbalance-id: lb-xxx
service.kubernetes.io/qcloud-loadbalancer-clusterid: cls-xxx
service.kubernetes.io/qcloud-loadbalancer-internal-subnetid: subnet-xxx
spec:
type: LoadBalancer
pod报错信息如下所示:
排错思路:
报错显示主机名无法解析,感觉像是k8s组件coredns出问题了,因为它负责域名解析,但是自己并未更改coredns的配置,同时查看日志发现coredns有如下报错
百度了半天,说和这个无关,这个不影响
最后通过咨询别人得知,必须是headless类型的svc 才能用这种主机名+svc方式去解析,clusterIP就可以
所以我把svc类型改成headless,如下图所示(这里还有一个坑,需要把之前的svc删掉,要不然会报错不识别type)
然后发现还是报错主机无法解析,然后我们查看一下三个pod的ip和endpoints是否能对应上,但是显示为none,说明svc并没有命中我们的pod容器(k8s会根据service关联到pod的podIP信息组合成一个endpoint,endpoint 是 k8s 集群中的一个资源对象,存储在 etcd 中,用来记录一个 service 对应的所有 pod 的访问地址)
最后查资料发现需要去掉svc的port.name才能和pod关联起来
然后果断去注释掉,但是报错无法部署svc服务,然后就修改了targetPort一行,结果神奇的关联上了(但是又发现es集群好像没办法通过ingress暴露端口,又遇到一个坑。。慢慢学习把)
最后这里也需要注意:es通过StatefulSet创建的时候需要写集群主机名,写多个主机名组成的变量的,完整写法是 pod_name.svc_name.ns_name.svc.cluster.local一般情况下后面的ns_name.svc.cluster.local可以不写,pod会自动填充(我这里都写上了),如下图所示
又来更新了,发现最终的解决办法:不用创建headless类型的svc,创建nodeport类型的即可,然后就可以用ingress进行域名+端口形式访问啦(应该是没有加标签的原因,加了lables后好了)
服务器租用托管,机房租用托管,主机租用托管,https://www.e1idc.com