CentOS 安装 Docker CE
卸载旧版本: 旧版本的 Docker 称为 docker 或者 docker-engine ,使用以下命令卸载旧版本
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine
添加yum源
官方源: sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
国内源: sudo yum-config-manager --add-repo https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo
使用 yum 安装依赖包: sudo yum install -y yum-utils device-mapper-persistent-data lvm2
安装 Docker CE:
sudo yum makecache fast
sudo yum install docker-ce
启动 Docker CE:
sudo systemctl enable docker
sudo systemctl start docker
建立 docker 用户组:
默认情况下, docker 命令会使用 Unix socket 与 Docker 引擎通讯。而只有root 用户和 docker 组的用户才可以访问 Docker 引擎的 Unix socket。
出于安全考虑,一般 Linux 系统上不会直接使用 root 用户。因此,更好地做法是将需要使用 docker 的用户加入 docker 用户组
建立 docker 组: sudo groupadd docker
将当前用户加入 docker 组: sudo usermod -aG docker $USER
添加镜像加速器:
国内从 Docker Hub 拉取镜像有时会遇到困难,此时可以配置镜像加速器。国内很多云服务商都提供了国内加速器服务,例如:
Azure 中国镜像 https://dockerhub.azk8s.cn
阿里云加速器(需登录账号获取)
七牛云加速器 https://reg-mirror.qiniu.com
对于使用 systemd 的系统,请在 /etc/docker/daemon.json 中写入如下内容(如果文件不存在请新建该文件)
{
"registry-mirrors": [
"https://dockerhub.azk8s.cn",
"https://reg-mirror.qiniu.com"
]
}
之后重新启动服务:
sudo systemctl daemon-reload
sudo systemctl restart docker
退出当前终端并重新登录,进行如下测试:
测试 Docker 是否安装正确: docker run hello-world
添加内核参数:
如果在 CentOS 使用 Docker CE 看到下面的这些警告信息:
WARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled
请添加内核配置参数以启用这些功能:
sudo tee -a /etc/sysctl.conf <<-EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
然后重新加载 sysctl.conf 即可: sudo sysctl -p
使用 Docker 镜像
获取镜像:
docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]
镜像名称的格式:
Docker 镜像仓库地址:地址的格式一般是 <域名/IP>[:端口号] 。默认地址是 Docker Hub
仓库名:如之前所说,这里的仓库名是两段式名称,即 <用户名>/<软件名> 。对于 Docker Hub,如果不给出用户名,则默认为 library ,也就是官方镜像
比如: docker pull ubuntu:18.04, 上面的命令中没有给出 Docker 镜像仓库地址,因此将会从 Docker Hub 获取镜像。而镜像名称是 ubuntu:18.04 ,因此将会获取官方镜像 library/ubuntu仓库中标签为 18.04 的镜像
运行:
打算启动镜像里面的 bash 并且进行交互式操作的话,可以执行下面的命令
docker run -it --rm ubuntu:18.04 bash
docker run 就是运行容器的命令,
-it :这是两个参数,一个是 -i :交互式操作,一个是 -t 终端
--rm :这个参数是说容器退出后随之将其删除
ubuntu:18.04 :这是指用 ubuntu:18.04 镜像为基础来启动容器
bash :放在镜像名后的是 命令,这里我们希望有个交互式 Shell,因此用的是 bash
列出镜像:
docker image ls
列表包含了 仓库名 、 标签 、 镜像 ID 、 创建时间 以及 所占用的空间
镜像 ID 则是镜像的唯一标识,一个镜像可以对应多个标签
删除镜像:
docker image rm 镜像ID
定制镜像:
使用commit定制(一般用来保存现场使用)
docker commit [选项] <容器ID或容器名> [<仓库名>[:<标签>]]
docker commit \
--author "Tao Wang <twang2218@gmail.com>" \
--message "修改了默认网页" \
webserver \
nginx:v2
--author 是指定修改的作者
--message 则是记录本次修改的内容
使用 Dockerfile 定制镜像:
在一个空白目录中,建立一个文本文件,并命名为 Dockerfile, 内容为
FROM nginx
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
FROM 指定基础镜像: 是必备的指令,并且必须是第一条指令
RUN 执行命令:
RUN 指令是用来执行命令行命令的。由于命令行的强大能力, RUN 指令在定制镜像时是最常用的指令之一。其格式有两种:
shell 格式: RUN <命令>, 就像直接在命令行中输入的命令一样。刚才写的Dockerfile 中的 RUN 指令就是这种格式
exec 格式: RUN ["可执行文件", "参数1", "参数2"] ,这更像是函数调用中的格式
每个RUN命令会构建一层, 所以在用到大量RUN命令的时候最好用 && 将RUN命令连接起来, 这样只会构建出一层
使用 docker build 命令进行镜像构建:
docker build [选项] <上下文路径/URL/->
docker build -t nginx:v3 . # . 表示docker上下文路径, 客户端会将这个路径下的文件打包交给服务端来辅助构建, 所以如果在Dockerfile中不使用 . 而是使用 ../ 或者 /opt之类的, 会失败
Dockerfile 指令详解:
COPY 复制文件:
COPY [--chown=<user>:<group>] <源路径>... <目标路径>
COPY package.json /usr/src/app/
使用 COPY 指令,源文件的各种元数据都会保留。比如读、写、执行权限、文件变更时间等
ADD 更高级的复制文件:
ADD 指令和 COPY 的格式和性质基本一致。但是在 COPY 基础上增加了一些功能。
比如 <源路径> 可以是一个 URL ,这种情况下,Docker 引擎会试图去下载这个链接的文件放到 <目标路径> 去
CMD 容器启动命令:
shell 格式: CMD <命令>
exec 格式: CMD ["可执行文件", "参数1", "参数2"...]
参数列表格式: CMD ["参数1", "参数2"...] 。在指定了 ENTRYPOINT 指令后,用 CMD 指定具体的参数
之前介绍容器的时候曾经说过,Docker 不是虚拟机,容器就是进程。既然是进程,那么在启动容器的时候,需要指定所运行的程序及参数
提到 CMD 就不得不提容器中应用在前台执行和后台执行的问题, Docker 不是虚拟机,容器中的应用都应该以前台执行,
而不是像虚拟机、物理机里面那样,用 systemd 去启动后台服务,容器内没有后台服务的概念.
一些初学者将 CMD 写为:CMD service nginx start, 然后发现容器执行后就立即退出了。甚至在容器内去使用 systemctl 命令结果却发现根本执行不了。
这就是因为没有搞明白前台、后台的概念,没有区分容器和虚拟机的差异,依旧在以传统虚拟机的角度去理解容器
对于容器而言,其启动程序就是容器应用进程,容器就是为了主进程而存在的,主进程退出,容器就失去了存在的意义,从而退出
ENTRYPOINT 入口点:
和CMD有类似作用, 但更强大
场景一:让镜像变成像命令一样使用
场景二:应用运行前的准备工作
ENV 设置环境变量:
ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...
VOLUME 定义匿名卷:
VOLUME ["<路径1>", "<路径2>"...]
VOLUME <路径>
容器运行时应该尽量保持容器存储层不发生写操作,对于数据库类需要保存动态数据的应用,其数据库文件应该保存于卷(volume)中
为了防止运行时用户忘记将动态文件所保存目录挂载为卷,在 Dockerfile 中,我们可以事先指定某些目录挂载为匿名卷,
这样在运行时如果用户不指定挂载,其应用也可以正常运行,不会向容器存储层写入大量数据
EXPOSE 声明端口:
EXPOSE <端口1> [<端口2>...]
EXPOSE 指令是声明运行时容器提供服务端口,这只是一个声明,在运行时并不会因为这个声明应用就会开启这个端口的服务
在 Dockerfile 中写入这样的声明有两个好处,一个是帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射;
另一个用处则是在运行时使用随机端口映射时,也就是 docker run -P时,会自动随机映射 EXPOSE 的端口
WORKDIR 指定工作目录:
WORKDIR <工作目录路径>
使用 WORKDIR 指令可以来指定工作目录(或者称为当前目录),以后各层的当前目录就被改为指定的目录,如该目录不存在, WORKDIR 会帮你建立目录
USER 指定当前用户:
USER <用户名>[:<用户组>]
USER 指令和 WORKDIR 相似,都是改变环境状态并影响以后的层。 WORKDIR是改变工作目录, USER 则是改变之后层的执行 RUN , CMD 以及ENTRYPOINT 这类命令的身份
如果以 root 执行的脚本,在执行期间希望改变身份,比如希望以某个已经建立好的用户来运行某个服务进程,不要使用 su 或者 sudo ,这些都需要比较麻烦的配置,而且在 TTY 缺失的环境下经常出错。建议使用 gosu
操作 Docker 容器:
启动容器:
基于镜像新建一个容器并启动
docker run ubuntu:18.04 /bin/echo 'Hello world'
docker run -d -p 80:80 nginx
docker run -t -i ubuntu:18.04 /bin/bash
-t 选项让Docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上, -i 则让容器的标准输入保持打开
将在终止状态( stopped )的容器重新启动
docker container start
终止状态的容器可以用 docker container ls -a 命令看到
后台运行
通过添加 -d 参数来实现
docker run -d ubuntu:18.04 /bin/echo 'Hello world'
可以通过 docker container ls命令来查看容器信息 (docker ps)
终止容器
docker container stop
重新启动容器
docker container restart
进入容器:
在使用 -d 参数时,容器启动后会进入后台, 某些时候需要进入容器进行操作, ,包括使用 docker attach 命令或 docker exec 命令,推荐大家使用 docker exec 命令
docker exec -it 69d1 bash
导出容器:
docker export 7691a814370e > ubuntu.tar
导入容器快照:
cat ubuntu.tar | docker import - test/ubuntu:v1.0
删除容器:
docker container rm trusting_newton
清理所有处于终止状态的容器:
docker container prune
查看容器信息:
docker inspect web
访问仓库
可以通过 docker search 命令来查找官方仓库中的镜像,并利用 docker pull 命令来将它下载到本地
Docker 数据管理
数据卷(Volumes)
数据卷 是一个可供一个或多个容器使用的特殊目录,它绕过 UFS,可以提供很多有用的特性
数据卷 可以在容器之间共享和重用
对 数据卷 的修改会立马生效
对 数据卷 的更新,不会影响镜像
数据卷 默认会一直存在,即使容器被删除
创建一个数据卷
docker volume create my-vol
查看所有的 数据卷
docker volume ls
查看指定 数据卷 的信息
docker volume inspect my-vol
启动一个挂载数据卷的容器
使用 --mount 标记来将 数据卷 挂载到容器里。在一次 docker run 中可以挂载多个 数据卷
docker run -d -P \
--name web \
--mount source=my-vol,target=/webapp \
training/webapp \
python app.py
删除数据卷
docker volume rm my-vol
挂载主机目录 (Bind mounts)
使用 --mount 标记可以指定挂载一个本地主机的目录到容器中去
docker run -d -P \
--name web \
--mount type=bind,source=/src/webapp,target=/opt/webapp \
training/webapp \
python app.py
上面的命令加载主机的 /src/webapp 目录到容器的 /opt/webapp 目录。
这个功能在进行测试的时候十分方便,比如用户可以放置一些程序到本地目录中,来查看容器是否正常工作。
本地目录的路径必须是绝对路径
Docker 网络管理
映射端口:
当使用 -P 标记时,Docker 会随机映射一个 49000~49900 的端口到内部容器开放的网络端口
-p 则可以指定要映射的端口,并且,在一个指定端口上只可以绑定一个容器。支持的格式有 ip:hostPort:containerPort | ip::containerPort |hostPort:containerPort
映射所有接口地址: hostPort:containerPor
docker run -d -p 5000:5000 training/webapp python app.py # 此时默认会绑定本地所有接口上的所有地址
映射到指定地址的指定端口: ip:hostPort:containerPort
docker run -d -p 127.0.0.1:5000:5000 training/webapp python app.py
映射到指定地址的任意端口: ip::containerPort
docker run -d -p 127.0.0.1::5000 training/webapp python app.py
还可以使用 udp 标记来指定 udp 端口
docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py
-p 标记可以多次使用来绑定多个端口:
docker run -d -p 5000:5000 -p 3000:80 training/webapp python app.py
查看映射端口配置:
使用 docker port 来查看当前映射的端口配置,也可以查看到绑定的地址
docker port webapp 或 docker port webapp 80
容器互联:
对我好像没啥用
04-04