This article covers how to upgrade faster in containerized situations. It involves two aspects: the design of docker image. Upgrade scheme.

Docker image design

Make full use of docker image layering mechanism to reduce the volume of upgrade and reduce traffic consumption.

Basic image design

The base image can be directly used by the official, or you can make your own, make your own flexibility, can add customized content, such as node_modules directory nodejs dependent, C++ additional libraries (such as cuda). Each build, based on the base image, not the previous version. Because Docker is made on the basis of one layer, even though there is little difference between versions, the volume only increases.

The following is an example of a layered test. Make two mirrors, do the foundation first, on this basis to make version 0.1. Download the base image first and then version 0.1. Observe the download process log.

# docker pull latelee/nodejs_test:base base: Pulling from latelee/nodejs_test 3cfb62949d9d: Pull complete 34aecfb75a58: Pull complete 3d83db6658b4: Pull complete c94ba0b8da75: Pull complete d7bff1b55288: Pull complete Digest: sha256:e17eefc913b842d944702fa008c3178e5f5cf6753b102954ee2426ff548aa6c4 Status: Downloaded newer Image for latelee/nodejs_test: Base # docker pull latelee/nodejs_test:0.1 0.1: Pulling from latelee/nodejs_test 3cfb62949d9d: Already exists 34aecfb75a58: Already exists 3d83db6658b4: Already exists c94ba0b8da75: Already exists d7bff1b55288: Already exists 7c1d066698dd: Pull complete Digest: sha256:f17bec3186ca681be8815adda298b217b6d0c1bcb248a0f57da4b03a8197db43 Status: Downloaded newer Image for latelee/nodejs_test:0.1Copy the code

The second download, many layers already exist, do not need to download again, so the speed is fast. On disk, mirroring is also reused, so it saves space.

Other tests: using a large file, make version 0.1 on the base image, then make version 0.2 on the base image (with minor changes), and then make version 0.11 on the base image using a version 0.2 file.

Host mapping scheme

Typically, the container serves as the runtime environment, and the host holds data files. Web services, for example, are typical. Here the meaning is reversed. That is, put the file into the image, and then map the running environment of the host machine to the container, and execute it. Example:

docker run -it --rm -v /home/latelee/nodejs/nodejs_test/node_modules:/home/node/node_modules \ -v /usr/local/bin/:/home/local/bin \ -v /lib/:/home/lib \ -v /usr/lib/:/home/usr/lib \ nodejsdata sh export PATH=$PATH:/home/local/bin export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/lib export LD_LIBRARY_PATH=$LD_LIBRARY_PATH: /home/usr/lib/# node -v v10.20.1 / # CD /home/node// # node koa_test.js RUN a LD_LIBRARY_PATH=$LD_LIBRARY_PATH: /home/usr/lib/# node -v v10.20.1 / # CD /home/node// # node koa_test.js koa server at localhost: 4000 docker run -it --rm -v /home/latelee/nodejs/nodejs_test/node_modules:/home/node/node_modules \ -v /usr:/usr \ -v /bin:/bin \ -v /lib/:/lib \ nodejs_test shCopy the code

Try to use Scratch, i.e. only copy the relevant JS files to the image, not based on busybox and other basic images, if the command is not mounted in the directory:

docker: Error response from daemon: OCI runtime create failed: container_linux.go:345: starting container process caused "exec: \"sh\": executable file not found in $PATH": unknown.
Copy the code

After mounting (for example, /bin/directory) :

standard_init_linux.go:211: exec user process caused "no such file or directory"
failed to resize tty, using default size
Copy the code

It seems impossible to do so. This problem has not been studied deeply.

In addition, I tried to use the directory of container B in container A, but failed. Maybe there is no such application. Mounting it first and then copying it to the host in a container seems feasible, but it takes up too much storage, so discard it.

Another example:

docker run -itd --rm --name nodejsapp -p 3000:3000 -v /home/node/node_modules/:/home/node/node_modules \ -v /usr/:/usr \ - v/lib / : / lib \ registry.cn-hangzhou.aliyuncs.com/latelee/nodejsdata offers:  docker run -itd --rm --name nodejsapp -p 3000:3000 \ -v /mnt/data:/mnt/data \ -v /home/node/node_modules/:/home/node/node_modules \ -v /usr/:/usr \ -v /lib/:/lib \ nodejsdataCopy the code

The verification is successful on arm. Prerequisite: The ARM board is installed with nodeJS environment and dependent node_modules. Mirror the application code, download it and run it. To reduce operations, mount the same directory directly.

Upgrade package

Think in terms of hot start and cold start. At present, only ideas, not hands-on coding.

Hot update

The cloud host is the server, and the terminal/board is the client. They maintain a long connection and can be realized by Websocket. When an upgrade is needed (such as CICD trigger, manual trigger, or POST request), the server receives the upgrade event and sends the command to the client. The client executes the Docker pull command to judge the return value and determine whether the new image is normal (such as MD5 or CRC, docker’s own ID can also be used). Everything starts normally. After monitoring for some time (such as 30 seconds to 1 minute), the container does not exit until it is normal. When the client proactively upgrades, determine whether the network is connected. You can upgrade the client at night or during off-peak hours.

Cold update

Make the script along with the system startup, execute docker pull first in the script, if it is the latest version, it will output the Docker ID value with the words “Image is up to date for”, you can judge it. Otherwise, the image will be pulled. In this case, you need to stop the container and delete the container before starting it (whether to restart the container directly can be realized is not studied at this moment). In this mode, you need to restart the device. If the startup takes a long time, the service stops for a long time. In the time interval allows the case, can use this method, convenient.

summary

The image shown in this article has been modified and is not a real image.

The attached

A builtroot updates node records.

The required version for the front-end is 10.15, builtroot defaults to 8.15. 1, Download alpine version image, select node, its library is musllibc, target board library is glibc, run the message Not found, because the linker is different. Failure. Download the armV7 version image and take it from it. Volume 30MB, large.

Buitroot = 8.15; buitroot = 10.15; buitroot = 8.15; Find the official code path https://git.busybox.net/buildroot/tree/package/nodejs/nodejs.mk?h=2019.05, choose a different version number, found the 201905 version, to take from the configuration file, Replace/add the original directory. Its reliance on https://git.busybox.net/buildroot/tree/package/nghttp2?h=2019.05. Make download slow, use cloud host download, and then use SCP copy. The compilation still fails, and according to the prompt log, it is openSSL again. Thought of upgrading buitroot to 201905, but also associated with the kernel and so on, the cost is high, abandoned. Copy /usr/bin/node to target board. Copy libhttp_parser, libuv, libcares. Results: The application depends on sqlite as/sqlite3 / lib/binding/node – v64 – Linux – arm, Sqlite3 /lib/binding/node-v57-linux-arm/node_sqlite3.node 4, using official pre-compiled versions, at https://nodejs.org/dist/v10.15.0/.