Docker

2021-10-18  本文已影响0人  陈海辉

Docker(Centos)

安装&卸载 Docker

 # 卸载旧的版本
yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
# 下载需要的安装包
yum install -y yum-utils
# 设置镜像的仓库(国内阿里云的)
yum-config-manager \
    --add-repo \
    https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 更新 yum 软件包索引
yum makecache fast # Contos7
yum makecache # Contos8
# 安装docker相关的配置(docker-ce 社区版; docker-ee 企业版)
yum install docker-ce docker-ce-cli containerd.io

卸载 Docker

yum remove docker-ce docker-ce-cli containerd.io # 1. 卸载依赖
rm -rf /var/lib/docker # 2. 删除资源  /var/lib/docker是docker的默认工作路径

配置阿里镜像加速器

# 新建文件
sudo mkdir -p /etc/docker
# 写入配置
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://mpa24q0m.mirror.aliyuncs.com"]
}
EOF
# 守护进程重新加载
sudo systemctl daemon-reload
# 重启服务
sudo systemctl restart docker

使用 Docker

帮助命令

systemctl start docker # 启动
systemctl enable docker # 设置开机自启动

docker version # 查看当前版本号,是否启动成功
docker info # 查看 docker 的系统信息,包括镜像和容器的数量
docker 命令名 --help # 帮助命令(可查看可选的参数)

镜像命令

docker images -aq # 查看下载过的镜像: -a 列出所有镜像; -q 只显示镜像 id
docker search 镜像名 # 搜索镜像: --filter=STARS=3000 过滤收藏数大于3000的
docker pull 镜像名:版本号 # 下载镜像: 版本号在镜像仓库中查看
docker rmi 镜像名 镜像id2 # 删除镜像, 也可通过 id 来删除
docker rmi -f $(docker images -aq) # 删除所有(查询结果)

容器命令

docker run [可选参数] 镜像名 # 运行容器(本地查找 > 远程仓库查找 > 下载 > 运行)
  # docker容器后台运行,必须要有一个前台的进程,否则会自动停止
  docker run -d centos /bin/sh -c "while true;do echo hi;sleep 5;done" # 编写shell脚本循环执行,使得centos容器保持运行状态
  
  #参数说明
  --name="名字" # 指定容器名字 xxx1 xxx2 用来区分容器
  -d # 后台方式运行
  -it # 交互方式运行: docker run -it centos /bin/bash # 启动并进入容器, 并用 bash 控制台交互
  -p # 指定容器的端口
    -p 主机端口:容器端口 # 常用
    -p ip:主机端口:容器端口  配置主机端口映射到容器端口
    -p 容器端口
  -P # 随机指定端口(大写的P)
  -e ES_JAVA_OPTS="-Xms128m -Xmx512m" # 环境配置, 限制最大内存占用情况
  --net # 使用网络连接, 多个容器间通信

docker stats # 查看资源使用情况

docker history 容器id # 查看容器的构建过程(倒序)

exit # 停止并退出容器(后台方式运行则仅退出)
Ctrl+P+Q  # 不停止容器退出

docker ps # 列出所有正在运行的容器
  -a # 所有(包括已停止的)
  -q # 只显示容器id
  -n=? # 最近几条

docker rm 容器id # 删除指定的容器 不能删除正在运行的容器,强制删除使用 rm -f
  docker rm -f $(docker ps -aq)   #删除所有的容器
  docker ps -a -q|xargs docker rm #删除所有的容器

docker start 容器id          # 启动容器
docker restart 容器id        # 重启容器
docker stop 容器id           # 停止当前运行的容器
docker kill 容器id           # 强制停止当前容器

其他常用命令

docker logs -tf 容器id # 查看日志
docker logs --tail number 容器id # num为要显示的日志条数

docker top 容器id # 查看容器中进程信息

docker inspect 容器id # 查看容器的元数据: 启动时参数, 配置...

# 进入当前正在运行的容器(后台方式转交互方式)
docker exec -it 容器id /bin/bash # 方式一(常用): 进入容器后开启一个新的终端, 可在里面操作
docker attach 容器id # 方式二: 进入容器正在执行的终端(正在执行当前代码)

# 拷贝容器的文件到主机中
docker cp 容器id:容器内路径 目的主机路径 # 拷贝是一个手动过程, 未尝不可通过 -v 卷的技术实现

# 提交容器到本地镜像
# 例: 1. 启动一个默认的 tomcat
#    2. 发现这个默认的没有 webapps 应用(镜像的原因)
#        3. 我自己拷贝进去了基本的文件
#    4. 将修改后的容器通过 commit 提交为一个本地镜像, 以后就可以用修改后的镜像
docker commit -m=“提交的描述信息”  -a="作者" 容器id 目标镜像名:[TAG]
image.png
image.png

可视化工具

# 安装
docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer

# 访问(需暴露阿里云的 8088 端口): https://ip地址:8088/

镜像

安装 Nginx

  1. 搜索镜像 search: 建议官网搜索
  2. 下载镜像 pull
  3. 查看是否下载完成 images
  4. 启动: docker run -d --name nginx01 -p 8080:80 nginx

安装 Mysql

docker pull mysql:5.7 # 下载镜像

# 启动 后台 端口映射 配置文件数据卷 数据表数据卷 配置密码
docker run -d -p 3306:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=mysql的密码 mysql:5.7

其它注意事项

# 限制 最大内存使用量(有的镜像太费内存, 导致所有都卡)
# -e ES_JAVA_OPTS="-Xms128m -Xmx512m"
docker run -d --name elasticsearch01 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms128m -Xmx512m" elasticsearch:7.6.2

容器数据卷

使用数据卷(方式一)

# 指定路径挂载: -v 主机目录:容器目录
# 匿名挂载: -v 容器目录     => 卷名为一串 hash 串
# 具名挂载(常用): -v 卷名:容器目录 => 所有未指定主机目录的, 默认挂载的主机目录为 `/var/lib/docker/volumes/xxx/_data`
docker run -it -v /home/xxx:/home:读写权限 镜像名 /bin/bash
  # 读写权限: ro 只读(在容器内无法修改); rw 可读写(默认可双向修改)
# 查看是否挂载成功 docker inspect 容器id > Mounts

docker volume ls # 查看所有卷信息
docker volume inspect 卷名 # 查看卷详情: Mountpoint 挂载的主机目录

Dockerfile(方式二)

# Dockerfile
FROM centos # 基础镜像
VOLUME ["挂载数据卷目录1", "挂载数据卷目录2"] # 匿名挂载两个目录
CMD echo "----- 执行结束 -----" # 执行终端命令
CMD /bin/bash

# 根据 Dockerfile 来生成镜像: -f 命令脚本路径; -t(target) 生成的镜像名; . 当前目录
docker build -f /Dockerfile所在路径 -t 镜像名:TAG号 .

数据卷容器

docker run -it --name 父容器名 镜像名 # 启动一个父容器(数据卷容器)
docker run -it --name 子容器名 --volumes-from 父容器名 镜像名 # 启动一个子容器, 数据卷来源于父容器

# 例: 多个 mysql 共享数据
docker run -d -p 3306:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=mysql密码 --name mysql01 mysql:5.7 # 运行第一个容器(数据卷容器)
docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=mysql密码 --name mysql02 --volumes-from mysql01 mysql:5.7 # 运行第二个容器, 继承第一个容器的数据卷

Dockerfile

Dockerfile 的指令

FROM             # 基础镜像, 一切从这里开始构建
MAINTAINER # 镜像是谁写的,姓名+邮箱
RUN              # 镜像构建的时候需要运行的命令
ADD              # 添加内容, 如 tomcat 镜像, 添加 tomcat 压缩包
COPY             # 功能类似ADD,但是是不会自动解压文件,也不能访问网络资源
WORKDIR      # 镜像的工作目录
VOLUME       # 挂载的目录(容器卷)
EXPOSE       # 保留端口配置
CMD              # 指定这个容器启动的时候要运行的命令(只有最后一个会生效)
EMTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD      # 当构建一个被继承Dockerfile,这个时候就会运行ONBUILD的指令,触发指令
ENV              # 构建的时候设置环境变量
指令

CMD & EMTRYPOINT 区别

# 编写 Dockerfile 文件
FROM centos
CMD ["ls", "-a"]
EMTRYPOINT ["ls", "-a"]

# 构建镜像
docker build -f Dockerfile文件路径 -t 镜像名[:版本号] . # 这里有个小点

# run 运行
docker run 镜像id -l # 想追加一个命令: ls -al
    # CMD 命令:            -l 会替换 "ls -a"               ==> 控制台抛错
    # EMTRYPOINT 命令: -l 会追加在后面 "ls -a -l" ==> 正常使用

实战测试

# 1. 编写 Dockerfile 的文件
FROM centos
MAINTAINER chenhaihui<1390568920@qq.com> # 作者+联系方式

ENV MYPATH /usr/local # 环境变量
WORKDIR $MYPATH # 镜像的工作目录: 使用了变量, 值为 /usr/local

RUN yum -y install vim # 镜像构建的时候需要运行的命令 vim
RUN yum -y install net-tools # 镜像构建的时候需要运行的命令 ifconfig

EXPOSE 80 # 指定对外的窗口

CMD echo $MYPATH # 容器启动时运行的命令: 打印环境变量
CMD echo "---end---"
CMD /bin/bash # 容器启动时运行的命令: 进行到 bash 命令

# 2. 通过这个文件构建镜像
docker build -f Dockerfile文件路径 -t 镜像名[:版本号] . # 这里有个小点
    Successfully built 镜像id
  Successfully tagged 镜像名:版本号
# 3. 测试运行
docker images
docker run -it 镜像名:版本号
docker history 容器id # 查看容器的构建过程(倒序)

实战 Tomcat 镜像

  1. 准备镜像文件 tomcat 压缩包, jdk的压缩包, 新建一个 readme.txt 文件
  2. 编写 Dockerfile 文件: 官方命名 Dockerfile
FROM centos
MAINTAINER chenhaihui<1390568920@qq.com> # 作者+联系方式

COPY readme.txt /usr/local/readme.txt # 将本地文件拷贝到 /usr/local 目录下

ADD jdk-8u251-linux-x64.tar.gz /usr/local/ # 将本地文件添加到 /usr/local 目录下(并解压)
ADD apache-tomcat-8.5.55.tar.gz /usr/local/ # 将本地文件添加到 /usr/local 目录下(并解压)

RUN yum -y install vim # 安装 vim

ENV MYPATH /usr/local
WORKDIR $MYPATH # 工件目录

# 一大堆的环境变量
ENV JAVA_HOME /usr/local/jdk1.8.0_251
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.55
ENV CATALINA_BASH /usr/local/apache-tomcat-8.5.55
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin

EXPOSE 8080 # 暴露端口

CMD /usr/local/apache-tomcat-8.5.55/bin/startup.sh && tail -F /usr/local/apache-tomcat-8.5.55/bin/logs/catalina.out
  1. 构建镜像
docker build -t 镜像名[:版本号] .
docker images
  1. 运行
docker run -d -p 9090:8080 -name 容器名
-v /home/tomcat/test:/usr/local/apache-tomcat-9.0.22/webapps/test
-v /home/tomcat/logs:/usr/local/apache-tomcat-9.0.22/logs
镜像名

发布镜像到 dockerhub

  1. dockerhub 上注册自己的账号

  2. 登录账号: docker login -u 用户名 > 输入密码

  3. 提交自己的镜像: docker push 镜像名 (镜像名最好使用 用户名/镜像名:版本号 命名方式)

  4. push 镜像的问题: 增加一个 tag

docker tag 本地镜像id 用户名/镜像名:版本号 # 添加 tag
docker push 用户名/镜像名:版本号 # 提交镜像

发布镜像到 阿里云

  1. 登录阿里云
  2. 找到容器镜像服务
  3. 创建命名空间:防止冲突
  4. 创建容器镜像
  5. 浏览阿里云: 按步骤执行

Docker 网络

原理

  1. 只要安装了 docker, 就会有一个网卡 docker0 桥接模式(255.255.0.1/16),使用的技术是 evth-pair 技术
    1. evth-pair 技术: 就是一对虚拟设备接口,他们都是成对出现的,一段连着协议,一段彼此相连
    2. 因为此特性,evth-pair 充当一个桥梁,连接各种虚拟网络设备的
    3. OpenStac, Docker 容器之间的连接,OVS 的连接,都是使用 evth-pair 技术
  2. 我们每启动一个 docker 容器,docker 就会给 容器分配一个ip
  3. Docker 使用的是 Linux 的桥接,宿主机中是一个 Docker 容器的网桥 docker0,最多65535-2个
image.png

--link 模式(已不建议使用)

ip addr # centos ip地址: 本机回环地址; 阿里云内网地址; docker0地址

# 测试一下
docker run -d -P --name 容器名1 镜像名 # 启动一个 tomcat 容器
docker exec -it 容器名1 ip addr # 获取 tomcat 容器的 ip 地址(docker 分配的)

docker run -d -P --name 容器名2 --link 容器名1 镜像名 # 让容器名2 通过 容器名1 连接网络
docker exec -it 容器名2 ping 容器名1 # 可以直接 ping 通, 但不能反向 ping 通过

自定义网络

网络模式

docker network ls # 查看所有的 docker 网络
docker network inspect 网络名 # 查看网络名详情

docker run -d -P --name 容器名 镜像名 # 默认是 --net bridge, 这个就是 docker0 网络
    docker0特点: 默认的, 域名不能访问, --link 可以打通连接(但很麻烦)

# 自定义一个网络: -d(driver) 网络模式; --subnet 子网掩码; --gateway 网关
docker network create -d bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 自定义网络名

# 运行容器时指定 自定义网络名: 自此, 要宿主机可通过 ip 或 容器名 ping 通网络
docker run -d -P --name 容器名 --net 自定义网络名 镜像名

网络连通

# 连通网络, 将 "容器" 放到了 "自定义网络名" 网络下
# 一个容器, 两个 ip 地址(阿里云 公网ip 私网ip)
docker network connect 自定义网络名 容器名

实战: 部署 Redis 集群

# 1. 创建一个 redis 的自定义网络名
docker network create redis --subnet 172.38.0.0/16

# 2. 通过 shell 脚本创建 6 个 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

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; # 循环创建容器, 也可一个个的启动

# 3. 创建集群: 是否按此配置 ==> 输入 yes
docker exec -it redis-1 /bin/sh # 进入一个容器
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

# 4. 操作集群
docker exec -it redis-1 /bin/sh # 进入一个容器
redis-cli -c # redis 客户端连接集群
cluster info # 集群信息
cluster nodes # 查看集群

set a 124 # 存储值
get a   # 获取值
上一篇下一篇

猜你喜欢

热点阅读