#clusterIP类型service的访问
[root@master ~]# kubectl get svc -n greenwich -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
myweb ClusterIP 10.99.226.104 <none> 80/TCP 124m app=nginx
- 通过IP地址10.99.226.104可以访问到后端负载的某一个pod
- 对于集群内部的pod可以通过域名service_name.namespace.svc.cluster.local访问后端负载的某一个pod
- DNS解析myweb服务到clusterip(10.99.226.104)
#有状态应用部署statefulset--数据需要持久化--更多的采用operator进行有状态应用的部署,
#创建无头服务headless service
[root@master greenwich]# cat headless-nginx.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
namespace: greenwich
labels:
app: nginx
spec:
selector:
app: nginx
ports:
- name: nginx-port
port: 80
clusterIP: None
[root@master greenwich]# kubectl apply -f headless-nginx.yaml
[root@master greenwich]# kubectl get svc -n greenwich
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-svc ClusterIP None <none> 80/TCP 8s
- Headless Service,我们访问service_name.namespace.svc.cluster.local的时候是直接解析到的 mysvc代理的某一个具体的Pod的IP地址,这是与普通的service最大的区别
- 普通service解析的是clusterip的地址;headless service解析的是后端enpoint中一个具体的pod地址
- headless Service 所代理的所有 Pod 的 IP 地址都会绑定一个如下所示的 DNS 记录:
- <pod-name>.<svc-name>.<namespace>.svc.cluster.local
#创建2个pv用于数据的持久化存储
[root@localhost bxj]# exportfs -arv
exporting 172.16.33.0/24:/mnt/sdb/bxj/pv02
exporting 172.16.33.0/24:/mnt/sdb/bxj/pv01
[root@master greenwich]# cat pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv01
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
nfs:
server: 172.16.33.101
path: /mnt/sdb/bxj/pv01
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv02
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
nfs:
server: 172.16.33.101
path: /mnt/sdb/bxj/pv02
[root@master greenwich]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv01 1Gi RWO Retain Available 7s
pv02 1Gi RWO Retain Available 7s
[root@master greenwich]# cat nginx-statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: nginx
namespace: greenwich
labels:
app: nginx
spec:
serviceName: nginx-svc
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- name: web
containerPort: 80
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
- 和volumeMounts进行关联的不是volumes而是volumeClaimTemplates,该属性会自动创建一个 PVC 对象,其实这里就是一个PVC的模板,PVC 被创建后会自动去关联当前系统中和他合适的 PV 进行绑定
- serviceName就是管理当前StatefulSet的服务名称,即无头服务必须在 StatefulSet之前存在,Pod 会遵循以下格式获取DNS/主机名:pod-specific-string.serviceName.default.svc.cluster.local,其中pod-specific-string由StatefulSet控制器管理
- StatefulSet 中的 Pod 拥有一个具有稳定的、独一无二的身份标志。这个标志基于 StatefulSet 控制器分配给每个 Pod 的唯一顺序索引。
[root@master greenwich]# kubectl apply -f nginx-statefulset.yaml
statefulset.apps/nginx created
#从下面的输出可以看出pod的启动有顺序
- Pod 的名称的形式为<statefulset name>-<ordinal index>
[root@master greenwich]# kubectl get pod -n greenwich -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-0 1/1 Running 0 50s 10.244.1.27 node01 <none> <none>
nginx-1 0/1 ContainerCreating 0 33s <none> node02 <none> <none>
[root@master greenwich]# kubectl get pod -n greenwich -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-0 1/1 Running 0 51s 10.244.1.27 node01 <none> <none>
nginx-1 1/1 Running 0 34s 10.244.2.19 node02 <none> <none>
#pv的状态在pvc创建完成之后由avaliable切换成了bound
- StatefulSet 中 Pod 副本的创建会按照序列号升序处理,副本的更新和删除会按照序列号降序处理
[root@master greenwich]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv01 1Gi RWO Retain Bound greenwich/www-nginx-0 25m
pv02 1Gi RWO Retain Bound greenwich/www-nginx-1 25m
[root@master greenwich]# kubectl exec pod/nginx-0 -n greenwich -- hostname
nginx-0
[root@master greenwich]# kubectl exec pod/nginx-1 -n greenwich -- hostname
nginx-1
#对statefulset的headless服务名称解析,可以看到得到的是两个Pod 的解析记录,但实际上如果我们通过nginx-svc这个DNS 去访问我们的服务的话,并不会随机或者轮询背后的两个 Pod,而是访问到一个固定的 Pod,
[root@master greenwich]# kubectl run -it --image busybox:1.28.3 test --restart=Never --rm /bin/sh -n greenwich
If you don't see a command prompt, try pressing enter.
/ # nslookup nginx-svc
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: nginx-svc
Address 1: 10.244.1.27 nginx-0.nginx-svc.greenwich.svc.cluster.local
Address 2: 10.244.2.19 nginx-1.nginx-svc.greenwich.svc.cluster.local
/ # nslookup nginx-0.nginx-svc
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: nginx-0.nginx-svc
Address 1: 10.244.1.27 nginx-0.nginx-svc.greenwich.svc.cluster.local
/ # nslookup nginx-1.nginx-svc
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: nginx-1.nginx-svc
Address 1: 10.244.2.19 nginx-1.nginx-svc.greenwich.svc.cluster.local
[root@master greenwich]# kubectl delete -f nginx-statefulset.yaml -n greenwich ; kubectl get pod -n greenwich -w
statefulset.apps "nginx" deleted
NAME READY STATUS RESTARTS AGE
nginx-0 1/1 Running 0 30s
nginx-1 1/1 Running 0 21s
nginx-1 1/1 Terminating 0 22s
nginx-0 1/1 Terminating 0 31s
总结:
- 无头服务headless service的clusterIP: None,该服务要先于statefulset创建
- statefulset的配置文件中servicName指向无头服务的服务名称
- 与volumeMounts对应的除了volume还可以是volumeClaimTemplate即pvc模板可以自动完成
和pv的绑定 - DNS对于clusterip类型的服务,解析的是service name 和 clusterip
- DNS对于headless类型的服务Pod 会遵循格式获取 DNS/主机名:podname.servicename.default.svc.cluster.local
- pod的名称形式statefulset_name-ordinal _index(nginx-0)
- StatefulSet 支持两种升级策略OnDelete和RollingUpdate