Kubernetes 教程实践
我想实际运行官方教程。
该教程使用 Katakoba,但这次我们将编写并运行yaml文件。
环境
-
- Master *1 (Ubuntu Server 18.04 on ESXi)
-
- Worker *8 (Ubuntu Server 18.04 on ESXi)
-
- Kubernetes v1.17.0
- このチュートリアルではネームスペース k8s-tutorial にすべてのリソースを作成します。
学什么
-
- コンテナ化されたアプリケーションをクラスターにデプロイ
-
- Deploymentのスケーリング
-
- 新しいソフトウェアのバージョンでコンテナ化されたアプリケーションをアップデート
- コンテナ化されたアプリケーションのデバッグ
创建 Kubernetes 集群
因为已在先前的文章中介绍过了,所以这里省略。
创建命名空间
apiVersion: v1
kind: Namespace
metadata:
name: k8s-tutorial
$ kubectl apply -f ns.yml
namespace/k8s-tutorial created
部署应用程序
$ kubectl create deployment kubernetes-bootcamp --image=gcr.io/google-samples/kubernetes-bootcamp:v1
将此命令转化为YAML格式并输入。
apiVersion: apps/v1
kind: Deployment
metadata:
name: kubernetes-bootcamp
namespace: k8s-tutorial
spec:
selector:
matchLabels:
app: kubernetes-bootcamp
template:
metadata:
labels:
app: kubernetes-bootcamp
spec:
containers:
- name: kubernetes-bootcamp
image: gcr.io/google-samples/kubernetes-bootcamp:v1
resources:
limits:
memory: "128Mi"
cpu: "500m"
$ kubectl apply -f deploy_01.yml
deployment.apps/kubernetes-bootcamp created
如果没有创建成功并出现错误,请检查 deploy_01.yml 文件。
我们将尝试确认部署的状态。
$ kubectl get deploy -n k8s-tutorial -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
kubernetes-bootcamp 1/1 1 1 2m47s kubernetes-bootcamp gcr.io/google-samples/kubernetes-bootcamp:v1 app=kubernetes-bootcamp
READY が 1/1 になっているので無事にデプロイされました。
一応、 Pod も確認してみましょう。
$ kubectl get po -n k8s-tutorial
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-64cd8bd759-ncxfr 1/1 Running 0 54s
状态已经变为运行中了。
因为这一章已经结束了,所以我们来打扫一下吧。
$ kubectl delete -f deploy_01.yml
deployment.apps "kubernetes-bootcamp" deleted
通过增加deployment或者应用Pod的SideCar等方式,可以构建出像这个图示的Kubernetes集群。
执行到Pod
将目标 Pod 的名称设置为环境变量。
$ export POD_NAME = kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}'
显示目标 Pod 内的环境变量
$ kubectl exec -n k8s-tutorial $POD_NAME env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=kubernetes-bootcamp-5b48cfdcbd-2wq82
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
在目标的 Pod 内部启动 Bash。
$ kubectl exec -n k8s-tutorial $POD_NAME -it bash
root kubernetes-bootcamp-xxxxxxxxxx-xxxxx:/# #このプロンプトは Pod 内の bash によるもの
检查Pod中的文件
root kubernetes-bootcamp-xxxxxxxxxx-xxxxx:/# ls -la
total 460
drwxr-xr-x 1 root root 4096 Jan 17 06:28 .
drwxr-xr-x 1 root root 4096 Jan 17 06:28 ..
-rwxr-xr-x 1 root root 0 Jan 17 06:28 .dockerenv
drwxr-xr-x 2 root root 4096 Jun 8 2016 bin
drwxr-xr-x 2 root root 4096 May 30 2016 boot
-rw------- 1 root root 393216 Jun 9 2016 core
drwxr-xr-x 5 root root 360 Jan 17 06:28 dev
drwxr-xr-x 1 root root 4096 Jan 17 06:28 etc
drwxr-xr-x 2 root root 4096 May 30 2016 home
drwxr-xr-x 1 root root 4096 Jun 9 2016 lib
drwxr-xr-x 2 root root 4096 Jun 8 2016 lib64
drwxr-xr-x 2 root root 4096 Jun 8 2016 media
drwxr-xr-x 2 root root 4096 Jun 8 2016 mnt
drwxr-xr-x 2 root root 4096 Jun 8 2016 opt
dr-xr-xr-x 217 root root 0 Jan 17 06:28 proc
drwx------ 1 root root 4096 Jul 22 2016 root
drwxr-xr-x 1 root root 4096 Jan 17 06:28 run
drwxr-xr-x 2 root root 4096 Jun 8 2016 sbin
-rw-r--r-- 1 root root 742 Jul 29 2016 server.js
drwxr-xr-x 2 root root 4096 Jun 8 2016 srv
dr-xr-xr-x 13 root root 0 Jan 17 06:28 sys
drwxrwxrwt 1 root root 4096 Jul 22 2016 tmp
drwxr-xr-x 1 root root 4096 Jul 22 2016 usr
drwxr-xr-x 1 root root 4096 Jul 22 2016 var
# 実際に Pod 内で動いているコード(Node.js)
root kubernetes-bootcamp-xxxxxxxxxx-xxxxx:/# 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-xxxxxxxxxx-xxxxx:/# curl localhost:8080
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-xxxxxxxxxx-xxxxx | v=1
# 抜け出す
root kubernetes-bootcamp-xxxxxxxxxx-xxxxx:/# exit
$ # Pod から脱出
访问Kubernetes训练营
依照先前部署的 deploy_01.yml 文件,在 kubernetes-bootcamp 上监听8080/tcp 端口,需创建相应的服务。
apiVersion: v1
kind: Service
metadata:
name: kubernetes-bootcamp
namespace: k8s-tutorial
spec:
selector:
app: kubernetes-bootcamp
type: NodePort
ports:
- port: 80
targetPort: 8080
$ kubectl apply -f svc_01.yml
service/kubernetes-bootcamp created
$ kubectl get svc -n k8s-tutorial
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes-bootcamp NodePort 10.96.46.6 <none> 80:32767/TCP 40s
访问 http://[Master的IP]:[外部公开端口]。
以以上示例为例,Master的IP地址是10.0.0.230,因此访问的网址是http://10.0.0.230:32767。
$ curl 10.0.0.230:32767
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-xxxxxxxxxx-xxxxx| v=1
执行时应该会得到与确认的结果相同的输出。
缩小/放大
$ kubectl get po -n k8s-tutorial
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-64cd8bd759-8w268 1/1 Running 0 85m
目前 kubernetes-bootcamp 的 Pod 数量为 1,但是可以进行增减。
$ kubectl scale -n k8s-tutorial deploy kubernetes-bootcamp --replicas 10
deployment.apps/kubernetes-bootcamp scaled
我们现在将kubernetes-bootcamp的Pod数量增加到了10个。让我们来确认一下Deployment和Pod。
$ kubectl get deploy -n k8s-tutorial kubernetes-bootcamp
NAME READY UP-TO-DATE AVAILABLE AGE
kubernetes-bootcamp 10/10 10 10 113m
$ kubectl get po -n k8s-tutorial
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-64cd8bd759-8w268 1/1 Running 0 95m
kubernetes-bootcamp-64cd8bd759-cbbk5 1/1 Running 0 3m10s
kubernetes-bootcamp-64cd8bd759-mtl5p 1/1 Running 0 3m10s
kubernetes-bootcamp-64cd8bd759-ndk55 1/1 Running 0 3m10s
kubernetes-bootcamp-64cd8bd759-tdp4f 1/1 Running 0 3m10s
kubernetes-bootcamp-64cd8bd759-tg5cx 1/1 Running 0 3m10s
kubernetes-bootcamp-64cd8bd759-wx2v6 1/1 Running 0 3m10s
kubernetes-bootcamp-64cd8bd759-xgqlt 1/1 Running 0 3m10s
kubernetes-bootcamp-64cd8bd759-zhzql 1/1 Running 0 3m10s
kubernetes-bootcamp-64cd8bd759-zqjlx 1/1 Running 0 3m10s
部署已达到10/10,并且有10个Pod被输出。
现在我们来试着减少已经增加的东西。
$ kubectl scale -n k8s-tutorial deploy kubernetes-bootcamp --replicas 3
deployment.apps/kubernetes-bootcamp scaled
$ kubectl get po -n k8s-tutorial
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-64cd8bd759-mtl5p 1/1 Running 0 9m37s
kubernetes-bootcamp-64cd8bd759-wx2v6 1/1 Running 0 9m37s
kubernetes-bootcamp-64cd8bd759-zhzql 1/1 Running 0 9m37s
只需使用与先前相同的命令来更改复制数量即可完成。
负载均衡
如果有多个 Pod 的情况下,我们是如何访问的呢?
$ kubectl get po -n k8s-tutorial
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-64cd8bd759-mtl5p 1/1 Running 0 52m
kubernetes-bootcamp-64cd8bd759-wx2v6 1/1 Running 0 52m
kubernetes-bootcamp-64cd8bd759-zhzql 1/1 Running 0 52m
有三个 Pod。让我们实际访问一下。
$ curl 10.0.0.230:32767
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-64cd8bd759-wx2v6 | v=1
$ curl 10.0.0.230:32767
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-64cd8bd759-zhzql | v=1
$ curl 10.0.0.230:32767
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-64cd8bd759-mtl5p | v=1
尽管我在访问Master,但资源被分配到了3个Pod中。
由于在创建Service时将spec.type指定为NodePort,因此它能很好地进行分散分配。
滚动更新
在这个教程中,我们使用了 kubernetes-bootcamp:v1。现在我们要将图像从v1更新到v2。
$ kubectl set image deploy kubernetes-bootcamp kubernetes-bootcamp=jocatalin/kubernetes-bootcamp:v2 -n k8s-tutorial
deployment.extensions/kubernetes-bootcamp image updated
让我们将图像更新为 jocatalin/kubernetes-bootcamp:v2,并实际确认一下 Pod。
$ kubectl get po -n k8s-tutorial
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-8686fc5f77-5wggs 1/1 Running 0 97s
kubernetes-bootcamp-8686fc5f77-bsxbb 1/1 Running 0 90s
kubernetes-bootcamp-8686fc5f77-znnq4 1/1 Running 0 103s
在 “LoadBalancing” 章节中确认时,它是 “kubernetes-bootcamp-64cd8bd759-xxxxx”,但由于更新了镜像,Pod 被重新创建为 “kubernetes-bootcamp-8686fc5f77-xxxxx”。AGE 也更新为较新的时间。
要检查正在使用的镜像,可以使用 “–output wide” 或 “describe” 命令。
$ kubectl get deploy -n k8s-tutorial -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
kubernetes-bootcamp 3/3 3 3 4h52m kubernetes-bootcamp jocatalin/kubernetes-bootcamp:v2 app=kubernetes-bootcamp
由于映像已经更新为jocatalin/kubernetes-bootcamp:v2,因此我们可以尝试访问v2映像。
$ curl 10.0.0.230:32767
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-8686fc5f77-znnq4 | v=2
$ curl 10.0.0.230:32767
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-8686fc5f77-5wggs | v=2
$ curl 10.0.0.230:32767
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-8686fc5f77-bsxbb | v=2
v = 2. 已经成为2了。
如果在“设置”中进行了图像更新,如果想要恢复到原始图像,即使遇到问题,也可以通过一个指令进行还原。
$ kubectl rollout undo deploy kubernetes-bootcamp -n k8s-tutorial
deployment.apps/kubernetes-bootcamp rolled back
我们可以试着恢复到以前的状态来确认一下。
$ kubectl get po -n k8s-tutorial
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-64cd8bd759-4bl2s 1/1 Running 0 12s
kubernetes-bootcamp-64cd8bd759-g4grz 1/1 Running 0 14s
kubernetes-bootcamp-64cd8bd759-ng69z 1/1 Running 0 17s
kubernetes-bootcamp-8686fc5f77-5wggs 1/1 Terminating 0 14m
kubernetes-bootcamp-8686fc5f77-bsxbb 1/1 Terminating 0 13m
kubernetes-bootcamp-8686fc5f77-znnq4 1/1 Terminating 0 14m
被应用了 v2 的 kubernetes-bootcamp-8686fc5f77-xxxxx 已被删除,并创建了应用了原始的 v1 的 kubernetes-bootcamp-64cd8bd759-xxxxx。
在这一部分中,我们已经看到了使用Kubernetes可以轻松地进行部署、发布、更新和回滚操作。
以上是官方教程的结束。今后我们将继续通过使用示例应用程序等来学习Kubernetes的功能。