目录
目录一、Pod介绍1.1 了解pod1.2 Pods如何管理多个容器1.3 使用Pod二、Pod的基本操作2.1 pods和namespaces2.2 创建、使用、删除Pod及镜像pull策略的讲解2.3 Pod里面配置多个容器2.3 pause容器的理解2.4 yaml文件里面各个参数的定义的帮助手册查看。技巧,一定要记住2.5 查看pod中容器的定义及创建过程及node日志查看(Event事件信息)2.6 Pod里面如何进入容器。2.7 Pod里面的运行命令,生命周期,重启策略2.8 Pod中使用变量三、静态Pod四、初始化容器 InitContainers
一、Pod介绍
https://kubernetes.io/docs/concepts/workloads/pods/pod-overview/ 官网介绍
http://docs.kubernetes.org.cn/312.html 中文kubernetes社区介绍
1.1 了解pod
Pod是Kubernetes创建或部署的最小/最简单的基本单位,一个Pod代表集群上正在运行的一个进程。
一个Pod封装一个应用容器(也可以有多个容器),存储资源、一个独立的网络IP以及管理控制容器运行方式的策略选项。Pod代表部署的一个单位:Kubernetes中单个应用的实例,它可能由单个容器或多个容器共享组成的资源。
Docker是Kubernetes Pod中最常见的runtime ,Pods也支持其他容器runtimes。
Kubernetes中的Pod使用可分两种主要方式:
Pod中运行一个容器。“one-container-per-Pod”模式是Kubernetes最常见的用法; 在这种情况下,你可以将Pod视为单个封装的容器,但是Kubernetes是直接管理Pod而不是容器。
Pods中运行多个需要一起工作的容器。Pod可以封装紧密耦合的应用,它们需要由多个容器组成,它们之间能够共享资源,这些容器可以形成一个单一的内部service单位,一个容器共享文件,另一个“sidecar”容器来更新这些文件。Pod将这些容器的存储资源作为一个实体来管理。
每个Pod都是运行应用的单个实例,如果需要水平扩展应用(例如,运行多个实例),则应该使用多个Pods,每个实例一个Pod。在Kubernetes中,这样通常称为Replication。Replication的Pod通常由Controller创建和管理。
1.2 Pods如何管理多个容器
请注意,在单个Pod中共同管理多个容器是一个相对高级的用法,应该只有在容器紧密耦合的特殊实例中使用此模式。例如,有一个容器被用作WEB服务器,用于共享volume,以及一个单独“sidecar”容器需要从远程获取资源来更新这些文件,如下图所示:

Pod提供两种共享资源:存储和网络
网络:每个Pod被分配一个独立的IP地址,Pod中的每个容器共享网络命名空间,包括IP地址和网络端口。Pod内的容器可以使用localhost相互通信。当Pod中的容器与Pod 外部通信时,他们必须协调如何使用共享网络资源(如端口)
存储:Pod可以指定一组共享存储volumes。Pod中的所有容器都可以访问共享volumes,允许这些容器共享数据。volumes 还用于Pod中的数据持久化,以防其中一个容器需要重新启动而丢失数据。有关Kubernetes如何在Pod中实现共享存储的更多信息,请参考Volumes。
1.3 使用Pod
Pod是有生命周期的。用后即焚的实体。所以会很少直接在kubernetes中创建单个pod。
注意:重启Pod中的容器跟重启Pod不是一回事。Pod只提供容器的运行环境并保持容器的运行状态,重启容器不会造成Pod重启。
Pod不会自愈,如果Pod运行的Node故障,或者是调度器本身故障,这个Pod会被删除。如果Pod所在的Node缺少自愈或者Pod处于维护状态,Pod也会被驱逐。
kubernetes使用controller的抽象层来管理Pod实例。controller可以创建和管理多个Pod,提供副本管理,滚动升级和集群级别的自愈能力。
二、Pod的基本操作
在上面提供的连接中,会有Pod模板这个段落。通过这个模板我们来了解Pod是如何运作和管理的
2.1 pods和namespaces
#查看当前k8s集群上有哪些命名空间
[root@master yaml]# kubectl get namespaces
NAME STATUS AGE
default Active 22h
kube-public Active 22h
kube-system Active 22h
#查看pods在那些命名空间上运行。默认创建的pods是在default里面运行
[root@master yaml]# kubectl get pods --namespace= #可以查看具体的命名空间下的pod
default kube-public kube-system
[root@master yaml]# kubectl get pods --all-namespaces #查看所有命名空间下的pod
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-594954f7fb-fvfqf 1/1 Running 4 22h
kube-system coredns-594954f7fb-m995v 1/1 Running 4 22h
kube-system etcd-master.cs.com 1/1 Running 5 22h
kube-system kube-apiserver-master.cs.com 1/1 Running 5 22h
kube-system kube-controller-manager-master.cs.com 1/1 Running 5 22h
kube-system kube-flannel-ds-amd64-2qqmc 1/1 Running 4 22h
kube-system kube-flannel-ds-amd64-v5ms7 1/1 Running 5 22h
kube-system kube-flannel-ds-amd64-v5vlb 1/1 Running 3 22h
kube-system kube-proxy-6vsfj 1/1 Running 4 22h
kube-system kube-proxy-h5cqv 1/1 Running 5 22h
kube-system kube-proxy-wp5zq 1/1 Running 5 22h
kube-system kube-scheduler-master.cs.com 1/1 Running 5 22h
2.2 创建、使用、删除Pod及镜像pull策略的讲解
#获取当前运行的pod,可以看到没有运行的pods
[root@master yaml]# kubectl get pods
No resources found.
#创建Pod模板的几种方式
官方文档中使用pod模板文件yaml
使用run命令行的方式来生成pod模板文件yaml
kubectl run test-web --image=nginx --generator=run-pod/v1 --dry-run -o yaml > pod2.yaml
用get命令导出
kubectl get test-web -o=yaml --export >new.yaml
#可以到官网文档查阅模板。在编写yaml时候一定要注意语法缩进。https://kubernetes.io/docs/concepts/workloads/pods/pod-overview/里面有个Pod模板。我们复制这个模板,命名为pod1.yaml
[root@master yaml]# cat pod1.yaml
apiVersion: v1 #版本号,这里V1.可以通过kubectl api-version查看
kind: Pod #表明资源对象的类型,这里是Pod
metadata: #对象元数据
name: myapp-pod #Pod的名称。可以创建后通过kubectl get pods查看
labels: #自定义标签列表
app: myapp
spec: #对容器的定义,在容器上加一层壳就是pod
containers: #容器列表
- name: myapp-container #容器的名称
image: busybox #容器使用的镜像名称
command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 3600'] #容器里面运行的内容
#使用命令来生成pod模板yaml文件。也要记住。
[root@master yaml]# kubectl run test-web --image=nginx --generator=run-pod/v1 --dry-run -o yaml > pod2.yaml
[root@master yaml]# cat pod2.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: test-web
name: test-web
spec:
containers:
- image: nginx
name: test-web
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
#指定一个pod模板文件来创建pod
kubectl apply -f pod1.yaml #建议使用。英语配置到给定的资源。资源如果不存在会自动创建,可以用来修改资源的信息。
kubectl create -f pod1.yaml #使用指定模板来创建资源。pod1.yaml使用后,后面就无法使用了。只能用一次。
[root@master yaml]# kubectl apply -f pod1.yaml
pod/myapp-pod created
[root@master yaml]# kubectl get pods #可以看到生成了一个pod
NAME READY STATUS RESTARTS AGE
myapp-pod 1/1 Running 0 20s
##这里思考一下。
我主机上面没有pod2.yaml文件里面的busybox镜像。但是在生成pods的时候却自动下载了一个busybox镜像。我如果在没网络的环境中,我自己本地有镜像,pod会创建成功吗?
#首先查看下pods的详细信息,可以看到pod的ip地址,运行在那个节点
[root@master yaml]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
myapp-pod 1/1 Running 0 2m54s 10.244.1.25 node1 <none> <none>
#然后到node1节点查看,发现确实下载了一个busybox的镜像
[root@node1 ~]# docker images |grep busybox
docker.io/busybox latest af2f74c517aa 2 weeks ago 1.2 MB
其实这里有一个镜像下载策略imagePullPolicy
#如何查看当前pod资源的默认策略呢。可以直接使用kubectl edit调用本地编辑器,直接编辑API资源。edit命令会打开使用KUBE_EDITOR,GIT_EDITOR 或者EDITOR环境变量定义的编辑器,可以同时编辑多个资源,但所编辑过的资源只会一次性提交。edit除命令参数外还接受文件名形式。
#文件默认输出格式为YAML。要以JSON格式编辑,请指定“-o json”选项。
#如果在更新资源时报错,将会在磁盘上创建一个临时文件来记录。在更新资源时最常见的错误是几个用户同时使用编辑器更改服务器上资源,发生这种情况,你需要将你的更改应用到最新版本的资源上,或者更新保存的临时副本。
[root@master ~]# kubectl edit pods myapp-pod
imagePullPolicy: Always
可以看到当前镜像的下载策略是Always。现在又遇到问题,我如何知道这些默认配置的含义,并且我需要配置不允许下载网络镜像,只能使用本地镜像呢?
[root@master ~]# kubectl explain pods.spec.containers.imagePullPolicy #这种方法后面会单独提出
KIND: Pod
VERSION: v1
FIELD: imagePullPolicy <string>
DESCRIPTION:
Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always
if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated.
More info:
https://kubernetes.io/docs/concepts/containers/images#updating-images
看上面的层层定义来查看。就可以回答上面的问题了,镜像的下载策略:Always, Never, IfNotPresent. Defaults to Always。Alway每次下载最新的镜像,Never只使用本地镜像,从不下载,IfNotPresent本地没有才下载。建议可以使用IfNotPresent。根据具体情况设置。
可以在pod1.yaml添加一行,就可以实现了。然后重新应用。
[root@master yaml]# cat pod1.yaml |grep imagePullPolicy
imagePullPolicy: Never
[root@master yaml]#kubectl get pods #可以看到如果我本地没用镜像,则会报一下错误
NAME READY STATUS RESTARTS AGE
myapp-pod 0/1 ImagePullBackoff 0 20s
#删除pods
[root@master yaml]# kubectl delete pods/myapp-pod 这种写法和kubectl delete pod myapp-pod一样
pod "myapp-pod" deleted
2.3 Pod里面配置多个容器
#编辑yaml文件
[root@master yaml]# cat pod1.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container1 #容器1
image: busybox
imagePullPolicy: IfNotPresent
command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 3600']
- name: myapp-container2 #容器2.如果要创建多个容器,就复制多个。
image: busybox
imagePullPolicy: IfNotPresent
command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 3600']
#这里其实可以看出来。这两个容器耦合度其实是没有的,这种建议一个pod运行一个node。也符合了前面的定义。如果耦合度很高的呢?
[root@master yaml]# cat web.yaml (这个文件参考Kubernetes权限指南第二版)
apiVersion: v1
kind: Pod
metadata:
name: web
labels:
name: web
spec:
containers:
- name: frontend
image: docker.io/kubeguide/guestbook-php-frontend:localredis
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
- name: redis
image: docker.io/kubeguide/redis-master
imagePullPolicy: IfNotPresent
ports:
- containerPort: 6379
docker.io/kubeguide/guestbook-php-frontend:localredis的php网页中,直接通过URL地址“localhost:6379”对同属于一个pod内的redis-master进行访问。
#查看pods状态。加-w可以观察对象的创建进度
[root@master yaml]# kubectl get pods -w
NAME READY STATUS RESTARTS AGE
myapp-pod 0/2 ContainerCreating 0 3s
myapp-pod 2/2 Running 0 11s
[root@master yaml]# kubectl get pods
NAME READY STATUS RESTARTS AGE
myapp-pod 2/2 Running 0 63s #可以看到有两容器了
[root@master yaml]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
myapp-pod 2/2 Running 0 100s 10.244.1.26 node1 <none> <none>
#到这里,我们就可以看出来第一章节定义:一个Pod封装一个应用容器(也可以有多个容器),存储资源(后面会讲)、一个独立的网络IP以及管理控制容器运行方式的策略选项
#节点端信息查看。可以看到2和容器正在运行
[root@node1 ~]# docker ps |grep myapp-pod
fd2285b18df5 af2f74c517aa "sh -c 'echo Hello..." 5 minutes ago Up 5 minutes k8s_myapp-container2_myapp-pod_default_4a39fcf4-642b-11e9-9773-000c29ba8de2_0
fe05a60f30cd af2f74c517aa "sh -c 'echo Hello..." 5 minutes ago Up 5 minutes k8s_myapp-container1_myapp-pod_default_4a39fcf4-642b-11e9-9773-000c29ba8de2_0
6a93d085cf13 k8s.gcr.io/pause:3.1 "/pause" 5 minutes ago Up 5 minutes k8s_POD_myapp-pod_default_4a39fcf4-642b-11e9-9773-000c29ba8de2_0
2.3 pause容器的理解
A.每个node节点里面都运行了一个pause容器,和Pod是一一对应的关系
B.pause容器之外的叫业务容器(业务容器共享pause容器的网络栈和存储卷),同一个Pod内多个容器能通信何文件共享主要就是靠它
C.功能:PID命名空间,网络命名空间,IPC命名空间,UTS命名空间
D.一个Pod里面由多个容器,其中一个容器故障,并不代表整个Pod出现故障。所以以pause的状态代表整个Pod的状态。
2.4 yaml文件里面各个参数的定义的帮助手册查看。技巧,一定要记住
小技巧:一定要记住
#如果没用模板如何编写呢?可以使用kubectl explain查看帮助文档
#比如我要获取pods的yaml里面的参数
[root@master yaml]# kubectl explain pods #先获取pods的定义及在yaml中是如何定义的
#进一步查看,我要知道具体某个参数的用法和定义呢?
[root@master yaml]# kubectl explain pods.spec.containers.image 就得到了这个下面的详细定义及用法说明。
KIND: Pod
VERSION: v1
FIELD: image <string>
DESCRIPTION:
Docker image name. More info:
https://kubernetes.io/docs/concepts/containers/images This field is
optional to allow higher level config management to default or override
container images in workload controllers like Deployments and StatefulSets.
2.5 查看pod中容器的定义及创建过程及node日志查看(Event事件信息)
[root@master ~]# kubectl describe pod myapp-pod #可以看到报错信息
Name: myapp-pod
Namespace: default
Priority: 0
PriorityClassName: <none>
Node: node1/192.168.48.151
Start Time: Sun, 21 Apr 2019 19:47:50 +0800
Labels: app=myapp
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"labels":{"app":"myapp"},"name":"myapp-pod","namespace":"default"},"spec":{"c...
Status: Running
IP: 10.244.1.26
Containers:
myapp-container1:
Container ID: docker://fe05a60f30cd0b4a8f88a5cf1c9d097d7ded7b35e9f27f34f581114ae71edc53
Image: busybox
Image ID: docker-pullable://docker.io/busybox@sha256:954e1f01e80ce09d0887ff6ea10b13a812cb01932a0781d6b0cc23f743a874fd
Port: <none>
Host Port: <none>
Command:
sh
-c
echo Hello Kubernetes! && sleep 3600
State: Running
Started: Sun, 21 Apr 2019 19:48:01 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-qvtvh (ro)
myapp-container2:
Container ID: docker://fd2285b18df53564b939918af9689807ee23755f48093441bc06ca98ae7c1f57
Image: busybox
Image ID: docker-pullable://docker.io/busybox@sha256:954e1f01e80ce09d0887ff6ea10b13a812cb01932a0781d6b0cc23f743a874fd
Port: <none>
Host Port: <none>
Command:
sh
-c
echo Hello Kubernetes! && sleep 3600
State: Running
Started: Sun, 21 Apr 2019 19:48:01 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-qvtvh (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-qvtvh:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-qvtvh
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 21m default-scheduler Successfully assigned default/myapp-pod to node1
Normal Pulled 20m kubelet, node1 Container image "busybox" already present on machine
Normal Created 20m kubelet, node1 Created container
Normal Started 20m kubelet, node1 Started container
Normal Pulled 20m kubelet, node1 Container image "busybox" already present on machine
Normal Created 20m kubelet, node1 Created container
Normal Started 20m kubelet, node1 Started container
#Node节点日志查看
[root@node1 ~]# journalctl -u kubelet
-- Logs begin at 六 2019-04-20 22:21:56 CST, end at 日 2019-04-21 21:17:25 CST. --
4月 20 22:22:01 node1 systemd[1]: Started kubelet: The Kubernetes Node Agent.
4月 20 22:22:01 node1 systemd[1]: Starting kubelet: The Kubernetes Node Agent...
4月 20 22:22:13 node1 kubelet[649]: Flag --cgroup-driver has been deprecated, This parameter should be set via the config file specified by the Ku
4月 20 22:22:13 node1 kubelet[649]: Flag --cgroup-driver has been deprecated, This parameter should be set via the config file specified by the Ku
4月 20 22:22:13 node1 kubelet[649]: I0420 22:22:13.803745 649 server.go:407] Version: v1.13.3
#查看容器日志
[root@master yaml]# kubectl logs myapp-pod -c myapp-container1
Hello Kubernetes!
2.6 Pod里面如何进入容器。
#这里和docker使用方式一样
[root@master yaml]# kubectl exec myapp-pod -it ls /
Defaulting container name to myapp-container1.
Use 'kubectl describe pod/myapp-pod -n default' to see all of the containers in this pod.
bin dev etc home proc root run sys tmp usr var
[root@master yaml]# kubectl exec myapp-pod -it sh
Defaulting container name to myapp-container1.
Use 'kubectl describe pod/myapp-pod -n default' to see all of the containers in this pod.
/ # ls
bin dev etc home proc root run sys tmp usr var
/ # touch test
/ # ls
bin dev etc home proc root run sys test tmp usr var
#多个容器的话,默认是进入第一个
就是yaml文件里面的定义顺序
spec:
containers:
- name: myapp-container1
image: busybox
imagePullPolicy: IfNotPresent
command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 3600']
- name: myapp-container2
image: busybox
imagePullPolicy: IfNotPresent
command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 3600']
#如何指定进入那个容器。
[root@master yaml]# kubectl exec myapp-pod -it -c myapp-container2 sh
/ # ls
bin dev etc home proc root run sys tmp usr var
2.7 Pod里面的运行命令,生命周期,重启策略

#Pod的生命周期
[root@master yaml]# kubectl explain pod.status.phase
KIND: Pod
VERSION: v1
FIELD: phase <string>
DESCRIPTION:
The phase of a Pod is a simple, high-level summary of where the Pod is in
its lifecycle. The conditions array, the reason and message fields, and the
individual container status arrays contain more detail about the pod's
status. There are five possible phase values: Pending: The pod has been
accepted by the Kubernetes system, but one or more of the container images
has not been created. This includes time before being scheduled as well as
time spent downloading images over the network, which could take a while.
Running: The pod has been bound to a node, and all of the containers have
been created. At least one container is still running, or is in the process
of starting or restarting. Succeeded: All containers in the pod have
terminated in success, and will not be restarted. Failed: All containers in
the pod have terminated, and at least one container has terminated in
failure. The container either exited with non-zero status or was terminated
by the system. Unknown: For some reason the state of the pod could not be
obtained, typically due to an error in communicating with the host of the
pod. More info:
https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-phase
#有道翻译大概如下:
#pod的状态在上面中定义,Pod的phase是简单,高级总结它的生命周期。有五个阶段值
#phase的值:
pend:pod已经存在接受Kubernetes系统,但一个或多个容器映像尚未创建。(比如正在网上拉取镜像)
Running:pod已绑定到一个节点,所有容器都已绑定被创建。至少有一个容器仍在运行,或者在进程中启动或重新启动的。
succeeded:pod中的所有容器都有在成功终止后,将不会重新启动。
Failed:所有容器都退出,且至少有一个容器非正常退出。
unknown:由于某种原因,Pod的状态不可能是获取,通常由于与主机通信时出错。
#运行命令,对长时间运行容器的要求是:主程序需要一直在前台执行。如果在后台执行,比如我们习惯加&调到后台运行程序。则运行完这个命令,则就会认为Pod结束,然后根据RC定义的副本数,反复创建新的Pod。陷入无线循环。所以需要我们自己创建的镜像要以前台命令作为启动的原因。可以参考工具Supervisor。
[root@master yaml]# cat pod1.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container1
image: busybox
imagePullPolicy: IfNotPresent
command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 3600'] 这个command写法还有另外一种方式,可以通过kubectl edit查看
command:(也可以换成age:)
- sh
- -c
- echo Hello Kubernetes! && sleep 20
#pod里面就是容器,容器里面就是进程,进程结束容器就退出
这个官方的pod模板运行周期是3600s,运行完后就会关闭。为了测试,时间改为20s
[root@master yaml]# kubectl get pods -w
NAME READY STATUS RESTARTS AGE
myapp-pod 1/1 Running 0 16s
myapp-pod 0/1 Completed 0 32s
myapp-pod 1/1 Running 1 33s
myapp-pod 0/1 Completed 1 53s
myapp-pod 0/1 CrashLoopBackOff 1 66s
myapp-pod 1/1 Running 2 67s
myapp-pod 0/1 Completed 2 87s
myapp-pod 0/1 CrashLoopBackOff 2 101s
myapp-pod 1/1 Running 3 116s
可以看到20s间隔重启一次,restarts计数器+1
#如何能让容器不自动重启呢?
#重启策略
我们看看系统默认的重启策略是:docker也一样(docker参数--restart=)
#kubectl edit pods myapp-pod
restartPolicy: Always
具体查看方法就不说了:
三种重启策略:
Always:总是重启是restarts计数器加1
Never:永不重启,则是命令运行完容器就退出。没有重启计数器。
[root@master yaml]# kubectl get pods
NAME READY STATUS RESTARTS AGE
myapp-pod 0/1 Completed 0 36s
OnFailure:只有失败了才重启
这里其实就是上面两种的结合,会有两种状态,如果运行成功就会有Never的状态,失败就会计数器加1,并退出并报错
[root@master yaml]# kubectl get pods
NAME READY STATUS RESTARTS AGE
myapp-pod 0/1 CrashLoopBackOff 1 12s
2.8 Pod中使用变量
#创建一个yaml
[root@master yaml]# cat pod5.yaml
apiVersion: v1
kind: Pod
metadata:
name: demo
labels:
purpose: demonstrate-envars
spec:
containers:
- name: env-demo
image: nginx #nginx镜像有个后台进程,所以不需要command运行命令
env:
- name: DEMOX
value: "hello x sir"
- name: DEMOY
value: "hello y sir"
[root@master yaml]# kubectl get pods #已经运行起来了。查看变量是否生效
NAME READY STATUS RESTARTS AGE
demo 1/1 Running 0 15s
[root@master yaml]# kubectl exec demo -it bash #可以看到变量在容器中已经生效
root@demo:/# env |grep DEMO
DEMOY=hello y sir
DEMOX=hello x sir
[root@node1 ~]# docker exec -it b027d4fda0f7 bash
root@demo:/# env |grep DEMO
DEMOY=hello y sir
DEMOX=hello x sir
[root@node1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b027d4fda0f7 docker.io/nginx@sha256:e71b1bf4281f25533cf15e6e5f9be4dac74d2328152edf7ecde23abc54e16c1c "nginx -g 'daemon ..." 11 minutes
#如果yaml文件改为这样。command里面的命令将覆盖nginx默认的后台进程(上面看到的)。执行结果将是“hello x sir”
spec:
containers:
- name: env-demo
image: nginx
env:
- name: DEMOX
value: "hello x sir" #传递了一个变量
command: ["/bin/echo"]
args: ["$(DEMOX)"]
#如果command和args都没有些,则用docker默认配置
#如果command写了,但args没写,则docker默认的配置会被忽略仅仅指向yaml文件的command(不带任何参数)
#如果command没写,但args写了,则docker默认配置的环境变量会被执行,但是调用的参数的是yaml文件的args
#如果都写了。那面docker默认的配置被忽略,使用yaml配置
三、静态Pod
由kubelet进行管理的存在于特定的Node上的Pod。不能通过API server进行管理,无法与RC,Deployment,DaemonSet进行关联。静态Pod总是由kubelet进行创建,并总是在Kubelet所在的Node上运行,不接受master管理。(这样理解:不需要master管理的pod,可以放到其他节点上去,让节点的kubelet自己管理)
静态pod创建两种方式:配置文件和http。一般是配置文件
如果在安装的时候没有指明--config=/etc/kubelet.d启动参数:kubelet需要监控的配置文件所在目录,会定期扫描该目录中的.yaml或.json文件进行创建。
那我们需要根据以下配置操作:
#节点上查看kubelet状态
[root@node1 ~]# systemctl status kubelet
● kubelet.service - kubelet: The Kubernetes Node Agent
Loaded: loaded (/etc/systemd/system/kubelet.service; enabled; vendor preset: disabled)
Drop-In: /etc/systemd/system/kubelet.service.d
└─10-kubeadm.conf
Active: active (running) since 一 2019-04-22 09:59:24 CST; 36min ago
Docs: https://kubernetes.io/docs/
Main PID: 1225 (kubelet)
CGroup: /system.slice/kubelet.service
#根据命令提示的加载路径可以看到/etc/systemd/system/kubelet.service.d/10-kubeadm.conf
[root@node1 kubelet.service.d]# cat ../kubelet.service
[Unit]
Description=kubelet: The Kubernetes Node Agent
Documentation=https://kubernetes.io/docs/
[Service]
ExecStart=/usr/bin/kubelet
Restart=always
StartLimitInterval=0
RestartSec=10
[Install]
WantedBy=multi-user.target
[root@node1 kubelet.service.d]# cat 10-kubeadm.conf
# Note: This dropin only works with kubeadm and kubelet v1.11+
[Service]
Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf"
Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml"
# This is a file that "kubeadm init" and "kubeadm join" generates at runtime, populating the KUBELET_KUBEADM_ARGS variable dynamically 这个文件由init和join运行时生成的文件,动态填充KUBELET_KUBEADM_ARGS这个变量
EnvironmentFile=-/var/lib/kubelet/kubeadm-flags.env
# This is a file that the user can use for overrides of the kubelet args as a last resort. Preferably, the user should use
# the .NodeRegistration.KubeletExtraArgs object in the configuration files instead. KUBELET_EXTRA_ARGS should be sourced from this file.
EnvironmentFile=-/etc/sysconfig/kubelet
ExecStart=
ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS
#在10-kubeadm.conf中在Environment变量中添加一个参数
[root@node1 kubelet.service.d]# cat 10-kubeadm.conf |grep -i "pod-manifest"
Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --pod-manifest-path=/etc/kubelet.d"
#重新加载配置
[root@node1 kubelet.service.d]# systemctl daemon-reload
[root@node1 kubelet.service.d]# systemctl restart kubelet.service
#node端可以看到已经生成了一个容器
[root@node1 kubelet.service.d]# docker ps |grep 'pod_static'
76bfce4a7d83 docker.io/nginx@sha256:e71b1bf4281f25533cf15e6e5f9be4dac74d2328152edf7ecde23abc54e16c1c "nginx -g 'daemon ..." About a minute ago Up About a minute k8s_static-pod_static-pod-node1_default_34285fdccae215c230fc7c5fbab9e289_0
#master端也可以看到生成了一个pod
[root@master yaml]# kubectl get pods
NAME READY STATUS RESTARTS AGE
static-pod-node1 1/1 Running 0 2m7s
#由于是静态pod。不通过API通信,所以在master删除这个pod会有什么影响呢?
[root@master yaml]# kubectl delete pods static-pod-node1
pod "static-pod-node1" deleted
[root@master yaml]# kubectl get pods #pod已经被关闭,处于pengding状态但是客户端容器运行没有任何影响。而且过一会又会自动拉起来变成running状态
NAME READY STATUS RESTARTS AGE
static-pod-node1 0/1 Pending 0 2s
[root@node1 kubelet.service.d]# docker exec -it 76bfce4a7d83 bash
root@static-pod-node1:/#
#如何删除静态pod呢,只需要在node端目录下删除对应的yaml文件就可以了
[root@node1 kubelet.d]# pwd
/etc/kubelet.d
[root@node1 kubelet.d]# rm pod5.yaml
rm:是否删除普通文件 "pod5.yaml"?y
[root@node1 kubelet.d]# docker ps |grep 'pod_static' #文件一删除,马上容器就删除了
[root@node1 kubelet.d]#
[root@master yaml]# kubectl get pods #master端也没有pod了
No resources found.
我想这种应用主要针对,比如master宕掉,不能对node管理,现在正好node有pod出现问题(而且急需要上线一个新的业务),可以临时把yaml文件导入到pod,临时拉起一个应用。后面如果master恢复,在把静态pod中pod导出成yaml文件运行。
四、初始化容器 InitContainers
初始化容器 init container ,是为其他容器做准备。先与普通应用容器先执行。
比如这样方便理解:
容器A依赖其他容器,可以设置A多个依赖容器A1 A2 A3A1 A2 A3按照顺序启动,A1没用启动起来,A2A3是不会启动,直到所有静态容器全部完成启动,容器A才会启动一般A容器启动运行之前,先做的一些准备工作。这个准备工作就是初始化容器。如果初始化容器失败,则会一直重启,Pod不会创建。
运用场景:
1.解决服务之间的依赖问题。我们一个web服务,web依赖于数据库。所以要报账数据库启动完成后才启动web。
2.做初始化配置的,解决顺序问题。
#创建yaml,创建一个卷workdir,类型emptyDir。创建一个nginx容器,挂载存储卷workdir到/xx目录。初始化容器init-pod,挂载存储卷workdir,挂载路径/work-dir,并在卷里面创建一个aa.txt文件
#然后到nginx容器里面查看是否有这个文件。就可证明初始化容器。
#这个例子也可以看出,同一个pod里面多个容器能够共享pod级别的存储卷volume
[root@master yaml]# cat pod5.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
volumes:
- name: workdir
emptyDir: {}
containers:
- name: myapp-container
image: nginx
volumeMounts:
- name: workdir
mountPath: "/xx"
initContainers:
- name: init-pod
image: busybox
command: ['sh','-c','touch /work-dir/aa.txt']
volumeMounts:
- name: workdir
mountPath: "/work-dir"
[root@master yaml]# kubectl get pods #可以看到初始化容器没有创建,只创建了myapp-pod
NAME READY STATUS RESTARTS AGE
myapp-pod 0/1 Init:0/1 0 12s
[root@master yaml]# kubectl get pods -w
NAME READY STATUS RESTARTS AGE
myapp-pod 0/1 PodInitializing 0 16s
myapp-pod 1/1 Running 0 18s
[root@master yaml]# kubectl exec myapp-pod -it bash
root@myapp-pod:/#
root@myapp-pod:/# cd xx/
root@myapp-pod:/xx# ls
aa.txt




