四、容器管理
- 容器的生命周期实践
- 什么是容器
容器类似于胶囊公寓,它是一个精简版的操作系统,一般容器中只运行一个应用(例如:eureka-server镜像)。 - 如何创建容器
通过镜像创建容器,通过docker run命令创建。 - 容器的作用
容器起到了隔离的作用,独享空间、网络等等。 - doker命令
docker run --help -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不能被代理
- docker创建示例
docker run -d -p 5000:5000 \ --restart=always \ --privileged=true \ --name=registry-local-jackly \ -v /date/volume/registry:/var/lib/registry \ registry
- docker常用命令
#查看正在运行的容器 docker ps #查看所有的容器(包括已经停止的容器) docker ps -a #停止容器 docker stop 容器ID #强制停止容器 docker kill 容器ID #启动容器 docker start 容器ID #重启容器 docker restart 容器ID #删除已经停止的容器 docker rm 容器ID #删除正在运行的容器,强制删除 docker rm -f 容器ID
- 如何进入容器内部
- 进入容器的方式
有4种方式能进入容器,分别为 exec、docker attach、ssh、nsenter. 这4种都能进入容器,但是最好用最常用的是exec - exec命令
docker exec --help -d 以后台方式执行,这样,我们执行完这条命令,还可以干其他事情,写脚本最常用 -e 代表环境变量 -i 以交互方式运行,是阻塞式的 -t 分配一个伪终端,这个参数通常与-i参数一起使用,然后在后面跟上容器里的/bin/bash,这样就把我们带到容器里去了。 -u 指定进入的容器以哪个用户登陆,默认是root
- 进入容器命令
#启动镜像,若镜像容器已经创建,则通过docker ps -a查询停止的容器id,在通过docker start 容器ID 启动容器 docker run -d -p 8761:8761 --name=eureka registry-jackly/eureka-server:1.0.0 #进入容器的相关命令 docker exec -it eureka sh #进入后可以使用ls查看目录(/app/service/eureka/data/app.jar) docker exec -it eureka /bin/bash docker exec -it eureka pwd docker exec -it eureka top
- 容器内容改变后,能否重新生成镜像
- 使用ll命令验证
①、进入容器:docker exec -it eureka /bin/bash ②、修改容器内容:echo "alias ll='ls -l'" >> ~/.bashrc && source ~/.bashrc ③、验证ll命令:ll ④、强制删除容器:docker rm -f 容器ID ⑤、启动镜像容器:docker run -d -p 8761:8761 --name=eureka registry-jackly/eureka-server:1.0.0 ⑥、进入容器使用ll命令:发现先前修改的实效
- 修改容器后,重新生成镜像
①、进入容器:docker exec -it eureka /bin/bash ②、修改容器内容:echo "alias ll='ls -l'" >> ~/.bashrc && source ~/.bashrc ③、验证ll命令:ll #生成镜像命令 docker commit --help -a 用来指定作者 -c 使用Dockerfile指令来创建镜像 -m 描述我们此次创建image的信息 -p 在commit时,将容器暂停 ④、重新生成镜像 docker commit -m="add ll" --author="jackly" eureka registry-jackly/eureka-server:2.0.0 ⑤、启动新镜像 docker run -d -p 8761:8761 --name=eureka registry-jackly/eureka-server:2.0.0
五、网络管理
- 外部网络如何访问容器应用
- 外部访问容器应用,是通过端口来实现的
#参数-p,指定端口,其中 8080是宿主机的端口,80是容器的端口 docker run -d -p 8080:80 nginx #参数-P(大写),随机端口,随机范围 32769-60999 docker run -d -P nginx
- dockerfile的端口实现规则
(1)有开放 EXPOSE 8761
#参数-p,指定端口 docker run -d -p 8761:8761 --name=eureka registry-agan/eureka-server:1.0.0 #参数-P,随机端口( 达到的效果是0.0.0.0:32771->8761) docker run -d -P --name=eureka registry-jackly/eureka-server:2.0.0
- (2)没有开放 EXPOSE 8761
#参数-p,指定端口(效果:正常) docker run -d -p 8761:8761 --name=eureka registry-jackly/eureka-server:2.0.0 #参数-P,随机端口( 达到的效果是,无端口号,连内部容器都没有端口) docker run -d -P --name=eureka registry-jackly/eureka-server:2.0.0
- 如何实现容器之间的网络通信
- 业务场景为4个容器
mysql、eureka、product、config - 安装mysql
#启动mysql容器 docker run -p 3306:3306 --name mysql \ -e MYSQL_ROOT_PASSWORD=agan \ -d mysql:5.7 #进入mysql容器 docker exec -it mysql /bin/bash #docker镜像没有ifconfig、ping指令 apt-get update apt install net-tools # ifconfig apt install iputils-ping # ping
- 创建eureka容器
docker run -d -p 8761:8761 --name=eureka registry-jackly/eureka-server:2.0.0
- 部署config镜像和容器(加入config有问题,暂时未找到原因)
dockerfile:
#1.基础镜像:FROM指令:基础镜像名:tag,例如java:8 FROM java:8 #2.维护者:格式:MAINTAINER <name> MAINTAINER jackly #3.镜像的操作指令 # ADD拷贝一个文件到容器中,格式:ADD <src> <dest> ADD config-server-0.0.1-SNAPSHOT.jar /app/service/config/data/app.jar #5.配置容器启动后,执行什么命令 ENTRYPOINT ["java","-jar","/app/service/config/data/app.jar"]
- 构建镜像
#其中 -t 对镜像进行命名,一般的命名法:仓库名字/镜像名字:版本号 #注意:其中 .号,代表当前目录下的dockerfile文件 docker build -t registry-jackly/config-server:1.0.0 .
- 创建容器
#查看本地镜像 docker images #启动镜像 link eureka:jacklyureka==>link 容器名称:别名(将配置中心服务注册到eureka) docker run -d -p 9030:9030 --name config \ --link eureka:jacklyureka \ registry-jackly/config-server:1.0.0 #查看config信息 http://172.31.65.26:9030/e-book-product/deauflt
- 进入config容器
查看eureka注册信息
- 部署product镜像和容器
dockerfile:
#1.基础镜像:FROM指令:基础镜像名:tag,例如java:8 FROM java:8 #2.维护者:格式:MAINTAINER <name> MAINTAINER jackly #3.镜像的操作指令 # ADD拷贝一个文件到容器中,格式:ADD <src> <dest> ADD e-book-product-core-0.0.1-SNAPSHOT.jar /app/service/product/data/app.jar #5.配置容器启动后,执行什么命令 ENTRYPOINT ["java","-jar","/app/service/product/data/app.jar"]
- 构建镜像
#其中 -t 对镜像进行命名,一般的命名法:仓库名字/镜像名字:版本号 #注意:其中 .号,代表当前目录下的dockerfile文件 docker build -t registry-jackly/product-server:1.0.0 .
- 创建容器
#查看本地镜像 docker images #启动镜像 注:link就是容器直接的连接,你不用IP的情况下可以通过link来实现容器名之间的通信;它的语法是 link 容器名:别名 docker run -d -p 8083:8083 --name product \ --link mysql:jacklymysql \ --link eureka:jacklyeureka \ registry-jackly/product-server:1.0.0 #验证效果 http://172.31.65.26:8761/ http://172.31.65.26:8083/product/findAllProduct
- link原理
#原理就是在prodct容器中的hosts加了2条记录。 docker exec -it product /bin/bash cat /etc/hosts
六、数据管理
- docker容器的数据如何共享给宿主机
- 宿主机查看eureka日志
1)使用docker run volume方式实现
#构建镜像 docker build -t registry-jackly/eureka-server:2.0.0 . #创建容器 #就是把docker的数据保存到宿主机的磁盘中,通常说的就是挂载点,或者叫做卷。 #语法: -v 宿主机目录:容器目录 docker run -d -p 8761:8761 --name=eureka \ --privileged=true \ -v /app/service/eureka/logs:/opt/data \ registry-jackly/eureka-server:2.0.0
- 2)使用dokcerfile方式实现
#1.基础镜像:FROM指令:基础镜像名:tag,例如java:8 FROM java:8 #2.维护者:格式:MAINTAINER <name> MAINTAINER jackly #3.加入挂载点 VOLUME /opt/data #4.镜像的操作指令 # ADD拷贝一个文件到容器中,格式:ADD <src> <dest> ADD eureka-server-0.0.1-SNAPSHOT.jar /app/service/eureka/data/app.jar #5.告诉docker容器暴露端口,在容器启动的时候,需要通过-p 做端口映射 EXPOSE 8761 #6.配置容器启动后,执行什么命令 ENTRYPOINT ["java","-jar","/app/service/eureka/data/app.jar"]
#重新构建eureka docker build -t registry-jackly/eureka-server:3.0.0 . #创建容器 docker run -d -p 8761:8761 --name=eureka \ --privileged=true \ registry-jackly/eureka-server:3.0.0
- 注意点:dockerfile volume 无法指定宿主机的目录,都是自动生成,而且是随机的;默认在/var/lib/docker/volumes/。
(为什么是随机生成?因为dockerfile无法确定每台宿主机是否都存在目录)
#如何找到宿主机的挂载目录? docker inspect eureka #信息段 "Mounts": [ { "Type": "volume", "Name": "cf527694ebafb92426a52f1916b26832b4c8977093083450a96fbccb3d866669", "Source": "/var/lib/docker/volumes/cf527694ebafb92426a52f1916b26832b4c8977093083450a96fbccb3d866669/_data", "Destination": "/opt/data", "Driver": "local", "Mode": "", "RW": true, "Propagation": "" }
- 总结
docker run 是能指定宿主机的目录。dockerfile volume 无法指定宿主机的目录,都是自动生成,而且是随机的;默认在/var/lib/docker/volumes/。
- 宿主机如何直接维护docker容器的数据
在没有使用-v挂载点时,创建的容器,在容器删除后,根据镜像重新生成容器后,数据也随之流失。如果使用了挂载点,删除容器后,在根据镜像生成容器,数据还会保留。
docker run -p 3306:3306 --name mysql \ -e MYSQL_ROOT_PASSWORD=agan \ --privileged=true \ -v /app/data/mysql:/var/lib/mysql \ -d mysql:5.7