1. 查找镜像不要使用docker search查找镜像,search只能搜索到镜像名称,并不能找到所有的标签名,也无法得知镜像使用方法。应该前往官方镜像网站查找需要的镜像。官方镜像网址:https:
1. 查找镜像
不要使用docker search查找镜像,search只能搜索到镜像名称,并不能找到所有的标签名,也无法得知镜像使用方法。应该前往官方镜像网站查找需要的镜像。
官方镜像网址:https://hub.docker.com/explore/
查找镜像可以使用搜索功能,只需要输入镜像名称即可,不要把标签也添加上,否则搜索不到结果。
镜像中有不同的标签,表明的软件的版本以及镜像的基础环境,例如redis镜像,有如下的版本:
图中标识redis共有11个版本镜像,每个版本的镜像存在多个标签。包括3.0和3.2版本,32位和64位的使用环境,alpine和window等基础镜像环境等。
根据自身的需要选择合适自己的镜像
2. 帮助文档
使用镜像不是简单的run运行就可以,很多时候还需要添加一些必要的参数才能跑起来,如何找到这些参数应该如何配置呢?查看帮助文档,在镜像页面的下方通常都是帮助文档,镜像相关信息。下面是redis镜像的帮助文档
3. 镜像源码
如果看帮助文档找不到自己想要看的帮助,或者想要知道镜像的整个构建使用过程,可以查看镜像的源码。
在镜像列表中,选择自己想要使用的镜像,点击旁边的Dockerfie连接,将会跳转到该镜像的git项目中。
在项目页面,我们可以看到redis的Dokcerfile文件,了解镜像做了什么操作,还可以找到镜像的启动脚本entrypoint.sh等
下载源码,我们也可以自己编译redis镜像。
4. 定制自己的镜像
如果镜像官方的镜像不能满足你的特别要求,这时候你需要自己定制镜像,下面我拿我自己定制的redis镜像做个例子。
我的需求是redis可以配置maxclient,maxmemory等参数首先参考官网的镜像帮助文档,redis的配置文件放在容器/usr/local/etc/redis/redis.conf文件夹下。
编写redis.conf文件
#daemonize yespidfile /var/run/redis.pid port 6379tcp-backlog 511timeout 300tcp-keepalive 300loglevel noticelogfile ""databases 16save 900 1save 300 10save 60 10000stop-writes-on-bgsave-error yesrdbcompression yesrdbchecksum yesdbfilename dump.rdbdir /data/slave-serve-stale-data yesslave-read-only yesrepl-disable-tcp-nodelay noslave-priority 100# maxmemory <bytes># maxmemory-policy volatile-lru# maxmemory-samples 3appendonly noappendfilename "appendonly.aof"appendfsync everysecno-appendfsync-on-rewrite noauto-aof-rewrite-percentage 100auto-aof-rewrite-min-size 64mblua-time-limit 5000slowlog-log-slower-than 10000slowlog-max-len 128notify-keyspace-events ""hash-max-ziplist-entries 512hash-max-ziplist-value 64list-max-ziplist-entries 512list-max-ziplist-value 64set-max-intset-entries 512zset-max-ziplist-entries 128zset-max-ziplist-value 64activerehashing yesclient-output-buffer-limit normal 0 0 0client-output-buffer-limit slave 256mb 64mb 60client-output-buffer-limit pubsub 32mb 8mb 60hz 10aof-rewrite-incremental-fsync yes
注意,redis.conf文件中有两个需要注意的地方:
- daemonize参数设置为no 或者注释掉,如果设置为yes,则容器启动就会结束,因为没有前台进程。
- bind 不要设置为127.0.0.1 注释掉,测试发现设置127.0.0.1会出现服务访问被拒绝的情况。
编写自己的启动脚本entrypoint.sh
在原redis镜像的entrypoint.sh做修改。
#!/bin/shset -e# first arg is `-f` or `--some-option`# or first arg is `something.conf`if [ "${1#-}" != "$1" ] || [ "${1%.conf}" != "$1" ]; then set -- redis-server "$@"fi# allow the container to be started with `--user`if [ "$1" = 'redis-server' -a "$(id -u)" = '0' ]; then chown -R redis . exec gosu redis "$0" "$@"fi#环境变量替换部分参数set_config(){ if [ $TIMEOUT ]; then sed -i 's/^timeout .*/timeout '"$TIMEOUT"'/g' /usr/local/etc/redis/redis.conf fi if [ $DATABASES ]; then sed -i 's/^databases .*/databases '"$DATABASES"'/g' /usr/local/etc/redis/redis.conf fi if [ $MAX_CLIENTS ]; then sed -i 's/^# maxclients.*/maxclients'"$MAX_CLIENTS"'/g' /usr/local/etc/redis/redis.conf fi #内存限制设置 local limit_in_bytes=$(cat /sys/fs/cgroup/memory/memory.limit_in_bytes) if [ "$limit_in_bytes" -ne "9223372036854771712" ]; then local limit_in_megabytes=$(expr $limit_in_bytes // 1048576) sed -i 's/^# maxmemory .*/maxmemory '"$limit_in_megabytes"'/g' /usr/local/etc/redis/redis.conf #开启内存限制最好指定清理策略 if [ $MAX_MEMORY_POLICY ]; then sed -i 's/^# maxmemory-policy.*/maxmemory-policy '"$MAX_MEMORY_POLICY"'/g' /usr/local/etc/redis/redis.conf else sed -i 's/^# maxmemory-policy.*/maxmemory-policy volatile-lru/g' /usr/local/etc/redis/redis.conf fi fi if [ $MAX_MEMORY ]; then sed -i 's/^# maxmemory .*/maxmemory '"$MAX_MEMORY"'/g' /usr/local/etc/redis/redis.conf #开启内存限制最好指定清理策略 if [ $MAX_MEMORY_POLICY ]; then sed -i 's/^# maxmemory-policy.*/maxmemory-policy '"$MAX_MEMORY_POLICY"'/g' /usr/local/etc/redis/redis.conf else sed -i 's/^# maxmemory-policy.*/maxmemory-policy volatile-lru/g' /usr/local/etc/redis/redis.conf fi fi}set_config && exec "$@"
脚本中set_config方法是我进行参数替换的部分,通过传入环境变量替换配置文件中的参数。注意,这里会存在两个问题。
- 容器重复启动,配置文件是否变化?entrypoint.sh是每次启动容器都会执行的脚本,第一次启动容器,和第n次启动容器,执行脚本的结果是否会导致配置文件不一样?
- 权限问题,redis创建了一个redis用户用于执行redis进程,而dockerfile创建的文件夹是root权限的,那么sed命令无法在该文件夹下使用,因为redis用户无法在该文件夹下创建临时文件。(这个问题可以在Dockerfile中解决)
编写Dockfile文件
FROM redis:3.0.7MAINTAINER [email protected] redis.conf /usr/local/etc/redis/redis.confRUN chown -R redis /usr/local/etc/redisCOPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.shCMD [ "redis-server" , "/usr/local/etc/redis/redis.conf" ]
- 使用了redis:3.0.7作为基础镜像
- 添加本地的redis.conf文件到容器相应目录
- 修改配置文件所在文件夹权限
- 添加本地的启动脚本,这里会覆盖原有的docker-entrypoint.sh
- 启动命令 使用配置文件启动
执行下面的命令生成镜像
$ docker build .Sending build context to Docker daemon 10.75 kBStep 1/6 : FROM redis:3.0.7 ---> c44fa74ead88Step 2/6 : MAINTAINER [email protected] ---> Using cache ---> bfdd1371df83Step 3/6 : COPY redis.conf /usr/local/etc/redis/redis.conf ---> Using cache ---> 0933f3eeba04Step 4/6 : RUN chown -R redis /usr/local/etc/redis ---> Using cache ---> e2cd58419d3bStep 5/6 : COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh ---> Using cache ---> 88413869eef5Step 6/6 : CMD redis-server /usr/local/etc/redis/redis.conf ---> Using cache ---> 082aa959aa4fSuccessfully built 082aa959aa4f$ docker tag 082aa959aa4f myredis:3.0.7
通过命令生成了自己定义的myredis:3.0.7镜像。
当然除了基于官方镜像做修改,还可以使用直接修改官方的Dockerfile文件等,也可以自行编写Dockerfile文件。