Skip to content

Docker

9 posts with the tag “Docker”

Python-slim镜像制作

Python基础镜像制作,添加中文字体

Windows 电脑上,可以在 C:\Windows\Fonts 下找到。 或者下载开源且风格类似的 思源宋体 (Noto Serif CJK SC)STIX (用于数学公式)

FROM python:3.11-slim
# 使用国内镜像源
# 防止 hidden 的 bookworm 源干扰
RUN rm -rf /etc/apt/sources.list.d/* /etc/apt/sources.list
RUN echo "deb http://mirrors.aliyun.com/debian/ testing main non-free non-free-firmware contrib" > /etc/apt/sources.list && \
echo "deb-src http://mirrors.aliyun.com/debian/ testing main non-free non-free-firmware contrib" >> /etc/apt/sources.list && \
echo "deb http://mirrors.aliyun.com/debian-security/ testing-security main non-free non-free-firmware contrib" >> /etc/apt/sources.list
# 1. 更新源并安装 fontconfig
# --no-install-recommends: 避免安装不必要的推荐包,保持镜像小
# rm -rf /var/lib/apt/lists/*: 安装后删除 apt 缓存,减小镜像体积 (Slim 镜像的最佳实践)
RUN apt-get update && \
apt-get install -y --no-install-recommends fontconfig && \
rm -rf /var/lib/apt/lists/*
# 2. 创建字体目录
RUN mkdir -p /usr/share/fonts/truetype/custom
# 3. 拷贝字体文件 (确保你的项目目录下有 fonts/simsun.ttc)
COPY ./fonts/simsun.ttc /usr/share/fonts/truetype/custom/
# 4. 刷新系统字体缓存 (现在这个命令可以成功运行了)
RUN fc-cache -fv
# --- 关键修改结束 ---
# 下面是原本的构建步骤
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
# ... CMD 等指令
  1. apt-get install fontconfig:

    • python:3.11 (完整版) 基于 Debian 完整版,通常自带很多工具。
    • python:3.11-slim 基于 Debian Slim,砍掉了非必要的工具(包括管理字体的工具)。如果不手动安装 fontconfig,你就无法将新字体注册到系统里。
  2. rm -rf /var/lib/apt/lists/*:

    • slim 镜像中,安装完软件后如果不清理缓存,会白白增加这一层的体积。这是编写高质量 Dockerfile 的标准操作。
  • 拷贝指令 (COPY):本身没有影响,完全通用。
  • 刷新指令 (fc-cache):在 slim 镜像下必须先安装 fontconfig 才能用。

Docker网络

Docker使用Linux桥接,在主机构建了一个特殊的、可定制的虚拟网络拓扑结构,Docker网桥接口路由,这个网桥接口被成为docker0。 每一个容器都被赋予一个唯一的私有IP地址,从外部的网络是不能直接连接到该私有IP。主机上的每个容器都会连接到docker0,构成一个网络,同时网桥接口docker0会连接到主机所连接的网络上。

Docker安装后自动提供了三种网络,可以使用docker network ls命令查看:

Terminal window
$~ docker network ls
NETWORK ID NAME DRIVER SCOPE
50d276f46ba7 bridge bridge local
f7d70556f900 host host local
7081fbaf563c none null local

所有的Docker容器要符合四种原型中的一种,原型定义了一个容器如何和本地容器、主机网络进行通信,每种原型有不同的目的,隔离程度。

img

  • Closed容器,容器中进程只能访问本地回环接口,不允许任何的网络流量,容器内进程不能访问容器外的网络,容器外程序也无法连接到容器网络接口上。

docker run 命令后添加参数—net none,即可创建Closed容器:

Terminal window
$ docker run --rm --net none alpine ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN qlen 1000
link/ipip 0.0.0.0 brd 0.0.0.0
3: ip6tnl0@NONE: <NOARP> mtu 1452 qdisc noop state DOWN qlen 1000
link/tunnel6 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 brd 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
  • Bridged容器 拥有两个接口:私有的本地回环接口和一个通过网桥连接主机的私有接口。Bridged容器是Docker的默认选项,可定制性最高,被认为是最佳实践。

docker run 命令忽略—net选项,或者—net 值设置为bridge,创建一个Brided容器:

Terminal window
$docker run --rm --net bridge alpine:latest ip addr
$docker run --rm alpine:latest ip addr

从容器中访问阿里DNS服务器:

Terminal window
$ docker run --rm alpine:latest ping -w 2 223.5.5.5 0 [15:36:26]
PING 223.5.5.5 (223.5.5.5): 56 data bytes
64 bytes from 223.5.5.5: seq=0 ttl=37 time=27.976 ms
64 bytes from 223.5.5.5: seq=1 ttl=37 time=31.903 ms
--- 223.5.5.5 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 27.976/29.939/31.903 ms
  • Joined

Joined容器原型隔离程度更低,这些容器共享一个网络栈,容器之间没有任何隔离。

可以使用docker run —network将两个容器进行连接,如下:第一个命令启动一个在本地回环接口监听的服务器,第二个命令连接第一个容器,并列出当前容器所有的开发端口。

Terminal window
$ docker run -d --name tudou --net none alpine:latest nc -l 127.0.0.1:4444
a72ecddb0f461720495960331c36ea29594e7986e87e8fa2f1cfff9f41468301
$ docker run -it --rm --network container:tudou alpine netstat -al
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:33957 0.0.0.0:* LISTEN
Active UNIX domain sockets (servers and established)
Proto RefCnt Flags Type State I-Node Path

当两个容器被连接,每一个接口都被共享,因此会引入端口冲突的问题。

Joined容器的使用场景

  1. 想要不同容器上的程序通过本地回环接口进行通信
  2. 一个容器中的程序将要改变Joined网络栈,而另外一个程序将要使用那个被改变的网络栈
  3. 想要监控另外一个容器中某个程序的网络流量
  • Open

Open容器非常危险。它没有网络容器,并对主机网络有完全的访问权。

docker run 命令的—net选项值为host时,就会创建Open容器:

Terminal window
$ docker run --rm --net host alpine ip addr

Docker搭建FTP服务器

使用Docker搭建FTP服务。使用的镜像是fauria/vsftpd

Terminal window
docker pull fauria/vsftpd
Terminal window
docker run -d --name vsftpd -v ~/sftp:/home/vsftpd \
-p 21:21 -p 20:20 -p 21100-21110:21100-21110 \
-e FTP_USER=myuser -e FTP_PASS=mypass \
-e PASV_ADDRESS=127.0.0.1 \
--restart=always \
fauria/vsftpd
#-p 进行端口绑定映射
#-v 添加容器数据卷
#-e FTP_USER=davion -e FTP_PASS=davion 添加一个初始化用户davion
#PASV_MIN_PORT和PASV_MAX_PORT映射的是被动模式下端口使用范围
#-name vsftpd 为容器命名为vsftpd
#--restart=always fauria/vsftpd docker 异常退出时自动重启容器

3. 在镜像中新增自定义的新用户

Section titled “3. 在镜像中新增自定义的新用户”
Terminal window
# 进入容器
docker exec -it vsftpd bash
# 创建
mkdir /home/vsftpd/myuser
echo -e "myuser\nmypass" >> /etc/vsftpd/virtual_users.txt
/usr/bin/db_load -T -t hash -f /etc/vsftpd/virtual_users.txt /etc/vsftpd/virtual_users.db
exit
#重启
docker restart vsftpd

在浏览器(或者其他ftp客户端工具)中输入:ftp://127.0.0.1 , 测试是否访问正常

Docker

Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。

Docker 是一个工具,可以帮助解决如安装、拆卸、升级、分发、信任和管理软件等常用问题。Docker包含一个命令行程序、一个后台守护进程和一组远程服务。

Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。

Docker 是一个工具,可以帮助解决如安装、拆卸、升级、分发、信任和管理软件等常用问题。Docker包含一个命令行程序、一个后台守护进程和一组远程服务。

不同于虚拟机,Docker容器不使用硬件虚拟化,运行在Docker容器中的程序接口直接和Linux内核打交道,容器中的程序和操作系统之间没有额外的中间层。

命令行工具在用户名称空间的内存中运行, 同操作系统上运行的其他程序一样。

image-20200617111314194

Docker构建的容器隔离包括以下8个方面:

  1. PID名称空间---进程表示符和能力
  2. UST名称空间---主机名和域名
  3. MNT名称空间---文件系统访问和结构
  4. NET名称空间---网路访问和结构
  5. USR名称空间---用户名和标识
  6. chroot()---控制文件系统根目录的位置
  7. cgroups---资源保护

Docker有三个特定功能,来帮助建立与环境无关的系统

  • 只读文件系统
  • 环境变量注入
  • 存储卷

只读文件系统,容器不能更改它所包含的任何文件,同时容器中的攻击者无法破坏文件。

创建容器时需使用—read-only标志,如:

Terminal window
docker run -d --read-only wordpress:4

环境变量是通过执行上下文提供给程序的键值对。可以让用户在更改程序配置时,无须修改任何文件或者更改启动程序的命令。

—env标志或者-e缩写,可用于注入任何环境变量, 如:

Terminal window
$ docker run --env MY_ENV="hello world" busybox:latest env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=90b9adbe051c
MY_ENV=hello world
HOME=/root

创建容器时,如果忘记添加参数—restart=always,那么容器并不会自动重启。容器已经创建,此时修改容器配置可以通过命令:docker container update,

Terminal window
± docker container update --help
Usage: docker container update [OPTIONS] CONTAINER [CONTAINER...]
Update configuration of one or more containers
Options:
--blkio-weight uint16 Block IO (relative weight), between 10 and 1000, or 0 to disable (default 0)
--cpu-period int Limit CPU CFS (Completely Fair Scheduler) period
--cpu-quota int Limit CPU CFS (Completely Fair Scheduler) quota
--cpu-rt-period int Limit the CPU real-time period in microseconds
--cpu-rt-runtime int Limit the CPU real-time runtime in microseconds
-c, --cpu-shares int CPU shares (relative weight)
--cpus decimal Number of CPUs
--cpuset-cpus string CPUs in which to allow execution (0-3, 0,1)
--cpuset-mems string MEMs in which to allow execution (0-3, 0,1)
--kernel-memory bytes Kernel memory limit
-m, --memory bytes Memory limit
--memory-reservation bytes Memory soft limit
--memory-swap bytes Swap limit equal to memory plus swap: '-1' to enable unlimited swap
--pids-limit int Tune container pids limit (set -1 for unlimited)
--restart string Restart policy to apply when a container exits

如,修改restart配置, 可以使用:

Terminal window
docker container update --restart=always 容器ID

本地Docker加载阿里Mysql物理备份

将阿里云数据库物理备份的数据下载到本地,使用Docker来加载,来做数据升级和迁移的本地测试。

  1. 将线上数据库物理备份,并下载到本地

    如下载后放置在~/Downloads/hins4577021_data_20181203163125.tar

  2. 将数据库备份文件解压, 如:

Terminal window
mkdir -p ~/Downloads/data
cd ~/Downloads
tar -xvf hins4577021_data_20181203163125.tar -C ./data
  1. 使用mysql 5.7 docker镜像,加载数据备份数据
Terminal window
docker run --name some-mysql -v "$PWD/data":/var/lib/mysql -e MYSQL_ROOT_PASSWORD=go -p 3306:3306 -d mysql:5.7
# 查看运行的容器
docker ps 0 [10:51:06]
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0a128332fe96 mysql:5.7 "docker-entrypoint.s…" 10 minutes ago Up 10 minutes 0.0.0.0:3306->3306/tcp, 33060/tcp some-mysql
  1. 连接数据库(使用线上数据库的用户名和密码)
Terminal window
mysql -h 127.0.0.1 -P3306 -u saas -p 0 [10:50:02]
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 7
Server version: 5.7.24 MySQL Community Server (GPL)
Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>

Docker镜像搭建Linux下samba共享目录

SambaSMB/CIFS 网络协议的重新实现, 它作为 NFS 的补充使得在 Linux、OS/2、DOS 和 Windows 系统中进行文件共享、打印机共享更容易实现。SMB协议是客户机/服务器型协议,客户机通过该协议可以访问服务器上的共享文件系统、打印机及其他资源。通过设置“NetBIOS over TCP/IP”使得Samba不但能与局域网络主机分享资源,还能与全世界的电脑分享资源。

这里通过使用docker镜像的方式来简化samba的安装, 来实现不同系统之间共享目录。

运行docker

Terminal window
sudo docker run -it -p 139:139 -p 445:445 -d dperson/samba

如果要使用本地存储,则可以:

Terminal window
sudo docker run -it --name samba -p 139:139 -p 445:445 \
-v /path/to/directory:/mount \
-d dperson/samba

配置参数:

Terminal window
docker run -it --rm dperson/samba -h
Usage: samba.sh [-opt] [command]
Options (fields in '[]' are optional, '<>' are required):
-h This help
-c "<from:to>" setup character mapping for file/directory names
required arg: "<from:to>" character mappings separated by ','
-g "<parameter>" Provide global option for smb.conf
required arg: "<parameter>" - IE: -g "log level = 2"
-i "<path>" Import smbpassword
required arg: "<path>" - full file path in container
-n Start the 'nmbd' daemon to advertise the shares
-p Set ownership and permissions on the shares
-r Disable recycle bin for shares
-S Disable SMB2 minimum version
-s "<name;/path>[;browse;readonly;guest;users;admins;writelist;comment]"
Configure a share
required arg: "<name>;</path>"
<name> is how it's called for clients
<path> path to share
NOTE: for the default value, just leave blank
[browsable] default:'yes' or 'no'
[readonly] default:'yes' or 'no'
[guest] allowed default:'yes' or 'no'
[users] allowed default:'all' or list of allowed users
[admins] allowed default:'none' or list of admin users
[writelist] list of users that can write to a RO share
[comment] description of share
-u "<username;password>[;ID;group]" Add a user
required arg: "<username>;<passwd>"
<username> for user
<password> for user
[ID] for user
[group] for user
-w "<workgroup>" Configure the workgroup (domain) samba should use
required arg: "<workgroup>"
<workgroup> for samba
-W Allow access wide symbolic links
-I Add an include option at the end of the smb.conf
required arg: "<include file path>"
<include file path> in the container, e.g. a bind mount
The 'command' (if provided and valid) will be run instead of samba

现在要将目录xw_share, 通过139和445端口进行共享, 并创建用户xw(密码为:overkill),禁用匿名用户访问,并且允许用户xw读写操作,可以如下设置:

Terminal window
docker run -it --name samba -p 139:139 -p 445:445 \
-v $PWD/xw_share:/mount -d dperson/samba -u "xw;overkill" -s "xw;/mount/;yes;no;no;all;xw;xw"
  1. Samba (简体中文)
  2. samba百度百科
  3. dperson/samba

使用Jenkins进行Docker构建环境配置

使用Jenkins对go程序进行编译,并构建docker镜像。这里讲述了在Centos7系统上,从零开始配置Jenkins(设置jenkins home目录、配置角色、配置用户),新建项目,配置docker。

系统环境:Centos7

Jenkins:2.165

Go:1.10.2

Docker: 18.03.1-ce

  1. 安装

添加Jenkins repository 到yum repos, 再安装Jenkins.

Terminal window
sudo wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo
sudo rpm --import https://jenkins-ci.org/redhat/jenkins-ci.org.key
sudo yum install jenkins

或者直接下载, 并将war包添加到环境变量中。

  1. 运行

    在终端中执行:

    Terminal window
    java -jar jenkins --httpPort=8080

    在浏览器打开 http://localhost:8080

    指定Jenkins HOME目录可以:

    Terminal window
    JENKINS_HOME=/home/xw/jenkins_home java -jar /usr/lib/jenkins/jenkins.war --httpPort=8080 &

使用第三方插件:Locale plugin

具体参见:[Jenkins强制设置语言为中文](https://www.cnblogs.com/hanxiaohui/p/8136621.html)

三、配置Jenkins的授权和访问控制

Section titled “三、配置Jenkins的授权和访问控制”

由于jenkins默认的权限管理体系不支持用户组或角色的配置,所以使用第三方插件Role Strategy Plugin实现。

配置过程,见:[Jenkins学习七:Jenkins的授权和访问控制](https://www.cnblogs.com/yangxia-test/p/4368778.html)

配置过程中,配置不当导致admin无法登陆时,可以通过修改配置文件方式解决, 具体可以参见以下方式解决:

有两种方式, 一种是配置仓库的用户名和密码,另外一种是配置SSH私钥, 配置方式具体可以参见:

构建可以通过设置参数,来达到可以在指定的分支、指定的Tag或者特定参数(如指定版本号)的情况下,进行特定化构建。

Jenkins默认不知可选择的参数,可以通过第三方插件来支持: Extensible Choice Parameter plugin

具体操作配置,可以参见:

配置过程中的指定的参数,会在[Build->Execute shell]中以环境变量的形式存在。

##六、配置Docker

这里准备使用新建[Freestyle project]项目,并通过【Execute shell】的最基本的方式来构建Docker镜像

由于Excel shell中是使用系统jenkins用户来执行docker命令,所以需要在jenkins用户下进行登录Docker私有仓库。

Terminal window
sudo su -s /bin/bash jenkins
bash-4.2$ docker login --username=xxx registry.cn-beijing.aliyuncs.com

在新建的自由风格项目中,指定好代码仓库后, 编辑Build部分如:

Docker运行cron

有时只需要运行最简单的单命令cron任务。alpine Docker镜像提供了一个很好的选择,这个镜像通过busybox提供了一个简单灵活的cron包。

复杂的定时任务,可以通过挂载卷的方式。

Terminal window
docker run -it --rm -v $PWD/tasks.cron:/tasks.cron alpine:3.5 sh -c "crontab /tasks.cron && crond -f -L /dev/stdout"

tasks.cron

* * * * * echo hello

构建自己的Docker镜像,通过使用ENTRYPOINT可以更简洁的运行cron任务

FROM alpine:3.8
LABEL maintainer="xwxwgo.com"
COPY entrypoint.sh /
RUN chmod +x /entrypoint.sh
ENTRYPOINT [ "/entrypoint.sh" ]

entrypoint.sh

#!/bin/sh
set -e
echo "$1" | crontab - && crond -f -L /dev/stdout

构建、执行

Terminal window
# 构建镜像
$ docker build -t xw-cron ./
# 执行
$ docker run -it --rm xw-cron "* * * * * echo hello"

Docker常用命令

Terminal window
docker run --detach --name web nginx:latest

—detach 缩写是 -d, 使用该选项,程序将在后台启动,不会附着到终端。运行守护式容器适合后台静默运行程序,也即是守护程序。

—name, 每个容器分配一个唯一的标识符, 一个16进制编码的1024位数字。大多数Docker界面上,Docker ID会截断前12个字符,使生成的ID更人性化,—name标识可以给容器分配一个固定的名称。

Terminal window
docker run --ineractive --tty --name test busybox:latest /bin/sh

—interactive(或-i) 选项会让Docker保持标准输入流(stdin, 标准输入)对容器开发, 即使容器没有终端连接。

—tty(或-t)选项会让Docker为容器分配一个虚拟终端,这使得可以给发送信号给容器

docker ps 命令可以查看当前正在运行中的容器。

Terminal window
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
21f9caa76a05 busybox:latest "/bin/sh -c 'sleep 3…" 21 minutes ago Up 21 minutes nsa

该命令显示每个运行中容器的以下信息:

  • CONTAINER ID 容器ID
  • IMAGE 使用的镜像
  • COMMAND 执行的命令
  • CREATED 容器运行的时长
  • PORT 容器暴露的网路端口
  • NAMES 容器名
Terminal window
docker restart test

docker restart 通过容器的ID或者容器名称,可以重启已经停止的容器

Terminal window
docker logs test

通过docker logs命令选项—fllow(或-f),可用来显示容器日志,并继续监视和更新容器的日志显示,不放过日志中的任何变化。

Terminal window
docker run -d --read-only wordpress:4

使用—read-only标志,可以创建一个只读的文件系统,容器不能更改它所包含的任何文件,因而即使容器中有攻击者,也无法破坏任何文件

Terminal window
docker run --env MY_ENV="hello world" busybox:latest

使用—env或者缩写-e,可以用于注入任何环境变量

Docker 提供重启策略,来控制容器退出时的自动重启行为。要为容器配置重启策略,需要在docker run 命令使用—restart标志, —restart标志值可以使用以下值:

描述
no不自动重启容器(默认值)
on-failure容器由于错误退出也即非0退出时,自动重启容器
always不管退出状态码是什么始终重启容器,docker daemon将无限次数地重启容器。容器也会在daemon启动时尝试重启,不管容器当时的状态如何。
unless-stopped同always相似,不管退出状态码是什么始终重启容器,不过当daemon启动时,如果容器之前已经为停止状态,不会尝试启动它。
Terminal window
docker run -d --restart unless-stopped redis