K8s应用编排
本篇内容以每一步的命令为标题,加深对命令及作用的印象。
kubectl create deployment
kubectl create deployment
可以直接创建Deployment控制器对象,它生成pod模板之后,可以编排pod对象,但需要用户以–image选项指定要使用的容器镜像。
可以使用--dry-run={none|client|server}
选项用于测试运行,并不真正执行资源对象的创建过程。也可以添加-o yaml
来以yaml格式输出api对象信息。
[root@k8s-master01 ~]# kubectl create deployment demoapp --image="nginx:latest" --dry-run
deployment.apps/demoapp created (dry run)
[root@k8s-master01 ~]#
[root@k8s-master01 ~]# kubectl create deployment demoapp --image="nginx:latest" --dry-run -o yaml > nginx.yaml
[root@k8s-master01 ~]# cat nginx.yaml
apiVersion: apps/v1
....
命令详解:
kubectl create deployment demoapp --image="nginx:latest" --dry-run
:以nginx:latest镜像创建名为demoapp的deployment控制器;但是不真正执行资源对象的创建过程kubectl create deployment demoapp --image="nginx:latest" --dry-run -o yaml > nginx.yaml
:和上面的作用一样,不过将deployment的api信息输出到了nginx.yaml文件中
确认测试命令无误后,可在移除–dry-run选项后再次执行命令以完成资源对象的创建。
[root@k8s-master01 ~]# kubectl create deployment demoapp --image="nginx:latest"
deployment.apps/demoapp created
[root@k8s-master01 ~]#
该命令创建的Deployment/demoapp对象会借助指定的镜像生成一个Pod,并自动为其添加app=demoapp标签,而控制器对象自身也将使用该标签作为标签选择器。
kubectl get
kubectl get
命令可用于获取各种资源对象的相关信息,它能显示对象类型特有格式的简要信息,也能打印出yaml和json格式的详细信息等。
[root@k8s-master01 ~]# kubectl get po -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
demo-nginx-79d8fd4b47-z2p2r 1/1 Running 0 5h57m 10.244.2.4 k8s-node02 <none> <none>
[root@k8s-master01 ~]# kubectl get deployments/demo-nginx -n dev
NAME READY UP-TO-DATE AVAILABLE AGE
demo-nginx 1/1 1 1 2d11h
[root@k8s-master01 ~]# kubectl get po -l app=demo-nginx -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
demo-nginx-79d8fd4b47-z2p2r 1/1 Running 0 5h55m 10.244.2.4 k8s-node02 <none> <none>
[root@k8s-master01 ~]# kubectl get deployments/demo-nginx -n dev -o yaml
apiVersion: extensions/v1beta1
kind: Deployment
...
[root@k8s-master01 ~]# kubectl get po -n dev -o yaml
apiVersion: v1
...
[root@k8s-master01 ~]# kubectl get po demo-nginx-79d8fd4b47-z2p2r -n dev -o yaml
apiVersion: v1
...
命令详解:
-
kubectl get po -n dev -o wide
:获取dev命名空间下所有pod节点信息 -
kubectl get deployments/demo-nginx -n dev
:获取dev命名空间下,deployments/demo-nginx控制器对象信息;Deployment资源对象是通过ReplicaSet控制器对象作为中间层实例完成对Pod对象的控制,各Pod的名称也是由ReplicaSet对象名称后跟几个随机字符构成。- NAME:Deployment资源对象的名称
- READY:以类似m/n格式返回两个数字,m代表就绪的Pod数量,n表示期望的总的Pod数量。
- UP-TO-DATE:更新到最新版本定义的Pod对象副本数量,在控制器的滚动更新模式下,它表示已经完成版本更新的Pod对象副本数量。
- AVAILABLE:当前处于可用状态的Pod对象副本数量,即可正常提供服务的副本数
- AGE:该资源的存在时长
-
kubectl get po -l app=demo-nginx -n dev -o wide
:该命令和上面kubectl get po -n dev -o wide
类似,不过当前命令是对所有pod的标签做了app=demo-nginx过滤的,上面的命令是获取所有的。- READY:m/n格式,m表示Pod中就绪状态的容器数量,n表示Pod中总的容器数量。
- STATUS:Pod的当前状态,其值可能是Pending、Running、Succeeded、Failed和Unknown等其中之一,并存在某些类型的中间状态(容器状态)。
- RESTARTS:Pod对象可能会因容器进程崩溃、超出资源限额等故障而被重启,此字段记录了它重启的次数。
- IP:Pod的IP地址,通常由网络插件自动分配。
- NODE:该Pod对象绑定的Node,目标Node由Scheduler负责挑选。
确认Pod对象转为Running状态后,即可在集群中任一节点(或其他Pod对象)直接访问容器化应用的服务。
我们可以测试在集群中的三台机器上访问我们的pod容器的地址,如下:
[root@k8s-master01 ~]# curl http://10.244.2.4
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
[root@k8s-node01 ~]# curl http://10.244.2.4
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
[root@k8s-node02 ~]# curl http://10.244.2.4
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
我们获取pod的ip除了使用-o wide
,还可以通过Deployment控制器的yaml文件获取;不过需要注意的是,label名称不要错误,否则是拿ip时会报错。
[root@k8s-master01 ~]# kubectl get pods -l app=nginx-demo -n dev -o jsonpath="{.items[0].metadata.name}"
error: error executing jsonpath "{.items[0].metadata.name}": Error executing template: array index out of bounds: index 0, length 0. Printing more information for debugging the template:
template was:
{.items[0].metadata.name}
object given to jsonpath engine was:
map[string]interface {}{"apiVersion":"v1", "items":[]interface {}{}, "kind":"List", "metadata":map[string]interface {}{"resourceVersion":"", "selfLink":""}}
[root@k8s-master01 ~]# kubectl get deployments -n dev
NAME READY UP-TO-DATE AVAILABLE AGE
demo-nginx 1/1 1 1 2d12h
[root@k8s-master01 ~]# kubectl get deployments/demo-nginx -o yaml
Error from server (NotFound): deployments.extensions "demo-nginx" not found
[root@k8s-master01 ~]# kubectl get deployments/demo-nginx -o yaml -n dev
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "1"
creationTimestamp: "2021-03-27T03:11:39Z"
generation: 1
labels:
app: demo-nginx
[root@k8s-master01 ~]# kubectl get pods -l app=demo-nginx -o jsonpath={.items[0].status.podIP} -n dev
10.244.2.4[root@k8s-master01 ~]#
命令详解:
kubectl get pods -l app=nginx-demo -n dev -o jsonpath="{.items[0].metadata.name}"
:获取标签为nginx-demo(不存在)的metadata.name信息,会报错kubectl get deployments -n dev
:获取dev命名空间下的所有deployment控制器,我们用deployment来获取标签kubectl get deployments/demo-nginx -o yaml -n dev
:获取demo-nginx的控制器api信息,以yaml格式展示,获取标签labelskubectl get pods -l app=demo-nginx -o jsonpath={.items[0].status.podIP} -n dev
:获取标签为app=demo-nginx的节点的ip
kubectl create service
简单来说,Service对象就是一组Pod的逻辑组合,它通过称为ClusterIP的地址和服务端口接收客户端请求,并将这些请求代理至使用标签选择器来过滤一个符合条件的Pod对象。kubectl create service命令可创建Service对象以将应用程序“暴露”于网络中,它使用的标签选择器为app=SVC_NAME。例如,下面的命令使用app=demo-nginx为标签选择器创建了Service/demo-nginx资源对象。
kubectl create service nodeport demo-nginx --tcp=80 -n dev
:在命令中,nodeport是指Service对象的类型,它会在集群中各节点上随机选择一个节点端口(hostPort)为该Service对象接入集群外部的访问流量,集群内部流量则由Service资源通过ClusterIP直接接入。命令选项--tcp=<port>[:<targetPort>]
用于指定Servcie端口及容器上要暴露的端口,省略容器端口时表示与Service端口相同
[root@k8s-master01 ~]# kubectl get svc -n dev
No resources found.
[root@k8s-master01 ~]# kubectl create service nodeport demo-nginx --tcp=80 -n dev
service/demo-nginx created
[root@k8s-master01 ~]# kubectl get svc -n dev
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
demo-nginx NodePort 10.103.163.81 <none> 80:31020/TCP 1s
命令解释:
kubectl get svc -n dev
:获取dev命名空间下的services信息kubectl create service nodeport demo-nginx --tcp=80 -n dev
:创建一个nodeport类型的service并且名为demo-nginx,指定service关联容器的端口为80
其中,PORT(s)字段中表明,集群中各工作节点会捕获发往本地的目标端口为31020的流量,并将其代理至当前Service对象的80端口,于是,集群外部的用户可以使用当前集群中任一节点的此端口来请求Service对象上的服务。CLUSTER-IP字段为当前Service的IP地址,它是一个虚拟IP,并没有配置在集群中任何主机的任何接口之上,但每个Node上的kube-proxy都会为CLUSTER-IP所在的网络创建用于转发的iptables或ipvs规则。此时,用户可于集群外部任一浏览器请求Kubernetes集群任意一个节点的相关端口来进行访问测试
kubectl scale
上面的所有操作都只生成了一个pod,其所能够承载的访问请求数量受限于这个Pod对象的服务能力。
请求流量上升到接近或超出其承载上限之前,用户可以通过Kubernetes的应用“扩容”(scaling up)机制来增加Pod副本数量,从而提升其服务容量。相应地,“缩容”是指缩减Pod副本数量,只不过这通常缘于与扩容操作相反的原因。
kubectl scale
命令就是专用于变动控制器应用规模的命令,它支持对Deployment、ReplicaSet、StatefulSet等类型资源对象的扩容和缩容操作。
[root@k8s-master01 ~]# kubectl get deployment -n dev
NAME READY UP-TO-DATE AVAILABLE AGE
demo-nginx 1/1 1 1 2d22h
[root@k8s-master01 ~]# kubectl scale deployment/demo-nginx --replicas=3 -n dev
deployment.extensions/demo-nginx scaled
[root@k8s-master01 ~]# kubectl get po -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
demo-nginx-79d8fd4b47-f8p8j 1/1 Running 0 79s 10.244.2.6 k8s-node02 <none> <none>
demo-nginx-79d8fd4b47-wt8rq 1/1 Running 0 79s 10.244.3.6 k8s-node01 <none> <none>
demo-nginx-79d8fd4b47-z2p2r 1/1 Running 0 16h 10.244.2.4 k8s-node02 <none> <none>
[root@k8s-master01 ~]# kubectl describe deployment/demo-nginx -n dev
Name: demo-nginx
Namespace: dev
CreationTimestamp: Sat, 27 Mar 2021 11:11:39 +0800
Labels: app=demo-nginx
Annotations: deployment.kubernetes.io/revision: 1
Selector: app=demo-nginx
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=demo-nginx
Containers:
nginx:
Image: docker.io/nginx:latest
Port: <none>
Host Port: <none>
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Progressing True NewReplicaSetAvailable
Available True MinimumReplicasAvailable
OldReplicaSets: <none>
NewReplicaSet: demo-nginx-79d8fd4b47 (3/3 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 3m deployment-controller Scaled up replica set demo-nginx-79d8fd4b47 to 3
[root@k8s-master01 ~]# kubectl get deployment/demo-nginx -n dev
NAME READY UP-TO-DATE AVAILABLE AGE
demo-nginx 3/3 3 3 2d22h
命令解释:
kubectl get deployment -n dev
:获取dev命名空间下的所有deployment控制器kubectl scale deployment/demo-nginx --replicas=3 -n dev
:将deployment控制器中demo-nginx的副本改为3kubectl get po -n dev -o wide
:获取dev下的pod信息,获取出ipkubectl describe deployment/demo-nginx -n dev
:获取dev下deployment控制器中demo-nginx的控制器的api信息kubectl get deployment/demo-nginx -n dev
:获取dev下deployment控制器中demo-nginx的控制器
Service对象内置的负载均衡机制可在其后端副本数量不止一个时自动进行流量分发,它还会自动监控关联到的Pod的健康状态,以确保仅将请求流量分发至可用的后端Pod对象。
每个能够接收流量的后端称为一个端点,它通常表现为相应主机或容器上可接收特定流量的访问入口(套接字),如下面命令结果中的Endpoints字段所示。
[root@k8s-master01 ~]# kubectl describe service/demo-nginx -n dev
Name: demo-nginx
Namespace: dev
Labels: app=demo-nginx
Annotations: <none>
Selector: app=demo-nginx
Type: NodePort
IP: 10.111.211.192
Port: 80-80 80/TCP
TargetPort: 80/TCP
NodePort: 80-80 32113/TCP
Endpoints: 10.244.2.4:80,10.244.2.6:80,10.244.3.6:80
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
[root@k8s-master01 ~]#
kubectl delete/edit
成功创建于Kubernetes之上的资源对象也称为活动对象(liveobject),其配置规范(live object configuration)由APIServer保存在集群状态存储系统etcd中。kubectl edit命令可调用默认编辑器对活动对象的可配置属性进行编辑。例如,若需要将此前创建的Service/demo-nginx对象的类型修改为ClusterIP,可以使用kubectl edit service demo-nginx
命令打开编辑界面后,通过将type属性的值修改为ClusterIP使其实时生效。
tips:不同资源类型的资源规范相差很大,而且未必所有字段都支持运行时修改。
不再有价值的活动对象可使用kubectl delete命令予以删除。例如,下面的命令能够删除service/demoapp资源对象
#kubectl delete service/demoapp -n xxx
有时候需要清空某一类型下的所有对象,此时只需要将上面命令对象名称换成–all选项便能实现。例如,删除dafault名称空间中所有的Deployment控制器
#kubectl delete deployment --all
受控于控制器的pod对象在删除后会被重建。默认情况下,删除Deployment一类的工作负载型控制器资源会级联删除相关的所有Pod对象。若要禁用该功能,需要在删除命令中使用–cascade=false选项。