[k8s] minikube的使用与应用部署
minikube的使用与应用部署
0. 安装minikube
minikube是K8s的单机版本,通过minikube可以熟悉k8s的运行机理和工具。
安装十分简单,只需拉取二进制文件,然后放到可执行目录即可:
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
1. 创建和查看集群
运行minikube start命令得以启动集群,在有网环境下自动拉取所需的镜像:
(base) wildkid1024@debian:~$ minikube start
?? Debian 11.3 (kvm/amd64) 上的 minikube v1.25.2
? 根据现有的配置文件使用 docker 驱动程序
?? Starting control plane node minikube in cluster minikube
?? Pulling base image ...
?? Restarting existing docker container for "minikube" ...
?? 正在 Docker 20.10.12 中准备 Kubernetes v1.23.3…
? kubelet.housekeeping-interval=5m
?? Verifying Kubernetes components...
? Using image gcr.io/k8s-minikube/storage-provisioner:v5
? Using image kubernetesui/dashboard:v2.3.1
? Using image kubernetesui/metrics-scraper:v1.0.7
?? Enabled addons: storage-provisioner, default-storageclass, dashboard
? The image 'k8s.gcr.io/kube-proxy' was not found; unable to add it to cache.
? The image 'k8s.gcr.io/kube-controller-manager' was not found; unable to add it to cache.
?? Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default
使用kubectl命令查看当前集群的信息,可以看到集群控制平面的运行地址和对应的DNS接口:
(base) wildkid1024@debian:~$ kubectl cluster-info
Kubernetes control plane is running at https://192.168.49.2:8443
CoreDNS is running at https://192.168.49.2:8443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
也可查看每个node的具体信息:
(base) wildkid1024@debian:~$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
minikube Ready control-plane,master 9d v1.23.3
2. 部署应用到集群中
通过kubectl create deloyment命令将应用部署到k8s集群当中,其对应的参数为部署名称和相应的镜像位置。比如通过一个简单的方式创建一个nodejs应用:
(base) wildkid1024@debian:~$ kubectl create deployment kubernetes-bootcamp --image=gcr.io/google-samples/kubernetes-bootcamp:v1
deployment.apps/kubernetes-bootcamp created
然后通过get deployments命令查看我们刚刚部署的应用的状态:
(base) wildkid1024@debian:~$ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
kubernetes-bootcamp 1/1 1 1 34s
如何查看里面的部署是否正常工作?通过kubectl proxy进行临时调试,首先要打开调试代理接口:
(base) wildkid1024@debian:~$ kubectl proxy
Starting to serve on 127.0.0.1:8001
确认node API可访问:
(base) wildkid1024@debian:~$ curl http://localhost:8001/version
{
"major": "1",
"minor": "23",
"gitVersion": "v1.23.3",
"gitCommit": "816c97ab8cff8a1c72eccca1026f7820e93e0d25",
"gitTreeState": "clean",
"buildDate": "2022-01-25T21:19:12Z",
"goVersion": "go1.17.6",
"compiler": "gc",
"platform": "linux/amd64"
}
确认相应的pod的API也可访问,里面有相应pod描述和信息:
(base) wildkid1024@debian:~$ curl http://localhost:8001/api/v1/namespaces/default/pods/kubernetes-bootcamp-65d5b99f84-b2d8p/
{
"kind": "Pod",
"apiVersion": "v1",
"metadata": {
"name": "kubernetes-bootcamp-65d5b99f84-b2d8p",
"generateName": "kubernetes-bootcamp-65d5b99f84-",
"namespace": "default",
"uid": "6d245d32-30c9-4c04-8bca-e49ab193b086",
"resourceVersion": "340266",
"creationTimestamp": "2022-05-13T09:10:13Z",
"labels": {
"app": "kubernetes-bootcamp",
"pod-template-hash": "65d5b99f84"
}
}
3. 查看调试应用
首先通过kubectl get命令查看集群中存在的pod:
(base) wildkid1024@debian:~$ kubectl get pods
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-65d5b99f84-b2d8p 1/1 Running 0 19m
kubia 1/1 Running 2 (35m ago) 9d
通过decribe则查看pod的创建情况,以及容器的具体信息,比如内部IP,端口,以及完成的事件信息:
(base) wildkid1024@debian:~$ kubectl describe pods
Name: kubernetes-bootcamp-65d5b99f84-b2d8p
Namespace: default
Priority: 0
Node: minikube/192.168.49.2
Start Time: Fri, 13 May 2022 17:10:13 +0800
Labels: app=kubernetes-bootcamp
pod-template-hash=65d5b99f84
Annotations:
Status: Running
IP: 172.17.0.6
IPs:
IP: 172.17.0.6
Controlled By: ReplicaSet/kubernetes-bootcamp-65d5b99f84
Containers:
kubernetes-bootcamp:
Container ID: docker://c652e3a4227816c44fc0240feb6c3b0048125967a438ffffa4a96cf523382100
Image: gcr.io/google-samples/kubernetes-bootcamp:v1
Image ID: docker-pullable://gcr.io/google-samples/kubernetes-bootcamp@sha256:0d6b8ee63bb57c5f5b6156f446b3bc3b3c143d233037f3a2f00e279c8fcc64af
Port:
Host Port:
State: Running
Started: Fri, 13 May 2022 17:10:41 +0800
Ready: True
Restart Count: 0
Environment:
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-qdn9d (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
kube-api-access-qdn9d:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional:
DownwardAPI: true
QoS Class: BestEffort
Node-Selectors:
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 21m default-scheduler Successfully assigned default/kubernetes-bootcamp-65d5b99f84-b2d8p to minikube
Normal Pulling 21m kubelet Pulling image "gcr.io/google-samples/kubernetes-bootcamp:v1"
Normal Pulled 21m kubelet Successfully pulled image "gcr.io/google-samples/kubernetes-bootcamp:v1" in 27.005193363s
Normal Created 21m kubelet Created container kubernetes-bootcamp
Normal Started 21m kubelet Started container kubernetes-bootcamp
通过kubectl logs命令则可查看容器在内部运行时打印出来的log信息:
(base) wildkid1024@debian:~$ kubectl logs kubernetes-bootcamp-65d5b99f84-b2d8p
Kubernetes Bootcamp App Started At: 2022-05-13T09:10:41.099Z | Running On: kubernetes-bootcamp-65d5b99f84-b2d8p
通过kubectl exec可以在容器中临时执行命令,比如查看容器的环境变量:
(base) wildkid1024@debian:~$ kubectl exec kubernetes-bootcamp-65d5b99f84-b2d8p -- env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=kubernetes-bootcamp-65d5b99f84-b2d8p
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_PORT_443_TCP_PROTO=tcp
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
NPM_CONFIG_LOGLEVEL=info
NODE_VERSION=6.3.1
HOME=/root
当然也可以执行可交互的shell命令,需要添加-it参数:
(base) wildkid1024@debian:~$ kubectl exec -it kubernetes-bootcamp-65d5b99f84-b2d8p -- bash
root@kubernetes-bootcamp-65d5b99f84-b2d8p:/# 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" );
});
root@kubernetes-bootcamp-65d5b99f84-b2d8p:/# curl localhost:8080
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-65d5b99f84-b2d8p | v=1
root@kubernetes-bootcamp-65d5b99f84-b2d8p:/#
这里在容器内执行了bash脚本,并查看了server.js的源代码,并通过curl对本地的服务进行了测试。
4. 公开应用的外部接口
前述部署的应用拥有内部的ip和端口,只能在集群内部进行访问,那么如果在外部进行访问,便需要创建service资源以映射到内部的服务。
通过kubectl expose命令为相应的部署创建一个可访问的services接口:
(base) wildkid1024@debian:~$ kubectl expose deployment/kubernetes-bootcamp --type="NodePort" --port 8080
service/kubernetes-bootcamp exposed
创建了一个暴露内部8080接口的service,可通过get services命令列出当前可使用的service列表, 通过describe services描述相应的services信息:
(base) wildkid1024@debian:~$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 443/TCP 9d
kubernetes-bootcamp NodePort 10.99.177.162 8080:31729/TCP 84s
(base) wildkid1024@debian:~$ curl $(minikube ip):31729
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-65d5b99f84-b2d8p | v=1
当相应的应用不需要对外提供访问接口时,可将相应创建的接口删除:
(base) wildkid1024@debian:~$ kubectl delete service kubernetes-bootcamp
service "kubernetes-bootcamp" deleted
(base) wildkid1024@debian:~$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 443/TCP 9d
然后通过ip访问进行验证,发现外部接口可访问,但仍可通过调试的方式在内部访问:
(base) wildkid1024@debian:~$ curl $(minikube ip):31729
curl: (7) Failed to connect to 192.168.49.2 port 31729: 拒绝连接
(base) wildkid1024@debian:~$ kubectl exec -ti kubernetes-bootcamp-65d5b99f84-b2d8p -- curl localhost:8080
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-65d5b99f84-b2d8p | v=1
(base) wildkid1024@debian:~$
5. 弹性放缩应用
在部署应用后,极大可能会对不同的应用进行放缩,比如把某个应用扩充为多个实例,传统部署方案可能要重新部署一遍运行环境,然后将对应的代码复制到新的环境,在集群中,只需要使用kubectl scale一行命令便可以实现:
(base) wildkid1024@debian:~$ kubectl scale deployments/kubernetes-bootcamp --replicas=4
deployment.apps/kubernetes-bootcamp scaled
(base) wildkid1024@debian:~$ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
kubernetes-bootcamp 4/4 4 4 70m
(base) wildkid1024@debian:~$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
kubernetes-bootcamp-65d5b99f84-2bvw9 1/1 Running 0 25s 172.17.0.8 minikube
kubernetes-bootcamp-65d5b99f84-b2d8p 1/1 Running 0 70m 172.17.0.6 minikube
kubernetes-bootcamp-65d5b99f84-spxb5 1/1 Running 0 25s 172.17.0.7 minikube
kubernetes-bootcamp-65d5b99f84-ssfjp 1/1 Running 0 25s 172.17.0.9 minikube
可以看到部署的实例数已经变为4个,对应的pods也变成了4个,其中1个是之前创建的,另外3个是新创建的。
当再使用外部服务接口去访问应用时,发现其已经实现了负载均衡,几次访问中每次访问的实例都不尽相同:
(base) wildkid1024@debian:~$ curl $(minikube ip):32578
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-65d5b99f84-spxb5 | v=1
(base) wildkid1024@debian:~$ curl $(minikube ip):32578
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-65d5b99f84-b2d8p | v=1
(base) wildkid1024@debian:~$ curl $(minikube ip):32578
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-65d5b99f84-2bvw9 | v=1
(base) wildkid1024@debian:~$ curl $(minikube ip):32578
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-65d5b99f84-b2d8p | v=1
有时也可以回收多余的应用实例,只需把实例的数目调节到预期的数目即可:
(base) wildkid1024@debian:~$ kubectl scale deployments/kubernetes-bootcamp --replicas=2
deployment.apps/kubernetes-bootcamp scaled
(base) wildkid1024@debian:~$ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
kubernetes-bootcamp 2/2 2 2 77m
(base) wildkid1024@debian:~$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
kubernetes-bootcamp-65d5b99f84-2bvw9 1/1 Running 0 7m43s 172.17.0.8 minikube
kubernetes-bootcamp-65d5b99f84-b2d8p 1/1 Running 0 77m 172.17.0.6 minikube
kubernetes-bootcamp-65d5b99f84-spxb5 1/1 Terminating 0 7m43s 172.17.0.7 minikube
kubernetes-bootcamp-65d5b99f84-ssfjp 1/1 Terminating 0 7m43s 172.17.0.9 minikube
多于预期数目的实例正在停止并进行资源回收。
6. 滚动热更新应用
应用上线后,会遇到版本更新的情况,传统办法是等半夜用户都下线时再进行离线系统维护。但随着用户在线时长越来越长,难免会影响到一小部分用户的使用体验。比较流行的做法是在线热更新,即在不下线的情况下对应用进行维护和版本升级,毫不影响用户体验。
类似与应用弹性放缩,应用的版本升级同样十分简单,只需通过kubectl set image将对应的镜像进行替换即可:
(base) wildkid1024@debian:~$ kubectl set image deployments/kubernetes-bootcamp kubernetes-bootcamp=jocatalin/kubernetes-bootcamp:v2
deployment.apps/kubernetes-bootcamp image updated
(base) wildkid1024@debian:~$ kubectl get pods
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-65d5b99f84-2bvw9 1/1 Running 0 15m
kubernetes-bootcamp-65d5b99f84-b2d8p 1/1 Running 0 86m
kubernetes-bootcamp-684bd555bb-grwpv 0/1 ContainerCreating 0 11s
kubia 1/1 Running 2 (102m ago) 9d
(base) wildkid1024@debian:~$ curl $(minikube ip):32578
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-684bd555bb-sngxj | v=2
此时应用的版本已经变成了v2版本,也可以通过rollout检查应用更新状况:
(base) wildkid1024@debian:~$ kubectl rollout status deployments/kubernetes-bootcamp
deployment "kubernetes-bootcamp" successfully rolled out
当部署了不正确的版本时,那么就需要对版本进行回滚了,kubectl同样提供了十分便捷的回滚命令。
这里通过一个错误的版本镜像来演示回滚操作:
(base) wildkid1024@debian:~$ kubectl set image deployments/kubernetes-bootcamp kubernetes-bootcamp=gcr.io/google-samples/kubernetes-bootcamp:v10
deployment.apps/kubernetes-bootcamp image updated
(base) wildkid1024@debian:~$ kubectl get pods
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-5bbb6c8c4-vsfq6 0/1 ErrImagePull 0 9s
kubernetes-bootcamp-684bd555bb-grwpv 1/1 Running 0 5m41s
kubernetes-bootcamp-684bd555bb-sngxj 1/1 Running 0 5m25s
这里发现应用新版本出现了ErrImagePull错误,就需要通过kubectl rollout undo命令来进行回滚:
(base) wildkid1024@debian:~$ kubectl rollout undo deployments/kubernetes-bootcamp
deployment.apps/kubernetes-bootcamp rolled back
(base) wildkid1024@debian:~$ kubectl get pods
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-684bd555bb-grwpv 1/1 Running 0 8m34s
kubernetes-bootcamp-684bd555bb-sngxj 1/1 Running 0 8m18s
------------ 完结 ------------------