docker 可以说给我们的部署带来极大的方便和可逢凶化吉性!(懂的同学自然懂)
在初步了解之后, 我们就能简单使用 docker 了.
刚开始玩 docker 时, 可以基于系统级别的镜像做定制, 比如基于 CentOS 镜像使用 docker;
- docker pull CentOS:7 # 把镜像拉下来
- docker run -it CentOS:7 # 创建一个容器即可运行
你可以在拉下来的容器里安装任何需要的应用 (必要的); 然后, 一切都看起来很美好!
但是, 这时, 我们最担心一个问题, 那就是 docker 挂了怎么办? 机器重启后怎么办?
是的, 这个担心是有道理的, 如果你没有去查细细看过官方文档, 那么多半你是吃过这亏, 才会清楚其中的坑!
所以, 我们来提几个问题? 简单而不简约!
1. 如何备份当前容器的修改? 备份是可靠性的一个保证!
1. 使用 commit 命令保存到本地
docker commit -m "msg" abcommitid myimage:1.0
其好处是操作方便, 本机永久保存, 方便下次快速操作. 坏处, 也不算, 就是你如果想放到远程, 你必须注册一个 docker hub 账号, 然后保存过去. 而且这样的镜像, 一般只适合自己使用, 不适合团队传播!(不过也不是绝对的)
2. 使用 docker save 保存压缩包到本地
docker save -o myimage_save.tar abcontainerid
这样备份好之后, 就可以将改该容器到处分发到其他机器或者做备份了. 这样做都好处是, 传播方便, 不会导致隐私泄露. 坏处是都是本地包, 没有存储在云端, 必须到处携带该包.
导入时使用 docker load 即可!
docker load -i myimage_save.tar
然后就可以看到镜像了, 使用 docker run 运行. 操作步骤稍微繁琐了点. 注意: 只有 docker run 才能自定义各种参数哦.(docker run 聚合了 create 和 start 的功能)
在部署应用时可能存在需要将新应用部署好后, 再删除原容器的操作, 所以容器重命名就很有必要的, 使用 docker rename
docker rename 原容器名 新容器名
3. 使用 docker export 保存到本地, 操作如同 docker save, 但是功能受限, 个人不是很喜欢使用
docker export -o mycontainer_save.tar tmp_container
2. 如何设置应用开机启动? 只要启动容器就够了!
应用场景可以说是刚需: 我把第一个镜像安装好后, 希望下次创建容器之后就能自动运行, 而不是还要操作 N 多繁杂步骤, 从而降低移植性带来的方便性!
1. 能想得最简单的是, 使用系统的开机启动功能
比如在 /etc/rc.d/rc.local 中添加相应的启动, 但是这里有个前提, 那就是你必须先把容器启起来; (启不启得来另说)
2. 使用 docker 的开机自动运行功能, 使用简单;
这里说的简单是指使用, 而在操作的时候则看个人了. 在 docker 创建时, 使用启动脚本, 自动运行. 主要的命令有: CMD, RUN, ADD . 创建一个 start.sh, 可以定复杂的启动逻辑; 但是这在后期中, 就很难更改其逻辑了哦!
CMD ["sh", "-c", "service httpd start;bash"] # 开机启动 apache 服务
3. 如何自定义端口映射? 容器需要与外部通信!
Docker 自带了端口映射功能, 使用 docker run -p 进行操作!
docker run -d -p 81:80 --name container_name myimage:1.0
多个端口映射使用多个 - p 即可;
4. 如何自定义 hostname? 订制你的机器名而不是随机数!
自定义 host 也很有用, 比如我想看我当前气息环境, hostname 就很有用, 还有 hostname 的固定可以不致让自己迷失; 只需要使用 - h 参数就可以了.
docker run -d -h myapi1 myimage:1.0
5. 如何插入 host 的解析? 容器内订制自己的 hosts !
这种应用场景是, 比如你其他应用的服务, 为了防止 ip 经常变更导致的麻烦性, 这种服务一般是以内网域名形式出现, 所以需要加入域名解析.
方法一是, 你给每个容器定义一个通用的域名解析器 dns;
方法二是, 为各自的 hosts 里加入解析. 而这在 docker 中, 则操作是不会被保存的, 每个新容器老是新 hosts. 可以通过 --add-host 添加自定义 hosts 解析:
docker run --add-host a.com:1.2.3.4 myimage:1.0
这种方式仅用于学习, 其中更有用的是加入一个 dns; 其操作步骤就是安装个 bind 软件, 然后配制 named.conf 即可. 使用时, VIM /etc/resolv.conf
nameserver 100.1.1.1
6. 如何自定义自己都的变量以满足容器内动态修改的需求? 特殊场景定制化!
其实如上的配置基本能满足大部分情况下的生产需求了. 但是难免还是个性的, 比如我想定义 nginx 访问某个的另外端口, 这时使用 dns 就不好搞了. 在不改变外部环境的情况下, 我们只能自定义修改了. 最直接的方式是在 nginx 中直接改掉即可. 但是这样做还有个, 如果我想让同一个容器灵活地指向任意端口怎么办? 那就只能自定义变量操作了, 在创建容器的时候指定该端口即可.
这样的自定义变量可以用于设置 nginx 的自定义端口, java 堆大小, 日志目录设置等等.
具体做法步骤如下:
- # 1. docker run -it myimage:1.0, 修改 nginx 配置文件, 使其可以方便被替换, 如下
- # VIM /usr/local/nginx/conf/conf.d/www.conf
- server {
- listen 80;
- server_name localhost;
- access_log /var/log/nginx/host.access.log main;
- location / {
- root /www/webapp/html/app1;
- try_files $uri $uri/ /index.HTML;
- index index.HTML index.htm;
- }
- location /API {
- # 设置点位符使外部可替换
- set $API_HOST 192.168.1.1;
- set $API_PORT 8083;
- proxy_pass http://$API_HOST:$API_PORT;
- index index.HTML index.htm;
- }
- }
- # 2. 自己尝试启动无误后, 将新变更提交到原镜像, docker commit
- docker commit -m 'conf update' abcommitid myimage:1.0
- # 3. VIM Dockerfile, 设置启动脚本
- FROM myimage:1.0
- MAINTAINER xxx <abc@abc.com>
- ENV NGINX_CONFD_PATH /usr/local/nginx/conf/conf.d
- ENV PATH /usr/local/nginx/sbin:$PATH
- ADD ./start.sh /usr/local/bin/start.sh
- RUN chmod +x /usr/local/bin/start.sh
- EXPOSE 80
- # 设置启动脚本, 脚本来源本机, 可随时修改
- CMD [ "/usr/local/bin/start.sh" ]
- # 4. 缩写启动脚本, 使在启动时执行动态配置变更 awk
- # VIM start.sh
- #!/bin/bash
- # override port variable if set
- if [ ! -z "$API_PORT" ]; then
- echo "------- xcz api port replacing to $API_PORT -----------";
- awk -v PORT="set \$API_PORT $API_PORT;" '{ sub(/set.*\$API_PORT.*/, PORT); print; }' ${NGINX_CONFD_PATH}/default.conf \
- > ${NGINX_CONFD_PATH}/default.conf.new && mv ${NGINX_CONFD_PATH}/default.conf.new ${NGINX_CONFD_PATH}/default.conf
- fi
- if [ ! -z "$API_HOST" ]; then
- echo "------- xcz api host replacing to $API_HOST -----------";
- awk -v HOST="set \$API_HOST $API_HOST;" '{ sub(/set.*\$API_HOST.*/, HOST); print; }' ${NGINX_CONFD_PATH}/default.conf \
- > ${NGINX_CONFD_PATH}/default.conf.new && mv ${NGINX_CONFD_PATH}/default.conf.new ${NGINX_CONFD_PATH}/default.conf
- fi
- # start nginx
- /bin/sh -c 'nginx -g"daemon off;" '
- # 5. 都操作好后, 重新构建一个新的镜像, 使用就可以了
- docker build -t myimage:1.1 .
- # 6. 使用时, 用 --env 来指定自定义变量
- docker run --env API_HOST=192.168.1.112 --env API_PORT=8090 -it myimage:1.1
- # 此时, 进入查看时, nginx 已经运行在不同的 API 端口下了
注意: 本处使用的是比较原始的 docker 版本, 如果使用到 docker-compose 等高级工具, 可能就不需要这么麻烦了!
7. 如何将宿主机目录与容器内目录进行交换? 可视化你的容器内容!
这样的场景是比较多的:
比如为了统一管理安装包, 不让所有安装包散乱在各个容器的各个目录;
比如为了让容器的数据存储使用一块新买的磁盘;
比如我想复制同一份代码到新容器使用, 从而方便后续独立修改;
比如你无法进入你的容器, 却想拿到其中的数据等等;
所以, 我们需要使用到目录映射功能, 这是 docker 自带的功能, 方便实用: -v 参数设置即可:
docker run -d -v /opt/docker/webapps:/www/webapp myimage:1.0
经过上面这些问答, 相信你已经能简单应付常用运维场景了, 尽情享受 docker 带来的可移植性方便以及其隔离性吧.
来源: https://www.cnblogs.com/yougewe/p/10425387.html