• Docker简介及基本使用


    1. docker简介

    学习一门技能或新的技术,我认为至少要明白三件事:

    • 这个东西是什么?
    • 为什么会出现,能够为我们解决什么问题?
    • 我们如何使用它?

    至于为什么会出现,大家可以自行百度或查阅官方文档,很多大牛们都有介绍,比我解释的更好,在此就不多做啰嗦,本着实践的原则,本文中只描述docker的出现为我们解决了什么问题,以及我们怎么样使用它。

    在2000年左右入行运维的同学大多数应该遇到过这么一个问题:

    同一套代码,开发环境、测试环境反复测试都没有问题,一上线就出现各种各样的问题。对于这类问题之前也做过总结,无非就是配置问题或环境问题,开发、测试、生产环境不一致,导致每次代码发布一堆人熬夜到很晚才能完成,效率根本谈不上。

    docker的出现为我们很好的解决了上述问题,所以得以被国内外的同行们认可,能够快速的发展,它能将代码连同运行环境,打包成一个镜像,同一个镜像可以在开发、测试、生产等各个环境进行部署。

    同时,可以做到不同的容器之间相互隔离,对于每个容器用到的资源也可以进行限制。

    当然,要实现这种部署方式,还离不开代码与配置分离、无状态化改造等等一系列的工作作为前提。但是好就好在这些都是一次性的工作,在后续的文章中,我也会有相关的文章分享出来。

    2. docker基础操作

    本文主要描述在CentOS7.8操作系统上面安装和配置docker,其他Linux发行版与之类似,因篇幅有限,不区分环境介绍。如在安装配置过程中遇到问题,可留言或加入博客中公布的QQ群进行交流。

    2.1. docker安装

    2.1.1 配置网卡转发

    # 若未配置,需要执行如下
    cat <<EOF >  /etc/sysctl.d/docker.conf
    net.bridge.bridge-nf-call-ip6tables = 1
    net.bridge.bridge-nf-call-iptables = 1
    net.ipv4.ip_forward=1
    EOF
    sysctl -p /etc/sysctl.d/docker.conf
    # 如果出现如下报错:
    sysctl: cannot stat /proc/sys/net/bridge/bridge-nf-call-ip6tables: No such file or directory
    sysctl: cannot stat /proc/sys/net/bridge/bridge-nf-call-iptables: No such file or directory
    # 解决,先执行命令:
    modprobe br_netfilter
    # 然后再次执行如下命令即可
    sysctl -p /etc/sysctl.d/docker.conf

    2.1.2 yum安装docker

    # 1)下载阿里源repo文件
    curl -o /etc/yum.repos.d/Centos-7.repo http://mirrors.aliyun.com/repo/Centos-7.repo
    curl -o /etc/yum.repos.d/epel-aliyun.repo http://mirrors.aliyun.com/repo/epel-aliyun.repo
    curl -o /etc/yum.repos.d/docker-ce.repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    yum clean all && yum makecache fast
    # 2)查看源中可用版本
    yum list docker-ce --showduplicates | sort -r
    # 3)yum安装指定版本docker
    yum install docker-ce-20.10.8 -y
    ## 安装旧版本:# yum install -y docker-ce-18.09.9
    ## 安装最新版:# yum install docker-ce
    # 4)配置源加速(阿里云:容器镜像服务 - 镜像加速)
    # 或直接访问如下连接,输入帐号密码即可获取自己的镜像加速地址
    ## https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
    mkdir -p /etc/docker
    vi /etc/docker/daemon.json
    {
      "registry-mirrors" : [
        "https://7ro8ynda.mirror.aliyuncs.com"
      ]
    }
    # 5)设置开机自启
    systemctl enable docker  
    systemctl daemon-reload
    # 6)启动docker
    systemctl start docker 
    # 7)查看docker信息
    docker info
    ps -ef |grep docker
    systemctl status docker
    # containerd
    ps -ef |grep containerd
    systemctl status containerd

    2.2 docker 常用操作

    2.2.1 docker核心要素

    docker有三大核心要素:仓库、镜像、容器,三者之间的关系如下图所示:

    • 镜像:包含了代码及其运行环境的包,类似于操作系统的ISO文件,是静态文件;
    • 容器:镜像运行后即是容器,可以对外提供服务;
    • 仓库:存储镜像的地方,类似于yum仓库,包括共有仓库如DockerHub和国内的阿里、网易等;私有仓库,如我们自己搭建的,可以搭建私有仓库的开源软件有官方推荐的Registry和比较著名的Harbor等。

    镜像是容器和仓库的桥梁,容器与仓库没有直接关系,他们是通过镜像建立联系的。

    我们要运行一个容器,就要从仓库中拉取对应的镜像,然后run起来,就成了可对外提供服务的容器。

    2.2.2. 镜像常用操作

    # 查看镜像列表
    docker images 
    # 或者
    docker image ls
    # 获取镜像(两个途径:从共有仓库获取,从私有仓库获取,默认从dockerHub仓库获取镜像
    docker pull nginx:alpine
    # 完整的写法是:
    docker pull docker.io/library/nginx:alpine
    # 为镜像打标签
    docker tag nginx:alpine localhost:5000/nginx:alpine
    # 说明:localhost:5000是我用官方推荐的Registry搭建的私有仓库
    docker push localhost:5000/nginx:alpine
    # 这样我们就可以将这个镜像推送到我们的私有仓库localhost:5000中
    # 查看私有仓库中的镜像
    curl -X GET http://localhost:5000/v2/_catalog
    {"repositories":["nginx"]}
    curl -X GET http://localhost:5000/v2/nginx/tags/list
    {"name":"nginx","tags":["alpine"]}
    # 根据Dockerfile构建一个自己的镜像(先预览一下,后面详细说明)
    docker build . -t my-nginx:ubuntu -f Dockerfile
    # 将镜像保存到本地
    docker save -o nginx-alpine.tar nginx:alpine
    # 删除本地镜像
    docker rmi nginx:alpine
    # 加载本地镜像
    docker load -i nginx-alpine.tar
    # 查询镜像被哪些镜像引用
    docker image inspect --format='{{.RepoTags}} {{.Id}} {{.Parent}}' $(docker image ls -q --filter since=镜像id)
    # 删除所有没有用到的镜像
    docker image prune -a   # docker版本最小为1.25

    2.2.3. 容器常用操作

    # 通过镜像启动容器(启动容器放后台运行)
    docker run --name my-nginx -d nginx:alpine
    # 查看容器列表
    docker ps
    docker ps -a     # 包含已经退出的容器
    # 进入一个已经启动的容器内部
    docker exec -ti my-nginx2 /bin/sh
    # 启动并进入容器(退出后,容器也退出状态)
    docker run -ti --name my-nginx3 nginx:alpine /bin/sh
    # 启动并进入容器,并且在退出容器后自动删除(测试某项功能的时候经常用到)
    docker run -ti --rm nginx:alpine /bin/sh
    / # ps
    PID   USER     TIME  COMMAND
        1 root      0:00 /bin/sh
        7 root      0:00 ps
    # 停止一个容器(此时容器为Exited状态)
    docker stop my-nginx
    # 启动一个停止的容器
    docker start my-nginx
    # 删除一个退出Exited状态的容器(正在运行的容器这种方式是删不掉的)
    docker rm my-nginx
    # 强制删除一个正在运行的容器
    docker rm -f my-nginx-alpine
    # 将容器内的端口映射到宿主机提供服务 -p <host_port>:<container_port>
    docker run --name nginx -d -p 8080:80 nginx:alpine
    # 资源限制,最大可用内存500M
    docker run --memory=500m nginx:alpine
    # 容器数据持久化 - 挂载主机目录
    docker run --name nginx -d  -v /opt:/opt  nginx:alpine
    docker run --name mysql -e MYSQL_ROOT_PASSWORD=123456 -d -v /opt/mysql/:/var/lib/mysql mysql:5.7
    # 容器与宿主机之间数据拷贝
    docker cp /tmp/test.txt nginx:/tmp
    # 容器拷贝到主机
    docker cp nginx:/tmp/test.txt ./
    # 查看容器日志
    docker logs my-nginx
    docker logs -f my-nginx
    docker logs --tail=100 -f my-nginx
    # 不进入容器执行命令查看容器内信息
    $ docker exec my-nginx ps aux
    # 容器的详细信息查看
    docker inspect my-nginx
    # 镜像的详细信息查看
    docker inspect nginx:alpine
    # docker运行容器测试,退出后删除容器(不是删除镜像),在日常工作中测试镜像经常用到
    docker run -it --rm ubuntu:14.04 bash
    ########## 容器批量操作 - 慎用 #########
    # 停止所有容器
    docker ps -a | grep "Exited" | awk '{print $1 }'|xargs docker stop
    # 删除所有容器
    docker ps -a | grep "Exited" | awk '{print $1 }'|xargs docker rm
    # 删除所有none容器
    docker images|grep none|awk '{print $3 }'|xargs docker rmi
    
    # 运行容器常用参数说明
    # -itd:在容器中打开一个伪终端进行交互操作,并在后台运行;
    # -v:把宿主机的/data/registry目录绑定 到 容器/var/lib/registry目录(这个目录是registry容器中存放镜像文件的目录),来实现数据的持久化;
    # -p:映射端口;访问宿主机的5000端口就访问到registry容器的服务了;
    # --restart=always:这是重启的策略,假如这个容器异常退出会自动重启容器;
    # --name registry:创建容器命名为registry,你可以随便命名;
    # registry:latest:这个是刚才pull下来的镜像;

    2.2.4 docker常用管理命令

    # 查看docker挂载目录volume
    docker inspect --format "{{.Config.Volumes}}" 676b04bec7c5
    # 查看Docker 磁盘使用情况
    docker system df
    # 清理磁盘
    docker system prune
    # 迁移数据目录
    rsync -avz /var/lib/docker /opt/data/docker
    # 配置mapper文件,根据docker服务的安装配置文件进行修改
    vim /usr/lib/systemd/system/dokcer.service
    # 在ExectStart=xxx 中添加属性
    ExectStart=xxx --graph /opt/data/docker
    # 利用Registry搭建本地docker仓库
    docker run -d -p 5000:5000 --restart always --name registry registry:2
    # 将本地仓库加入docker配置文件daemon.json中
    cat /etc/docker/daemon.json 
    {
        "graph": "/data/docker",
        "registry-mirrors": ["https://7ro8ynda.mirror.aliyuncs.com"],
        "insecure-registries": ["10.168.215.55:5000"],
    }
    # 重启docker服务
    systemctl restart docker

    2.2.5 docker常用选项说明

    # 常用选项说明
      -d, --detach=false, 指定容器运行于前台还是后台,默认为false
      -i, --interactive=false, 打开STDIN,用于控制台交互
      -t, --tty=false, 分配tty设备,该可以支持终端登录,默认为false
      -u, --user="", 指定容器的用户
      -a, --attach=[], 登录容器(必须是以docker run -d启动的容器)
      -w, --workdir="", 指定容器的工作目录
      -c, --cpu-shares=0, 设置容器CPU权重,在CPU共享场景使用
      -e, --env=[], 指定环境变量,容器中可以使用该环境变量
      -m, --memory="", 指定容器的内存上限
      -P, --publish-all=false, 指定容器暴露的端口
      -p, --publish=[], 指定容器暴露的端口
      -h, --hostname="", 指定容器的主机名
      -v, --volume=[], 给容器挂载存储卷,挂载到容器的某个目录
      --volumes-from=[], 给容器挂载其他容器上的卷,挂载到容器的某个目录
      --cap-add=[], 添加权限,权限清单详见:http://linux.die.net/man/7/capabilities
      --cap-drop=[], 删除权限,权限清单详见:http://linux.die.net/man/7/capabilities
      --cidfile="", 运行容器后,在指定文件中写入容器PID值,一种典型的监控系统用法
      --cpuset="", 设置容器可以使用哪些CPU,此参数可以用来容器独占CPU
      --device=[], 添加主机设备给容器,相当于设备直通
      --dns=[], 指定容器的dns服务器
      --dns-search=[], 指定容器的dns搜索域名,写入到容器的/etc/resolv.conf文件
      --entrypoint="", 覆盖image的入口点
      --env-file=[], 指定环境变量文件,文件格式为每行一个环境变量
      --expose=[], 指定容器暴露的端口,即修改镜像的暴露端口
      --link=[], 指定容器间的关联,使用其他容器的IP、env等信息
      --lxc-conf=[], 指定容器的配置文件,只有在指定--exec-driver=lxc时使用
      --name="", 指定容器名字,后续可以通过名字进行容器管理,links特性需要使用名字
      --net="bridge", 容器网络设置:
        bridge 使用docker daemon指定的网桥
        host //容器使用主机的网络
        container:NAME_or_ID >//使用其他容器的网路,共享IP和PORT等网络资源
        none 容器使用自己的网络(类似--net=bridge),但是不进行配置
      --privileged=false, 指定容器是否为特权容器,特权容器拥有所有的capabilities
      --restart="no", 指定容器停止后的重启策略:
        no:容器退出时不重启
        on-failure:容器故障退出(返回值非零)时重启
        always:容器退出时总是重启
      --rm=false, 指定容器停止后自动删除容器(不支持以docker run -d启动的容器)
      --sig-proxy=true, 设置由代理接受并处理信号,但是SIGCHLD、SIGSTOP和SIGKILL不能被代理

    2.2.6 介绍一个界面管理docker工具portainer

    我们运行docker后,会默认在/var/run下面有个docker.sock,这个工具就是根据这个sock文件来访问和管理本地的docker,使用方法如下:

    docker run --name portainer -d -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer

    然后访问 ip:9000

    后面的文章会介绍Dockerfile的使用,如何制作一个自己的镜像?敬请关注。

    人们永远没有足够的时间把它做好,但永远有足够的时间重新来过。 可是,因为并不是总有机会重做一遍,你必须做得更好,换句话说, 人们永远没有足够的时间去考虑到底是不是想要它,但永远有足够的时间去为之后悔。 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ 浅掘千口井,不如深挖一口井!当知识支撑不了野心时,那就静下心来学习吧!运维技术交流QQ群:618354452

    个人微信公众号,定期发布技术文章和运维感悟。欢迎大家关注交流。

  • 相关阅读:
    为什么大多数IOC容器使用ApplicationContext,而不用BeanFactory
    重温Java泛型,带你更深入地理解它,更好的使用它!
    看完了这篇,面试的时候人人都能单手撸冒泡排序!
    JAVA基础4---序列化和反序列化深入整理(Hessian序列化)
    VS Code 变身小霸王游戏机!
    equals()方法和hashCode()方法详解
    openFeign远程调用时使用Mybatis-plus的IPage接口进行返回分页数据失败的记录
    通过express快速搭建一个node服务
    UML 类图
    jdk命令行工具系列——检视阅读
  • 原文地址:https://www.cnblogs.com/miaocbin/p/15245518.html
Copyright © 2020-2023  润新知