Home | 简体中文 | 繁体中文 | 杂文 | Github | 知乎专栏 | Facebook | Linkedin | Youtube | 打赏(Donations) | About
知乎专栏

104.10. Dockerfile

104.10.1. 基于 Dockerfile 创建镜像

为什么要自己创建镜像呢? 因为官方提供的镜像无法满足我们的需求,例如 nginx 镜像你会发现 ps, top 等等很多命令缺失。

104.10.1.1. 创建 Dockerfile 文件

需求基于centos7镜像创建nginx stable最新版本镜像

		
############################################################
# Dockerfile to build Nginx container
# Based on centos7
############################################################

FROM centos:latest

MAINTAINER Netkiller <netkiller@msn.com>

# Install EPEL
RUN yum install -y epel-release && yum clean all

# Update RPM Packages
RUN yum -y update

# Install Nginx
RUN rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
RUN yum install -y nginx
RUN yum clean all

# forward request and error logs to docker log collector
RUN ln -sf /dev/stdout /var/log/nginx/access.log
RUN ln -sf /dev/stderr /var/log/nginx/error.log

# be backwards compatible with pre-official images
#RUN ln -sf ../share/nginx /usr/local/nginx

# prepare container

# add startup script
#ADD startup.sh /startup.sh
#RUN chmod 755 /startup.sh

VOLUME ["/etc/nginx"]
VOLUME ["/usr/share/nginx/html"]
VOLUME ["/var/www"]

EXPOSE 80 443

CMD ["nginx", "-g", "daemon off;"]
		
			

104.10.1.2. 创建镜像

		
# docker build -t "centos:nginx" .
Sending build context to Docker daemon 3.072 kB
Step 1/14 : FROM centos:latest
 ---> 3bee3060bfc8
Step 2/14 : MAINTAINER Netkiller <netkiller@msn.com>
 ---> Using cache
 ---> 8f351964d568
Step 3/14 : RUN yum install -y epel-release && yum clean all
 ---> Using cache
 ---> bf86eff77ff3
Step 4/14 : RUN yum -y update
 ---> Using cache
 ---> 4915172ac4f3
Step 5/14 : RUN rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
 ---> Using cache
 ---> 4a919bd141c9
Step 6/14 : RUN yum install -y nginx
 ---> Using cache
 ---> 2718221eab8c
Step 7/14 : RUN yum clean all
 ---> Using cache
 ---> 62231a5f1d76
Step 8/14 : RUN ln -sf /dev/stdout /var/log/nginx/access.log
 ---> Using cache
 ---> 38be8f0cc782
Step 9/14 : RUN ln -sf /dev/stderr /var/log/nginx/error.log
 ---> Using cache
 ---> bbf3a468d24f
Step 10/14 : VOLUME /etc/nginx
 ---> Using cache
 ---> 919292c7ce04
Step 11/14 : VOLUME /usr/share/nginx/html
 ---> Using cache
 ---> c2aeb8ed3c1c
Step 12/14 : VOLUME /var/www
 ---> Using cache
 ---> 31849cb8a9d0
Step 13/14 : EXPOSE 80 443
 ---> Using cache
 ---> 0e3d3b4a215b
Step 14/14 : CMD nginx -g daemon off;
 ---> Using cache
 ---> d5f21e409690
Successfully built d5f21e409690
		
			

查看镜像

		
# docker image ls                 
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              nginx               d5f21e409690        4 minutes ago       364 MB
centos              latest              3bee3060bfc8        2 days ago          193 MB
nginx               latest              958a7ae9e569        8 days ago          109 MB
redis               latest              a858478874d1        2 weeks ago         184 MB		
		
			

104.10.1.3. 运行镜像

		
# docker run --name my-centos-nginx -d centos:nginx
ecf342ddd66d1d5f3d28c583ec852c05903ef4813fcb75295c907a6b578dea3d

# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
ecf342ddd66d        centos:nginx        "nginx -g 'daemon ..."   23 seconds ago      Up 23 seconds       80/tcp, 443/tcp          my-centos-nginx
0df3b275bb03        nginx               "nginx -g 'daemon ..."   6 hours ago         Up 6 hours          80/tcp                   my-nginx
1c4540d8617f        redis               "docker-entrypoint..."   2 days ago          Up 2 days           0.0.0.0:6379->6379/tcp   my-redis
		
			

104.10.1.4. 测试 Nginx

		
[root@netkiller]~/docker/nginx# docker exec -it my-centos-nginx /bin/bash

[root@netkiller-docker /]# ps ax
  PID TTY      STAT   TIME COMMAND
    1 ?        Ss     0:00 nginx: master process nginx -g daemon off;
    7 ?        S      0:00 nginx: worker process
    8 ?        Ss     0:00 /bin/bash
   22 ?        R+     0:00 ps ax

[root@netkiller-docker /]# curl http://localhost
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
		
		
			

104.10.1.5. 提交镜像

		
# docker commit my-centos-nginx netkiller/centos:nginx
sha256:9ea1851b1c9f04aa3168977f666337223d09e20983f7a2c2328e15132a03d224
		
			
		
# docker push netkiller/centos:nginx
The push refers to a repository [docker.io/netkiller/centos]
16916856eaaa: Pushed 
6172d61b45f1: Pushed 
db323af550f0: Pushed 
232df2cfd38f: Pushed 
c247a550215b: Pushed 
3b5451d7989c: Pushed 
e3a6f1af6a7a: Pushed 
9e3cea652b37: Pushed 
dc1e2dcdc7b6: Mounted from library/centos 
nginx: digest: sha256:ad9bd1ae3a3e17dac70f32afc14baf90932949d3eaa8bebbe907726aca3ea336 size: 2205
		
			

104.10.2. 基于 Alpine 制作镜像

获取最新镜像

		
root@netkiller ~# docker pull alpine:latest
		
		

运行镜像,看看这个镜像,在里面模拟一次执行

		
root@netkiller ~# docker run --rm -it --name=alpine --entrypoint=sh alpine:latest
		
		

进入容器,修改apk库的镜像

		
root@netkiller ~# docker run --rm -it --name=alpine --entrypoint=sh alpine:latest

sed 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' -i /etc/apk/repositories 
apk update
apk add python3
		
		

		
FROM python:3-alpine
MAINTAINER netkiller "netkiller@msn.com"

RUN echo https://mirrors.aliyun.com/alpine/latest-stable/main/ > /etc/apk/repositories
RUN pip install --no-cache-dir flask && pip3 install python-jenkins
RUN pip install --no-cache-dir netkiller-devops --upgrade -i https://pypi.tuna.tsinghua.edu.cn/simple
RUN mkdir -p /data 

ADD ./ /data

RUN chmod +x /data/devops
RUN rm -rf /var/cache/apk/*

WORKDIR /data

EXPOSE 8080

CMD ["python3", "app.py"]		
		
		

104.10.3. Dockerfile 缺失的工具

工作中我们常常发现官方镜像裁剪的面目全非,里面缺失很多常用工具,这种情况给我们工作带来诸多不便。

104.10.3.1. Debian/Ubuntu 镜像

切换镜像

https://mirrors.tuna.tsinghua.edu.cn/help/debian/
			 
cat > /etc/apt/sources.list <<-EOF

deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye main contrib non-free
# deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye main contrib non-free
deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye-updates main contrib non-free
# deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye-updates main contrib non-free

deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye-backports main contrib non-free
# deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye-backports main contrib non-free

deb https://mirrors.tuna.tsinghua.edu.cn/debian-security bullseye-security main contrib non-free
# deb-src https://mirrors.tuna.tsinghua.edu.cn/debian-security bullseye-security main contrib non-free

EOF
			
			

ps,top 等系统工具

			
apt update -y && apt install -y procps		
			
			

ping

			
apt install iputils-ping
			
			

telnet

			
apt install -y telnet			
			
			

ip, ss

			
apt install -y iproute2			
			
			

ifconfig, netstat

			
apt install -y net-tools			
			
			

dig

			
apt install -y dnsutils
			
			

104.10.3.2. CentOS

psmisc 里面包含 ps, top 等命令

			
dnf install -y bzip2 tree psmisc \
telnet wget rsync vim-enhanced \
net-tools bind-utils			
			
			

nslookup

			
dnf install -y bind-utils
			
			
			
dnf install -y net-tools			
			
			

104.10.3.3. alpine

添加 apk 仓库

			
FROM python:3.9-alpine
MAINTAINER netkiller "netkiller@msn.com"

RUN echo https://mirrors.aliyun.com/alpine/latest-stable/main/ > /etc/apk/repositories
RUN pip3 install flask && pip3 install python-jenkins
RUN mkdir -p /data 

ADD ./ /data

RUN chmod +x /data/devops
RUN rm -rf /var/cache/apk/*

WORKDIR /data

EXPOSE 8080

CMD ["python3", "app.py"]
			
			

104.10.4. Dockerfile 语法

104.10.4.1. COPY

跨容器拷贝

			
FROM demo/test:latest as netkiller

MAINTAINER Netkiller <netkiller@msn.com>

RUN mkdir /www

COPY some/path/to/ /www/



FROM nginx:1.13-alpine

RUN rm -rf /usr/share/nginx/html/*
COPY --from=netkiller /www/ /usr/share/nginx/html/
			
			

--from 参数

			
# Install the base requirements for the app.
# This stage is to support development.
FROM python:alpine AS base
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt

# Run tests to validate app
FROM node:12-alpine AS app-base
WORKDIR /app
COPY app/package.json app/yarn.lock ./
RUN yarn install
COPY app/spec ./spec
COPY app/src ./src
RUN yarn test

# Clear out the node_modules and create the zip
FROM app-base AS app-zip-creator
RUN rm -rf node_modules && \
    apk add zip && \
    zip -r /app.zip /app

# Dev-ready container - actual files will be mounted in
FROM base AS dev
CMD ["mkdocs", "serve", "-a", "0.0.0.0:8000"]

# Do the actual build of the mkdocs site
FROM base AS build
COPY . .
RUN mkdocs build

# Extract the static content from the build
# and use a nginx image to serve the content
FROM nginx:alpine
COPY --from=app-zip-creator /app.zip /usr/share/nginx/html/assets/app.zip
COPY --from=build /app/site /usr/share/nginx/html			
			
			

104.10.4.2. EXPOSE

EXPOSE 是声明端口,容器内运行的程序使用了什么端口

			
EXPOSE <端口1> [<端口2>...]
			
			

104.10.4.3. ENTRYPOINT

从命令行传递参数给容器

			
FROM ubuntu
ENTRYPOINT [ "top", "-b" ]		
			
			

运行下面的命令:

			
$ docker run --rm test1 -c				
			
			

实际 Docker 内部

			
top -b -c			
			
			

ENTRYPOINT 与 CMD 组合

			
FROM ubuntu
ENTRYPOINT [ "top", "-b" ]
CMD [ "-c" ]			
			
			
docker-entrypoint.sh 文件
				
ENTRYPOINT ["docker-entrypoint.sh"]				
				
				

你不能写成

				
ENTRYPOINT docker-entrypoint.sh				
				
				

ENTRYPOINT docker-entrypoint.sh 会使用 sh -c 执行

				
 "/bin/sh -c /srv/docker-entrypoint.sh /srv/rocketmq/bin/mqnamesrv" 				
				
				

而我们需要的是

				
/srv/docker-entrypoint.sh /srv/rocketmq/bin/mqnamesrv				
				
				

所以需要写成 ENTRYPOINT ["docker-entrypoint.sh"]