Luo Hao

Docker——常见场景

rehoni / 2022-04-11


《Docker-从入门到实践》

1、MySQL

docker search mysql
docker pull mysql

# 进入shell,查看mysql版本信息
docker run -it mysql /bin/bash
mysql --help | grep Distrib
mysql --version

# 后台启动,可以使用-v 挂载目录,比如/data/mysql/logs:/logs
docker run -p 3306:3306 --name mysql_test -e MYSQL_ROOT_PASSWORD=123456 -d mysql
# 查看端口映射
docker port mysql_test
# 进入运行的MySQL容器内部
docker exec -it mysql_test /bin/bash

2、mongodb

# 运行,-v 为设置容器的挂载目录,这里是将本机的“/data/mongo”目录挂载到容器中的/data/db中,作为 mongodb 的存储目录
docker run -p 27017:27017 -v ~/docker/mongodb:/data/db --name mongodb_test -d mongo

# 进入运行的mongodb容器内部
docker exec -it mongodb_test  mongo
# 连接数据库(此时不需要用户就可以连接),创建用户
db.createUser({
    user: 'root',pwd:'123456',
    roles:[ { role: "userAdminAnyDatabase", db: "admin" } ]
});d

#创建完用户我们就要重新启动mongo服务,并且指定auth
#删除已经运行的mongo容器:
docker rm -f mongodb_test

#指定验证启动mongo容器:
docker run -p 27017:27017 -v ~/docker/mongodb:/data/db --name mongodb_test -d mongo --auth

#连接数据库(需要用户名密码,即需要auth才能操作)

3、powerjob

docker run -d \
              --restart=always \
       --name powerjob-server \
       -p 7700:7700 -p 10086:10086 \
       --net=host \
       -e TZ="Asia/Shanghai" \
       -e JVMOPTIONS="" \
       -e PARAMS="--spring.profiles.active=product --spring.datasource.core.jdbc-url=jdbc:mysql://127.0.0.1:3306/powerjob-product?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true&useSSL=false --spring.datasource.core.username=root --spring.datasource.core.password=123456 --spring.data.mongodb.uri=mongodb://127.0.0.1:27017/powerjob-product" \
       -v ~/docker/powerjob-server:/root/powerjob/server -v ~/.m2:/root/.m2 \
       tjqq/powerjob-server:latest

4、从容器中拷贝文件到宿主机中

先上语法:

docker cp [OPTIONS] [CONTAINER_ID]:[SRC_PATH] [DEST_PATH]

语法是这么个写法,在实际的操作中,在写容器内的路径的时候并不能自动补全,所以实际上还需要还要先进入到容器才行。

1.在服务器上用有权限的用户,执行 docker ps 查看全部容器。

2.复制id对应容器的id,并执行 docker exec -it [容器id] /bin/bash 进入容器

3.假设我要复制的是common.log文件,那么我进入容器后就用find ./ -name “common.log"命令找到那个文件所在目录,假设查找结果是 ./mwbase/applogs/rtlog/OLS/common.log,执行exit退出docker容器

4.退出容器后,我希望复制到宿主机的/home/rhlog目录下重命名为yyy.log,那么最后的命令就是:

docker cp 容器id:容器内文件路径 目标路径
#示例
docker cp 6741xxxxxxxx:/xxxx/xxx/xxx/xxxx/common.log /home/rhlog/yyy.log  #注意没有"."

执行结果可以看到/home/rhlog目录拷贝得到了yyy.log,这样文件就拷贝出来辣。

5、linux服务器离线二进制安装docker

安装包下载地址 https://download.docker.com/linux/static/stable/x86_64/

简易安装Docker,且普通用户可以访问docker

解压docker的安装包,并将文件夹内所有可执行程序放置到**/usr/bin**

创建docker组,并将普通用户加入到docker组内

groupadd docker
usermod -aG docker ems

启动docker

nohup dockerd >/dev/null &

普通用户执行docker命令,查看输出

如果执行失败,将docker相关可执行文件权限修改至777,但这一操作会存在安全风险,慎用

当然也可以使用systemd管理

cp docker-18.03.1-ce/* /usr/local/bin/
cat >/usr/lib/systemd/system/docker.service <<EOF
[Unit]
Description=Docker Application Container Engine
Documentation=http://docs.docker.io
[Service]
Environment="PATH=/usr/local/bin:/bin:/sbin:/usr/bin:/usr/sbin"
EnvironmentFile=-/run/flannel/docker
ExecStart=/usr/local/bin/dockerd --log-level=error
ExecReload=/bin/kill -s HUP $MAINPID
Restart=on-failure
RestartSec=5
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
Delegate=yes
KillMode=process
[Install]
WantedBy=multi-user.target
EOF

6、docker导入导出

image导入导出

# 镜像保存
docker save [image-id or image name] > specific_image.tar
# example
docker save apsara_sdk:latest > apsara_sdk.tar

# 镜像导入
docker load < apsara_sdk.tar
# 因为镜像的大小比较大,(如果从二区直接透过隔离装置传输会传不成功,所以)需要将tar 文件进行切分,按照以下的步骤
# 先将 apsara_sdk.tar 文件进行压缩
tar czvf apsara_sdk.tar.gz apsara_sdk.tar
# 将文件 apsara_sdk.tar.gz 进行拆分 
split -b 10M -d -a 1

7、普通用户允许使用docker

创建docker组并将用户加入docker组,将docker相关的可执行文件权限改成755,重启docker

groupadd docker
gpasswd -a ems docker
cd /usr/bin && chmod 755 docker*
systemctl restart docker

8、容器时区不一致

date -R                          //查看linux主机时间和时区
date exec [container] date -R    // 查看容器时间和时区

img

2者的时间差了8个小时

解决方案

1、利用Dockerfile创建镜像时。在Dockerfile中加入

ENV TIME_ZONE=Asia/Shanghai 
RUN ln -snf /usr/share/zoneinfo/$TIME_ZONE /etc/localtime && echo $TIME_ZONE > /etc/timezone

2、容器创建时。加入时区挂载选项:-v /etc/localtime:/etc/localtime。实例:

docker run -d -p 6379:6379 -v /etc/localtime:/etc/localtime --name test-redis redis

img

3、容器已启动时。

docker exec -it container /bin/bash // 进入交互模式,container为容器ID或名称,下同
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
docker restart container // 重启容器
docker exec container date -R // 查看时区

img

9、centos在线安装docker

Docker安装

### CentOS8 默认是会读取centos.org的mirrorlist的,所以一般来说是不需要配置镜像的。
### (Refer to: https://www.linuxidc.com/Linux/2019-10/161212.htm)

# step 1: 安装必要的一些系统工具
sudo yum install -y yum-utils device-mapper-persistent-data lvm2

# step 2: 更新 container.io 包, 否则可能会报 `package docker-ce-3:19.03.13-3.el7.x86_64 requires containerd.io >= 1.2.2-3, ...`的错
# 可在 https://mirrors.aliyun.com/docker-ce/linux/centos/8/x86_64/stable/Packages/ 下找最新版安装
sudo dnf install -y --allowerasing https://mirrors.aliyun.com/docker-ce/linux/centos/8/x86_64/stable/Packages/containerd.io-1.3.7-3.1.el8.x86_64.rpm

# Step 3: 安装Docker-CE
sudo yum install -y docker-ce

# Step 4: 开启Docker服务并设置开机自启
sudo systemctl start docker && sudo systemctl enable docker

# 测试, 如输出下图结果则安装成功
docker version

Docker-compose 安装

# 方法一 (Refer to: https://docs.docker.com/compose/install/)
sudo curl -L "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

sudo chmod +x /usr/local/bin/docker-compose

# 方法二 (Refer to: https://docs.docker.com/compose/install/#install-using-pip)
sudo pip3 install docker-compose

# 测试, 如输出下图结果则安装成功
docker-compose --version
# 输出:docker-compose version 1.27.4, build xxx

修改docker镜像源

docker中国 https://registry.docker-cn.com

网易 http://hub-mirror.c.163.com

中科大 https://docker.mirrors.ustc.edu.cn

sudo vim /etc/docker/daemon.json

{
  "registry-mirrors": ["https://docker.mirrors.ustc.edu.cn"]
}

sudo systemctl daemon-reload
sudo service docker restart
# docker search nginx
# 查看配置的源
docker info|grep Mirrors -A 1

docker在centos7上daemon启动失败的一个解决方案

SELinux is not supported with the overlay graph driver

image-20201231100214991

10、win10启动docker

问题

这次出现这个问题的原因是给电脑上安装了安卓模拟器导致了冲突,后卸载后docker仍不可用,故再排查一次。

An Error occurred.

windows 10 docker cannot enable hyper-v service

1、systeminfo命令

在命令行中执行systeminfo,如果所有列出的Hyper-V要求的值都为Yes,则系统可以运行Hyper-V。

Hyper-V要求:    虚拟机监视器模式扩展:是
                固件中已启用虚拟化:是
                二级地址转换:是
                执行数据保护可用:是

同样需要四项均为“”才符合运行Hyper-V虚拟机的要求

2、启用或关闭Windows功能

image-20201203142557473

3、bios设置

CPU Configuration -> Intel Virtualization Technology,将次设置项修改为enabled

如果已经是enabled状态,可以考虑开关一次此设置,再F10保存重启。

11、docker启动code-server

docker run -it --name code-server -p 127.0.0.1:8080:8080 \
  -v "$HOME/.config:/home/coder/.config" \
  -v "$PWD:/home/coder/project" \
  -u "$(id -u):$(id -g)" \
  -e "DOCKER_USER=$USER" \
  codercom/code-server:latest

12、rabbitmq

13、报错ERROR: Failed to Setup IP tables: Unable to enable SKIP DNAT rule

执行docker-compose up -d时出现ERROR: Failed to Setup IP tables: Unable to enable SKIP DNAT rule

原因是因为防火墙关闭之后需要重启docker服务。

执行:

service docker restart

即可。

14、docker开启允许远程访问

vi /usr/lib/systemd/system/docker.service
# 添加
-H tcp://0.0.0.0:2375 

systemctl daemon-reload    
service docker restart 

15、postgre

docker run --name some-postgres -p 15432:5432 -e POSTGRES_PASSWORD=mysecretpassword -d postgres

16、docker网络排查

  1. 修改ip会对docker网络造成影响吗?

    修改 IP 地址可能会对 Docker 网络造成影响,具体取决于修改的方式和网络配置。 如果你修改了 Docker 主机的 IP 地址,那么 Docker 容器的网络配置也可能会受到影响。例如,如果 Docker 容器使用了主机的网络,那么容器的 IP 地址也会随之改变。 如果你修改了 Docker 容器的 IP 地址,那么容器的网络配置也会受到影响。例如,如果容器使用了固定的 IP 地址,那么修改容器的 IP 地址可能会导致容器无法连接到网络。 因此,在修改 IP 地址之前,建议你先备份网络配置,并确保你了解修改 IP 地址可能会对网络造成的影响。如果你不确定如何修改 IP 地址,最好先咨询系统管理员或查阅相关文档。

  2. 创建容器 nrec_vsftpd_implicit_ssl WARNING: IPv4 forwarding is disabled. Networking will not work.

    这段信息表示警告:IPv4 转发已禁用,网络将无法正常工作。 在 Docker 中,如果 IPv4 转发被禁用,那么容器将无法访问外部网络,也无法被外部网络访问。这可能会导致容器中的应用程序无法正常工作。 要解决这个问题,你可以在 Docker 主机上启用 IPv4 转发。在 Linux 系统中,可以通过编辑 /etc/sysctl.conf 文件来启用 IPv4 转发,添加以下内容: bash net.ipv4.ip_forward = 1 然后,使用 sysctl -p 命令使更改生效: bash sysctl -p 这样,IPv4 转发就被启用了,容器中的应用程序应该能够正常访问外部网络和被外部网络访问。 需要注意的是,启用 IPv4 转发可能会带来一些安全风险,因此在生产环境中使用时需要谨慎考虑。如果你不确定如何处理这些安全风险,最好先咨询系统管理员或查阅相关文档。

  3. /etc/sysctl.conf 这个文件是配置什么的?

    /etc/sysctl.conf 是一个系统配置文件,用于配置系统参数和内核选项。它包含了一些系统内核参数的设置,这些参数可以影响系统的性能、安全性和功能。

    sysctl.conf 文件中,你可以设置各种系统参数,例如网络设置、内存管理、文件系统、系统日志等。这些参数的设置可以通过编辑 sysctl.conf 文件来完成,也可以通过命令行工具 sysctl 来进行动态设置。

    需要注意的是,修改 sysctl.conf 文件可能会对系统造成潜在的风险,因此在进行任何更改之前,建议你先备份系统配置,并谨慎操作。如果你不确定如何修改系统参数,最好先咨询系统管理员或查阅相关文档。

17、docker的ftps相关

docker run -d -v /users/ems/websophic/files/ftp:/home/vsftpd -p 10012:21 -p 30000-30020:30000-30020 -e FTP_USER=ems -e FTP_PASS=Nems-9700 -e PASV_ADDRESS=198.124.0.200 -e PASV_MIN_PORT=30000 -e PASV_MAX_PORT=30020 -e REVERSE_LOOKUP_ENABLE=NO -e LOCAL_UMASK=000 -e FILE_OPEN_MODE=0666 --name nrec_vsftpd_implicit_ssl --restart=always nrec_vsftpd:implicit_ssl

vsftpd镜像会把对应的服务器文件夹权限改写成ftp/ftp,相当于这个镜像创建了个新的用户

可以在启动时增加了 file_open_mode和local_umask,可以给其他用户也带上这个访问权限的来着

FILE_OPEN_MODE的0666和0777的区别

FILE_OPEN_MODE 的值为 06660777 时的区别在于它们对文件权限的设置不同。 在 Unix 系统中,文件的权限由三个数字组成,分别表示所有者、组和其他用户的读、写和执行权限。这些数字用二进制表示,分别为 4(读)、2(写)和 1(执行)。例如,0666 表示所有者和组用户具有读写权限,其他用户具有读权限;而 0777 表示所有者具有读写执行权限,组用户和其他用户具有读写执行权限。 因此,当 FILE_OPEN_MODE 的值为 0666 时,打开的文件将具有以下权限: - 所有者:读(4)、写(2)、执行(1) - 组用户:读(4)、写(2)、执行(1) - 其他用户:读(4)、写(2) 而当 FILE_OPEN_MODE 的值为 0777 时,打开的文件将具有以下权限: - 所有者:读(4)、写(2)、执行(1) - 组用户:读(4)、写(2)、执行(1) - 其他用户:读(4)、写(2)、执行(1) 请注意,具体的文件权限可能会受到系统的 umask 设置和文件的默认权限的影响。

local_unmask 的000和011 的区别:

local_unmask 的值为 000011 时的区别在于它们对文件权限的掩码设置不同。 在 Unix 系统中,文件的权限由三个数字组成,分别表示所有者、组和其他用户的读、写和执行权限。这些数字用二进制表示,分别为 4(读)、2(写)和 1(执行)。例如,权限为 rwxr-xr-x 的文件可以表示为 755local_unmask 是一个八进制数字,用于设置文件权限掩码。它用于确定文件创建时的默认权限。当 local_unmask 的值为 000 时,表示文件的默认权限不受限制,即完全开放。当 local_unmask 的值为 011 时,表示文件的默认权限受到限制,只有所有者和组可以读写,其他用户只能读取。 因此,当 local_unmask 的值为 000 时,文件创建时的默认权限为 777(完全开放);当 local_unmask 的值为 011 时,文件创建时的默认权限为 750(所有者和组可以读写,其他用户只能读取)。 需要注意的是,local_unmask 的值仅在文件创建时生效,对于已存在的文件,它不会改变文件的权限。此外,它只影响当前用户创建的文件的默认权限,而不会影响其他用户或系统文件的权限。