第二章 K8S基础操作笔记
一、K8S基础操作1、kubernetes卸载与docker卸载1.1、docker卸载查询安装情况yum list installed | grep dockercontainerd.io.x86_64 1.2.13-3.1.el7 @docker-ce-stabledocker-ce.x86_64 ...
一、K8S基础操作
1、kubernetes卸载与docker卸载
1.1、docker卸载
查询安装情况
yum list installed | grep docker
containerd.io.x86_64 1.2.13-3.1.el7 @docker-ce-stable
docker-ce.x86_64 3:19.03.5-3.el7 @docker-ce-stable
docker-ce-cli.x86_64 1:19.03.5-3.el7 @docker-ce-stable
卸载docker
yum -y remove docker-ce-cli.x86_64
yum -y remove containerd.io.x86_64
删除镜像/容器等
rm -rf /var/lib/docker
rm -rf /var/run/docker
1.2、kubernetes卸载
kubernetes安装:
yum install -y kubelet-1.16.4 kubeadm-1.16.4 kubectl-1.16.4
卸载kubernetes
查看安装组件:yum list installed | grep kube*
cri-tools.x86_64 1.13.0-0 @kubernetes
kubeadm.x86_64 1.16.4-0 @kubernetes
kubectl.x86_64 1.16.4-0 @kubernetes
kubelet.x86_64 1.16.4-0 @kubernetes
kubernetes-cni.x86_64 0.7.5-0 @kubernetes
删除:
yum -y remove kubelet.x86_64
yum -y remove kubeadm.x86_64
yum -y remove kubectl.x86_64
yum -y remove kubernetes-cni.x86_64
首先清理运行到k8s群集中的pod,使用,
kubectl delete node --all
然后从主机系统中删除数据卷和备份(如果不需要)。最后,可以使用脚本停止所有k8s服务,
for service in kube-apiserver kube-controller-manager kubectl kubelet kube-proxy kube-scheduler; do
systemctl stop $service
done
yum -y remove kubernetes #if it's registered as a service
2、kubectl的命令用法
可以借助kubectl -h命令学习用法,下面介绍常用的一些命令使用:
重启kubelet:
systemctl daemon-reload
systemctl restart kubelet
get | 获取列出一个或多个资源的信息。(资源分为pod、instance、service等很多种) |
describe | 输出指定的一个/多个资源的详细信息。(一般describe状态有问题节点,如Pending等) |
logs | 输出pod中一个容器的日志。(如果pod只包含一个容器则可以省略容器名) |
create | 指定Yaml或Json,创建资源。(通过文件或者控制台输入) |
delete | 删除一个资源(可以是pod、instance等) |
exec | 在容器内部执行命令 |
Rolling-update | 执行指定ReplicationController的滚动更新。(不中断业务的更新方式) |
2.1、kubectl run创建一个应用程序
kubectl run nginx-dep --image=nginx:1.7.9 --port=80 --replicas=2 --dry-run
可以先测试:--dry-run
正式创建,查看状态:
创建命令:kubectl run nginx-dep --image=nginx:1.7.9 --port=80 --replicas=2
查看服务信息:
kubectl get pods -o wide #获取pod的信息,-o wide表示更详细的显示信息
看到系统里启动了两个pod服务(运行nginx),分别运行在节点node2和node3上。
测试nginx服务,服务ok
2.2、探究pod详情:
执行命令:
kubectl describe pod nginx-dep-5779c9d6c9-dswhg
进入容器查看:
格式:kubectl exec -it podName -c containerName -n namespace -- shell comand
命令:kubectl exec -it nginx-dep-5779c9d6c9-dswhg -c nginx-dep /bin/bash
[root@bogon ~]# kubectl exec -it nginx-dep-5779c9d6c9-dswhg -c nginx-dep /bin/bash
root@nginx-dep-5779c9d6c9-dswhg:/# whereis nginx
nginx: /usr/sbin/nginx /etc/nginx /usr/share/nginx
root@nginx-dep-5779c9d6c9-dswhg:/#
2.3、暴露服务到外网
将pod创建完成后,访问该pod内的服务只能在集群内部通过pod的的地址去访问该服务;当该pod出现故障后,该pod的控制器会重新创建一个包括该服务的pod;此时访问该服务须要获取该服务所在的新的pod的地址ip去访问。
#删除当前的pod:
kubectl delete pods pods-nginx-7d748784f5-pnprd
如何保持pod的故障恢复,对调用者无影响呢?
可以创建一个service,当新的pod的创建完成后,service会通过pod的label连接到该服务,只需通过service即可访问该服务。
查看svc的label配置
上述方式,虽然能够通过service访问到pod服务。但在集群外部,是无法访问到的,如在本地windows机器上,想要访问到nginx服务,网络是不通的。我们可以修改service的类型的NodePort。
命令:kubectl edit svc nginx-svc
查看绑定端口:
在外部可以通过node节点的地址及该端口访问pod内的服务。
2.4、服务的伸缩
Pod创建完成后,当服务的访问量过大时,可以对pod的进行扩展让pod中的服务处理更多的请求;当访问量减小时,可以缩减pod数量,以节约资源。这些操作都可以在线完成,并不会影响现有的服务。
命令:kubectl scale --replicas=3 deployment nginx-dep
2.5、服务的在线升级与回滚
在kubernetes服务中部署完服务后,对服务的升级可以在线完成,升级出问题后也可以在线完成回滚。
查看镜像命令:kubectl describe pod ‘images name’
可以看到滚动更新的过程:
kubectl set image deployment nginx-dep nginx-dep=nginx:1.19.1
kubectl get pod -w ##w参数是watch,持续执行,并观察改变
再次查看镜像版本
还可以再回滚回原来的版本:
kubectl rollout undo deployment nginx-dep
查看版本,又回到1.7.9的版本
2.6、常用命令总结
- kubectl annotate – 更新资源的注解。
- kubectl api-versions – 以“组/版本”的格式输出服务端支持的API版本。
- kubectl apply – 通过文件名或控制台输入,对资源进行配置。
- kubectl attach – 连接到一个正在运行的容器。
- kubectl autoscale – 对replication controller进行自动伸缩。
- kubectl cluster-info – 输出集群信息。
- kubectl config – 修改kubeconfig配置文件。
- kubectl create – 通过文件名或控制台输入,创建资源。
- kubectl delete – 通过文件名、控制台输入、资源名或者label selector删除资源。
- kubectl describe – 输出指定的一个/多个资源的详细信息。
- kubectl edit – 编辑服务端的资源。
- kubectl exec – 在容器内部执行命令。
- kubectl expose – 输入replication controller,service或者pod,并将其暴露为新的kubernetes service。
- kubectl get – 输出一个/多个资源。
- kubectl label – 更新资源的label。
- kubectl logs – 输出pod中一个容器的日志。
- kubectl namespace -(已停用)设置或查看当前使用的namespace。
- kubectl patch – 通过控制台输入更新资源中的字段。
- kubectl port-forward – 将本地端口转发到Pod。
- kubectl proxy – 为Kubernetes API server启动代理服务器。
- kubectl replace – 通过文件名或控制台输入替换资源。
- kubectl rolling-update – 对指定的replication controller执行滚动升级。
- kubectl run – 在集群中使用指定镜像启动容器。
- kubectl scale – 为replication controller设置新的副本数。
- kubectl stop – (已停用)通过资源名或控制台输入安全删除资源。
- kubectl version – 输出服务端和客户端的版本信息。
参考地址:
https://www.jianshu.com/p/2ded3a8cc788
https://www.kubernetes.org.cn/doc-45
备注:补全命令安装:
yum -y install bash-completion
source /etc/profile.d/bash_completion.sh
3、YAML文件管理资源
K8s两种创建资源的方式:
- 用kubectl命令的方式直接创建:比如前面的创建deployment
- 通过配置文件和kubectl apply创建,正式的使用,一般采用第二种方式
3.1、资源清单的格式:
apiVersion: extensions/v1beta1 # 配置格式的版本
kind: Deployment # 创建的资源类型,这里是deployment
metadata: # 元数据
name: nginx-deployment # name是必须的元数据
namespace #k8s自身的namespace
annotations #主要目的是方便用户阅读查找
spec: # spec是Deployment的规格说明
replicas: 2 # 副本数量
template: # Pod的模板
metadata: # Pod的元数据,至少要定义label
labels:
app: web_server # label的key和value可以随意指定
spec: # Pod的规格,定义Pod中容器的属性,name和image必填
containers:
- name: nginx
image: nginx:1.7.9
status:当前状态,本字段有kubernetes自身维护,用户不能去定义
资源类型:
Pod、ReplicaSet、Deployment、StatefulSe、DaemonSet、Job、Service、Ingress
- 缩进表示层级关系
- 不支持制表符“tab”缩进,使用空格缩进
- 通常开头缩进2 个空格
- 字符后缩进1 个空格,如冒号、逗号等
- “---” 表示YAML格式,一个文件的开始
- “#”注释
3.2、创建deployment
查看文件内容:vi nginx-deployment.yaml
apiVersion: apps/v1 # 配置格式的版本
kind: Deployment # 创建的资源类型,这里是deployment
metadata: # 元数据
name: nginx-deployment
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
此文件定义内容,效果与上一节中的命令方式相同。但配置更为详尽
#使用create子命令以yaml文件的方式启动
创建命令:
kubectl create -f nginx-deployment.yaml
3.3、扩容伸缩
将配置参数replicas: 2改为replicas: 3即可
然后使用kubectl apply生效:
kubectl apply -f nginx-deployment.yaml
3.4、获取资源的apiVersion版本及资源配置的帮助
k8s中可以使用kubectl api-versions获取当前k8s版本上所有的apiVersion版本信息(每个版本可能不同)
[root@bogon k8sconfig]# kubectl explain pod
KIND: Pod
VERSION: v1
执行命令:kubectl explain Ingress
[root@bogon k8sconfig]# kubectl explain Ingress
KIND: Ingress
VERSION: extensions/v1beta1
可以看到出来,不同的资源属于不同的apiVersion版本,你还可以查看资源的配置清单的二级级别的字段。执行命令:
kubectl explain pod.metadata
查看二级字段中有哪些三级字段
查看命令:
kubectl explain pod.metadata.labels
3.5、使用service提供外部访问
命令:vim nginx-svc.yaml
[root@bogon k8sconfig]# cat nginx-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service
labels:
app: nginx
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
selector:
app: nginx
创建命令:
kubectl create -f nginx-svc.yaml
浏览器访问http://192.168.30.161:31234/ 正常ok
二、k8s资源操作
1、Pod控制器(kube-controller-manager)
kube-controller-manager是Kubernetes的大脑,它通过apiserver监控整个集群的状态,并确保集群处于预期的工作状态。
1.1、ReplicaSets控制器
k8s中最初有个Replication Controller ,它保证了在所有时间内,都有特定数量的Pod副本正在运行,如果太多了,Replication Controller就杀死几个,如果太少了,Replication Controller会新建几个,和直接创建的pod不同的是,Replication Controller会替换掉那些删除的或者被终止的pod,不管删除的原因是什么(维护阿,更新啊,Replication Controller都不关心)。基于这个理由,我们建议即使是只创建一个pod,我们也要使用Replication Controller。
Replication Controller 就像一个进程管理器,监管着不同node上的多个pod,而不是单单监控一个node上的pod,Replication Controller 会委派本地容器来启动一些节点上服务(Kubelet ,Docker)。对于服务和用户来说,Replication Controller是通过一种无形的方式来维持着服务的状态
ReplicaSet是加强版的Replication Controller,其功能只是扩展了Replication Controller的selector,支持基于集合的selector(version in (v1.0, v2.0)或env notin (dev, qa)),K8s中一般我们不再使用Replication Controller。
1.2、Deployment控制器
Deployment为Pod和Replica Set(下一代Replication Controller)提供声明式更新。意思就是,Replica Set一是在Deployment里使用的。你只需要在Deployment中描述你想要的目标状态是什么,Deployment controller就会帮你将Pod和Replica Set的实际状态改变到你的目标状态。你可以定义一个全新的Deployment,也可以创建一个新的替换旧的Deployment。
典型的用法:
1)使用Deployment来创建ReplicaSet。ReplicaSet在后台创建pod。检查启动状态,看它是成功还是失败。
2)然后,通过更新Deployment的PodTemplateSpec字段来声明Pod的新状态。这会创建一个新的ReplicaSet,Deployment会按照控制的速率将pod从旧的ReplicaSet移动到新的ReplicaSet中。
3)如果当前状态不稳定,回滚到之前的Deployment revision。每次回滚都会更新Deployment的revision。
4)扩容Deployment以满足更高的负载。
5)暂停Deployment来应用PodTemplateSpec的多个修复,然后恢复上线。
6)根据Deployment 的状态判断上线是否hang住了。
7)清除旧的不必要的ReplicaSet。
文件nginx-deployment.yaml内容如下:
apiVersion: apps/v1 # 配置格式的版本
kind: Deployment # 创建的资源类型,这里是deployment
metadata: # 元数据
name: nginx-deployment
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
示例:
kubectl create -f nginx-deployment.yaml
1.3、DaemonSet
DaemonSet保证在每个Node上都运行一个容器副本,常用来部署一些集群的日志、监控或者其他系统管理应用。k8s内部就启用了这个,一般运维监控才用到它。日志收集,系统监控等
系统程序,比如kube-proxy, kube-dns, glusterd, ceph等都是DaemonSet
1.4、StatefulSet
StatefulSet是为了解决有状态服务的问题(对应Deployments和ReplicaSets是为无状态服务而设计),我们后续讲完了K8s存储后,再回头来讲它的使用
1.5、Job控制器
Job控制器用于调配pod对象运行一次性任务,容器中的进程在正常运行结束后不会对其进行重启,而是将pod对象置于completed状态。若容器中的进程因错误而终止,则需要依据配置确定重启与否,未运行完成的pod对象因其所在的节点故障而意外终止后会被重新调度。
job控制器对象有两种:
1)单工作队列的串行式job:
即以多个一次性的作业方式串行执行多次作业,直至满足期望的次数
job-single.yaml任务内容:
apiVersion: batch/v1 # 配置格式的版本
kind: Job # 创建的资源类型,这里是deployment
metadata: # 元数据
name: job-single
namespace: default
spec:
template:
spec:
containers:
- name: singlejob
image: alpine
command: ["/bin/sh","-c","echo 123456"] # 任务为打印一个字符串
restartPolicy: Never
执行命令运行pod:
kubectl create -f job-single.yaml
查看pod的运行日志:
kubectl logs job-single-t217h
2)多工作队列的并行式job:
这种方式可以设置工作队列数,即作业数,每个队列仅负责运行一个作业。
job-multi.yaml文件内容:
apiVersion: batch/v1 # 配置格式的版本
kind: Job # 创建的资源类型,这里是deployment
metadata: # 元数据
name: job-multi
namespace: default
spec:
completions: 10 #执行次数
parallelism: 2 #并行个数
template:
spec:
containers:
- name: multijob
image: alpine
command: ["/bin/sh","-c","echo many jobs"] # 任务内容
restartPolicy: Never
执行命令前先删除前面创建的容器,避免内存不够用,查看命令:
kubectl get deployment --得到容器name
删除命令:
kubectl delete deployment ‘容器name’
然后创建多任务job:
kubectl create -f job-multi.yaml
此任务运行后,查看其执行的pod个数
2、Pod的调度
在k8s中当定义某个Pod对象时,若没有特定调度规则设定,则k8s本身会调用GenericScheduler通过预选优选算法来为该Pod选择一个最优Node节点,即最终Node节点是谁是不确定的。例如,我们前面经常用一deployment的过程:
比如这个创建:create -f nginx-deployment.yaml
查看其中一个pod的事件列表,第一步都是计算调度的assigned决定:
但在实际工作中,我们可能需要指向性地将某个Pod定向调度到某个Node中,K8s为我们准备了几种方式来实现这种需求。
2.1、NodeName强制约束
我们可以使用NodeName指定,来强制约束pod要在某个node上运行
1)文件内容pod-nodename.yaml:
apiVersion: v1
kind: Pod
metadata:
name: pod-nginx
labels:
app: nginx #给自己打上标签
spec:
nodeName: work2 #强制匹配 指定node要到work2上面运行
containers: #创建了两个容器
- name: nginx
image: nginx:1.7.9
2)创建命令:
kubectl create -f pod-nodename.yaml
实际上,这种node的指定是强制的,是直接取消掉的k8s的调度计算的
查看pod的事件列表:
kubectl describe pod pod-nginx
2.2、NodeSelector定向调度
通过kubernetes的label-selector机制进行节点选择,由scheduler调度策略MatchNodeSelector进行label匹配,调度pod到目标节点,该匹配规则是强制约束,使用示例如下:
1)给目标node打上一些标签,示例如下:
给资源打标签:设置work1 like=north,work2 like=sourth
kubectl label nodes work1 like=north
kubectl label nodes work2 like=sourth
查看Label标签:
kubectl get pods --show-labels
注意:添加标签后面的内容是以key-value的形式放的,如果已存在删除方式为:key-
查看结果:kubectl get pods --show-labels
其实就是为work2节点加一个属性,key和value值都随意
删除这个属性,只需要将key紧接一个“-”字符即可
kubectl label nodes work2 like-
2)在pod的定义加上nodeSelector设置(pod的偏向喜好)
示例文件pod-nodesel.yaml内容:
apiVersion: v1
kind: Pod
metadata:
name: pod-nginx
labels:
app: nginx #给自己打上标签
spec:
containers: #创建了两个容器
- name: nginx
image: nginx:1.7.9
nodeSelector: # 设置容器创建在有标签south的节点上
like: south
运行这个pod,看它是否能得偿所愿
kubectl create -f pod-nodesel.yaml
注意:
创建的容器冲突了最好先删除前面创建好的,然后在新建
kubectl get deploy
kubectl delete deploy nginx-dep
[root@leader k8sconfig]# kubectl get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-dep 2/2 2 2 45m
[root@leader k8sconfig]# kubectl delete deploy nginx-dep
deployment.apps "nginx-dep" deleted
2.3、NodeAffinity调度
NodeSelector调度算法比较简单,只是调度pod到某个拥有特定标签的Node上。而现实世界复杂的多,我们需要的是一系列的策略来决定,于是NodeAffinity出场,扩展了策略
NodeAffinity亲和性有两种表达方式:
RequiredDuringSchedulingIgnoredDuringExecution:必须满足指定的规则才可以调度Pod到Node上,相当于硬限制。
PreferredDuringSchedulingIgnoredDuringExecution:强调优先满足指定的规则,相当于软限制,并不强求。
示例:pod-nodeaff.yaml
运行尝试,查验结果:
PreferredDuringSchedulingIgnoredDuringExecution的用法,依次类推,希望你能举一反三。此外,此使用匹配语法灵活,你完全可以配出一系列实际效果,如pod节点的互斥性等等
3、K8S的label作用
我们在上述的章节中,看到了k8s中一个特殊的存在:label,在这里特别强调一下:
标签是一种简单却又功能强大的kubernetes特性,不仅可以组织pod,也可以组织所有其他的kubernetes资源,标签是可以附加到资源的任意键值对,用以选择具有该确切标签的资源,只要标签的key在资源内是唯一的,一个资源便可以拥有多个标签。
k8s除了使用标签来控制pod的调度之外,还有两个功能,也是使用label来实现的。
3.1、deploy控制器通过label找到对应控制的pods集群
文件nginx-deployment.yaml内容:
apiVersion: apps/v1 # 配置格式的版本
kind: Deployment # 创建的资源类型,这里是deployment
metadata: # 元数据
name: nginx-deployment
namespace: default
spec:
replicas: 3
selector:
matchLabels: #deployment是通过匹配label--app,来对应pod控制器的
app: nginx
template:
metadata:
labels: #deployment是通过匹配label--app,来对应pod控制器的
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
3.2、Service与Pod
Service通过label来绑定port到对应的pods集群,从而提供稳定的服务
创建命令:
kubectl create -f nginx-svc.yaml
Service方式创建的节点服务访问时通过kube-proxy代理访问到其他pod标签label=nginx的节点。
Service功能:
- 防止Pod失联
- 定义一组Pod的访问策略
- 支持ClusterIP,NodePort以及LoadBalancer三种类型
- Service的底层实现主要有iptables和ipvs二种网络模式
pod与service的关系:
- 通过label-selector相关联
- 通过Service实现Pod的负载均衡(TCP/UDP 4层)
4、Pod的健康检查
Kubernetes会维持Pod的状态及个数,而Pod内容器失败后往往也会导致pod退出,这么看来,K8s在某种程度上已经帮我们保证了容器服务的安全性。但也有很多场景,仅仅这样远远不够,比如某个时候容器服务假死,或者容器服务已经出错但并未退出,这些情况k8s的策略是无能为力的;K8S提供了一处机制,来帮助我们来检查容器的健康的程度。
健康检查(Health Check)用于检测您的应用实例是否正常工作,是保障业务可用性的一种传统机制,一般用于负载均衡下的业务,如果实例的状态不符合预期,将会把该实例“摘除”,不承担业务流量。Kubernetes中的健康检查使用存活性探针(liveness probes)和就绪性探针(readiness probes)来实现,service即为负载均衡,k8s保证service后面的pod都可用,是k8s中自愈能力的主要手段。
目前支持的探测方式包括:HTTP、TCP、Exec命令,我们主要讲一下常见易用的Exec方式和Http方式。
4.1、通过exec方式做健康探测
对于Exec探针,Kubernetes则只是在容器内运行命令。如果命令以退出代码0返回,则容器标记为健康。否则它被标记为不健康。当您不能或不想运行HTTP服务时,此类型的探针则很有用,但是必须是运行可以检查您的应用程序是否健康的命令。
用法如以下示例:
测试如下:
创建pod:
kubectl create -f liveness-exec.yaml
查看pod事件:
可以看到,在容器刚启动的60秒内,服务是正常的。此时healthy文件也在容器里。但容器启动后60秒后,healthy文件自动被删除,此时liveness检测无法探测到healthy文件,于是触发K8S机制剔除掉服务,并重建容器。
4.2、通过HTTP方式做健康探测
HTTP探针可能是最常见的自定义Liveness探针类型。即使您的应用程序不是HTTP服务,您也可以在应用程序内创建轻量级HTTP服务以响应Liveness探针。 Kubernetes去访问一个路径,如果它得到的是200或300范围内的HTTP响应,它会将应用程序标记为健康。 否则它被标记为不健康。
httpGet配置项:
- host:连接的主机名,默认连接到pod的IP。你可能想在http header中设置"Host"而不是使用IP。
- scheme:连接使用的schema,默认HTTP。
- path: 访问的HTTP server的path。
- httpHeaders:自定义请求的header。HTTP运行重复的header。
- port:访问的容器的端口名字或者端口号。端口号必须介于1和65535之间。
示例:
运行此pod实例:
kubectl create -f liveness-http.yaml
查看事件列表:
此时,我们执行命令删除掉容器内的文件,看容器事件
更多推荐
所有评论(0)