我们知道 kubectl 是直接操作 APIServer 的,所以就相当于把我们的清单提交给了 APIServer,然后集群获取到清单描述的应用信息后存入到 etcd 数据库中,然后 kube-scheduler 组件发现这个时候有一个 Pod 还没有绑定到节点上,就会对这个 Pod 进行一系列的调度,把它调度到一个最合适的节点上,然后把这个节点和 Pod 绑定到一起(写回到 etcd),然后节点上的 kubelet 组件这个时候 watch 到有一个 Pod 被分配过来了,就去把这个 Pod 的信息拉取下来,然后根据描述通过容器运行时把容器创建出来,最后当然同样把 Pod 状态再写回到 etcd 中去,这样就完成了一整个的创建流程。
$ kubectl create -f nginx-deployment.yaml
deployment.apps/nginx-deploy created
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deploy-54f57cf6bf-2fdjz 1/1 Running 0 7s
nginx-deploy-54f57cf6bf-57287 1/1 Running 0 7s
我们可以看到会在集群中生成两个 Pod 出来。而整个资源清单文件对应到 Kubernetes 中就是一个 API Object(API 对象),我们按照这些对象的要求填充上对应的属性后,提交给 Kubernetes 集群,就可以为我们创建出对应的资源对象,比如我们这里定义的是一个 Deployment 类型的 API 对象,我们按照这个 API 对象的要求填充了一些属性,就会为我们创建出对应的资源对象,我们可以通过下面的命令来获取:
$ kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deploy 2/2 2 2 12m
而这个 Deployment 定义的副本 Pod 具体是什么样的,是通过下面的 Pod 模板来定义的,就是 template 下面的定义,这个模板中定义了我们的 Pod 中只有一个名为 nginx 的容器,容器使用的镜像是 nginx:1.7.9(spec.containers[0].image),并且这个容器监听的端口是 80(spec.containers[0].ports[0].containerPort),另外我们还为 Pod 添加了一个app: nginx这样的 Label 标签,这里需要非常注意的是上面的 selector.matchLabels 区域就是来表示我们的 Deployment 来管理哪些 Pod 的,所以这个地方需要和 Pod 模板中的 Label 标签保持一致,这个 Label 标签之前我们也提到过是非常重要的。
另外我们也可以发现每个 API 对象都有一个 Metadata 的字段,用来表示该对象的元数据的,比如定义 name、namespace 等,比如上面 Deployment 和 Pod 模板中都有这个字段,至于为什么 Pod 模板中没有 name 这个元信息呢,这是因为 Deployment 这个控制器会自动在他自己的 name 基础上生成 Pod 名,不过 Deployment 下面定义的 Label 标签就没有 Pod 中定义的 Label 标签那么重要了,只是起到一个对该对象标识和过滤的作用。比如我们在查询对象的时候可以带上标签来进行过滤:
$ kubectl get deployment -l chapter=first-app
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deploy 2/2 2 2 51m
$ kubectl get pods -l app=nginx
NAME READY STATUS RESTARTS AGE
nginx-deploy-54f57cf6bf-2fdjz 1/1 Running 0 51m
nginx-deploy-54f57cf6bf-57287 1/1 Running 0 51m
到这里我们就完成了我们的第一个应用的容器化部署,但是往往我们在部署应用的过程中或多或少会遇到一些问题,这个时候我们可以使用一个 kubectl describe 命令来查看资源对象的详细信息,比如我们用下面的命令来查看 Pod 的详细信息:
$ kubectl describe pod nginx-deploy-54f57cf6bf-2fdjz
Name: nginx-deploy-54f57cf6bf-2fdjz
Namespace: default
Priority: 0
Node: ydzs-node2/10.151.30.23
Start Time: Sat, 09 Nov 2019 15:20:32 +0800
Labels: app=nginx
pod-template-hash=54f57cf6bf
Annotations:
Status: Running
IP: 10.244.2.199
IPs:
IP: 10.244.2.199
Controlled By: ReplicaSet/nginx-deploy-54f57cf6bf
Containers:
nginx:
Container ID: docker://e40e78eee7a431b6e7277b414967cce936ac750e2a8ba30298302cdd89e54300
Image: nginx:1.7.9
Image ID: docker-pullable://nginx@sha256:e3456c851a152494c3e4ff5fcc26f240206abac0c9d794affb40e0714846c451
Port: 80/TCP
Host Port: 0/TCP
State: Running
Started: Sat, 09 Nov 2019 15:20:35 +0800
Ready: True
Restart Count: 0
Environment:
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-5tsh4 (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-5tsh4:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-5tsh4
Optional: false
QoS Class: BestEffort
Node-Selectors:
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled default-scheduler Successfully assigned default/nginx-deploy-54f57cf6bf-2fdjz to ydzs-node2
Normal Pulled 52m kubelet, ydzs-node2 Container image "nginx:1.7.9" already present on machine
Normal Created 52m kubelet, ydzs-node2 Created container nginx
Normal Started 52m kubelet, ydzs-node2 Started container nginx
我们可以看到很多这个 Pod 的详细信息,比如调度到的节点、状态、IP 等,一般我们比较关心的是下面的 Events 部分,就是我们说的事件。
$ kubectl explain deployment
KIND: Deployment
VERSION: apps/v1
DESCRIPTION:
Deployment enables declarative updates for Pods and ReplicaSets.
FIELDS:
apiVersion
APIVersion defines the versioned schema of this representation of an
object. Servers should convert recognized schemas to the latest internal
value, and may reject unrecognized values. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
kind
Kind is a string value representing the REST resource this object
represents. Servers may infer this from the endpoint the client submits
requests to. Cannot be updated. In CamelCase. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
metadata
我们可以看到上面的信息和我们在 API 文档中查看到的基本一致,比如我们看到其中 spec 字段是一个 类型的,证明该字段下面是一个对象,我们可以继续去查看这个字段下面的详细信息:
$ kubectl explain deployment.spec
KIND: Deployment
VERSION: apps/v1
RESOURCE: spec
DESCRIPTION:
Specification of the desired behavior of the Deployment.
DeploymentSpec is the specification of the desired behavior of the
Deployment.
FIELDS:
minReadySeconds
Minimum number of seconds for which a newly created pod should be ready
without any of its container crashing, for it to be considered available.
Defaults to 0 (pod will be considered available as soon as it is ready)
paused
Indicates that the deployment is paused.
progressDeadlineSeconds
The maximum time in seconds for a deployment to make progress before it is
considered to be failed. The deployment controller will continue to process
failed deployments and a condition with a ProgressDeadlineExceeded reason
will be surfaced in the deployment status. Note that progress will not be
estimated during the time a deployment is paused. Defaults to 600s.
replicas
Number of desired pods. This is a pointer to distinguish between explicit
zero and not specified. Defaults to 1.
revisionHistoryLimit
The number of old ReplicaSets to retain to allow rollback. This is a
pointer to distinguish between explicit zero and not specified. Defaults to
10.
selector -required-
Label selector for pods. Existing ReplicaSets whose pods are selected by
this will be the ones affected by this deployment. It must match the pod
template's labels.
strategy
The deployment strategy to use to replace existing pods with new ones.
template -required-
Template describes the pods that will be created.