这些docker知识你必须知道!

Docker

容器技术已经成为应用程序封装和交付的核心技术
容器技术的核心有以下几个内核技术组成:
Cgroups(control groups) 资源管理
namespace 进程隔离
selinux 安全
docker是完整的一套容器管理系统, 提供了一组命令, 让用户更加方便直接的使用容器技术, 而不需要过多关心底层内核技术

docker的优点:
相比与传统的虚拟化技术, 更加简介高效
传统虚拟机需要给每个VM安装操作系统, docker不需要
容器使用的共享公共库和程序
docker的缺点:
容器的隔离性没有虚拟化强
公用linux内核, 安全性有先天缺陷
selinux难以驾驭
监控容器和容器排错是挑战

镜像:

在docker中容器是基于镜像启动的
镜像是启动容器的核心
镜像采用分层设计
使用快照的COW技术, 确保底层数据不丢失

在这里插入图片描述
部署Docker

  • 需要64位操作系统,必须7以上的版本,而且要卸载防火墙。
  • 配置yum源,docker的软件包位于光盘RHEL7-extras.iso CentOS-7.5-1804.iso
    - mount -t iso9660 -o ro,loop CentOS-7.5-1804.iso /var/ftp/centos-1804
    - mount -t iso9660 -o ro,loop RHEL7-extras.iso /var/ftp/extras
    - yum remove firewalld-* //卸载防火墙
    - yum -y install docker
    - systemctl start docker //启动docker
    - systemctl enable docker

相关命令:
docker images //查看已有的镜像
docker search busybox //要求虚拟机可以上网,下载镜像。 带ok字样的是官方的
docker pull docker.io/busybox //下载镜像
docker push docker.io/busybox //上传镜像
docker images //再次查看
文件名REPOSITORY 标签TAG 编号ID IMAGE ID CREATED SIZE
docker.io/busybox latest 83aa35aa1c79 7 days ago 1.22 MB

镜像的备份与恢复:

  • 镜像如果不写 标签默认就是latest
    镜像名称(文件名) + 标签 == 唯一!
    docker save docker.io/busybox:latest -o busybox.tar -o 输出为文件 文件名任意 //镜像打包
    scp busybox.tar root@192.168.1.22:/root
    docker load -i busybox.tar -i为input为导入 可以docker load --help查看 //镜像导入

容器的镜像采用分层设计最大255层,下面的层都是只读的
docker history docker.io/busybox:latest //查看镜像历史 了解镜像制作过程
docker inspect docker.io/busybix:latest //查看镜像底层信息
docker tag //创建链接,复制
docker rmi //删除本地镜像
镜像里面可以是服务和系统,服务和系统是一种应用

六个命名空间:

  • 隔离主机名
  • 隔离文件系统 在容器里创建文件,源主机看不见
  • 隔离用户
  • 隔离网络 ip地址不同但是可以ping通
  • 隔离进程 进程的pid是跟真机不同
  • 信号相量

启动容器相关命令:

docker run -参数 镜像名称:标签 启动命令

  • 交互参数 -i
  • 终端参数 -t
  • 后台参数(服务) -d
[root@kubenode-01 ~]# docker run -it docker.io/centos:latest  /bin/bash
#这样就进入到容器里了
[root@5bf2300e4a43 /]# hostname
5bf2300e4a43

隔离用户

[root@kubenode-01 ~]# cat /etc/passwd | wc -l
43
[root@5bf2300e4a43 /]# cat /etc/passwd | wc -l
15

隔离网络

[root@kubenode-01 ~]# ifconfig eth0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.21  netmask 255.255.255.0  broadcast 192.168.1.255

        
[root@5bf2300e4a43 /]# ifconfig eth0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.2  netmask 255.255.0.0  broadcast 0.0.0.0
       

隔离文件系统

[root@5bf2300e4a43 /]# mkdir test ; ls /
bin  dev  etc  home  lib  lib64  media  mnt  opt  proc
root  run  sbin  srv  sys  test  tmp  usr  var

[root@kubenode-01 ~]# ls /
bin   dev  file  lib    media  opt   root  sbin  sys  usr
boot  etc  home  lib64  mnt    proc  run   srv   tmp  var  
kubenode1上并没有刚才创建的test目录

隔离进程

[root@5bf2300e4a43 /]# ps -ef
UID         PID   PPID  C STIME TTY          TIME CMD
root          1      0  0 10:16 ?        00:00:00 /bin/bash
root         79      1  0 10:27 ?        00:00:00 ps -ef
#一个系统不可能有两个PID一样的进程
[root@kubenode-01 ~]# ps -ef
UID         PID   PPID  C STIME TTY          TIME CMD
root          1      0  0 17:13 ?        00:00:03 /usr/lib/systemd/systemd --switched-root --system --des
root          2      0  0 17:13 ?        00:00:00 [kthreadd]

启动nginx镜像创建容器

[root@kubenode-01 ~]# docker run -itd docker.io/nginx:latest 
fd43bf1bf45e6777fa9b0b08d24d2a316cda8fd5f0b7f74f2588025f469e9f26
[root@kubenode-01 ~]# docker ps  查看启动的容器
CONTAINER ID
fd43bf1bf45e (容器ID)
[root@kubenode-01 ~]# docker inspect fd	  查看容器的相关信息,得知IP地址
.....
 "IPAddress": "172.17.0.2",
.....

[root@kubenode-01 ~]# curl http://172.17.0.2
<!DOCTYPE html>
....
<title>Welcome to nginx!</title>  #启动成功
......

docker ps 查看正在运行的容器 加 -a 是查看所有容器
docker ps -aq 查询所有运行容器的id
docker stop //关闭容器
docker run -itd docker.io/nginx:latest //加-d选项在后台运行
docker inspect 容器id //查询容器的详细信息
docker start 容器id //开启容器
docker stop 容器id
docker restart //重启容器
docker top 容器id //查看容器中的进程
docker rm 容器id //删除容器,删除启动中的容器时要加-f选项
docker rm $(docker ps -q) //删除括号命令中的执行结果
docker exec -it 容器id /bin/bash //进入容器。
echo $$ //显示当前的pid号
docker attch 容器id //以上帝身份进入容器(一般排错用,尽量不用)
如果pid是1 exit容器回被关闭!

自定义镜像

  • 先进入一个容器
  • 可以在容器里下载软件包等操作。。
  • 退出容器
  • 执行docker commit 容器ID 镜像名称:标签名称

dockerfile关键词:

  • FROM:基础镜像
  • ADD:复制文件到镜像 宿主机的文件放到容器里去
  • RUN:在容器内执行命令
  • CMD :容器启动时执行的命令
  • ENV:设置变量
  • EXPOSE:开放的端口
  • WORLDIR :定义容器默认工作目录,作用相当于cd
  • CMD的语法格式
    /bin/ls -l -a
    CMD [ “/bin/ls”, “-l”,"-a"]

书写dockerfile:

[root@kubenode-01] # mkdir demo ; touch local.repo  dockerfile
[root@kubenode-01 demo]# ls
dockerfile  local.repo
#local.repo 必须在跟 Dockerfile文件的相同目录中
[root@kubenode-01 demo]# vim dockerfile
FROM  docker.io/centos:latest		//基于centos:latest 镜像做
RUN  rm -rf /etc/yum.repos.d/*.repo	//RUN表示在容器内执行命令
ADD  local.repo  /etc/yum.repo.d/local.repo	//将真机的local.repo文件拷贝到容器里
#local.repo 必须在跟 Dockerfile文件的相同目录中
RUN yum -y install net-tools bash-completion iproute vim psmisc 

[root@kubenode-01 demo]#   docker build  -t new.io:test .   #必须在dockerfile所在目录下操作
Sending build context to Docker daemon 3.584 kB
Step 1 : FROM docker.io/centos:latest
 ---> 76d6bc25b8a5
Step 2 : RUN rm -rf /etc/yum.repos.d/*.repo
 ---> Running in afd64221b997
 ---> 02c37cc3f241
 .......
[root@kubenode-01 demo]# docker images
REPOSITORY          TAG               IMAGE ID            CREATED             
new.io              test             f1b594b99f70        7 minutes ago       

书写dockerfile自定义web网站

先启动一个容器测试:
[root@kubenode-01 web]# docker run -it my.io:test
[root@e0edacd90733 /]# yum -y install httpd
[root@e0edacd90733 /]# systemctl restart httpd #报错,容器里自己是没无法启动服务
[root@e0edacd90733 /]# rpm -ql httpd | grep service
/usr/lib/systemd/system/htcacheclean.service
/usr/lib/systemd/system/httpd.service
[root@e0edacd90733 /]# cat /usr/lib/systemd/system/httpd.service
[Service]
Type=notify
EnvironmentFile=/etc/sysconfig/httpd #运行环境
ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND #启动命令

[root@e0edacd90733 /]# cat /etc/sysconfig/httpd #查看运行环境需要的变量
[root@e0edacd90733 /]# exit #退出容器


[root@kubenode-01 ~ ]# mkdir web
[root@kubenode-01 web]# touch dockerfile
[root@kubenode-01 web]# vim dockerfile
FROM my.io:test
RUN yum -y install httpd
ENV LANG=C
WORKDIR /var/www/html
EXPOSE 80
CMD ["/usr/sbin/httpd"," -DFOREGROUND"]
RUN echo ‘Hello world’ > /var/www/html/index.html
:wq
[root@kubenode-01 web]# docker build -t myweb.io:httpd .
[root@kubenode-01 web]# docker images
REPOSITORY TAG IMAGE ID CREATED
myweb.io httpd 8696c3f5e63d 20 seconds ago

[root@kubenode-01 web]# docker run -itd myweb.io:httpd
cb73c033eff96867b22537e3fd14df1dd740822cbc34ac0ba3897c0a98e1a25e
[root@kubenode-01 web]# docker inspect cb
[root@kubenode-01 web]# curl http://172.17.0.3
Hello world


自定义私有仓库

1.安装软件包并启动私有仓库
[root@kubenode-01 ~]# yum -y install docker-distribution.x86_64
[root@kubenode-01 ~]# systemctl start docker-distribution.service
[root@kubenode-01 ~]# systemctl enable docker-distribution.service
[root@kubenode-01 ~]# ss -ntulp | grep 5000
tcp LISTEN 0 128 :::5000 ::😗 users:
[root@kubenode-01 ~]# curl http://192.168.1.100:5000/v2/_catalog //访问私有仓库
{“repositories”:[]}

2.宣告docker的仓库地址(修改所有docker主机的配置文件)

  • 停止所有容器

[root@kubenode-01 ~]# vim /etc/sysconfig/docker //修改主配置文件
修改13,23行
INSECURE_REGISTRY=’–insecure-registry 192.168.1.100:5000’ //允许非加密方式访问仓库
ADD_REGISTRY=’–add-registry 192.168.1.100:5000’ //docker仓库地址
:wq
[root@kubenode-01 ~]# systemctl restart docker
curl http://192.168.1.100:5000/v2/_catalog //访问测试
[root@kubenode-01 ~]# rsync -av /etc/sysconfig/docker root@192.168.1.22:/etc/sysconfig/docker
[root@kubenode-02 ~]# systemctl restart docker
curl http://192.168.1.100:5000/v2/_catalog //访问测试

3.上传镜像到私有仓库(必须打标签)
docker tag myos:httptest 192.168.1.100:5000/myos:httptest //打标签
docker push 192.168.1.100:5000/myos:httptest //上传镜像
curl http://192.168.1.100:5000/v2/_catalog
curl http://192.168.1.100:5000/v2/myos/tags/list //查看标签
4. 使用镜像启动容器
docker02利用仓库中的镜像启动容器
docker run -it 192.168.1.100:5000/myos:latest //下载镜像生成容器
/var/lib/registry/ //存放镜像的目录,要删除镜像进入目录里

持久化存储

卷的概念:

  • docker容器不保持任何数据

  • 重要数据请使用外部卷存储

  • 容器可以挂在真实机目录或共享存储为卷

    docker run -it -v 宿主机目录或文件:容器内目录或文件 myos:latest

映射目录

修改主机的映射目录就是修改容器里被映射的目录

[真机: ] #docker run -itd -v /tmp:/httpd myos.httpd 将宿主机的tmp目录映射到容器里叫httpd
[真机: ] #docker exec -it 00 /bin/bash
[容器 00:] # cp /etc/httpd/conf/httpd.conf /httpd
[容器 00:] # exit
[真机: ] # vim /tmp/httpd.conf 将端口改为8080
[真机: ] # docker run -it -v /tmp/httpd.cof: /etc/httpd/conf/httpd.conf myos.httpd
[真机: ] #docker exec -it ac /bin/bash
[容器 ac:] # ss -ntulp | grep 8080 发现端口已被改成8080

使用NFS共享存储:

Docker主机挂在共享目录,在将共享目录映射到容器中。
在这里插入图片描述
[root@module ~]# rpm -qa | grep nfs-utils 下载NFS软件提供服务
nfs-utils-1.3.0-0.54.el7.x86_64
[root@module ~]# vim /etc/exports
/var/webhome *(rw)
:wq
root@module ~]# mkdir /var/webhome 将/var/webhome共享出去
[root@module ~]# chmod 777 /var/webhome
[root@module ~]# systemctl restart nfs
[root@module ~]# echo Hello world > /var/webhome/index.html


[root@kubenode-01 ]# yum -y install nfs
[root@kubenode-01 ]#showmount -e 192.168.1.100
[root@kubenode-01 ]#mount -t nfs 192.168.1.100:/var/webhome /mnt
[root@kubenode-01 ]#docker run -it docker.io/nginx:latest /bin/bash 进容器加/bin/bash
[root@kubenode-01 ]#docker run -itd -v /mnt:/usr/share/nginx/html docker.io/nginx 启动服务不加
[root@kubenode-01 ]#docker inspect 3e 查看IP地址
[root@kubenode-01 ]#curl -i 172.17.0.2
[root@kubenode-01 tmp]# curl -i 172.17.0.2
HTTP/1.1 200 OK
Server: nginx/1.15.8

hellow world


[root@kubenode-2 ]# yum -y install nfs
[root@kubenode-2 ]#showmount -e 192.168.1.100
[root@kubenode-2 ]#mount -t nfs 192.168.1.100:/var/webhome /mnt
[root@kubenode-2 ]# docker run -itd -v /mnt:/var/www/html/ 192.168.1.100:5000/web2:test2 直接使用仓库里的镜像启动容器
[root@kubenode-2 ]#docker inspect 14
[root@kubenode-2 ]# curl -i 172.17.0.3
[root@kubenode-02 ~]# curl -i 172.17.0.3
HTTP/1.1 200 OK
Date: Fri, 26 Jun 2020 14:26:07 GMT
Server: Apache/2.4.6 (CentOS)

hellow world


自定义网桥

在docker中利用镜像生成的容器默认是接在docker0上
可以将docker0想象成一个虚拟的交换机
[root@kubenode-01 ~]# docker network ls #查看docker网络
NETWORK ID NAME DRIVER SCOPE
2b4687baca4f bridge bridge local
47cd23c7c75b host host local
80e09e8993fe none null local
[root@kubenode-01 ~]# docker network create --subnet 10.10.10.0/24 docker1 生成docker1为10网段
81d2964dfaf2e87d6b88dcc33be9aac67dbfae84cf9f04f483ef4d2b7446e459
[root@kubenode-01 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
2b4687baca4f bridge bridge local
81d2964dfaf2 docker1 bridge local

[root@kubenode-01 ~]# docker run -it --network=docker1 new.io:test 指定网络创建容器
[容器: ]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.10.10.2 netmask 255.255.255.0 broadcast 0.0.0.0

利用docker1网络创建的容器不能与docker0的容器互通,在有网络需求的架构中可以使用这种方法
[root@kubenode-01 ~]# docker network rm docker1 删除


对外发布服务:

  • 默认容器可以访问外网
  • 但外部网络的主机不可以访问容器内的资源
  • 容器的特征是可以把宿主机变成对应的服务
  • 我们可以使用-p 参数把容器端口和宿主机的端口做绑定
    • -p 宿主机端口:容器端口
    • 例如把docker1 变成httpd
      • docker run -itd -p 80:80 docker.io/myos:httpd
    • 例如把docker1 变成nginx
      • docker run -itd -p 80:80 docker.io/nginx:latest

[root@kubenode-01 ~]# docker run -itd -p80:80 docker.io/nginx:latest
61808de85e36d20c6fe85230f1798754d319c08a4f927443ff79f81902a9a47d
[root@kubenode-01 ~]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.1.21 netmask 255.255.255.0 broadcast 192.168.1.255

  • 使用浏览器访问 192.168.1.21
    在这里插入图片描述
    [root@kubenode-01 ~]# docker run -itd -p8080:80 web2:test 利用端口绑定启动httpd容器
    • 使用浏览器访问 192.168.1.21
      在这里插入图片描述

[root@kubenode-01 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
34d68a846541 docker.io/nginx:latest “nginx -g 'daemon off” 3 seconds ago Up 2 seconds 0.0.0.0:80->80/tcp big_ramanujan
3dd247af8b7f web2:test “/usr/sbin/httpd -DFO” About a minute ago Up About a minute 0.0.0.0:8080->80/tcp big_mclean

谈谈我对docker的理解:

  • docker的重点在于镜像的编排,可以把各种服务放到容器中,很轻便
  • 利用docker save 保存镜像,或者搭建私有仓库实现批量部署
  • 镜像的编排就像盖房子一样,镜像的后端盘都是只读的,利用docker commit 容器ID 镜像:标签 生成新的镜像
  • 假如需要部署10台DNS,直接利用dockerfile写一个DNS镜像,在所有机器上执行端docker 的绑定端口将容器的服务寄生在宿主机上
  • docker的难点我觉得在于镜像的编排…
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值