从0-1的docker镜像服务构建

摘要

由于项目服务器要从centos 6升级到centos 7,但是在升级过程中,发现web项目的php在加载自行编写的C扩展时,运行在centos 7总是崩溃,但是直接改C扩展预计要花比较长的时间,可能会延误服务器升级,遂计划基于centos 6,将php构造成docker 镜像来运行。正所谓当翻越山峰耗时,那么绕过去不失为一个办法,最终目的都是抵达终点。
于是有了本篇文章,从docker安装、镜像构建,到docker-compose管理容器,最后基于systemctl管理docker-compose异常重启。

一、环境准备

1、docker安装

1)yum安装

 yum install -y yum-utils vim  // 安装基础工具
 yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo //添加软件源信息
 yum -y install docker-ce
 systemctl enable docker --now  //启动docker并设置为开机自启
 

2)二进制安装(推荐,更加灵活)

  1. 下载安装
wget https://download.docker.com/linux/static/stable/x86_64/docker-20.10.21.tgz
tar -zxvf docker-20.10.21.tgz
mkdir -p /usr/local/docker-20.10.21
mv docker/* /usr/local/docker-20.10.21

  1. 创建软连接
ln -sv /usr/local/docker-20.10.21/* /usr/bin/
  1. 创建docker组,docker启动需要
groupadd -r docker
  1. systemctl配置
[root@ali ~]# cat /usr/lib/systemd/system/docker.service
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service
Wants=network-online.target

[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd --config-file=/etc/docker/daemon.json
ExecReload=/bin/kill -s HUP $MAINPID
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
# Uncomment TasksMax if your systemd version supports it.
# Only systemd 226 and above support this version.
#TasksMax=infinity
TimeoutStartSec=0
# set delegate yes so that systemd does not reset the cgroups of docker containers
Delegate=yes
# kill only the docker process, not all processes in the cgroup
KillMode=process
# restart the docker process if it exits prematurely
Restart=on-failure
RestartSec=3s
StartLimitBurst=3
StartLimitInterval=60s

[Install]
WantedBy=multi-user.target

  1. docker配置
[root@ali ~]# cat /etc/docker/daemon.json
{
  "data-root": "/home/docker/data-root",
  "pidfile": "/home/docker/run/docker.pid",
  "log-level": "info",
  "registry-mirrors": ["http://hub-mirror.c.163.com","https://registry.docker-cn.com"]   #docker镜像源
}
  1. 开机自启动
systemctl enable docker --now
  1. 启动
systemctl restart docker

docker配置相关
docker命令

2、docker-compose安装

docker-compose 是用于定义和运行多容器 Docker 应用程序的工具,通过一个配置文件来管理多个Docker容器,在配置文件中,所有的容器通过services来定义,然后使用docker-compose脚本来启动,停止和重启应用,和应用中的服务以及所有依赖服务的容器,非常适合组合使用多个容器进行开发的场景。这样就可以替代复杂的shell脚本来管理多个容器。

二进制文件获取

linux下载

curl -L https://github.com/docker/compose/releases/download/2.14.2/docker-compose-`uname -s`-`uname -m` -o /usr/bin/docker-compose

二、镜像制作

2.1、编写Dockerfile文件

指令说明

2.1.1、熟悉常用Dockerfile命令
  • FROM #基础镜像,我们要制作的镜像常常是依赖某个基础镜像来实现的,这些基础镜像常见的如centos,ubatu,alpine,harbox,debian等,其中alpine很小,安全。
    这些镜像到docker官方仓库搜索即可,选择相应的版本,如:FROM centos:6.6 。

  • COPY #从上下文目录中复制文件或者目录到容器里指定路径。如:COPY ./package/usr/lib64/phpmath.so /usr/lib64/phpmath.so。

  • RUN #用于在基础镜像中执行后面跟着的命令行命令。如:RUN mkdir -p /usr/local/php/ 。

  • CMD #类似于 RUN 指令,用于运行程序,但二者运行的时间点不同:1)CMD 在docker run 时运行;2)RUN 是在 docker build。如果有多条仅最后一条生效。该指令所启动的程序即容器的主进程,其退出容器也会退出,所以该指令的命令应当是常驻进程。

2.1.2、制作php镜像案例
FROM centos:6.6

COPY ./package/usr/lib64/phpmath.so /usr/lib64/phpmath.so
COPY ./package/usr/lib64/libserialize.so /usr/lib64/libserialize.so
COPY ./package/usr/lib64/protocolbuffers.so /usr/lib64/protocolbuffers.so
COPY ./package/usr/lib64/redis.so /usr/lib64/redis.so
COPY ./package/usr/lib64/mysqli.so /usr/lib64/mysqli.so

COPY ./package/php5 /usr/local/
COPY ./dockerphp5/usr/local/php/etc/php-fpm.conf /usr/local/php/etc/php-fpm.conf

RUN mkdir -p /home/php/fpm/  #fpm 日志目录

RUN mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
COPY ./dockerphp5/etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo
RUN yum clean all && yum makecache
RUN yum -y install vixie-cron
RUN yum -y install crontabs

#一些定时脚本
COPY ./dockerphp5/etc/crontab /etc/crontab
RUN mkdir -p /etc/cron.minutely/
COPY ./dockerphp5/etc/cron.minutely/* /etc/cron.minutely/
RUN mkdir -p /etc/cron.hourly/
COPY ./dockerphp5/etc/cron.hourly/* /etc/cron.hourly/
RUN mkdir -p /etc/cron.daily/
COPY ./dockerphp5/etc/cron.daily/* /etc/cron.daily/

EXPOSE 9000

CMD ["/usr/bin/phpfpmd.sh"]   #/usr/bin/phpfpmd.sh有多条命令,仅最后一条是常驻的

[root@ali ~]# cat /usr/bin/phpfpmd.sh
#!bin/bash
/etc/init.d/crond restart
/usr/local/php/sbin/php-fpm -y /usr/local/php/etc/php-fpm.conf -g /usr/local/php/var/run/php-fpm.pid

2.2、build镜像
docker build -t php:5.4.7 -f ./dockerphp5/Dockerfile .  #其中-t指定镜像名称和tag(版本)

如果顺利执行完,就可以看到镜像了

[root@ali ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
php      5.4.7     360997ecc130   3 weeks ago   852MB
centos       6.6       368c96d786ae   3 years ago   203MB

三、docker-compose管理容器

3.1、编写docker-compose.ymal配置文件

指令说明

version: '3'
services:
  php5:                        
    image: "php:5.4.7"                                 #指定镜像
    ports:
      - "127.0.0.1:9000:9000"
    volumes:                                           #指定目录挂载
      - "/usr/local/web:/usr/local/web"                #项目代码目录
      - "/home/web:/home/web"                          #项目日志等目录 
      - "/etc/docker/cron.minutely:/etc/cron.minutely"
      - "/etc/docker/cron.hourly:/etc/cron.hourly"
      - "/etc/docker/cron.daily:/etc/cron.daily"
      - "/etc/localtime:/etc/localtime"                #时间与宿主机一致
    extra_hosts:                                       #向容器/etc/hosts添加域名
      - "redis.link.cn:200.200.172.106"
      - "mysql.link.cn:200.200.172.108"
    container_name: "phpfpmd"                         #容器名称
    

此时可以通过/usr/bin/docker-compose -f /etc/docker/docker-compose.yml up 来启动容器了,相比较docker run -itd -p 9000:9000 -v xxx:xxx --add-host xxx:xxx --name phpfpmd php:5.4.7 简洁多了,特别是容器多的时候,但是无法解决开机自启动,没有看门狗的问题,这个可以利用systemctl来解决

3.2、编写systemctl配置

指令说明

[Unit]
Description=php-fpm
#Documentation=nothing
After=network-online.target docker.service
Wants=network-online.target
Requires=docker.service  

[Service]
#service type
Type=simple          #服务类型,1)simple(默认值):ExecStart字段启动的进程为主进程 2)forking:ExecStart字段将以fork()方式启动,此时父进程将会退出,子进程将成为主进程

#3)oneshot:类似于simple,但只执行一次,Systemd 会等它执行完,才启动其他服务 4)dbus:类似于simple,但会等待 D-Bus 信号后启动

#5)notify:类似于simple,启动结束后会发出通知信号,然后 Systemd 再启动其他服务,fixme:这种需要启动程序实现sd_notify 6)idle:类似于simple,但是要等到其他任务都执行完,才会启动该服务。一种使用场合是为让该服务的输出,不与其他服务的输出相混合

# for php-fpm container control,
ExecStart=/usr/bin/docker-compose -f /etc/docker/docker-compose.yml up 
#ExecReload=
ExecStop=/usr/bin/docker-compose -f /etc/docker/docker-compose.yml stop

# kill only the docker process, only exec ExecStop
KillMode=none
# softdog :restart the php-fpm process if it exit
Restart=on-failure  #异常时会重启
RestartSec=3s       #每3s检查一次
StartLimitBurst=3
StartLimitInterval=60s   

[Install]
WantedBy=multi-user.target

编写完成放到/usr/lib/systemd/system/目录下,即/usr/lib/systemd/system/phpfpmd.service

  1. 刷新
systemctl daemon-reload
  1. 开启自启动
systemctl enable phpfpmd
  1. 启动容器
systemctl restart phpfpmd

至此一个完整的docker容器就完成了

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值