Administrator
发布于 2026-05-17 / 2 阅读
0

Docker

# 简介 \* 开源的应用容器引擎,基于Go语言 \* 完全隔离的沙箱机制,类似app之间的关系 \* 重要的是性能开销极低 \* 程序简化 \* docker镜像中包含环境,服务环境搭建简单 # 应用场景 1. web自动打包发布 2. 自动化测试 3. 在服务型环境中部署,调整 应用 # Docker引擎 1. 包含以下组件的客户端服务器应用程序 \* 一种服务器,一种称为守护进程并长时间运行的程序 \* REST API 用于指定程序可以用来与守护进程通信的接口 \* 一个有命令行界面的CLI工具的客户端 !\[\](/usr/uploads/my-upload/2024/10/d79ed0af043e68a08dce.png) # Docker系统架构 1. 使用客户端-服务器架构模式,使用远程api来管理和创建Docker容器 2. Docker容器通过Docker镜像来创建 3. 关系:容器---》对象,镜像------》类 1. 镜像封装了基本的属性 2. 真正操作的是容器, 4. docker pull ----\>守护进程---》创建两个容器------》本机存在镜像的时候直接创建,否则到docker库下载 !\[\](/usr/uploads/my-upload/2024/10/d09a1a49b52c60c1b0cd.png) # Docker安装 1. 可以安装在windwos,mac,linux 2. 前提条件 3. 若为linux只适用于64位 4. linux内核要大于3.10 5. https://www.dean0731.cn/archives/582/ # 第一个Docker应用程序 \`\`\`shell # 从网上下载ubuntu15.10 的镜像,创建一个容器 ,使用容器打印 "hello docker" docker run ubuntu:15.10 /bin/echo "hello Docker" docker images docker ps docker rm containerID \`\`\` \`\`\`shell # 用主线程的交互式容器,即可进入Ubuntu容器 root命令行 docker run -it ubuntu:15.10 /bin/bash 后台运行 -d表示在后台 docker run -d ubuntu:15.10 /bin/bash -c "while true:do echo hello docker;sleep 1;done" \`\`\` \`\`\`shell # 查看容器日志,加参数 -f可动态查看 docker logs containerId docker stop containerId # 适用bash与正在运行的容器进行交互 docker exec -it containerId /bin/bash docker COMMAND --help \`\`\` # 运行web容器 \`\`\`shell # 在一个完整的操作系统上运行python程序 # -P:表示把容器的端口映射到宿主机,宿主机随机一个端口映射到容器 # 镜像为training/webapp # 它是一个flask程序 运行命令python app.py docker run -d -P training/webapp python app.py # 可以指定访问端口 宿主机4000,容器5000 docker run -d -p 4000:5000 training/webapp python app.py # 查看容器中的进程 docker top containerId docker top names # 查看容器状态:json字符格式 docker inspect \`\`\` \`\`\`shell # 出现一个新的image,与上个同名,tag不同, 设置镜像标签 docker tag containerId imageName:newTag \`\`\` docker 安装后会产生一个虚拟网卡,mac等,容器产生的Ip都是基于虚拟网卡的 # Docker镜像管理 若使用的镜像不存在会从 [Docker Hub](https://hub.docker.com) 下载 \`\`\`shell docker pull tomcat docker pull tomcat:8.5.49-jdk11-openjdkv # 镜像,默认获取最新版本,也可以指定版本获取 # 镜像,一般选择官方的,使用docker pull name 获取 # starts 表示的是使用量,可作为评价标准 docker search tomcat \`\`\` !\[\](/usr/uploads/my-upload/2024/10/ac3a58ceff3873712c1a.png) \`\`\`shell # 创建镜像from容器 docker commit -m="has update" -a="userName" containerId newImageName:Tag(随便) # Dockerfile创建镜像 mkdir myUbuntu cd myUbuntu vi Dockerfile #(名字不要更改) FROM ubuntu:15.10 # 系统 MAINTAINER your-email COPY test.txt /home # 将宿主机的文件test.txt copy 到镜像的home下 RUN /bin/bash -c "Hello world" # 指定镜像默认执行的命令 CMD \["/bin/echo","this is param1"\] # 文件中只能有一个cmd,有多个会只执行第一个 WORKDIR /home # 指定默认的工作目录 EXPOSE 80 # 暴露端口 EXPOSE 8080 docker build -t yourImageName . # 在当前目录查找dockerfile 为改文件的镜像命名 \`\`\` # Docker实例教程 \`\`\`shell # 使用docker 后台运行tomcat容器 并做端口映射,并修改容器的默认名字为tomcat, docker run --name tomcat -p 8080:8080 -d tomcat # 若要在容器内tomcat 部署程序,交互式进入,写自己的html即可 \`\`\` \`\`\`shell docker pull mysql # 拉去mysql 镜像 docker run -p 3306:3306 -name mysql \\ -v /usr/local/deoker/mysql/conf:/etc/mysql \\ # 映射宿主机目录到容器目录 -v /usr/local/docker/mysql/logs:/val/log/mysql \\ # -v 数据卷 -v /usr/local/docker/mysql/data:/var/lib/mysql \\ -e MYSQL_ROOT_PASSWORD=123456 \\ # -e 指定环境边变量 -d mysql # 若以后要重新运行时,密码变更了,需要删除宿主机下原来的数据卷,否则会不生效,还使用原来的配置。 \`\`\` \`\`\`shell vim Dockerfile FROM tomcat MAINTAINER email ADD xxx.war /usr/local/tomcat/webapps/xxx.war # 添加war包到容器 docker build -t name . # 构建镜像 docker run -d -p 8080:8080 imageName # 本方式是直接将war打入本镜像,比较麻烦,可使用数据卷解决 \`\`\` # 数据卷 - 绕过拷贝写,修改容器内容相当于直接修改宿主机内容,性能高 - 不需要在docker commit 打包进镜像文件 - 宿主,容器,容器之间共享文件 - 创建数据卷 \`\`\`shell docker run -d -P -v /webapps training/webapps python app.py # 将tomcat容器的目录映射到宿主目录,即时原容器目录有内容也不可用 docker run -name tomcat1 -d -p 8080:8080 -v /usr/local/docker/tomcat/share/webapps:/usr/local/tomcat/webapps tomcat # 或 dockerfile中指定 VOLUME /var/lib/test \`\`\` - 备份数据卷 \`\`\`shell docker run -p 3306:3306 -name mysql \\ -v /usr/local/deoker/mysql/conf:/etc/mysql \\ -v /usr/local/docker/mysql/logs:/val/log/mysql \\ -v /usr/local/docker/mysql/data:/var/lib/mysql \\ -e MYSQL_ROOT_PASSWORD=123456 \\ -d mysql # 启动数据库 # 1. 连接容器内数据库,做出修改 # 2. 进入宿主机的数据卷,直接备份docker/mysql目录即可 tar -zcvf backup.tar.gz . # 3. 恢复数据卷,其重新的容器时,挂载备份的文件即可 \`\`\` # Docker Compose - 简化docker操作的工具,安装docker-compose \`\`\`shell curl -L https://github.com/docker/compose/releases/download/1.25.0/docker-compose-\`uname -s\`-\`uname -m\` -o /usr/local/bin/docker-compose # 或直接下载上传即可,重命名为docker-compose,放入环境变量目录 chown -R root:root docker-compose chmod +x docker-compose # 官网那个可能慢 curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.5/docker-compose-\`uname -s\`-\`uname -m\`\>/usr/local/docker-compose \`\`\` - docker-compose 使用 \`\`\`shell # 启用tomca容器 # 原始方法:docker run ....... # docker-compose mkdir tomcat;cd tomcat vim docker-compose.yml # yml 语言 version: "3" # compose的版本号决定 services: tomcat: # 服务名字,可变的 restart:always image:tomcat container_name:tomcat ports: - "8080:8080" docker-compose up # 此时是主线程启动 docker-compose down # 停止,并删除 docker-compose up -d # 后台运行 必须在docker-compose.yml所在的目录 \`\`\` \`\`\`yaml version: "3" services: tomcat: restart:always image:tomcat container_name:tomcat ports: - "8080:8080" volumes: - "/usr/local/docker/tomcat/webapps/test:/usr/local/tomcat/webapps/test" environment: TZ: Asia/Shanghai \`\`\` \`\`\`yaml # mysql version: "3" services: mysql: restart: always image:mysql container_name:mysql port: - 3306:3306 environment: TZ:Asia/Shanghai MYSQL_ROOT_PASSWORD:123456 command: --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci --explicit_defaults_for_timestamp=true --lower_case_table_name=1 --max_allowed_packet=128M --sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBST\\ ITUTION,NO_ZERO_DATE,NO_ZERO_IN_DATA,ERROR_FOR_DIVISION_BY_ZERO" volumes: - mysql-data:/var/lib/mysql volumes: mysql-data: # docker安装目录/volumes/下创建mysql_mysql-data文件夹作为映射 # /var/lib/docker/volumes/mysql_mysql-data \`\`\` \`\`\`yaml version: 3 services: tomcat: restart:always image:tomcat container_name:tomcat ports: - 8080:8080 volumes: - /usr/local/docker/project/webapps/:/usr/local/tomcat/webapps/ environment: TZ: Asia/Shanghai mysql: restart: always image:mysql container_name:mysql port: - "3306:3306" environment: TZ:Asia/Shanghai MYSQL_ROOT_PASSWORD:123456 command: --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci --explicit_defaults_for_timestamp=true --lower_case_table_name=1 --max_allowed_packet=128M --sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SU\\ BSTITUTION,NO_ZERO_DATE,NO_ZERO_IN_DATA,ERROR_FOR_DIVISION_BY_ZERO" volumes: - mysql-data:/var/lib/mysql volumes: mysql-data: \`\`\` - 项目部署 !\[image-20200910201125247\](/usr/uploads/my-upload/2024/10/b3126e768fd8d843242e.png) \`\`\`python # app.py import time import redis from flask import Flask app = Flask(__name__) cache = redis.Redis(host='redis', port=6379) def get_hit_count(): retries = 5 while True: try: return cache.incr('hits') except redis.exceptions.ConnectionError as exc: if retries == 0: raise exc retries -= 1 time.sleep(0.5) @app.route('/') def hello(): count = get_hit_count() return 'Hello World! I have been seen {} times.\\n'.format(count) \`\`\` \`\`\`shell # requirements.txt flask redis \`\`\` \`\`\`dockerfile # Dockerfile FROM python:3.7-alpine WORKDIR /code ENV FLASK_APP app.py ENV FLASK_RUN_HOST 0.0.0.0 RUN apk add --no-cache gcc musl-dev linux-headers COPY requirements.txt requirements.txt RUN pip install -r requirements.txt EXPOSE 5000 COPY . . CMD \["flask", "run"\] \`\`\` \`\`\`yaml # docker-compose.yml version: '3' services: web: build: . # 使用当前Dockerfile构建镜像 ports: - "5000:5000" redis: image: "redis:alpine" # 使用现成镜像 \`\`\` \`\`\`shell # build docker-compose build # 启动 docker-compose up -d \`\`\` - 创建网络 - 执行docker-compose.yml - 启动服务 - 就是里面的镜像 - 默认服务名:文件名\\_服务名\\__num(运行实例个数) - 网络 - docker network ls - 通过compose启动,就会生成网络,因此项目中网络都是一个 - 访问时不用ip,使用服务名,更简洁,在springboot配置文件中 spring.redis.host=redis \`\`\`yaml version: "3.8" services: redis: # 服务 image: redis:alpine ports: - "6379" networks: - frontend deploy: replicas: 2 update_config: parallelism: 2 delay: 10s restart_policy: condition: on-failure db: # 服务 image: postgres:9.4 volumes: - db-data:/var/lib/postgresql/data networks: - backend deploy: placement: max_replicas_per_node: 1 constraints: - "node.role==manager" vote: image: dockersamples/examplevotingapp_vote:before ports: - "5000:80" networks: - frontend depends_on: - redis deploy: replicas: 2 update_config: parallelism: 2 restart_policy: condition: on-failure result: image: dockersamples/examplevotingapp_result:before ports: - "5001:80" networks: - backend depends_on: - db deploy: replicas: 1 update_config: parallelism: 2 delay: 10s restart_policy: condition: on-failure worker: image: dockersamples/examplevotingapp_worker networks: - frontend - backend deploy: mode: replicated replicas: 1 labels: \[APP=VOTING\] restart_policy: condition: on-failure delay: 10s max_attempts: 3 window: 120s placement: constraints: - "node.role==manager" visualizer: image: dockersamples/visualizer:stable ports: - "8080:8080" stop_grace_period: 1m30s volumes: - "/var/run/docker.sock:/var/run/docker.sock" deploy: placement: constraints: - "node.role==manager" networks: frontend: backend: volumes: db-data: \`\`\` \`\`\`dockerfile # java dockerfile例子 FROM java:8 COPY \*.jar /app.jar CMD \["--server.port=8888"\] EXPOSE 8888 ENTRYPOINT \["java","-jar","/app.jar"\] \`\`\` \`\`\`yaml version: '3.8' services: javaservice: build: . image: javaservice depends_on: - redis ports: - "8888:8888" redis: image: "redis:alpine" \`\`\` # 集群 Docker Swarm - 集群方式部署,主机更多的时候使用k8s - xshell命令同步操作安装docker - 工作模式 !\[image-20200910213320141\](/usr/uploads/my-upload/2024/10/b36f13bbbd8d054cefbc.png) \`\`\`shell # swarm 集群初始化 docker swarm init --advertise-addr ip1 # 初始化节点 默认是lader,是管理节点 # 令牌生成 docker swarm join-token worker docker swarm join-token manager # 加入集群work。manager使用令牌加入 # worker,manager:Reachable,loader # 一般情况管理节点大于等于3个,此时有损坏的开可以使用,若2管理节点,损坏一个后就不能使用了,即最少2个管理可使用,否则就会docker集群就不能使用了,raft协议:保证大多数节点存活 # docker node ls 查看节点 # docker swarm leave 离开集群 \`\`\` docker service,之前的集群,不能动态扩容,缩容 - 容器---》服务--》副本 \`\`\`shell # nginx 集群 # 服务启动 滚动更新,扩容,缩容,docker run不可以 # 会随机在worker启动 docker service -p 8888:80 --name my_nginx nginx # 查看服务信息 docker service ps my_nginx # 查看服务列表 docker service ls # my_nginx 创建副本 docker service update --relipcas 3 my_nginx # 作用同上 docker service scale my_nginx=3 # 访问时访问集群中任何一个都可以 https://ip1:8888,https://ip2:8888,即使ip2没有服务,但它在集群中 # 缩小 docker service update --relipcas 1 my_nginx # 移除服务 docker service rm my_nginx \`\`\` 扩展:网络模式 overlay:集群中不同主机上的docker是不能ping的,此模式使用虚拟ip,完成此功能 imgress:overlay的进一步开发,有负载均衡作用 # Docker stack \`\`\`shell # 单机docker-compose docker-compose up -d # 集群docker stack docker stack deploy # 也是基于yaml文件,与compose格式类似 \`\`\` # Docker secret 统一秘钥管理 # Docker config 统一配置管理 # 扩展到k8s - 云原生时代,直接云端下载应用,购买服务器,部署k8s即可使用 - go语言,天生的并发语言,docker,kvs,v8等都是go开发的