• docker(一)—— docker安装与项目部署


    Docker 部署项目

    一、安装docker(Ubuntu)

    转自:https://blog.csdn.net/jinking01/article/details/82490688

    • 由于apt官方库里的docker版本可能比较旧,所以先卸载可能存在的旧版本:
    $ sudo apt-get remove docker docker-engine docker-ce docker.io
    
    • 更新apt包索引:
    $ sudo apt-get update
    
    • 安装以下包以使apt可以通过HTTPS使用存储库(repository):
    $ sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common
    
    • 添加Docker官方的GPG密钥:
    $ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
    
    • 使用下面的命令来设置stable存储库:
    $ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
    
    • 再更新一下apt包索引:
    $ sudo apt-get update
    
    • 安装最新版本的Docker CE:
    $ sudo apt-get install -y docker-ce
    
    • 验证docker
    $ systemctl status docker
    

    docker正常启动,状态如下图:

    • 若未启动,则启动docker服务:
    $ sudo systemctl start docker
    
    • 查看docker版本号验证
    $ sudo docker -v
    

    二、docker仓库配置

    1、设置公有仓库

    • 修改仓库配置文件
    $ vim /etc/docker/daemon.json
    

    {
      "registry-mirrors": ["https://registry.docker-cn.com"]
    }
    
    • 重启docker
    $ systemctl daemon-reload 
    $ systemctl restart docker
    

    常用国内加速站点:

    https://registry.docker-cn.com			国内
    http://hub-mirror.c.163.com				网易
    https://3laho3y3.mirror.aliyuncs.com		阿里
    http://f1361db2.m.daocloud.io
    https://mirror.ccs.tencentyun.com
    

    2、设置私有仓库

    参考:https://www.cnblogs.com/xiao987334176/p/9946915.html

    1)搭建私有仓库——私有服务器上

    • 搭建工具

    docker 官方提供了 registry 的镜像,可以使用它来建私有仓库。

    • 环境
    系统 IP 角色
    Ubuntu 18.04 10.0.0.0 docker 客户端服务器
    Ubuntu 18.04 10.0.0.1 docker 仓库服务器(root用户)
    • 都安装docker,修改docker源,并重启(参考一)

    • 在10.0.0.1上拉取registry

      docker pull registry
      
    • 在10.0.0.1上启动仓库

      docker run -d --name docker-registry --restart=always -p 5000:5000 registry
      

    2)设置私有仓库

    • 客户端10.0.0.0设置私有仓库地址,并重启

      $ vim /etc/docker/daemon.json
      
      {
        "registry-mirrors": ["https://registry.docker-cn.com"],
        "insecure-registries": ["10.0.0.1:5000"]		# 设置私有仓库地址
      }
      
      systemctl restart docker
      
    • 测试私有仓库

      在10.0.0.0下载一个镜像,如alpine

      sudo docker pull alpine
      

      打tag,镜像名称由registry和tag两部分组成,registry完整格式:[registry_ip]:[registry:port]/[user]/[image_name:version]

      sudo docker tag alpine 10.0.0.1:5000/alpine
      
    • 上传本地镜像

      sudo docker push 10.0.0.1:5000/alpine
      
    • 查看仓库镜像

      curl 10.0.0.1:5000/v2/_catalog
      

    三、拉取镜像

    1、登录仓库

    sudo docker login -u [user] -p [password] [ip:port]
    
    • user 仓库用户名
    • password 仓库密码
    • ip:port为仓库地址

    2、拉取镜像

    sudo docker pull [image_name]
    

    四、dockerfile编写

    在项目目录下创建Dockerfile文件

    参考:https://www.cnblogs.com/cloudfloating/p/11737447.html

    1、RUN

    RUN 指令是用来执行命令行命令的。RUN 指令的格式有两种:

    • shell 格式:RUN <命令>,就像直接在命令行中输入命令一样。

      RUN java -jar app.jar
      
    • exec 格式:RUN ["可执行文件", "参数1", "参数2"]

      RUN ["java", "-jar", "app.jar"]
      

    Dockerfile 中,每一个指令都会在镜像上建立一层,所以对于多个命令行,不要写多个 RUN 指令

    多个命令,在一个RUN中实现,使用 **&& **连接起来

    FROM ubuntu
    
    RUN apt-get update 
        && apt-get install -y redis
    

    2、COPY

    COPY 指令用来将宿主的文件目录复制到镜像中。有两种格式:

    • COPY [--chown=<user>:<group>] <源路径>... <目标路径>

      COPY app.jar /usr/src/
      
    • COPY [--chown=<user>:<group>] ["源路径1", ... "目标路径"]

      COPY ["app.jar", "config.yml", "/usr/src"]
      

    对于多个路径参数,最后一个为目标路径其他都是源路径目标路径 可以是绝对路径,也可以是相对于工作目录的路径(工作目录可以用 WORKDIR 来指定)。目标路径如果不存在,在复制文件前会先创建。

    3、CMD

    CMD 是容器启动命令,它指定了容器启动后要执行的程序。与 RUN 指令相似有两种形式:

    • shell 格式:CMD <命令>

      CMD echo 'Hello, world!''
      
    • exec 格式:CMD ["可执行文件", "参数1", "参数2", ...]

      CMD [ "sh", "-c", "echo 'Hello, world!'" ]
      

    还有一种参数列表格式:CMD ["参数1", "参数2", ...]。在指定了 ENTRYPOINT 指令后,可以用 CMD 指定参数。

    在使用 CMD 时,程序必须以前台运行,Docker 不是虚拟机,容器没有后台服务的概念。如果使用 CMD 运行一个后台程序,那么容器在命令执行完就会退出。

    CMD java -jar app.jar &
    

    以上命令让 app.jar 在后台运行,容器启动后就会立刻退出。Docker 容器与守护线程很相似,当所有前台程序退出后,容器就会退出。

    CMD 指定的命令可以在运行时替换,跟在镜像名称后面的参数将替换镜像中的 CMD

    docker run app echo $HOME
    

    以上命令运行容器时使用 echo $HOME 替换掉镜像中的启动命令。

    4、ENV

    ENV 指令用来设置环境变量,格式有两种:

    • ENV <key> <value
    • ENV <key1>=<value1> <key2>=<value2>

    环境变量在后面的其它指令中可以通过 $key 来使用:

    FROM ubuntu
    ENV VERSION="8-jre"
    
    RUN apt-get update 
        && apt-get install -y openjdk-$VERSION
    ...
    

    5、ARG

    ARG 指令指定构建参数,与 ENV 效果一样,都是设置环境变量。不同的是,ARG 设置的构建参数,在容器运行时不存在。

    格式:ARG <key>[=<默认值>],可以指定默认值,也可以不指定。

    FROM alpine
    ARG NAME="Hello, Docker!"
    
    RUN echo $NAME
    CMD echo $NAME
    

    对于以上 Dockerfile,在构建时可以看到输出,但是在运行容器时没有输出。

    ARG 设置的参数可以在构建命令中指定:docker build --build-arg <key>=<value>

    6、VOLUME

    VOLUME 指令用来定义匿名卷。

    • VOLUME <路径>
    • VOLUME ["路径1", "路径2", ...]

    对于数据库类需要保持数据的应用,其文件应该保存于卷(volume)中,在 Dockerfile 中,可以事先将指定的目录挂载为匿名卷。

    VOLUME /data
    

    这里 /data 目录在容器运行时自动挂载为匿名卷,任何写入 /data 中的数据都不会记录到容器的存储层。在运行时可以覆盖这个挂载设置:

    docker run -v dbdir:/data
    

    以上命令将 dbdir 目录挂载到了 /data,替换了 Dockerfile 中的挂载配置。

    7、EXPOSE

    EXPOSE 指令指定容器运行时暴露的端口。格式:EXPOSE <端口1> [<端口2> ...]

    FROM ubuntu
    EXPOSE 8080
    
    RUN apt-get update 
        && apt-get install -y tomcat8
    ...
    

    以上 Dockerfile 安装了 tomcat 应用,在运行容器时会暴露 8080 端口。

    EXPOSE 只是指定了容器暴露的端口,并不会在宿主机进行端口映射。在使用 docker run -P 时,会自动随机映射 EXPOSE 指定的端口,也可以使用 -p 指定端口:docker run -p <宿主端口>:<容器端口>

    8、WORKDIR

    WORKDIR 指令指定工作目录,即指定当前目录,类似于 cd 命令,以后各层的当前目录都是 WORKDIR 指定的目录。如果目录不存在,会自动创建。格式:WORKDIR <目录路径>

    不能把 Dockerfile 当成 Shell 脚本来写:

    RUN cd /src/app
    RUN java -jar app.jar
    

    以上操作中第二行的工作目录并不是 /src/app,两个指令不在同一层,第一个 RUN 指令的 cd 操作和第二个没有任何关系。因此要切换目录,应该使用 WORKDIR 来指定。

    9、USER

    USER 指令指定当前用户。与 WORKDIR 相似,会影响以后的层。USER 改变执行 RUNCMDENTRYPOINT 的用户。格式:USER <用户名>[:<用户组>]

    USER 指定的用户和组必须是事先创建好的,否则无法切换。

    # 添加用户
    RUN groupadd -r redis 
        && useradd -r -g redis redis
    USER redis
    ENTRYPOINT ["reids-server"]
    

    10、ONBUILD

    ONBUILD 指令后面跟的是其它指令,它在当前镜像构建时不会被执行,只有以当前镜像为基础镜像去构建下一级镜像时才会被执行。格式:ONBUILD <其它指令>

    FROM openjdk:8-jre-alpine
    WORKDIR /app
    ONBUILD COPY ./app.jar /app
    ...
    

    这个 Dockerfile 在构建时不会执行 ONBUILD

    FROM my-jre
    ...
    

    假设之前构建的镜像名是 my-jre,以上 Dockerfile 构建镜像时,原来的 ONBUILD 将执行。

    11、ENTRYPOINT

    ENTRYPOINT 的格式与 CMD 一样有两种格式。

    它和 CMD 一样都是指定容器启动的程序和参数,但稍有区别。当指定了 ENTRYPOINT 后,CMD 的内容将作为参数加到 ENTRYPOINT 后面。

    也就是变成了:

    <ENTRYPOINT> "<CMD>"
    

    ENTRYPOINT 可以让镜像像命令一样使用,当仅仅使用 CMD 时,run 命令中镜像名后面的参数会替换 CMD 的内容。使用 ENTRYPOINT 后,这些参数将附加到原来命令的后面。

    FROM alpine
    ENTRYPOINT [ "ls" ]
    

    使用以上 Dockerfile 构建的镜像运行容器:

    docker run app -al
    

    -al 参数将附加到 ENTRYPOINT 指定的命令后面,当容器启动时执行的是 ls -al

    12、Dockerfile案例

    FROM ubuntu:18.04    # 从仓库拉取一个Ubuntu 18.04的进项
    
    WORKDIR /root		# 容器中的工作目录
    
    RUN apt-get update && 
        apt-get install -y vim python3 python3-pip language-pack-zh* mysql-client	# 容器中安装环境
    
    RUN python3 -m pip install -r /root/requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple/    # 容器中安装项目依赖
    
    
    

    五、docker安装MySQL

    1、下载指定版本镜像

    docker pull mysql:8.0.21
    

    2、启动容器

    cd /home/up/docker_test		# 进入挂载文件
    
    docker run -p 3307:3306 --name mysql-8 -v $PWD/mysql_data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=hf1234 -d mysql:8.0.21			# $PWD 表示当前目录下
    
    -p:表示端口映射,冒号左面的是宿主机的端口,而右侧则表示的是MySQL容器内的端口
    --name:给MySQL容器取的名字
    -d:表示后台运行
    -e MYSQL_ROOT_PASSWORD:设置root用户密码
    -v:表示挂载路径,冒号左面的表示宿主机的挂载目录,冒号右边则表示容器内部的路径。
    

    3、进入容器

    docker exec -it mysql-8 bash
    
    msyql -uroot -p			# 登录数据库
    

    可能出现的错误:

    4、可设置远程访问

    use mysql;
    
    select host,user from user;
    
    ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '<root_password>';
    
    flush privileges;
    

    六、docker容器间通信

    如果在同一个主机上,MySQL为一个容器,django项目为另一个容器,那么就需要两个容器能够互相访问

    1、案例

    django应用容器MySQL容器

    cd /home/xx/docker_recoder	# 宿主机挂载目录
    xx@xx: /home/xx/docker_recoder: $ docker run -d --name mysqlserver -v $PWD/mysql/mysql_data:/var/lib/mysql -p3307:3306 mysql:latest  # 运行MySQL容器
    
    xx@xx: /home/xx/docker_recoder: $ docker run -d --name django-web -v $PWD/web/logs:/root/web/logs -p8001:8000 django_web:1.0  # 启动django应用容器,$PWD表示当前目录
    

    注意事项

    • 在django中MySQL的host用MySQL容器内部的 ipport为容器内部的port(3306)

      • 可通过docker inspect mysqlserver查看容器信息,无需安装工具
      • 可通过进入容器后,ifconfig获取容器ip,但是需要安装ifconfig,如下第三点所示安装方法

    • 查看容器间能否通信,可以ping <container ip>,能ping通说明能通信

      ping 172.17.0.3
      
    • 如果无pingifconfig等工具

      # 安装ping
      apt-get install inetutils-ping
      
      # 安装ifconfig
      apt-get install net-tools
      

    2、实现同主机容器间通信

    在安装好docker后,docker将创建一个linux网桥docker0,它在内核层连通了其他的物理或虚拟网卡,也就是所有容器和本地主机都放到同一个物理网络。docker还会给我们创建三个网络:bridge/host/none网桥bridge模式是在实际项目中常用的,在没有指定相关网络的情况下,容器都会连接到默认的bridge网络。可以通过 --network 参数指定容器连接的网络。

    docker network ls		# 查看宿主机中所有的docker网络
    

    (1)link连接

    默认的桥接网络支持使用端口映射和docker run --link命令,实现容器间互相通信。该方法已经在官方文档中标识为不推荐使用

    (2)自定义bridge网络,实现容器间通信

    从 Docker 1.10 版本开始,docker daemon 实现了一个内嵌的 DNS server,使容器可以直接通过“容器名”通信。使用默认的bridge网络,不能通过DNS server实现通过容器名通信,但是使用自定义bridge网络可以做到通过容器名互相通信

    0)使用默认的网桥,即启动容器时,不指定--network,此时可通过 ip进行ping,但是不能通过容器名进行ping

    进入容器,查看hosts,此时hosts中并没有其他容器的信息

    docker exec -it contian-name bash
    cat /etc/hosts
    

    1)创建网桥

    docker network create --driver=bridge mybridge
    
    docker network create 
      --driver=bridge 
      --subnet=172.28.5.0/24 
      --ip-range=172.28.5.0/24 
      --gateway=172.28.5.1 
      mybridge
    

    2)使用自定义网桥启动容器

    通过--network指定网桥

    docker run --name name --network mybridge -p 8001:8000 image_id
    

    3)查看容器网桥

    docker network inspect mybridge
    

    如图,两个容器mysql-test、django-test都绑在了该网桥

    3、容器加入网桥的方式

    1)启动容器时,通过--network指定网桥

    docker run --network
    

    2)启动容器后,加入网桥

    docker run  --name my-name    # 不指定网桥
    
    docker network connect my_bridge my-name		 # 通过 docker network connect 为已启动的容器添加网桥
    

    七、docker化部署流程

    1. docker pull mysql:8.0拉取MySQL的镜像

    2. 项目中编写Dockerfiledocker build -t image_name .制作项目镜像

    3. 创建网桥,docker network create --driver=bridge mybridge

    4. 启动容器

      docker run -d --name mysql-1 --network mybridge -e MYSQL_ROOT_PASSWORD=123123 -v /home/xx/mysql_data:/var/lib/mysql -p 3307:3306 mysql:8.0

      docker run --name django-test --network mybridge -p 8001:8000 django_test:latst

    5. 进入容器,可修改项目的配置,或者将配置文件通过-v挂载到宿主机

  • 相关阅读:
    轻松掌握Ajax.net系列教程十二:使用TabContainer&TabPanel
    轻松掌握Ajax.net系列教程十五:使用AutoCompleteExtender
    一步一步学Linq to sql(二):DataContext与实体
    一步一步学Linq to sql(十):分层构架的例子
    轻松掌握Ajax.net系列教程十四:使用CalendarExtender
    一步一步学Linq to sql(八):继承与关系
    整理了一些tsql技巧
    一步一步学Linq to sql(三):增删改
    数据库连接字符串大全
    海量数据库的查询优化及分页算法方案
  • 原文地址:https://www.cnblogs.com/linagcheng/p/13440287.html
Copyright © 2020-2023  润新知