使用小细节
从节点上使用kubectl时,如果出现
1 | The connection to the server localhost:8080 was refused - did you specify the right host or port? |
可以使用以下命令解决:
1 | export KUBECONFIG=/etc/kubernetes/admin.conf |
原因暂时母鸡,我试过把这句话加到环境变量,但是并没有卵用…..
(问题找到了。。将master节点的/etc/kubernetes/admin.conf拷贝到 worker节点上)执行如下即可:
1 | mkdir -p $HOME/.kube |
另外,每次集群宕机后,各节点都需要运行一遍swapoff -a ,不然无法启动。
第一个kubernetes应用
在上一篇笔记中,已经使用kubeadm这个工具搭建好了一个完整的kubernetes集群,现在就是时候来体验一下如何使用kubernetes管理容器应用了。
首先,kubernetes是基于容器进行部署的,那么我们需要的第一个东西就是镜像。然后,我们需要根据kubernetes的规范和要求,将镜像组织为kubernetes能够认识的方式: 编写yaml文件。
kubernetes与Docker的不同之处就在于,kubernetes不推荐使用命令行的方式来运行容器,而是使用yaml/json的方式来运行。将容器的信息都记录在文件中,然后使用如下的语句将它运行起来:
1 | kubectl create -f xxx.yaml |
这样,在运行容器的同时,也记录下了run的相关信息。在需要变更时,可以有相关记录。(其实在容器编排上来说docker-compose也是这样的思路,只是kubernetes提供的功能相对来说更加的强大和全面。)比如下面这个yaml文件:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.16.0
ports:
- containerPort: 80
在这个文件中,metadata代表的是元数据信息,name:nginx-deployment就是为这个Deployment自定义的名称,而kind: Deployment代表的是定义多个副本的应用。replicas告诉kubernetes需要在所有节点中,保证有且仅有2个节点在同时运行。
除此之外,template定义了pod的模板,声明每个创建出来的容器都带有一个标签app:nginx,使用的基础镜像为nginx:1.16.0,并且开放容器端口80。
使用kubectl apply指令创建/更新这个yaml文件对应的容器:
1 | kubectl apply -f nginx-deployment.yaml |
kubectl create 和 kubectl replace 分别对应着创建和更新,但一般不推荐,因为apply可以统一完成这两种操作。
接下来,可以通过kubectl get 检查运行结果:1
2
3
4
5
6kubectl get pods -l app=nginx
...
NAME READY STATUS RESTARTS AGE
nginx-deployment-75fdccc955-vpdqm 1/1 Running 0 25s
nginx-deployment-75fdccc955-wdfxf 1/1 Running 0 25s
这个命令中,-l表示的是查找pod中label标签为app=nginx的,也就是yaml文件中所配置的那样,可以看到两个副本都已经处于running状态,表示这个Deployment所管理的Pod都处于预期状态。
此外,使用kubectl describe可以查看pod的相关信息。
1 | kubectl describe pod nginx-deployment-75fdccc955-vpdqm |
在返回结果中,可以看到诸如name、node、labels、IP等等一系列相关信息。除此之外,还有一个特别的部分:Events。在Events中,可以看到这个Pod从分配节点到拉取镜像再到运行容器的整个流程。所以,当运行发生异常时往往可以在这里看到错误信息,帮助Debug。
当需要进行升级时,如从1.16.0升级到latest版本,只需要将yaml文件对应的镜像改为image: nginx即可,然后运行
1 | kubectl apply -f nginx-deployment.yaml |
如果速度较快的话,可以查看到如下情况:(停止和删除原先的Pod,并重新创建的过程)
1 | kubectl get pods -l app=nginx |
接下来,尝试为容器添加Volume数据卷映射,修改yaml内容为如下所示: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
27apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: nginx-vol
volumes:
- name: nginx-vol
hostPath:
path: /var/data
可以看到,在这个yaml中增加了一个volumeMounts的属性,它所代表的含义是将容器mountPath所指定的目录挂载到名称为nginx-vol的Volume中,同时volumes属性声明了一个名为nginx-vol的卷供容器使用,并且类型为hostPath。这样一来,宿主机的/var/data目录就和容器的mountPath目录建立了映射关系。
运行kubectl describe指令可以查看到映射的信息:
1 | ...... |
到这里,还可以使用kubectl exec指令进入到Pod中
1 | kubectl exec -it nginx-deployment-7bffbd4747-kz8qt sh |
最后,如果需要从集群中删除这个nginx-deployment的话,执行kubectl delete指令即可
1 | kubectl delete -f nginx-deployment.yaml |
制作image-sign的Deployment
在有了上述知识后,我决定将之前在alpine镜像安装字体库使用到的image-sign制作为一个deployment。(可以使用docker pull hoppou/image-sign 从dockerhub拉取这个镜像呢,另外记得改镜像名称~)
编写如下yaml:
1 | apiVersion: apps/v1 |
由于镜像功能极为简单,yaml的内容也很清晰,只需要将端口打开即可,运行:
1 | kubectl apply -f image-sign-deployment.yaml |
1 | kubectl get pod -l app=image-sign |
查看其中一个pod的相关属性:
1 | kubectl describe pod image-sign-deployment-59948dd446-8n8l7 |
可以看到IP信息为10.244.1.40,接下来使用postman进行测试:
大功告成!!!ヽ(・∀・)ノ
Tips补充
在kubernetes中拉取镜像有如下三种策略,可以通过imagePullPolicy进行设置
1 | Never ---- 从不拉取,只使用已有镜像 |
目前版本的kubernetes默认使用的是IfNotPresent,但在没有标明镜像的tag时,如 image: nginx 这种写法会采用Always的方式进行拉取。