作为应用开发者,首先制作容器的镜像,制作完成后,需要按照k8s的规范和要求,即编写配置文件的方式来将镜像提交运行。
编写Pod YAML
Kubernetes 跟 Docker 等很多项目最大的不同,就在于它不推荐你使用命令行的方式直接运行容器(虽然 Kubernetes 项目也支持这种方式,比如:kubectl run),而是希望你用 YAML 文件的方式,即:把容器的定义、参数、配置,统统记录在一个 YAML 文件中,然后用这样一句指令把它运行起来:
$ kubectl create -f 我的配置文件这样做的好处就是,这个文件会记录下k8s到底运行了一个什么样的容器。
apiVersion: 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.7.9
ports:
- containerPort: 80这样的一个YAML文件,对应到k8s中,就是一个API对象,k8s根据这个对象创建出其定义的容器或者其它类型的API资源。
- Kind字段,指明了API对象的类型,这里是Deployment,是一个定义多副本应用的对象。
- metadata字段:是API对象的标识,即元数据,k8s就是根据元数据找到这个对象。其中最重要的labels字段,Deployment可以根据labels从k8s过滤出关心的对象。
一个 Kubernetes 的 API 对象的定义,大多可以分为 Metadata 和 Spec 两个部分。前者存放的是这个对象的元数据,对所有 API 对象来说,这一部分的字段和格式基本上是一样的;而后者存放的,则是属于这个对象独有的定义,用来描述它所要表达的功能。
运行应用并查看信息
接下来就是运行这个应用:
$ kubectl create -f nginx-deployment.yaml运行起来后就可以通过kubectl get命令来查看运行的pod的信息,使用-l选项利用前面提到的labels进行过滤,要注意labels虽然是键值对,但是在命令行中使用=而不是冒号。
$ kubectl get pods -l app=nginx
NAME READY STATUS RESTARTS AGE
nginx-deployment-67594d6bf6-9gdvr 1/1 Running 0 10m
nginx-deployment-67594d6bf6-v6j7w 1/1 Running 0 10m还可以使用kubectl describe命令,查看一个API对象的细节
$ kubectl describe pod nginx-deployment-67594d6bf6-9gdvr
Name: nginx-deployment-67594d6bf6-9gdvr
Namespace: default
Priority: 0
PriorityClassName: <none>
Node: node-1/10.168.0.3
Start Time: Thu, 16 Aug 2018 08:48:42 +0000
Labels: app=nginx
pod-template-hash=2315082692
Annotations: <none>
Status: Running
IP: 10.32.0.23
Controlled By: ReplicaSet/nginx-deployment-67594d6bf6
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 1m default-scheduler Successfully assigned default/nginx-deployment-67594d6bf6-9gdvr to node-1
Normal Pulling 25s kubelet, node-1 pulling image "nginx:1.7.9"
Normal Pulled 17s kubelet, node-1 Successfully pulled image "nginx:1.7.9"
Normal Created 17s kubelet, node-1 Created container
Normal Started 17s kubelet, node-1 Started container要特别关注Event事件部分,所有对API对象的重要操作都会被记录在这里,这是进行Debug的重要依据。
更新应用
要对Nginx服务进行升级,从1.7.9升级为1.8。首先要做的就是修改YAML文件,将对应部分进行修改。
...
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80可以使用kubectl replace来完成这个更新操作:
$ kubectl replace -f nginx-deployment.yaml不过更加推荐使用kubectl apply命令,因为对k8s对象的创建和更新都可以统一使用这个命令完成,用户无需关注是创建还是更新。
$ kubectl apply -f nginx-deployment.yaml
# 修改nginx-deployment.yaml的内容
$ kubectl apply -f nginx-deployment.yaml通过YAML文件,大大降低了开发和运维之间的沟通成本。保证了应用的部署参数在开发和部署环境中的一致性。
声明一个volume
尝试声明一个volume,因为volume是Pod的一部分,所以在template.spec字段下添加
...
template:
...
spec:
containers:
- name: nginx
image: nginx:1.8
ports:
- containerPort: 80
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: nginx-vol
volumes:
- name: nginx-vol
emptyDir: {}这里创建了一个名为nginx-vol,类型为emptyDir的volume。
emptyDir类型与docker的隐式volume参数相同,不显式声明宿主机的volume,那么就会创建一个临时目录来挂载到容器的volume中,k8s的emptyDir只是使用自己创建的临时目录,而不是docker创建的_data目录。
显式指定volume通过hostPath:
...
volumes:
- name: nginx-vol
hostPath:
path: " /var/data"然后通过kubectl apply命令进行更新
$ kubectl apply -f nginx-deployment.yaml整个更新过程是滚动的,先创建新的,然后删除旧的,通过执行kubectl get,可以看到这个过程
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-5c678cfb6d-v5dlh 0/1 ContainerCreating 0 4s
nginx-deployment-67594d6bf6-9gdvr 1/1 Running 0 10m
nginx-deployment-67594d6bf6-v6j7w 1/1 Running 0 10m
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-5c678cfb6d-lg9lw 1/1 Running 0 8s
nginx-deployment-5c678cfb6d-v5dlh 1/1 Running 0 19s进入Pod
使用kubectl exec命令即可进入到Pod当中(加入Namespace中),查看容器内容
$ kubectl exec -it nginx-deployment-5c678cfb6d-lg9lw -- /bin/bash
# ls /usr/share/nginx/html删除Pod
从k8s集群当中,删除应用
$ kubectl delete -f nginx-deployment.yaml