k8s 中 Pod 的控制器( 三 )


无状态服务
无状态服务不会在本地存储持久化数据 。多个服务实例对于同一个用户请求的响应结果是完全一致的 。这种多服务实例之间是没有依赖关系,比如web应用,在k8s控制器 中动态启停无状态服务的pod并不会对其它的pod产生影响 。
有状态服务
有状态服务需要在本地存储持久化数据 , 典型的是分布式数据库的应用,分布式节点实例之间有依赖的拓扑关系 。
比如,主从关系 。如果 K8S 停止分布式集群中任 一实例 pod , 就可能会导致数据丢失或者集群的 crash 。
来个栗子
cat <<EOF >./pod-statefulSet.yamlapiVersion: v1kind: Servicemetadata:name: nginxlabels:app: nginxspec:ports:- port: 80name: webclusterIP: Noneselector:app: nginx---apiVersion: apps/v1kind: StatefulSetmetadata:name: webspec:selector:matchLabels:app: nginx # 必须匹配 .spec.template.metadata.labelsserviceName: "nginx"replicas: 3 # 默认值是 1template:metadata:labels:app: nginx # 必须匹配 .spec.selector.matchLabelsspec:terminationGracePeriodSeconds: 10containers:- name: nginximage: nginx:1.14.2ports:- containerPort: 80name: webvolumeMounts:- name: wwwmountPath: /usr/share/nginx/htmlvolumeClaimTemplates:- metadata:name: wwwspec:accessModes: [ "ReadWriteOnce" ]resources:requests:storage: 1GiEOFDaemonSetDaemonSet:主要是用来保证集群中的每个节点只运行一个 Pod , 且保证只有一个 Pod , 这非常适合一些系统层面的应用 , 例如日志收集、资源监控等 , 这类应用需要每个节点都运行 , 且不需要太多实例 , 一个比较好的例子就是 Kubernetes 的 kube-proxy 。
当有节点加入集群时 ,  也会为他们新增一个 Pod。当有节点从集群移除时 , 这些 Pod 也会被回收 。
DaemonSet 的应用场景:
1、在每个节点上运行集群守护进程;
2、在每个节点上运行日志收集守护进程;
3、在每个节点上运行监控守护进程 。
来个栗子
cat <<EOF >./nginx-daemonset.yamlapiVersion: apps/v1kind: DaemonSetmetadata:name: nginx-daemonsetlabels:app: nginx-daemonsetspec:selector:matchLabels:app: nginx-daemonsettemplate:metadata:labels:app: nginx-daemonsetspec:containers:- name: nginx-daemonsetimage: nginx:alpineresources:limits:cpu: 250mmemory: 512Mirequests:cpu: 250mmemory: 512MiimagePullSecrets:- name: default-secretEOF这样就能在每个节点中部署一个 Pod 了 , 不过 DaemonSet 也支持通过 label 来选择部署的目标节点
cat <<EOF >./nginx-daemonset.yamlapiVersion: apps/v1kind: DaemonSetmetadata:name: nginx-daemonsetlabels:app: nginx-daemonsetspec:selector:matchLabels:app: nginx-daemonsettemplate:metadata:labels:app: nginx-daemonsetspec:nodeSelector: # 节点选择 , 当节点拥有nodeName=node7时才在节点上创建PodnodeName: node7containers:- name: nginx-daemonsetimage: nginx:alpineresources:limits:cpu: 250mmemory: 512Mirequests:cpu: 250mmemory: 512MiimagePullSecrets:- name: default-secretEOFJob 和 CronJobJob 和 CronJob 是负责处理定时任务的 。
两者的区别主要在于:
Job 负责处理一次性的定时任务 , 即仅需执行一次的任务;
CronJob 是基于时间的 Job , 就类似于 Linux 系统的 crontab 文件中的一行 , 在指定的时间周期运行指定的 Job 。
首先来创建一个 Job
cat <<EOF >./job-demo.yamlapiVersion: batch/v1kind: Jobmetadata:name: job-demospec:template:metadata:name: job-demospec:restartPolicy: Nevercontainers:- name: counterimage: busyboxcommand:- "bin/sh"- "-c"- "echo hello"EOF运行
$ kubectl apply -f job-demo.yaml$ kubectl get podsNAMEREADYSTATUSRESTARTSAGEjob-demo-8qrd90/1Completed040s$ study-k8s kubectl get jobNAMECOMPLETIONSDURATIONAGEjob-demo1/136s45s$ kubectl logs -f job-demo-8qrd9hello

经验总结扩展阅读