(1)掌握Kubernetes节点的调度方法。
(2)掌握Kubectl工具的基本使用。
(3)掌握Kubernetes部署并发布简单服务的方法。
确保Kubernetes集群已部署完成。
Kubectl是Kubernetes集群的命令行工具,通过kubectl能够对集群本身进行管理,并能够在集群上进行容器化应用的安装部署。运行kubectl命令的语法如下:
# kubectl [command] [TYPE] [NAME] [flags]
l comand:指定要对资源执行的操作,例如create、get、describe和delete。
l TYPE:指定资源类型,资源类型需注意大小写。
l NAME:指定资源的名称,名称也是大小写敏感的。如果省略名称,则会显示所有的资源。
l flags:指定可选的参数。
Kubectl常用的命令见表7-6-2。
表7-6-2 Kubectl主要命令
命令 |
类型 |
作用 |
get |
查 |
列出某个类型的下属资源 |
describe |
查 |
查看某个资源的详细信息 |
logs |
查 |
查看某个Pod的日志 |
create |
增 |
新建资源 |
explain |
查 |
查看某个资源的配置项 |
delete |
删 |
删除某个资源 |
edit |
改 |
修改某个资源的配置项 |
apply |
改 |
应用某个资源的配置项 |
1.Kubectl工具的使用
(1)kubectl get(列出资源)
K8S把所有的东西都抽象成了资源,而kubectl get命令就是用来查看这些资源的,最常见的资源就是Pod。
Pod的概念其实和Docker中的容器非常相似。Pod是K8S中的最小工作单位,可以把Pod理解成一个一个的小机器人,而K8S抽象出来的大资源池就是它们的工厂。
那么Pod和Docker容器是什么关系呢,简单来说,Pod将一个或多个Docker容器封装成一个统一的整体进行管理并对外提供服务。
不仅部署的服务要封装成Pod,就连K8S平台自身也是运行在一堆Pod上。
查看一下K8S的Pod
参数“-n”指定了要查看哪个命名空间下的Pod。K8S平台自身所有的Pod都被放置在kube-system命名空间下。
命名空间namespace是K8S中“组”的概念,提供同一服务的Pod应该被放置同一命名空间下,而不是混杂在一起。K8S可以用命名空间来做权限控制和资源隔离。如果不指定的话,Pod将被放置在默认的命名空间default下。
执行了kubectl get pod -n kube-system命令后可以看到以下内容
其中每一行就是一个资源,这里看到的资源是Pod,这个列表里包含了K8S在所有节点上运行的Pod,加入的节点越多,那么显示的Pod也就越多。
以下是查询结果中的参数说明:
l NAME:Pod的名字,K8S可以为Pod随机分配一个五位数的后缀。
l READY:Pod中已经就绪的Docker容器的数量,Pod封装了一个或多个Docker容器,此处“1/1”的含义为“就绪1个容器/共计1个容器”。
l STATUS:Pod的当前状态,常见的状态有Running、Error、Pending等。
l RESTART:Pod一共重启了多少次,K8S可以自动重启Pod。
l AGE:Pod启动的时间。
kubectl get可以列出K8S中所有资源,这里只介绍了如何用kubectl获取Pod的列表,还可以获取其它资源列表信息,如get svc(查看服务)、get rs(查看副本控制器)、get deploy(查看部署)等。
如果想要查看更多信息,指定-o wide参数即可,语法如下:
# kubectl get <资源> -n <命名空间> -o wide
加上这个参数之后就可以看到资源的IP和所在节点。
(2)kubectl describe(查看详情)
kubectl describe命令可以用来查看某一资源的具体信息,同样可以使用-n参数指定资源所在的命名空间。
例如,可以用如下命令来查看刚才Pod列表中的某个Pod的详细信息
查询结果中可以看到很多的信息,首先是基本属性,可以在详细信息的开头找到。
[root@master ~]# kubectl describe pod kube-proxy-p66nn -n kube-system
Name: kube-proxy-p66nn #Pod名称
Namespace: kube-system #所处命名空间
Priority: 2000001000
PriorityClassName: system-node-critical
Node: node/172.16.51.39 #所在节点
Start Time: Sun, 31 May 2020 07:17:00 +0800 #启动时间
Labels: controller-revision-hash=5f46cbf776
k8s-app=kube-proxy
pod-template-generation=1
Annotations: <none> #注释
Status: Running #当前状态
IP: 172.16.51.39 #所在节点IP
Controlled By: DaemonSet/kube-proxy #由哪种资源控制
其中几个比较常用的,例如Node、Labels和Controlled By。通过Node可以快速定位到Pod所处的机器,从而检查该机器是否出现问题或宕机等。通过labels可以检索到该Pod的大致用途及定位。而通过Controlled By可以知道该Pod是由哪种K8S资源创建的,然后就可以使用“kubectl get<资源名>”命令继续查找问题。
在中间部分可以找到Containers段落。该段落详细的描述了Pod中每个Docker容器的信息,常用的比如Image字段,当Pod出现ImagePullBackOff错误的时候就可以查看该字段,确认拉取的是什么镜像。其他的字段名都很通俗,直接翻译即可。
Containers:
kube-flannel:
Container ID: docker://5f73810591df58b2d9d62ed08d3eef76613c424c5776381c050faf8689d23727
Image: registry.aliyuncs.com/google_containers/kube-proxy:v1.14.1
Image ID: docker://sha256:20a2d7035165926828d874302769d26feb6ba80db3965a006bfaa13cf2508286
Port: <none>
Host Port: <none>
Command:
/usr/local/bin/kube-proxy
Args:
--config=/var/lib/kube-proxy/config.conf
--hostname-override=$(NODE_NAME)
State: Running
Started: Sun, 31 May 2020 22:01:23 +0800
Ready: Terminated
Restart Count: 0
Limits:
cpu: 100m
memory: 50Mi
Requests:
cpu: 100m
memory: 50Mi
Environment:
POD_NAME: kube-flannel-ds-amd64-6hf4w (v1:metadata.name)
POD_NAMESPACE: kube-system (v1:metadata.namespace)
Mounts:
/lib/modules from lib-modules (ro)
/run/xtables.lock from xtables-lock (rw)
/var/lib/kube-proxy from kube-proxy (rw)
/var/run/secrets/kubernetes.io/serviceaccount from kube-proxy-token-4s977 (ro)
在describe查看详情的时候,最常用的信息获取处就是Event段落,可以在介绍内容的末尾找到它,如下:
Events: <none>
Events字段为<none>就说明该Pod一切正常。当Pod的状态不是Running时,这里一定会有或多或少的问题,然后就可以通过其中的信息分析Pod出现问题的详细原因了。
(3)kubectl logs(查看日志)
如果要查看一个Pod的具体日志,就可以通过“kubectl logs <pod名>”命令来查看。kubectl logs只能查看Pod的日志。通过添加-f参数可以持续查看日志。例如,查看kube-system命名空间中某个flannel Pod的日志
# kubectl logs -f kube-proxy-l9rzt -n kube-system
(4)kubectl create(创建资源)
K8S中的所有东西都可以通过kubectl create命令创建,无论是创建一个Pod还是一个大型的滚动升级服务Deployment,create命令都可以做到。使用create生成一个资源主要有两种常用方法,从YAML配置文件创建和简易创建。
如果想让K8S生成一个和预期一模一样的资源,那就要充分而详细地描述这个资源,K8S就提供了这么一个方法,可以使用YAML文件按照K8S指定好的结构定义一个对象,然后使用如下方法将该文件传递给K8S。
# kubectl create -f <配置文件名.yaml>
例如,使用下面的配置文件就可以创建一个最简单的Pod
然后使用“kubectl create -f kubia.yaml”命令即可创建。
如果配置文件有问题,那么K8S就会报错,多数错误一般都是拼写导致的。使用YAML文件相对比较复杂,可以先来学习更简单的简易创建模式。
K8S为一些常用的资源提供了简易创建的方法,比如说Service、Namespace、Deployment等,这些方法可以使用“kubectl create <资源类型> <资源名>”的方式创建。例如,创建一个名叫hello-world的命名空间,直接使用下面命令即可
(5)kubectl explain(解释配置)
K8S可以通过配置文件来生成资源,而为了尽可能详细地描述资源的模样,K8S提供了数量庞大的配置项。使用explain命令可以快速地了解到某个配置项的作用,其语法如下:
# kubectl explain <配置名>
要了解创建Pod的基本属性都是干什么的,使用kubectl explain pod命令即可
(6)kubectl delete(删除资源)
kubectl delete命令用于删除资源,语法如下:
# kubectl delete <资源类型> <资源名>
例如,删除一个名为kubia-manual的Pod。
[root@master ~]# kubectl delete pod kubia-manual
pod "kubia-manual" deleted
如果要删除所有的Pod,命令如下:
# kubectl delete pod --all
如果要删除一切,命令如下:
# kubectl delete all --all
(7)kubectl edit(修改配置)
K8S的每个资源都是通过一个YAML配置文件生成的,哪怕是简易创建的资源,也是K8S从一个默认的配置文件创建而来的。可以使用“kubectl get <资源类型> <资源名> -o yaml”命令查看某个现有资源的配置项。例如,查看kube-proxy-l9rzt的配置项
# kubectl get pod kube-proxy-l9rzt -n kube-system -o yaml
执行之后就可以看到一个很长的配置列表,使用kubectl edit命令就可以编辑刚才打开的配置列表。
# kubectl edit pod kube-proxy-l9rzt -n kube-system
注意:对于运行中的资源无法修改其名称或类型,可以修改其它属性,例如,将拉取镜像的标签指定为latest。
修改完成后输入“:wq”命令保存即可。
使用“kubectl edit <资源类型> <资源名>”命令可以编辑一个资源的具体配置项,edit命令在实际使用中更偏向于人工修改某个配置项来解决问题。例如,修改镜像地址解决拉取不到镜像的问题。
(8)kubectl apply(应用配置)
kubectl edit可以对某个资源进行简单快捷的修改,但是如果想对资源进行大范围的修改,就可以用到kubectl apply命令。其基本用法如下:
# kubectl apply -f <新配置文件名.yaml>
kubeclt apply可以理解成edit命令的升级版,其最大的区别就是,apply接受一个YAML配置文件,而不是打开一个编辑器去修改。K8S在接受到这个配置文件后,会根据metadata中的元数据来查找目标资源,如果没有的话则直接新建;如果有的话就依次比对配置文件之间有什么不同点,然后更新并应用不同的配置。
这么做的好处有很多,例如,通过kubectl apply -f https://some-network-site/resourse.yaml命令从一个网站上部署了用户的资源,这样当它的管理者更新了这个配置文件后,用户只需要再次执行这个命令,就可以应用更新后的内容了,而不用关心到底修改了哪些配置项。
2.部署并发布简单应用
一旦运行了K8S集群,就可以在其上部署容器化应用程序。为此,需要创建Deployment配置,Deployment指示K8S如何创建和更新应用程序的实例。创建Deployment后,K8S调度组件将应用程序实例提到集群中的各个节点上。
创建应用程序实例后,Kubernetes Deployment Controller会持续监控这些实例。如果托管实例的节点关闭或被删除,则Deployment控制器会替换它,K8S提供了一种自我修复机制来解决机器故障或维护问题
(1)创建Deployment
使用kubectl create命令创建一次部署,该部署用于管理Pod
命令中nginx为Deployment名称,--image为指定使用的镜像,默认从Docker Hub拉取。
(2)查看Deployment
创建完成后查看Deployment列表
(3)查看Pod
查看Pod运行状态
(4)发布服务
K8S暴露服务有3种方式,分别为LoadBlancer Service、NodePort Service和Ingress。
Ingress的官方定义为管理对外服务到集群内服务之间规则的集合,可以理解为Ingress定义规则来允许进入集群的请求被转发到集群中对应服务上,从而实现服务暴露。Ingress能把集群内Service配置成外网能够访问的URL,流量负载均衡,终止SSL,提供基于域名访问的虚拟主机等等。
LoadBlancer Service是K8S结合云平台的组件,如国外GCE、AWS、国内阿里云等等,使用它向使用的底层云平台申请创建负载均衡器来实现,但它有局限性,对于使用云平台的集群比较方便。
NodePort Service是通过在节点上暴露端口,然后通过将端口映射到具体某个服务上来实现服务暴露,比较直观方便,但是对于集群来说,随着Service不断增加,需要的端口越来越多,很容易出现端口冲突,而且不容易管理。当然对于小规模的集群服务,还是比较不错的。
NodePort服务是引导外部流量服务的最原始方式。NodePort方式会在所有节点上开放一个特定端口,任何发送到该端口的流量都被转发到对应服务。此处案例采用NodePort的方式来暴露Nginx服务。
查看Nginx服务对外暴露的端口。
暴露服务后,就可以通过“http://172.16.51.38:32176”来访问Nginx服务了
(5)Pod动态伸缩
在实际生产系统中,经常会遇到某个服务需要扩容的场景,也可能会遇到由于资源紧张或者工作负载降低而需要减少服务实例数量的场景。此时,可以利用K8S的弹性伸缩功能来完成这些任务。
弹性伸缩是指适应负载变化,以弹性可伸缩方式提供资源。反映到K8S中,可根据负载的高低,动态地调整Pod的副本数。目前K8S提供了API接口实现Pod的弹性伸缩,Pod的副本数本来通过Replication Controller进行控制,所以Pod的弹性伸缩就是修改Replication Controller的Pod副本数,可以通过kubectl scale命令来完成。
通过执行如下命令将Nginx Deployment控制的Pod副本数量从初始的1更新为5
执行kubectl get pods命令来验证Pod的副本数量是否增加到5
将--replicas设置为比当前Pod副本数量更小的数字,系统将会“杀掉”一些运行中的Pod,即可实现应用集群缩容
还可以使用autoscale自动设置在K8S集群中运行的pod数量(水平自动伸缩)。
指定Deployment、ReplicaSet或ReplicationController,并创建已经定义好资源的自动伸缩器。使用自动伸缩器可以根据需要自动增加或减少系统中部署的Pod数量
设置后,Pod的副本数就会根据负载在1-10之间自动伸缩。