文章目录
- Docker简介
- Docker安装
- Docker镜像管理
- Docker容器管理
- Dockerfile
-
- [Dockerfile 语法](#Dockerfile 语法)
- 案例
- 总结
Docker简介
什么是容器
-
容器是用来装东西的,Linux 里面的容器是用来装应用的;
-
容器就是将软件打包成标准化单元,以用于开发、交付和部署;
-
容器技术已经成为应用程序封装和交付的核心技术;
-
容器原理:容器技术的核心,由以下几个内核技术组成:
- Cgroups (Control Groups) :资源管理
- SELinux:安全 (是针对于文件系统,文件的管理措施)
- NameSpace:命名空间
命名空间:
- 是指可以对系统资源空间进行分割隔离的技术
- 例如:创建一个虚拟机,在虚拟机里的所有操作,都不会对真实机造成影响。
- 命名空间分为六大类,可以从各个方面来对系统资源空间进行隔离;
UTS
:主机名隔离NETWORK
:网络隔离MOUNT
:文件系统隔离USER
:用户隔离PID
:进程隔离IPC
:信号向量隔离
Docker 的优缺点
-
优点
- 相比于传统的虚拟化技术,容器更加简洁高效
- 传统虚拟机需要给每个 VM 安装操作系统
- 容器使用的共享公共库和程序
-
缺点
- 容器的隔离性没有虚拟机强
- 共用Linux内核,安全性有先天缺陷
Docker
使用模板机的克隆以下机器,配置如下
主机名 | IP地址 | 内存 | CPU |
---|---|---|---|
docker-0001 | 192.168.8.107 | 2G | 2 |
docker-0002 | 192.168.8.108 | 2G | 2 |
docker-0001配置IP地址和主机名
shell
[root@localhost ~]# hostnamectl set-hostname docker-0001
[root@docker-0001 ~]# nmcli connection modify ens33 ipv4.method auto connection.autoconnect yes
[root@docker-0001 ~]# nmcli connection up ens33
[root@docker-0002 ~]# yum clean all
[root@docker-0002 ~]# yum repolist
docker-0002配置IP地址和主机名
shell
[root@localhost ~]# hostnamectl set-hostname docker-0002
[root@docker-0002 ~]# nmcli connection modify ens33 ipv4.method auto connection.autoconnect yes
[root@docker-0002 ~]# nmcli connection up ens33
[root@docker-0002 ~]# yum clean all
[root@docker-0002 ~]# yum repolist
Docker安装
docker安装(两台主机都要安装,以docker-0001为例)
开启路由转发,docker是通过虚拟交换机来进行通讯的,需要开启路由转发的功能
shell
[root@docker-0001 ~]# echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
[root@docker-0001 ~]# sysctl -p #sysctl -p 让配置立刻生效(否则需要重启虚拟机)
[root@docker-0001 ~]# yum -y install docker
[root@docker-0001 ~]# systemctl enable --now docker #启动docker服务
Docker镜像管理
什么是镜像
-
镜像是启动容器的核心
-
在Docker 中容器是基于镜像启动的
-
镜像采用分层设计,使用 COW 技术
-
容器本身是没有操作系统,和宿主机共用一个操作系统;
-
容器是docker(容器的管理工具)使用镜像文件来启动的;
-
镜像是启动容器的模板,镜像中存放的是应用程序(服务软件),例如: 有一个http的镜像文件,在这个镜像中就存放的是http的所有文件和变量;
-
用户使用镜像启动容器时,会生成一个独立于镜像的容器层,并不会对镜像层产生任何影响;
-
而且容器采用了cow(写时复制)的技术,用户可以使用一个镜像文件创建多个容器,互不干扰;
-
镜像采用分层技术:
- 用户可以根据自己的需求来制作镜像,例如:在镜像的第一层定义应用程序的变量,在镜像的第二层修改配置文件,在镜像的第三层进行应用软件的部署;
- 分层做好镜像后,用户使用镜像启动容器时,可以选择根据镜像的哪一层来启动,类似快照还原;
-
镜像来源
- 镜像可以从官方镜像仓库下载https://hub.docker.com
- 自己制作
镜像管理
docker images
#查看本机镜像docker search 关键词
#查找包含关键词的镜像docker pull 镜像名称:标签
#下载镜像docker rmi 镜像名称:标签
#删除镜像docker history 镜像名称: 镜像标签
#查看镜像的制作历史docker inspect 镜像名称: 镜像标签
#查看镜像的信息docker tag 镜像名称: 镜像标签 新镜像名称: 新的标签
#为镜像的打新名称和标签
shell
[root@docker-0001 ~]# docker images #还没有导入镜像,所以没有镜像
shell
[root@docker-0001 ~]# docker search busybox
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
busybox Busybox base image. 2010 [OK]
shell
[root@docker-0001 ~]# docker pull busybox
查看镜像
shell
[root@docker-0001 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
busybox latest 6858809bf669 4 weeks ago 1.232 MB
#REPOSITORY 镜像名称
#TAG 镜像标签
#IMAGE ID 镜像ID号
#CREATED 镜像创建时间
#SIZE 镜像大小
镜像的备份与恢复
- 镜像备份:
docker save 镜像名称:镜像标签 -o 备份文件夹(tar格式)
- 镜像恢复(导入镜像):
docker load -i 备份文件名称
docker-0001导出镜像(备份)
shell
[root@docker-0001 ~]# docker save busybox:latest -o /root/busybox.tar
#导出镜像busybox,需要指定名字和标签,导出到/root目录下,名称为busybox.tar
#名称和路径可以随意指定
拷贝备份镜像到docker-0002上
shell
[root@docker-0001 ~]# scp /root/busybox.tar 192.168.8.108:/root/
docker-0002恢复镜像
shell
[root@docker-0002 ~]# docker load -i busybox.tar
[root@docker-0002 ~]# docker images
教学环境中将docker-images目录上传到docker-0001的/root下,并导入这四个镜像到docker里面
shell
[root@docker-0001 ~]# cd docker-images
[root@docker-0001 docker-images]# for i in *.tar.gz
> do
> docker load -i $i
> done
docker-0001看镜像的制作历史
shell
[root@docker-0001 ~]# docker history centos:latest #由下到上,镜像可以分为3层
查看镜像的信息
shell
[root@docker-0001 ~]# docker inspect centos:latest
[root@docker-0001 ~]# docker inspect nginx:latest
..........
"Cmd": [ # Cmd 默认的启动命令,即:启动容器时,默认的启动命令
"nginx",
"-g",
"daemon off;"
],
..........
docker-0001为镜像busybox:lastest打的新名称和标签
shell
[root@docker-0001 ~]# docker tag busybox:latest xxhh:test
docker-0001删除镜像
shell
[root@docker-0002 ~]# docker rmi busybox:latest
Docker容器管理
运行容器
docker run -参数 镜像名称:镜像标签 启动命令
#创建+运行+进入容器命令docker ps [-a] [-q]
#查看容器docker rm [-f]
#删除容器(-f强制)
docker-0001根据centos镜像启动并进入一个容器
shell
[root@docker-0001 ~]# docker run -it centos:latest /bin/bash
#/bin/bash为容器内的命令,容器内存在,才可以使用
[root@89d1ec3a0dc8 /]# exit
[root@docker-0001 ~]# docker run -itd nginx:latest
#启动nginx,是个服务,要加d,放后台才能运行
查看容器
shell
[root@docker-0001 ~]# docker ps
[root@docker-0001 ~]# docker ps -a #ps -a 查看创建的所有的容器(运行的和已经停止的)
[root@docker-0001 ~]# docker ps -q #ps -q 查看运行中容器的ID值
[root@docker-0001 ~]# docker ps -aq #ps -aq查看所有容器的id,用于脚本对容器的管理
删除容器(容器ID不能照抄,每个人都不一样)
shell
[root@docker-0001 ~]# docker rm 512567e6f64f
删除正在使用的容器时,会报错,无法删除,需要先停止容器,再执行删除命令
shell
[root@docker-0001 ~]# docker stop 512567e6f64f #停止容器
[root@docker-0001 ~]# docker rm 512567e6f64f
删除所有的容器:支持命令行重录,前一个命令的结果$(docker ps -aq)可以作为后一个命令的参数
shell
[root@docker-0001 ~]# docker rm -f $(docker ps -aq) #$()用来获取命令的执行结果
容器启动、停止、重启
docker start 容器id
#启动容器docker stop 容器id
#停止容器docker restart 容器id
#重启容器
shell
[root@docker-0001 ~]# docker run -itd nginx:latest
查看容器信息
shell
[root@docker-0001 ~]# docker inspect 38b8ee2a8754
......
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
......
[root@docker-0001 ~]# curl http://172.17.0.2
<title>Welcome to nginx!</title>
............
shell
[root@docker-0001 ~]# docker stop 38b8ee2a8754 #停止容器
[root@docker-0001 ~]# docker start 38b8ee2a8754 #启动容器
[root@docker-0001 ~]# docker restart 38b8ee2a8754 #重启容器
拷贝文件
-
docker cp 本机文件路径 容器id:容器内路径
(上传) -
docker cp 容器id:容器内路径 本机文件路径
(下载)
在第一个终端中执行
shell
[root@docker-0001 ~]# docker run -it centos:latest
[root@69f7753eb1e8 /]# cd /etc/yum.repos.d/
[root@69f7753eb1e8 yum.repos.d]# rm -rf *
#另外开一个docker-0001的终端操作
shell
[root@docker-0001 ~]# docker cp /etc/yum.repos.d/CentOS-Base.repo 69f7753eb1e8:/etc/yum.repos.d/Centos-base.repo
[root@69f7753eb1e8 yum.repos.d]# yum -y install net-tools #在容器里面可以正常使用
[root@69f7753eb1e8 yum.repos.d]# ifconfig
[root@69f7753eb1e8 yum.repos.d]# exit
进入容器
-
docker exec -it 容器id 命令
-
docker attach 容器id
shell
[root@docker-0001 ~]# docker ps -a #查看正在使用的容器
[root@docker-0001 ~]# docker start 69f7753eb1e8 #启动centos的容器
[root@docker-0001 ~]# docker exec -it 69f7753eb1e8 /bin/bash #根据centos容器ID,进入容器
[root@69f7753eb1e8 /]# ps -ef #两个bash进程
[root@69f7753eb1e8 /]# exit #退出
- attach 以上帝进程的身份,进入容器内部,当执行exit退出容器时,会结束整个容器,通常用于在测试时,查看报错信息;
shell
[root@docker-0001 ~]# docker attach 69f7753eb1e8 #Ctrl + p+ q 退出容器,但不会停止
[root@69f7753eb1e8 /]# ps -ef #一个bash进程(上帝进程)
[root@69f7753eb1e8 /]# exit #退出,容器关闭
[root@docker-0001 ~]# docker start 69f7753eb1e8 #启动被关闭容器
[root@docker-0001 ~]# docker attach 69f7753eb1e8
#Ctrl + p+ q 退出容器,但不会停止容器的运行
- 在对容器的使用过程中,都是使用exec,新开一个进程的方式进入容器,进行操作;
- 而attach 往往应用于调试,终端输出的情况;
容器与应用
删除之前所有的容器
shell
[root@docker-0001 ~]# docker rm -f $(docker ps -aq)
重新运行容器
shell
[root@docker-0001 ~]# docker run -it --name myapache centos:latest
[root@d7cfa9370097 /]# cd /etc/yum.repos.d/
[root@d7cfa9370097 yum.repos.d]# rm -rf *
把宿主机的yum文件拷贝给刚刚启动的容器
shell
[root@docker-0001 ~]# docker cp /etc/yum.repos.d/CentOS-Base.repo myapache:/etc/yum.repos.d/CentOS-Base.repo
此时就可以在容器里面安装相关的软件包
shell
[root@d7cfa9370097 yum.repos.d]# yum -y install httpd php psmisc iproute net-tools
[root@d7cfa9370097 yum.repos.d]# pstree -p
因为容器内并没有systemd的服务,无法使用systemctl来启动httpd的服务
查看httpd的服务文件,获取环境变量文件和服务启动命令
shell
[root@d7cfa9370097 /]# cat /lib/systemd/system/httpd.service
........
[Service]
EnvironmentFile=/etc/sysconfig/httpd #环境变量文件
ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND
#启动命令,$OPTIONS 此环境变量为空,可以不用写
[root@d7cfa9370097 /]# cat /etc/sysconfig/httpd #从环境变量文件中,获取环境变量
......
LANG=C
[root@d7cfa9370097 html]# echo 'hello world' > /var/www/html/index.html
[root@dcfa9370097 /]# /usr/sbin/httpd -DFOREGROUND #启动httpd服务
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
可以在宿主机测试,通过提示的地址172.17.0.2(IP地址不要照抄)
shell
[root@docker-0001 ~]# curl 172.17.0.2
hello world
此时容器内容的终端是被占用的,是在前台运行的,如果关闭,不能够再次访问httpd,
若想要退出,使用ctrl + pq
shell
[root@docker-0001 ~]# docker exec -it d7cfa9370097 /bin/bash
[root@d7cfa9370097 /]# pstree -p
bash(1)---httpd(66)-+-httpd(67)
|-httpd(68)
|-httpd(69)
|-httpd(70)
`-httpd(71)
[root@d7cfa9370097 /]# exit
Dockerfile
- Dockerfile是用于构建Docker镜像的文本文件。它包含一组指令,用于描述镜像的基础操作,以及打包应用程序运行所需的所有依赖项。
Dockerfile 语法
FROM
:基础镜像RUN
:制作镜像时执行的命令,可以有多个ADD
:复制文件到镜像,自动解压 (文件类型为: tar.gz 或 tar.bz2)COPY
:复制文件到镜像,不解压MAINTAINER
:镜像创建者信息EXPOSE
:开放的端口ENV
:设置变量WORKDIR
:定义容器默认工作目录(等于cd)CMD
: 容器启动时执行的命令,仅可以有一条CMD,若多条会覆盖,最后一条生效- CMD 容器的默认启动命令,可以自己定义,也可以使用默认的
- Dockerfile中,不指定CMD时,则使用默认的启动命令;
- 如果没有使用CMD指定启动命令,则会继承上一个镜像的默认启动命令;
- CMD 容器的默认启动命令,有且只能有一条;
使用 Dockerfile 工作流程
- mkdir build
- cd build
- 编写 Dockerfile
- 根据Dockerfile生成新的镜像:docker build -t imagename Dockerfile所在目录
案例
- 创建支持httpd服务镜像
因为容器内并没有systemd的服务,无法使用systemctl来启动httpd的服务
查看httpd的服务文件,获取环境变量文件和服务启动命令
shell
[root@a670096c60ad /]# cat /lib/systemd/system/httpd.service
........
[Service]
EnvironmentFile=/etc/sysconfig/httpd #环境变量文件
ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND #启动命令,$OPTIONS此环境变量为空
[root@a670096c60ad /]# vim /etc/sysconfig/httpd #从环境变量文件中,获取环境变量
......
LANG=C
[root@a670096c60ad /]# LANG=C #设置环境变量
[root@54cb8bfa063d /]# /usr/sbin/httpd -DFOREGROUND #启动httpd服务,Ctrl + C 退出
编写httpd的Dockerfile文件(从这里开始做)
dockerfile
[root@docker-0001 ~]# mkdir web
[root@docker-0001 ~]# cd web/
[root@docker-0001 web]# vim Dockerfile
FROM docker.io/centos:latest
RUN yum -y install httpd php
ENV LANG=C
EXPOSE 80
WORKDIR /var/www/html
COPY index.html /var/www/html/
CMD ["/usr/sbin/httpd","-DFOREGROUND"]
生成index.html
shell
[root@docker-0001 web]# echo 123 > index.html
build 创建新的镜像;-t 指定新镜像的名字和标签;. 指定Dockerfile文件所在的目录
shell
[root@docker-0001 web]# docker build -t myos:httpd .
shell
[root@docker-0001 web]# docker images
[root@docker-0001 web]# docker run -itd myos:httpd #后台启动容器,因为是一个服务
[root@docker-0001 web]# docker ps #查看正在使用的容器
[root@docker-0001 web]# docker inspect 800b21aa9736 #查看容器的详细信息
[root@docker-0001 web]# curl http://172.17.0.2/ #IP地址不要抄
总结
- 掌握Docker容器管理平台
- 掌握镜像和容器的关系
- 掌握镜像管理命令
- 掌握容器管理命令
- 掌握Dockerfile语法格式