容器是用来装东西的,Linux 里面的容器是用来装应用的;
容器就是将软件打包成标准化单元,以用于开发、交付和部署;
容器技术已经成为应用程序封装和交付的核心技术;
容器原理:容器技术的核心,由以下几个内核技术组成:
UTS
:主机名隔离NETWORK
:网络隔离MOUNT
:文件系统隔离USER
:用户隔离PID
:进程隔离IPC
:信号向量隔离优点
缺点
Docker
使用模板机的克隆以下机器,配置如下
主机名 | IP地址 | 内存 | CPU |
---|---|---|---|
docker-0001 | 192.168.8.107 | 2G | 2 |
docker-0002 | 192.168.8.108 | 2G | 2 |
docker-0001配置IP地址和主机名
[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地址和主机名
[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-0001为例)
开启路由转发,docker是通过虚拟交换机来进行通讯的,需要开启路由转发的功能
[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 中容器是基于镜像启动的
镜像采用分层设计,使用 COW 技术
容器本身是没有操作系统,和宿主机共用一个操作系统;
容器是docker(容器的管理工具)使用镜像文件来启动的;
镜像是启动容器的模板,镜像中存放的是应用程序(服务软件),例如: 有一个http的镜像文件,在这个镜像中就存放的是http的所有文件和变量;
用户使用镜像启动容器时,会生成一个独立于镜像的容器层,并不会对镜像层产生任何影响;
而且容器采用了cow(写时复制)的技术,用户可以使用一个镜像文件创建多个容器,互不干扰;
镜像采用分层技术:
镜像来源
docker images
#查看本机镜像docker search 关键词
#查找包含关键词的镜像docker pull 镜像名称:标签
#下载镜像docker rmi 镜像名称:标签
#删除镜像docker history 镜像名称: 镜像标签
#查看镜像的制作历史docker inspect 镜像名称: 镜像标签
#查看镜像的信息docker tag 镜像名称: 镜像标签 新镜像名称: 新的标签
#为镜像的打新名称和标签[root@docker-0001 ~]# docker images #还没有导入镜像,所以没有镜像
[root@docker-0001 ~]# docker search busybox
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
busybox Busybox base image. 2010 [OK]
[root@docker-0001 ~]# docker pull busybox
查看镜像
[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导出镜像(备份)
[root@docker-0001 ~]# docker save busybox:latest -o /root/busybox.tar
#导出镜像busybox,需要指定名字和标签,导出到/root目录下,名称为busybox.tar
#名称和路径可以随意指定
拷贝备份镜像到docker-0002上
[root@docker-0001 ~]# scp /root/busybox.tar 192.168.8.108:/root/
docker-0002恢复镜像
[root@docker-0002 ~]# docker load -i busybox.tar
[root@docker-0002 ~]# docker images
教学环境中将docker-images目录上传到docker-0001的/root下,并导入这四个镜像到docker里面
[root@docker-0001 ~]# cd docker-images
[root@docker-0001 docker-images]# for i in *.tar.gz
> do
> docker load -i $i
> done
docker-0001看镜像的制作历史
[root@docker-0001 ~]# docker history centos:latest #由下到上,镜像可以分为3层
查看镜像的信息
[root@docker-0001 ~]# docker inspect centos:latest
[root@docker-0001 ~]# docker inspect nginx:latest
..........
"Cmd": [ # Cmd 默认的启动命令,即:启动容器时,默认的启动命令
"nginx",
"-g",
"daemon off;"
],
..........
docker-0001为镜像busybox:lastest打的新名称和标签
[root@docker-0001 ~]# docker tag busybox:latest xxhh:test
docker-0001删除镜像
[root@docker-0002 ~]# docker rmi busybox:latest
docker run -参数 镜像名称:镜像标签 启动命令
#创建+运行+进入容器命令docker ps [-a] [-q]
#查看容器docker rm [-f]
#删除容器(-f强制)docker-0001根据centos镜像启动并进入一个容器
[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,放后台才能运行
查看容器
[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不能照抄,每个人都不一样)
[root@docker-0001 ~]# docker rm 512567e6f64f
删除正在使用的容器时,会报错,无法删除,需要先停止容器,再执行删除命令
[root@docker-0001 ~]# docker stop 512567e6f64f #停止容器
[root@docker-0001 ~]# docker rm 512567e6f64f
删除所有的容器:支持命令行重录,前一个命令的结果$(docker ps -aq)可以作为后一个命令的参数
[root@docker-0001 ~]# docker rm -f $(docker ps -aq) #$()用来获取命令的执行结果
docker start 容器id
#启动容器docker stop 容器id
#停止容器docker restart 容器id
#重启容器[root@docker-0001 ~]# docker run -itd nginx:latest
查看容器信息
[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>
............
[root@docker-0001 ~]# docker stop 38b8ee2a8754 #停止容器
[root@docker-0001 ~]# docker start 38b8ee2a8754 #启动容器
[root@docker-0001 ~]# docker restart 38b8ee2a8754 #重启容器
docker cp 本机文件路径 容器id:容器内路径
(上传)
docker cp 容器id:容器内路径 本机文件路径
(下载)
在第一个终端中执行
[root@docker-0001 ~]# docker run -it centos:latest
[root@69f7753eb1e8 /]# cd /etc/yum.repos.d/
[root@69f7753eb1e8 yum.repos.d]# rm -rf *
#另外开一个docker-0001的终端操作
[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
[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 #退出
[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 退出容器,但不会停止容器的运行
删除之前所有的容器
[root@docker-0001 ~]# docker rm -f $(docker ps -aq)
重新运行容器
[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文件拷贝给刚刚启动的容器
[root@docker-0001 ~]# docker cp /etc/yum.repos.d/CentOS-Base.repo myapache:/etc/yum.repos.d/CentOS-Base.repo
此时就可以在容器里面安装相关的软件包
[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的服务文件,获取环境变量文件和服务启动命令
[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地址不要照抄)
[root@docker-0001 ~]# curl 172.17.0.2
hello world
此时容器内容的终端是被占用的,是在前台运行的,如果关闭,不能够再次访问httpd,
若想要退出,使用ctrl + pq
[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
FROM
:基础镜像RUN
:制作镜像时执行的命令,可以有多个ADD
:复制文件到镜像,自动解压 (文件类型为: tar.gz 或 tar.bz2)COPY
:复制文件到镜像,不解压MAINTAINER
:镜像创建者信息EXPOSE
:开放的端口ENV
:设置变量WORKDIR
:定义容器默认工作目录(等于cd)CMD
: 容器启动时执行的命令,仅可以有一条CMD,若多条会覆盖,最后一条生效
使用 Dockerfile 工作流程
因为容器内并没有systemd的服务,无法使用systemctl来启动httpd的服务
查看httpd的服务文件,获取环境变量文件和服务启动命令
[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文件(从这里开始做)
[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
[root@docker-0001 web]# echo 123 > index.html
build 创建新的镜像;-t 指定新镜像的名字和标签;. 指定Dockerfile文件所在的目录
[root@docker-0001 web]# docker build -t myos:httpd .
[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地址不要抄