Docker的介绍及简单使用
一、docker版本管理
1.版本管理
-
Docker 引擎主要有两个版本:企业版(EE)和社区版(CE)
-
每个季度(1-3,4-6,7-9,10-12),企业版和社区版都会发布一个稳定版本(Stable)。社区版本会提供 4 个月的支持,而企业版本会提供 12 个月的支持
-
每个月社区版还会通过 Edge 方式发布月度版
-
从 2017 年第一季度开始,Docker 版本号遵循 YY.MM-xx 格式,类似于 Ubuntu 等项目。例如,2018 年 6 月第一次发布的社区版本为 18.06.0-ce
二、安装
1.配置宿主机网卡转发
## 若未配置,需要执行如下
$ cat <<EOF > /etc/sysctl.d/docker.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward=1
EOF
$ sysctl -p /etc/sysctl.d/docker.conf
2.Yum安装配置docker
## 下载阿里源repo文件
$ curl -o /etc/yum.repos.d/Centos-7.repo http://mirrors.aliyun.com/repo/Centos-7.repo
$ curl -o /etc/yum.repos.d/docker-ce.repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
$ yum clean all && yum makecache
## yum安装
$ yum install docker-ce-20.10.6 -y
## 查看源中可用版本
$ yum list docker-ce --showduplicates | sort -r
## 安装旧版本
##yum install -y docker-ce-18.09.9
## 配置源加速
## https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
mkdir -p /etc/docker
vi /etc/docker/daemon.json
{
"registry-mirrors" : [
"https://8xpk5wnt.mirror.aliyuncs.com"
]
}
## 设置开机自启
systemctl enable docker
systemctl daemon-reload
## 启动docker
systemctl start docker
## 查看docker信息
docker info
## docker-client
which docker
## docker daemon
ps aux |grep docker
## containerd
ps aux|grep containerd
systemctl status containerd
三、docker的使用
3.1 查看镜像列表
$ docker images
3.2 如何获取镜像
(1) 从远程仓库拉取
$ docker pull nginx:alpine
$ docker images
(2) 使用tag命令
$ docker tag nginx:alpine 172.21.51.143:5000/nginx:alpine
$ docker images
(3) 本地构建
$ docker build . -t my-nginx:ubuntu -f Dockerfile
3.3 如何通过镜像启动容器
$ docker run --name my-nginx-alpine -d nginx:alpine
3.4 如何知道容器内部运行了什么程序?
# 进入容器内部,分配一个tty终端
$ docker exec -ti my-nginx-alpine /bin/sh
# ps aux
3.5 docker构建镜像
(1) 创建Dockerfile
# 告诉docker使用哪个基础镜像作为模板,后续命令都以这个镜像为基础
FROM ubuntu
# RUN命令会在上面指定的镜像里执行命令
RUN apt-get update && apt install -y nginx
#告诉docker,启动容器时执行如下命令
CMD ["/usr/sbin/nginx", "-g","daemon off;"]
(2) 构建本地镜像
$ docker build . -t my-nginx:ubuntu -f Dockerfile
3.6 如何访问容器内服务
# 进入容器内部
$ docker exec -ti my-nginx-alpine /bin/sh
# ps aux|grep nginx
# curl localhost:80
3.7 宿主机中如何访问容器服务
# 删掉旧服务,重新启动
$ docker rm -f my-nginx-alpine
$ docker run --name my-nginx-alpine -d -p 8080:80 nginx:alpine
$ curl 172.21.51.143:8080
3.8 docker client如何与daemon通信
# /var/run/docker.sock
$ docker run --name portainer -d -p 9001:9000 -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer
3.9 导出镜像到文件中
$ docker save -o nginx-alpine.tar nginx:alpine
3.10 从文件中加载镜像
$ docker load -i nginx-alpine.tar
3.11 删除镜像
docker rmi nginx:alpine
3.12 查看容器列表
## 查看运行状态的容器列表
$ docker ps
## 查看全部状态的容器列表
$ docker ps -a
3.13 启动容器
## 后台启动
$ docker run --name nginx -d nginx:alpine
## 映射端口,把容器的端口映射到宿主机中,-p <host_port>:<container_port>
$ docker run --name nginx -d -p 8080:80 nginx:alpine
## 资源限制,最大可用内存500M
$ docker run --memory=500m nginx:alpine
3.14 容器数据持久化
## 挂载主机目录
$ docker run --name nginx -d -v /opt:/opt nginx:alpine
$ docker run --name mysql -e MYSQL_ROOT_PASSWORD=123456 -d -v /opt/mysql/:/var/lib/mysql mysql:5.7
3.15 进入容器或者执行容器内的命令
$ docker exec -ti <container_id_or_name> /bin/sh
$ docker exec <container_id_or_name> hostname
3.16 主机与容器之间拷贝数据
## 主机拷贝到容器
$ echo '123'>/tmp/test.txt
$ docker cp /tmp/test.txt nginx:/tmp
$ docker exec -ti nginx cat /tmp/test.txt
123
## 容器拷贝到主机
$ docker cp nginx:/tmp/test.txt ./
3.17 查看容器日志
## 查看全部日志
$ docker logs nginx
## 实时查看最新日志
$ docker logs -f nginx
## 从最新的100条开始查看
$ docker logs --tail=100 -f nginx
3.18 停止或者删除容器
## 停止运行中的容器
$ docker stop nginx
## 启动退出容器
$ docker start nginx
## 删除非运行中状态的容器
$ docker rm nginx
## 删除运行中的容器
$ docker rm -f nginx
3.19 查看容器或者镜像的明细
## 查看容器详细信息,包括容器IP地址等
$ docker inspect nginx
## 查看镜像的明细信息
$ docker inspect nginx:alpine
四、部署docker registery
4.1 部署镜像仓库
https://docs.docker.com/registry/
## 使用docker镜像启动镜像仓库服务
$ docker run -d -p 5000:5000 --restart always --name registry registry:2
## 默认仓库不带认证,若需要认证,参考https://docs.docker.com/registry/deploying/#restricting-access
4.2 推送本地镜像到镜像仓库中
$ docker tag nginx:alpine localhost:5000/nginx:alpine
$ docker push localhost:5000/nginx:alpine
## 查看仓库内元数据
$ curl -X GET http://172.21.51.143:5000/v2/_catalog
$ curl -X GET http://172.21.51.143:5000/v2/nginx/tags/list
## 镜像仓库给外部访问,不能通过localhost,尝试使用内网地址172.21.51.143:5000/nginx:alpine
$ docker tag nginx:alpine 172.21.51.143:5000/nginx:alpine
$ docker push 172.21.51.143:5000/nginx:alpine
The push refers to repository [172.21.51.143:5000/nginx]
Get https://172.21.51.143:5000/v2/: http: server gave HTTP response to HTTPS client
## docker默认不允许向http的仓库地址推送,如何做成https的,参考:https://docs.docker.com/registry/deploying/#run-an-externally-accessible-registry
## 我们没有可信证书机构颁发的证书和域名,自签名证书需要在每个节点中拷贝证书文件,比较麻烦,因此我们通过配置daemon的方式,来跳过证书的验证:
$ cat /etc/docker/daemon.json
{
"registry-mirrors": [
"https://8xpk5wnt.mirror.aliyuncs.com"
],
"insecure-registries": [
"172.21.51.143:5000"
]
}
$ systemctl restart docker
$ docker push 172.21.51.143:5000/nginx:alpine
$ docker images # IMAGE ID相同,等于起别名或者加快捷方式
REPOSITORY TAG IMAGE ID CREATED SIZE
172.21.51.143:5000/nginx alpine 377c0837328f 4 weeks ago
nginx alpine 377c0837328f 4 weeks ago
localhost:5000/nginx alpine 377c0837328f 4 weeks ago
registry 2 708bc6af7e5e 2 months ago
- 挂载已有的数据,重新创建镜像仓库容器
## 解压离线镜像文件
$ tar zxf registry.tar.gz -C /opt
## 删除当前镜像仓库容器
$ docker rm -f registry
## 使用docker镜像启动镜像仓库服务
$ docker run -d -p 5000:5000 --restart always -v /opt/registry:/var/lib/registry --name registry registry:2
五、Dockerfile使用
$ docker build . -t ImageName:ImageTag -f Dockerfile
Dockerfile是一堆指令,在docker build的时候,按照该指令进行操作,最终生成我们期望的镜像
-
FROM 指定基础镜像,必须为第一个命令
格式: FROM <image> FROM <image>:<tag> 示例: FROM mysql:5.7 注意: tag是可选的,如果不使用tag时,会使用latest版本的基础镜像
-
MAINTAINER 镜像维护者的信息
格式: MAINTAINER <name> 示例: MAINTAINER Yongxin Li MAINTAINER inspur_lyx@hotmail.com MAINTAINER Yongxin Li <inspur_lyx@hotmail.com>
-
COPY|ADD 添加本地文件到镜像中
格式: COPY <src>... <dest> 示例: ADD hom* /mydir/ # 添加所有以"hom"开头的文件 ADD test relativeDir/ # 添加 "test" 到 `WORKDIR`/relativeDir/ ADD test /absoluteDir/ # 添加 "test" 到 /absoluteDir/
-
WORKDIR 工作目录
格式: WORKDIR /path/to/workdir 示例: WORKDIR /a (这时工作目录为/a) 注意: 通过WORKDIR设置工作目录后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT、ADD、COPY等命令都会在该目录下执行
-
RUN 构建镜像过程中执行命令
格式: RUN <command> 示例: RUN yum install nginx RUN pip install django RUN mkdir test && rm -rf /var/lib/unusedfiles 注意: RUN指令创建的中间镜像会被缓存,并会在下次构建中使用。如果不想使用这些缓存镜像,可以在构建时指定--no-cache参数,如:docker build --no-cache
-
CMD 构建容器后调用,也就是在容器启动时才进行调用
格式: CMD ["executable","param1","param2"] (执行可执行文件,优先) CMD ["param1","param2"] (设置了ENTRYPOINT,则直接调用ENTRYPOINT添加参数) CMD command param1 param2 (执行shell内部命令) 示例: CMD ["/usr/bin/wc","--help"] CMD ping www.baidu.com 注意: CMD不同于RUN,CMD用于指定在容器启动时所要执行的命令,而RUN用于指定镜像构建时所要执行的命令。
-
ENTRYPOINT 设置容器初始化命令,使其可执行化
格式: ENTRYPOINT ["executable", "param1", "param2"] (可执行文件, 优先) ENTRYPOINT command param1 param2 (shell内部命令) 示例: ENTRYPOINT ["/usr/bin/wc","--help"] 注意: ENTRYPOINT与CMD非常类似,不同的是通过docker run执行的命令不会覆盖ENTRYPOINT,而docker run命令中指定的任何参数,都会被当做参数再次传递给ENTRYPOINT。Dockerfile中只允许有一个ENTRYPOINT命令,多指定时会覆盖前面的设置,而只执行最后的ENTRYPOINT指令
-
ENV
格式: ENV <key> <value> ENV <key>=<value> 示例: ENV myName John ENV myCat=fluffy
-
EXPOSE
格式: EXPOSE <port> [<port>...] 示例: EXPOSE 80 443 EXPOSE 8080 EXPOSE 11211/tcp 11211/udp 注意: EXPOSE并不会让容器的端口访问到主机。要使其可访问,需要在docker run运行容器时通过-p来发布这些端口,或通过-P参数来发布EXPOSE导出的所有端口
六、Docker网络
docker容器是一块具有隔离性的虚拟系统,容器内可以有自己独立的网络空间,
- 多个容器之间是如何实现通信的呢?
- 容器和宿主机之间又是如何实现的通信呢?
- 使用-p参数是怎么实现的端口映射?
** 网络模式 **
我们在使用docker run创建Docker容器时,可以用--net选项指定容器的网络模式,Docker有以下4种网络模式:
-
bridge模式,使用--net=bridge指定,默认设置
-
host模式,使用--net=host指定,容器内部网络空间共享宿主机的空间,效果类似直接在宿主机上启动一个进程,端口信息和宿主机共用
-
container模式,使用--net=container:NAME_or_ID指定
指定容器与特定容器共享网络命名空间
-
none模式,使用--net=none指定
网络模式为空,即仅保留网络命名空间,但是不做任何网络相关的配置(网卡、IP、路由等)