第二章 K8S基础操作笔记

一、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中自愈能力的主要手段。

目前支持的探测方式包括:HTTPTCPExec命令我们主要讲一下常见易用的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
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值