镜像的查找、使用和定制

1. 查找镜像

不要使用docker search查找镜像,search只能搜索到镜像名称,并不能找到所有的标签名,也无法得知镜像使用方法。应该前往官方镜像网站查找需要的镜像。

官方镜像网址:https://hub.docker.com/explore/

查找镜像可以使用搜索功能,只需要输入镜像名称即可,不要把标签也添加上,否则搜索不到结果。

镜像中有不同的标签,表明的软件的版本以及镜像的基础环境,例如redis镜像,有如下的版本: redis镜像列表

图中标识redis共有11个版本镜像,每个版本的镜像存在多个标签。包括3.0和3.2版本,32位和64位的使用环境,alpine和window等基础镜像环境等。

根据自身的需要选择合适自己的镜像

2. 帮助文档

使用镜像不是简单的run运行就可以,很多时候还需要添加一些必要的参数才能跑起来,如何找到这些参数应该如何配置呢?查看帮助文档,在镜像页面的下方通常都是帮助文档,镜像相关信息。下面是redis镜像的帮助文档

redis镜像使用帮助

3. 镜像源码

如果看帮助文档找不到自己想要看的帮助,或者想要知道镜像的整个构建使用过程,可以查看镜像的源码。

在镜像列表中,选择自己想要使用的镜像,点击旁边的Dockerfie连接,将会跳转到该镜像的git项目中。

在项目页面,我们可以看到redis的Dokcerfile文件,了解镜像做了什么操作,还可以找到镜像的启动脚本entrypoint.sh等

redis项目

下载源码,我们也可以自己编译redis镜像。

4. 定制自己的镜像

如果镜像官方的镜像不能满足你的特别要求,这时候你需要自己定制镜像,下面我拿我自己定制的redis镜像做个例子。

我的需求是redis可以配置maxclient,maxmemory等参数 首先参考官网的镜像帮助文档,redis的配置文件放在容器/usr/local/etc/redis/redis.conf文件夹下。

编写redis.conf文件

#daemonize yes

pidfile  /var/run/redis.pid 

port 6379

tcp-backlog 511

timeout  300

tcp-keepalive 300

loglevel notice

logfile ""

databases 16

save 900 1
save 300 10
save 60 10000

stop-writes-on-bgsave-error yes

rdbcompression yes

rdbchecksum yes

dbfilename dump.rdb

dir /data/

slave-serve-stale-data yes

slave-read-only yes

repl-disable-tcp-nodelay no

slave-priority 100

# maxmemory <bytes>

# maxmemory-policy volatile-lru

# maxmemory-samples 3

appendonly no

appendfilename "appendonly.aof"

appendfsync everysec

no-appendfsync-on-rewrite no

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

lua-time-limit 5000

slowlog-log-slower-than 10000

slowlog-max-len 128

notify-keyspace-events ""


hash-max-ziplist-entries 512
hash-max-ziplist-value 64


list-max-ziplist-entries 512
list-max-ziplist-value 64

set-max-intset-entries 512

zset-max-ziplist-entries 128
zset-max-ziplist-value 64

activerehashing yes

client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60

hz 10
aof-rewrite-incremental-fsync yes

注意,redis.conf文件中有两个需要注意的地方:

  • daemonize参数设置为no 或者注释掉,如果设置为yes,则容器启动就会结束,因为没有前台进程。
  • bind 不要设置为127.0.0.1 注释掉,测试发现设置127.0.0.1会出现服务访问被拒绝的情况。

编写自己的启动脚本entrypoint.sh

在原redis镜像的entrypoint.sh做修改。

#!/bin/sh
set -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.7
MAINTAINER shijieming@lutongnet.com
COPY redis.conf /usr/local/etc/redis/redis.conf
RUN chown -R redis /usr/local/etc/redis
COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
CMD [ "redis-server" , "/usr/local/etc/redis/redis.conf" ]
  1. 使用了redis:3.0.7作为基础镜像
  2. 添加本地的redis.conf文件到容器相应目录
  3. 修改配置文件所在文件夹权限
  4. 添加本地的启动脚本,这里会覆盖原有的docker-entrypoint.sh
  5. 启动命令 使用配置文件启动

执行下面的命令生成镜像

$ docker build .
Sending build context to Docker daemon 10.75 kB
Step 1/6 : FROM redis:3.0.7
 ---> c44fa74ead88
Step 2/6 : MAINTAINER shijieming@lutongnet.com
 ---> Using cache
 ---> bfdd1371df83
Step 3/6 : COPY redis.conf /usr/local/etc/redis/redis.conf
 ---> Using cache
 ---> 0933f3eeba04
Step 4/6 : RUN chown -R redis /usr/local/etc/redis
 ---> Using cache
 ---> e2cd58419d3b
Step 5/6 : COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
 ---> Using cache
 ---> 88413869eef5
Step 6/6 : CMD redis-server /usr/local/etc/redis/redis.conf
 ---> Using cache
 ---> 082aa959aa4f
Successfully built 082aa959aa4f
$ docker tag 082aa959aa4f myredis:3.0.7

通过命令生成了自己定义的myredis:3.0.7镜像。

当然除了基于官方镜像做修改,还可以使用直接修改官方的Dockerfile文件等,也可以自行编写Dockerfile文件。

转载于:https://my.oschina.net/u/3438714/blog/1069005

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值