Docker使用

Docker基本用法

将当前用户添加到docker用户组

为了避免每次使用docker命令都需要加上sudo权限,可以将当前用户加入安装中自动创建的docker用户组(可以参考官方文档):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
sudo usermod -aG docker $USER
# 如果不行可以试试这个
#创建docker组
weiyj@ubuntu18:~$ sudo groupadd docker
groupadd: group 'docker' already exists
#将当前用户加入docker组
weiyj@ubuntu18:~$ sudo gpasswd -a ${USER} docker
Adding user weiyj to group docker
#重启docker服务
weiyj@ubuntu18:~$ sudo service docker restart
#刷新docker组成员
weiyj@ubuntu18:~$ newgrp - docker
#再试试命令^_^
weiyj@ubuntu18:~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE

执行完此操作后,需要退出服务器,再重新登录回来,才可以省去sudo权限。

镜像(images)

  1. docker pull ubuntu:20.04:拉取一个镜像
  2. docker images:列出本地所有镜像
  3. docker image rm ubuntu:20.04docker rmi ubuntu:20.04:删除镜像ubuntu:20.04
  4. docker [container] commit CONTAINER IMAGE_NAME:TAG:创建某个container的镜像
  5. docker save -o ubuntu_20_04.tar ubuntu:20.04:将镜像ubuntu:20.04导出到本地文件ubuntu_20_04.tar
  6. docker load -i ubuntu_20_04.tar:将镜像ubuntu:20.04从本地文件ubuntu_20_04.tar中加载出来
  7. docker tag::更改镜像名称或版本
  8. docker push::将镜像push到远程仓库

容器(container)

  1. docker [container] create -it ubuntu:20.04:利用镜像ubuntu:20.04创建一个容器。
  2. docker ps -a:查看本地的所有容器
  3. docker [container] start CONTAINER:启动容器
  4. docker [container] stop CONTAINER:停止容器
  5. docker [container] restart CONTAINER:重启容器
  6. docker [contaienr] run -itd ubuntu:20.04:创建并启动一个容器
  7. docker [container] attach CONTAINER:进入容器
    • 先按Ctrl-p,再按Ctrl-q可以挂起容器
    1. docker [container] exec CONTAINER COMMAND:在容器中执行命令
    2. docker [container] rm CONTAINER:删除容器
    3. docker container prune:删除所有已停止的容器
    4. docker export -o xxx.tar CONTAINER:将容器CONTAINER导出到本地文件xxx.tar
    5. docker import xxx.tar image_name:tag:将本地文件xxx.tar导入成镜像,并将镜像命名为image_name:tag
    6. docker export/importdocker save/load的区别:
      • export/import会丢弃历史记录和元数据信息,仅保存容器当时的快照状态
      • save/load会保存完整记录,体积更大
    7. docker top CONTAINER:查看某个容器内的所有进程
    8. docker stats:查看所有容器的统计信息,包括CPU、内存、存储、网络等信息
    9. docker cp xxx CONTAINER:xxxdocker cp CONTAINER:xxx xxx:在本地和容器间复制文件
    10. docker rename CONTAINER1 CONTAINER2:重命名容器
    11. docker update CONTAINER --memory 500MB:修改容器限制
    12. docker logs 查看启动日志
    13. docker commit将容器创建为镜像

    网络(network)

    1
    2
    3
    4
    docker network create<network_name> #创建一个网络
    docker network connect<network_name><container_name_or_id> #将容器连接到指定网络
    docker inspect<container_name_or_id> #验证容器网络
    docker run -d --name<container_name> --network<network_name><image_name> #启动时添加网络

    Docker卸载

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    yum remove docker \

    docker-client \

    docker-client-latest \

    docker-common \

    docker-latest \

    docker-latest-logrotate \

    docker-logrotate \

    docker-engine

    Dockerfile

    Dockerfile中的RUN、CMD、ENTYRYPOINT(仅在[]下)

    • CMD

      cmd为docker容器构建好之后执行的命令,多个CMD会覆盖,CMD作为docker容器启动后默认执行的命令优先级最低,cmd如果采用[]形式,需先指定/bin/bash,这里不需要是因为本身就在centos下的shell。

      1
      2
      3
      FROM centos
      CMD ["ls","-a"]
      CMD ["ls", "-l"]
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      ykexc@VM-4-7-ubuntu:~/docker/test$ vim Dockerfile
      ykexc@VM-4-7-ubuntu:~/docker/test$ docker build -t test:1 .
      [+] Building 3.7s (5/5) FINISHED
      ykexc@VM-4-7-ubuntu:~/docker/test$ docker run --name test001 -it test:1
      total 48
      lrwxrwxrwx 1 root root 7 Nov 3 2020 bin -> usr/bin
      drwxr-xr-x 5 root root 360 Nov 10 08:58 dev
      drwxr-xr-x 1 root root 4096 Nov 10 08:58 etc
      drwxr-xr-x 2 root root 4096 Nov 3 2020 home
      lrwxrwxrwx 1 root root 7 Nov 3 2020 lib -> usr/lib
      lrwxrwxrwx 1 root root 9 Nov 3 2020 lib64 -> usr/lib64
      drwx------ 2 root root 4096 Sep 15 2021 lost+found
      drwxr-xr-x 2 root root 4096 Nov 3 2020 media
      drwxr-xr-x 2 root root 4096 Nov 3 2020 mnt
      drwxr-xr-x 2 root root 4096 Nov 3 2020 opt
      dr-xr-xr-x 255 root root 0 Nov 10 08:58 proc
      dr-xr-x--- 2 root root 4096 Sep 15 2021 root
      drwxr-xr-x 11 root root 4096 Sep 15 2021 run
      lrwxrwxrwx 1 root root 8 Nov 3 2020 sbin -> usr/sbin
      drwxr-xr-x 2 root root 4096 Nov 3 2020 srv
      dr-xr-xr-x 13 root root 0 Nov 10 08:58 sys
      drwxrwxrwt 7 root root 4096 Sep 15 2021 tmp
      drwxr-xr-x 12 root root 4096 Sep 15 2021 usr
      drwxr-xr-x 20 root root 4096 Sep 15 2021 var

      若在docker run命令后面加上的命令也会将CMD命令覆盖

      1
      2
      3
      4
      5
      ykexc@VM-4-7-ubuntu:~/docker/test$ ls
      Dockerfile
      ykexc@VM-4-7-ubuntu:~/docker/test$ docker run --name test002 -it test:1 ls -a
      . .. .dockerenv bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var

    • ENTYRYPOINT

      ENTYRYPOINT作为Docker容器运行后真正执行的命令,如果有CMD的话,那么CMD会作为参数

      1
      2
      3
      4
      5
      FROM centos
      CMD ["ls","-a"]
      CMD ["huya"]

      ENTRYPOINT ["echo"]
      1
      2
      3
      4
      5
      ykexc@VM-4-7-ubuntu:~/docker/test$ docker run --name test002 -it test:2
      huya #输出的就是最后一个CMD
      ykexc@VM-4-7-ubuntu:~/docker/test$ docker run --name test003 -it test:2 ykexc
      ykexc #如果run后根参数那么就继续覆盖

    • RUN

      RUN命令为Dockerfile在构建镜像时执行的命令

    Dockerfile中的ARG、ENV区别

    • ARG仅在dockerfile构建时起作用

      可以在构建时覆盖ARG,可在docker build 后加--build-arg <ARG>=xxx

    • ENV在构建时和在容器启动后都有用,并且使用 ENV 指定定义的环境变量始终会覆盖同名的 ARG 指令。

      可以在运行时覆盖ENV,可在docker run后加-e <ENV>=xxx

    Dockerfile中的ADD、COPY区别

    • COPY类似于docker cp命令 COPY <当前目录下的文件> <镜像的路径>
    • ADD和COPY类似,但是ADD会自动解压.tar.gz压缩包。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    FROM ubuntu
    RUN apt update && apt install -y openjdk-17-jdk
    COPY build/libs/gradle-test-0.0.1-SNAPSHOT.jar app.jar
    CMD java -jar app.jar

    -------------------------------------------------------------

    FROM openjdk:17-slim
    ARG JAR=build/libs/doc-0.0.1-SNAPSHOT.jar
    COPY ${JAR} app.jar
    ENTRYPOINT ["java", "-jar", "/app.jar"]
    EXPOSE 8088

    Dockercompose

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    version: "3.9"
    services:
    spring:
    container_name: app_springboot
    build: .
    ports:
    - "8087:8087"
    depends_on:
    - mysql
    restart: always
    mysql:
    container_name: app_mysql
    image: mysql:latest
    environment:
    MYSQL_ROOT_HOST: '%'
    MYSQL_ROOT_PASSWORD: '123456.root'
    MYSQL_DATABASE: 'study'
    TZ: 'Asia/Shanghai'
    ports:
    - "3306:3306"
    redis:
    container_name: app_redis
    image: redis:latest
    ports:
    - "6379:6379"

    -------------------------------------------
    version: "3.9"
    services:
    spring:
    container_name: se_sb
    build: .
    ports:
    - "8085:8085"
    restart: always
    mysql:
    container_name: se_mysql
    image: mysql:latest
    environment:
    MYSQL_ROOT_HOST: '%'
    MYSQL_ROOT_PASSWORD: '123456.root'
    MYSQL_DATABASE: 'sty'
    TZ: 'Asia/Shanghai'
    ports:
    - "3306:3306"
    volumes:
    - ./data:/var/lib/mysql
    - ./init:/docker-entrypoint-initdb.d
    redis:
    container_name: se_redis
    image: redis:latest
    ports:
    - "6379:6379"


    Tips

    临时端口映射

    1.查询容器ip: docker inspect <container_id> | grep IPAddress

    2.宿主机配置iptables:

    • iptables -t nat -A DOCKER -p tcp --dport <host_port> -j DNAT --to-destination <container_ip>:<docker_port>
    • iptables -t nat -A POSTROUTING -j MASQUERADE -p tcp --source <container_ip> --destination <container_ip> --dport <docker_port>
    • iptables -A DOCKER -j ACCEPT -p tcp --destination <container_ip> --dport <docker_port>

    3.查看是否成功: iptables -t nat -nvL

    例如:将容器内22端口映射到宿主机20000端口。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    172.17.0.2   --->    container_ip
    20000 ---> host_port
    22 ---> docker_port

    iptables -t nat -A DOCKER -p tcp --dport 20000 -j DNAT --to-destination 172.17.0.2:22
    iptables -t nat -A POSTROUTING -j MASQUERADE -p tcp --source 172.17.0.2 --destination 172.17.0.2 --dport 22
    iptables -A DOCKER -j ACCEPT -p tcp --destination 172.17.0.2 --dport 22

    iptables -t nat -nvL #(查看是否映射成功)

Docker使用
http://example.com/2023/02/27/Docker使用/
作者
ykexc
发布于
2023年2月27日
许可协议