k8s——statefulset 与 ingress
k8s——statefulset 与 ingressStatefulSetStatefulSet设计Headless Service创建Statefulset:IngressStatefulSetDeployment的不足,Deployment不足以覆盖所有的应用编排问题,因为在它看来,一个应用的所有Pod是完全一样的,所有它们之间就没有顺序,也无所谓运行在哪台宿主机上,需要时,Deploymen
k8s——statefulset 与 ingress
StatefulSet
Deployment的不足,Deployment不足以覆盖所有的应用编排问题,因为在它看来,一个应用的所有Pod是完全一样的,所有它们之间就没有顺序,也无所谓运行在哪台宿主机上,需要时,Deployment就通过Pod模板创建新的Pod,不需要时就“杀掉”任意一个Pod。
但是在实际场景中,并不是所有应用都满足这样的要求,比如:主从关系,主备关系,还有就是数据存储类应用,多个实例通常会在本地磁盘上保存一份数据,而这些实例一旦被杀掉,即使重建出来,实例与数据之间的对应关系也已经丢失,从而导致应用失败。
这种实例之间有不对等关系,或者有依赖关系的应用,被称为“有状态应用(Stateful Application)”。为了能对“有状态应用”做出支持,Kubernetes在Deployment基础上,扩展出了StatefulSet。
StatefulSet能较好满足一些有状态应用特有的需求:
-
每个Pod有order序号,会按序号创建、删除、更新Pod。
-
通过配置headless service,使每个Pod有一个唯一的网络标识(hostname)。
-
通过配置pvc template,每个Pod有一个独享的pv存储盘。
-
支持一定数量的灰度发布。
StatefulSet设计
StatefulSet将真实世界里的应用状态,抽象为了两种情况:
拓扑状态:
这种情况是说,应用的多个实例之间不是完全对等的关系,这些应用实例必须按照某些顺序启动,比如某个应用的主节点A要先于B启动,那么当把A和B两个节点删除之后,重新创建出来时,也要是这个顺序才行,并且,新创建出来的A和B必须和原来的A和B的网络标识一样,这样原先的访问者才能使用同样的方法访问到这个新Pod。
存储状态:
这种情况是说,应用的多个实例分别绑定了不同的存储数据,对于这些应用实例来说,Pod A第一次读取到的数据和隔了十分钟之后再次读取到的数据应该是同一份,哪怕在此期间Pod A被重新创建过。
所以,StatefulSet的核心功能就是通过某种方式纪录这些状态,然后在Pod被重新创建时,能够为新Pod恢复这些状态。
Headless Service
Service是Kubernetes项目中用来将一组Pod暴露给外界访问的一种机制,比如,一个Deployment有3个Pod,那么就可以定义一个Service,然后用户只要能访问到这个Service,就能访问到某个具体的Pod。
但是,这个Service是怎么被访问到的呢?
第一种方式:
以Service的VIP(Virtual IP:虚拟IP)方式,比如:当访问192.168.0.1这个Service的IP地址时,它就是一个VIP,在实际中,它会把请求转发到Service代理的具体Pod上。
第二种方式:
就是以Service的DNS方式,在这里又分为两种处理方法:第一种是Normal Service,这种情况下,当访问DNS纪录时,解析到的是Service的VIP;第二种是Headless Service,这种情况下,访问DNS纪录时,解析到的就是某一个Pod的IP地址。
Headless Service不需要分配一个VIP,而是可以直接以DNS纪录的方式解析出被代理Pod的IP地址,这样设计可以使Kubernetes项目为Pod分配唯一“可解析身份”,而有了这个身份之后,只要知道了一个Pod的名字以及它对应的Service的名字,就可以非常确定地通过这些DNS纪录访问到Pod的IP地址。
创建Statefulset:
可以使每个pod有序号
通过headlessservice使每个pod有唯一的网络标识
通过pvctemplate每个pod有独立的pv存储
支持一定数量的灰度发布
创建pv:
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv1
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
nfs:
path: /volume/pv1
server: 192.168.19.163
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv2
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
nfs:
path: /volume/pv2
server: 192.168.19.163
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv3
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
nfs:
path: /volume/pv3
server: 192.168.19.163
创建statefilset:
apiVersion: apps/v1
kind: StatefulSet
metadata:
labels:
app: web
name: web
spec:
replicas: 3
selector:
matchLabels:
app: nginx
serviceName: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: web
image: nginx:alpine
ports:
- containerPort: 80
name: web
volumeMounts:
- name: aaaa
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: aaaa
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
selector:
app: nginx
ports:
- port: 80
protocol: TCP
clusterIP: None
查看:
[root@k8smaster]# kubectl get statefulsets.apps
NAME READY AGE
web 3/3 1m27s
[root@k8smaster]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
web-0 1/1 Running 0 2m16s 10.244.2.11 k8snode2 <none> <none>
web-1 1/1 Running 0 1m58s 10.244.1.15 k8snode1 <none> <none>
web-2 1/1 Running 0 1m12s 10.244.1.16 k8snode1 <none> <none>
[root@k8smaster statefilset]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv1 1Gi RWO Retain Bound default/aaaa-web-1 3m16s
pv2 1Gi RWO Retain Bound default/aaaa-web-0 3m16s
pv3 1Gi RWO Retain Bound default/aaaa-web-2 3m16s
对StatefulSet 所使用的镜像进行升级,然后再次查看状态:
[root@k8smaster# kubectl set image statefulset web web=nginx:mainline
再次查看:
[root@k8smaster statefilset]# kubectl get statefulsets.apps -o wide
NAME READY AGE CONTAINERS IMAGES
web 3/3 11m web nginx:mainline
[root@k8smaster statefilset]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv1 1Gi RWO Retain Bound default/aaaa-web-1 13m
pv2 1Gi RWO Retain Bound default/aaaa-web-0 13m
pv3 1Gi RWO Retain Bound default/aaaa-web-2
规律总结
匹配Pod name(网络标识)的模式为:(statefulset名称)-(序号),比如上面的示例:nginx-web-0,nginx-web-1,nginx-web-2。
- StatefulSet为每个Pod副本创建了一个DNS域名,这个域名的格式为:$(podname).(headless server name)。
- StatefulSet使用Headless服务来控制Pod的域名,这个域名的FQDN为:(servicename).(namespace).svc.cluster.local,其中,“cluster.local”指的是集群的域名。
- 根据volumeClaimTemplates为每个Pod创建一个pvc,pvc匹配模式为:(volume_name)-(pod_name),比如上面的volumeMounts.name=www-storage,Pod name=nginx-web-[0-2],因此创建出来的PVC是www-storage-nginx-web-0、www-storage-nginx-web-1、www-storage-nginx-web-2。
- 删除Pod不会删除其pvc,删除pvc将自动释放pv。
StatefulSet的启停顺序:
- 有序部署:部署StatefulSet时,如果有多个Pod副本,它们会被顺序地创建(从0到N-1)。
- 有序删除:当Pod被删除时,它们被终止的顺序是从N-1到0。
- 有序扩展:当对Pod执行扩展操作时,与部署一样,它前面的Pod必须都处于Running和Ready状态。
StatefulSet Pod管理策略:
在v1.7以后,通过允许修改Pod排序策略,同时通过.spec.podManagementPolicy字段确保其身份的唯一性。
- OrderedReady:上述的启停顺序,默认设置。
- Parallel:告诉StatefulSet控制器并行启动或终止所有Pod,并且在启动或终止另一个Pod之前不等待前一个Pod变为Running and Ready或完全终止。
Ingress
在Kubernetes中,服务和Pod的IP地址仅可以在集群网络内部使用,对于集群外的应用是不可见的。
为了使外部的应用能够访问集群内的服务,在Kubernetes目前提供了以下几种方案:
- NodePort
- LoadBalancer
- Ingress
Ingress组成
-
Ingress controller
将新加入的Ingress转化成Nginx的配置文件并使之生效。 -
Ingress服务
将Nginx的配置抽象成一个Ingress对象,每添加一个新的服务只需写一个新的Ingress的yaml文件即可。
Ingress工作原理
Ingress controller通过和Kubernetes api交互,动态的去感知集群中ingress规则变化,然后读取它,按照自定义的规则,就是写明了哪个域名对应哪个service,生成一段nginx配置,再写到nginx-ingress-controller的Pod里,这个Ingress controller的Pod里运行着一个Nginx服务,控制器会把生成的nginx配置写入/etc/nginx.conf文件中,然后reload一下使配置生效,以此达到域名分配置和动态更新的问题。
所有节点下载 https://github.com/kubernetes/ingress-nginx
docker load -i ingress28.tar
master 修改 yaml 文件:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx- ingress -controller
namespace: ingress -nginx
labels:
app. kubernetes . io/name: ingress -nginx
app . kubernetes . io/part-of: ingress -nginx
spec:
replicas: 1
selector:
matchLabels :
app . kubernetes . io/name: ingress -nginx
app. kubernetes . io/part-of: ingress -nginx
template:
metadata:
labels:
app. kube rnetes . io/name: ingress -nginx
app. kubernetes . io/part-of: ingress -nginx
annotations :
prometheus. io/port: "10254"
prometheus . io/scrape: "true"
spec :
hostNetwork: true ## 添加此行
# wait upto five minutes for. the drain of connections
terminationGracePeriodSeconds: 300
serviceAccountName: nginx- ingress -serviceaccount
nodeSelecto r:
kubernetes.10/os: linux
containers :
- name: nginx- ingress -controller
master主机编写 yaml 文件:
apiVersion: v1
kind: Service
metadata:
name: ingress-nginx
labels:
app: ingress-nginx
namespace: ingress-nginx
spec:
type: NodePort
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP
- name: https
port: 443
targetPort: 443
protocol: TCP
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
更多推荐
所有评论(0)