本文档根据官方的示例教程编写,在本地 windows 环境中的 minikube 下进行的操作。
创建集群
Kubernetes 是一个生产级的开源平台,负责协调计算机集群内部和跨集群应用程序容器的布局(调度)和执行。
Kubernetes 集群由两种类型的资源组成:
- 用于协调集群的 Master
- 用于作为 worker 运行应用程序的 Node
启动集群
首先启动 minikube 。
$ minikube start
查看集群版本
可以通过 kubectl version 命令查看集群的版本,运行结果如下所示,会同时看到 client 和 server 两个版本号。其中,client 对应 kubectl 的版本,server 对应 Master 上安装的 Kubernetes 的版本。
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"15", GitVersion:"v1.15.3", GitCom
mit:"2d3c76f9091b6bec110a5e63777c332469e0cba2", GitTreeState:"clean", BuildDate:
"2019-08-19T11:13:54Z", GoVersion:"go1.12.9", Compiler:"gc", Platform:"windows/a
md64"}
Server Version: version.Info{Major:"1", Minor:"16", GitVersion:"v1.16.0", GitCom
mit:"2bd9643cee5b3b3a5ecbd3af49d09018f0773c77", GitTreeState:"clean", BuildDate:
"2019-09-18T14:27:17Z", GoVersion:"go1.12.9", Compiler:"gc", Platform:"linux/amd
64"}
查看集群详情
通过 kubectl cluster-info 命令查看集群的详情。
$ kubectl cluster-info
Kubernetes master is running at https://192.168.99.109:8443
KubeDNS is running at https://192.168.99.109:8443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
运行 kubectl get nodes 命令查看集群中的 Node 节点,这会显示所有可用于应用程序的节点。现在我们只有一个节点,且其 status 状态是 ready,表示可以用于部署应用程序。
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
minikube Ready master 13m v1.16.0
部署应用程序
部署应用
通过 kubectl run 命令在 Kubernetes 上运行我们的第一个应用,这里我们使用的镜像是 jocatalin/kubernetes-bootcamp 。
$ kubectl run kubernetes-bootcamp --image=jocatalin/kubernetes-
bootcamp:v1 --port=8080
kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in
a future version. Use kubectl run --generator=run-pod/v1 or kubectl create inste
ad.
deployment.apps/kubernetes-bootcamp created
如果需要删除所有通过 kubectl run 命令创建的 Deployment,可以运行下面命令:
kubectl delete deployments --all
现在,通过创建 Deployment 已经成功部署了第一个应用。通过下面命令列出所有的 Deployment:
$ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
kubernetes-bootcamp 1/1 1 1 4m21s
查看应用
Kubernetes 中运行的 Pod 运行在私有的隔离网络中。默认情况下,Pod 仅对同一个 Kubernetes 集群中的 service 和其他 Pod 可见。当我们使用 kubectl 时,会通过 API 终端交互,实现与应用程序的通信。
kubectl 命令可以创建代理,将通信转发到集群范围的专用网络。代理可以通过 control-C 终止,并且在运行时不会显示任何输出。
打开第二个终端窗口来运行代理。
$ kubectl proxy
Starting to serve on 127.0.0.1:8001
在浏览器中访问 http://127.0.0.1:8001 ,可以看到所有可以访问的API。
API 服务器会基于 Pod 的名字自动为每个 Pod 创建一个终端,这个终端也可以通过代理访问。
先获取 pod 名称。
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-756f66956c-hzl28 1/1 Running 0 36m
然后访问 http://localhost:8001/api/v1/namespaces/default/pods/kubernetes-bootcamp-756f66956c-hzl28/proxy/ 。
探索应用
使用 kubectl 进行故障排除时,最常见的命令包括:
- kubectl get - 列出资源
- kubectl describe - 显示有关资源的详细信息
- kubectl logs - 从 Pod 中的容器打印日志
- kubectl exec - 在 Pod 中的容器上执行命令
使用这些命令查看应用程序的部署时间、当前状态、运行位置以及配置信息。
检查应用配置
下前面部署的应用是否正在运行。使用 kubectl get 命令查看存在的 Pod:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-756f66956c-hzl28 1/1 Running 0 36m
如果没有运行中的 Pod,再次执行上面命令(部署需要几秒钟的时间)。
然后,查看这个 Pod 里面有哪些容器,这些容器是通过哪些镜像构建的。使用 kubectl describe pods 命令:
Name: kubernetes-bootcamp-756f66956c-hzl28
Namespace: default
Priority: 0
Node: minikube/10.0.2.15
Start Time: Mon, 13 Jan 2020 17:19:10 +0800
Labels: pod-template-hash=756f66956c
run=kubernetes-bootcamp
Annotations:
Status: Running
IP: 172.17.0.4
Controlled By: ReplicaSet/kubernetes-bootcamp-756f66956c
Containers:
kubernetes-bootcamp:
Container ID: docker://503afe3da8a94491460f2cb4629240e3dc9cf1ca44723606030
a4800dd5cb1b3
Image: jocatalin/kubernetes-bootcamp:v1
Image ID: docker-pullable://jocatalin/kubernetes-bootcamp@sha256:0d6b8
ee63bb57c5f5b6156f446b3bc3b3c143d233037f3a2f00e279c8fcc64af
Port: 8080/TCP
Host Port: 0/TCP
State: Running
Started: Mon, 13 Jan 2020 17:21:48 +0800
Ready: True
Restart Count: 0
Environment:
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-ks2qf (ro
)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-ks2qf:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-ks2qf
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
/kubernetes-bootcamp-756f66956c-hzl28 to minikube
Normal Pulling 50m kubelet, minikube Pulling image "jocatalin/kube
rnetes-bootcamp:v1"
Normal Pulled 47m kubelet, minikube Successfully pulled image "jo
catalin/kubernetes-bootcamp:v1"
Normal Created 47m kubelet, minikube Created container kubernetes-
bootcamp
Normal Started 47m kubelet, minikube Started container kubernetes-
bootcamp
这里会看到 Pod 中容器的详情:IP 地址,使用的端口号,和 Pod 生命周期相关的事件列表。
查看容器日志
应用程序发送到 STDOUT 的任何内容都将成为 Pod 中容器的日志。使用 kubectl logs 命令检索这些日志:
$ kubectl logs kubernetes-bootcamp-756f66956c-hzl28
Kubernetes Bootcamp App Started At: 2020-01-13T09:21:48.466Z | Running On: kube
rnetes-bootcamp-756f66956c-hzl28
Running On: kubernetes-bootcamp-756f66956c-hzl28 | Total Requests: 1 | App Uptim
e: 2115.696 seconds | Log Time: 2020-01-13T09:57:04.163Z
在容器中执行命令
Pod 启动并运行后,可以直接在容器中执行命令。使用 exec 命令时需要指定 Pod 的名字作为参数。列出环境变量:
$ kubectl exec kubernetes-bootcamp-756f66956c-hzl28 env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=kubernetes-bootcamp-756f66956c-hzl28
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
KUBERNETES_SERVICE_HOST=10.96.0.1
KUBERNETES_SERVICE_PORT=443
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_PORT_443_TCP_PROTO=tcp
NPM_CONFIG_LOGLEVEL=info
NODE_VERSION=6.3.1
HOME=/root
在 Pod 的容器中开始一个 bash 会话:
$ kubectl exec -ti kubernetes-bootcamp-756f66956c-hzl28 bash
现在,在我们运行 NodeJS 应用程序的容器中开启了会话。查看应用程序的源代码文件 server.js :
root@kubernetes-bootcamp-756f66956c-hzl28:/# cat server.js
var http = require('http');
var requests=0;
var podname= process.env.HOSTNAME;
var startTime;
var host;
var handleRequest = function(request, response) {
response.setHeader('Content-Type', 'text/plain');
response.writeHead(200);
response.write("Hello Kubernetes bootcamp! | Running on: ");
response.write(host);
response.end(" | v=1\n");
console.log("Running On:" ,host, "| Total Requests:", ++requests,"| App Uptime
:", (new Date() - startTime)/1000 , "seconds", "| Log Time:",new Date());
}
var www = http.createServer(handleRequest);
www.listen(8080,function () {
startTime = new Date();;
host = process.env.HOSTNAME;
console.log ("Kubernetes Bootcamp App Started At:",startTime, "| Running On:
" ,host, "\n" );
});
可以通过 curl 命令确认应用程序是否启动并在运行中(这里是在 NodeJS 容器内执行命令,所以可以使用 localhost):
root@kubernetes-bootcamp-756f66956c-hzl28:/# curl localhost:8080
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-756f66956c-hzl28 |v=1
然后使用 exit 命令退出。
root@kubernetes-bootcamp-756f66956c-hzl28:/# exit
exit
暴露应用到外网
虽然每个 Pod 具有唯一的 IP 地址,但是如果没有 Service,这些 IP 不会暴露到集群外部。Service 允许应用程序接收流量。通过在 ServiceSpec 中指定类型,可以以不同的方式暴露 Service:
- ClusterIP(默认) - 将 Service 公开在集群的内部 IP 上。这种类型使服务只能从集群内访问。
- NodePort - 使用 NAT 在集群中每个选定节点的同一端口上暴露 Service。使用
: 使集群外部的服务可访问。ClusterIP 的超集。 - LoadBalancer - 在当前云中创建外部负载平衡器(如果支持)并为服务分配固定的外部 IP。NodePort 的超集。
- ExternalName - 使用任意名称(由规范中的externalName指定)通过返回具有名称的 CNAME 记录来暴露 Service。没有使用代理。需要 v1.7 或更高版本的 kube-dns。
创建 Service
列出集群当前运行的 Service:
$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 443/TCP 25h
有一个名为 Kubernetes 的 Service,在 Minikube 启动集群时会默认创建这个服务。通过 expose 命令,使用 NodePort 参数(Minikube 暂时不支持 LoadBalancer),创建新 Service 并将其暴露到外网:
$ kubectl expose deployment/kubernetes-bootcamp --type="NodePort" --port 8080
service/kubernetes-bootcamp exposed
再次列出集群当前运行的 Service:
$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
AGE
kubernetes ClusterIP 10.96.0.1 443/TCP
25h
kubernetes-bootcamp NodePort 10.107.185.136 8080:30087/TCP
30s
kubernetes-bootcamp 这个 Service 已经运行了。可以看到,这个 Service 有一个唯一的 CLUSTER-IP,一个内部端口号以及一个 EXTERNAL-IP(Node 节点的 IP)。
要找出开放到外部的端口(通过 NodePort 选项)是哪个,需要运行 kubectl describe service 命令:
$ kubectl describe services/kubernetes-bootcamp
Name: kubernetes-bootcamp
Namespace: default
Labels: run=kubernetes-bootcamp
Annotations:
Selector: run=kubernetes-bootcamp
Type: NodePort
IP: 10.107.185.136
Port: 8080/TCP
TargetPort: 8080/TCP
NodePort: 30087/TCP
Endpoints: 172.17.0.4:8080
Session Affinity: None
External Traffic Policy: Cluster
Events:
查看 minikube 的 ip。
$ minikube ip
192.168.99.109
在本机浏览器中访问 http://192.168.99.109:30087/。
Service 暴露成功。
使用标签
Deployment 自动为 Pod 创建了一个标签。使用 kubectl describe deployment 命令,可以看到标签的名称:
$ kubectl describe deployment
Name: kubernetes-bootcamp
Namespace: default
CreationTimestamp: Mon, 13 Jan 2020 17:19:10 +0800
Labels: run=kubernetes-bootcamp
Annotations: deployment.kubernetes.io/revision: 1
Selector: run=kubernetes-bootcamp
Replicas: 1 desired | 1 updated | 1 total | 1 available | 0 unavai
lable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: run=kubernetes-bootcamp
Containers:
kubernetes-bootcamp:
Image: jocatalin/kubernetes-bootcamp:v1
Port: 8080/TCP
Host Port: 0/TCP
Environment:
Mounts:
Volumes:
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets:
NewReplicaSet: kubernetes-bootcamp-756f66956c (1/1 replicas created)
Events:
可以通过这个标签查询 Pod。使用 kubectl get pods 命令时,通过 -l 参数指定标签值:
$ kubectl get pods -l run=kubernetes-bootcamp
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-756f66956c-hzl28 1/1 Running 0 25h
查看 Service 时,也可以使用这个参数:
$ kubectl get services -l run=kubernetes-bootcamp
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
AGE
kubernetes-bootcamp NodePort 10.107.185.136 8080:30087/TCP
26m
可以通过 kubectl label 对象类型 对象名字 新标签 命令创建新标签:
$ kubectl get services -l run=kubernetes-bootcamp
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
AGE
kubernetes-bootcamp NodePort 10.107.185.136 8080:30087/TCP
26m
这会为我们的 Pod 应用一个新标签(这里将应用程序的版本固定到 Pod),可以使用 kubectl describe pod 命令检查:
$ kubectl describe pods kubernetes-bootcamp-756f66956c-hzl28
Name: kubernetes-bootcamp-756f66956c-hzl28
Namespace: default
Priority: 0
Node: minikube/10.0.2.15
Start Time: Mon, 13 Jan 2020 17:19:10 +0800
Labels: app=v1
pod-template-hash=756f66956c
run=kubernetes-bootcamp
Annotations:
Status: Running
IP: 172.17.0.4
Controlled By: ReplicaSet/kubernetes-bootcamp-756f66956c
Containers:
kubernetes-bootcamp:
Container ID: docker://503afe3da8a94491460f2cb4629240e3dc9cf1ca44723606030
a4800dd5cb1b3
Image: jocatalin/kubernetes-bootcamp:v1
Image ID: docker-pullable://jocatalin/kubernetes-bootcamp@sha256:0d6b8
ee63bb57c5f5b6156f446b3bc3b3c143d233037f3a2f00e279c8fcc64af
Port: 8080/TCP
Host Port: 0/TCP
State: Running
Started: Mon, 13 Jan 2020 17:21:48 +0800
Ready: True
Restart Count: 0
Environment:
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-ks2qf (ro
)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-ks2qf:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-ks2qf
Optional: false
QoS Class: BestEffort
Node-Selectors:
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
看到标签附加到了 Pod 上,现在可以使用这个新标签来查询 Pod 列表了。
$ kubectl get pods -l app=v1
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-756f66956c-hzl28 1/1 Running 0 2d16h
删除 Service
通过 kubectl delete service -l your-label 命令删除 Service。
kubectl delete service -l run=kubernetes-bootcamp
service "kubernetes-bootcamp" deleted
确认 Service 删除是否成功:
kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 443/TCP 2d17h
这里会发现 Service 删除成功。之前暴露的 IP 地址和端口号确认路由不再暴露到外网,http://192.168.99.109:30087/ 已经无法访问。
这证明集群外部无法继续访问我们的应用程序了。可以通过在 Pod 内部执行 curl 来验证应用程序仍然在运行中:
$ kubectl exec -ti kubernetes-bootcamp-756f66956c-hzl28 curl lo
calhost:8080
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-756f66956c-hzl28 |
v=1
可以看到应用仍在运行。
伸缩应用
Deployment 只创建一个 Pod 来运行我们的应用程序。当流量增加时,我们需要扩展应用以满足用户需求。应用的伸缩是通过改变 Deployment 中副本的数量来完成的。可以使用 kubectl run 命令的 --replicas 参数从头开始创建具有多个实例的Deployment。
列出 Pod:
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP
NODE NOMINATED NODE READINESS GATES
kubernetes-bootcamp-756f66956c-hzl28 1/1 Running 0 2d18h 172.
17.0.4 minikube
列出 Deployment:
$ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
kubernetes-bootcamp 1/1 1 1 2d18h
这时候应该只有 1 个 Pod。各字段的解释如下:
- DESIRED 字段显示配置的副本数量
- CURRENT 字段显示现在有多少副本正在运行
- UP-TO-DATE 是已更新的副本数量,在滚动更新时,这个数字会从 0 增大到 DESIRED 字段值
- AVAILABLE 字段显示用户实际可用的副本数量
将 Deployment 扩展到 4 个副本。使用 kubectl scale 命令时,指定 Deployment 类型、名称以及所需实例的数量:
$ kubectl scale deployments/kubernetes-bootcamp --replicas=4
deployment.apps/kubernetes-bootcamp scaled
再次列出可用的 Deployment:
kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
kubernetes-bootcamp 4/4 4 4 2d18h
更改已生效,现在应用程序有 4 个可用实例。接下来,看一下 Pod 的数量是否发生了变化:
kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP
NODE NOMINATED NODE READINESS GATES
kubernetes-bootcamp-756f66956c-9lbhm 1/1 Running 0 25s 172.
17.0.6 minikube
kubernetes-bootcamp-756f66956c-hzl28 1/1 Running 0 2d18h 172.
17.0.4 minikube
kubernetes-bootcamp-756f66956c-lw5d7 1/1 Running 0 25s 172.
17.0.5 minikube
kubernetes-bootcamp-756f66956c-z4bwp 1/1 Running 0 25s 172.
17.0.7 minikube
现在有 4 个具有不同 IP 地址的 Pod。更改已在 Deployment 事件日志中注册。使用 describe 命令查看:
$ kubectl describe deployments/kubernetes-bootcamp
Name: kubernetes-bootcamp
Namespace: default
CreationTimestamp: Mon, 13 Jan 2020 17:19:10 +0800
Labels: run=kubernetes-bootcamp
Annotations: deployment.kubernetes.io/revision: 1
Selector: run=kubernetes-bootcamp
Replicas: 4 desired | 4 updated | 4 total | 4 available | 0 unavai
lable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: run=kubernetes-bootcamp
Containers:
kubernetes-bootcamp:
Image: jocatalin/kubernetes-bootcamp:v1
Port: 8080/TCP
Host Port: 0/TCP
Environment:
Mounts:
Volumes:
Conditions:
Type Status Reason
---- ------ ------
Progressing True NewReplicaSetAvailable
Available True MinimumReplicasAvailable
OldReplicaSets:
NewReplicaSet: kubernetes-bootcamp-756f66956c (4/4 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 97s deployment-controller Scaled up replica set
kubernetes-bootcamp-756f66956c to 4
从这个命令的输出中也可以看到现在有 4 个副本。
负载均衡
再次创建 Service 暴露端口。
$ kubectl expose deployment/kubernetes-bootcamp --type="NodePor
t" --port 8080
service/kubernetes-bootcamp exposed
通过 describe 命令找出暴露的 IP 地址和端口:
$ kubectl describe services/kubernetes-bootcamp
Name: kubernetes-bootcamp
Namespace: default
Labels: run=kubernetes-bootcamp
Annotations:
Selector: run=kubernetes-bootcamp
Type: NodePort
IP: 10.108.207.197
Port: 8080/TCP
TargetPort: 8080/TCP
NodePort: 31174/TCP
Endpoints: 172.17.0.4:8080,172.17.0.5:8080,172.17.0.6:8080 + 1 mo
re...
Session Affinity: None
External Traffic Policy: Cluster
Events:
在浏览器中多次访问 http://192.168.99.109:31174/ 。
请求会命中不同的 Pod。这证明负载均衡生效了。
缩减应用
再次运行 kubectl scale 命令将 Service 缩减为 2 个副本:
$ kubectl scale deployment/kubernetes-bootcamp --replicas=2
deployment.apps/kubernetes-bootcamp scaled
列出 Deployment 来验证变更是否生效:
$ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
kubernetes-bootcamp 2/2 2 2 3d15h
期望的副本数是 2。列出 Pod 的数量:
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE
IP NODE NOMINATED NODE READINESS GATES
kubernetes-bootcamp-756f66956c-9lbhm 1/1 Running 0 21h
172.17.0.6 minikube
kubernetes-bootcamp-756f66956c-hzl28 1/1 Running 0 3d15h
172.17.0.4 minikube
kubernetes-bootcamp-756f66956c-lw5d7 1/1 Terminating 0 21h
172.17.0.5 minikube
kubernetes-bootcamp-756f66956c-z4bwp 1/1 Terminating 0 21h
172.17.0.7 minikube
只剩 2 个运行中的 Pod 了。
滚动更新
用户希望应用程序随时都可以访问,而开发者希望每天能部署几个新版本。在 Kubernetes 中通过滚动更新实现这两个目的。滚动更新使用新的实例逐个更新 Pod(而不是一次全部更新),从而实现不停机对 Deployment 的更新。新 Pod 将分配到具有可用资源的节点上。
滚动更新允许执行以下操作:
- 将应用程序从一个环境推到另一个环境(通过容器镜像更新)
- 回退到以前的版本
- 以零停机时间持续集成和持续交付应用程序
更新版本
执行 set image 命令,并指定 Deployment 名称及新镜像,升级应用程序的镜像到版本 2。
$ kubectl set image deployments/kubernetes-bootcamp kubernetes-
bootcamp=jocatalin/kubernetes-bootcamp:v2
deployment.apps/kubernetes-bootcamp image updated
命令通知 Deployment 为应用程序使用不同的镜像,并初始化滚动更新。检查新 Pod 的状态:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-756f66956c-9lbhm 1/1 Terminating 0 23h
kubernetes-bootcamp-756f66956c-hzl28 1/1 Terminating 0 3d18h
kubernetes-bootcamp-7d6f8694b6-hxw49 1/1 Running 0 19s
kubernetes-bootcamp-7d6f8694b6-lqfwl 1/1 Running 0 6s
验证升级
首先,检查应用程序是否在运行。通过 describe service 命令找出暴露的 IP 地址和端口号:
kubectl describe services/kubernetes-bootcamp
Name: kubernetes-bootcamp
Namespace: default
Labels: run=kubernetes-bootcamp
Annotations:
Selector: run=kubernetes-bootcamp
Type: NodePort
IP: 10.108.207.197
Port: 8080/TCP
TargetPort: 8080/TCP
NodePort: 31174/TCP
Endpoints: 172.17.0.5:8080,172.17.0.7:8080
Session Affinity: None
External Traffic Policy: Cluster
Events:
在浏览器中访问 http://192.168.99.109:31174/ 。
每次请求命中的 Pod 都运行最新版本(v2)。
更新也可以通过 rollout status 命令来确认:
$ kubectl rollout status deployments/kubernetes-bootcamp
deployment "kubernetes-bootcamp" successfully rolled out
通过在 Pod 上执行 describe 命令来查看应用程序当前运行的镜像的版本号:
$ kubectl describe pods
Name: kubernetes-bootcamp-7d6f8694b6-hxw49
Namespace: default
Priority: 0
Node: minikube/10.0.2.15
Start Time: Fri, 17 Jan 2020 11:25:41 +0800
Labels: pod-template-hash=7d6f8694b6
run=kubernetes-bootcamp
Annotations:
Status: Running
IP: 172.17.0.5
Controlled By: ReplicaSet/kubernetes-bootcamp-7d6f8694b6
Containers:
kubernetes-bootcamp:
Container ID: docker://d9e2d35e01dbd9f2168fd017377df467867f4ae0c8297f3f4af
2bbe2dd49f10a
Image: jocatalin/kubernetes-bootcamp:v2
Image ID: docker-pullable://jocatalin/kubernetes-bootcamp@sha256:fb1a3
ced00cecfc1f83f18ab5cd14199e30adc1b49aa4244f5d65ad3f5feb2a5
Port: 8080/TCP
Host Port: 0/TCP
State: Running
Started: Fri, 17 Jan 2020 11:25:53 +0800
Ready: True
Restart Count: 0
Environment:
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-ks2qf (ro
)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-ks2qf:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-ks2qf
Optional: false
QoS Class: BestEffort
Node-Selectors:
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Name: kubernetes-bootcamp-7d6f8694b6-lqfwl
Namespace: default
Priority: 0
Node: minikube/10.0.2.15
Start Time: Fri, 17 Jan 2020 11:25:54 +0800
Labels: pod-template-hash=7d6f8694b6
run=kubernetes-bootcamp
Annotations:
Status: Running
IP: 172.17.0.7
Controlled By: ReplicaSet/kubernetes-bootcamp-7d6f8694b6
Containers:
kubernetes-bootcamp:
Container ID: docker://a2faa786f854e9a81f7cc702d4c12291e14e06a70c9bcad6627
873477fe6aa85
Image: jocatalin/kubernetes-bootcamp:v2
Image ID: docker-pullable://jocatalin/kubernetes-bootcamp@sha256:fb1a3
ced00cecfc1f83f18ab5cd14199e30adc1b49aa4244f5d65ad3f5feb2a5
Port: 8080/TCP
Host Port: 0/TCP
State: Running
Started: Fri, 17 Jan 2020 11:25:55 +0800
Ready: True
Restart Count: 0
Environment:
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-ks2qf (ro
)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-ks2qf:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-ks2qf
Optional: false
QoS Class: BestEffort
Node-Selectors:
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
查看 Image 字段,现在运行的是应用程序的版本 2。
回滚更新
现在执行另外一个更新,部署标记为 v10 的镜像:
$ kubectl set image deployments/kubernetes-bootcamp kubernetes-
bootcamp=gcr.io/google-samples/kubernetes-bootcamp:v10
deployment.apps/kubernetes-bootcamp image updated
查看 Deployment 的状态:
$ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
kubernetes-bootcamp 2/2 1 2 3d23h
查看所有的 Pod:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-7d6f8694b6-hxw49 1/1 Running 0 5h2m
kubernetes-bootcamp-7d6f8694b6-lqfwl 1/1 Running 0 5h2m
kubernetes-bootcamp-886577c5d-9nrxt 0/1 ErrImagePull 0 23s
发现有报错,Pod 的 describe 命令可以提供更多信息:
$ kubectl describe pods
Name: kubernetes-bootcamp-7d6f8694b6-hxw49
Namespace: default
Priority: 0
Node: minikube/10.0.2.15
Start Time: Fri, 17 Jan 2020 11:25:41 +0800
Labels: pod-template-hash=7d6f8694b6
run=kubernetes-bootcamp
Annotations:
Status: Running
IP: 172.17.0.5
Controlled By: ReplicaSet/kubernetes-bootcamp-7d6f8694b6
Containers:
kubernetes-bootcamp:
Container ID: docker://d9e2d35e01dbd9f2168fd017377df467867f4ae0c8297f3f4af
2bbe2dd49f10a
Image: jocatalin/kubernetes-bootcamp:v2
Image ID: docker-pullable://jocatalin/kubernetes-bootcamp@sha256:fb1a3
ced00cecfc1f83f18ab5cd14199e30adc1b49aa4244f5d65ad3f5feb2a5
Port: 8080/TCP
Host Port: 0/TCP
State: Running
Started: Fri, 17 Jan 2020 11:25:53 +0800
Ready: True
Restart Count: 0
Environment:
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-ks2qf (ro
)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-ks2qf:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-ks2qf
Optional: false
QoS Class: BestEffort
Node-Selectors:
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Name: kubernetes-bootcamp-7d6f8694b6-lqfwl
Namespace: default
Priority: 0
Node: minikube/10.0.2.15
Start Time: Fri, 17 Jan 2020 11:25:54 +0800
Labels: pod-template-hash=7d6f8694b6
run=kubernetes-bootcamp
Annotations:
Status: Running
IP: 172.17.0.7
Controlled By: ReplicaSet/kubernetes-bootcamp-7d6f8694b6
Containers:
kubernetes-bootcamp:
Container ID: docker://a2faa786f854e9a81f7cc702d4c12291e14e06a70c9bcad6627
873477fe6aa85
Image: jocatalin/kubernetes-bootcamp:v2
Image ID: docker-pullable://jocatalin/kubernetes-bootcamp@sha256:fb1a3
ced00cecfc1f83f18ab5cd14199e30adc1b49aa4244f5d65ad3f5feb2a5
Port: 8080/TCP
Host Port: 0/TCP
State: Running
Started: Fri, 17 Jan 2020 11:25:55 +0800
Ready: True
Restart Count: 0
Environment:
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-ks2qf (ro
)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-ks2qf:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-ks2qf
Optional: false
QoS Class: BestEffort
Node-Selectors:
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Name: kubernetes-bootcamp-886577c5d-9nrxt
Namespace: default
Priority: 0
Node: minikube/10.0.2.15
Start Time: Fri, 17 Jan 2020 16:27:31 +0800
Labels: pod-template-hash=886577c5d
run=kubernetes-bootcamp
Annotations:
Status: Pending
IP: 172.17.0.4
Controlled By: ReplicaSet/kubernetes-bootcamp-886577c5d
Containers:
kubernetes-bootcamp:
Container ID:
Image: gcr.io/google-samples/kubernetes-bootcamp:v10
Image ID:
Port: 8080/TCP
Host Port: 0/TCP
State: Waiting
Reason: ErrImagePull
Ready: False
Restart Count: 0
Environment:
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-ks2qf (ro
)
Conditions:
Type Status
Initialized True
Ready False
ContainersReady False
PodScheduled True
Volumes:
default-token-ks2qf:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-ks2qf
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 assigne
d default/kubernetes-bootcamp-886577c5d-9nrxt to minikube
Normal Pulling 34s (x2 over 61s) kubelet, minikube Pulling image "gcr.i
o/google-samples/kubernetes-bootcamp:v10"
Warning Failed 19s (x2 over 46s) kubelet, minikube Failed to pull image
"gcr.io/google-samples/kubernetes-bootcamp:v10": rpc error: code = Unknown desc
= Error response from daemon: Get https://gcr.io/v2/: net/http: request cancele
d while waiting for connection (Client.Timeout exceeded while awaiting headers)
Warning Failed 19s (x2 over 46s) kubelet, minikube Error: ErrImagePull
Normal BackOff 4s (x2 over 46s) kubelet, minikube Back-off pulling ima
ge "gcr.io/google-samples/kubernetes-bootcamp:v10"
Warning Failed 4s (x2 over 46s) kubelet, minikube Error: ImagePullBack
Off
仓库中没有名为 v10 的镜像。现在要回到之前的可以正常工作的版本。使用 rollout undo 命令:
$ kubectl rollout undo deployments/kubernetes-bootcamp
deployment.apps/kubernetes-bootcamp rolled back
rollout 命令将 Deployment 恢复到之前已知的状态(v2 版本的镜像)。更新是版本化的,你可以恢复到任何之前知道的 Deployment 状态。再次列出 Pods:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-7d6f8694b6-hxw49 1/1 Running 0 5h11m
kubernetes-bootcamp-7d6f8694b6-lqfwl 1/1 Running 0 5h11m
可以看到已经回退。