k8s---控制器
控制器
●控制器:又称之为工作负载,分别包含以下类型控制器
- Deployment:无状态化服务
- StatefulSet:有状态化服务
- DaemonSet:不需要指明资源创建在某个节点,只要节点在集群中都会被创建资源(日志收集,监控)
- Job:一次性创建任务,记录在pod日志中
- CronJob:周期性创建任务
●Pod与控制器之间的关系
- controllers:在集群上管理和运行容器的对象通过label-selector相关联
- Pod通过控制器实现应用的运维,如伸缩,升级等
- label-selector:标签,关联控制器实现Pod通过控制器实现应用的运维,如伸缩,升级等
1.Deployment
示例1:部署无状态化应用
- 管理Pod和ReplicaSet
- 具有上线部署、副本设定、滚动升级、回滚等功能
- 提供声明式更新,例如只更新一个新的镜像
- 应用场景:web服务
[aaa@qq.com demo]# vim nginx-deployment.yaml ##编辑nginx-deployment的资源文件
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3 ##副本集数量为3个
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.15.4
ports:
- containerPort: 80
[aaa@qq.com demo]# kubectl create -f nginx-deployment.yaml ##创建pod资源
[aaa@qq.com demo]# kubectl get all ##查看所有信息
NAME READY STATUS RESTARTS AGE
pod/nginx-deployment-d55b94fd-lmc9r 1/1 Running 0 2m11s
pod/nginx-deployment-d55b94fd-pxvsc 1/1 Running 0 2m11s
pod/nginx-deployment-d55b94fd-thlmv 1/1 Running 0 2m11s
pod/pod-example 1/1 Running 0 160m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 6d12h
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx-deployment 3 3 3 3 2m11s
NAME DESIRED CURRENT READY AGE
replicaset.apps/nginx-deployment-d55b94fd 3 3 3 2m11s
##Replicaset 是控制版本,副本数,回滚就是通过此来实现
[aaa@qq.com demo]# kubectl edit deployment/nginx-deployment ##查看控制器
......
spec:
progressDeadlineSeconds: 600
replicas: 3 ##副本数量为3个
revisionHistoryLimit: 10
selector: ##控制器
matchLabels:
app: nginx
strategy:
rollingUpdate: ##使用滚动更新
maxSurge: 25% ##最大更新数是25%
maxUnavailable: 25% ##最大删除数是25%
type: RollingUpdate
template:
metadata:
creationTimestamp: null
labels:
app: nginx
spec:
containers:
- image: nginx:1.15.4
imagePullPolicy: IfNotPresent
name: nginx-deployment
namespace: default
resourceVersion: "880370"
selfLink: /apis/extensions/v1beta1/namespaces/default/deployments/nginx-deployment
uid: d5f1ec3d-50cd-11ea-895a-000c297a15fb
最大更新数25%:最大更新pod副本数量的25%
最大删除数25%:最大删除pod副本数量的25%
假设有100个副本集,就会先更新25%个pod,这时总资源为125%,就需要销毁25%的旧pod保持副本集的数量还是100个,第二轮更新还是依据这种方式,先更新25%,在删除25%,直到全部更新完毕
注最大删除数要等于最大更新数
[aaa@qq.com demo]# kubectl rollout history deployment/nginx-deployment ##查看历史版本
deployment.extensions/nginx-deployment
REVISION CHANGE-CAUSE
1 <none>
2.SatefulSet
1.部署有状态应用
2.解决Pod独立生命周期,保持Pod启动顺序和唯一性
3.稳定,唯一的网络标识符,持久存储(例如:etcd配置文件,节点地址发生变化,将无法使用)
4.有序,优雅的部署和扩展、删除和终止(例如:mysql主从关系,先启动主,再启动从)
5.有序,滚动更新
6.应用场景:数据库
无状态化和有状态的区别
●无状态:
- deployment 认为所有的pod都是一样的
- 不用考虑顺序的要求
- 不用考虑在哪个node节点上运行
- 可以随意扩容和缩容
●有状态:
- 实例之间有差别,每个实例都有自己的独特性,元数据不同,例如etcd,zookeeper
- 实例之间不对等的关系,以及依靠外部存储的应用。
●常规service和无头服务区别:
- service:一组Pod访问策略,提供cluster-IP群集之间通讯,还提供负载均衡和服务发现。
- Headless service 无头服务,不需要cluster-IP,直接绑定具体的Pod的IP
示例2:部署有状态化应用
[aaa@qq.com demo]# kubectl create -f nginx-service.yaml
service/nginx-service created
[aaa@qq.com demo]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 6d12h
nginx-service NodePort 10.0.0.36 <none> 80:46390/TCP 22s
回到node节点操作(这边举例node01)
[aaa@qq.com ~]# systemctl restart flanneld.service ##重启flanneld网络组件
[aaa@qq.com ~]# systemctl restart docker ##重启docker
[aaa@qq.com ~]# curl 10.0.0.36 ##查看群集间通讯
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title> ##能正常访问页面
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
示例3:部署headless应用(因为Pod动态IP地址,所以常用于绑定DNS访问)
[aaa@qq.com demo]# vim headless.yaml ##编写headless的yaml文件,提供无头服务
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None ##不设置clusterIP
selector:
app: nginx
[aaa@qq.com demo]# kubectl delete -f . ##删除当前目录下创建的资源
创建提供无头服务的资源
[aaa@qq.com demo]# kubectl create -f headless.yaml ##创建无头服务的资源
service/nginx created
[aaa@qq.com demo]# kubectl get svc ##查看服务
创建dns k8s的资源
[aaa@qq.com demo]# vim coredns.yaml
# Warning: This is a file generated from the base underscore template file: coredns.yaml.base
apiVersion: v1
kind: ServiceAccount ##创建了Account资源
metadata:
name: coredns
namespace: kube-system ##命名空间
labels:
kubernetes.io/cluster-service: "true" ##设置用dns的形式去访问cluster-ip
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: ##原始资源,建立rbac的管控
- endpoints
- services
- pods
- namespaces
verbs:
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1 ##验证
kind: ClusterRoleBinding ##绑定Cluster
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: |
.: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" ##启用核心功能dns
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 ##下载提供dns服务的镜像
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 ##提供dns服务的端口
name: dns
protocol: UDP ##提供udp服务
- containerPort: 53
name: dns-tcp
protocol: TCP ##提供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 ##dns访问的ip
ports:
- name: dns
port: 53
protocol: UDP
- name: dns-tcp
port: 53
protocol: TCP
[aaa@qq.com demo]# kubectl apply -f coredns.yaml ##创建dns
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
[aaa@qq.com demo]# kubectl get pods -n kube-system ##查看kube-system资源
NAME READY STATUS RESTARTS AGE
coredns-56684f94d6-m4744 1/1 Running 0 14m
kubernetes-dashboard-7dffbccd68-zpzrq 1/1 Running 3 5d23h
[aaa@qq.com demo]# kubectl get pods -n kube-system -o wide ##
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE
coredns-56684f94d6-m4744 1/1 Running 0 15m 172.17.91.2 192.168.148.139 <none> ##提供了DNS资源
kubernetes-dashboard-7dffbccd68-zpzrq 1/1 Running 3 5d23h 172.17.13.2 192.168.148.140 <none>
[aaa@qq.com demo]# vim pod7.yaml ##编辑一个测试的pod资源
apiVersion: v1
kind: Pod ##pod类型
metadata:
name: dns-test ##名称
spec:
containers:
- name: busybox
image: busybox:1.28.4 ##镜像是linux最小内核
args:
- /bin/sh
- -c
- sleep 36000 ##休眠时间是36000秒
restartPolicy: Never ##重启策略:不进行重启
验证dns解析
[aaa@qq.com demo]# kubectl create -f pod7.yaml ##创建pod测试资源
pod/dns-test created
[aaa@qq.com demo]# kubectl get pods ##查看pod资源
NAME READY STATUS RESTARTS AGE
dns-test 1/1 Running 0 58s
node节点重启docker服务和flannel网络组件
[aaa@qq.com ~]# systemctl restart docker
[aaa@qq.com ~]# systemctl restart flanneld.service
[aaa@qq.com demo]# kubectl exec -it dns-test sh ##进入资源验证dns解析
/ # nslookup kubernetes ##用dns解析kubernetes
Server: 10.0.0.2 ##解析成功是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
/ # exit ##退出
创建nginx资源服务,测试dns检查功能
[aaa@qq.com demo]# kubectl create -f nginx-service.yaml ##创建nginx-service资源
service/nginx-service created
[aaa@qq.com demo]# kubectl get svc ##查看服务
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 6d23h
nginx ClusterIP None <none> 80/TCP 70m
nginx-service NodePort 10.0.0.196 <none> 80:45696/TCP 40s ##nginx服务对应的CLUSTER-IP地址
[aaa@qq.com demo]# kubectl delete svc/nginx
service "nginx" deleted
[aaa@qq.com demo]# kubectl delete svc/nginx-service
service "nginx-service" deleted
[aaa@qq.com demo]# vim sts.yaml ##编写无头服务资源
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80 ##80端口
name: web
clusterIP: None ##建立了无头服务的资源
selector:
app: nginx
---
apiVersion: apps/v1beta1
kind: StatefulSet ##有状态化服务,配合无头服务
metadata:
name: nginx-statefulset
namespace: default
spec:
serviceName: nginx
replicas: 3 ##副本集数量为3个
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
[aaa@qq.com demo]# kubectl create -f sts.yaml ##创建无头服务的pod资源
service/nginx created
statefulset.apps/nginx-statefulset created
[aaa@qq.com demo]# kubectl get pods ##查看pod资源
NAME READY STATUS RESTARTS AGE
dns-test 1/1 Running 0 30m
nginx-statefulset-0 1/1 Running 0 41s
nginx-statefulset-1 1/1 Running 0 23s
nginx-statefulset-2 1/1 Running 0 18s
[aaa@qq.com demo]# kubectl get svc ##查看服务
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 7d
nginx ClusterIP None <none> 80/TCP 55s ##无头服务
[aaa@qq.com ~]# kubectl get ep ##查看资源的IP地址
NAME ENDPOINTS AGE
kubernetes 192.168.148.137:6443,192.168.148.138:6443 7d
nginx 172.17.13.4:80,172.17.91.3:80,172.17.91.4:80 5m28s
[aaa@qq.com demo]# kubectl exec -it dns-test sh ##验证dns
/ # nslookup nginx
Server: 10.0.0.2
Address 1: 10.0.0.2 kube-dns.kube-system.svc.cluster.local
Name: nginx
Address 1: 172.17.91.3 nginx-statefulset-0.nginx.default.svc.cluste ##解析dns对应的地址成功,直接访问pod ip
Address 2: 172.17.91.4 nginx-statefulset-2.nginx.default.svc.cluste
Address 3: 172.17.13.4 nginx-statefulset-1.nginx.default.svc.cluste
●总结
- StatefulSet与Deployment区别:有身份的!
●身份三要素:
- 域名 nginx-statefulset-0.nginx
- 主机名 nginx-statefulset-0
- 存储(PVC)
3.DaemonSet
●作用:
- 在每一个Node上运行一个Pod
- 新加入的Node也同样会自动运行一个Pod
●应用场景:Agent
https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/
官方案例(监控)
示例3.部署DaemonSet 应用:
[aaa@qq.com demo]# vim ds.yaml ##编辑DaemonSet的yaml文件
apiVersion: apps/v1
kind: DaemonSet ##类型为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
[aaa@qq.com demo]# kubectl create -f ds.yaml ##创建资源
daemonset.apps/nginx-deployment created
4.Job
Job分为普通任务(Job)和定时任务(CronJob)
一次性执行
应用场景:离线数据处理,视频解码等业务
示例4.部署job 应用
1.在node节点下载perl镜像,因为镜像比较大所以提前下载好(这边举例node01)
[aaa@qq.com ~]# docker pull perl
2.示例中,重试次数默认是6次,修改为4次,当遇到异常时Never状态不会重启,所以要设定次数。
[aaa@qq.com demo]# vim job.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: pi ##指定资源类型为pi
spec:
template:
spec:
containers:
- name: pi
image: perl
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"] ##用pi语言计算圆周率
restartPolicy: Never ##异常时Never状态不会重启
backoffLimit: 4 ##重试次数默认是6次,修改为4次
[aaa@qq.com demo]# kubectl apply -f job.yaml ##创建资源
job.batch/pi created
发现资源运行完就处于完成状态,验证了是job这种一次性任务
[aaa@qq.com demo]# kubectl logs pi-fmzk5 ##查看日志信息
5.CronJob
●周期性任务,像Linux的Crontab一样。
●应用场景:通知,备份
官方地址:
https://kubernetes.io/docs/tasks/job/automated-tasks-with-cron-jobs/
示例:部署CronJob 应用
1.每分钟建立容器打印hello
[aaa@qq.com demo]# 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 ##重启策略
[aaa@qq.com demo]# kubectl create -f cronjob.yaml ##创建资源
cronjob.batch/hello created
[aaa@qq.com demo]# kubectl get cronjob ##查看cronjob资源
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
hello */1 * * * * False 1 20s 82s ##每分钟执行一次
[aaa@qq.com demo]# kubectl get pods
发现每分钟都会生成一个pod,然后执行输出任务
[aaa@qq.com demo]# kubectl logs hello-1602731820-fgnm6 ##查看日志
Thu Oct 15 03:17:27 UTC 2020
Hello from the Kubernetes cluster ##执行了echo输出信息