Kubernetes 支持两种方式创建资源:
1. 用 kubectl 命令直接创建,比如:
kubectl run nginx-deployment --image=nginx:1.7.9 --replicas=2
在命令行中通过参数指定资源的属性。
2. 通过配置文件和 kubectl apply
创建,要完成前面同样的工作,可执行命令:
kubectl apply -f nginx.yml
分别介绍:
一、kubectl run 直接创建Deployment
Kubernetes 通过各种 Controller 来管理 Pod 的生命周期。
为了满足不同业务场景,Kubernetes 开发了 Deployment、ReplicaSet、DaemonSet、StatefuleSet、Job 等多种 Controller。
首先学习最常用的 Deployment。
先从例子开始(通过 kubectl run
创建 Deployment),运行一个 Deployment:
kubectl run nginx-deployment --image=nginx:1.7.9 --replicas=2
上面的命令将部署包含两个副本的 Deployment nginx-deployment
,容器的 image 为 nginx:1.7.9
。
下面详细分析 Kubernetes 都做了些什么工作。
daweij@master:~$ kubectl get deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE httpd-app 2 2 2 2 53m kubernetes-bootcamp 2 2 2 2 5h nginx-deployment 2 2 2 0 17m
kubectl get deployment
命令可以查看 nginx-deployment
的状态,输出显示两个副本正常运行。
kubectl describe deployment
了解更详细的信息。
daweij@master:~$ kubectl describe deployment nginx-deployment
Name: nginx-deployment
Namespace: default
CreationTimestamp: Wed, 07 Mar 2018 14:02:48 +0800
Labels: run=nginx-deployment
Annotations: deployment.kubernetes.io/revision=1
Selector: run=nginx-deployment
Replicas: 2 desired | 2 updated | 2 total | 0 available | 2 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 1 max unavailable, 1 max surge
Pod Template:
Labels: run=nginx-deployment
Containers:
nginx-deployment:
Image: nginx:1.7.9
Port: <none>
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available False MinimumReplicasUnavailable
OldReplicaSets: <none>
NewReplicaSet: nginx-deployment-d5655dd9d (2/2 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 18m deployment-controller Scaled up replica set nginx-deployment-d5655dd9d to 2
daweij@master:~$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
httpd-app-5fbccd7c6c-c8qq7 1/1 Running 0 55m 10.233.71.8 node3
httpd-app-5fbccd7c6c-jstpm 1/1 Running 0 55m 10.233.75.8 node2
kubernetes-bootcamp-5d7f968ccb-c57nw 1/1 Running 0 4h 10.233.75.7 node2
kubernetes-bootcamp-5d7f968ccb-lv24f 1/1 Running 0 4h 10.233.71.7 node3
nginx-deployment-d5655dd9d-4td79 0/1 ContainerCreating 0 18m <none> node1
nginx-deployment-d5655dd9d-9btkm 0/1 ContainerCreating 0 18m <none> node4
上述标红部分,告诉我们创建了一个NewReplicaSet: nginx-deployment-d5655dd9d,Events
是 Deployment 的日志,记录了 ReplicaSet 的启动过程。
通过上面的分析,也验证了 Deployment 通过 ReplicaSet 来管理 Pod 的事实。
接着我们将注意力切换到nginx-deployment-d5655dd9d,执行 kubectl describe replicaset
:
daweij@master:~$ kubectl get replicaset NAME DESIRED CURRENT READY AGE nginx-deployment-d5655dd9d 2 2 2 21m
两个副本已经就绪,用 kubectl describe replicaset
查看详细信息:
daweij@master:~$ kubectl describe replicaset nginx-deployment-d5655dd9d
Name: nginx-deployment-d5655dd9d
Namespace: default
Selector: pod-template-hash=812118858,run=nginx-deployment
Labels: pod-template-hash=812118858
run=nginx-deployment
Annotations: deployment.kubernetes.io/desired-replicas=2
deployment.kubernetes.io/max-replicas=3
deployment.kubernetes.io/revision=1
Controlled By: Deployment/nginx-deployment
Replicas: 2 current / 2 desired
Pods Status: 2 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
Labels: pod-template-hash=812118858
run=nginx-deployment
Containers:
nginx-deployment:
Image: nginx:1.7.9
Port: <none>
Environment: <none>
Mounts: <none>
Volumes: <none>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 31m replicaset-controller Created pod: nginx-deployment-d5655dd9d-4td79
Normal SuccessfulCreate 31m replicaset-controller Created pod: nginx-deployment-d5655dd9d-9btkm
Controlled By
指明此 ReplicaSet 是由 Deployment nginx-deployment
创建。
Events
记录了两个副本 Pod 的创建。接着我们来看 Pod,执行 kubectl get pod
:
daweij@master:~$ kubectl get pod NAME READY STATUS RESTARTS AGE nginx-deployment-d5655dd9d-4td79 1/1 Running 0 32m nginx-deployment-d5655dd9d-9btkm 1/1 Running 0 32m
两个副本 Pod 都处于 Running
状态,用 kubectl describe pod
查看更详细的信息:
daweij@master:~$ kubectl describe pod nginx-deployment-d5655dd9d-4td79 Name: nginx-deployment-d5655dd9d-4td79 Namespace: default Node: node1/172.28.2.211 Start Time: Wed, 07 Mar 2018 14:03:08 +0800 Labels: pod-template-hash=812118858 run=nginx-deployment Annotations: <none> Status: Running IP: 10.233.102.133 Controlled By: ReplicaSet/nginx-deployment-d5655dd9d Containers: nginx-deployment: Container ID: docker://bd8995acce93e5b9ee64bb1984973de74ad65823da33d7bb2d68a3e0bb149d21 Image: nginx:1.7.9 Image ID: docker-pullable://nginx@sha256:e3456c851a152494c3e4ff5fcc26f240206abac0c9d794affb40e0714846c451 Port: <none> State: Running Started: Wed, 07 Mar 2018 14:24:52 +0800 Ready: True Restart Count: 0 Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from default-token-8g5br (ro) Conditions: Type Status Initialized True Ready True PodScheduled True Volumes: default-token-8g5br: Type: Secret (a volume populated by a Secret) SecretName: default-token-8g5br Optional: false QoS Class: BestEffort Node-Selectors: <none> Tolerations: <none> Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 33m default-scheduler Successfully assigned nginx-deployment-d5655dd9d-4td79 to node1 Normal SuccessfulMountVolume 32m kubelet, node1 MountVolume.SetUp succeeded for volume "default-token-8g5br" Normal Pulling 32m kubelet, node1 pulling image "nginx:1.7.9" Normal Pulled 11m kubelet, node1 Successfully pulled image "nginx:1.7.9" Normal Created 11m kubelet, node1 Created container Normal Started 11m kubelet, node1 Started container
Controlled By
指明此 Pod 是由 ReplicaSet nginx-deployment-1260880958
创建。Events
记录了 Pod 的启动过程。如果操作失败(比如 image 不存在),也能在这里查看到原因。
总结一下这个过程:
-
用户通过
kubectl
创建 Deployment。 -
Deployment 创建 ReplicaSet。
-
ReplicaSet 创建 Pod。
从上图也可以看出,对象的命名方式是:子对象的名字
= 父对象名字
+ 随机字符串或数字
。
二、通过配置文件和 kubectl apply
创建创建Deployment
通过配置文件和 kubectl apply
创建,要完成前面同样的工作,可执行命令:
kubectl apply -f nginx.yml
nginx.yml 的内容为:
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 2 template: metadata: labels: app: web_server spec: containers: - name: nginx image: nginx:1.7.9
资源的属性写在配置文件中,文件格式为 YAML。
下面对这两种方式进行比较。
基于命令的方式:
-
简单直观快捷,上手快。
-
适合临时测试或实验。
基于配置文件的方式:
-
配置文件描述了
What
,即应用最终要达到的状态。 -
配置文件提供了创建资源的模板,能够重复部署。
-
可以像管理代码一样管理部署。
-
适合正式的、跨环境的、规模化部署。
-
这种方式要求熟悉配置文件的语法,有一定难度。
kubectl apply
不但能够创建 Kubernetes 资源,也能对资源进行更新,非常方便。
不过 Kubernets 还提供了几个类似的命令,例如 kubectl create
、kubectl replace
、kubectl edit
和 kubectl patch
。
为避免造成不必要的困扰,我们会尽量只使用 kubectl apply
,
此命令已经能够应对超过 90% 的场景,事半功倍。
读懂 Deployment YAML
既然要用 YAML 配置文件部署应用,现在就很有必要了解一下 Deployment 的配置格式,其他 Controller(比如 DaemonSet)非常类似。
还是以 nginx-deployment 为例,配置文件如下图所示:
① apiVersion
是当前配置格式的版本。
② kind
是要创建的资源类型,这里是 Deployment
。
③ metadata
是该资源的元数据,name
是必需的元数据项。
④ spec
部分是该 Deployment
的规格说明。
⑤ replicas
指明副本数量,默认为 1。
⑥ template
定义 Pod 的模板,这是配置文件的重要部分。
⑦ metadata
定义 Pod 的元数据,至少要定义一个 label。label 的 key 和 value 可以任意指定。
⑧ spec
描述 Pod 的规格,此部分定义 Pod 中每一个容器的属性,name
和 image
是必需的。
此 nginx.yml 是一个最简单的 Deployment 配置文件,后面我们学习 Kubernetes 各项功能时会逐步丰富这个文件。
先删除之前操作创建的Depolyment:
kubectl delete deployment nginx-deployment
执行 kubectl apply -f nginx.yml
:
daweij@master:~/stady01/nginx$ kubectl apply -f nginx.yml deployment "nginx-deployment" created daweij@master:~/stady01/nginx$ kubectl get deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE httpd-app 2 2 2 2 1h kubernetes-bootcamp 2 2 2 2 6h nginx-deployment 2 2 2 1 9s
daweij@master:~/stady01/nginx$ kubectl get replicaset NAME DESIRED CURRENT READY AGE httpd-app-5fbccd7c6c 2 2 2 1h kubernetes-bootcamp-5d7f968ccb 2 2 2 6h kubernetes-bootcamp-7689dc585d 0 0 0 5h nginx-deployment-5cff94d9b 2 2 1 37s daweij@master:~/stady01/nginx$ kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE httpd-app-5fbccd7c6c-c8qq7 1/1 Running 0 1h 10.233.71.8 node3 httpd-app-5fbccd7c6c-jstpm 1/1 Running 0 1h 10.233.75.8 node2 kubernetes-bootcamp-5d7f968ccb-c57nw 1/1 Running 0 5h 10.233.75.7 node2 kubernetes-bootcamp-5d7f968ccb-lv24f 1/1 Running 0 5h 10.233.71.7 node3 nginx-deployment-5cff94d9b-5j79m 0/1 ContainerCreating 0 48s <none> node3 nginx-deployment-5cff94d9b-q7z8s 1/1 Running 0 48s 10.233.102.135 node1
Deployment、ReplicaSet、Pod 都已经就绪。
如果要删除这些资源,执行 kubectl delete deployment nginx-deployment
或者 kubectl delete -f nginx.yml
。
daweij@master:~/stady01/nginx$ kubectl delete -f nginx.yml deployment "nginx-deployment" deleted daweij@master:~/stady01/nginx$ kubectl get deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE httpd-app 2 2 2 2 1h kubernetes-bootcamp 2 2 2 2 6h