如果说svc、pod、pv等资源是k8s的数据流,那么ReplicationController、ReplicaSet、StatefulSet便是k8s的控制流,可以控制k8s 中pod的副本数和动态伸缩。我们基于以前制作的apple:5678镜像来进行学习。
1,ReplicationController
apiVersion: v1kind: ReplicationControllermetadata:name: apple-rctllabels:name: apple-rctlspec:replicas: 2selector:app: appletemplate:metadata:labels:app: applespec:containers:- name: appleimage: apple:5678env :- name : GET_HOSTS_FROMvalue : envports:- containerPort: 5678
RC只支持基于等式的selector(app!= apple或app!=apple)
% kubectl apply -f deployment/ReplicationController.yamlreplicationcontroller/apple-rc created
% kubectl get rcNAME DESIRED CURRENT READY AGEapple-rc 3 3 3 32s
查看下pod,发现有两个pod已经创建成功了
% kubectl get pod |grep apple-rctlapple-rctl-2hdpt 1/1 Running 0 29sapple-rctl-wrmwp 1/1 Running 0 15s
2,ReplicaSet
Replica Set还支持新的、基于集合的selector(version in (v1.0, v2.0)或env notin (dev, qa))
apiVersion: apps/v1kind: ReplicaSetmetadata:name: apple-rsspec:replicas: 3 #有3个副本selector: #标签选择器matchLabels:app: appletemplate: #模板metadata:labels:app: applespec:containers:- name: apple-appimage: apple:5678env:- name: GET_HOSTS_FROMvalue: dnsports:- containerPort: 5678
中间遇到的问题
% kubectl apply -f deployment/ReplicaSet.yamlerror: unable to recognize "deployment/ReplicaSet.yaml": no matches for kind "ReplicaSet" in version "extensions/v1beta1"
需要查看下当前k8s支持的版本
% kubectl api-versionsadmissionregistration.k8s.io/v1admissionregistration.k8s.io/v1beta1apiextensions.k8s.io/v1apiextensions.k8s.io/v1beta1apiregistration.k8s.io/v1apiregistration.k8s.io/v1beta1apps/v1authentication.k8s.io/v1authentication.k8s.io/v1beta1authorization.k8s.io/v1authorization.k8s.io/v1beta1autoscaling/v1autoscaling/v2beta1autoscaling/v2beta2batch/v1batch/v1beta1catalog.cattle.io/v1certificates.k8s.io/v1certificates.k8s.io/v1beta1coordination.k8s.io/v1coordination.k8s.io/v1beta1discovery.k8s.io/v1discovery.k8s.io/v1beta1events.k8s.io/v1events.k8s.io/v1beta1extensions/v1beta1flowcontrol.apiserver.k8s.io/v1beta1management.cattle.io/v3networking.k8s.io/v1networking.k8s.io/v1beta1node.k8s.io/v1node.k8s.io/v1beta1policy/v1policy/v1beta1rbac.authorization.k8s.io/v1rbac.authorization.k8s.io/v1beta1samplecontroller.k8s.io/v1alpha1scheduling.k8s.io/v1scheduling.k8s.io/v1beta1storage.k8s.io/v1storage.k8s.io/v1beta1ui.cattle.io/v1v1
然后修改成对应的版本即可。
% kubectl apply -f deployment/ReplicaSet.yamlreplicaset.apps/apple-rc create
3,StatefulSet
使用statefulset需要使用对应的StorageClass,先声明一个
apiVersion: storage.k8s.io/v1kind: StorageClassmetadata:name: apple-nfs-storageprovisioner: docker.io/hostpath # or choose another name, must match deployment's env PROVISIONER_NAME' fuseim.pri/ifs 改为docker.io/hostpathparameters:archiveOnDelete: "false" # # When set to "false" your PVs will not be archived# by the provisioner upon deletion of the PVC.
statefulset是有状态的,有状态的副本集都会用到持久存储,所以各个节点不能使用同一存储卷,每个节点有自已的专用存储,因此需要一个pv的模板StorageClass。
apiVersion: apps/v1kind: StatefulSetmetadata:name: apple-ssspec:selector:matchLabels:app: apple #必须匹配 .spec.template.metadata.labelsserviceName: "apple-headless" #声明它属于哪个Headless Service.replicas: 3 #副本数template:metadata:labels:app: apple # 必须配置 .spec.selector.matchLabelsspec:terminationGracePeriodSeconds: 1containers:- name: appleimage: apple:5678ports:- containerPort: 5678name: applevolumeMounts:- name: apple-pvcmountPath: /usr/share/apple/htmlvolumeClaimTemplates: #可看作pvc的模板- metadata:name: apple-pvcspec:accessModes: [ "ReadWriteOnce" ]storageClassName: "apple-nfs-storage" #存储类名,改为集群中已存在的 apple-nfs-storage 改为docker.io/hostpath 改为 hostpathresources:requests:storage: 1Ki
在StatefulSet中与之对应的headless service,headless service,即无头服务,因为是有状态的服务,希望我们每一次连接到同一个pod,关联到同一份pv存储,但是每一次重启后后pod的ip都会被重新分配,所以需要headless service,它和普通服务的区别是创建服务的时候制定 clusterIp:none,这样kubeproxy就不会做负载均衡,方便应用内部自己控制,同时给每一个pod都提供了域名,我们可以保证pod的域名重启后不变,保证了每次连接到同一个pod。
% kubectl apply -f deployment/StorageClass.yamlstorageclass.storage.k8s.io/apple-nfs-storage created
% kubectl apply -f deployment/statefulset.yamlstatefulset.apps/apple-ss created
启动后我们发现状态一直没有ready
% kubectl get statefulsetNAME READY AGEapple-ss 0/3 22s
看下pod的描述信息
% kubectl describe pod apple-ss-0Name: apple-ss-0Namespace: defaultPriority: 0Node: <none>Labels: app=applecontroller-revision-hash=apple-ss-6bb7949cbdstatefulset.kubernetes.io/pod-name=apple-ss-0Annotations: <none>Status: PendingIP:IPs: <none>Controlled By: StatefulSet/apple-ssContainers:apple:Image: apple:5678Port: 5678/TCPHost Port: 0/TCPEnvironment: <none>Mounts:usr/share/apple/html from apple-pvc (rw)var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-qzvxw (ro)Conditions:Type StatusPodScheduled FalseVolumes:apple-pvc:Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)ClaimName: apple-pvc-apple-ss-0ReadOnly: falsekube-api-access-qzvxw:Type: Projected (a volume that contains injected data from multiple sources)TokenExpirationSeconds: 3607ConfigMapName: kube-root-ca.crtConfigMapOptional: <nil>DownwardAPI: trueQoS Class: BestEffortNode-Selectors: <none>Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300snode.kubernetes.io/unreachable:NoExecute op=Exists for 300sEvents:Type Reason Age From Message---- ------ ---- ---- -------Warning FailedScheduling 39s default-scheduler 0/1 nodes are available: 1 pod has unbound immediate PersistentVolumeClaims.Warning FailedScheduling 38s default-scheduler 0/1 nodes are available: 1 pod has unbound immediate PersistentVolumeClaims.
发现pod绑定pv出现了问题
1 pod has unbound immediate PersistentVolumeClaims.
仔细研究发现storageClass里声明的parameters:fuseim.pri/ifs 在docker for mac 上不支持, 改为docker.io/hostpath就好了
修改后我们看下StorageClass资源
% kubectl get storageclassNAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGEapple-nfs-storage docker.io/hostpath Delete Immediate false 4shostpath (default) docker.io/hostpath Delete Immediate false 104d
查看我们的pod和statefullset,发现已经起来了
% kubectl get pod |grep apple-ssapple-ss-0 1/1 Running 0 64sapple-ss-1 1/1 Running 0 64sapple-ss-2 1/1 Running 0 62s% kubectl get statefulsetNAME READY AGEapple-ss 3/3 83s






