Docker 简单笔记
Created 2021.12.24 by William Yu; Last modified: 2022.07.12-V1.2.6
Contact: windmillyucong@163.com
Copyleft! 2021 William Yu. Some rights reserved.
Docker 简单笔记
Reference
- https://docs.docker.com/
- https://docker.easydoc.net/doc/
- https://docs.docker.com/engine/install/ubuntu/
- https://yeasy.gitbook.io/docker_practice/
- https://yeasy.gitbook.io/docker_practice/
1. Install
- https://docs.docker.com/engine/install/ubuntu/
- https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository
- https://docs.docker.com/compose/install/
1.1 Install docker
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| sudo apt-get update
sudo apt-get install \
ca-certificates \
curl \
gnupg \
lsb-release
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
|
确认是否安装成功
1
| docker run --rm hello-world
|
看到如下输出即可
备注:可能出现的问题
问题1.
1
| W: GPG error: https://apt.dockerproject.org ubuntu-trusty InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY F76221572C52609D
|
1
| curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
|
如果是使用zsh之类的shell可能会出现此问题。 原因:输入的y 不能被正常捕获,然后key不能被正常加载。
检查key文件,检查权限与文件大小
1
2
| $ ls -lh /usr/share/keyrings/docker-archive-keyring.gpg
-rw-r--r-- 1 root root 0 1月 5 12:48 /usr/share/keyrings/docker-archive-keyring.gpg
|
2.7k
1
2
| $ ls -lh /usr/share/keyrings/docker-archive-keyring.gpg
-rw-r--r-- 1 root root 2.7K 1月 5 13:02 /usr/share/keyrings/docker-archive-keyring.gpg
|
问题2.
https://blog.csdn.net/CaoMei_HuaCha/article/details/87544109
1.2 Install Docker compose
1
2
| sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
|
确认是否安装成功
1
| docker-compose --version
|
1.3 权限
1
| sudo usermod -aG docker trifo
|
2. 基本概念
2.1 镜像(Image
)
相当于操作系统安装包
2.2 容器(Container
)
镜像是静态的,容器是镜像运行的实体。相当于安装在计算机上的操作系统
2.3 仓库(Repository
)
- 一个 Docker Registry 中可以包含多个 仓库(
Repository
)
- 每个仓库可以包含多个 标签(
Tag
);每个标签对应一个镜像。
3. 启用 docker
启动docker
1
2
| $ sudo systemctl enable docker
$ sudo systemctl start docker
|
4. 镜像
镜像的相关操作:
获取远程镜像
1
| $ sudo docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]
|
列出所有镜像
列出所有本地镜像
或者从Dockerfile build 镜像。
由镜像创建容器
1
| docker run -ti -d --name <容器名称> <镜像名称:版本>
|
镜像推送
用户可以将自己的镜像推送到 Docker Hub,Docker Hub 是一个由 Docker 公司运行和管理的基于云的存储库。它是一个在线存储库,Docker 镜像可以由其他用户发布和使用。有两种库:公共存储库和私有存储库。如果你是一家公司,你可以在你自己的组织内拥有一个私有存储库,而公共镜像可以被任何人使用。
1
| docker push <REPOSITORY>:<TAG> # 注意:不满足格式要求
|
推送到hub的镜像遵守需要命名规则 <user_name>/<REPOSITORY>:<TAG>
修改镜像的名称
1
| docker tag <REPOSITORY>:<TAG> <user_name>/<REPOSITORY>:<TAG>
|
然后push
1
| docker push <user_name>/<REPOSITORY>:<TAG>
|
镜像导出为文件
1
| docker save -o <file_name>.tar <REPOSITORY>:<TAG>
|
从文件导入镜像
1
| docker load -i <file_name>.tar
|
5. Dockerfile
Dockerfile用于编译镜像。
Dockerfile编写
- 注意dockerfile文件夹下面最好不要有其他东西
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
| FROM ubuntu:latest
LABEL maintainer="zhonger zhonger@live.cn"
# Create a no-passowrd sudo user
RUN apt update \
&& apt install -y sudo \
&& useradd -m ubuntu -s /bin/bash && adduser ubuntu sudo \
&& echo "ubuntu ALL=(ALL) NOPASSWD : ALL" | tee /etc/sudoers.d/nopasswd4sudo
# Adjust Timezone
ENV DEBIAN_FRONTEND=noninteractive
RUN apt install -y tzdata \
&& ln -fs /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
USER ubuntu
WORKDIR /home/ubuntu
# Install zsh
RUN sudo apt install -y git zsh \
&& git clone https://github.com/ohmyzsh/ohmyzsh.git ~/.oh-my-zsh \
&& cp ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc \
&& sed -i "s/robbyrussell/bira/" ~/.zshrc \
&& sudo usermod -s /bin/zsh ubuntu
# Clean apt-cache
RUN sudo apt autoremove -y \
&& sudo apt clean -y \
&& sudo rm -rf /var/lib/apt/lists/*
ENTRYPOINT ["/bin/zsh"]
|
用 Dockerfile build 镜像
编译生成 Docker 镜像
- https://docs.docker.com/engine/reference/commandline/build/
1
| docker build . -t zhonger/ubuntu:latest
|
查看结果
由镜像创建docker 容器
1
| sudo docker run -ti -d --name dev zhonger/ubuntu:latest
|
容器启动
容器执行命令
1
| sudo docker exec -it dev /bin/zsh
|
5. 容器
容器的相关使用操作
- https://yeasy.gitbook.io/docker_practice/container/run
创建容器
并执行终端
1
| docker run -t -i ubuntu:18.04 /bin/bash
|
- -t 参数 让Docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上
- -i 参数 则让容器的标准输入保持打开
run 命令
- https://docs.docker.com/engine/reference/run/
创建一个新的容器并运行一个命令
1
| docker run <各项参数> <镜像> <命令>
|
参数:
- -a stdin: 指定标准输入输出内容类型,可选 STDIN/STDOUT/STDERR 三项;
- -d: 后台运行容器,并返回容器ID;
- -i: 以交互模式运行容器,通常与 -t 同时使用;
- -P: 随机端口映射,容器内部端口随机映射到主机的端口
- -p: 指定端口映射,格式为:主机(宿主)端口:容器端口
- -t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用;
- –name: 为容器指定一个名称;如省略则会 Docker 会自动分配一个名称
- –dns 8.8.8.8: 指定容器使用的DNS服务器,默认和宿主一致;
- –dns-search example.com: 指定容器DNS搜索域名,默认和宿主一致;
- -h “mars”: 指定容器的hostname;
- -e username=”ritchie”: 设置环境变量;
- –env-file=[]: 从指定文件读入环境变量;
- –cpuset=”0-2” or –cpuset=”0,1,2”: 绑定容器到指定CPU运行;
- -m :设置容器使用内存最大值;
- –net=”bridge”: 指定容器的网络连接类型,支持 bridge/host/none/container: 四种类型;
- –link=[]: 添加链接到另一个容器;
- –expose=[]: 开放一个端口或一组端口;
- –volume , -v: 绑定一个卷
启动容器
exec 命令
在容器中直接执行命令
1
| $ docker exec -it <CONTAINER ID>或者<NAMES> <执行的命令>
|
举例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| # 创建容器
$ docker run -dit ubuntu
69d137adef7a8a689cbcb059e94da5489d3cddd240ff675c640c8d96e84fe1f6
# 查看容器
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
69d137adef7a ubuntu:latest "/bin/bash" 18 seconds ago Up 17 seconds zealous_swirles
# exec -i 参数
$ docker exec -i 69d1 bash
ls
bin
boot
dev
...
# exec -it 参数
$ docker exec -it 69d1 /bin/bash
root@69d137adef7a:/#
|
进入容器终端
1
| docker exec -it <CONTAINER ID>或者<NAMES> /bin/bash
|
查看运行中的容器
1
2
3
| docker container ls
或者
docker ps
|
查看所有容器(包含终止状态的容器)
1
2
3
| docker container ls -a
或者
docker ps -a
|
终止运行中的容器
1
| docker container stop <CONTAINER_ID>
|
启动容器
处于终止状态的容器,可以通过命令来重新启动。
1
| docker container start <CONTAINER_ID>
|
终止并重启容器
该命令会将一个运行态的容器终止,然后再重新启动它。
1
| docker container restart <CONTAINER_ID>
|
移除容器
1
| docker rm <CONTAINER_ID>
|
容器向本机传送文件
1
| docker cp container_name_or_id:容器目录 本地目录
|
本地向容器传送文件
1
| docker cp 本地目录 container_name_or_id:容器目录
|
容器打包导出为镜像
打包前也可以将写好的代码放在容器里面,有利于快速部署
1
| docker commit container_name_or_id image_name:image_tag
|
6. 挂载x display 到宿主机
在docker 中使用 x display,将x display挂载到docker容器的宿主机上
1. 宿主机设置
1
2
3
| # 宿主机执行
sudo apt-get install x11-xserver-utils
xhost +
|
2. 创建容器时添加参数
然后创建docker容器时,添加选项:
1
2
3
4
| sudo docker run -it --name monitor \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-e DISPLAY=unix$DISPLAY \
zhonger/ubuntu:latest
|
3. 如果容器已经存在,可以修改参数
我们在已经启动的容器里做了一些事情,这时有了显示图像的需要,但从头新启动一个容器有点麻烦。
-
使用 ifconfig 查看主机和docker的IP地址
例如:主机的IP为 xxx ;docker 的IP为YYY
-
docker 中
1
| export DISPLAY= XXX #把环境变量映射到主机IP
|
- 主机中
1
2
| sudo gedit /etc/lightdm/lightdm.conf
#增加一行 xserver-allow-tcp=true
|
1
2
| sudo systemctl restart lightdm
xhost + #注意加号前应有空格
|
这样配置就完成了,这是第一次配置的操作。
以后每次重新开机时,还是要在主机里运行一下 xhost +,在docker里运行一下export DISPLAY= XXX 。
其实还是挺麻烦的。
最关键的是,这种方式用的是IP地址,在系统没联网时,网卡就没有分配的IP地址了,这种方法就行不通了。
4. 怎样测试能否显示图像界面
- 一个显示时钟的小程序xclock
- 不过我在Ubuntu16.04的环境里搜不到这个了,能安装的叫xarclock,功能一样 。
在docker中运行
1
2
| sudo apt-get install xarclock #安装这个小程序
xarclock #运行,如果配置成功,会显示出一个小钟表动画
|
7. 目录挂载
本地目录到docker容器中
- https://yeasy.gitbook.io/docker_practice/data_management/bind-mounts
- https://docker.easydoc.net/doc/81170005/cCewZWoN/kze7f0ZR
三种挂载方式
- build mount 直接将宿主机的目录映射到容器中
- tmpfs mount 适合存储临时文件,存宿主机内存中。不可多容器共享。
- volume 由容器创建和管理,创建在宿主机,所以删除容器不会丢失,官方推荐,更高效,Linux 文件系统,适合存储数据库数据。可挂到多个容器上
1. volume
-v
1
| docker run -v <本地目的>:<容器目录> <镜像名称,如ubuntu:18.04>
|
- -v 代表挂载目录
- 本地目的和容器目录使用
:
分隔
- 均是绝对路径
- 当容器目录不存在时会自动创建
- 如需挂载多个目录,可以使用多个
-v
来挂载多个目录
2. mount
–mount
1
2
3
4
| docker run -it --name <容器名称> \
# -v /src/webapp:/usr/share/nginx/html \
--mount type=bind,source=/src/webapp,target=/usr/share/nginx/html \
<镜像名称,如ubuntu:18.04>
|
- –mount 参数:
- 以前使用
-v
参数时如果本地目录不存在 Docker 会自动为你创建一个文件夹;
- 而使用
--mount
参数时如果本地目录不存在,Docker 会报错。
- 所以 mount参数更安全。
- source 本地目录
- target 容器目录
权限
- 挂载主机目录的默认权限是
读写
。
- 用户也可以通过增加
readonly
指定为 只读
。容器内无法更改该文件夹
1
2
3
4
5
| docker run -d -P \
--name web \
# -v /src/webapp:/usr/share/nginx/html:ro \
--mount type=bind,source=/src/webapp,target=/usr/share/nginx/html,readonly \
nginx:alpine
|
8. Docker ssh
Dockerfile 中使用私钥
- http://xfyuan.github.io/2020/10/build-docker-with-private-ssh-key/
但是上面的方法只是在Dockerfile中使用密钥,镜像中不在具有使用权限。
Docker 容器中添加密钥
将key复制到docker容器
1
| sudo docker cp ~/.ssh/id_rsa <容器名称>:/home/trifo/.ssh/
|
进入 docker 容器里面
1
2
| # 检查是否已经复制进
ls ~/.ssh
|
然后添加密钥
1
2
| # 报错
Could not open a connection to your authentication agent.
|
添加私钥出错,执行如下命令即可
1
2
3
| $ eval `ssh-agent -s`
Agent pid 322
# 然后再 ssh-add
|
1
2
3
4
| # ssh 使用时如果报错
╭─trifo@e1edb7ac7304 ~/.ssh
╰─ $ ssh 192.168.0.103
Unable to negotiate with 192.168.0.103 port 22: no matching key exchange method found. Their offer: diffie-hellman-group1-sha1
|
可以使用以下参数解决
1
| $ ssh -oKexAlgorithms=+diffie-hellman-group1-sha1 192.168.0.103
|
或者方案二
1
2
3
4
| vim ~/.ssh/config
# 然后填入
Host 192.168.*.*
KexAlgorithms +diffie-hellman-group1-sha1
|
1
2
3
4
5
6
7
| # 如果报错
Offending ECDSA key in /home/c/.ssh/known_hosts:55
remove with:
ssh-keygen -f "/home/c/.ssh/known_hosts" -R "192.168.2.196"
ECDSA host key for 192.168.2.196 has changed and you have requested strict checking.
Host key verification failed.
|
可以使用的解决方案
1
| ssh-keygen -R 192.168.2.196
|
暂略
备注:docker wechat
- https://github.com/top-bettercode/docker-wechat 不能调整字体大小
- https://github.com/Alice-space/docker-wechat 修复字体大小的问题
1
| sudo docker pull alicespace/wechat
|
1
2
3
4
| git clone https://github.com/Alice-space/docker-wechat.git
cd docker-wechat
chmod +x ./local_launch.sh
./local_launch.sh
|