关于Containers:
容器是一种将应用程序的(编译)代码与运行时所需的依赖项一起打包的技术。您运行的每个容器都是可重复的;包含依赖项的标准化意味着无论您在何处运行它都会获得相同的行为。
关于InitContainer:
初始化容器与普通容器完全一样,除了:
- 初始化容器总是在容器执行之前运行完成。
- 每个 initContainer必须在下一个启动之前成功完成。
- 如果 Pod 的 init 容器失败,Kubernetes 会反复重启 Pod,直到 init 容器成功。但是,如果 Pod 的
restartPolicy 为 Never,Kubernetes 不会重启 Pod。
总结:
Containers 托管您的 dockerized 应用程序,initContainer 运行在主容器执行之前运行所需的任务。
一个简单的例子是您提供的代码:
- 您创建了一个带有 php 服务器的容器,但您希望始终更新
index.html 的内容,而无需更改 pod 清单本身。
- 所以您添加了一个
initContainer 来获取更新后的index.php 并添加到容器中。
- 我已使用
volume 参数修复了您的yaml,以添加将保存下载文件的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。
注意: 上面的网络服务器功能不完整,因为完整的php-fpm 部署稍微复杂一些,而且它不是这个问题的核心,所以我将把本教程留给它:PHP-FPM, Nginx, Kubernetes, and Docker
有人可能会争辩说,index.html 不是 Pod 初始化的关键文件,并且可以在 pod 执行期间使用 Command 替换,所以我将在这里留下一个答案,我给出的答案是在 pod 初始化之前持续更改 resolv.conf pod 重启后:DNS Config is Skipped in GKE.
initContainer 的另一个很好的用法是让 pod 在初始化之前等待集群中的另一个资源准备好。
- 这是一个带有
initContainer 的名为 init-mydb 的 pod,它在允许容器 myapp-container 启动之前等待并监视名为 mydb 的服务处于 running 状态,假设 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
- pod 处于
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
如果您有任何问题,请在 cmets 中告诉我!