1、手动构建一个简单的docker镜像并运行
- 运行一个 nginx 镜像
docker pull nginx:1.14.1 #或者 docker run -d --name a0 -p 80:80 nginx:1.14.1
- 逐行查看 nginx 镜像的构建过程
- https://hub.docker.com
- LABEL maintainer=NGINX Docker Maintainers docker-maint@nginx.com
- 设置 key = value 形式的说明数据
- ENV NGINX_VERSION=1.14.1-1~stretch
- 设置环境变量
- /bin/sh -c ln -sf /dev/stdout /var/log/nginx/access.log
- 将 nginx 日志内容定向到 /dev/stdout 即不存储在容器内部,防止容器体积越来越大
- 可以通过 docker logs containerid 查看容器日志
- STOPSIGNAL [SIGTERM]
- 设置容器的停止信号
- EXPOSE 80/tcp
- 暴露端口
- CMD [“nginx” “-g” “daemon off;”]
- 前台启动
- 多个 CMD 指令只会使用最后一个
- CMD 的两种方式
- CMD [“exec”,”p1”,”p2”](数组方式)
- CMD [“p1”,”p2”](与 ENCRYPTION 结合使用作为补充参数)
- CMD exec p1 p2(shell方式)
- 手动构建一个简单的docker镜像并运行(01.nginx)
FROM nginx:1.14.1 ENTRYPOINT ["nginx"] CMD ["-g","daemon off;"]
docker build . -t 1.14.1-edit
#前台运行 docker run -it --name a1 -p 81:80 nginx:1.14.1-edit #后台运行 docker run -d --name a2 -p 82:80 nginx:1.14.1-edit #覆盖 CMD docker run -it --name a3 -p 83:80 nginx:1.14.1-edit -h
2、docker关于多应用关联启动
- 制作 linux+nginx+mysql+php+redis 的开发环境
- 构建
- 先根据编辑好的 dockerfile 构建定制的 php、nginx 镜像
- 过程中展示构建的使用
- 启动方式1(磁盘挂载共享目录)(02.lnmp)
#运行一个临时的php容器将代码复制出来 docker run -d --name temp php:7.3.33-fpm-edit #将容器中的 /var/www/html 目录 复制到宿主机的 /data/ 目录下,并重命名为 www mkdir /data/ docker cp temp:/var/www/html /data/www #如果为以下写法,/data/ 下的 www 目录存在,则表示将 /var/www/html 复制到 /data/www 下 mkdir -p /data/www docker cp temp:/var/www/html /data/www #之后通过 docker-compose 启动 docker-compose up -d
- 不方便之处在于运行前需要提前复制容器中的代码到宿主机,否则由于宿主机目录为空,会同步覆盖容器中的代码也为空
- 启动方式2(volume:数据卷)(03.lnmp)
#无需复制目录 直接通过 docker-compose 启动 #主要改动见 docker-compose.yml docker-compose up -d #注意如果不需要,要及时清理容器卷 使用以下指令查看数据卷 docker-compose volume ls #因为通过上述方式启动容器,他们共享一个 volume #注意看此命令的提示信息 docker-compose down --volumes #也可以通过以下指令删除不使用的容器卷 docker-compose volume rm volume_name
- 构建
- 制作 Linux+httpd+mysql+redis 的开发环境
- 略
- docker的数据共享方案
- 磁盘挂载
- 共享volumes
- 多应用需要共享数据时使用volumes的好处
- 使用volumes如果不需要数据应该及时删除或者docker-compose down的时候删除
- 数据卷容器(略)
- 将容器作为数据卷
3、一个容器中启动多个应用的解决方案(04.lnmp)
- 以在 php 容器中配置 cron 服务为例
- 具体见文件
- 最后可通过 docker logs containerid 查看任务计划执行效果
4、通过 docker 配置自己专属的开发机
4.1 启动容器
# -d: 后台运行容器,并返回容器 ID # -p: 指定端口映射,格式为:主机(宿主)端口:容器端口 # --name="nginx-lb": 为容器指定一个名称; # --privileged=true: 使用该参数,container 内的 root 拥有真正的 root 权限 # /usr/sbin/init: 使用init启动,这样可以避免 docker-centos 中的 systemctl 失效 # --restart=always docker重启后自动重启 # -v /a:/b -v表示与宿主机的共享目录,这里表示将宿主机的 /a 目录映射到docker容器的 /b 目录 # 一组端口映射的写法 docker run -d -p 5000:22 --privileged=true centos:7.9.2009 /usr/sbin/init # 多组端口映射的写法 docker run -d -p 5022:22 -p 5080:80 --privileged=true centos:7.9.2009 /usr/sbin/init
4.2 配置宿主机防火墙(可选)
- 注意配置防火墙会影响docker的运行,因此配置结束需要重启docker
#临时关闭防火墙(不推荐) systemctl stop firewalld #或者将映射的所有端口从防火墙放行 firewall-cmd --zone=public --add-port=5022/tcp --permanent firewall-cmd --zone=public --add-port=5080/tcp --permanent firewall-cmd --reload
4.3 进入容器配置
- 进入容器
#CONTAINER-ID 表示容器id docker exec -it CONTAINER-ID /bin/bash
- 修改 root 用户密码(必要)
passwd root
- 升级系统(可选)
yum update -y
- 安装常用工具(推荐)
yum install -y vim zip unzip wget git
- 安装 openssl 、openssh 服务(必要)
yum install -y openssl openssh-server openssh-clients #编辑文件 /etc/ssh/sshd_config 并取消注释 PermitRootLogin yes 所在行 vim /etc/ssh/sshd_config #重启ssh服务并保证开机启动ssh服务 systemctl restart sshd systemctl enable sshd
- 安装 service 命令(可选)
yum install -y initscripts
- 配置防火墙(可选)
yum install -y firewalld systemctl stop firewalld systemctl disable firewalld
- 安装 nmcli 网络工具(可选)
yum install -y NetworkManager systemctl start NetworkManager systemctl enable NetworkManager
- 安装业务软件。。。。。
- 退出容器
exit
4.4 使用测试
- 使用 ssh 远程登录进行测试,注意配置的 ssh 端口
4.5 打包容器
- 使用 docker commit
#将容器打包为镜像 docker commit -m="2022-08-03-配置了SSH登录" -a="witersen" containerid centos:7.9.2009-edit #查看容器 docker images #查看镜像详细信息 docker inspect imageid #以后即可使用此镜像快速运行为容器供个人使用,还可以推送到个人镜像仓库或者阿里云镜像仓库等方便从不同的机器拉取
- 使用 docker save
#将镜像打包为文件 #此方式适合不通过镜像仓库,具备快速迁移条件的机器间快速迁移 docker save centos:7.9.2009-edit > centos:7.9.2009-edit.tar #查看文件体积 du -ah #在新机器导入可用以下命令 docker load < centos:7.9.2009-edit.tar
5、好习惯和常见问题
- 进入容器调试
docer exec -it containerid bash/sh/.....
- 不将重要数据存储在docker容器中
- 因为会出现数据丢失的风险
- docker中的编码问题
- 通过 centos:7.9.2009 基础镜像运行的容器,语言编码默认为 posix
#查看编码 locale #设置编码 localedef -c -i en_US -f UTF-8 C.UTF-8 \ && echo 'LANG="C.UTF-8"' >> /etc/sysconfig/i18n \ && echo 'LC_ALL="C.UTF-8"' >> /etc/sysconfig/i18n \ && echo 'export LANG="C.UTF-8"' >> /etc/profile \ && echo 'export LC_ALL="C.UTF-8"' >> /etc/profile
- docker中的时间同步问题
- 如果配置的 docker 镜像涉及到任务计划等与时间密切相关的业务,需要特别注意时间同步问题
# 时间同步 ENV TZ=Asia/Shanghai \ DEBIAN_FRONTEND=noninteractive RUN ln -fs /usr/share/zoneinfo/${TZ} /etc/localtime \ && echo ${TZ} > /etc/timezone
- docker中的任务计划问题
- docker中使用任务计划的几种方案
- 使用宿主机执行docker中的指令
- 使用一个单独的容器做任务计划
- 在需要任务计划的容器中配置cron服务
- crontab -e 和 crontab file 和手动编辑的区别
- 配置任务计划时,如果有交互条件,可以使用 crontab -e 进行进行任务计划文件编辑
- 如果没有交互条件,任务计划的配置需要通过命令执行,则可以通过 crontab file 的方式执行
- 一般情况下不要试图通过手动编辑任务计划文件来代替 crontab -e 的操作,这样会导致任务计划不执行,最好通过 crontab file 的方式,将要执行的指令写入 file 文件,然后令 crontab 工具读取文件并导入
- 注意使用 crontab file 的形式导入计划任务文件的时候,注意文件的编码为Linux下的编码
- docker中使用任务计划的几种方案
- docker commit 打包镜像的时候映射数据没有被一起打包的问题
- docker commit 不会保存 -v 映射到容器中的数据
- 在构建过程中启动程序是无效
- 构建过程中可以启动一些应用程序,但是这个操作是无效的,应该将启动步骤放在 CMD 或者 ENTRYPOINT 等指令中,因为docker 镜像本质可以理解为打包的文件系统模板,容器才是根据这些参数真正运行的应用
- 善于使用构建缓存
- docker-compose 的四种重启策略
- no
- 任何情况下都不会重启容器
- on-failure
- 如果容器退出状态码异常时将重启,如果容器退出状态正常将不做任何处理
- always
- 容器非正常退出、容器被正常停止、重启机器、重启docker等都会触发容器重启
- unless-stopped
- 如果容器正常停止,然后机器重启或docker服务重启,这种情况下容器将不会被重启
- no
- 还有最重要的一个点
- 在执行 docker build 的时候,确保宿主机的时间是与网络时间同步,因为有时候可能由于虚拟机回退,造成宿主机时间不准确,在进行docker build 的过程中会由于时间问题造成错误
E: Release file for http://mirrors.aliyun.com/debian/dists/bullseye-backports/InRelease is not valid yet (invalid for another 5h 38min 44s). Updates for this repository will not be applied.
原创文章,作者:witersen,如若转载,请注明出处:https://www.witersen.com