k8s in action 读书笔记-使用docker和k8s

笔者不喜欢先解释事物是如何工作的,然后再解释它的功能并教人们如何使用它 。就像学习开车,你不想知道引擎盖下是什么,你首先想要学习怎样从 A 点开到 B 。只有在你学会了如何做到这后,你才会对汽车如何使这成为可能产生兴趣。毕竟,知道引擎盖下面是什么,可能在有 天它抛锚后你被困在路边时,会帮助你让车再次移动。

image.png

docker 基础

docker 运行命令

1
2
3
4
5
6
7
8
# busybox 一层镜像,包含很多标准的UNIX命令。
hhzzer@admin-PC:~/nodejs-app$ docker run busybox echo "hello world"
Unable to find image 'busybox:latest' locally
latest: Pulling from library/busybox
e5d9363303dd: Pull complete
Digest: sha256:c5439d7db88ab5423999530349d327b04279ad3161d7596d2126dfb5b02bfd1f
Status: Downloaded newer image for busybox:latest
hello world

编译简单 nodejs 应用并打包成镜像执行

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
hhzzer@admin-PC:~/nodejs-app$ cat app.js
const http = require('http');
const os = require('os');
console.log("kubia server starting ...");

var handler = function(request, response) {
console.log("Recived request from " + request.connection.remoteAddress);
response.writeHead(200);
response.end("You've hit " + os.hostname() + "\n");
};
var www = http.createServer(handler);
www.listen(8080);

hhzzer@admin-PC:~/nodejs-app$ cat app.js
const http = require('http');
const os = require('os');
console.log("kubia server starting ...");

var handler = function(request, response) {
console.log("Recived request from " + request.connection.remoteAddress);
response.writeHead(200);
response.end("You've hit " + os.hostname() + "\n");
};
var www = http.createServer(handler);
www.listen(8080);

# 使用docker built -t tagname . 打包
hhzzer@admin-PC:~/nodejs-app$ docker build -t kubia .
Sending build context to Docker daemon 3.072kB

# 运行打包的镜像 -d 为后台运行容器并打印出容器id
hhzzer@admin-PC:~/nodejs-app$ docker run --name kubia-container -p 8080:8080 -d kubia
15924bc23a69938a3a4f2b23f2b4bf5689ea91f5650d46a0239558bc0a963c10
# 检查容器运行状态
hhzzer@admin-PC:~/nodejs-app$ docker logs 15924bc23a69
kubia server starting ...
Recived request from ::ffff:172.17.0.1
# curl命令测试容器提供的http服务
hhzzer@admin-PC:~/nodejs-app$ curl localhost:8080
You ve hit 15924bc23a69
# 进入容器内部查看
hhzzer@admin-PC:~/nodejs-app$ docker exec -it 15924bc23a69 bash
root@15924bc23a69:/#
# 停止容器
docker container stop 15924bc23a69
# 删除容器
docker container rm 15924bc23a69
# 查看所有容器
docker container ls -a
# 查看容器详细信息
docker inspect container 15924bc23a69

把镜像推送到 docker hub

1
2
3
4
5
docker login
docker tag kubia hhzzer/kubia
docker push hhzzer/kubia
# 在任意其他电脑运行自己的容器
docker run -p 8080:8080 -d luksa/kubia

k8s 基础

windows 环境使用 minikube 搭建单机 k8s 集群。参考链接
管理员权限命令行执行如下命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.\minikube.exe start  --image-mirror-country cn --iso-url=https://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/iso/minikube-v1.16.0.iso  --registry-mirror=https://reg-mirror.qiniu.com --vm-driver="hyperv" --hyperv-virtual-switch="MinikubeSwitch" --memory=2048

# 启动过程
* Microsoft Windows 10 Pro 10.0.19041 Build 19041 上的 minikube v1.16.0
* 根据用户配置使用 hyperv 驱动程序
* 正在使用镜像存储库 registry.cn-hangzhou.aliyuncs.com/google_containers
* Starting control plane node minikube in cluster minikube
* Creating hyperv VM (CPUs=2, Memory=2048MB, Disk=20000MB) ...
! This VM is having trouble accessing https://registry.cn-hangzhou.aliyuncs.com/google_containers
* To pull new external images, you may need to configure a proxy: https://minikube.sigs.k8s.io/docs/reference/networking/proxy/
* 正在 Docker 20.10.0 中准备 Kubernetes v1.20.0…
- Generating certificates and keys ...
- Booting up control plane ...
- Configuring RBAC rules ...
* Verifying Kubernetes components...
* Enabled addons: storage-provisioner, default-storageclass
* Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default

wsl2-ubuntu 安装 kubectl 并设置命令补全

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
wget https://storage.googleapis.com/kubernetes-release/release/v1.20.0/kubernetes-client-linux-amd64.tar.gz
tar xzvf kubernetes-client-linux-amd64.tar.gz
sudo cp kubernetes/client/bin/kubectl /usr/bin/
# 配置kubectl
mkdir .kube
cp /mnt/c/Users/admin/.kube/config ~/.kube/
cp /mnt/c/Users/admin/.minikube/profiles/minikube/client.* ~/.kube/
cp /mnt/c/Users/admin/.minikube/ca.crt ~/.kube/
# 修改config中ca、clinet证书路径。
hhzzer@admin-PC:~/nodejs-app$ grep hhzzer ~/.kube/config
certificate-authority: /home/hhzzer/.kube/ca.crt
client-certificate: /home/hhzzer/.kube/client.crt
client-key: /home/hhzzer/.kube/client.key

# kubectl 命令补全
source <(kubectl completion bash)
# 可添加到用户bash配置文件中,登陆自动导入环境变量
echo 'source <(kubectl completion bash)' >> ~/.bashrc

查看 k8s 集群基本信息

1
2
3
4
5
6
7
8
9
10
11
hhzzer@admin-PC:~$ kubectl cluster-info
Kubernetes control plane is running at https://172.20.134.184:8443
KubeDNS is running at https://172.20.134.184:8443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

hhzzer@admin-PC:~$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
minikube Ready control-plane,master 4h v1.20.0

kubectl describe node

使用 k8s 部署应用

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# 新版本kubectl run 只能运行一个pod,不能通过参数运行rc。
kubectl run kubia --image=hhzzer/kubia --port=8080 --generator=run/v1
hhzzer@admin-PC:~$ kubectl get pods
NAME READY STATUS RESTARTS AGE
kubia 0/1 ContainerCreating 0 10s

# 通过dry-run=client -o yaml 可以输出kubectl命令对应的yaml文件。观察文件可知是创建了一个pod。
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: kubia
name: kubia
spec:
containers:
- image: hhzzer/kubia
name: kubia
ports:
- containerPort: 8080
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
# 使用kubectl create deployment 部署应用。
kubectl create deployment kubia --image=hhzzer/kubia --port=8080 --dry-run=client -o yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: kubia
name: kubia
spec:
replicas: 1
selector:
matchLabels:
app: kubia
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: kubia
spec:
containers:
- image: hhzzer/kubia
name: kubia
ports:
- containerPort: 8080
resources: {}
status: {}

# 真正运行deployment, 由container组成pod,由pod组成rs(副本集),由rs组成deployment。
kubectl create deployment kubia --image=hhzzer/kubia --port=8080
hhzzer@admin-PC:~$ kubectl get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
kubia 1/1 1 1 13s
hhzzer@admin-PC:~$ kubectl get rs
NAME DESIRED CURRENT READY AGE
kubia-864b87d69f 1 1 1 3m15s
hhzzer@admin-PC:~$ kubectl get pods
NAME READY STATUS RESTARTS AGE
kubia-864b87d69f-qsxwx 1/1 Running 0 3m36s
# 使用expose暴露服务
hhzzer@admin-PC:~$ kubectl expose deployment kubia --port=8080 --target-port=8080 --dry-run
=client -o yaml
apiVersion: v1
kind: Service
metadata:
creationTimestamp: null
labels:
app: kubia
name: kubia
spec:
ports:
- port: 8080
protocol: TCP
targetPort: 8080
selector:
app: kubia
status:
loadBalancer: {}
# 因为默认暴露方式为ClusterIP,只能在minikube中访问
minikube中执行
curl http://10.111.84.19:8080
You ve hit kubia-864b87d69f-qsxwx
# 修改成NodePort,使得在集群外部可以访问。
hhzzer@admin-PC:~$ kubectl expose deployment kubia --name kubia-http --port=8080 --target-p
ort=8080 --type=NodePort --dry-run=client -o yaml
apiVersion: v1
kind: Service
metadata:
creationTimestamp: null
labels:
app: kubia
name: kubia-http
spec:
ports:
- port: 8080
protocol: TCP
targetPort: 8080
selector:
app: kubia
type: NodePort
status:
loadBalancer: {}

hhzzer@admin-PC:~$ kubectl expose deployment kubia --name kubia-http --port=8080 --target-p
ort=8080 --type=NodePort
service/kubia-http exposed
# 通过minikube查看服务暴露在node的哪个端口
C:\Users\admin\云原生>minikube.exe service kubia-http
|-----------|------------|-------------|-----------------------------|
| NAMESPACE | NAME | TARGET PORT | URL |
|-----------|------------|-------------|-----------------------------|
| default | kubia-http | 8080 | http://172.20.134.184:31425 |
|-----------|------------|-------------|-----------------------------|
* 正通过默认浏览器打开服务 default/kubia-http...
# 在集群外部访问测试,可以访问成功,证明服务暴露ok。
hhzzer@admin-PC:~$ curl http://172.20.134.184:31425
You've hit kubia-864b87d69f-qsxwx

应用弹性伸缩

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
hhzzer@admin-PC:~$ kubectl scale deployment kubia --replicas=3
deployment.apps/kubia scaled
hhzzer@admin-PC:~$ kubectl get deployments.apps kubia
NAME READY UP-TO-DATE AVAILABLE AGE
kubia 3/3 3 3 23m
hhzzer@admin-PC:~$ kubectl get pods
NAME READY STATUS RESTARTS AGE
kubia-864b87d69f-5z9mn 1/1 Running 0 23s
kubia-864b87d69f-dkp6m 1/1 Running 0 24s
kubia-864b87d69f-qsxwx 1/1 Running 0 23m
# 服务测试,发现服务能负载到3个pod
hhzzer@admin-PC:~$ curl http://172.20.134.184:31425
You've hit kubia-864b87d69f-5z9mn
hhzzer@admin-PC:~$ curl http://172.20.134.184:31425
You've hit kubia-864b87d69f-qsxwx
hhzzer@admin-PC:~$ curl http://172.20.134.184:31425
You've hit kubia-864b87d69f-qsxwx
hhzzer@admin-PC:~$ curl http://172.20.134.184:31425
You've hit kubia-864b87d69f-dkp6m
# 检查pod分布
hhzzer@admin-PC:~$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
kubia-864b87d69f-5z9mn 1/1 Running 0 3m30s 172.17.0.5 minikube <none> <none>
kubia-864b87d69f-dkp6m 1/1 Running 0 3m31s 172.17.0.4 minikube <none> <none>
kubia-864b87d69f-qsxwx 1/1 Running 0 27m 172.17.0.3 minikube <none> <none>

image.png