WorkLoad
控制器又称工作负载是用于实现管理pod的中间层,确保pod资源符合预期的状态,pod的资源出现故障时,会尝试 进行重启,当根据重启策略无效,则会重新新建pod的资源。
1.写配置文件
vi /opt/deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
namespace: demo
spec:
replicas: 1 #指定Pod副本数
selector: #指定Pod的选择器
matchLabels:
app: mysql
template:
metadata:
labels: #给Pod打label
app: mysql
spec:
hostNetwork: true
...
2.部署
kubectl create -f deploy.yaml
kubectl -n demo get deploy
#kubectl -n demo scale deploy myblog --replicas=2
添加副本
服务更新
kubectl -n demo apply -f deploy-myblog.yaml
kubectl -n demo edit deploy myblog
kubectl set image deploy myblog myblog=192.168.188.8:5000/myblog:v2 --record
更新策略
...
spec:
replicas: 2 #指定Pod副本数
selector: #指定Pod的选择器
matchLabels:
app: myblog
strategy:
rollingUpdate:
maxSurge: 25%
#最大激增数,计算时向上取整,更新过程中最多会有replicas + maxSurge个pod
maxUnavailable: 25%
#最多有几个pod处于无法服务状态
type: RollingUpdate #指定更新方式为滚动更新,默认策略,通过get deploy yaml查看
...
服务回滚
通过滚动升级的策略可以平滑的升级Deployment,若升级出现问题,需要最快且最好的方式回退到上一次能够提供正常工作的版本。为此K8S提供了回滚机制。
kubectl create -f deploy-myblog.yaml --record #记录回滚
kubectl -n demo rollout history deploy myblog #查看记录
kubectl -n demo rollout undo deploy myblog --to-revision=1 #回滚到具体REVISION
Kubernetes调度
NodeSelector
nodeSelector:
component: mysql
NodeAffinity
节点亲和性,分为两种,软策略和硬策略。软策略,若未满足,可忽略。硬策略,必须满足。
K8S操作符:
- In:在某个列表中
- NotIn:不在某个列表中
- Gt:大于某个值
- Lt:小于某个值
- Exists:存在
- DoesNotExist:不存在
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
#硬策略
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: NotIn
values:
- 192.168.136.128
- 192.168.136.132
preferredDuringSchedulingIgnoredDuringExecution:
#软策略
- weight: 1
preference:
matchExpressions:
- key: disktype
operator: In
values:
- ssd
- sas
污点与容忍
污点是Node的一个属性,设置了污点后,是不会将Pod调度到这个Node上的。同样给Pod设置了个属性容忍,只要Pod能够容忍Node上的污点,那么可把Pod调度过去。
污点设置
kubectl taint node [node_name] key=value:[effect]
#创建
其中[effect] 可取值: [ NoSchedule | PreferNoSchedule | NoExecute ]
NoSchedule:一定不能被调度。
PreferNoSchedule:尽量不要调度。
NoExecute:不仅不会调度,还会驱逐Node上已有的Pod。
示例:kubectl taint node slave1 smoke=true:NoSchedule
kubectl taint node [node_name] key=value:[effect]- #删除
Pod容忍污点示例
tolerations:
- key: "smoke"
operator: "Equal" #如果操作符为Exists,那么value属性可省略,不指定operator,默认为Equal
value: "true"
effect: "NoSchedule"
- key: "drunk"
operator: "Equal" #如果操作符为Exists,那么value属性可省略,不指定operator,默认为Equal
value: "true"
effect: "NoSchedule"
Service
Cluster IP
service是一组pod的服务抽象,相当于一组pod的LB,负责将请求分发给对应的pod。service会为这个LB提供一个IP,一般称为cluster IP 。使用Service对象,通过selector进行标签选择,找到对应的Pod。
1.写配置文件
vi /opt/svc_myblog.yaml
apiVersion: v1
kind: Service
metadata:
name: myblog
namespace: demo
spec:
ports:
- port: 80
protocol: TCP
targetPort: 8002
selector:
app: myblog
type: ClusterIP
2.部署
kubectl -n demo create -f svc-myblog.yaml
kubectl -n demo get svc #查看空间的ClusterIP
kubectl -n demo describe svc myblog #查看容器详情
NodePort
cluster-ip为虚拟地址,只能在k8s集群内部进行访问,集群外部如果访问内部服务,实现方式之一为使用NodePort方式。
apiVersion: v1
kind: Service
metadata:
name: myblog
namespace: demo
spec:
ports:
- port: 80
protocol: TCP
targetPort: 8002
selector:
app: myblog
type: NodePort
服务发现
组件之间可以通过定义的Service名称实现通信。
案例
vi /opt/mysql.yaml
#hostNetwork: true
vi /opt/configmap.yaml
data:
MYSQL_HOST: "mysql" # 此处ip替换为mysql
MYSQL_PORT: "3306"
kubectl -n demo apply -f configmap.yaml
kubectl -n demo apply -f mysql.yaml
Kube-proxy
运行在每个节点上,监听 API Server 中服务对象的变化,再通过创建流量路由规则来实现网络的转发。
- User space, 让 Kube-Proxy 在用户空间监听一个端口,所有的 Service 都转发到这个端口,然后 Kube-Proxy 在内部应用层对其进行转发 , 所有报文都走一遍用户态,性能不高,k8s v1.2版本后废弃。
- Iptables, 通过各个node节点上的iptables规则来实现service的负载均衡,但是随着service数量的增大,iptables模式由于线性查找匹配、全量更新等特点,其性能会显著下降。
- IPVS, 与iptables同样基于Netfilter,但是采用的hash表,因此当service数量达到一定规模时,hash查表的速度优势就会显现出来,从而提高service的服务性能。
iptables-save |grep "demo/mysql"
iptables-save |grep 'KUBE-SVC-EF7Z4L6MLBBDKFLJ'
iptables-save |grep 'KUBE-SEP-OEVU4IRXYVEBQBXB'
Ingress
实现七层的负载均衡,借助于Ingress,Ingress控制器的实现方式有很多,比如nginx, Contour, Haproxy, trafik, Istio。
安装
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
vi mandatory.yaml
hostNetwork: true #添加为host模式
nodeSelector:
ingress: "true" #替换此处,来决定将ingress部署在哪些机器
使用
kubectl create -f mandatory.yaml
vi /opt/ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: myblog
namespace: demo
spec:
rules:
- host: myblog.devops.cn
http:
paths:
- path: /
backend:
serviceName: myblog
servicePort: 80
kubectl create -f ingress.yaml