About 容器:
容器是一种用于打包应用程序的(编译的)代码及其运行时所需的依赖项的技术。您运行的每个容器都是可重复的;包含依赖项的标准化意味着无论您在何处运行它,都会获得相同的行为。
About 初始化容器:
Init 容器与常规容器完全相同,除了:
- 初始化容器总是在容器执行之前运行完成。
- 每个initContainer必须在下一个开始之前成功完成.
- 如果 Pod 的初始化容器失败,Kubernetes反复重启Pod直到初始化容器成功。但是,如果 Pod 有
restartPolicy
Never,Kubernetes 不会重启 Pod。
总结:Containers
托管您的 Docker 化应用程序,initContainer
运行需要运行的任务before主要容器执行。
一个简单的例子是您提供的代码:
- 您创建了一个带有 php 服务器的容器,但您想要以下内容
index.html
始终更新,而无需更改 pod 清单本身。
- 所以你添加了一个
initContainer
获取更新的index.php
并添加到容器中。
- 我已经修复了你的 yaml
volume
参数来添加emptyDir
这将保存下载的文件并更改mountPath
到默认的 html 文件夹/var/www/html
:
apiVersion: v1
kind: Pod
metadata:
name: php-updated
spec:
containers:
- name: php
image: php:7-fpm
volumeMounts:
- name: dir
mountPath: /var/www/html/
initContainers:
- name: install
image: busybox
volumeMounts:
- name: dir
mountPath: /var/www/html/
command:
- wget
- "-O"
- "/var/www/html/index.php"
- https://raw.githubusercontent.com/videofalls/demo/master/index.php
volumes:
- name: dir
emptyDir: {}
POC:
$ kubectl apply -f php.yaml
pod/php-updated created
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
php-updated 1/1 Running 0 3s
$ kubectl exec -it php-updated -- /bin/bash
root@php-updated:/var/www/html# cat index.php
<?php
echo 'Demo Test';
- 正如你所看到的
initContainer
在 Pod 之前运行,将文件下载到与 PHP 服务器共享的已安装卷Container
.
NOTE:上面的网络服务器并没有完全发挥作用,因为完整的php-fpm
部署稍微复杂一些,这不是这个问题的核心,所以我将把这个教程留给它:PHP-FPM、Nginx、Kubernetes 和 Docker
有人可能会争辩说index.html
不是 Pod 初始化的关键文件,可以在 pod 执行期间使用以下命令进行替换Command
所以我会在这里留下我为不断改变而给出的答案resolv.conf
在 Pod 初始化之前,甚至在 Pod 重新启动之后:GKE 中跳过 DNS 配置.
另一个很棒的用法initContainer
就是让一个pod在初始化之前等待集群中的另一个资源准备好。
- 这是一个带有
initContainer
called init-mydb
等待并监视名为的服务mydb
待在running
允许容器之前的状态myapp-container
开始,想象myapp-container
是一个需要数据库连接才能执行的应用程序,否则会反复失败。
再生产:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
run: my-app
name: my-app
spec:
replicas: 2
selector:
matchLabels:
run: my-app
template:
metadata:
labels:
run: my-app
spec:
restartPolicy: Always
containers:
- name: myapp-container
image: busybox:1.28
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
initContainers:
- name: init-mydb
image: busybox:1.28
command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]
$ kubectl apply -f my-app.yaml
deployment.apps/my-app created
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
my-app-6b4fb4958f-44ds7 0/1 Init:0/1 0 4s
my-app-6b4fb4958f-s7wmr 0/1 Init:0/1 0 4s
- 豆荚已坚持
Init:0/1
等待初始化容器完成的状态。
- 现在让我们创建一个服务
initContainer
正在等待running
在完成他的任务之前:
apiVersion: v1
kind: Service
metadata:
name: mydb
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9377
$ kubectl apply -f mydb-svc.yaml
service/mydb created
$ kubectl get pods -w
NAME READY STATUS RESTARTS AGE
my-app-6b4fb4958f-44ds7 0/1 Init:0/1 0 91s
my-app-6b4fb4958f-s7wmr 0/1 Init:0/1 0 91s
my-app-6b4fb4958f-s7wmr 0/1 PodInitializing 0 93s
my-app-6b4fb4958f-44ds7 0/1 PodInitializing 0 94s
my-app-6b4fb4958f-s7wmr 1/1 Running 0 94s
my-app-6b4fb4958f-44ds7 1/1 Running 0 95s
^C
$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/my-app-6b4fb4958f-44ds7 1/1 Running 0 99s
pod/my-app-6b4fb4958f-s7wmr 1/1 Running 0 99s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/mydb ClusterIP 10.100.106.67 <none> 80/TCP 14s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/my-app 2/2 2 2 99s
NAME DESIRED CURRENT READY AGE
replicaset.apps/my-app-6b4fb4958f 2 2 2 99s
如果您有任何疑问,请在评论中告诉我!