Docker入门

由于docker大多都比较熟悉了,这块主要做一个记录总结,为下一步学习k8s准备。

1. 安装Docker

我的系统是centos,主要介绍下安装流程:

# 移除历史安装包
sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
# 配置yum源
sudo yum install -y yum-utils
sudo yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

# 安装docker
sudo yum install -y docker-ce docker-ce-cli containerd.io
#以下是在安装k8s的时候使用
yum install -y docker-ce-20.10.7 docker-ce-cli-20.10.7  containerd.io-1.4.6

# 启动
systemctl enable docker --now

# 配置加速
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://82m9ar63.mirror.aliyuncs.com"],
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2"
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

2.Docker常用命令

4.1 汇总
Docker环境信息   info、version
镜像仓库命令      login、logout、pull、push、search
镜像管理          build、images、import、load、rmi、save、tag、commit
容器生命周期管理  create、exec、kill、pause、restart、rm、run、start、stop、unpause
容器运维操作      attach、export、inspect、port、ps、rename、stats、top、wait、cp、diff、update
容器资源管理      volume、network
系统信息日志      events、history、logs
4.2 镜像相关
docker images -a            #列出本地所有的镜像
docker images -q            #只显示镜像ID
docker images --digests     #显示镜像的摘要信息
docker images --no-trunc    #显示完整的镜像信息

# 查找镜像
docker search tomcat    # 从Docker Hub上查找tomcat镜像
docker search --filter=stars=300 tomcat     #从Docker Hub上查找关注度大于300的tomcat镜像

# 镜像下载
docker pull tomcat      #从Docker Hub上下载tomcat镜像,默认是最新版本。等价于:docker pull tomcat:latest
docker pull tomcat:8  # 选择指定版本下载

# 删除镜像(需要容器停止且删除)
# 单个镜像删除,相当于:docker rmi java:latest
docker rmi java
# 强制删除(删除正在运行的镜像,注:以后台方式运行的不能被强制删除)
docker rmi -f java
# 多个镜像删除,不同镜像间以空格间隔
docker rmi -f java tomcat nginx
# 删除本地全部镜像
docker rmi -f $(docker images -q)
 
# 镜像构建(在Dockerfile同级目录下)
docker build .

# 如果使用自己构建的镜像 镜像保存为文件 -o: 输出到指定文件
docker save myimage -o myimage.tar

# 从文件加载镜像 -i: 从指定文件读取
docker load -i myimage.tar 
4.3 容器相关
# 查看容器
# 查看正在运行的容器
docker ps
# 查看所有容 包括停止的容器
docker ps -a
# -q参数,只显示container id
docker ps -q
# 查看容器详细信息
docker inspect demo1

# 启动停止容器
#新建并启动容器,参数:-i  以交互模式运行容器;-t  为容器重新分配一个伪输入终端;--name  为容器指定一个名称 --restart=always 设置自启动
docker run -i -t --name mycentos 镜像名称/镜像ID

#后台启动容器,参数:-d  已守护方式启动容器
docker run -d mycentos

#启动止容器
docker start 容器id
# 重启容器
docker restart 容器id
# 关闭容器
docker kill 容器id
docker stop 容器id

-t 参数让Docker分配一个伪终端并绑定到容器的标准输入上
-i 参数则让容器的标准输入保持打开。
-c 参数用于给运行的容器分配cpu的shares值
-m 参数用于限制为容器的内存信息,以 B、K、M、G 为单位
-v 参数用于挂载一个volume,可以用多个-v参数同时挂载多个volume
-p 参数用于将容器的端口暴露给宿主机端口 格式:host_port:container_port 或者 host_ip:host_port:container_port
--name 容器名称
--net 容器使用的网络
-d 创建一个后台运行容器
# 进入容器
# 使用run方式在创建时进入
docker run -it centos /bin/bash
# 关闭容器并退出
exit
# 仅退出容器,不关闭
快捷键:Ctrl + P + Q
快捷键:Ctrl + Shift + P + Q

# run之后的两种进入容器的方式
docker exec -it 容器id bash
docker attach 容器id bash
区别:
exec:进入容器后,开启一个新的终端,可以再里面操作;
attach:进入容器正在执行的终端,不会启动新的终端进程;


# 容器进程
# top支持 ps 命令参数,格式:docker top [OPTIONS] CONTAINER [ps OPTIONS]
# 列出redis容器中运行进程
docker top tomcat
# 查看所有运行容器的进程信息
for i in  `docker ps |grep Up|awk '{print $1}'`;do echo \ &&docker top $i; done

# 容器日志
# 查看redis容器日志,默认参数
docker logs tomcat
# 查看redis容器日志,参数:-f  跟踪日志输出;-t   显示时间戳;--tail  仅列出最新N条容器日志;
docker logs -f -t --tail=20 redis
# 查看容器redis从2022年11月28日后的最新10条日志。
docker logs --since="2021-08-10" --tail=10 redis

# 容器文件拷贝
docker cp 容器id:容器内路径  目的主机路径
4.4 仓库相关
# 登录docker hub
docker login

#给旧镜像起名
docker tag java-demo:v1.0  leifengyang/java-demo:v1.0

# 推送到docker hub
docker push leifengyang/java-demo:v1.0

# 别的机器
docker pull leifengyang/java-demo:v1.0

# 别的机器运行
docker run -d -p 8080:8080 --name myjava-app java-demo:v1.0 

3. Dockerfile

1.FROM 表示基础镜像,并且必须是第一条语句。
三种写法,其中<tag>和<digest> 是可选项,如果没有选择,那么默认值为latest

FROM <image>
FROM <image>:<tag>
FROM <image>:<digest> 

2.MAINTAINER 表示作者
MAINTAINER <name>

3.LABEL 指定标签 可以有多个 使用空格分开
LABEL version="1.0" 

4.ADD 把宿主机的文件或文件夹拷贝到容器中
tip1:路径的填写可以是容器内的绝对路径,也可以是相对于工作目录的相对路径,推荐写成绝对路径
tip2:可以是一个本地文件或者是一个本地压缩文件,还可以是一个url url就相当于wget
tip3:src为一个目录的时候,会自动把目录下的文件复制过去,目录本身不会复制 如果src为多个文件则dest必须是目录
ADD <src>... <dest>

5.COPY 复制命令
tip:与add相同,但是只能是本地文件
COPY <src>... <dest>

6.EXPOSE 暴露容器运行时的监听端口
tip:这并不会和主机端口想绑定 如果想和主机绑定还是需要-port指令
EXPOSE <port>/<tcp/udp>
EXPOSE 80/tcp

7.ENV 环境变量 第一种设置一个 第二种可以设置多个
ENV <key> <value>
ENV <key>=<value> ...

8.RUN 执行命令
# 直接执行shell命令
RUN <command>
# 第一个是可执行文件,如executable.sh 后面可以跟命令的参数
RUN ["executable", "param1", "param2"]

9.CMD 容器启动默认命令或者参数
tip:参数一定要用双引号,不能是单引号。因为参数传递后解析的是json array
# 前两种理解为执行可执行文件或命令即可 第三中就是shell
CMD ["executable","param1","param2"]
CMD ["param1","param2"]
CMD command param1 param2
ps:RUN和CMD是不同的,RUN是构建的命令,CMD是容器启动时执行的命令,构建时仅仅是声明。

10.ENTRYPOINT 容器启动时执行的命令
ENTRYPOINT ["executable", "param1", "param2"]  
ENTRYPOINT command param1 param2
ps:CMD和ENTRYPOINT是很相似的,都是容器启动时执行,并且语法类似,同时只有最后一条生效。不同点在于CMD会被docker run的命令覆盖,如docker run ... /bin/bash则cmd不生效。但是ENTRYPOINT会生效。
tip:如果我们在Dockerfile种同时写了ENTRYPOINT和CMD,并且CMD指令不是一个完整的可执行命令,那么CMD指定的内容将会作为ENTRYPOINT的参数

11.VOLUME 目录挂载
VOLUME ["/data"]
如:VOLUME /share/data #声明容器中/share/data为匿名卷
VOLUME指令只是起到了声明了容器中的目录作为匿名卷,但是并没有将匿名卷绑定到宿主机指定目录的功能。这一功能是通过-v参数去实现的
volume只是指定了一个目录,用以在用户忘记启动时指定-v参数也可以保证容器的正常运行。比如mysql,你不能说用户启动时没有指定-v,然后删了容器,就把mysql的数据文件都删了,那样生产上是会出大事故的,所以mysql的dockerfile里面就需要配置volume,这样即使用户没有指定-v,容器被删后也不会导致数据文件都不在了。还是可以恢复的。

12.USER 设置启动容器的用户,可以是用户名或UID,所以,只有下面的两种写法是正确的
USER daemo
USER UID
tip:如果设置了容器以daemon用户去运行,那么RUN, CMD 和 ENTRYPOINT 都会以这个用户去运行,使用这个命令一定要确认容器中拥有这个用户,并且拥有足够权限

13.WORKDIR 设置工作目录,对RUN,CMD,ENTRYPOINT,COPY,ADD生效。如果不存在则会创建,也可以设置多次
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
结果是/a/b/c
tip:WORKDIR可以解析环境变量

14.ARG 定义变量 在docker build创建镜像的时候,使用 --build-arg =来指定参数 可以给默认值
ARG user1
ARG buildno=1

15.STOPSIGNAL 停止容器是给一个指令

例如:

FROM python:3.7

ENV PYTHONUNBUFFERED 1
ENV PYTHONDONTWRITEBYTECODE 1
ENV TZ 'Asia/Shanghai'

#RUN sed -i s/archive.ubuntu.com/mirrors.aliyun.com/g /etc/apt/sources.list \
#    && sed -i s/security.ubuntu.com/mirrors.aliyun.com/g /etc/apt/sources.list \
#    && apt-get update && apt-get upgrade

#RUN pip install --upgrade pip
RUN python -m pip install --upgrade pip -i https://pypi.tuna.tsinghua.edu.cn/simple

ADD deploy/flask/requirements.txt /

#RUN pip3 install -r /requirements.txt -U -i https://pypi.doubanio.com/simple/
#RUN pip3 install -r /requirements.txt -U -i https://mirrors.aliyun.com/pypi/simple/
RUN pip3 install -r /requirements.txt -U -i https://pypi.tuna.tsinghua.edu.cn/simple/

# make a new directory to store the jdk files
RUN mkdir /usr/local/java

# copy the jdk  archive to the image,and it will automaticlly unzip the tar file
ADD deploy/flask/jdk-8u301-linux-x64.tar.gz /usr/local/java/

# make a symbol link
RUN ln -s /usr/local/java/jdk1.8.0_301 /usr/local/java/jdk

# set environment variables
ENV JAVA_HOME /usr/local/java/jdk
ENV JRE_HOME ${JAVA_HOME}/jre
ENV CLASSPATH .:${JAVA_HOME}/lib:${JRE_HOME}/lib
ENV PATH ${JAVA_HOME}/bin:$PATH


WORKDIR /work

docker-compose:

version: "3"
services:
  ledi-clue-base:
    build:
      context: ../
      dockerfile: deploy/flask/Dockerfile
    container_name: ledi-clue-base
    hostname: tangy
    environment:
      TZ: Asia/Shanghai
      # dev、prod、test
      env: dev
    volumes:
      - ../:/work
      # 只有需要读取本地文件的服务配置此项挂载
      - /var/services/homes/admin/update:/update
    # 需要访问宿主机服务的开启此项
    network_mode: "host"
    restart: unless-stopped
    # command: nohup python3 ./src/run.py >>/dev/null 2>&1 &
    command: python3 ./src/run.py

  nginx:
    build:
      context: ../
      dockerfile: deploy/nginx/Dockerfile
    ports:
      - "80:8080"
    depends_on:
      - ledi-clue-base


4. 常用的应用docker安装教程

4.1 mysql8.0
# 下载镜像
docker pull mysql:8.0

# 挂载目录
mkdir -p /data/mysql/conf
mkdir -p /data/mysql/data
mkdir -p /data/mysql/logs

# 创建my.cnf配置文件 如下
vi /data/mysql/conf/my.cnf

# 启动
docker run  --restart=always  --name mysql8.0  -v /data/mysql/cnf:/etc/mysql  -v /data/mysql/data:/var/lib/mysql  -v /data/mysql/log:/var/log  -v /data/mysql/mysql-files:/var/lib/mysql-files -p 3306:3306  -e MYSQL_ROOT_PASSWORD='123456'   -d mysql:8.0
[client]
port = 3306
default-character-set = utf8mb4
 
[mysql]
port = 3306
default-character-set = utf8mb4
 
[mysqld]
# bind-address = 0.0.0.0
# port = 3306
 
max_connections=10000
 
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
 
# 设置时区和字符集
# default-time-zone='+8:00'
character-set-client-handshake=FALSE
init_connect='SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci'
 
gtid-mode=ON
enforce-gtid-consistency = ON
4.2 MongoDB
docker pull mongo:latest

docker run -itd --name mongo -p 27017:27017 mongo --auth

5.参考文章

1.Dockerfile详解超全

2.Docker常用命令

3.雷丰阳博客

4.Dockerfile的VOLUME

最后修改:2022 年 12 月 18 日
如果觉得我的文章对你有用,请随意赞赏