作为应用开发者,首先制作容器的镜像,制作完成后,需要按照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

tags: 容器 应用部署 k8s