一、k8s的五种控制器

1.1 k8s的控制器类型

Kubernetes中内建了很多controller(控制器),这些相当于一个状态机,用来控制Pod的具体状态和行为:

  • deployment:适合无状态的服务部署
  • StatefullSet:适合有状态的服务部署
  • DaemonSet:一次部署,所有的node节点都会部署,例如一些典型的应用场景:
    • 运行集群存储 daemon,例如在每个Node上运行 glusterd、ceph
    • 在每个Node上运行日志收集 daemon,例如 fluentd、 logstash
    • 在每个Node上运行监控 daemon,例如 Prometheus Node Exporter
  • Job:一次性的执行任务
  • Cronjob:周期性的执行任务

控制器又被称为工作负载,pod通过控制器实现应用的运维,比如伸缩、升级等
在这里插入图片描述

1.2 Deployment控制器

适合部署无状态的应用服务,用来管理pod和replicaset,具有上线部署、副本设定、滚动更新、回滚等功能,还可提供声明式更新,例如只更新一个新的Image

编写yaml文件,并创建nginx服务pod资源

[root@master test]# vim nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3   
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx1
        image: nginx:1.15.4
        ports:
        - containerPort: 80
[root@master test]# kubectl create -f nginx-deployment.yaml 
deployment.apps/nginx-deployment created
[root@master test]# kubectl get pod
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-78cdb5b557-86fm9   1/1     Running   0          44s
nginx-deployment-78cdb5b557-jqvng   1/1     Running   0          44s
nginx-deployment-78cdb5b557-rkxtk   1/1     Running   0          44s

查看控制器参数:可以使用describe或者edit两种方式

[root@master test]# kubectl describe deploy nginx-deployment
'或者使用edit'
[root@master test]# kubectl edit deploy nginx-deployment
  strategy:
    rollingUpdate:        '此段解释的是滚动更新机制'
      maxSurge: 25%       '25%指的是pod数量的百分比,最多可以扩容125%'
      maxUnavailable: 25%  '25%指的是pod数量的百分比,最多可以缩容75%'
    type: RollingUpdate

查看控制器的历史版本,滚动更新以此为基础

[root@master test]# kubectl rollout history deploy/nginx-deployment
deployment.extensions/nginx-deployment 
REVISION  CHANGE-CAUSE
1         <none>    '发现只有一个,说明没有开始滚动更新,否则会保持2个'

1.3 SatefulSet控制器

  • 适合部署有状态应用
  • 解决Pod的独立生命周期,保持Pod启动顺序和唯一性
  • 稳定,唯一的网络标识符,持久存储(例如:etcd配置文件,节点地址发生变化,将无法使用)
  • 有序,优雅的部署和扩展、删除和终止(例如:mysql主从关系,先启动主,再启动从)
  • 有序,滚动更新
  • 应用场景:例如数据库

无状态服务的特点:

  • deployment 认为所有的pod都是一样的
  • 不用考虑顺序的要求
  • 不用考虑在哪个node节点上运行
  • 可以随意扩容和缩容

有状态服务的特点:

  • 实例之间有差别,每个实例都有自己的独特性,元数据不同,例如etcd,zookeeper
  • 实例之间不对等的关系,以及依靠外部存储的应用

常规的service服务和无头服务的区别

  • service:一组Pod访问策略,提供cluster-IP群集之间通讯,还提供负载均衡和服务发现
  • Headless service 无头服务,不需要cluster-IP,直接绑定具体的Pod的IP,无头服务经常用于statefulset的有状态部署

创建无头服务的service资源和dns资源
由于有状态服务的IP地址是动态的,所以使用无头服务的时候要绑定dns服务

1、编写yaml文件并创建service资源

[root@master test]# vim nginx-headless.yaml

apiVersion: v1
kind: Service    '创建一个service类型的资源'
metadata: 
  name: nginx-headless
  labels: 
    app: nginx
spec: 
  ports: 
  - port: 80
    name: web
  clusterIP: None     '不使用clusterIP'   
  selector: 
    app: nginx
[root@master test]# kubectl create -f nginx-headless.yaml 
service/nginx-headless created
[root@master test]# kubectl get svc
NAME             TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes       ClusterIP   10.0.0.1     <none>        443/TCP   15d
nginx-headless   ClusterIP   None         <none>        80/TCP    16s

2、配置dns服务,使用yaml文件创建

[root@master test]# vim coredns.yaml
# Warning: This is a file generated from the base underscore template file: coredns.yaml.base

apiVersion: v1
kind: ServiceAccount	'系统账户,为pod中的进程和外部用户提供身份信息'
metadata:
  name: coredns
  namespace: kube-system	'指定名称空间'
  labels:
      kubernetes.io/cluster-service: "true"
      addonmanager.kubernetes.io/mode: Reconcile
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole	'创建访问权限的角色'
metadata:
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
    addonmanager.kubernetes.io/mode: Reconcile
  name: system:coredns
rules:
- apiGroups:
  - ""
  resources:
  - endpoints
  - services
  - pods
  - namespaces
  verbs:
  - list
  - watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding	'创建集群角色绑定的用户'
metadata:
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
    addonmanager.kubernetes.io/mode: EnsureExists
  name: system:coredns
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:coredns
subjects:
- kind: ServiceAccount
  name: coredns
  namespace: kube-system
---
apiVersion: v1
kind: ConfigMap  	'通过此服务来更改服务发现的工作方式'
metadata:
  name: coredns
  namespace: kube-system
  labels:
      addonmanager.kubernetes.io/mode: EnsureExists
data:
  Corefile: |	'是coreDNS的配置文件'
    .:53 {
        errors
        health
        kubernetes cluster.local in-addr.arpa ip6.arpa {
            pods insecure	
            upstream
            fallthrough in-addr.arpa ip6.arpa
        }
        prometheus :9153
        proxy . /etc/resolv.conf
        cache 30
        loop
        reload
        loadbalance
    }
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: coredns
  namespace: kube-system
  labels:
    k8s-app: kube-dns
    kubernetes.io/cluster-service: "true"
    addonmanager.kubernetes.io/mode: Reconcile
    kubernetes.io/name: "CoreDNS"
spec:
  # replicas: not specified here:
  # 1. In order to make Addon Manager do not reconcile this replicas parameter.
  # 2. Default is 1.
  # 3. Will be tuned in real time if DNS horizontal auto-scaling is turned on.
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
  selector:
    matchLabels:
      k8s-app: kube-dns
  template:
    metadata:
      labels:
        k8s-app: kube-dns
      annotations:
        seccomp.security.alpha.kubernetes.io/pod: 'docker/default'
    spec:
      serviceAccountName: coredns
      tolerations:
        - key: node-role.kubernetes.io/master
          effect: NoSchedule
        - key: "CriticalAddonsOnly"
          operator: "Exists"
      containers:
      - name: coredns
        image: coredns/coredns:1.2.2
        imagePullPolicy: IfNotPresent
        resources:
          limits:
            memory: 170Mi
          requests:
            cpu: 100m
            memory: 70Mi
        args: [ "-conf", "/etc/coredns/Corefile" ]
        volumeMounts:
        - name: config-volume
          mountPath: /etc/coredns
          readOnly: true
        ports:
        - containerPort: 53
          name: dns
          protocol: UDP
        - containerPort: 53
          name: dns-tcp
          protocol: TCP
        - containerPort: 9153
          name: metrics
          protocol: TCP
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 60
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 5
        securityContext:
          allowPrivilegeEscalation: false
          capabilities:
            add:
            - NET_BIND_SERVICE
            drop:
            - all
          readOnlyRootFilesystem: true
      dnsPolicy: Default
      volumes:
        - name: config-volume
          configMap:
            name: coredns
            items:
            - key: Corefile
              path: Corefile
---
apiVersion: v1
kind: Service
metadata:
  name: kube-dns
  namespace: kube-system
  annotations:
    prometheus.io/port: "9153"
    prometheus.io/scrape: "true"
  labels:
    k8s-app: kube-dns
    kubernetes.io/cluster-service: "true"
    addonmanager.kubernetes.io/mode: Reconcile
    kubernetes.io/name: "CoreDNS"
spec:
  selector:
    k8s-app: kube-dns
  clusterIP: 10.0.0.2 
  ports:
  - name: dns
    port: 53
    protocol: UDP
  - name: dns-tcp
    port: 53
    protocol: TCP
[root@master test]# kubectl create -f coredns.yaml 
serviceaccount/coredns created
clusterrole.rbac.authorization.k8s.io/system:coredns created
clusterrolebinding.rbac.authorization.k8s.io/system:coredns created
configmap/coredns created
deployment.extensions/coredns created
service/kube-dns created
[root@master test]# kubectl get pod,svc -n kube-system   '查看kube-system名称空间的pod和svc资源'
NAME                                        READY   STATUS    RESTARTS   AGE
pod/coredns-56684f94d6-cc9jk                1/1     Running   0          58s
pod/kubernetes-dashboard-7dffbccd68-v6q55   1/1     Running   1          6d2h
pod/kuboard-78bcb484bc-s7svz                1/1     Running   0          2d2h

NAME                           TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)         AGE
service/kube-dns               ClusterIP   10.0.0.2     <none>        53/UDP,53/TCP   58s
service/kubernetes-dashboard   NodePort    10.0.0.220   <none>        443:30001/TCP   6d2h
service/kuboard                NodePort    10.0.0.184   <none>        80:32567/TCP    6d2h

3、创建一个测试的pod资源并验证DNS解析

[root@master test]# vim demo08.yaml
apiVersion: v1
kind: Pod
metadata:
  name: dns-test
spec:
  containers:
  - name: busybox
    image: busybox:1.28.4
    args:
    - /bin/sh
    - -c
    - sleep 36000
  restartPolicy: Never
[root@master test]# kubectl create -f demo08.yaml 
pod/dns-test created
[root@master test]# kubectl exec -it dns-test sh  '进入容器进行解析'
/ # nslookup kubernetes
Server:    10.0.0.2
Address 1: 10.0.0.2 kube-dns.kube-system.svc.cluster.local

Name:      kubernetes
Address 1: 10.0.0.1 kubernetes.default.svc.cluster.local

创建statefulset资源
1、编写yaml文件并创建资源

[root@master test]# vim statefulset-test.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None	'指定为无头服务'
  selector:
    app: nginx
---
apiVersion: apps/v1beta1  
kind: StatefulSet  
metadata:
  name: nginx-statefulset  
  namespace: default
spec:
  serviceName: nginx  
  replicas: 3     '指定副本数量'
  selector:
    matchLabels:  
       app: nginx
  template:  
    metadata:
      labels:
        app: nginx  
    spec:
      containers:
      - name: nginx
        image: nginx:latest  
        ports:
        - containerPort: 80
[root@master test]# vim pod-dns-test.yaml 	'创建用来测试dns的pod资源'
apiVersion: v1
kind: Pod
metadata:
  name: dns-test
spec:
  containers:
  - name: busybox
    image: busybox:1.28.4
    args:
    - /bin/sh
    - -c
    - sleep 36000
  restartPolicy: Never

[root@master test]# kubectl delete -f .	'先删除之前所有的资源' 

2、创建资源并测试

[root@master test]# kubectl create -f sfs.yaml 
service/nginx created
statefulset.apps/nginx-statefulset created
[root@master test]# kubectl get pod,svc
NAME                      READY   STATUS    RESTARTS   AGE
pod/dns-test              1/1     Running   0          5m1s
pod/nginx-statefulset-0   1/1     Running   0          92s
pod/nginx-statefulset-1   1/1     Running   0          83s
pod/nginx-statefulset-2   1/1     Running   0          44s

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.0.0.1     <none>        443/TCP   15d
service/nginx        ClusterIP   None         <none>        80/TCP    92s
[root@master test]# kubectl exec -it dns-test sh   '登陆pod资源进行测试'
/ # nslookup pod/nginx-statefulset-0
Server:    10.0.0.2
Address 1: 10.0.0.2 kube-dns.kube-system.svc.cluster.local

nslookup: can't resolve 'pod/nginx-statefulset-0'
/ # nslookup nginx-statefulset-0.nginx
Server:    10.0.0.2
Address 1: 10.0.0.2 kube-dns.kube-system.svc.cluster.local

Name:      nginx-statefulset-0.nginx
Address 1: 172.17.29.3 nginx-statefulset-0.nginx.default.svc.cluster.local
/ # nslookup nginx-statefulset-1.nginx
Server:    10.0.0.2
Address 1: 10.0.0.2 kube-dns.kube-system.svc.cluster.local

Name:      nginx-statefulset-1.nginx
Address 1: 172.17.76.3 nginx-statefulset-1.nginx.default.svc.cluster.local
/ # nslookup nginx-statefulset-2.nginx
Server:    10.0.0.2
Address 1: 10.0.0.2 kube-dns.kube-system.svc.cluster.local

Name:      nginx-statefulset-2.nginx
Address 1: 172.17.29.2 nginx-statefulset-2.nginx.default.svc.cluster.local

相比于Deployment而言,StatefulSet是有身份的!(序列编号区分唯一身份)
身份三要素:

1、域名 nginx-statefulset-0.nginx

2、主机名 nginx-statefulset-0

3、存储(PVC)

StatefulSet的有序部署和有序伸缩
有序部署(即0到N-1)

有序收缩,有序删除(即从N-1到0)

无论是部署还是删除,更新下一个 Pod 前,StatefulSet 控制器终止每个 Pod 并等待它们变成 Running 和 Ready。

1.4 DaemonSet控制器

  • 在每一个Node上运行一个Pod
    新加入的Node也同样会自动运行一个Pod
  • 应用场景:监控,分布式存储,日志收集等

编写yaml文件并创建资源进行测试

[root@master test]# vim ds.yaml
apiVersion: apps/v1
kind: DaemonSet 
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.15.4
        ports:
        - containerPort: 80

查看资源的部署情况,发现daemonset的资源已经分配到两个node节点上了

[root@master test]# kubectl create -f ds.yaml 
daemonset.apps/nginx-deployment created
[root@master test]# kubectl get pods
NAME                     READY   STATUS    RESTARTS   AGE
nginx-deployment-gdsnd   1/1     Running   0          6s
nginx-deployment-z2dbl   1/1     Running   0          6s

1.5 Job控制器

  • 一次性执行任务,类似Linux中的job
  • 应用场景:如离线数据处理,视频解码等业务

编写yaml文件并创建资源测试

[root@master test]# vim job.yaml

apiVersion: batch/v1
kind: Job
metadata:
  name: pi
spec:
  template:
    spec:
      containers:
      - name: pi
        image: perl
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]    '计算圆周率'
      restartPolicy: Never
  backoffLimit: 4     '重试次数默认是6次,修改为4次,当遇到异常时Never状态会重启,所以要设定次数'

查看job资源

[root@master test]# kubectl create -f job.yaml 
job.batch/pi created
[root@master test]# kubectl get pods
NAME       READY   STATUS      RESTARTS   AGE
pi-dscgp   0/1     Completed   0          76s    '执行成功后就结束了'
[root@master test]# kubectl logs pi-dscgp   '查看日志可以查看结果'
3.141592653589793238462643.....

1.6 cronjob控制器

  • 周期性任务,像Linux的Crontab一样
  • 应用场景:如通知,备份等

编写yaml文件

[root@master test]# vim cronjob.yaml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox
            args:
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster
          restartPolicy: OnFailure

创建资源

[root@master test]# kubectl create -f cronjob.yaml 
cronjob.batch/hello created
[root@master test]# kubectl get cronjob
NAME    SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
hello   */1 * * * *   False     0        <none>          38s
[root@master test]# kubectl get pods
NAME                     READY   STATUS      RESTARTS   AGE
hello-1602677340-dt9hq   0/1     Completed   0          39s

可以查看日志信息

[root@master test]# kubectl logs hello-1602677340-dt9hq
Wed Oct 14 12:09:21 UTC 2020
Hello from the Kubernetes cluster
[root@master test]# kubectl get pods
NAME                     READY   STATUS      RESTARTS   AGE
hello-1602677340-dt9hq   0/1     Completed   0          2m21s
hello-1602677400-2nd48   0/1     Completed   0          81s
hello-1602677460-qp2xt   0/1     Completed   0          20s

使用cronjob要慎重,用完之后要删掉,不然会占用很多资源

Logo

开源、云原生的融合云平台

更多推荐