新创建容器的IP 地址是随机的
容器在重启后每次 IP 都会发生变化
容器服务只有宿主机才能访问
如何才能使用容器对外提供稳定的服务?
容器端口可以与宿主机的端口进行映射绑定
从而把宿主机变成对应的服务,不用关心容器的IP地址
每个端口都只能和一个容器绑定
- # 宿主机绑定 apache
- [root@docker ~]# docker run -itd --name web -p 80:80 myos:httpd
- # 绑定后,直接访问宿主机的 IP 地址即可
- [root@docker ~]# curl http://192.168.1.31
- Welcome to The Apache.
-
- # 同一个端口不能同时绑定给多个容器
- # 如果想把 80 端口绑定给 nginx 容器需要把之前的 apache 容器关停
- [root@docker ~]# docker rm -f web
- [root@docker ~]# docker run -itd --name web -p 80:80 myos:nginx
- # 重新绑定后,访问验证
- [root@docker ~]# curl http://192.168.1.31
- Nginx is running !
-
- # 完成实验,删除容器
- [root@docker ~]# docker rm -f web
- 发布nginx-php 服务
-
- 创建容器 nginx和 php-fpm
- 配置 php 容器使用 nginx的网络名称空间
- 使用卷修改nginx的配置文件,使之能够解析 php
- 把容器服务发布出来,并访问验证
Docker容器不适合保存任何数据
重要数据在容器内不方便管理易丢失
修改多个容器中的数据非常困难
多容器之间有数据共享、同步需求
数据文件与配置文件频繁更改
以上问题都可以使用容器卷来解决
Docker可以映射宿主机文件或目录到容器中
启动容器时,使用 -v 映射参数(可有多个)
docker run -itd -v 宿主机对象:容器内对象 镜像名称:标签
使用卷共享网站数据目录,让 httpd 容器和nginx容器共享网站数据目录
- # 创建共享卷目录
- [root@docker ~]# mkdir /var/webroot
-
- # 添加测试页面
- [root@docker ~]# echo "hello world" >/var/webroot/index.html
- [root@docker ~]# cp info.php /var/webroot/
-
- # 创建 nginx 容器,并映射数据卷
- [root@docker ~]# docker run -itd --rm --name mynginx \
- -v /var/webroot:/usr/local/nginx/html myos:nginx
-
- # 创建 apache 容器,与 mynginx 映射同样的卷
- [root@docker ~]# docker run -itd --rm --name myhttpd \
- -v /var/webroot:/var/www/html myos:httpd
-
- # 查看容器 IP 地址,并访问验证
- [root@docker ~]# docker inspect mynginx |grep -i IPAddress
- [root@docker ~]# curl http://172.17.0.2
- hello world
-
- [root@docker ~]# docker inspect myhttpd |grep -i IPAddress
- [root@docker ~]# curl http://172.17.0.3
- hello world
- # 获取配置文件
- [root@docker ~]# mkdir /var/webconf
- [root@docker ~]# docker cp mynginx:/usr/local/nginx/conf/nginx.conf /var/webconf/
-
- # 编辑配置文件,添加 php 解析配置
- [root@docker ~]# vim /var/webconf/nginx.conf
- location ~ \.php$ {
- root html;
- fastcgi_pass 127.0.0.1:9000;
- fastcgi_index index.php;
- include fastcgi.conf;
- }
-
- # 使用卷映射配置文件,重建 nginx 容器
- [root@docker ~]# docker rm -f mynginx
- [root@docker ~]# docker run -itd --rm --name mynginx -p 80:80 \
- -v /var/webconf/nginx.conf:/usr/local/nginx/conf/nginx.conf \
- -v /var/webroot:/usr/local/nginx/html myos:nginx
-
- # 进入容器验证配置文件
- [root@docker ~]# docker exec -it mynginx /bin/bash
- [root@e440b53a860a html]# cat /usr/local/nginx/conf/nginx.conf
docker 的网络通信模式
bridge 模式,默认模式
host 模式,与宿主机共享网络
none 模式,无网络模式
container 模式,共享其他容器的网络命名空间
自定义网络,自由创建桥接网络或者overlay网络

使用网络名称空间共享网络: - 参数 --network=container:容器名称 | ID
- # 创建 php 容器,使用 nginx 的网络名称空间
- [root@docker ~]# docker run -itd --network=container:mynginx \
- -v /var/webroot:/usr/local/nginx/html \
- --rm --name myphp myos:php-fpm
-
- # 配置验证
- [root@docker ~]# docker exec -it mynginx ss -ltun
- Netid State Recv-Q Send-Q Local Address:Port
- tcp LISTEN 0 128 127.0.0.1:9000
- tcp LISTEN 0 128 *:80
- [root@docker ~]# curl http://127.0.0.1/info.php
- <pre>
- Array
- (
- [REMOTE_ADDR] => 172.17.0.1
- [REQUEST_METHOD] => GET
- [HTTP_USER_AGENT] => curl/7.61.1
- [REQUEST_URI] => /info.php
- )
- php_host: 4525e99cea77
- 1229
从计算机诞生开始,架构就是一个一直绕不开的话题
架构并不是被发明出来的,而是持续演进的结果
2013年一个名为 docker的项目开源,随容器技术的兴起一种通过以容器为载体,使用多个小型服务组合来构建复杂应用的微服务架构逐渐清晰,这些小型服务围绕具体应用来构建。各个服务之间可以采用不同的编程语言,不同的存储技术,运行在各自的进程之中,互不干扰,协同工作
微服务并不是一种技术,而是架构思想、它以容器技术为载体,演进出的一种以软件运行环境、产品、研发、运营为一体全新模式。站在 Docker 的角度,软件就是容器的组合而容器又是服务的最佳载体,一台计算机同时运行多个容器从而就能很轻松地实现复杂的架构。
优点:松耦合高内聚、高度可扩展、出色的弹性、易于部署、访问
在微服务架构中每个微服务一般都会包含多个容器实例
如果每个微服务都要手动管理,那么效率之低、维护量之大可想而知。为了解决编排部署的问题,docker 公司推出了docker Compose 工具
Compose 是一个用于定义和运行多容器的应用的工具
使用 Compose,可以在一个文件中配置多个容器服务,然后使用一个简单的命令就可以轻松、高效地管理配置中引用的所有容器服务
服务文件:docker-compose.yaml
- # 安装 compose 组件
- [root@docker ~]# dnf install -y docker-compose-plugin
-
- # 创建项目
- [root@docker ~]# vim docker-compose.yaml
- name: websvc # 项目名称
- version: "3" # 语法格式版本
- services: # 关键字,定义服务
- websvc: # 服务名称
- container_name: nginx # 容器名称
- image: myos:nginx # 创建容器使用的镜像
| 指令 | 说明 |
|---|---|
| up | 创建项目并启动容器 |
| down | 删除项目容器及网络 |
| ls | 列出可以管理的项目 |
| start/stop/restart | 启动项目/停止项目/重启项目 |
| images | 列出项目使用的镜像 |
| ps | 显示项目中容器的状态 |
| logs | 查看下项目中容器的日志 |
- # 创建项目,并启动
- [root@docker ~]# docker compose -f docker-compose.yaml up -d
- [+] Running 2/2
- ⠿ Network websvc_default Created 0.0s
- ⠿ Container nginx Started 0.3s
-
- # 查看项目
- [root@docker ~]# docker compose ls
- NAME STATUS CONFIG FILES
- websvc running(1) /root/docker-compose.yaml
-
- # 查看项目中的容器状态
- [root@docker ~]# docker compose -p websvc ps
- NAME COMMAND SERVICE STATUS PORTS
- nginx "nginx -g 'daemon of…" websvc running 80/tcp
-
- # 启动、停止、重启项目
- [root@docker ~]# docker compose -p websvc stop
- [+] Running 1/1
- ⠿ Container nginx Stopped 0.1s
- [root@docker ~]# docker compose -p websvc start
- [+] Running 1/1
- ⠿ Container nginx Started 0.2s
- [root@docker ~]# docker compose -p websvc restart
- [+] Running 1/1
- ⠿ Container nginx Started 0.3s
-
- # 查看项目中容器的日志
- [root@docker ~]# docker inspect nginx |grep IPAddress
- [root@docker ~]# curl http://172.17.0.2/info.php
- <html>
- <head><title>404 Not Found</title></head>
- <body>
- <center><h1>404 Not Found</h1></center>
- <hr><center>nginx/1.22.1</center>
- </body>
- </html>
- [root@docker ~]# docker compose -p websvc logs
- nginx | 2023/02/13 13:55:39 [error] 7#0: *1 open() "/usr/local/nginx/html/info.php" failed (2: No such file or directory), client: 172.17.0.1, server: localhost, request: "GET /info.php HTTP/1.1", host: "172.17.0.2"
-
- # 删除项目
- [root@docker ~]# docker compose -p websvc down
- [+] Running 2/2
- ⠿ Container nginx Removed 0.1s
- ⠿ Network websvc_default Removed 0.0s
Compose 项目是 Docker 官方的开源项目,负责实现容器集群的快速编排,在 Compose 中有两个核心概念,分别是服务和项目
服务 (service):一个应用的容器,实际上可以包括若干运行相同镜像的容器实例。
项目(project):由一组关联的应用容器组成的一个完整业务单元,在 docker-compose.yaml 文件中定义
| 指令 | 说明 |
|---|---|
| networks | 配置容器连接的网络 |
| container_name | 指定容器名称 |
| depends_on | 解决容器的依赖、启动先后的问题 |
| command | 覆盖容器启动后默认执行的命令 |
| environment | 设置环境变量 |
| image | 指定为镜像名称或镜像 ID |
| network_mode | 设置网络模式 |
| restart | 容器保护策略[always、no、on-failure] |
| ports | 暴露端口信息 |
| volumes | 数据卷,支持 [volume、bind、tmpfs、npipe] |
- [root@docker ~]# vim docker-compose.yaml
- name: websvc # 项目名称
- version: "3" # 语法版本格式
- services: # 关键字,定义服务
- nginxsvc: # 服务名称
- container_name: nginx # 容器名称
- image: myos:nginx # 创建容器使用的镜像
- restart: always # 容器保护策略
- volumes: # 卷
- - type: bind # 卷类型
- source: /var/webconf/nginx.conf # 宿主机路径
- target: /usr/local/nginx/conf/nginx.conf # 容器路径
- - type: bind
- source: /var/webroot # 宿主机路径
- target: /usr/local/nginx/html # 容器路径
- network_mode: bridge # 网络工作模式
- ports: # 端口绑定
- - 80:80 # 宿主机端口:容器端口
- environment:
- - "TZ=Asia/Shanghai"
- php-fpm: # 服务名称
- container_name: php-fpm # 容器名称
- image: myos:php-fpm # 创建容器使用的镜像
- restart: always # 容器保护策略
- volumes: # 卷
- - type: bind # 卷类型
- source: /var/webroot # 宿主机路径
- target: /usr/local/nginx/html # 容器路径
- depends_on: # 依赖关系
- - nginxsvc # 依赖容器名称
- network_mode: "container:nginx" # 网络工作模式
- # 创建,并启动项目
- [root@docker ~]# docker compose -f docker-compose.yaml up -d
- [+] Running 2/2
- ⠿ Container nginx Started 0.3s
- ⠿ Container php-fpm Started 0.3s
-
- # 查看项目
- [root@docker ~]# docker compose ls
- NAME STATUS CONFIG FILES
- websvc running(2) /root/docker-compose.yaml
-
- # 查看容器状态,验证服务
- [root@docker ~]# docker compose -p websvc ps
- NAME COMMAND SERVICE STATUS
- nginx "nginx -g 'daemon of..." nginx running ......
- php-fpm "php-fpm --nodaemoni..." php-fpm running ......
-
- # 访问 php 页面验证
- [root@docker ~]# curl -s http://127.0.0.1/info.php
- <pre>
- Array
- (
- [REMOTE_ADDR] => 172.17.0.1
- [REQUEST_METHOD] => GET
- [HTTP_USER_AGENT] => curl/7.61.1
- [REQUEST_URI] => /info.php
- )
- php_host: 7e037978c775
- 1229
Habor 是在 Registry 上进行了相应的企业级扩展,从而获得了更加广泛的应用,这些新的企业级特性包括:提供 WEB界面,优化用户体验,支持登陆、搜索功能,区分公有、私有镜像,以及基于角色的访问控制,集成日志审计、支持水平扩展等功能。
部署 harbor 环境非常繁琐,涉及到 web服务器、数据库服务器、程序代码、docker 私有镜像仓库等 9个应用
官方为了简化安装部署的步骤和流程,采用了微服务方式对项目进行了管理,所有应用官方都以 docker 镜像的方式发布,项目采用 compose 方式管理
使用微服务项目方式部署 harbor 仓库
| 主机名 | ip地址 | 最低配置 |
|---|---|---|
| harbor | 192.168.1.30 | 2CPU,4G内存 |
- [root@harbor ~]# vim /etc/hosts
- 192.168.1.30 harbor
-
- # 安装部署 docker 及 compose 组件
- [root@harbor ~]# dnf install -y docker-ce docker-compose-plugin
- [root@harbor ~]# systemctl enable --now docker
- # 导入 harbor 项目镜像
- [root@harbor ~]# tar -zxf harbor-v2.7.0.tgz -C /usr/local/
- [root@harbor ~]# cd /usr/local/harbor
- [root@harbor harbor]# docker load -i harbor.v2.7.0.tar.gz
- # 创建 https 证书
- [root@harbor harbor]# mkdir tls
- [root@harbor harbor]# openssl genrsa -out tls/cert.key 2048
- [root@harbor harbor]# openssl req -new -x509 -days 3650 \
- -key tls/cert.key -out tls/cert.crt \
- -subj "/C=CN/ST=BJ/L=BJ/O=Tedu/OU=NSD/CN=harbor"
- # 修改配置文件
- [root@harbor harbor]# cp harbor.yml.tmpl harbor.yml
- [root@harbor harbor]# vim harbor.yml
- 05: hostname: harbor
- 08: # http:
- 10: # port: 80
- 17: certificate: /usr/local/harbor/tls/cert.crt
- 18: private_key: /usr/local/harbor/tls/cert.key
- 34: harbor_admin_password: admin123
-
- # 预安装环境检查,生成项目文件
- [root@harbor harbor]# /usr/local/harbor/prepare
- # 创建并启动项目
- [root@harbor harbor]# docker compose -f docker-compose.yml up -d
- # 添加开机自启动
- [root@harbor harbor]# chmod 0755 /etc/rc.d/rc.local
- [root@harbor harbor]# echo "/usr/bin/docker compose -p harbor start" >>/etc/rc.d/rc.local
- # 查看项目
- [root@harbor harbor]# docker compose ls
- NAME STATUS CONFIG FILES
- harbor running(9) /usr/local/harbor/docker-compose.yml
- # 查看容器状态
- [root@harbor harbor]# docker compose -p harbor ps
- NAME COMMAND SERVICE STATUS
- harbor-core "/harbor/entrypoint.…" core running (healthy)
- harbor-db "/docker-entrypoint.…" postgresql running (healthy)
- harbor-jobservice "/harbor/entrypoint.…" jobservice running (healthy)
- harbor-log "/bin/sh -c /usr/loc…" log running (healthy)
- harbor-portal "nginx -g 'daemon of…" portal running (healthy)
- nginx "nginx -g 'daemon of…" proxy running (healthy)
- redis "redis-server /etc/r…" redis running (healthy)
- registry "/home/harbor/entryp…" registry running (healthy)
- registryctl "/home/harbor/start.…" registryctl running (healthy)
用户:用来登录 harbor,以及认证权限
项目:用来存储镜像的地址路径
公共仓库:任何人都可以访问或下载镜像,上传镜像需要用户认证
私有仓库:不管是上传还是下载只有认证用户才可以访问
| 容器管理命令 | 说明 |
|---|---|
| docker login | 登录私有镜像仓库 |
| docker logout | 退出登录 |
- # 添加主机配置
- [root@docker ~]# vim /etc/hosts
- 192.168.1.30 harbor
- 192.168.1.35 registry
- # 添加私有仓库配置
- [root@docker ~]# vim /etc/docker/daemon.json
- {
- "registry-mirrors": ["https://harbor:443", "http://registry:5000"],
- "insecure-registries":["harbor:443", "registry:5000"]
- }
- [root@docker ~]# systemctl restart docker
-
- # 登录 harbor 仓库
- [root@docker ~]# docker login harbor:443
- Username: luck
- Password: ********
- ... ...
- Login Succeeded
- # 认证信息记录文件
- [root@docker ~]# cat /root/.docker/config.json
- {
- "auths": {
- "harbor:443": {
- "auth": "bHVjazoqKioqKioqKg=="
- }
- }
- }
- # 退出登录
- [root@docker ~]# docker logout harbor:443
- Removing login credentials for harbor:443
- # 设置标签
- [root@docker ~]# docker tag rockylinux:8.5 harbor:443/myimg/rockylinux:8.5
- # 没有登录上传失败
- [root@docker ~]# docker push harbor:443/myimg/rockylinux:8.5
- 65dbea0a4b39: Preparing
- unauthorized: unauthorized to access repository ......
-
- # 登录成功后才可以上传
- [root@docker ~]# docker login harbor:443
- Username: luck
- Password: ********
-
- Login Succeeded
- # 上传成功
- [root@docker ~]# docker push harbor:443/myimg/rockylinux:8.5
- The push refers to repository [harbor:443/myimg/rockylinux]
- ......
-
- # 设置标签
- [root@docker ~]# docker tag myos:latest harbor:443/library/myos:latest
- # 上传镜像到 library 项目,没有权限上传失败
- [root@docker ~]# docker push harbor:443/library/myos:latest
- The push refers to repository [harbor:443/library/myos]
- 65dbea0a4b39: Preparing
- unauthorized: unauthorized to access repository:
- ......
-
- # 赋权后重新上传镜像
- [root@docker ~]# docker push harbor:443/library/myos:latest
- The push refers to repository [harbor:443/library/myos]
- ......
- 镜像管理
-
- 赋予普通用户管理项目library 的权限
- 上传 rockylinux:8.5到 myimg/rockylinux:8.5
- 上传 myos:httpd到 myimg/httpd:latest
- 上传 myos:8.5、myos:httpd、myos:nginx、myos:php-fpm、myos:latest 到 library 项目下
- [root@docker ~]# docker tag myos:httpd harbor:443/myimg/httpd:latest
- [root@docker ~]# docker push harbor:443/myimg/httpd:latest
- [root@docker ~]# docker rmi harbor:443/myimg/httpd:latest
- [root@docker ~]# for i in 8.5 httpd nginx php-fpm latest;do
- docker tag myos:${i} harbor:443/library/myos:${i}
- docker push harbor:443/library/myos:${i}
- docker rmi myos:${i} harbor:443/library/myos:${i}
- done