Docker

容器化技术

用 Docker 启动虚拟机来运行自己的应用

Docker虚拟机对比VMware虚拟机:

  • 占资源少

  • 启动速度快

为什么使用Docker

  1. 1.

    独立的虚拟环境,在任何场景下应用运行的环境可以保持完全一致

  2. 2.

    可以充分发挥服务器的运算能力

安装docker

参考官方文档,在CentOS中安装

https://docs.docker.com/engine/install/centos/

用docker部署应用

镜像

  • 虚拟机的一组静态磁盘文件

  • 可以任意下载、复制、分发

    • hub.docker.com

  • 镜像名称,由两部分组成

    • Repository:Tag

    • 名称:标签

    • 如果不写标签,默认标签是latest

镜像的常用命令

# 下载镜像
docker pull 镜像名称

# 镜像列表
docker images

# 为镜像添加新的名称
docker tag redis:7-alpine my-redis:1.0
docker tag redis:7-alpine redis-tedu:2.0

# 删除镜像的名称
# 删除最后一个名称时,会把镜像磁盘文件一起删除
# remove image
docker rmi redis:7-alpine
docker images

docker rmi my-redis:1.0
docker images

docker rmi my-redis:2.0
docker images

# 导出镜像到压缩文件
docker save redis rabbitmq:management | gzip > a.gz

# 从压缩文件导入,加载镜像
# 先删除
docker rmi redis rabbitmq:management
# 再导入
docker load -i a.gz

容器

Docker的虚拟机

常用容器命令:

-

# 启动tomcat容器
# docker run
#     1. 在本地查找镜像,如果不存在,会自动从仓库下载
#     2. 新创建一个容器
#     3. 在容器中自动运行启动tomcat

# 默认在前台运行,会占用命令行
# Ctrl+c可以退出tomcat
# tomcat退出后,容器中没有任何前台进程运行,那么容器也自动退出
docker run tomcat:8

# 查看镜像构建历史,CMD属性设置的就是默认启动命令
docker history tomcat:8
docker history redis
docker history mariadb
docker history rabbitmq:management

# 查看镜像详情中的CMD属性
docker inspect tomcat:8

# 覆盖CMD,不执行默认命令而是执行自己指定的任意命令
# pwd、ls、env显示完结果后会自动退出,容器也会自动退出
# bash不会自动退出,容器也不会退出
docker run tomcat:8 pwd
docker run tomcat:8 ls -a -l
docker run tomcat:8 env
docker run tomcat:8 bash
catalina.sh start
top
# Ctrl+c退出top
exit #退出bash





# 启动容器
docker run mariadb

# 在前台启动,占用命令行
docker run redis

# 查看容器
docker ps		# 运行状态的容器
docker ps -a   	# all

# 查看镜像中设置的默认启动命令
docker history redis

docker history mariadb

docker history rabbitmq:management

# 覆盖 CMD 设置的默认命令
docker run redis pwd

docker run redis ls -a -l

# -i 交互 -t 终端
docker run -it redis bash

exit

docker ps -a


镜像中设置默认启动命令:

CMD

CMD ["redis-server"]

# "java -jar /opt/cs/cs.jar"
CMD ["java", "-jar", "/opt/cs/cs.jar"]

ENTRYPOINT

# "java -jar /opt/cs/cs.jar"
ENTRYPOINT ["java"]
CMD ["-jar", "/opt/cs/cs.jar"]

# 覆盖ENTRYPOINT
docker run --entrypoint java tomcat:8 -version

docker run --entrypoint ls tomcat:8 -a -l

-d 后台运行

docker run -d tomcat:8
docker ps
docker ps -a



docker run -d \
redis

docker ps

docker logs 容器ID前3位

进入容器,执行容器中的命令

docker exec -it 0b pwd

docker exec -it 0b touch a.txt

docker exec -it 0b ls -a -l

docker exec -it 0b bash
top
# ctrl+c 退出top

exit  # 退出bash,回到宿主机

docker ps

容器命名

# 容器改名
# 为id是63的容器命名,叫t3
docker rename 63 t3

# 新建容器时为容器命名
# --name 容器名
docker run -d \
--name cat1 \
tomcat:8

# 查看容器中的日志
docker logs cat1

# 停止容器,会最长等待10秒,让内部应用执行退出清理过程
docker stop cat1

docker logs cat1
# 重新启动容器
docker start cat1

docker logs cat1
# docker restart cat1
# 杀掉容器,不等待内部应用退出,直接杀掉
docker kill cat1

docker logs cat1





docker run -d --name r1 \
redis

docker run -d --name r2 \
redis

docker ps

docker logs r1

docker stop r1 r2

docker start r1 r2

--restart=always 让容器可以随系统自动重启

服务器重启,或docker系统服务重启,容器默认是退出状态

docker run -d --name cat2 \
tomcat:8

docker run -d --name cat3 \
--restart always \
tomcat:8

# 重启docker系统服务
systemctl restart docker

# cat2是关闭状态,cat3随系统一起启动,是运行状态
docker ps -a





docker run -d --name r3 \
--restart=always \
redis

docker ps

# 重启docker系统服务
systemctl restart docker

docker ps 

--rm 容器关闭时,会被系统自动删除

启动临时容器

  • 查看容器中的一些默认设置

  • 从容器复制文件到宿主机

# 查看tomcat容器的默认环境变量
docker run --rm tomcat:8 env
# 查看默认文件夹
docker run --rm tomcat:8 pwd
# 查看默认配置文件内容
docker run --rm tomcat:8 cat conf/server.xml

# 查看容器列表,上面三个新的容器不存在,已经被自动删除
docker ps -a




# redis容器启动后,容器内有哪些环境变量
docker run --rm redis env

docker cp 在容器和宿主机之间互相复制文件

# 新建容器
docker run -d --name cat4 \
--restart always \
tomcat:8

# 把tomcat的配置文件server.xml复制到宿主机
docker cp cat4:/usr/local/tomcat/conf/server.xml ~/ 
ll

# 修改配置文件,69行把端口改成80端口
# i     编辑模式
# esc   正常模式
# :     命令模式
# :w    保存
# :q    退出
# :wq   保存并退出
# :q!   强制退出,丢弃修改
vim server.xml

# 修改过的配置文件,复制到容器中,覆盖默认的配置文件
docker cp ~/server.xml cat4:/usr/local/tomcat/conf/server.xml

# 重启容器,tomcat启动时会使用新的配置,在80端口启动
docker restart cat4
docker logs cat4



# 从容器复制文件到宿主机
docker cp r3:/data/dump.rdb ~/

ls

# 从宿主机复制文件到容器
docker cp ~/ip-static r3:/data/ip

# 进入容器查看文件
docker exec -it r3 ls /data/

删除容器

# docker rm 容器名称或者容器id
# 默认只能删除已经停止的容器
docker rm 46a

# 运行状态容器需要使用-f参数强制删除
docker rm cat2
docker rm -f cat2

# 一次删除多个容器
docker rm -f 5f7 63a cat4

# 清理所有停止的容器
docker container prune
# 清理时免确认
docker container prune -f

# 再启动几个,后面用来测试删除操作
docker run -d tomcat:8
docker run -d tomcat:8
docker run -d tomcat:8
docker run -d tomcat:8

# 列出所有容器的id
docker ps -aq
# 删除全部容器
docker rm -f $(docker ps -aq)

docker ps -a

数据挂载:文件、文件夹、数据卷

# 启动mariadb数据库,挂载宿主机的一个文件夹存放数据文件
# -v挂载会自动创建宿主机目录
docker run -d --name mysql \
-v /opt/mysql/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=root \
mariadb

ll /opt/mysql/data

# 进入容器创建表,添加数据
docker exec -it mysql mysql -uroot -proot

create database test;
use test;
create table a(a int);
insert into a values(1),(2),(3),(4);
exit

docker rm -f mysql

ll /opt/mysql/data

docker run -d --name mysql \
-v /opt/mysql/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=root \
mariadb

docker exec -it mysql mysql -uroot -proot

use test;
select * from a;


# 挂载文件

# 临时启动一个tomcat:8的容器,从容器复制 server.xml
docker run -d --rm --name tmp \
tomcat:8

docker cp tmp:/usr/local/tomcat/conf/server.xml ~/

docker stop tmp;

# 修改第69行,8080端口改成80
vim ~/server.xml

# 将 ~/server.xml 挂载到tomcat容器,tomcat会使用配置文件中的80端口启动
docker run -d --name cat1 \
-v ~/server.xml:/usr/local/tomcat/conf/server.xml \
tomcat:8

docker logs cat1;

数据卷挂载

#  清理容器
docker rm -f $(docker ps -aq)

# 新建数据卷
docker volume create my-vol
# 查看数据卷列表
docker volume ls
# 查看数据卷详情
docker inspect my-vol

# 启动数据库容器,挂载my-vol数据卷
docker run -d --name mysql \
-v my-vol:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=root \
mariadb

# 查看容器的挂载详情
docker inspect mysql

ll /var/lib/docker/volumes/my-vol/_data

默认数据卷挂载

mariadb镜像中的配置:VOLUME [/var/lib/mysql]

如果启动容器时,不手动挂载则会自动创建一个随机数据卷挂载到这个路径。

#  清理容器
docker rm -f $(docker ps -aq)

# 删除上一步测试的数据卷my-vol
docker volume rm my-vol

# 启动mariadb时,不手动挂载数据目录
docker run -d --name mysql \
-e MYSQL_ROOT_PASSWORD=root \
mariadb

# 查看容器的挂载情况
docker inspect mysql

# 查看自动创建的随机数据卷
docker volume ls

# 删除容器时,随机数据卷默认不删除
docker rm -f mysql

docker volume ls

# 启动mariadb时,不手动挂载数据目录
docker run -d --name mysql \
-e MYSQL_ROOT_PASSWORD=root \
mariadb

# 查看数据卷
docker volume ls

# 删除容器时,把随机数据卷一起删除
docker rm -f mysql --volumes

# 查看数据卷
docker volume ls

# 清理无主的数据卷
docker volume prune

端口映射

-p 服务器端口:容器端口

docker rm -f $(docker ps -aq)

docker run -d --name cat1 \
-p 8990:8080 \
tomcat:8

docker ps

# 浏览器访问
http://192.168.64.140:8990

--net host 让容器直接使用宿主机的网络和端口

docker run -d --name cat2 \
--net host \
tomcat:8

# 浏览器访问
http://192.168.64.140:8080

虚拟网络

docker rm -f $(docker ps -aq)

# 创建网络
docker network create my-net
# 查看网络列表
docker network ls
# 查看网络详情
docker inspect my-net
# 宿主机上创建的虚拟网卡
ifconfig

# 容器cat1和cat2连接到my-net网络
docker run -d --name cat1 \
--net my-net \
tomcat:8

docker run -d --name cat2 \
--net my-net \
tomcat:8

docker inspect cat1
docker inspect cat2

# 宿主机访问cat1和cat2
curl http://172.18.0.2:8080
curl http://172.18.0.3:8080
# 从cat1访问cat2
docker exec -it cat1 curl http://172.18.0.3:8080
# 容器之间互相访问,可以使用容器名,docker提供DNS解析,将容器名解析成ip
docker exec -it cat1 curl http://cat2:8080

创建网络时,手动指定子网参数:

docker network create dockernet --subnet=192.168.23.0/24

docker network ls
docker inspect dockernet

创建容器连接到虚拟网络时,手动指定固定ip

# 清理容器
docker rm -f $(docker ps -aq)

# 启动容器,指定固定ip
docker run -d --name cat1 \
--net dockernet \
--ip 192.168.23.231 \
tomcat:8

docker inspect cat1

构建镜像

使用配置文件,来配置环境安装流程。

Dockerfile配置文件:

# Dockerfile文件内容:

# 基础镜像
FROM tomcat:8

# 复制文件到新的镜像中
COPY server.xml /usr/local/tomcat/conf/

# 暴露端口
EXPOSE 80

# 默认切换的目录
WORKDIR /usr/local/tomcat/

# 默认启动命令
CMD ["catalina.sh", "run"]

将 Dockerfile 和构建过程中使用的文件,一起放到一个文件夹下

# [tomcat]
#	- Dockerfile
#	- server.xml
	
# 准备文件夹和文件
mkdir /root/tomcat/
vim /root/tomcat/Dockerfile # 编辑文件, 把上面内容粘进去
# 按键盘i,进入编辑模式
# 按键盘esc,退出编辑模式
# :进入命令模式,输入wq,保存并退出

cp /root/server.xml /root/tomcat/
ls /root/tomcat/

执行构建:

cd ~/

docker build -t my-tomcat:1.0 /root/tomcat/

docker images

image-20220820092534407

  • 镜像是分层结构

  • 每一层都可以被重复使用

  • 每一层镜像构建出来之后都不可变

docker 案例

# 部署halo博客系统
docker run -it -d --name halo \
-p 8090:8090 \
-v ~/.halo:/root/.halo \
--restart=always \
halohub/halo:1.6.0

http://192.168.64.140:8090

CREATE DATABASE wordpress CHARSET utf8mb4;

CREATE USER `root`@`%`;
GRANT ALL PRIVILEGES ON *.* TO `root`@`%` IDENTIFIED BY 'root';
GRANT ALL PRIVILEGES ON *.* TO `root`@`192.168.64.140` IDENTIFIED BY 'root';

# wordpress建站系统
docker run -d --name wordpress \
-e WORDPRESS_DB_HOST=192.168.64.1 \
-e WORDPRESS_DB_USER=root \
-e WORDPRESS_DB_PASSWORD=root \
-e WORDPRESS_DB_NAME=wordpress \
-p 80:80 \
wordpress

# 浏览器访问
http://192.168.64.140

阿里云服务器安装Docker、Halo博客、Wordpress建站系统

阿里免费试用服务器

  1. 1.

    2核4G

  2. 2.

    centos 7.9

  3. 3.

    带宽3M

  4. 4.

    过期自动释放,避免产生费用

  5. 5.

    进入控制台,找到ECS服务器实例

  6. 6.

    实例最右边三个点拉开,重置实例密码(管理员的密码),并重启

  7. 7.

    mobaxterm连接服务器的公网ip

  8. 8.

    安装docker yum install -y yum-utils

yum-config-manager
--add-repo
https://download.docker.com/linux/centos/docker-ce.repo

yum -y install docker-ce docker-ce-cli containerd.io docker-compose-plugin

systemctl enable docker

systemctl start docker

  1. 1.

    控制台实例页面,点击实例进入实例,进入安全组,点击打开默认的安全组 添加入向设置(快速添加),可以添加全部端口

  2. 2.

    部署博客系统

docker run -it -d --name halo
-p 80:8090
-v ~/.halo:/root/.halo
--restart=always
halohub/halo:1.6.0

  1. 1.

    访问博客 http://服务器地址