一、Docker概述
docker是一种轻量级应用容器引擎,可以将应用与具体操作系统的联系剥离出来,并且可以将不同应用容器相互隔离,能够在保证效率的前提下降低应用之间的相互影响。其设计可以与虚拟机进行类比,但比虚拟机更轻量。由于docker容器具有独立完整的运行环境,可以实现“打包一次,到处运行”(类似上世纪90年代,java的口号“write once, run anywhere”),而且十分轻量,十分适合应用的开发部属,是互联网APP开发的首选。在docker的基础上,还衍生了 Kubernetes(K8S,底层支持不仅是docker)、dockerSwap(docker公司亲儿子)等集群化管理工具,容器化时代已经来临。
1.1 Docker安装
## 安装依赖
yum install -y yum-utils device-mapper-persistent-data lvm2
## 设置仓库
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
## 安装docker
yum install docker-ce docker-ce-cli containerd.io
## 开机启动
systemctl start docker
systemctl enable docker
## 测试安装
docker version
docker run hello-world
## 官方脚本一键安装
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
ubuntu安装参见https://www.runoob.com/docker/ubuntu-docker-install.html
nvidia-docker 安装参见英伟达官网
1.2 基本命令
docker类似于一个独立于操作系统的虚拟机,因此它的操作基本命令都是docker
命令的子命令。
1.2.1 pull
docker pull [options] NAME[:TAG]
docker的应用容器建立基础是docker应用镜像。镜像除了可以自己构建外,已经有很多镜像被制作好放到指定仓库中。pull命令的作用在于从远程仓库中下载镜像到docker中。
- options 一些命令参数选项,通过docker pull —help查看
- :TAG 用于指定镜像版本,默认是latest。
- NAME 镜像名称
下例就是获取网易仓库提供的Tomcat镜像。
docker pull hub.c.163.com/library/tomcat:latest
常见docker镜像仓库
1.2.2 images
docker images [options] [REPOSITORY[:TAG]]
获取docker中已安装的镜像,可以列举全部镜像也可以指定镜像名称。
1.2.3 run
docker run [options] IMAGE[:TAG] [COMMAND] [ARG..]
- IMAGE 镜像名称
- COMMAND 运行起来的时候要执行什么命令.
- options 运行参数选项
- -p 端口映射,将系统端口与docker端口建立映射关系,如 -p 8867:8867
- -v 文件夹映射,将主机文件与docker文件建立映射关系,如 -v /public/home/zhanghn:/home,前者为主机,后者为容器
- -d 后台运行,此时不会看到输出日志在控制台
- —network 用于指定网络,常指定为host,使用主机网络
- —name 用于指定容器名称,不指定时名称随机,不便于管理
从镜像创建新的容器并运行。
例如创建Ubuntu-vscode的新容器,容器内home文件夹与主机文件夹zhanghn对应,以免相互拷贝文件的麻烦。vscode镜像的base镜像是centos镜像。
docker run -d -p 8867:8067 -v /public/home/zhanghn:/home/zhanghn -v /public/packages:/home/packages --name zhanghn ubuntu-vscode:v3.22.1
docker run -d -p PORT:8067 -v /public/home/USERNAME:/home/USERNAME -v /public/packages:/home/packages —name USERNAME ubuntu-vscode:v3.22.2 —user-data-dir /home/USERNAME/.vscode-server —extensions-dir /home/USERNAME/.local/share/code-server/extensions —config /home/USERNAME/.config/code-server/key.yaml && chmod 666 /home/USERNAME/.config/code-server/key.yaml
容器中可以通过ssh连接外部,但是好像无法直接从外部ssh到容器中。
1.2.3 build
docker build [OPTIONS] PATH | URL |
自定义镜像制作的命令,需要事先撰写Dockerfile
,道理类似于CMakeLists.txt
和Makefiles
,为固定文件名。
- OPTIONS 构建选项,如-t可以为构建镜像命名和版本
- PATH|URL Dockerfile所在目录或者URL
1.2.4 ps
docker ps
类似于linux命令ps,列举当前运行的或结束的容器进程。
1.2.5 rmi
docker rmi
移除镜像。
1.2.6 rm
docker rm
移除容器。常用组合命令产生已经退出的容器
docker rm `docker ps -a|grep Exited|awk '{print $1}'`
1.2.7 kill
docker kill ID
类似于linux的kill,终止一个容器进程。
1.2.8 start
docker start ID/NAME
不同于run,start用于启动已经创建的容器。
1.2.9 rename
docker rename OLD NEW
对容器进行重命名。
1.2.10 system
docker system prune --volumes -a
清除没用的,悬空的镜像
1.2.11 exec
docker exec -it VSCODE-zhanghn bash
exec命令用于已创建的容器,执行特定的命令,-it选项使得其以终端形式运行。exec命令不受dockerfile的ENTRYPOINT影响。方便以终端形式使用容器。
1.2.12 container
docker container <cmd>
这是docker容器的系列操作命令集
docker container inspect <CONTAINER ID>
查看docker容器配置信息docker container update <CONTAINER ID> <OPTION>
追加或更新docker容器配置参数,但不是全部都可以docker container update VSCODE-zhanghn --restart=always
就能修改restart参数
1.2.13 save
docker save -o <*.tar> <Image>
该命令能够将docker镜像保存,便于docker镜像迁移而不必发布到dockerhub上。与docker load
对应。
1.2.14 load
docker load -i <*.tar>
将save保存的镜像导入,一般用于镜像迁移。
1.2.15 tag
docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
该命令给已有的本地镜像打新标签。常见场景是给latest
标签的镜像同时起一个别的版本标签方便版本控制。
1.2.16 push
docker push docker push [OPTIONS] NAME[:TAG]
该命令用于将本地镜像发布到镜像仓库,例如默认的dockerhub。
二、Dockerfile
2.1 常见指令
FROM
这是所有非基础镜像都有的指令,而且必须在首行。代表对应的base镜像。可以类比类的集成。
COPY
这是将主机文件拷贝至容器内的指令
ADD
与COPY类似,推荐用COPY。对于tar.gz这种,会将其解压。
ENV
设置容器内环境变量
RUN
在执行docker build
时使用,执行相应的bash命令
ENTRYPOINT
在运行容器时使用,类似于C++的main函数,会执行bash命令。注意的是,指令启动的进程是docker容器的1号进程,类似于Linux的1号进程,必须是持续运行的进程。该进程的终结意味着docker容器的终结。可以使用&&
进行多条语句,但最后一句必须是持续运行的进程。
CMD
在运行容器时使用,与ENTRYPOINT类似。会被ENTRYPOINT覆盖。可以再build时从命令行接收参数并将内容传给ENTRYPOINT作为参数。因此可以用CMD写不定参。
WORKDIR
设定build时当前工作目录,指的是镜像内目录而非主机目录
三、注意
docker容器启动时以非交互形式进入的bash,因此环境变量等配置只能在~/.bashrc中。
docker容器创建后,可以在相应目录下修改配置参数https://blog.csdn.net/wesleyflagon/article/details/78961990
docker容器默认存储目录修改可以在
/etc/docker/daemon.conf
中配置graph参数,也可以在/lib/systemd/system/docker.service
中配置无法使用远程挂载目录作为docker目录,会报错。
ExecStart=/usr/bin/dockerd —graph=/home/docker
四、docker容器参数修改
这里针对的是已经启动的容器,对于新建容器,只需要在run时增加参数即可。一般性操作在于关闭docker服务,并在对应的docker容器目录下·<dockerRootDir>/containers/<ID>/
修改hostconfig.json
和config.v2.json
。并重启docker。两个配置文件一个针对的是宿主机(host),一个针对的容器自己,配置时需要同步信息。
4.1 追加TCP端口映射
修改hostconfig.json
,增加TCP端口绑定。其中key值为docker容器内端口,HostPort为宿主机端口。
“PortBindings”:{
“8067/tcp”:[{“HostIp”:””,”HostPort”:”8067”}],
“8080/tcp”:[{“HostIp”:””,”HostPort”:”28080”}]
}
修改config.v2.json
,增加docker端口暴露和端口映射(必须和hostconfig.json对应)。
“ExposedPorts”:{
“8067/tcp”:{},
“8080/tcp”:{}
}
“Ports”:{
“8067/tcp”:[{“HostIp”:”0.0.0.0”,”HostPort”:”8067”}],
“8080/tcp”:[{“HostIp”:”0.0.0.0”,”HostPort”:”28080”}]
}
4.2 追加privilege权限
在创建新docker容器时,--privileged=true
可以授予容器与宿主机root用户一样的权限,方便更改一些系统级变量。虽然docker内root是root用户,但对于宿主机来说,它未获得privilege权限时仍然是普通用户,无法修改一些基于宿主机的系统参数。因此privilege权限实际上是宿主机对容器的授权,其配置是针对宿主机的,因此只需要修改hostconfig.json
。
“Privileged”:true
“SecurityOpt”:[“label=disable”]
“MaskedPaths”:null
“ReadonlyPaths”:null //必须将这些只读路径删除
此时重启后,可以再容器中修改配置sysctl.conf
,甚至可以在docker容器中启动docker。
fs.inotify.max_user_watches=524288 //例如在sysctl.conf中设定最大文件监视
sysctl -p
值得注意的是,上述系统变量修改不会持久化保存在docker容器中,重启docker容器需要重新执行sysctl -p
。
4.3 追加自动重启
在创建新docker容器时,--restart=always
可以让容器随着docker服务一起启动,剂自动重启。对于已经有的容器,有两种方法可以实现追加。
update命令
docker container update <CONTAINER ID> --restart=always
这个命令前面已经提到过
修改hostconfig.json中RestartPolicy
“RestartPolicy”:{“Name”:”no”,”MaximumRetryCount”:0} # 修改前
“RestartPolicy”:{“Name”:”always”,”MaximumRetryCount”:0} # 修改后
4.4 开放docker远程服务
在/lib/systemd/system/docker.service
修改如下配置,增加unix和tcp配置。此外可以通过其他配置方法,但多种配置混合会造成冲突而启动失败,故建议统一在dcoker.service中修改。
# for containers run by docker
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2375
而远端可以通过docker -H <ip:port>
形式或修改环境变量。2375是默认docker服务端口,可以省略。
docker -H 172.16.10.210 images 所列为远程
export DOCKER_HOST=172.16.10.210:2375
docker images ## 所列为远程服务器docker内容
export DOCKER_HOST=
docker images ## 本地
4.5 修改Docker Root目录
默认情况下,docker的根目录是/var/lib/docker
,这里面包含所有镜像和容器等内容。但一般var目录是较小的,不适合生产环境大规模部署。可以通过修改graph参数调整路径,可以有以下两种修改策略。
//查看当前docker root目录
# docker info|grep -i "docker root dir"
Docker Root Dir: /var/lib/docker
//修改/etc/docker/daemon.json,添加"graph":"/docker/docker"
# vim /etc/docker/daemon.json
# systemctl stop docker
# systemctl daemon-reload
# systemctl start docker
//修改/lib/systemd/system/docker.service,在dockerd启动参数中追加 --graph=/docker/docker
# vim /lib/systemd/system/docker.service
五、自建Docker私有仓库
基于register镜像的建立
docker官方提供了一个register镜像,只要拉取并暴露5000端口即建立。1
2docker pull register
docker run -d -p 5000:5000 --restart always --name registry registry
然后可以看到http://<host>:5000/v2/_catalog/
能被正常访问。此时可以通过设置tag并push到私有仓库1
2docker tag <Image>[:tag] <host>:5000/<Target_Imagename>[:tag]
docker push <host>:5000/<Target_Imagename>[:tag]
值得注意的是,如果私有仓库不是localhost,那么需要修改/etc/docker/daemon.json
1
2
3{
"insecure-registries": ["<host>:5000"]
}
并重启docker服务1
2sudo systemctl daemon-reload
sudo systemctl restart docker
国内docker镜像加速器
docker hub和pypi等一样在国内速度慢,可以配置国内镜像源,例如阿里云。
阿里云的镜像需要注册登录获取私有连接,
然后修改/etc/docker/daemon.json
。1
2
3
4
5
6
7
8
9sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://****.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker