安装docker
-
安装yum
sudo yum install -y yum-utils
-
配置yum的下载地址为阿里云
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
-
下载docker
sudo yum install docker-ce docker-ce-cli containerd.io
-
启动docker
sudo systemctl start docker
docker命令
帮助命令
docker version # 显示docker的版本信息
docker info # 显示docker的系统信息,包括镜像和容器的数量
docker 命令 --help # 帮助命令
镜像命令
docker images
查看所有本地主机上的镜像
[root@AlibabaECS ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest bf756fb1ae65 8 months ago 13.3kB
# 解释
REPOSITORY 镜像的仓库源
TAG 镜像的标签
IMAGE ID 镜像的id
CREATED 镜像的创建时间
# 可选项
-a, --all # 列出所有的镜像
-q, --quiet # 只显示镜像的id
docker search
搜索镜像
[root@AlibabaECS ~]# docker search mysql
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 9911
# 可选项
--filter , -f Filter output based on conditions provided
docker search mysql -f=stars=5000
docker pull
下载镜像
# 下载镜像 docker pull 镜像名[:tag]
[root@AlibabaECS ~]# docker pull mysql
Using default tag: latest # 如果不写tag,默认就是latest
latest: Pulling from library/mysql
bf5952930446: Pull complete # 分层下载,docker image的核心 联合文件系统
8254623a9871: Pull complete
938e3e06dac4: Pull complete
ea28ebf28884: Pull complete
f3cef38785c2: Pull complete
894f9792565a: Pull complete
1d8a57523420: Pull complete
6c676912929f: Pull complete
ff39fdb566b4: Pull complete
fff872988aba: Pull complete
4d34e365ae68: Pull complete
7886ee20621e: Pull complete
Digest: sha256:c358e72e100ab493a0304bda35e6f239db2ec8c9bb836d8a427ac34307d074ed # 签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest # 真实地址
# 两条命令等价
docker pull mysql
docker.io/library/mysql:latest
# 指定版本下载
docker pull mysql:5.7
[root@AlibabaECS ~]# docker pull mysql:5.7
5.7: Pulling from library/mysql
bf5952930446: Already exists
8254623a9871: Already exists
938e3e06dac4: Already exists
ea28ebf28884: Already exists
f3cef38785c2: Already exists
894f9792565a: Already exists
1d8a57523420: Already exists
5f09bf1d31c1: Pull complete
1b6ff254abe7: Pull complete
74310a0bf42d: Pull complete
d398726627fd: Pull complete
Digest: sha256:da58f943b94721d46e87d5de208dc07302a8b13e638cd1d24285d222376d6d84
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7
docker rmi
删除镜像
[root@AlibabaECS ~]# docker rmi -f 容器id # 删除指定的容器
[root@AlibabaECS ~]# docker rmi -f 容器id 容器id 容器id # 删除多个容器
[root@AlibabaECS ~]# docker rmi -f $(docker images -aq) # 删除全部容器
容器命令
docker run
新建容器并启动
docker run [可选参数] image
# 参数说明
--name = "Name" 容器名字 tomcat01,tomcat02,用来区分容器
-d 后台方式运行
-it 使用交互方式运行,进入容器查看区分
-p 指定容器的端口 -p 8080:8080
-p ip:主机端口:容器端口
-p 主机端口:容器端口(常用)
-p 容器端口
容器端口
-p 随机指定端口
# 测试,启动并进入容器
[root@AlibabaECS bin]# docker run -it centos /bin/bash
[root@94d468db18da /]# ls # 查看容器内的centos,基础版本,很多命令都是不完善的!
bin etc lib lost+found mnt proc run srv tmp var
dev home lib64 media opt root sbin sys usr
# 从容器中退回主机
[root@94d468db18da /]# exit
docker ps
列出所有容器
docker ps 命令
# 列出当前正在运行的容器
-a # 列出当前正在运行的容器+带出历史运行过的容器
-n=? # 显示最近创建的容器
-q # 只显示容器的编号
- 退出容器
exit # 直接容器停止并退出
Ctrl + P + Q # 容器不停止退出
docker rm
删除容器
docker rm 容器id # 删除指定容器,不能删除正在运行的容器,如果要强制删除 rm -f
docker rm -f $(docker ps -aq) # 删除所有的容器
docker ps -aq|xargs docker rm # 删除所有的容器
- 启动和停止容器的操作
docker start 容器id # 启动容器
docker restart 容器id # 重启容器
docker stop 容器id # 停止当前正在运行的容器
docker kill 容器id # 强制停止当前容器
常用其他命令
- 后台启动容器
# 命令 docker run -d 镜像名
[root@AlibabaECS /]# docker run -d centos
# 问题docker ps, 发现 centos 停止了
# 常见的坑, docker容器使用后台运行,就必须要有一个前台进程,docker发现没有应用,就会自动停止
# nginx,容器启动后,发现自己没有提供服务,就会立刻停止,就是没有程序了
docker logs
查看日志
docker logs -f -t --tail 容器,没有日志
# 自己编写一段shell脚本
[root@AlibabaECS /]# docker run -d centos /bin/sh -c "while true;do echo kuangshen;sleep 1;done"
# 显示日志
-tf # 显示日志
--tail number # 要显示的日志条数
[root@AlibabaECS /]# docker logs -ft --tail f1178d5b0bd8
docker top
查看容器中的进程信息ps
# 命令 docker top 容器id
[root@AlibabaECS /]# docker top f1178d5b0bd8
UID PID PPID C STIME TTY TIME CMD
root 21626 21609 0 while true;do echo kuangshen;sleep 1;done
root 27492 21626 0 13:15 ? 00:00:00
docker inspect
查看镜像源数据
[root@AlibabaECS /]# docker inspect f1178d5b0bd8
docker exec
进入当前正在运行的容器
# 我们通常都是使用后台方式运行的,需要进入容器,修改一些配置
# 命令
docker exec -it 容器id
# 测试
[root@AlibabaECS ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f1178d5b0bd8 centos "/bin/sh -c 'while t…" 2 hours ago Up 2 hours stupefied_colden
[root@AlibabaECS ~]# docker exec -it f1178d5b0bd8 /bin/bash
[root@f1178d5b0bd8 /]# ls
bin etc lib lost+found mnt proc run srv tmp var
dev home lib64 media opt root sbin sys usr
[root@f1178d5b0bd8 /]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 05:10 ? 00:00:02 /bin/sh -c while true;do echo kuangshen;sleep 1;done
root 8869 0 0 07:38 pts/0 00:00:00 /bin/bash
root 8887 1 0 07:38 ? 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/
root 8888 8869 0 07:38 pts/0 00:00:00 ps -ef
# 方式二
docker attach 容器id
# 测试
[root@AlibabaECS ~]# docker attach f1178d5b0bd8
正在执行当前的代码...
# docker exec # 进入容器后开启一个新的终端,可以在里面操作(常用)
# docker attach # 进入容器正在执行的终端,不会启动新的进程
docker cp
从容器内拷贝到主机上
# 命令
docker cp [r] 容器id :容器内路径 目的地主机路径
# 参数r : 递归拷贝
# 测试
[root@AlibabaECS home]# docker cp a485a9d900b4:/home/test.java /home
docker网络
我们每启动一个docker容器,docker就会给docker容器分配一个ip,我们只要按照了docker,就会有一个docker0桥接模式,使用的技术是veth-pair技术!
我们发现这个容器带来网卡,都是一对对的
veth-pair 就是一对的虚拟设备接口,他们都是成对出现的,一端连着协议,一端彼此相连
正因为有这个特性 veth-pair 充当一个桥梁,连接各种虚拟网络设备的
OpenStac,Docker容器之间的连接,OVS的连接,都是使用evth-pair技术
网络模型图
tomcat01和tomcat02公用一个系统路由器,docker0。
所有的容器不指定网络的情况下,都是docker0路由的,docker会给我们的容器分配一个默认的可用ip。
使用--link完成容器间的连接
- 我们来测试下tomcat01和tomcat02是否可以ping通
# 获取tomcat01的ip 172.17.0.2
$ docker-tomcat docker exec -it tomcat01 ip addr
550: eth0@if551: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
# 让tomcat02 ping tomcat01
$ docker-tomcat docker exec -it tomcat02 ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.098 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.071 ms
# 结论:容器和容器之间是可以互相ping通 但是只能通过ip地址ping通
-
思考一个场景:我们编写了一个微服务,database url=ip: 项目不重启,数据ip换了,我们希望可以处理这个问题,可以通过名字来进行访问容器?
使用--link命令
$ docker exec -it tomcat02 ping tomca01 # ping不通 ping: tomca01: Name or service not known # 运行一个tomcat03 --link tomcat02 $ docker run -d -P --name tomcat03 --link tomcat02 tomcat 5f9331566980a9e92bc54681caaac14e9fc993f14ad13d98534026c08c0a9aef # 3连接2 # 用tomcat03 ping tomcat02 可以ping通 $ docker exec -it tomcat03 ping tomcat02 PING tomcat02 (172.17.0.3) 56(84) bytes of data. 64 bytes from tomcat02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.115 ms 64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.080 ms # 2连接3 # 用tomcat02 ping tomcat03 ping不通
–-link 本质就是在hosts配置中添加映射
现在使用Docker已经不建议使用–link了!
自定义网络,不适用docker0!
docker0问题:不支持容器名连接访问!
自定义网络完成容器间的连接
docker network
connect -- Connect a container to a network
create -- Creates a new network with a name specified by the
disconnect -- Disconnects a container from a network
inspect -- Displays detailed information on a network
ls -- Lists all the networks created by the user
prune -- Remove all unused networks
rm -- Deletes one or more networks
网络模式
bridge :桥接 docker(默认,自己创建也是用bridge模式)
none :不配置网络,一般不用
host :和所主机共享网络
container :容器网络连通(用得少!局限很大)
# 我们直接启动的命令 --net bridge,而这个就是我们得docker0
# bridge就是docker0
$ docker run -d -P --name tomcat01 tomcat
等价于 => docker run -d -P --name tomcat01 --net bridge tomcat
# docker0,特点:默认,域名不能访问。 --link可以打通连接,但是很麻烦!
# 我们可以 自定义一个网络
$ docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
使用例子
安装MySQL
# 获取镜像
[root@AlibabaECS home]# docker pull mysql:5.7
# 运行容器,需要做数据挂载! # 安装启动mysql, 需要配置密码的,这是要注意的点!
# 参考官网hub
docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
# 启动我们的
-d 后台运行
-p 端口映射
-v 卷挂载
-e 环境配置
--name 容器名字
[root@AlibabaECS home]# docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
# 启动成功之后,我们使用本地Navicat连接测试
# 在本地测试创建一个数据库,查看一下我们映射的路径是否ok!
安装nginx
编写nginx配置文件
server {
listen 8080;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
docker run -it -d --name nginx #名称
-p 8080:8080 # 端口映射
-v /usr/yzy/dist:/usr/share/nginx/html # 挂载资源路径
-v /usr/yzy/nginx/nginx.conf:/etc/nginx/nginx.conf #挂载主配置文件
# 挂载默认配置文件,反向代理就是从这个配置文件中配置 不配置这个启不起来
-v /usr/yzy/nginx/nginx.conf:/etc/nginx/conf.d/default.conf
-v /usr/yzy/logs:/var/log/nginx nginx # 挂载日志文件
docker run -d --name nginx
-p 8080:8080
-v /usr/yzy/dist:/usr/share/nginx/html
-v /usr/yzy/nginx/nginx.conf:/etc/nginx/conf.d/default.conf
-v /usr/yzy/logs:/var/log/nginx nginx
部署redis集群
# 创建网卡
docker network create redis --subnet 172.38.0.0/16
# 通过脚本创建六个redis配置
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
done
# 通过脚本运行六个redis
for port in $(seq 1 6);
do
docker run -p 637${port}:6379 -p 1667${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
# 进入其中一个redis
docker exec -it redis-1 /bin/sh #redis默认没有bash
#搭建集群命令
redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1
#部署成功,进入集群
redis-cli -c
SpringBoot微服务打包Docker镜像
1、构建SpringBoot项目
2、maven打包成jar包
3、编写dockerfile
FROM java:8
COPY *.jar /app.jar
CMD ["--server.port=8080"]
EXPOSE 8080
ENTRYPOINT ["java","-jar","app.jar"]
4、构建镜像
# 1.复制jar和DockerFIle到服务器
# 2.构建镜像
$ docker build -t xxxxx:xx .
5、发布运行