create-k8s-cluster-with-minikube

安装 kubectl & minikube

集群运行

查看 minikube 版本

1
$ minikube version

启动集群

1
$ minikube start

查看 kubectl 版本

1
$ kubectl version

查看集群信息

1
$ kubectl cluster-info

获取 node 节点

1
$ kubectl get nodes

使用 kubectl 创建部署

使用 kubectl create deployment 命令部署:
用法:

1
$ kubectl create deployment NAME --image=image [--dry-run] [options]

1
$ kubectl create deployment kubernetes-bootcamp --image=gcr.io/google-samples/kubernetes-bootcamp:v1

太好了! 您刚刚通过创建部署来部署了第一个应用程序。 这为您执行了一些操作:

  • 搜索可以在其中运行应用程序实例的合适节点(我们只有1个可用节点)
  • 安排应用程序在该节点上运行
  • 配置集群以在需要时在新节点上重新安排实例

    查看部署的应用信息

    使用 kubectl get deployments
    1
    2
    3
    $ kubectl get deployments
    NAME READY UP-TO-DATE AVAILABLE AGE
    kubernetes-bootcamp 1/1 1 1 9m6s

查看我们的应用

首先打开一个新的终端 使用 kubectl proxy

1
2
$ kubectl proxy
Starting to serve on 127.0.0.1:8001

我们可以使用curl命令直接通过API查询版本

1
2
3
4
5
6
7
8
9
10
11
12
$ curl http://localhost:8001/version
{
"major": "1",
"minor": "17",
"gitVersion": "v1.17.0",
"gitCommit": "70132b0f130acc0bed193d9ba59dd186f0e634cf",
"gitTreeState": "clean",
"buildDate": "2019-12-07T21:12:17Z",
"goVersion": "go1.13.4",
"compiler": "gc",
"platform": "linux/amd64"
}

如果8001端口不可访问,请确保上面的 kubectl proxy 命令运行正常。

API服务器将基于容器名称自动为每个容器创建一个端点,该端点也可以通过代理进行访问。
首先我们需要获取 Pod 名称,并将其存储在 环境变量 POD_NAME 中:

1
$ export POD_NAME=$(kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}')

1
2
$ echo Name of the Pod: $POD_NAME
Name of the Pod: kubernetes-bootcamp-69fbc6f4cf-xsx5g

使用Kubectl进行故障排除

常用命令:

  • kubectl get -列表资源
  • kubectl describe -显示有关资源的详细信息
  • kubectl logs -从容器中的容器中打印日志
  • kubectl exec -在容器中的容器上执行命令
1
2
3
4
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-69fbc6f4cf-xsx5g 1/1 Running 0 43m
#### 查看容器日志
1
$ kubectl logs $POD_NAME

在容器中执行命令

列出容器环境变量

1
$ kubectl exec $POD_NAME env

接下来,让我们在Pod的容器中开始bash会话

1
$ kubectl exec -ti $POD_NAME bash

该应用程序的源代码位于server.js文件中

1
cat server.js

您可以通过运行curl命令来检查应用程序是否启动

1
2
root@kubernetes-bootcamp-69fbc6f4cf-xsx5g:/# curl localhost:8080
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-69fbc6f4cf-xsx5g | v=1

接下来,让我们列出集群中的当前服务

1
2
3
$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 26h

使用 kubectl expose 命令去创建新服务并将其公开给外部流量

1
$ kubectl expose deployment/kubernetes-bootcamp --type="NodePort" --port 8080

再次查看服务

1
2
3
4
$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 26h
kubernetes-bootcamp NodePort 10.96.75.184 <none> 8080:31803/TCP 25s

为了找出外部打开了哪个端口(通过NodePort选项),我们将运行describe service命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ kubectl describe services/kubernetes-bootcamp
Name: kubernetes-bootcamp
Namespace: default
Labels: app=kubernetes-bootcamp
Annotations: <none>
Selector: app=kubernetes-bootcamp
Type: NodePort
IP: 10.96.75.184
Port: <unset> 8080/TCP
TargetPort: 8080/TCP
NodePort: <unset> 31803/TCP
Endpoints: 172.17.0.4:8080
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>

接下来,创建一个名为 NODE_PORT 的环境变量,并给改变量赋值:

1
$ export NODE_PORT=$(kubectl get services/kubernetes-bootcamp -o go-template='{{(index .spec.ports 0).nodePort}}')

输出 NODE_PORT

1
2
$ echo NODE_PORT=$NODE_PORT
NODE_PORT=31803

现在,我们可以使用curl,Node的IP和外部暴露的端口来测试该应用程序是否在群集外部暴露:

1
2
$ curl $(minikube ip):$NODE_PORT
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-69fbc6f4cf-xsx5g | v=1

使用标签(labels)

部署会自动为我们的Pod创建一个标签。 使用describe deployment命令,您可以看到标签的名称

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
$ kubectl describe deployment
Name: kubernetes-bootcamp
Namespace: default
CreationTimestamp: Fri, 27 Dec 2019 02:24:23 +0000
Labels: app=kubernetes-bootcamp
Annotations: deployment.kubernetes.io/revision: 1
Selector: app=kubernetes-bootcamp
Replicas: 1 desired | 1 updated | 1 total | 1 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=kubernetes-bootcamp
Containers:
kubernetes-bootcamp:
Image: gcr.io/google-samples/kubernetes-bootcamp:v1
Port: <none>
Host Port: <none>
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Progressing True NewReplicaSetAvailable
Available True MinimumReplicasAvailable
OldReplicaSets: <none>
NewReplicaSet: kubernetes-bootcamp-69fbc6f4cf (1/1 replicas created)
Events: <none>

利用labels获取pos和services
kubectl describe deployment命令获取到Labels: app=kubernetes-bootcamp

1
2
3
$ kubectl get pods -l app=kubernetes-bootcamp
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-69fbc6f4cf-xsx5g 1/1 Running 0 5h20m

1
2
3
$ kubectl get services -l app=kubernetes-bootcamp
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes-bootcamp NodePort 10.96.75.184 <none> 8080:31803/TCP 3h51m

想要添加自定义的标签(label),可以使用 kubectl label命令:

1
$ kubectl label pod $POD_NAME appversion=v1

查看添加的lables

1
$ kubectl describe pods $POD_NAME

用自定义标签(label)获取Pod:

1
2
3
$ kubectl get pod -l appversion=v1
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-69fbc6f4cf-xsx5g 1/1 Running 0 6h21m

删除服务(services)

首先查看有哪些服务(services)

1
2
3
4
$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 30h
kubernetes-bootcamp NodePort 10.96.75.184 <none> 8080:31803/TCP 4h23m

使用标签删除服务

1
2
$ kubectl delete service -l app=kubernetes-bootcamp
service "kubernetes-bootcamp" deleted

再次查看服务(services)

1
2
3
$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 30h

curl 检测对外暴露的服务也停止了

1
$ curl $(minikube ip):$NODE_PORT

扩展部署(Scaling a deployment)

使用 kubectl scale扩展部署

1
2
$ kubectl scale deployments/kubernetes-bootcamp --replicas=4
deployment.apps/kubernetes-bootcamp scaled

1
2
3
$ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
kubernetes-bootcamp 4/4 4 4 30h

查看节点数量是否变化

1
2
3
4
5
6
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
kubernetes-bootcamp-69fbc6f4cf-fqfxs 1/1 Running 0 7m56s 172.17.0.5 minikube <none> <none>
kubernetes-bootcamp-69fbc6f4cf-qmkj2 1/1 Running 0 7m56s 172.17.0.7 minikube <none> <none>
kubernetes-bootcamp-69fbc6f4cf-r245z 1/1 Running 0 7m56s 172.17.0.6 minikube <none> <none>
kubernetes-bootcamp-69fbc6f4cf-xsx5g 1/1 Running 0 28h 172.17.0.4 minikube <none> <none>

查看部署日志

1
$ kubectl describe deployments/kubernetes-bootcamp

验证负载均衡

首先定义一个全部变量NODE_PORT

1
$ export NODE_PORT=$(kubectl get services/kubernetes-bootcamp -o go-template='{{(index .spec.ports 0).nodePort}}')

运行几次下面的命令,验证请求是否会分布到不同的节点。

1
$ curl $(minikube ip):$NODE_PORT

1
2
3
4
5
6
7
8
$ curl $(minikube ip):$NODE_PORT
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-69fbc6f4cf-r245z | v=1
$ curl $(minikube ip):$NODE_PORT
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-69fbc6f4cf-xsx5g | v=1
$ curl $(minikube ip):$NODE_PORT
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-69fbc6f4cf-r245z | v=1
$ curl $(minikube ip):$NODE_PORT
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-69fbc6f4cf-fqfxs | v=1

我们会根据每个请求选择不同的Pod。 这表明负载平衡正在工作。

升级你的应用

使用 kubectk set image命令

1
2
$ kubectl set image deployments/kubernetes-bootcamp kubernetes-bootcamp=jocatalin/kubernetes-bootcamp:v2
deployment.apps/kubernetes-bootcamp image updated

查看pods可以看见新生成的pods

1
2
3
4
5
6
7
$ kubectl get pods

NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-b4d9f565-9t665 1/1 Running 0 2m12s
kubernetes-bootcamp-b4d9f565-mnwtv 1/1 Running 0 2m15s
kubernetes-bootcamp-b4d9f565-n5559 1/1 Running 0 2m14s
kubernetes-bootcamp-b4d9f565-tfp6f 1/1 Running 0 2m10s

用curl来检查升级后的应用

1
2
3
4
5
6
$ curl $(minikube ip):$NODE_PORT
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-b4d9f565-mnwtv | v=2
$ curl $(minikube ip):$NODE_PORT
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-b4d9f565-9t665 | v=2
$ curl $(minikube ip):$NODE_PORT
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-b4d9f565-tfp6f | v=2

从输出上看应用是升级到了v2版本。

查看rollout状态

1
2
$ kubectl rollout status deployments/kubernetes-bootcamp
deployment "kubernetes-bootcamp" successfully rolled out

查看当前镜像版本

1
$ kubectl describe pods

回滚更新(Rollback an update)

首先将我们的应用升级到v10

1
2
$ kubectl set image deployments/kubernetes-bootcamp kubernetes-bootcamp=gcr.io/google-samples/kubernetes-bootcamp:v10
deployment.apps/kubernetes-bootcamp image updated

然后获取部署状态:

1
2
3
$ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
kubernetes-bootcamp 3/4 2 3 30h

可以看到只有3个节点READY,证明这个v10是有问题的。
下面让我们来获取pods

1
2
3
4
5
6
7
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-6b4c55d8fc-v85kx 0/1 ImagePullBackOff 0 4m1s
kubernetes-bootcamp-6b4c55d8fc-xw8bw 0/1 ImagePullBackOff 0 4m1s
kubernetes-bootcamp-b4d9f565-9t665 1/1 Running 0 23m
kubernetes-bootcamp-b4d9f565-mnwtv 1/1 Running 0 23m
kubernetes-bootcamp-b4d9f565-n5559 1/1 Running 0 23m

使用describe获取更多的信息

1
2
3
4
5
6
7
8
9
10
$ kubectl describe pods
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 27m default-scheduler Successfully assigned default/kubernetes-bootcamp-b4d9f565-n5559 to minikube
Normal Pulling 27m kubelet, minikube Pulling image "jocatalin/kubernetes-bootcamp:v2"
Normal Pulled 27m kubelet, minikube Successfully pulled image "jocatalin/kubernetes-bootcamp:v2"
Normal Created 27m kubelet, minikube Created container kubernetes-bootcamp
Normal Started 27m kubelet, minikube Started container kubernetes-bootcamp

从Events中看出没有 v10 版本的镜像。
接下来用kubectl rollout undo命令来进行回滚。

1
2
$ kubectl rollout undo deployments/kubernetes-bootcamp
deployment.apps/kubernetes-bootcamp rolled back

查看应用是否成功回滚至之前的版本

1
2
3
4
5
6
7
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-b4d9f565-9t665 1/1 Running 0 31m
kubernetes-bootcamp-b4d9f565-j2hmr 1/1 Running 0 96s
kubernetes-bootcamp-b4d9f565-mnwtv 1/1 Running 0 31m
kubernetes-bootcamp-b4d9f565-n5559 1/1 Running 0 31m
root@docker:~#

看到4个READY状pods。
用curl查看应用输出:

1
2
$ curl $(minikube ip):$NODE_PORT
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-b4d9f565-9t665 | v=2

参考文档

kubernetes-basics