RedHat OpenShift QuickStart 1.2

一、在容器中传入/出文件

1. 创建一个初始化项目

oc login -u developer -p developer
oc new-project myproject

2. 在容器中下载文件

先通过镜像创建一个叫blog的应用

oc new-app openshiftkatacoda/blog-django-py --name blog

将应用暴露给外界:

oc expose svc/blog

监控应用的部署:

oc rollout status dc/blog

一旦部署完成,web应用程序准备就绪,该命令就会退出。

部署完成的结果就是一个运行的容器,你可以通过下面命令来查看该应用对应的pod名称:

oc get pods --selector app=blog

因为只是运行了一个应用实例,所以只会列出一个。

对于下面需要和pod进行交互,所以需要pod的名称作为参数

为了更容易地在这些指令中引用pod的名称,我们在这里定义了一个shell函数来捕获名称,以便将其存储在环境变量中。然后将在您运行的命令中使用该环境变量。

下面shell命令的功能只是取得pod的名称:

oc get pods --selector app=blog -o jsonpath='{.items[?(@.status.phase=="Running")].metadata.name}'

使用了带有--selector选择器的oc get pods命令,并且使用jsonpath来获取正在运行的pod的名称。

通过下面命令来创建shell函数:

pod() { local selector=$; local query='?(@.status.phase=="Running")'; oc get pods --selector $selector -o jsonpath="{.items[$query].metadata.name}"; }

在POD环境变量中获取pod的名称,运行:

POD=`pod app=blog`; echo $POD

要在运行应用程序的相同容器中创建交互式shell,可以使用oc rsh命令,为它提供包含pod名称的环境变量。

oc rsh $POD

在交互式shell中,查看应用程序目录中存在哪些文件。

ls -las

会有一个类似的文件:

44 -rw-r--r--. 1 1000520000 root 44032 Oct 24 02:51 db.sqlite3

验证你当前在哪个文件夹下:

pwd

输出:

/opt/app-root/src

退出

exit

使用oc rsync命令将容器内的文件拷贝到本地,格式是:

oc rsync <pod-name>:/remote/dir/filename ./local/dir

oc rsync $POD:/opt/app-root/src/db.sqlite3 .

应该显示:

receiving incremental file list db.sqlite3

sent 43 bytes received 44,129 bytes 88,344.00 bytes/sec

total size is 44,032 speedup is 1.00

使用ls -las查看当前本地的文件,应该可以看到db.sqlite3已经被拷贝到本地。

请注意,要将文件复制到其中的本地目录必须存在。如果不想将其复制到当前目录,请确保预先创建了目标目录。

你也同样可以拷贝文件夹到本地,命令格式如下:

oc rsync <pod-name>:/remote/dir ./local/dir

拷贝media文件夹到本地:

oc rsync $POD:/opt/app-root/src/media .

如果您希望在复制目录时重命名该目录,则应该首先使用要使用的名称创建目标目录。创建uploads文件夹

mkdir uploads
oc rsync $POD:/opt/app-root/src/media/. uploads

为了确保只复制容器上目录的内容,而不复制目录本身,远程目录的后缀是/.

注意,如果目标目录包含与容器中的文件同名的现有文件,则将覆盖本地文件。如果目标目录中有不存在于容器中的其他文件,则这些文件将保持原样。如果您确实需要一个完全相同的副本,其中目标文件夹总是被更新为与容器中存在的内容完全相同,那么可以使用——delete选项来运行oc rsync。

在复制目录时,可以通过使用--exclude和--include选项来指定要针对目录和文件进行匹配的模式,并根据需要排除或包含它们,这样可以更有选择性地选择要复制的内容。

如果在一个pod中有多个容器在运行,则需要使用--container选项指定要使用哪个容器。

3. 上传文件到容器

要将文件从本地机器复制到容器中,再次使用oc rsync命令。

将本地文件拷贝到容器,格式为:

oc rsync ./local/dir <pod-name>:/remote/dir

与从容器复制到本地机器不同,没有用于复制单个文件的表单。要仅复制选定的文件,您需要使用--exclude和--include选项来筛选从指定目录中复制的和未复制的内容。

使用curl访问容器中不存在的robots.txt文件,会出现404 not found:

curl --head http://blog-myproject.2886795272-80-shadow01.environments.katacoda.com/robots.txt

创建robots.txt文件以便上传:

cat > robots.txt << !
User-agent: *
Disallow: /
!

对于所使用的web应用程序,它从应用程序源代码的htdocs子目录中托管静态文件。上传robots.txt文件运行:

oc rsync . $POD:/opt/app-root/src/htdocs --exclude=* --include=robots.txt --no-perms

正如之前所述,复制单个文件到容器是不可能的,因此我们应该按照指示复制当前目录,首先使用--exclude=* 选项说明复制时应该忽略所有文件。通过--include=robots.txt选项覆盖之前的模式,可以只有robots.txt文件被拷贝。

在将文件复制到容器时,需要存在被复制文件所在的目录,并且可以将其写入容器作为其运行的用户或组。应该在构建镜像的过程中设置目录和文件的权限。

在上面的命令中,还使用了--no-perms选项,因为容器中的目标目录虽然可以由容器作为其运行时所在的组写入,但是它的所有者不同于容器作为其运行时所在的用户。这意味着虽然可以将文件添加到目录中,但是不能更改现有目录的权限。--no-perms选项告诉oc rsync不要尝试更新权限,以避免失败和返回错误。

如果想拷贝整个文件夹,那么就不要使用--exclude和--include选项,下面拷贝htdocs 文件夹到容器:

oc rsync . $POD:/opt/app-root/src/htdocs --no-perms

注意:这将会将所有文件拷贝,包含以.开头的隐藏文件或目录,你应该小心,如果需要的话使用--exclude和--include来限制拷贝的文件。

4. 与容器同步文件

除了上传下载外,还可以使用oc rsync来允许本地和容器实时同步文件。

也就是,你本地的文件系统将会监控文件改动,如果有改动,则会上传到容器中。如果需要,也可以反向运行,容器中文件的改变也可以同步到本地。

在应用程序开发期间,可以将本地计算机中的更改自动复制到容器中,这是一个很有用的例子。

像PHP,python,或者Ruby这种脚本语言,不需要单独的编译,手动重启web server也不会导致容器退出,web server可以一直加载修改后的文件,你可以在openshift上来进行开发代码。

为了演示这种功能,clone已经部署的web应用的仓库。

git clone https://github.com/openshift-katacoda/blog-django-py

这将会创建名为blog-django-py的包含源代码的字文件夹,

现在运行以下命令,让oc rsync对代码执行实时同步,将blog-django-py目录中的任何更改复制到容器中。

oc rsync blog-django-py/. $POD:/opt/app-root/src --no-perms --watch &

你可以使用下面命令来查看运行进度:

jobs

在改动代码之前,先看一下运行的应用:

http://blog-myproject.2886795272-80-shadow01.environments.katacoda.com/

你会看见网站的横幅是红色的

RedHat OpenShift QuickStart 1.2

现在来改变横幅的颜色:

echo "BLOG_BANNER_COLOR = 'blue'" >> blog-django-py/blog/context_processors.py

等待查看已上载的更改文件,然后刷新web站点的页面。

不幸的是,您将看到标题横幅仍然是红色的。这是因为对于Python来说,任何代码更改都由正在运行的进程缓存,因此有必要重新启动web服务器应用程序进程。

对于这个部署,将使用WSGI服务器mod_wsgi-express。要重新启动web服务器应用程序进程,请运行以下命令:

oc rsh $POD kill -HUP 

这个命令的作用是向容器中运行的进程ID 1发送HUP信号,它是正在运行的mod_wsgi-express的实例。这将触发所需的重新启动和重新加载应用程序,但不需要实际退出web服务器。

再次刷新页面将会看见横幅变蓝。

RedHat OpenShift QuickStart 1.2

请注意,标题横幅中显示的pod名称没有改变,这表示没有重新启动pod,只是重新启动了web服务器应用程序进程。

手动强制重新启动web服务器应用程序流程可以完成这项工作,但是更好的方法是web服务器能够自动检测代码更改并触发重新启动。

对于mod_wsgi-express以及如何配置这个web应用程序,可以通过设置部署的环境变量来启用它。要设置此环境变量,请运行:

oc set env dc/blog MOD_WSGI_RELOAD_ON_CHANGES=

该命令将更新部署配置,关闭现有的pod,并将其替换为应用程序的新实例,环境变量现在正传递给应用程序。

通过以下方式监控应用程序的重新部署:

oc rollout status dc/blog

因为之前存在的pod已经被关闭了,我们需要重新获取pod的名称:

POD=`pod app=blog`; echo $POD

因为失去了和pod的连接,后台运行的同步程序同样停止了。

可以通过jobs命令查看:

jobs

如果因为没有检测到pod停止而仍在运行,使用下面命令来停止:

kill - %

可以继续使用jobs命令来确认。继续运行oc rsync命令来建立和新pod的连接:

oc rsync blog-django-py/. $POD:/opt/app-root/src --no-perms --watch &

刷新blog项目的页面,页面的横幅应该是蓝色的,再次修改code,让横幅变为绿色:

echo "BLOG_BANNER_COLOR = 'green'" >> blog-django-py/blog/context_processors.py

可以需要等一段时间web server重启来达到横幅变绿的效果。

用下面命令杀死文件同步进程:

kill - %

虽然可以通过这种方式将本地计算机中的文件同步到容器中,但是是否可以将它用作启用实时编码的机制将取决于使用的编程语言和使用的web应用程序堆栈。当使用mod_wsgi-express时,这对于Python是可能的,但是对于Python或其他编程语言的其他WSGI服务器可能不可能。

请注意,即使对于Python,也只能在修改代码文件时使用。如果需要安装额外的Python包,则需要从原始源代码重新构建应用程序。这是因为在使用这种机制时,对包所需的更改(Python的更改在requirements.txt文件中给出)不会触发包的安装。

5. 将文件复制到持久卷

使用下面命令创建一个虚拟应用:

oc run dummy --image centos/httpd--centos7

我们使用oc run命令,因为它只创建一个部署配置和托管pod。没有创建服务,因为我们实际上并不需要在这里运行的应用程序(本例中是Apache HTTPD服务器的实例)是contactable的。我们使用Apache HTTPD服务器纯粹是为了保持pod运行。

要监视pod的启动并确保其部署,请运行以下命令:

oc rollout status dc/dummy

当它运行时,会创建一些资源对象,可以通过下面命令来查看:

oc get all --selector run=dummy -o name

我们创建一个永久卷并将其挂载在容器内部的/mnt上,这是Linux系统中用于临时挂载卷的传统目录。

oc set volume dc/dummy --add --name=tmp-mount --claim-name=data --type pvc --claim-size=1G --mount-path /mnt

这将在虚拟应用上导致一次新的部署,监控应用进程方便我们知道什么时候可以完成:

oc rollout status dc/dummy

为了确认永久卷挂载成功,运行:

oc get pvc

获取现在运行的虚拟应用的pod名称:

POD=`pod run=dummy`; echo $POD

现在,我们可以使用挂载持久卷的/mnt目录作为目标目录,将任何文件复制到持久卷中。在本例中,由于我们执行的是一次性复制,所以可以使用tar策略而不是rsync策略。

oc rsync ./ $POD:/mnt --strategy=tar

完成后,可以列出容器内目标目录的内容来确认是否被传输:

oc rsh $POD ls -las /mnt

如果您已经使用完成了这个持久卷,并且可能需要使用另一个持久卷和不同的数据重复该过程,那么您可以卸载该持久卷,但保留虚拟应用程序。

oc set volume dc/dummy --remove --name=tmp-mount

使用下面命令监控重新构建的进程是否完成:

oc rollout status dc/dummy

再次使用POD=`pod run=dummy`; echo $POD获取当前pod名称。

如果存在现有的永久卷,使用下面命令将永久卷挂载到虚拟程序中:

oc set volume dc/dummy --add --name=tmp-mount --claim-name=data --mount-path /mnt

当你需要删除虚拟程序的时候,使用oc delete命令加run=dummy标签选择器确保删除这个虚拟应用相关的资源:

oc delete all --selector run=dummy

检查dummy的所有资源是否被删除:

oc get all --selector run=dummy -o name

尽管我们已经删除了虚拟应用程序,但持久卷声明仍然存在,稍后可以针对数据所属的实际应用程序挂载它。

oc get pvc

6. 命令总结

oc rsync <pod-name>:/remote/dir/filename ./local/dir: Copy a single file from the pod to the local directory.

oc rsync <pod-name>:/remote/dir ./local/dir: Copy the directory from the pod to the local directory.

oc rsync <pod-name>:/remote/dir/. ./local/dir: Copy the contents of the directory from the pod to the local directory.

oc rsync <pod-name>:/remote/dir ./local/dir --delete: Copy the contents of the directory from the pod to the local directory. The --delete option ensures that the resulting directories will match exactly, with directories/files in the local directory which are not found in the pod being deleted.

oc rsync ./local/dir <pod-name>:/remote/dir --no-perms: Copy the directory to the remote directory in the pod. The --no-perms option ensures that no attempt is made to transfer permissions, which can fail if remote directories are not owned by user container runs as.

oc rsync ./local/dir <pod-name>:/remote/dir --exclude=* --include=<filename> --no-perms: Copy the single file to the remote directory in the pod. The --no-perms option ensures that no attempt is made to transfer permissions, which can fail if remote directories are not owned by user container runs as.

oc rsync ./local/dir <pod-name>:/remote/dir --no-perms --watch: Copy the directory to the remote directory in the pod and then keep the remote directory syncrhonized with the local directory, with any changed files automatically being copied to the pod. The --no-perms option ensures that no attempt is made to transfer permissions, which can fail if remote directories are not owned by user container runs as. The --watch option is what enables the synchronization mechanism.

oc run dummy --image centos/httpd-24-centos7: Run a dummy application pod which can be used to mount persistent volumes to facilitate copying files to a persistent volume.

oc set volume dc/dummy --add --name=tmp-mount --claim-name=<claim-name> --type pvc --claim-size=1G --mount-path /mnt: Claim a persistent volume and mount it against a dummy application pod at the directory /mnt so files can be copied into the persistent volume using oc rsync.

oc set volume dc/dummy --add --name=tmp-mount --claim-name=<claim-name> --mount-path /mnt: Mount an existing persistent volume against a dummy application pod at the directory /mnt so files can be copied into the persistent volume using oc rsync.

oc rsync ./local/dir <pod-name>:/remote/dir --strategy=tar: Copy the directory to the remote directory in the pod. The --strategy=tar option indicates to use tar to copy the files rather than rsync.

原文:https://learn.openshift.com/introduction/transferring-files/

上一篇:Redis Sentinel机制与用法(一)


下一篇:Spring Session工作原理