Docker安装
时间:2020/10/31
环境准备
[root@docker ~]# uname -r
3.10.0-514.26.2.el7.x86_64
[root@docker ~]# cat /etc/os-release
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"
安装
帮助文档
# 1、卸载旧的版本
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
# 2、需要的安装包
yum install -y yum-utils
# 3、设置镜像仓库
yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo #默认是国外的
yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo #阿里云地址
# 4、安装docker相关 docker—ce社区 ee企业版
yum install docker-ce docker-ce-cli containerd.io
# 5、启动docker
systemctl start docker
# 6、使用docker version查看是否安装成功
docker version
# 7、hello-world
docker run hello-world
# 8、查看一下下载的这个hello-world镜像
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest bf756fb1ae65 9 months ago 13.3kB
了解:卸载docker
# 1 卸载镜像
yum remove docker-ce docker-ce-cli containerd.io
# 2 删除资源
rm -rf /var/lib/docker #默认工作路径
阿里云镜像加速
配置使用
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://ptjpt45q.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
回顾hello-world流程
底层原理
Docker是怎么工作的?
Docker是一个Client-Server结构的系统,Docker的守护进程运行在主机上,通过Socket从客户端访问!
DockerServer接受到Docker-Client的指令,就会执行这个命令!
Docker为什么比vm快?
1、Docker有着比虚拟机更少的抽象层
2、Docker利用的是宿主机的内核,vm需要是Guest OS
所以说,新建一个容器的时候,docker不需要像虚拟机一样重新加载一个操作系统
Docker的常用命令
帮助命令
docker version #显示docker的版本信息
docker info #显示docker的系统信息,包括镜像的容器的数量
docker 命令 --help #帮助命令
镜像命令
docker images 查看所有本地的主机上的镜像
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest bf756fb1ae65 9 months ago 13.3kB
#解释
REPOSITORY 镜像的仓库源
TAG 镜像的标签
IMAGE ID 镜像的ID
CREATED 镜像的创建时间
SIZE 镜像的大小
#可选项
-a, --all #列出所有的镜像
-q, --quiet #只显示镜像的id
docker search 搜索镜像
docker pull 下载镜像
#指定版本下载
docker pull mysql:5.7
docker rmi 删除镜像
[root@docker ~]# docker rmi -f 镜像ID #删除指定的镜像
[root@docker ~]# docker rmi -f 镜像ID 镜像ID 镜像ID #删除多个指定的镜像
[root@docker ~]# docker rmi -f $(docker images -ap) #删除全部的镜像
容器命令
说明:我们有了镜像才可以创建容器,linux,下载一个centos镜像来测试学习
docker pull centos
新建容器并启动
docker run [可选参数] image
# 参数说明
--name="Name" 容器名字
-d 后台运行
-it 使用交互方式运行,进入容器查看内容
-p 指定容器的端口 -p 8080:8080
-p ip:主机端口:容器端口
-p 主机端口:容器端口 (常用)
# 测试 启动并进入容器
[root@docker ~]# docker run -it centos /bin/bash
退出容器
exit # 直接容器停止并退出
Ctrl+P+Q #容器不停止退出
删除容器
docker rm 容器id # 删除指定容器
docker rm -f $(docker ps -aq) # 删除全部容器
启动和停止容器的操作
docker start 容器id
docker restart 容器id
docker stop 容器id
docker kill 容器id
常用其他命令
后台启动容器
# 命令 docker run -d 镜像名!
[root@docker ~]# docker run -d centos
# 问题 docker ps 发现centos停止了
# 常见的坑,docker容器使用后台运行 就必须要有一个前台进程,docker发现没有应用,就会自动停止
查看日志
docker logs -f -t --tail 容器,没有日志
# 自己编写一段shell脚本
[root@docker ~]# docker run -d centos /bin/bash -c "while true;do echo youkun;sleep 2;done"
# 显示日志
[root@docker ~]# docker logs -ft --tail 10 dcb855c707a6
2020-10-15T06:02:42.249234282Z youkun
2020-10-15T06:02:44.251190786Z youkun
2020-10-15T06:02:46.253108579Z youkun
2020-10-15T06:02:48.254884627Z youkun
2020-10-15T06:02:50.256759949Z youkun
查看容器中进程信息
# 命令 docker top 容器id
[root@docker ~]# docker top dcb855c707a6
UID PID PPID C STIME TTY TIME CMD
root 23691 23659 0 14:00 ? 00:00:00 /bin/bash -c while true;do echo youkun;sleep 2;done
查看镜像的元数据
# 命令
docker inspect 容器id
# 测试
[root@docker ~]# docker inspect dcb855c707a6
[
{
"Id": "dcb855c707a62693bf7efa8043ae3329f83b7535f0786adbed00ac053f49a0fa",
"Created": "2020-10-15T06:00:19.729941413Z",
"Path": "/bin/bash",
"Args": [
"-c",
"while true;do echo youkun;sleep 2;done"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 23691,
"ExitCode": 0,
"Error": "",
"StartedAt": "2020-10-15T06:00:20.118898964Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
进入当前正在运行的容器
# 我们通常容器都是使用后台方式运行的,需要进入容器,修改一些配置
# 命令
docker exec -it 容器id
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dcb855c707a6 centos "/bin/bash -c 'while…" 9 minutes ago Up 9 minutes relaxed_gauss
[root@docker ~]# docker exec -it dcb855c707a6 /bin/bash
# 方式二
docker attach 容器id
# 测试
[root@docker ~]# docker attach dcb855c707a6
youkun
youkun
^Cyoukun
# docker exec #进入容器后开启一个新的终端,可以在里面操作(常用)
# docker attach #进入容器正在执行的终端,不会启动新的进程!
从容器内拷贝文件到主机上
docker cp 容器id:容器内路径 目的的主机路径
# 进入docker容器内部
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3384120b0730 centos "/bin/bash" 17 seconds ago Up 15 seconds strange_lumiere
[root@docker ~]# docker attach 3384120b0730
[root@3384120b0730 /]# cd /home/ && touch youk.txt
[root@3384120b0730 home]# ls
youk.txt
[root@3384120b0730 home]# exit
exit
# 将这个文件拷贝出来到主机上
[root@docker ~]# docker cp 3384120b0730:/home/youk.txt /home/
[root@docker ~]# ls /home/
java.txt youk.txt
[root@docker ~]#
小结
练习:docker安装nginx
# 1、搜索镜像 search
# 2、下载镜像 pull
# 3、运行测试
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest f35646e83998 46 hours ago 133MB
centos latest 0d120b6ccaa8 2 months ago 215MB
# -d 后台运行
# --name 给容器命名
# -p 宿主机端口:容器内部端口
[root@docker ~]# docker run -d --name nginx01 -p 3344:80 nginx
79b03da051c112457a8969af7b813b1c6b332f8b09ea266bc49e5e97776c8abb
[root@docker ~]# dpcker [s
-bash: dpcker: 未找到命令
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
79b03da051c1 nginx "/docker-entrypoint.…" 7 seconds ago Up 6 seconds 0.0.0.0:3344->80/tcp nginx01
[root@docker ~]# curl localhost:3344
# 进入容器
[root@docker ~]# docker exec -it nginx01 /bin/bash
root@79b03da051c1:/# whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
root@79b03da051c1:/# cd /etc/nginx
root@79b03da051c1:/etc/nginx# ls
conf.d koi-utf mime.types nginx.conf uwsgi_params
fastcgi_params koi-win modules scgi_params win-utf
root@79b03da051c1:/etc/nginx#
练习:docker安装tomcat
# 官方的使用
docker run -it --rm tomcat:9.0
#我们之前的启动都是后台,停止了容器之后,容器还是可以查到
#docker run -it --rm,一般用来测试,用完就删除
# 下载并启动
docker pull tomcat
# 启动运行
[root@docker ~]# docker run -d -p 3355:8080 --name tomcat01 tomcat
# 测试可以访问
http://47.111.162.109:3355/
# 进入容器
[root@docker ~]# docker exec -it tomcat01 /bin/bash
可视化
- portainer(先用这个)
[root@docker ~]# docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
- Rancher(CI/CD再用)
什么是portainer?
Docker图形化界面管理工具!提供一个后台面板供我们操作!
访问测试 http://47.111.162.109:8088
Docker镜像讲解
镜像是什么
镜像是一种轻量级,可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。
所有的应用,直接打包docker镜像,就可以直接跑起来!
如何得到镜像:
- 从远处仓库下载
- 朋友拷贝给你
- 自己制作一个镜像DockerFile
Docker镜像加载原理
UnionFS(联合文件系统)
Docker镜像加载原理
分层理解
分层的镜像
我们可以去下载一个镜像,注意观察下载的日志输出,可以看到的是一层一层的在下载。
为什么Docker镜像要采用这种分层的结构呢?
最大的好处,莫过于是资源共享了!比如有多个镜像都从相同的Base镜像构建而来,那么宿主机只需在磁盘上保留一份base镜像,同时内存中野只需要加载一份base镜像,这样就可以为所有的容器服务了,而且镜像的每一层都可以被共享。
查看镜像分层的方式可以通过docker image inspect 命令!
[root@docker ~]# docker image inspect redis:latest
[
{
"Id": "sha256:bd571e6529f32461648680c82e2540f9db4b3bb92709ae5d19dd347531c98f19",
"RepoTags": [
"redis:latest"
],
"RepoDigests": [
"redis@sha256:33ca074e6019b451235735772a9c3e7216f014aae8eb0580d7e94834fe23efb3"
],
"Parent": "",
"Comment": "",
"Created": "2020-10-13T22:07:24.375626298Z",
"Container": "80733509b3e962b415a5a913b000a74cc6f38cc2b240c4a86a83dd1bab898424",
"ContainerConfig": {
"Hostname": "80733509b3e9",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"6379/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"GOSU_VERSION=1.12",
"REDIS_VERSION=6.0.8",
"REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-6.0.8.tar.gz",
"REDIS_DOWNLOAD_SHA=04fa1fddc39bd1aecb6739dd5dd73858a3515b427acd1e2947a66dadce868d68"
],
"Cmd": [
"/bin/sh",
"-c",
"#(nop) ",
"CMD [\"redis-server\"]"
],
"ArgsEscaped": true,
"Image": "sha256:974dcd648a85b0ef1ae78d66080dd7e7cbcf534c343b805242f1173dab60679a",
"Volumes": {
"/data": {}
},
"WorkingDir": "/data",
"Entrypoint": [
"docker-entrypoint.sh"
],
"OnBuild": null,
"Labels": {}
},
"DockerVersion": "18.09.7",
"Author": "",
"Config": {
"Hostname": "",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"6379/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"GOSU_VERSION=1.12",
"REDIS_VERSION=6.0.8",
"REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-6.0.8.tar.gz",
"REDIS_DOWNLOAD_SHA=04fa1fddc39bd1aecb6739dd5dd73858a3515b427acd1e2947a66dadce868d68"
],
"Cmd": [
"redis-server"
],
"ArgsEscaped": true,
"Image": "sha256:974dcd648a85b0ef1ae78d66080dd7e7cbcf534c343b805242f1173dab60679a",
"Volumes": {
"/data": {}
},
"WorkingDir": "/data",
"Entrypoint": [
"docker-entrypoint.sh"
],
"OnBuild": null,
"Labels": null
},
"Architecture": "amd64",
"Os": "linux",
"Size": 104192177,
"VirtualSize": 104192177,
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/2fe2185aeaf18fceb3f8b754141d4feb5bd06507859c55d9c5ef75dbc51d0c29/diff:/var/lib/docker/overlay2/787b98418bf4038f4e7fa56908691a59fabd8445d48adef0309c14cef761bf9e/diff:/var/lib/docker/overlay2/5aadf616f1346991c4e096dd043f8fb134fb1b66edf95a63a6c283086114e506/diff:/var/lib/docker/overlay2/5ac381ac4d57675782f9f04fb240cebf54d3857ba29aabbaaaad566c4b41b5d8/diff:/var/lib/docker/overlay2/70b49643e1a0a36d9321132dbecac5b7725a5f7928bd873c52d0caeaad40177d/diff",
"MergedDir": "/var/lib/docker/overlay2/a8f0d3efeb6f8d36ddd1ff4db649818665198fe444eee2f7d4ebde39adc675e6/merged",
"UpperDir": "/var/lib/docker/overlay2/a8f0d3efeb6f8d36ddd1ff4db649818665198fe444eee2f7d4ebde39adc675e6/diff",
"WorkDir": "/var/lib/docker/overlay2/a8f0d3efeb6f8d36ddd1ff4db649818665198fe444eee2f7d4ebde39adc675e6/work"
},
"Name": "overlay2"
},
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:d0fe97fa8b8cefdffcef1d62b65aba51a6c87b6679628a2b50fc6a7a579f764c",
"sha256:832f21763c8e6b070314e619ebb9ba62f815580da6d0eaec8a1b080bd01575f7",
"sha256:223b15010c47044b6bab9611c7a322e8da7660a8268949e18edde9c6e3ea3700",
"sha256:a1a4c1d0c191cee2ac3912696fe57cf9ad84cbfaf3d13f314061bd89fe73cabb",
"sha256:e9acf707b7fe3eef2f7c6bd127b3b34b262889cb670013adfb46883a49a4ac8e",
"sha256:b854b24feeee6cbd8fc5d6401f5f1b4a3d40c483444e6c4b06a2b7b31f347b40"
]
},
"Metadata": {
"LastTagTime": "0001-01-01T00:00:00Z"
}
}
]
[root@docker ~]#
如何提交一个自己的镜像
commit镜像
docker commit 提交容器成为一个新的副本
#命令和git原理类似
docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]
实战测试
[root@docker ~]# docker commit -a="youkun" -m"add webapps app" 1e18beb1b75f tomcat02:0.1
sha256:011c39409d51bcd5f56d29cc3baff4768910872cedd947d43dff990b7e480391
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat02 0.1 011c39409d51 58 seconds ago 652MB
容器数据卷
什么是容器数据卷
docker的理念回顾
将应用和环境打包成一个镜像!
容器之间可以有一个数据共享的技术!Docker容器中产生的数据,同步到本地!
这就是卷技术,目录的挂载,将我们容器内的目录,挂载在Linux上面!
总结一句话:容器的持久化和同步操作!容器间也是可以数据共享的!
使用数据卷
方式一:直接使用命令来挂载 -v
docker run -it -v 主机目录:容器内目录
# 测试
[root@docker ~]# docker run -it -v /home/ceshi:/home/ centos /bin/bash
# 启动起来时候我们可以通过 docker inspect 容器id
好处:我们以后修改只需要在本地修改就可以,容器内自动同步
shell脚本
# 自动创建配置文件,并运行docker
#!/bin/bash
for port in $(seq 1 6); \
do \
mkdir -p /mydata/redis/node-${port}/conf
touch /mydata/redis/node-${port}/conf/redis.conf
cat << EOF > /mydata/redis/node-${port}/conf/redis.conf
port 6379
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.38.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
docker run -p 637${port}:6379 -p 1637${port}:16379 --name redis-${port} \
-v /mydata/redis/node-${port}/data:/data \
-v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
done
docker run -p 6371:6379 -p 16371:16379 --name redis-1 \
-v /mydata/redis/node-1/data:/data \
-v /mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf