2.k8s常用的资源
孙富阳, 江湖人称没人称。多年互联网运维工作经验,曾负责过孙布斯大规模集群架构自动化运维管理工作。擅长Web集群架构与自动化运维,曾负责国内某大型博客网站运维工作。
1.pod资源
1.什么是pod
pod是最小资源单位.
任何的一个k8s资源都可以由yaml清单文件来定义
k8s yaml文件的主要组成
apiVersion: v1 api版本
kind: pod 资源类型
metadata: 属性
spec: 详细
2.创建一个pod资源
##创建yaml目录
[root@k8s-master ~]# mkdir k8s_yaml
[root@k8s-master ~]# cd k8s_yaml/
[root@k8s-master ~/k8s_yaml]# mkdir pod
[root@k8s-master ~/k8s_yaml]# cd pod/
[root@k8s-master ~/k8s_yaml/pod]# pwd
/root/k8s_yaml/pod
###编写yaml文件
[root@k8s-master ~/k8s_yaml/pod]# cat k8s_pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: web
spec:
containers:
- name: nginx
image: 10.0.0.11:5000/nginx:1.13
ports:
- containerPort: 80
####这里用nginx1.13是为了后面演示滚动升级
###创建并检查pod资源
[root@k8s-master ~/k8s_yaml/pod]# kubectl create -f k8s_pod.yaml
pod "nginx" created
[root@k8s-master ~/k8s_yaml/pod]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx 0/1 ContainerCreating 0 1m
###下载nginx镜像并上传至私有镜像仓库
[root@k8s-master ~/k8s_yaml/pod]# cd
[root@k8s-master ~]# docker pull nginx:1.13
[root@k8s-master ~]# docker tag docker.io/nginx:1.13 10.0.0.11:5000/nginx:1.13
[root@k8s-master ~]# docker push 10.0.0.11:5000/nginx:1.13
###这时候发现pod资源的容器还是没有启动
并且kubectl get pod -o wide查看被调度到了10.0.0.13这台机器

###查看一下资源的状态,是在哪一步被卡主了kubectl describe pod nginx

####查看一下不存在的文件到底在不在

###那现在不下载软件包,又需要下载红帽的那个容器怎么办
先把镜像pull下来然后上传到自己的私有仓库
[root@k8s-master ~]# docker pull tianyebj/pod-infrastructure
[root@k8s-master ~]# docker tag docker.io/tianyebj/pod-infrastructure:latest 10.0.0.11:5000/sunfuyang/pod-infrastructure:latest
[root@k8s-master ~]# docker push 10.0.0.11:5000/sunfuyang/pod-infrastructure:latest
####那为什么谷歌的k8s会去redhat下载镜像呢

所以需要修改这里的配置文件将红帽的网址替换为私有仓库的地址,然后重启k8s
[root@k8s-node02 ~]# systemctl restart kubelet.service
##再次回到master查看,发现已经运行起来了

###查看node节点的docker镜像和容器,发现多了两个镜像和两个容器

3.pod资源是什么
###为什么pod创建的nginx容器没有ip
我们能通过172.18.28.2ping通nginx容器,但是nginx容器的ip地址确是空的

那为什么还能访问到nginx容器呢?是因为使用的是docker四种网络类型中的container网络类型
Pod容器不占用端口,所以访问任何端口都不会和nginx容器冲突
每跑一个pod资源,都会起一个pod容器

那为什么要起一个pod容器呢
可以简单的理解为自动发现容器,pod容器相当于k8s客户端,会向服务端通知,新加了一个容器。也是为了实现k8s的高级功能。
Pod容器占用资源非常少还不到1M
所以每创建一个pod资源都至少起两个容器

Pod创建两个容器
pod资源:至少由两个容器组成,pod基础容器和业务容器组成(最多1+4)
pod配置文件2:
[root@k8s-master ~/k8s_yaml/pod]# cat k8s_pod2.yaml
apiVersion: v1
kind: Pod
metadata:
name: test
labels:
app: web
spec:
containers:
- name: nginx
image: 10.0.0.11:5000/nginx:1.13
ports:
- containerPort: 80
- name: alpine
image: 10.0.0.11:5000/alpine:latest
command: ["sleep","1000"]
####注意,他们是公用网络的。要避免两个容器间的通讯是本地地址127
如何进入到进入pod容器
kubectl exec -it pod_name /bin/bash###还可以加-c参数指定进入那个容器
2.ReplicationController资源(新版本已被弃用)
1.什么是rc
rc:保证指定数量的pod始终存活,rc通过标签选择器来关联pod
2.k8s资源的常见操作
kubectl create -f xxx.yaml
kubectl get pod|rc
kubectl describe pod nginx
kubectl delete pod nginx 或者kubectl delete -f xxx.yaml
kubectl edit pod nginx
kubectl apply -f xxx.yaml
3.创建一个rc
创建k8s_rc1.yaml文件
[root@k8s-master ~]# mkdir -p k8s_yaml/rc
[root@k8s-master ~]# cd k8s_yaml/rc
[root@k8s-master ~/k8s_yaml/rc]# cat k8s_rc1.yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: nginx###相同类型资源名字不能相同
spec:
replicas: 5##副本数
selector:##标签选择器
app: myweb
template:
metadata:
labels:
app: myweb
spec:
containers:
- name: myweb
image: 10.0.0.11:5000/nginx:1.13
ports:
- containerPort: 80
[root@k8s-master ~/k8s_yaml/rc]# kubectl create -f k8s_rc1.yaml
检查一下创建的结果

第一列名字,第二列期望数,就是配置文件里replicas的数量,第三列是已创建的数,第四列是已运行数。
可以看到pod资源被均匀的分配到不同的节点,并且pod资源名字也是随机的
Rc对容器的故障恢复
删除一个pod资源会怎么样
[root@k8s-master ~/k8s_yaml/rc]# kubectl delete pod nginx-1zpdh

node节点故障了怎么办?
[root@k8s-node01 ~]# systemctl stop kubelet.service
等待一会,master发现node1节点没了,会自动迁移pod资源至node2

明显看到node1节点已经挂了,但是pod资源没有被迁移,这是因为有时间间隔,为了加快速度,可以进行监控,当node节点找不到了,就从master中移除节点,这样就会立刻迁移pod资源了
[root@k8s-master ~/k8s_yaml/rc]# kubectl delete node 10.0.0.12

RC不同RC的selector能不能一样?(lable标签的作用)

Rc之间会不会出现如上图所示情况
rc1管理的是5个pod资源,但是rc2是3个,当rc2发现rc1拉起5个pod会杀死两个pod资源。杀死之后,又不满足rc1的期望了,又会拉起2个pod资源,如此往复,很麻烦
所以体现了标签的重要性
[root@k8s-master ~/k8s_yaml/rc]# kubectl edit pod nginx修改标签
可以看到标签改了之后pod被杀死了一个
所以rc通过标签选择器(selector)来识别pod资源是否归自己管

4.rc的滚动升级
[root@k8s-master rc]# cp k8s_rc1.yaml k8s_rc2.yaml
[root@k8s-master rc]# cat k8s_rc2.yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: nginx
spec:
replicas: 5
selector:
app: myweb2
template:
metadata:
labels:
app: myweb2
spec:
containers:
- name: myweb2
image: k8s-master:5000/sunfuyang/nginx:1.15
ports:
- containerPort: 80

升级 kubectl rolling-update nginx -f k8s_rc2.yaml --update-period=1s
回滚 kubectl rolling-update nginx2 -f k8s_rc1.yaml --update-period=1s
3.service资源
1.什么是svc

如上图所示,Service是一组Pod提供负载均衡,对外提供统一访问入口。Pod和Service的关系如下所示:
(1)service通过标签关联一组Pod;
(2)service使用iptable或者ipvs为一组Pod提供负载均衡能力;
service的引入主要解决Pod的动态变化,提供统一的访问入口。service主要提供以下两个功能:
(1)防止Pod失联,准备找到提供同一个服务的Pod(服务发现);
(2)定义一组Pod的访问策略(负载均衡);
service的工作流程图如下图所示。我们大致总结以下service的工作流程:
(1)当client访问工作节点的service时,首先他会根据iptables/ipvs规则做相应的负载均衡策略找到后端的Pod以提供服务;
(2)其中iptables/ipvs的规则是由kube-proxy组件来实现的;
(3)kubelet会实时监控对应工作节点的Pod信息;
生产环境在使用iptables和ipvs的对比
iptables:
(1)灵活,功能强大;
(2)规则从上至下遍历匹配和更新,因此在集群规模过大时,可能缺点就越明显,因为每次都需要遍历大量的规则;
ipvs:
(1)工作在内核态,有更好的性能;
(2)调度算法丰富:"rr","wrr","lc","wlc","ip hash"等;
综上所述,推荐大家在生产环境中使用"ipvs"模式。k8s 1.8+版本中推荐使用lvs(四层负载均衡 传输层tcp,udp),在早期版本中,默认使用的是iptables规则哟
2.创建一个svc资源
创建k8s_svc1.yaml文件
[root@k8s-master k8s_yaml]# mkdir svc
[root@k8s-master k8s_yaml]# cd svc/
[root@k8s-master svc]# cat k8s_svc.yaml
apiVersion: v1
kind: Service #简称svc
metadata:
name: myweb
spec:
#clusterIP: 10.254.86.101 ##指定svc的IP地址
type: NodePort #默认ClusterIP
ports:
- port: 80 #clusterIP
nodePort: 30000 #node port
targetPort: 80 #pod port
selector:
app: myweb2
[root@k8s-master svc]# kubectl create -f k8s_svc.yaml
检查一下创建的结果


可以看到svc通过标签关联了pod,同时两个节点都可以访问到资源
修改副本数量,并观察对应service的Endpoints信息变化
kubectl scale rc nginx --replicas=2 #调整rc的副本书
kubectl exec -it pod_name /bin/bash #进入pod容器
3.修改nodePort范围
vim /etc/kubernetes/apiserver
KUBE_API_ARGS="--service-node-port-range=3000-60000"
4.命令行创建svc资源
kubectl expose rc nginx --type=NodePort --port=80
service默认使用iptables来实现负载均衡, k8s 1.8新版本中推荐使用lvs(四层负载均衡 传输层tcp,udp)
5.service资源常用的类型
ClusterIP类型
默认的类型,分配一个稳定的IP地址,即VIP,只能在集群内部访问。换句话说,适用于K8S集群内部,这意味着k8s集群外部将无法访问到
NodePort类型
适用于对K8S集群外部暴露应用,会在每个节点上启用一个端口来暴露服务,可以在集群外部访问。也会分配一个稳定内部集群IP地址。
LoadBalancer类型
适合在公有云上对K8S集群外部暴露应用。
与NodePort类似,在每个节点上启用一个端口来暴露服务。除此之外,kubernetes会请求底层云平台(例如阿里云,腾讯云,AWS等)上的负载均衡器,将每个Node(<NodeIP>:<NodePort>)作为后端添加进去
4.deployment资源
1.什么是deployment
有rc在滚动升级之后,会造成服务访问中断。这是因为基于rc滚动升级时其对应的Pod标签会发生变化,想要快速恢复业务,则需要人工手动修改"svc"资源管理的pod标签。这个过程尽管您的手速再快也是会在短时间内造成服务的中断。
综上所述,于是k8s引入了deployment资源。Deployment是最常见的控制器,用于更高级部署和管理Pod。
Deployment功能:
(1)管理ReplicaSet,通过RS资源管理Pod;
(2)具有上线部署,副本设定,滚动升级,回滚等功能;
(3)提供声明式更新(换句话说,就是告诉deployment资源更新什么内容),例如只更新一个新的Image;
应用场景: 网站,API,微服务等
2.基于deployment部署Pod并进行资源限制
[root@k8s-master k8s_yaml]# mkdir deployment
[root@k8s-master k8s_yaml]# cd deployment/
[root@k8s-master deployment]# cat k8s_deployment1.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 3
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
type: RollingUpdate
minReadySeconds: 30
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: k8s-master/sunfuyang/nginx:1.13
ports:
- containerPort: 80
resources: ###资源
limits: ###资源限制
cpu: 100m
memory: 10M
requests: ###资源需求
cpu: 100m
memory: 10M
[root@k8s-master deployment]# kubectl create -f k8s_deployment1.yaml
[root@k8s-node-2 ~]# docker container stats --no-stream
可以很明显的看到新创建的pod资源被限制了

3.基于命令行的方式对deplpyment资源进行滚动升级和回滚
命令行升级版本
[root@k8s-master svc]# kubectl set image deploy nginx nginx=k8s-master:5000/sunfuyang/nginx:1.13
###nginx=xxx 这个nginx是容器的名字
查看deployment所有历史版本
kubectl rollout history deployment nginx
回滚到上一个版本
kubectl rollout undo deployment nginx
回滚到指定版本
kubectl rollout undo deployment nginx --to-revision=2
4.deplpyment资源yaml文件指定升级策略
[root@k8s-master deployment]# cat k8s_deployment2.yaml
apiVersion: extensions/v1beta1 # 注意观察这个API的版本编号哟~在后期的版本中其是有变化的!
kind: Deployment
metadata:
name: nginx
spec:
replicas: 5 # 指定启动Pod的副本数。
strategy: # 指定滚动升级策略
rollingUpdate:
maxSurge: 2 # 在原有的Pod基础上,多启动Pod的数量,假设原来待升级的Pod数量为5,如果我们该值设置为2,表示同时允许启动5 + 2个容器数量。 注意哈,我们也可以指定百分比哟~
maxUnavailable: 1 # 指定最大不可用的Pod数量,如果我们设置该值为1,很明显,副本数为5,表示最少要有4个Pod是可用的。
type: RollingUpdate # 滚动升级
minReadySeconds: 30 # 指定Pod升级的间隔时间,以秒为单位。
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: k8s-master:5000/sunfuyang/nginx:1.15
ports:
- containerPort: 80
resources:
limits:
cpu: 100m
memory: 10M
requests:
cpu: 100m
memory: 10M
[root@k8s-master deployment]# kubectl apply -f k8s_deployment2.yaml
5.deplpyment资源和rc资源的区别
共同点:
(1)可以控制Pod数量;
(2)都可以滚动升级;
(3)通过标签选择器关联Pod;
不同点:
(1)rc升级需要yaml文件(如果在使用者修改了文件内容会造成不必要的麻烦),deployment修改配置文件可以实时生效(直接在命令行使用"kubectl edit deployment nginx"案例);
(2)rc升级会导致服务中断(需要手动修改service的标签),而deployment升级并不会中断服务访问;
(3)rc直接控制Pod,而deployment基于rs来控制Pod;
5.daemonset资源
1.什么是daemonset
DaemonSet功能概述:
(1)在每一个Node上运行一个pod;
(2)新加入的Node也同样会自动运行一个Pod;
应用场景:
(1)网络插件(例如kube-proxy,colico);
(2)zabbix agent;
(3)node_export;
(4)日志收集端,例如filebeat;
温馨提示:
(1)DaemonSet不支持副本设置哟,其特点是在所有不含污点的工作节点上只运行一个Pod,如果配置了污点容忍也可以在被打污点的工作节点上运行哟;
(2)DaemonSet也支持滚动更新,但是没必要设置更新策略
2.创建一个daemonset资源
[root@k8s-master k8s_yaml]# mkdir daemonset
[root@k8s-master k8s_yaml]# cd daemonset/
[root@k8s-master daemonset]# cat k8s_DaemonSet.yaml
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
name: nginx-ds
spec:
template:
metadata:
labels:
app: nginx-ds
spec:
containers:
- name: nginx-ds
image: k8s-master:5000/sunfuyang/nginx:1.13
ports:
- containerPort: 80
resources:
limits:
cpu: 100m
memory: 10M
requests:
cpu: 100m
memory: 10M
[root@k8s-master daemonset]# kubectl apply -f k8s_DaemonSet.yaml
下图可以看到虽然没有定义副本数,但是每个节点都有pod

未经允许不得转载:孙某某的运维之路 » 2.k8s常用的资源
评论已关闭