社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  docker

docker入门

立刀流 • 4 年前 • 481 次点击  
阅读 6

docker入门

docker思想

  1. 集装箱

    将所有需要的内容放到不同的集装箱中,谁需要这些环境就直接拿到这个集装箱就可以了。

  2. 标准化

    1. 运输标准化,Docker有一个码头,所有上传的集装箱都在这个码头上,当谁需要某个环境,直接去搬运这个集装箱就可以。
    2. 命令标准化,docker提供了一些指令,帮助我们去操作获取。
    3. 提供了REST的API,衍生出了很多图形化界面,Rancher。
  3. 隔离性

    docker在运行集装箱内的内容时,会在linux内核中,单独开辟一个空间,这个空间不会影响到其他程序。

注册中心。(超级码头、上面放的就是集装箱)

镜像。(集装箱)

容器。(运行起来的镜像)

安装docker

#1.下载docker依赖环境
yum -y install yum-utils device-mapper-persistent-data lvm2
#2.设置下载docker的镜像源
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
#3.安装docker
yum makecache fast
yum -y install docker-ce
#4.启动,并设置开机自动启动,测试
#启动docker服务
systemctl start docker
#设置开机启动
systemctl enable docker
#测试
docker run hello-world
复制代码

我这里遇到几点问题

1.安装失败,重新执行yum -y install docker-ce安装即可;

2.启动失败,报错start request repeated too quickly for docker.service,用dockerd指令重新执行,看报错信息, Error while creating filesystem xfs on device docker-8:3-34889290-base: exit status 1 storage-driver=devicemapper。网上查询是由于XFS文件系统管理工具的版本太低,使用如下命令升级:yum update xfsprogs -y。再启动。查看状态systemctl status docker

3.启动成功后运行hello-world失败,报错docker: Cannot connect to the Docker daemon at unix:///var/run/docker.sock.,查了一圈资料感觉都不对。重新启动虚拟机,重启docker,再次运行,成功。

注:docker 版本(Docker version 19.03.12, build 48a66213fe)

docker中央仓库

  1. docker官方的中央仓库

  2. 国内镜像仓库,网易凤巢、daoclould....

    hub.daocloud.io/ 推荐

    我使用该网站拉取遇到的问题:

    docker pull daocloud.io/library/tomcat:8.5.15-jre8 无法下载,报509,证书验证失败

    解决方法:查看hub.daocloud.io/的证书,并下载它的二级…

  3. 公司内部采用私服的方式拉取(添加配置)

    #需要在/etc/docker/daemon.json添加配置,ip:port为私服地址
    {
    "registry-mirrors":["https://registry.docker-cn.com"],
    "insecure-registries":["ip:port"]
    }
    #重启两个服务
    systemctl daemon-reload
    systemctl restart docker
    复制代码

docker镜像

通过docker images可以查看已有的镜像

image-20200909153928273.png 通过docker pull 镜像名来从仓库中拉取指定镜像,通过docker search redis查看可用版本。

我们来拉取一个redis的最新镜像

image-20200909165232821.png

运行redis容器:docker run -itd --name redis-test -p 6379:6379 redis

参数解释:

OptionsMean
-i以交互模式运行容器,通常与 -t 同时使用;
-t为容器重新分配一个伪输入终端,通常与 -i 同时使用;
-d后台运行容器,并返回容器ID;
-p映射容器服务的 6379 端口到宿主机的 6379 端口。外部可以直接通过宿主机ip:6379 访问到 Redis 的服务。

通过docker ps查看容器运行信息,docker ps -a命令,查询所有的容器

image-20200909165658061.png 进入我们的redis容器

docker exec -it redis-test /bin/bash或者docker exec -it 容器id /bin/bash
复制代码

并尝试执行一条指令

image-20200909170210744.png

通过docker stop 容器id去停止一个容器,docker restart 容器id去重启一个容器。

镜像删除使用 docker rmi 命令,比如我们删除 hello-world 镜像:

 docker rmi hello-world 或 docker rmi 镜像id
 #停止全部容器
 docker stop $(docker ps -qa)
 #删除全部容器
 docker rm $(docker ps -qa)
复制代码

如果该镜像运行过,需要先删除容器,docker rm 容器id,否则会删除失败

镜像导入导出

#导出镜像
docker save -o ./test.images 镜像id
#导入镜像
docker load -i test.images
#修改镜像名称
docker tag 镜像id 新镜像名称:版本
#导出容器
docker export ./test.tar 镜像id
#导入容器,实质也是将容器运行时的镜像导入,并给导入的镜像命名
docker import ./test.tar mytest
复制代码

查看容器日志

docker logs -f 容器id
复制代码

清除没有被容器使用的镜像文件

docker image prune -af 
#清除多余的数据,包括停止的容器、多余的镜像、未被使用的volume等等
docker system prune -f 
复制代码

容器生命周期

容器的生命周期是容器可能处于的状态,容器的生命周期分为 5 种。

created:初建状态

running:运行状态

stopped:停止状态

paused: 暂停状态

deleted:删除状态

image-20201031114826169.png

docker应用

准备项目

准备mysql容器

#运行mysql容器,--name指定了容器的名字,指定了root用户的密码,冒号后tag参数指定了要运行的版本
docker run -d -p 3306:3306 --name mysql -e MYSQL_ROOT_PASSWORD=root daocloud.io/library/mysql:5.7.4
复制代码

遇到的问题

  1. Navicat连接不上

查询网上资料,大概就是两点。修改mysql用户的权限,允许远程连接;开放宿主机的3306端口,允许外部进行访问。这两点我都已经改过,却发现依然连接不上,于是继续修改,还发现一个要打开服务的,于是放开了http和mysql,然后我还是连接不上。。。。折腾2小时,已崩。决定第二天用tcpdump抓包一下3306端口,本机进行telnet访问,看是否进来。第二天重新开机,发现可以连接了,只能证明一件事:重启大法好!!!!

  1. 附上相关指令:

centos7默认防火墙为filewall

  • 放通端口 firewall-cmd --zone=public --add-port=3306/tcp --permanent firewall-cmd --reload 查看所有开放的端口 firewall-cmd --zone=public --list-ports

  • 放通服务

    查看可以打开的服务 firewall-cmd --get-services 添加一个服务 firewall-cmd --permanent --add-service=http 查看已经打开的服务 firewall-cmd --list-services

  • 放通mysql远程权限

    docker exec -it 容器id bash //进入容器

    mysql -uroot -p //进入mysql命令行

    use mysql

    ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'root'; //允许任何客户端连接

    flush privileges; //刷新权限

    SELECT user,host FROM user //host为%为都可以连接

准备tomcat容器

#启动tomcat,记得开放防火墙8080端口
docker run -itd --name tomcat -p 8080:8080 daocloud.io/library/tomcat:8.5.15-jre8
#通过命令将宿主机的内容复制到tomcat容器
#docker cp 文件名称 容器id:容器内部路径
docker cp test.tar f3:/usr/local/tomcat/webapps/
复制代码

数据卷

将宿主机的一个目录映射到容器的一个目录中,操作宿主机中文件,则容器内的也会发生变化

#创建数据卷
docker volume create 数据卷名称
#创建之后,默认会存放在一个目录下 /var/lib/docker/volumes/数据卷名称/_data
#查看数据卷详细信息
docker volume inspect tomcat
#查询全部数据卷
docker volume ls
#删除数据卷
docker volume rm 数据卷名称
#应用数据卷
#当映射数据卷时,数据卷如果不存在,docker会自动创建,这种方式会将容器中自带的文件也存储在默认存放路径中
docker run -v 数据卷名称:容器内部路径 镜像id
#直接指定一个路径作为数据卷的存放位置,这种不会默认存储容器中的文件(推荐)
docker run -v 路径:容器内部路径 镜像id
复制代码

在运行镜像时指定数据卷映射:

docker run -d -p 8080:8080 --name tomcat -v tomcat:/usr/local/webapps/ b43
复制代码

启动tomcat时指定数据卷,我们就会在/var/lib/docker/volumes/tomcat/_data下发现webapps中的东西

image-20200912115551716.png

docker自定义镜像

#创建Dokerfile文件,并且指定自定义镜像信息
#Dockerfile文件中常用的内容
from:指定当前自定义镜像依赖的环境
copy:将相对路径下的内容复制到自定义镜像中
workdir:声明镜像的默认工作目录
cmd:需要执行的命令(在workdir下执行的,cmd可以写多个,只以最后面一个为准)
复制代码

举例:自定义一个Dockerfile文件,并将我们的hellodocker.war部署,打包成自己的镜像

#Dockerfile内容
from daocloud.io/library/tomcat:8.5.15-jre8
copy hellodocker.war /usr/local/tomcat/webapps
复制代码
#通过docker指令制作镜像,把当前目录下的Dockerfile文件制作成一个镜像
docker bulid -t  镜像名称:[tag] .
复制代码

如下图:

image-20200912144255308.png

运行我们自定义的镜像:

image-20200912144524266.png

docker-compose的使用

之前运行一个镜像是需要加大量的参数,可以通过docker-compose编写这些参数。

docker-compose可以帮助我们批量管理容器,它是一个容器编排工具。

只需要通过一个docker-compose.yml文件去维护即可。

#下载docker-compose
#由于github网站太卡,可以用http://get.daocloud.io/去下载,根据实际情况修改版本
curl -L https://get.daocloud.io/docker/compose/releases/download/1.27.2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
复制代码

docker-compose管理mysql和tomcat容器

编写yml配置信息,version版本对照:docs.docker.com/compose/com…

我的目录及数据存储:/opt/docker_mysql_tomcat

version: '3.8'
services:
  mysql:            #服务的名称
    restart: always   #代表只有docker启动,容器就跟着启动
    network_mode: bridge   #指定使用已有网络,不会生成默认的网络
    image: daocloud.io/library/mysql:5.7.4    #指定镜像
    container_name: mysql   #指定容器名称
    ports:
      - 3306:3306   #端口号映射
    environment:
      MYSQL_ROOT_PASSWORD: root   #指定root用户密码
      TZ: Asia/shanghai     #指定时区
    volumes:
      - /opt/docker_mysql_tomcat/mysql_data:/var/lib/mysql   #映射数据卷
  tomcat:
    restart: always
    network_mode: bridge


    

    image: docker-tomcat:1.0.0
    container_name: docker-tomcat
    ports:
      - 8080:8080
    environment:
      TZ: Asia/shanghai
    volumes:
      - /opt/docker_mysql_tomcat/tomcat_webapps:/usr/local/tomcat/webapps
      - /opt/docker_mysql_tomcat/tomcat_logs:/usr/local/tomcat/logs
复制代码

使用docker-compose命令管理容器

在使用docker-compose命令时,默认会在当前目录下找docker-compose.yml文件

#第一次启动,在docker-compose文件所在目录下
docker-compose up -d
#停止
docker-compose stop
#开启
docker-compose start
#重启
docker-compose restart
#停止并删除
docker-compose down
#查看
docker-compose ps
#查看日志
docker-compose logs -f 
复制代码

遇到的问题

  1. 按照以上配置启动,一切正常,但是无法访问,监听端口也没有任何请求进来

排查:先确认是否是宿主机问题导致。把该doker-compose启动的容器停掉,换成命令行式的启动一个镜像,发现可以访问(一个插曲,我启动的tomcat映射的宿主机8081端口,该端口没有放开,本地却可以访问到),说明服务虚机应该没有问题。

  1. 搜索docker-compose启动正常,服务无法访问的问题,也没有太多有效信息。这里我想起了之前了解过一点点docker容器会自己生成一套网络相关的东西,不同的网络模式会造成无法访问。

    #查询已配置的网络
    docker network ls
    #结果如下,其中docker_mysql_tomcat_default正式默认生成的
    NETWORK ID          NAME                          DRIVER              SCOPE
    2a460ca90250        bridge                        bridge              local
    3e0eb402b8e4        docker_mysql_tomcat_default   bridge              local
    cc495b89bd29        host                          host                local
    a300f2ee0209        none                          null                local
    #比较命令行启动的容器信息与docker-compose启动的容器信息
    docker inspect 容器id
    #配置docker-compose的网络,在每个容器名字下再添加一行,使用已有的网络,上面配置已添加
    network_mode: bridge
    复制代码
  2. 查看网络的具体配置信息

    #docker network ls中得到的NAME
    docker network inspect 网络名
    复制代码
  3. 不配置网络就会默认新建一个,为什么新建的网桥无法与宿主机通信?

    这个问题折磨了我许久,最终解决。先说结论,原因在于linux内核版本太低,需要升级内核。

    我是从这篇博客得到的启发:blog.csdn.net/coolfishbon…

    升级后,再次重新创建一个网桥,随便启动一个镜像用这个建好的网桥,进入容器内部,ping自己的网关,在ping自己的虚机地址,都可以ping通,说明已经可以正常的使用了。

docker-compose 配合Dockerfile使用

使用docker-compose.yml文件和Dockerfile文件在生成自定义镜像的同时启动当前镜像,并且由docker-compose去管理容器。

#yml文件
version: '3.8'
services:
  hello:
    restart: always
    build:              #构建自定义镜像
      context: ../      #指定Dockerfile文件所在目录
      dockerfile: Dockerfile
    image: hello:1.0.0
    container_name: hello
    ports:
      - 8081:8080
    environment:
      TZ: Asia/shanghai

复制代码

Dockerfile文件

from daocloud.io/library/tomcat:8.5.15-jre8
copy hellodocker.war /usr/local/tomcat/webapps
复制代码
#基于docker-compose以及Dockerfile构建自定义镜像
docker-compose up -d
#如果自定义镜像不存在,会进行构建,如果已经存在,则直接运行
#重新构建的话,用下面命令
docker-compose bulid 或者 docker-compose up -d --bulid
复制代码

#我的目录结构
/root/docker-tomcat/docker-compose   -------docker-compose.yml
/root/docker-tomcat   ----docker-compose  -------Dockerfile  ------hellodocker.war
复制代码

docker网络

Docker中的网络接口默认都是虚拟的接口,沙盒 ( Sandbox )网络 ( Network )、**端点 ( Endpoint )**三者形成了 Docker 网络的核心模型,也就是容器网络模型。我们看下docker的网络模型

image.png 启动docker会创建一个docker0的默认网桥,用来与宿主机和容器进行通信,网桥上有一个地址段与网关,每个容器的ip都从地址段中进行获取。

docker的默认网络

$ docker network ls
NETWORK ID          NAME                DRIVER
7fca4eb8c647        bridge              bridge
9f904ee27bf5        none                null
cf03ee007fb4        host                host
复制代码

docker的网络模式一个有下面几种:

1)bridge模式,--net=bridge(默认)
这是dokcer网络的默认设置,为容器创建独立的网络命名空间,容器具有独立的网卡等所有单独的网络栈,是最常用的使用方式。
在docker run启动容器的时候,如果不加--net参数,就默认采用这种网络模式。安装完docker,系统会自动添加一个供docker使用的网桥docker0,我们创建一个新的容器时,
容器通过DHCP获取一个与docker0同网段的IP地址,并默认连接到docker0网桥,以此实现容器与宿主机的网络互通。
 
2)host模式,--net=host
这个模式下创建出来的容器,直接使用容器宿主机的网络命名空间。
将不拥有自己独立的Network Namespace,即没有独立的网络环境。它使用宿主机的ip和端口。
 
3)none模式,--net=none
为容器创建独立网络命名空间,但不为它做任何网络配置,容器中只有lo,用户可以在此基础上,对容器网络做任意定制。
这个模式下,dokcer不为容器进行任何网络配置。需要我们自己为容器添加网卡,配置IP。
因此,若想使用pipework配置docker容器的ip地址,必须要在none模式下才可以。
 
4)Overlay模式,--net=overlay
容器在两个跨主机进行通信的时候,是使用overlay network这个网络模式进行通信,如果使用host也可以实现跨主机进行通信,直接使用这个物理的ip地址就可以进行通信。
 
5)用户自定义:docker 1.9版本以后新增的特性,允许容器使用第三方的网络实现或者创建单独的bridge网络,提供网络隔离能力。
复制代码

网络相关操作

#创建指定网段、网关的网络,-d指定什么模式
docker network create -d bridge --subnet=172.22.0.0/24 --gateway=172.22.0.1 my_net
#创建的网络用ifconfig查看,都是br-{networkid},如果要展示网络名,可以这样
docker network create -d bridge --subnet=172.22.0.0/24 --gateway=172.22.0.1 my_net -o com.docker.network.bridge.name=my_net
#查看已有的网络
docker network ls
#删除一个网络
docker network rm 网络名
#查看网络信息
docker network inspect 网络名

复制代码

docker CI、CD

CI介绍

CI(continuous intergration)持续集成

持续集成:编写代码,提交git,将项目重新构建并测试。

搭建gitlab服务器

  1. 创建一个全新虚拟机,至少4G的内存

  2. 安装docker以及docker-compose

  3. 编写docker-compose.yml文件,修改虚机ssh的端口号,因为gitlab要占用22端口

    镜像地址:github.com/CCC1004/git… 整个下载过程可能比较长

    version '3'
    services:
      gitlab:
        image: 'twang2218/gitlab-ce-zh:11.1.4'
        container_name: 'gitlab'
        restart: always
        privileged: true
        hostname: 'gitlab'
        environment:
          TZ: 'Asia/shanghai'
          GITLAB_OMNIBUS_CONGIG: |
          external_url 'http://192.168.199.110'  #宿主机ip
          gitlab_rails['time_zone']='Asia/shanghai'
          gitlab_rails['smtp_enable']=true
          gitlab_rails['gitlab_shell_ssh_port']=22
        ports:
          - 80:80
          - 443:443
    
    
        
    
          - 22:22
        volumes:
          - /opt/docker_gitlab/config:/etc/gitlab
          - /opt/docker_gitlab/data:/var/opt/gitlab
          - /opt/docker_gitlab/logs:/var/log/gitlab
    复制代码

安装gitlab-runner

CD介绍

持续交付、持续部署

image-20200913212345623.png

通过gitlab-runner实时部署服务器环境,自测无问题后通过Jenkins部署测试环境,供测试人员测试,最后发布到生产环境。这就是CI、CD模型。

搭建Jenkins

编写docker-compose.yml

version '3'
services:
  jenkins:
    image: jenkins/jenkins
    restart: always
    container_name: jenkins
    ports:
      - 8888:8080
      - 5000:5000
    volumes:
      - ./data:/var/jenkins_home    #data目录授777权限
复制代码

登陆密码在日志中,安装插件【publish ssh】、【git parameter】

小结

这个教程呢,我是在b站找的一个视频然后进行学习的,整个实践过程中确实发现了好多问题,幸好最后都解决了。收获还是有的,可惜公司并没有使用容器技术、现在我都又快忘光了。。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/110589
 
481 次点击