作为和Docker Swarm对比,在kubernetes中不能直接运行容器。在Kubernetes群集中,只能运行pods。Pods在kubernetes中是部署的原子单位。一个Pod是一个或者多个共存的容器,它们共享着相同的内核命名空间,比如网络命名空间。下图是对两个Pods进行阐述。
在上图中,有两个pods,Pod1和Pod2。第一个pod包含两个容器,第二个仅包含一个容器。每个Pod都获得了Kubernetes群集分配给它的唯一的IP。 上面的示例中,分配的IP分别是10.0.12.3和10.0.12.5 .
一个pod可以包含一个或者多个容器。所有这些容器共享着相同的内核名称空间,并且它们共享着相同的网络命名空间。但是端口号是不能够重复的。比如在Pod1中,main container使用的端口是80,而supporting容器使用的端口号是3000.
但一个Docker的容器进行创建的时候,Docker会自动给它们创建网卡并分配IP地址,所以容器之间的应用是隔离的,并且也使用的是不同的命名空间。
但对于kubernetes pod来说,这种情况就不同了。当创建一个新的pod时,kubernetes首先创建所谓的pause container,该容器只负责创建和管理命名空间,而命名空间就是给pod中的所有容器共享使用的。 除此之外,它没有其它用处。 Pause容器通过veth0连接着bridge docker0。其它容器使用Docker engine的功能来让其它容器使用已经存在的网络命名空间。语法如下:
$ docker container create –net container:pause …
上面的语法–net选项,就是使用container:作为值。假如使用上面的方式创建一个新的容器,那么Docker 将不会创建一个新的veth终端,因为容器会使用和pause相同的一个。
另外一点就是多个容器使用相同的网络命名空间如何实现通信。
请看下图:
Containers in pods communicate via localhost
两个使用相同的Linux内核网络命名空间的容器,它们可以通过localhost做到和对方进行通信,有点和运行在一个主机上的两个进程通过本地主机通信一样。
$ docker container run -d –name pause nginx:alpine
$ docker container run –name main -dit \
–net container:pause \
alpine:latest /bin/sh
$ docker exec -it main /bin/sh
容器的生命周期是,实始化–运行—最后结束。相同的pod也有生命周期的,由于Pod可以包含一个或者多个容器,因此它的生命周期比单一容器的生命周期要复杂的多。生命周期可以依下图来描述。
当pod在群集节点中创建后,它第一步就会进入pending状态。只要pod中的所有容器启动和正常运行,那么pod第二步就会进入running状态。假如pod被要求终止,那第就进入了第三步进行终止。假如所有的容器终止退出时状态码且为0,那么这个pod就进入了成功的状态。
假如Pod是处于运行状态的,但是有pod中的一个容器突然由于某种原因损坏或退出的状态码不为0。 那么pod状态将会从running转为failed状态。
假如pod在要求正常关闭的时候,有一个容器退出的状态码为非0,那么pod也会进入failed状态。
apiVersion: v1
kind: Pod
metadata:
name: web-pod
spec:
containers:
– name: web
image: nginx:alpine
ports:
– containerPort: 80
$ kubectl create -f pod.yaml
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
web-pod 1/1 Running 0 2m
容器可以挂载卷,那么pods同样也可以实现容器挂载卷的功能。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-data-claim
spec:
accessModes:
– ReadWriteOnce
resources:
requests:
storage: 2Gi
$ kubectl create -f volume-claim.yaml
apiVersion: v1
kind: Pod
metadata:
name: web-pod
spec:
containers:
– name: web
image: nginx:alpine
ports:
– containerPort: 80
volumeMounts:
– name: my-data
mountPath: /data
volumes:
– name: my-data
persistentVolumeClaim:
claimName: my-data-claim
$ kubectl create -f pod-with-vol.yaml
$ kubectl exec -it web-pod — /bin/sh
/ # cd /data
/data # echo “Hello world!” > sample.txt
/data # exit