docker思想
-
集装箱
将所有需要的内容放到不同的集装箱中,谁需要这些环境就直接拿到这个集装箱就可以了。
-
标准化
- 运输标准化,Docker有一个码头,所有上传的集装箱都在这个码头上,当谁需要某个环境,直接去搬运这个集装箱就可以。
- 命令标准化,docker提供了一些指令,帮助我们去操作获取。
- 提供了REST的API,衍生出了很多图形化界面,Rancher。
-
隔离性
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中央仓库
-
docker官方的中央仓库
-
国内镜像仓库,网易凤巢、daoclould....
我使用该网站拉取遇到的问题:
docker pull daocloud.io/library/tomcat:8.5.15-jre8 无法下载,报509,证书验证失败
解决方法:查看hub.daocloud.io/的证书,并下载它的二级…
-
公司内部采用私服的方式拉取(添加配置)
#需要在/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
可以查看已有的镜像
通过
docker pull 镜像名
来从仓库中拉取指定镜像,通过docker search redis
查看可用版本。
我们来拉取一个redis的最新镜像
运行redis容器:docker run -itd --name redis-test -p 6379:6379 redis
参数解释:
Options | Mean |
---|---|
-i | 以交互模式运行容器,通常与 -t 同时使用; |
-t | 为容器重新分配一个伪输入终端,通常与 -i 同时使用; |
-d | 后台运行容器,并返回容器ID; |
-p | 映射容器服务的 6379 端口到宿主机的 6379 端口。外部可以直接通过宿主机ip:6379 访问到 Redis 的服务。 |
通过docker ps
查看容器运行信息,docker ps -a
命令,查询所有的容器
进入我们的redis容器
docker exec -it redis-test /bin/bash或者docker exec -it 容器id /bin/bash
并尝试执行一条指令
通过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:删除状态
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
遇到的问题
- Navicat连接不上
查询网上资料,大概就是两点。修改mysql用户的权限,允许远程连接;开放宿主机的3306端口,允许外部进行访问。这两点我都已经改过,却发现依然连接不上,于是继续修改,还发现一个要打开服务的,于是放开了http和mysql,然后我还是连接不上。。。。折腾2小时,已崩。决定第二天用tcpdump抓包一下3306端口,本机进行telnet访问,看是否进来。第二天重新开机,发现可以连接了,只能证明一件事:重启大法好!!!!
- 附上相关指令:
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中的东西
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] .
如下图:
运行我们自定义的镜像:
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
遇到的问题
- 按照以上配置启动,一切正常,但是无法访问,监听端口也没有任何请求进来
排查:先确认是否是宿主机问题导致。把该doker-compose启动的容器停掉,换成命令行式的启动一个镜像,发现可以访问(一个插曲,我启动的tomcat映射的宿主机8081端口,该端口没有放开,本地却可以访问到),说明服务虚机应该没有问题。
搜索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
查看网络的具体配置信息
#docker network ls中得到的NAME docker network inspect 网络名
不配置网络就会默认新建一个,为什么新建的网桥无法与宿主机通信?
这个问题折磨了我许久,最终解决。先说结论,原因在于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的网络模型
启动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服务器
-
创建一个全新虚拟机,至少4G的内存
-
安装docker以及docker-compose
-
编写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介绍
持续交付、持续部署
通过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站找的一个视频然后进行学习的,整个实践过程中确实发现了好多问题,幸好最后都解决了。收获还是有的,可惜公司并没有使用容器技术、现在我都又快忘光了。。