K8S-控制器
Pod控制器概念以及使用
RS 核心资源有三种
1.用户期望的副本数
2. 标签选择器 以便选定由自己管理和控制的pod
3. pod 资源模板
deployment 运行在RS之上,还支持滚动更新和回滚机制 只能管理无状态副本集
支持的功能:
回滚,更新,缩放,暂停/恢复,金丝雀发布等
RC功能较少,基本上不用
DaemonSet 此控制器指定一个节点上只运行一个pod副本,一般是用来运行系统的守护进程
job 运行完成即退出,执行一次性的任务
StatefulSet 用于运行管理有状态副本集
K8S快速入门
查看pod日志 ]# kubectl exec -it $(kubectl get pod -n zhiyi-system-test|grep "ai-live-dev"|awk '{print $1}') -n zhiyi-system-test -- tail -f /home/ailive-logs/gray/ailive_dao.2019-05-16.log ]# kubectl cluster-info //查看集群信息 Kubernetes master is running at https://192.168.64.110:6443 KubeDNS is running at https://192.168.64.110:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy master ~]# kubectl run nginx-deploy --image=nginx --port=80 --replicas=1 //创建一个副本数为1且名称为nginx-deploy 的对外暴露的端口(仅集群内部)为80的nginx镜像pod。 master ~]# kubectl get deployment //查看该控制器下启动的pod NAME READY UP-TO-DATE AVAILABLE AGE nginx-deploy 1/1 1 1 6m59s master ~]# kubectl get pods -o wide //查看默认名称空间下Pod运行的详细信息 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deploy-98c9d6c66-mbmrm 1/1 Running 0 9m45s 10.244.1.2 k8s-node1 <none> <none>
测试控制器维持副本数量
master ~]# kubectl delete nginx-deploy-98c9d6c66-mbmrm master ~]# kubectl get pods -o wide //可以看到pod已被调度器启动并调度到node2上且IP发生了改变 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deploy-98c9d6c66-gbm56 1/1 Running 0 7m12s 10.244.2.2 k8s-node2 <none> <none> service:由上面测试可以看到,当pod被重启IP地址会发生改变,应使用固定地址来访问pod。
控制器下所有的pod都托管到名称为nginx的service且pod端口80映射到service 80端口上
master ~]# kubectl expose deployment nginx-deploy --name=nginx --port=80 --target-port=80 --protocol=TCP master ~]# kubectl get svc //查看默认名称空间servie NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 26h nginx ClusterIP 10.99.80.100 <none> 80/TCP 21s master ~]# kubectl get pods -n kube-system //查看当前运行的DNS服务pod资源 NAME READY STATUS RESTARTS AGE coredns-6955765f44-sfptk 1/1 Running 5 3d16h coredns-6955765f44-xf9jt 1/1 Running 4 3d16h
master ~]# kubectl get svc -n kube-system //查看指定名称空间的service,DNS服务也有属于自己的service托管 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 26h //可以看到DNS的service地址为10.96.0.10 master ~]# kubectl run clientq --image=busybox:latest --replicas=1 -it --restart=Never //运行一个不重启的pod / # cat /etc/resolv.conf nameserver 10.96.0.10 //可以看到pod的DNS已自动配置为kube-dns 的10.96.0.10 search default.svc.cluster.local svc.cluster.local cluster.local master ~]# dig -t A nginx.default.svc.cluster.local @10.96.0.10 //解析service名称为nginx的地址 验证service功能,标签选择器,只需要访问service地址加端口即可 wget -O - -q http://nginx:80/ //访问service名称加端口即可访问到后端pod资源 master ~]# kubectl delete nginx-deploy-98c9d6c66-gbm56 //模拟故障 -master ~]# kubectl get pods //可以看到调取器已重新启动pod NAME READY STATUS RESTARTS AGE clientq 1/1 Running 0 46m nginx-deploy-98c9d6c66-n25dd 1/1 Running 0 85s
wget -O - -q http://nginx:80/ //再次通过service地址访问 master ~]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d16h nginx ClusterIP 10.99.8.143 <none> 80/TCP 2d12h //名称为nginx的service地址为10.99.8.143:80 master ~]# kubectl describe svc nginx //查看service名称为nginx的详细信息 Name: nginx Namespace: default Labels: run=nginx-deploy Annotations: <none> Selector: run=nginx-deploy //service以pod标签选择器来识别管理pod Type: ClusterIP //类型 IP: 10.99.80.100 Port: <unset> 80/TCP TargetPort: 80/TCP Endpoints: 10.244.1.6:80 //后端pod资源,pod被重启或被删除重建,改地址会改变 Session Affinity: None Events: <none> master ~]# kubectl get pods --show-labels //查看Pod标签信息 NAME READY STATUS RESTARTS AGE LABELS nginx-deploy-98c9d6c66-n25dd 1/1 Running 0 12m pod-template-hash=98c9d6c66,run=nginx-deploy //可以看到标签
总结:用户可以修改service地址或者service被重建后地址发生改变,修改后的地址可以自动反映到DNS中,无须修改DNS解析
-master ~]# kubectl delete svc nginx //模拟故障,svc重建 master ~]# kubectl expose deployment nginx-deploy --name=nginx --port=80 --target-port=80 --protocol=TCP //svc重建 -master ~]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx ClusterIP 10.99.8.143 <none> 80/TCP 14s //可以看到重建后的service地址发生了改变 进入另外一个容器测试 ]# kubectl exec -it busybox -n linux40 /bin/sh / # wget -O - -q http://nginx:80/ //使用service名称依然可以访问 控制器也是通过标签选择器来关联到Pod资源上 master ~]# kubectl describe deployment nginx-deploy Labels: run=nginx-deploy //通过标签选择器来维持副本的期望值
总结:我们不需要关注pod自身,只关注servie,service会生成一个iptatles或ipvs规则将访问service的地址和端口的请求通过标签选择器来调度到关联的各pod资源上。
Pod的扩展与缩进
master ~]# kubectl run nginx --image=nginx --replicas=2 //创建默认控制器为deploy的名称为nginx且副本数为2的pod。 master ~]# kubectl scale deploy nginx --replicas=5 //扩展副本数为5 master ~]# kubectl scale deploy nginx --replicas=3 //能扩展也能缩进,缩减副本数为3
pod的手动滚动更新
master ~]# kubectl set image deployment nginx nginx=nginx:v2
pod镜像版本回滚 master ~]# kubectl rollout undo deployment nginx deployment.apps/nginx rolled back 修改网络类型为NodePort master ~]# kubectl edit svc nginx ports: - nodePort: 31520 port: 80 protocol: TCP targetPort: 80 selector: run: nginx-deploy sessionAffinity: None type: NodePort //修改类型为节点网络
master ~]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx NodePort 10.99.8.143 <none> 80:31520/TCP 2d16h //可以看到端口已经随机映射到了节点的31520
此时只需要在节点前面做代理服务器即可访问到k8s集群内资源。
RS控制器使用
apiVersion: apps/v1 kind: ReplicaSet metadata: name: myapp namespace: default //定义命名空间 spec: replicas: 2 selector: matchLabels: app: myapp release: canary template: metadata: name: myapp-pod labels: app: myapp release: canary spec: containers: - name: myapp-container image: nginx:latest imagePullPolicy: IfNotPresent //镜像拉取策略,如镜像版本镜像升级且标签不发生变动,建议使用always ports: - name: http containerPort: 80
测试控制器-副本期望值
master yaml]# kubectl delete pods myapp-dhvfk master yaml]# kubectl get pods NAME READY STATUS RESTARTS AGE myapp-dhvfk 0/1 Terminating 0 5m47s //可以看到该控制器对pod资源删除时顺序为先创建新的再删除老的。 myapp-k7brb 1/1 Running 0 5m47s myapp-r6jmj 1/1 Running 0 7s master yaml]# kubectl get pods -o wide --show-labels //显示pod标签 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES LABELS myapp-k7brb 1/1 Running 0 25m 10.244.1.63 k8s-node1 <none> <none> app=myapp,release=canary myapp-r6jmj 1/1 Running 0 19m 10.244.2.60 k8s-node2 <none> <none> app=myapp,release=canary nginx 1/1 Running 0 17s 10.244.2.65 k8s-node2 <none> <none> <none> master yaml]# kubectl label pods nginx haha=myapp //为名为nginx的pod加上标签 master yaml]# kubectl label pods nginx release=canary // 为名为nginx的pod加上标签 master yaml]# kubectl get pods -o wide --show-labels //再次查看标签,副本期望值为2,多出来会被删掉 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES LABELS myapp-k7brb 1/1 Running 0 32m 10.244.1.63 k8s-node1 <none> <none> app=myapp,release=canary myapp-r6jmj 1/1 Running 0 26m 10.244.2.60 k8s-node2 <none> <none> app=myapp,release=canary nginx 0/1 Terminating 0 7m22s 10.244.2.65 k8s-node2 <none> <none> app=myapp,release=canary
注:生产环境标签尽量多而复杂,否则会出现pod资源匹配度高而导致pod资源被资源管理器乱删除。
注:service通过标签选择器来关联控制器创建的pod资源作为后端,service与控制器无任何关联关系,但不同控制器创建的pod资源可以被service以拥有相同标签来被关联作为后端。
RS 控制器的扩容和缩容
master yaml]# kubectl edit rs myapp apiVersion: apps/v1 kind: ReplicaSet metadata: creationTimestamp: "2020-04-06T07:50:19Z" generation: 2 name: myapp namespace: default resourceVersion: "474496" selfLink: /apis/apps/v1/namespaces/default/replicasets/myapp uid: a83d2a05-83a1-4d75-8041-9dfe35049dff spec: replicas: 5 //修改副本数,支持扩容和缩容 selector: matchLabels: app: myapp release: canary .........
RS 控制器的滚动更新
master yaml]# kubectl get rs -o wide NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR myapp 5 5 5 66m myapp-container nginx:latest app=myapp,release=canary master yaml]# kubectl edit rs myapp .... template: metadata: creationTimestamp: null labels: app: myapp release: canary name: myapp-pod spec: containers: - image: nginx:v1 //滚动更新镜像 imagePullPolicy: IfNotPresent name: myapp-container ..... master yaml]# kubectl get rs -o wide //可以看到RS控制器的镜像版本已被升级为v1版本 NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR myapp 5 5 5 68m myapp-container nginx:v1 app=myapp,release=canary
注:修改控制器的镜像版本,pod版本并不会立即升级,只有当pod资源重建才会重新加载RS控制器模板的镜像。
测试
master yaml]# kubectl delete pods myapp-6t4nn //删除一个pod,RS自动创建一个pod
master yaml]# kubectl describe pod myapp-8xll4 //查看pod详细信息,可以看到新建的pod镜像版本为v1
此方法可用户灰度发布(金丝雀发布) ,先发布一个新版本镜像pod,保留大部分老的镜像,当过段时间新版本测试无问题,在批量发布新版本的镜像。
蓝绿部署,基于deploment的滚动更新与回滚机制,deploment 运行在RS控制器的基础上
deployment 滚动更新过程如下
定义一个控制器
apiVersion: apps/v1 kind: Deployment metadata: name: myapp-deploy namespace: default spec: replicas: 5 selector: matchLabels: app: myapp releas: canary template: //模板 metadata: labels: app: myapp releas: canary spec: containers: - name: myapp image: nginx:v1 imagePullPolicy: IfNotPresent ports: - name: http containerPort: 80
修改副本期望值为3,滚动更新时,原先的旧版本RS控制器并不会随着pod被删除
apiVersion: apps/v1 kind: Deployment metadata: name: myapp-deploy namespace: default spec: replicas:3 selector: matchLabels: app: myapp releas: canary template: metadata: labels: app: myapp releas: canary spec: containers: - name: myapp image: nginx:v2 imagePullPolicy: IfNotPresent ports: - name: http containerPort: 80
master ~]# kubectl apply -f deploy-demo.yaml //滚动升级 master ~]# kubectl get rs -o wide //老版本的控制器并不会被删除,并且可以使用老版本的控制器回滚 NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR myapp-deploy-5484df784f 3 3 3 13m myapp nginx:v2 myapp-deploy-f476f4fcf 0 0 0 27m myapp nginx:v1 master ~]# kubectl patch deployment myapp-deploy -p '{"spec":{"replicas":5}}' //通过打补丁方式新增pod副本 master ~]# kubectl patch deployment myapp-deploy -p '{"spec":{"replicas":2}}' //能增也能减
通过打补丁方式设定控制器下pod滚动更新时最大不可用与最大激增
master ~]# kubectl patch deployment myapp-deploy -p '{"spec":{"strategy":{"rollingUpdate":{"maxSurge":1,"maxUnavailable":0}}}}'
金丝雀发布(灰度发布)过程
更新的暂停与回滚
1.升级指定控制器下pod的镜像版本,仅当更新一个pod版本后不删除原来pod并暂停更新剩余pod资源。 # master ~]# kubectl set image deployment myapp-deploy myapp=nginx:v2 && kubectl rollout pause deployment myapp-deploy # 低版本命令
kubectl set image deployment/secret-files secret-files=124.222.68.142:10006/k8s/busybox:1.28 && kubectl rollout pause deployment/secret-files
deployment.apps/secret-files image updated
deployment.apps/secret-files paused
2.待一段时间后确认没问题了,再执行批量滚动更新 master ~]# kubectl rollout resume deployment/myapp-deploy
3.查看pod运行情况与RS版本 master ~]# kubectl get pods master ~]# kubectl get rs -o wide
4.查看该控制器历史版本 master ~]# kubectl rollout history deployment myapp-deploy
5.回滚至指定版本 master ~]# kubectl rollout undo deployment myapp-deploy --to-revision=1 //指定版本回滚,不加默认上一个版本
6.再次查看,已回滚至指定版本 master ~]# kubectl get rs -o wide
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现