Docker容器入门操作介绍

Docker介绍

Docker是通过内核虚拟化技术(namespaces及cgroups等)来提供容器的资源隔离与安全保障等。由于Docker在操作系统层实现隔离,所以Docker容器在运行时,不需要类似虚拟机(VM)额外的操作系统开销,提高资源利用率。

Docker运行结构

Docker是一个C/S结构的项目,有Docker Client、RESTAPI、Docker Server、images、container、 volumes、network组成。

  • Docker Client:Docker客户端命令工具。
  • REST API:提供标准的RESTful接口。
  • Docker Server::Docker daemon的主要组成部分,接收用户从Docker Client调用REST API发送过来的请求。
  • images:docker镜像,是Docker run的原材料。
  • container: Docker运行的内容,是独立存在的。
  • data volumes: 通过数据挂载的方式,实现数据共享;
  • network:用户容器与外部、容器之间的通信,常用的方法有端口映射、link等。

Docker的优点:

  • 灵活:即使是复杂的应用程序也可封装。
  • 轻量级:容器利用并共享主机内核。
  • 便携式:您可以在本地构建,部署到云上并在任何地方运行。
  • 可扩展性:您可以增加和自动分发容器副本。
  • 可堆叠:您可以垂直堆叠服务并及时并及时堆叠服务。

主机虚拟化和容器的区别

一个容器中运行原生Linux和共享主机与其它容器的内核,它运行一个独立的进程,不占用任何其它可执行文件的内存,使其轻量化。相比之下,虚拟机(VM)运行一个完整的“客户”操作系统,通过虚拟机管理程序虚拟访问主机资源。一般来说,虚拟机提供的环境比大多数应用程序需要的资源多。

虚拟机

虚拟机(virtual machine)就是带环境安装的一种解决方案。它可以在一种操作系统里面运行另一种操作系统,比如在Windows系统里面运行Linux系统。应用程序对此毫无感知,因为虚拟机看上去跟真丝系统一模一样,而对于底层系统来说,虚拟机就是一个普通文件,不需要了就删掉,对其它部分毫无影响。

虚拟机的缺点:

  • 资源占用多: 虚拟机会独占一部分内存和硬盘空间。它运行的时候,其他程序就不能使用这些资源了。哪怕虚拟机里面的应用程序,真正使用的内存只有1M,虚拟机依然需要几百MB的内容才能运行。
  • 冗余步骤多: 虚拟机是完整的操作系统,一些系统级别的操作步骤,往往无法跳过,比如用户登录。
  • 启动慢: 启动操作系统需要多久,启动虚拟机就需要多久。可能要等几分钟,应用陈故乡才能真正运行。

容器

由于虚拟机存在这个缺点,Linux发展出了另一种虚拟化技术:Linux容器(Linux Containers,缩写为LXC)。 Linux容器不是模拟一个完整的操作系统,而是对进程进行隔离。或者说,在正常进程的外面套了一个保护层。对于容器里面的进程来说,它接触到的各种资源都是虚拟的,从而实现与底层系统的隔离。由于容器是进程级别的,相比虚拟机又很多优势。

  • 启动快: 容器里面的应用,直接就是底层系统的一个进程,而不是虚拟机内部的进程。所以,启动容器相当于启动本机的一个进程,而不是启动一个操作系统,速度就快很多。
  • 资源占用少: 容器只占用需要的资源,不占用那些没有用到的资源;虚拟机由于是完整的操作系统,不可避免要占用所以资源。另外,多个容器可以共享资源,虚拟机都是独享资源。
  • 体积小: 容器只要包含用到的组件即可,而虚拟机是整个操作系统的打包,所以容器文件比虚拟机文件要小很多。总之,容器有点像轻量级的虚拟机,能够提供虚拟化的环境,但是成本开销小得多。

Docker与OpenStack对比

类别DockerOpenStack
部署难度非常简单组件多,部署复杂
启动速度秒级分钟级
执行性能和物理系统几乎一致VM会占用一些资源
镜像体积镜像是MB级别虚拟机镜像GB级别
管理效率管理简单组件相互依赖,管理复杂
隔离性隔离性高彻底隔离
可管理性单进程、不建议启动SSH完整的系统管理
网络连接比较弱借助Neutron可以灵活组件各类网络架构

Docker安装部署

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 环境准备
yum install -y yum-utils
# 官方yum仓库
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

# 建议使用国内Yum源
cd /etc/yum.repos.d/
wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

# 安装docker
yum list docker --show-duplicates
yum install -y docker-ce

# 配置镜像加速
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://l2v84zex.mirror.aliyuncs.com"]
"bip": "172.0.110.1/24" #建议docker IP与主机IP有关联。
}
EOF
# 启动docker
sudo systemctl daemon-reload
sudo systemctl enabled --now docker

Docker源码安装

源码下载位置:https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/static/stable/x86_64/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# 下载docker源码
mkdir /server/tools
cd /server/tools
wget https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/static/stable/x86_64/docker-20.10.21.tgz
tar xf docker-20.10.21.tgz -C /opt/
ln -s /opt/docker/* /bin/

# 创建systemd启动文件
cat > /usr/lib/systemd/system/docker.service <<EOF
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service containerd.service
Wants=network-online.target

[Service]
Type=notify
ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always
StartLimitBurst=3
StartLimitInterval=60s
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
TasksMax=infinity
Delegate=yes
KillMode=process

[Install]
WantedBy=multi-user.target
EOF

# 配置镜像加速
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://l2v84zex.mirror.aliyuncs.com"]
"bip": "172.0.110.1/24" #建议docker IP与主机IP有关联。
}
EOF
# 启动docker
sudo systemctl daemon-reload
sudo systemctl enabled --now docker

Docker基础命令操作

获取镜像

1
2
3
4
docker search centos
docker pull centos:6.9
docker pull centos:7.5.1804
docker pull nginx

查询镜像

1
2
3
docker images
docker images -q
docker inspect ID/name:tag

删除镜像

1
2
3
docker rmi  IID 
docker rmi `docker images -q`
docker rmi $(docker images -q)

导入导出镜像

1
2
docker image save nginx >/opt/nginx.tar.gz
docker image load -i /opt/nginx.tar.gz

容器体验

1
2
3
4
5
6
7
8
9
10
11
12
docker run hello-world
docker run -it --name="test_docker" 9f38484d220f /bin/bash
docker run -d -p 8080:80 --name="discuz" nginx:1.14

--name="新容器名称" # 为容器启一个名称
-d # 后台运行容器,并返回容器ID,也就是启动守护士容器
-i # 以交互模式运行容器,通常与-t同时使用.
-t # 为容器重新分配一个伪终端(tty),通过与-i同时使用
-P # 随机端口映射 [大写P]
-p # 端口映射 [小写P]
-v # 数据卷 加参数 ro:容器内的目录只读,不可写
# /宿主机绝对路径目录:/容器内目录[:ro] 镜像名

守护式启动

1
2
3
4
5
6
7
8
9
## 1.交互式启动容器+Ctrl+p+q
docker run -it --name "testnginx" nginx /bin/bash
加ctrl+p+q
docker attach testnginx

## 2.死循环
docker run --name testnginx1 -d nginx /bin/sh -c "while true ;do echo hello world; sleep 1;done"3.服务前台运行
sshd -D
nginx -g ""

容器网络访问

1
2
3
4
5
6
7
8
9
## 指定映射(docker 会自动添加一条iptables规则来实现端口映射)
-p hostPort:containerPort
-p ip:hostPort:containerPort
-p ip::containerPort(随机端口)
-p hostPort:containerPort/udp
-p 81:80 –p 443:443

##随机映射
docker run -P 80(随机端口)

容器的其他管理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
docker ps -a  -q -l
docker top testxx
docker inspect
docker attach 容器ID|容器名称(工具类)配合ctrl+p+q,退出容器会销毁容器。
docker exec -i -t 容器ID|容器名称 /bin/bash(服务类),一般是做服务类容器调试用(类似ssh服务,退出容器不会销毁)。
docker exec -it centos6.9 /bin/bash
docker logs testxx 查询日志
docker logs -t testxx
docker logs -tf testxx
docker logs -tf --tail 10 testxx
docker logs -tf --tail 0 testxx
-t # 加入的时间戳
-f # 跟随最新的日志打印
--tail 行数 # 输出最后几行的日志

数据卷管理

1
2
3
4
5
6
7
8
docker run -d -p 8083:80 --name "http8083" -v /opt/Volume/httpd:/usr/local/apache2/htdocs httpd 

docker run -d -p 8084:80 --name "http8084" -v /opt/Volume/httpd:/usr/local/apache2/htdocs httpd

[root@docker httpd]# curl 10.0.0.110:8083
test volume
[root@docker httpd]# curl 10.0.0.110:8084
test volume

数据卷容器

1
2
3
4
5
6
7
8
9
docker run -it  --name "httpd_volumes" -v /opt/Volume/httpd_volume/conf:/usr/local/apache2/conf -v /opt/Volume/httpd_volume/html:/usr/local/apache2/htdocs centos:6.9 /bin/bash
ctrl p q
拷贝数据到数据卷中
/opt/Volume/httpd_volume/html
/opt/Volume/httpd_volume/conf
docker cp DOCKERNAME:/opt/a.txt /opt
从给定容器装载所有卷
docker run -d -p 8085:80 --volumes-from httpd_volumes --name "http8085" httpd
docker run -d -p 8086:80 --volumes-from httpd_volumes --name "http8086" httpd