1.起源
最初是基于Linux开发的技术
2.Docker
2.1 起源
Docker最初是DotCloud公司在法国期间发起的一个公司内部项目,后来以Apache2.0授权协议开源,代码在Github上维护。
Docker是基于Google公司推出的Golang语言开发而来,基于Linux内核的Cgroups、NameSpace,以及Union FS等技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术。
由于隔离的进程独立于宿主机和其他隔离的进程,也被称之为容器。
最初的Docker是基于LXC的,后来去除LXC转而使用自行开发的Libcontainer。
Docker被定义为开源的容器引擎,可以方便的对容器进行管理。例如对镜像打包封装,引入Docker Registry对镜像统一管理。
利用Docker可以实现开发,测试,生产环境的部署致性,极大的减少运维成本。
解释:
以前:开发和运维需要互相沟通来进行代码的环境配置才能对开发人员开发完成的程序进行部署测试。
现在有了docker:在代码写好后还会开发dockerfile脚本,即将代码和依赖关系打包为镜像文件docker image,其他人员可以直接运行。
2.2容器与传统虚拟机技术的区别
虚拟机:固定的硬件资源,完整的操作系统
容器:可变的硬件资源(性能可变),无操作系统(更轻便)
相比于虚拟机技术的优点:性能强,可启动的容器数量多,启动时间短,无需硬件虚拟化的支持
3.Docker安装部署
3.1 docker安装
1.更新仓库元数据
[root@localhost ~]# wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
[root@localhost ~]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
[root@localhost ~]# yum clean all
[root@localhost ~]# yum makecache
[root@localhost ~]# iptables -F
[root@localhost ~]# getenforce
2.下载和更新各种依赖包
[root@localhost ~]# yum install -y bash-completion vim lrzsz wget expect net-tools nc nmap tree dos2unix htop iftop iotop unzip telnet sl psmisc nethogs glances bc ntpdate openldap-devel
3.关闭防火墙
[root@localhost ~]# systemctl disable firewalld
4.查看系统当前内核是否大于等于3.10
[root@localhost ~]# uname -r
3.10.0-957.el7.x86_64
5.配置流量转发(用于docker和宿主机的端口映射)
[root@localhost ~]# cat <<EOF > /etc/sysctl.d/docker.conf
> net.bridge.bridge-nf-call-ip6tables = 1
> net.bridge.bridge-nf-call-iptables = 1
> net.ipv4.ip_forward=1
> EOF
执行上述指令后可能会出现下述问题:
[root@localhost ~]# sysctl -p /etc/sysctl.d/docker.conf
sysctl: cannot stat /proc/sys/net/bridge/bridge-nf-call-ip6tables: No such file or directory
sysctl: cannot stat /proc/sys/net/bridge/bridge-nf-call-iptables: No such file or directory
net.ipv4.ip_forward = 1
解决办法:
[root@localhost ~]# modprobe br_netfilter
[root@localhost ~]# sysctl -p /etc/sysctl.d/docker.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
6.更新仓库
[root@localhost ~]# curl -o /etc/yum.repos.d/docker-ce.repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 2081 100 2081 0 0 9609 0 --:--:-- --:--:-- --:--:-- 9634
[root@localhost ~]# curl -o /etc/yum.repos.d/Centos-7.repo http://mirrors.aliyun.com/repo/Centos-7.repo
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 2523 100 2523 0 0 9954 0 --:--:-- --:--:-- --:--:-- 9972
[root@localhost ~]# yum clean all && yum makecache
7.安装社区版docker
[root@localhost ~]# yum install docker-ce-20.10.6 -y
8.配置daemon.json文件
[root@localhost ~]# mkdir -p /etc/docker
[root@localhost ~]# touch /etc/docker/daemon.json
[root@localhost ~]# vim /etc/docker/daemon.json
9.重载daemon文件并启动docker
[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl enable docker
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.
[root@localhost ~]# systemctl restart docker
[root@localhost ~]# ps -ef|grep docker
root 22392 1 0 01:45 ? 00:00:00 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
root 23113 22145 0 01:46 pts/1 00:00:00 grep --color=auto docker
3.2容器部署
1.查看正在运行的镜像以及下载的镜像
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
2.查看docker版本
[root@localhost ~]# docker version
Client: Docker Engine - Community
Version: 25.0.4
API version: 1.41 (downgraded from 1.44)
Go version: go1.21.8
Git commit: 1a576c5
Built: Wed Mar 6 16:33:16 2024
OS/Arch: linux/amd64
Context: default
Server: Docker Engine - Community
Engine:
Version: 20.10.6
API version: 1.41 (minimum version 1.12)
Go version: go1.13.15
Git commit: 8728dd2
Built: Fri Apr 9 22:43:57 2021
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.6.28
GitCommit: ae07eda36dd25f8a1b98dfbf587313b99c0190bb
runc:
Version: 1.1.12
GitCommit: v1.1.12-0-g51d5e94
docker-init:
Version: 0.19.0
GitCommit: de40ad0
3.查找并拉取nginx镜像文件
[root@localhost ~]# docker search nginx
[root@localhost ~]# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
e1caac4eb9d2: Pull complete
88f6f236f401: Pull complete
c3ea3344e711: Pull complete
cc1bb4345a3a: Pull complete
da8fa4352481: Pull complete
c7f80e9cdab2: Pull complete
18a869624cb6: Pull complete
Digest: sha256:c26ae7472d624ba1fafd296e73cecc4f93f853088e6a9c13c0d52f6ca5865107
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
4.列举下载的镜像
[root@localhost ~]# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest e4720093a3c1 3 weeks ago 187MB
5.查看打开的端口
[root@localhost ~]# netstat -tunlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 1/systemd
tcp 0 0 0.0.0.0:6000 0.0.0.0:* LISTEN 8874/X
tcp 0 0 192.168.122.1:53 0.0.0.0:* LISTEN 7285/dnsmasq
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 6817/sshd
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN 6813/cupsd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 7250/master
tcp6 0 0 :::111 :::* LISTEN 1/systemd
tcp6 0 0 :::6000 :::* LISTEN 8874/X
tcp6 0 0 :::22 :::* LISTEN 6817/sshd
tcp6 0 0 ::1:631 :::* LISTEN 6813/cupsd
tcp6 0 0 ::1:25 :::* LISTEN 7250/master
udp 0 0 192.168.122.1:53 0.0.0.0:* 7285/dnsmasq
udp 0 0 0.0.0.0:67 0.0.0.0:* 7285/dnsmasq
udp 0 0 0.0.0.0:68 0.0.0.0:* 46221/dhclient
udp 0 0 0.0.0.0:111 0.0.0.0:* 1/systemd
udp 0 0 0.0.0.0:5353 0.0.0.0:* 6127/avahi-daemon:
udp 0 0 0.0.0.0:51497 0.0.0.0:* 6127/avahi-daemon:
udp 0 0 127.0.0.1:323 0.0.0.0:* 6168/chronyd
udp 0 0 0.0.0.0:789 0.0.0.0:* 6135/rpcbind
udp6 0 0 :::111 :::* 1/systemd
udp6 0 0 ::1:323 :::* 6168/chronyd
udp6 0 0 :::789 :::* 6135/rpcbind
6.运行镜像文件并列举镜像
-d :后台运行容器
-p 80:80 :端口映射,将宿主机的80端口映射到容器的80端口
[root@localhost ~]# docker run -d -p 80:80 nginx
b3c6ecad288f3ccd49916458d4b60080b11f260ed76916ad265a45a7c7ccf974
[root@localhost ~]# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest e4720093a3c1 3 weeks ago 187MB
7.列举正在运行的镜像
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b3c6ecad288f nginx "/docker-entrypoint.…" 42 seconds ago Up 40 seconds 0.0.0.0:80->80/tcp, :::80->80/tcp frosty_buck
8.进入nginx网址
[root@localhost ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:7a:3c:09 brd ff:ff:ff:ff:ff:ff
inet 192.168.83.132/24 brd 192.168.83.255 scope global noprefixroute dynamic ens33
valid_lft 1497sec preferred_lft 1497sec
inet6 fe80::8ed:41f:eda1:da17/64 scope link noprefixroute
valid_lft forever preferred_lft forever
3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
link/ether 52:54:00:24:ea:00 brd ff:ff:ff:ff:ff:ff
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
valid_lft forever preferred_lft forever
4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN group default qlen 1000
link/ether 52:54:00:24:ea:00 brd ff:ff:ff:ff:ff:ff
5: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ed:74:61:25 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:edff:fe74:6125/64 scope link
valid_lft forever preferred_lft forever
7: veth01c5400@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether 12:f9:92:f0:69:28 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::10f9:92ff:fef0:6928/64 scope link
valid_lft forever preferred_lft forever
网址为:192.168.83.132
9.查看活跃的端口
[root@localhost ~]# netstat -tunlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 1/systemd
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 71475/docker-proxy
tcp 0 0 0.0.0.0:6000 0.0.0.0:* LISTEN 8874/X
tcp 0 0 192.168.122.1:53 0.0.0.0:* LISTEN 7285/dnsmasq
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 6817/sshd
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN 6813/cupsd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 7250/master
tcp6 0 0 :::111 :::* LISTEN 1/systemd
tcp6 0 0 :::80 :::* LISTEN 71481/docker-proxy
tcp6 0 0 :::6000 :::* LISTEN 8874/X
tcp6 0 0 :::22 :::* LISTEN 6817/sshd
tcp6 0 0 ::1:631 :::* LISTEN 6813/cupsd
tcp6 0 0 ::1:25 :::* LISTEN 7250/master
udp 0 0 192.168.122.1:53 0.0.0.0:* 7285/dnsmasq
udp 0 0 0.0.0.0:67 0.0.0.0:* 7285/dnsmasq
udp 0 0 0.0.0.0:68 0.0.0.0:* 46221/dhclient
udp 0 0 0.0.0.0:111 0.0.0.0:* 1/systemd
udp 0 0 0.0.0.0:5353 0.0.0.0:* 6127/avahi-daemon:
udp 0 0 0.0.0.0:51497 0.0.0.0:* 6127/avahi-daemon:
udp 0 0 127.0.0.1:323 0.0.0.0:* 6168/chronyd
udp 0 0 0.0.0.0:789 0.0.0.0:* 6135/rpcbind
udp6 0 0 :::111 :::* 1/systemd
udp6 0 0 ::1:323 :::* 6168/chronyd
udp6 0 0 :::789 :::* 6135/rpcbind
80端口由进程docker-proxy来管理
10.停止某容器(id号)
[root@localhost ~]# docker stop b3c6ecad288f
b3c6ecad288f
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4.Docker的生命周期
5.Docker镜像的原理
在获取redis镜像的时候,为什么下载了多行信息,最终获取的却是一个redis文件?
[root@localhost ~]# docker pull redis
Using default tag: latest
latest: Pulling from library/redis
e1caac4eb9d2: Already exists
7469c6c5b625: Pull complete
a3d1b68c4a62: Pull complete
152cbe749752: Pull complete
7218480dfba1: Pull complete
e61c48a0d344: Pull complete
4f4fb700ef54: Pull complete
82adb0efabd8: Pull complete
Digest: sha256:e647cfe134bf5e8e74e620f66346f93418acfc240b71dd85640325cb7cd01402
Status: Downloaded newer image for redis:latest
docker.io/library/redis:latest
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest e4720093a3c1 3 weeks ago 187MB
redis latest d1397258b209 8 weeks ago 138MB
5.1切换发行版
Linux内核+centos发行版组成了系统。因此,在内核不变的情况下,可以灵活地替换发行版,从而使用不同的系统。
1.拉取镜像
[root@localhost ~]# docker pull centos:7.8.2003
[root@localhost ~]# docker pull ubuntu
2.查看当前所处发行版
[root@localhost ~]# cat /etc/redhat-release
CentOS Linux release 7.6.1810 (Core)
[root@localhost ~]# uname -r
3.10.0-957.el7.x86_64
3.在容器中运行centos 7.8.2003发行版(借用宿主机的Linux内核)
运行容器且进入容器内
-i:交互式命令操作
-t:开启一个终端
afb6fca791e0:镜像user id
bash:进入容器后执行的命令,开启shell解释
[root@localhost ~]# docker run -it afb6fca791e0 bash
4.查看容器内的发行版本
[root@1f49f16c6e9f /]# cat /etc/redhat-release
CentOS Linux release 7.8.2003 (Core)
5.退出容器空间
[root@1f49f16c6e9f /]# exit
exit
6.在容器中运行Ubuntu发行版
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest ca2b0f26964c 10 days ago 77.9MB
nginx latest e4720093a3c1 3 weeks ago 187MB
redis latest d1397258b209 8 weeks ago 138MB
centos 7.8.2003 afb6fca791e0 3 years ago 203MB
root@0bb41fed0552:/# cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=22.04
DISTRIB_CODENAME=jammy
DISTRIB_DESCRIPTION="Ubuntu 22.04.4 LTS"
7.在容器中运行suse发行版
[root@localhost ~]# docker run -it opensuse/leap bash
1f201ce945ab:/ # cat /etc/
cat: /etc/: Is a directory
1f201ce945ab:/ # cat /etc/hostname
1f201ce945ab
小结
-
一个完整的系统是由linux的内核+发行版组成
-
利用docker容器可以获取不同的发行版镜像,再配合linux内核,运行各种容器来实现不同的操作系统
5.2镜像原理
1.原理理解
1.进入正在运行的容器nginx中
[root@localhost ~]# docker exec -it b3c6ecad288f bash
2.查看nginx所在镜像的系统发行版
root@b3c6ecad288f:/# cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
NAME="Debian GNU/Linux"
VERSION_ID="12"
VERSION="12 (bookworm)"
VERSION_CODENAME=bookworm
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
root@b3c6ecad288f:/# exit
exit
2.Docker为什么要分层镜像
镜像分享一大好处就是共享资源,例如有多个镜像都来自于同一个base镜像,那么在docker host只需要存储一份base镜像。
内存里也只需要加载一份host,即可为多个容器服务
即使多个容器共享一个base镜像,某个容器修改了base镜像的内容,例如修改/etc/下配置文件,其他容器的/etc/下内容是不会被修改的,修改动作只限制在单个容器内,这就是容器的写入时复制特性 (Copy-on-write)
3.可写的容器层
容器层保存镜像层中被修改的部分,优先级高于镜像层(即运行时会替换镜像文件)
5.Docker镜像的内容
docker镜像层级管理的方式大大便捷了Docker镜像的分发和存储。Docker hub是全世界的镜像仓库。
-
Docker镜像代表一个容器的文件系统内容
-
镜像层级技术属于联合文件系统
-
容器是一个动态的环境,每一层镜像里的文件都属于静态内容。
-
dockerfile里的ENV、VOLUME、CMD等内容都会落实到容器环境里。