docker筆記

容器的概念
什麼是容器(一個容器就是啓了一個進程
容器就是在系統裏的一個進程
)
• 容器技術已經成爲應用程序封裝和交付的核心技術
• 容器技術的核心有以下幾個內核技術組成:
– CGroups(Control Groups)-資源管理
– NameSpace-進程隔離(命名空間)
讓你感知不到你是在一個籠子裏,給你砌上牆
– SELinux安全
限制容器的一些文件能不能訪問
• 由於是在物理機上實施隔離,啓動一個容器,可以像
啓動一個進程一樣快速
什麼是Docker
Docker是完整的一套容器管理系統
• Docker提供了一組命令,讓用戶更加方便直接地使
用容器技術,而不需要過多關心底層內核技術
Docker 相當於libvirtd 這個角色
虛擬化:kvm ---qemu----libvirtd
Docker特性
相比於傳統的虛擬化技術,容器更加簡潔高效
• 傳統虛擬機需要給每個VM安裝操作系統
• 容器使用的共享公共庫和程序
容器和虛擬化比起來,容器不需要裝操作系統,是容器的最大優勢,啓動速度快簡潔高效,也是劣勢因爲操作系統是固定的!

     虛擬化                               容器

Guest OS Docker
其實這缺一層libvirtd
Hypervisor Host OS
支持虛擬化的支持表示(KVM,QEMU,libvirtd) (表示不要KVM硬件仿真)
Infrastructure 硬件層 Infrastructure 硬件層

Host OS :表示不需要kvm 硬件仿真,沒有硬件概念,就是一個進程!
實際上libvirtd 和Docker是一層
它把libvirtd歸納到Hypervisor這一層了
容器優點:沒有操作系統,統一由Docker進程來管理!

Docker的缺點
• 容器的隔離性沒有虛擬化強
• 共用Linux內核,安全性有先天缺陷
• SELinux難以駕馭
• 監控容器和容器排錯是挑戰
部署Docker
安裝前準備
• 需要64位操作系統
• 至少RHEL6.5以上的版本,強烈推薦RHEL7
• 關閉防火牆(不是必須)Docker 會自動的管理系統的防火牆,所以在安裝Docker的時候要把系統的防火牆幹掉!
Docker 也會接管網絡的一部分,所以網絡的也要幹掉Network!
準備2臺虛擬機內存各4G
2臺都安裝
1.安裝軟件包:(docker_imges.zip)
配置自定義yum源
– docker-engine
– docker-engine-selinux
2.安裝yum install docker-engine
3.驗證:
systemctl start docker.service
Ifconfig
4.查看版本:
docker version
Docker使用
Docker有兩個概念,一個叫鏡像,一個叫容器!
虛擬機裏也有兩個概念,一個是模版,一個是實例!
模版:就是啓動實例的模版,模版在後端保存所啓動實例的文件和所需數據!
在Docker裏鏡像的概念和模版的概念一樣!
在虛擬機裏除了模版,還有一個啓動的虛擬機叫實例,在Docker裏啓動的容器,叫容器!
鏡像:是啓動容器的模版,是核心!

什麼是鏡像
• 在Docker中容器是基於鏡像啓動的
• 鏡像是啓動容器的核心
• 鏡像採用分層設計
• 使用快照的COW技術,確保底層數據不丟失
鏡像(後端盤)
Thin R/W layer 容器(前端盤)

公共的後端盤,有無數個前端盤,可以用這個後端盤快速的鏡像出無數個前端盤!
虛擬機的後端盤是自己做的,
Docker的容器後端盤是哪裏來的 ?
有2種方案
1.自己做,挺麻煩
2.容器的鏡像從官方下載!
3.下一層是上一次的後端盤,永遠只讀
Docker的命令
docker 的命令跟yum的命令挺像的!
yum search bash (這是yum搜索包的方式)
docker search centos (這是docker 搜索鏡像的方式)

docker images (查看有什麼鏡像)
docker help images (查看幫助)
docker images -a (顯示所有鏡像)
下載鏡像(從鏡像倉庫中下載鏡像)
[root@server0 ~]# docker help pull 查看幫助信息
docker pull [OPTIONS] NAME[:TAG|@DIGEST]
[root@server0 ~]# docker pull rhel7
• 上傳鏡像(上傳鏡像到倉庫)
[root@server0 ~]# docdocker help push
Usage: docker push [OPTIONS] NAME[:TAG]
[root@server0 ~]# docker push rhel7
搜索鏡像:docker search busybox
下載鏡像:docker pull busybox
鏡像備份:docker save busybox:latest >busybox.tar
Busybox:latest 默認是latest標籤,可以自己更改標籤!
查看包:file busybox.tar
查看內容:tar tvf busybox.tar
傳到192.168.1.12機子上:scp busybox.tar 192.168.1.12:/root/
恢復鏡像備份:docker load <busybox.tar

添加默認網關:ip route add default via 192.168.1.254或route add default gw 192.168.1.254 臨時添加
永久添加:/etc/sysconfig/network
GATEWAY=192.168.1.254

軟件包:dcoker_images.zip
在docker01機器上解壓: unzip docker_images.zip
導入鏡像:cd docker_images/
導入:for i in *; do docker load <${i}; done
啓動鏡像
• 啓動centos鏡像生成一個容器
[root@server0 ~]# docker images
[root@server0 ~]# docker run -it centos bash
Docker run -it +鏡像名:標籤 +(容器裏的命令)這裏你是不知道容器裏有什庅命令的?可以不寫,有默認啓動容器的命令!
-it:i是交互式的,t是分配一個終端
我在centos的鏡像裏所運行的命令!
啓動一個容器就是啓動一個進程,運行一個命令!
• 開啓另一個終端(查看容器信息)
[root@server0 ~]# docker ps
啓動centos鏡像:docker run -it centos /bin/bash
進入容器:
[root@171d6dd84557 /]#vi /etc/yum.repos.d/local.repo

[root@171d6dd84557 /]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 00:26 ? 00:00:00 /bin/bash
root 62 1 0 00:31 ? 00:00:00 ps -ef
容器裏Pid 進程爲1,系統的老大進程
容器裏有單獨的Ip,隔離起來了,
虛擬機運行的進程,在物理機上看不見,在物理機上運行的進程,虛擬機上也看不見!
容器是共享的,容器裏運行的命令,在系統裏是可以看見的,但是系統裏運行的命令,
容器裏是看不見的!系統可以管理容器裏的內容!
容器裏所有硬件的相關操作都會受限制,因爲硬件是和系統是共享的,不像虛擬機,有qemu仿真虛擬硬件!
查看正在運行的容器:docker ps
查看之前的容器:docker ps -a
簡略顯示:docker ps -aq q(只顯示id)
docker run -it nginx #卡在那裏了,nginx 是一個系統服務,啓動之後就掛在那裏了。
docker run -d nginx #表示以後臺進程的方式啓動nginx
-d 表示後臺進程
-itd :前臺進程,d後臺服務都包括,但是有一個問題,就是不交互了,一啓動就放在後臺了,如何進入交互呢?用這個命令!
docker exec -it f387376c4c57 /bin/bash
容器啓動進程,其實是分兩種的:
1.一種是用戶能交互使用的前臺進程。如果啓動一個前臺程序,沒有可交互式的終端,就和我們寫腳本,但是什庅也沒寫一樣!
2.還有一種是系統的服務, 後臺進程!
鏡像後面的命令是可以改變的 例:
docker run -it centos /bin/bash
docker run -it centos /usr/bin/python

命令列表
• 命令列表
– docker images //查看鏡像列表
– docker history //查看鏡像製作歷史
– docker inspect //查看鏡像底層信息
– docker pull //下載鏡像
– docker push //上傳鏡像
– docker rmi //刪除本地鏡像
– docker save //鏡像另存爲tar包
– docker load //使用tar包導入鏡像
– docker search //搜索鏡像
– docker tag //修改鏡像名稱和標籤

查看鏡像製作歷史:
docker history busybox
查看鏡像底層信息
docker inspect centos
環境變量:
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
默認啓動命令:

           "Cmd": [
            "/bin/sh",
            "-c",
            "#(nop) ",
            "CMD [\"/bin/bash\"]"
        ],

刪除本地鏡像:
注意:啓動容器時刪除鏡像會報錯!
docker rmi centos
刪除流程,先把容器刪了,再刪鏡像
刪除容器:docker rm +容器id #容器id用(docker ps -a 找)

修改鏡像名稱和標籤(和軟鏈接相似,ln)
查看i節點: ls -i busybox.tar
創建軟鏈接:ln busybox.tar f1
查看i節點: ls -i *
修改鏡像名稱和標籤
docker tag busybox:latest ooo:xxx
查看:docker images

容器常用命令
命令列表
– docker run //運行容器
– docker ps //查看容器列表
– docker stop //關閉容器
– docker start //啓動容器
– docker restart //重啓容器
– docker attach|exec //進入容器
– docker inspect //查看容器底層信息
– docker top //查看容器進程列表
– docker rm //刪除容器
docker inspect -f {{. NetworkSettings.IPAddress.}}找到需要查找的東西屬於哪一級以點區分 最上層的{是第一個點然後往下匹配 +容器ID 可以寫腳本時使用
批量刪除容器: docker rm $(docker ps -qa)
批量關閉容器:docker stop $(docker ps -q)
把系統裏所有關閉的和沒有關閉的容器通通刪掉:

  1. docker rm $(docker stop $(docker ps -aq))
    2.for i in $(docker ps -qa); do docker stop ${i}; docker rm ${i}; done
    rpm:就是redhat包管理!(RHEL,CentOs,fedora,)yum rpm
    deb:是debian的包 (debina,ubuntu) apt-get dpkg
    redhat debina
    #------------------------------------------#
    RHEL,CentOS debina
    fedora ubuntu
    安裝 yum apt-get
    管理 rpm dpkg
    #------------------------------------------#
    補充兩個命令:dpkg apt-get
    dpkg 和 rpm 相似
    dpkg -l = rpm -qa
    dpkg -S /usr/bin/lsns = rpm -qf /usr/bin/lsns
    dpkg -L util-linux = rpm -ql util-linux
    紅帽裝包: yum install httpd
    debina裝包:apt-get install apache2

docker exec -it f387376c4c57 //容器ID /bin/bash
ctrl +z 進程終止放入後臺 bg
exec:在容器裏執行一個命令,如果這個命令是交互式的,就分給我一個交互終端,如果不是交互式的,執行完就推出了!
f387376c4c57:容器id
docker attach f38 不能exit退出,不能ctrl+c 中斷 只能ctrl p q放入後臺退出
如果是進程是交互的,就進去了,但是如果是後臺服務,它就卡在那了。這就是attach.
還有一個缺點,如果進入容器了,exit退出時,它會把這個pid爲1的進程幹掉,pid爲1的是上帝進程,相當於所有進程都幹掉了 。
如果用attach進入容器,但不想容器結束,可以放在後臺的方法:Ctrl +p +q
docker top 容器ID 查看容器裏運行的命令
在容器裏修改nginx 默認首頁:
查找首頁文件:
第一種方法:
dpkg -l | grep nginx
dpkg -L nginx
第二種方法:
nginx -h
nginx -t (判斷配置文件的語法是否正確)
nginx -T (也是判斷配置文件是否正確,但是會把配置文件輸出的屏幕上)
nginx -T | grep root
cat /etc/nginx/nginx.conf
cd /etc/nginx/conf.d/
ls
grep root default.conf
修改首頁:
vi /usr/share/nginx/html/index.html

自定義鏡像
docker 的核心應用是打包應用環境(封裝應用的和程序交互的核心技術!)
docker commit d4b3f9d74b9b myos:latesst
commit :意思是把一個容器保存成一個鏡像

Nginx redis httpd tomcat

鏡像 鏡像 鏡像 鏡像

      docker                 

       OS

Dockerfile
• Dockerfile語法格式
– FROM:基礎鏡像
– MAINTAINER:鏡像創建者信息
– EXPOSE:開放的端口
– ENV:設置變量
– ADD:複製文件到鏡像
– RUN:製作鏡像時執行的命令,可以有多個
– WORKDIR:定義容器默認工作目錄
– CMD:容器啓動時執行的命令,僅可以有一條CMD
Dockerfile 文件案例:第一個字母必須大寫
Dockerfile 01
FROM centos:latest
#FROM 表示從centos的鏡像修改
RUN rm -f /etc/yum.repos.d/
#RUN 表示在容器裏運行一個命令
ADD local.repo /etc/yum.repos.d/local.repo
#ADD 表示把本地文件添加到容器裏去
RUN yum install -y net-tools psmisc vim
Dockerfile 02
FROM myos:latest
CMD ["/usr/bin/python"]
#CMD 修改默認啓用命令 有專門的格式,列表格式
Dockerfile 03
FROM myos
RUN yum install -y httpd
WORKDIR /var/www/html
#WORKDIR 表示永久的進入此目錄中
RUN echo "hello nsd1804" >index.html
ENV EnvironmentFile=/etc/sysconfig/httpd
EXPOSE 80
#EXPOSE 監聽端口80
CMD ["/usr/sbin/httpd", "-DFOREGROUND"]
創建Dockerfile
mkdir oo
cd oo
cp /etc/yum.repos.d/cloud.repo . 當前目錄 .. 父目錄
touch Dockerfile (D必須是大寫)
vim Dockerfile
FROM centos:latest
RUN rm -f /etc/yum.repos.d/

ADD local.repo /etc/yum.repos.d/local.repo local.repo必須在當前目錄下
RUN yum install -y net-tools psmisc vim

創建鏡像:
docker build -t myos:test .
封裝ssh應用:
FROM myos
RUN yum -y install openssh-server
RUN echo 11 | passwd --stdin root
RUN sshd-keygen
ENV EnvironmentFile=/etc/sysconfig/sshd
CMD ["/usr/sbin/sshd", "-D"]
sshd-keygen 給服務創建的公私鑰 在etc/ssh/
自定義鏡像倉庫
registry基本概念
• 共享鏡像的一臺服務器(鏡像化的一臺服務器)

編輯成鏡像的方法有兩種:
Dockerfile
commit
自定義私有倉庫
• 流程:
– docker pull registry
– vim /etc/docker/daemon.json
{
"insecure-registries" : ["192.168.1.10:5000"]
}
– docker run -d -p 5000:5000 registry
– docker tag 鏡像 IP:5000/鏡像:label
– docker push IP:5000/鏡像:label
• 進入registry容器查看/etc/docker/registry/config.yml
創建私有倉庫:
1.cd /etc/docker/
2.vim daemon.json
{
"insecure-registries": ["192.168.1.11:5000"]}
3.systemctl restart docker.service

4.docker push 192.168.1.11:5000/busybox:latest
for i in latest python sshd httpd; do docker tag myos:${i} 192.168.1.11:5000/myos:${i}; docker push 192.168.1.11:5000/myos:${i}; done
報錯:
Get https://192.168.1.11:5000/v1/_ping: http: server gave HTTP response to HTTPS client
就是配置文件寫錯了! 或者沒有重啓服務!
驗證:在192.168.1.12服務器上驗證
1.vim /etc/docker/daemon.json
{
"insecure-registries": ["192.168.1.11:5000"]}

2.systemctl restart docker.service
3.docker images
4.docker run -it 192.168.1.11:5000/myos:latest
擴展小知識:如何知道私有倉庫裏有什摩鏡像?
使用API進行查看
curl http://192.168.1.11:5000/v2/_catalog
查看標籤
curl http://192.168.1.11:5000/v2/busybox/tags/list
小問題;容器的數據存到哪裏了?
虛擬機的數據存到虛擬硬盤文件裏了
Docker 存儲卷的映射
存儲卷
卷的概念
• docker容器不保持任何數據
• 重要數據請使用外部卷存儲(數據持久化)
• 容器可以掛載真實機目錄或共享存儲爲卷

主機卷的映射
• 將真實機目錄掛載到容器中提供持久化存儲
[root@jacob ~]# docker run -v /data:/data -it centos bash
-v 前面是真機的目錄,再後面是容器內的目錄
我在一臺機器上讓多個容器共享一份數據,而且增刪該查還是實時的,所有容器看見這個文件夾都是共享的!
比如:這個web服務器的數據經常變化,web服務器的配置也經常變化,我再啓動web服務的配置的時候,我就可以把一個配置在我本地文件夾,我直接映射覆蓋掉容器裏的web服務的配置,這樣的話一啓動,就相當於我配置好的apache和nginx!
Web的網頁怎麼辦呢?
可以在物理機上創建一個文件夾,在容器啓動的時候,直接把這個數據也映射進去,-v這個參數可以映射好多次!
在一個機房裏,局域網裏,我怎麼在多個容器裏共享數據?
在一臺服務器上做NFS,其它主機可以mount,NFS到本機的文件夾上,然後再可以映射到容器裏的內部文件夾,只要NFS裏的文夾一更改,整個機房的內容就都更改了。
共享存儲
共享存儲基本概念
• 一臺共享存儲服務器可以提供給所有Docker主機使用
• 共享存儲服務器(NAS、SAN、DAS等)
• 如:
– 使用NFS創建共享存儲服務器
– 客戶端掛載NFS共享,並最終映射到容器中
使用共享存儲的案例
服務器
– yum -y install nfs-utils
– vim /etc/exports
– systemctl start nfs
Docker主機1
192.168.xx.xx
• Docker主機
– mount掛載共享
– 運行容器時,使用-v選項映射磁盤到容器中

在192.168.1.13服務器上做NFS共享:
1.yum -y install nfs-utils
2.mkdir /var/webroot (把這個文件夾映射出去)
3.vim /etc/exports
/var/webroot *(rw,root_squash)
#默認的NFS是guest的用戶,所以要添加root_squash
4.systemctl restart nfs

5.exportfs -avr
6.showmount -e 192.168.1.13
7.chmod 777 /var/webroot/

在192.168.1.11服務器上:
1.yum install -y nfs-utils
2.mount -t nfs 192.168.1.13:/var/webroot /mnt
3.df -h
4.showmount -e 192.168.1.13
5.rpcinfo 192.168.1.13
6.docker run -itd -v /mnt:/var/www/html 192.168.1.11:5000/myos:httpd (#改容器裏的默認首頁)
7.docker run -itd -v /mnt:/var/www/html 192.168.1.11:5000/myos:httpd
8.docker inspect 722 (查看容器ip)
9.curl -i http://172.17.0.3
mount -l | grep mnt
在 192.168.1.12服務器上:
1.yum install -y nfs-utils
2.mount -t nfs 192.168.1.13:/var/webroot /mnt
3.docker exec -it 014 /bin/bash
cd /var/www/html
echo haha > index.html
在192.168.1.11 服務器上:
1.curl -i http://172.17.0.3

Docker網絡架構(很重要)
Linux網橋(很重要)
#就是虛擬交換機
創建虛擬網卡
• 真實網卡配置文件
– cat /etc/sysconfig/network-scripts/ifcfg-eth0
• 虛擬網卡配置文件
– cat /etc/sysconfig/network-scripts/ifcfg-eth0:0
[root@jacob ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0:0
TYPE=Ethernet
BOOTPROTO=static
... ...
NAME=eth0:0
DEVICE=eth0:0
ONBOOT=yes
IPADDR=192.168.1.10

最終怎麼把docker容器發佈到局域網裏去!
!!!創建虛擬網卡:
1.cd /etc/sysconfig/network-scripts/
2.cp ifcfg-eth0 ifcfg-eth0:1
3.vim ifcfg-eth0:1

Generated by dracut initrd

DEVICE="eth0:1"
ONBOOT="yes"
NM_CONTROLLED="no"
TYPE="Ethernet"

BOOTPROTO="static"
IPADDR="192.168.1.20"
PREFIX="24"
#GATEWAY="192.168.1.254" (只能有一個網關)
如果是DHCP只把名改一下就行DEVICE="eth0:1"
4.systemctl restart network

創建虛擬網橋(就是虛擬交換機)
有兩種方式創建虛擬交換機:
第一種:手動創建(不推薦)
第二種:使用docker
[root@jacob ~]# cat /etc/sysconfig/network-scripts/ifcfg-br0
TYPE=Bridge
BOOTPROTO=static
... ...
NAME=br0
DEVICE=br0
ONBOOT=yes
IPADDR=192.168.1.10
[root@jacob ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0
TYPE=Ethernet
BOOTPROTO=static
... ...
NAME=eth0
DEVICE=eth0
BRIDGE=br0
ONBOOT=yes
IPADDR=192.168.1.10
[root@jacob ~]# ~]# brctl show
手動創建虛擬交換機:

1.cd /etc/sysconfig/network-scripts/
2.cp ifcfg-eth0 ifcfg-br
3.vim ifcfg-br

Generated by dracut initrd

DEVICE="br"
ONBOOT="yes"
NM_CONTROLLED="no"
TYPE="Bridge"

BOOTPROTO="static"
IPADDR="192.168.1.20"
PREFIX="24"
#GATEWAY="192.168.1.254"
4.yum -y install bridge-utils
5.systemctl restart network
6.brctl show #查看虛擬交換機
Docker網絡拓撲
Docker查看網絡模式
docker network list
docker支持3種網絡模式
bridge:橋接
host:僅主機
none:無網絡
Docker 創建交換機
docker network
docker network create --help
docker network create --subnet 192.168.100.0/24 docker1
--subnet value :設置一個子網
docker network ls #查看
docker run -it --network docker1 myos
#使用 docker1 的虛擬交換機
Ifconfig
192.168.100.2
ping 172.17.0.1 #127.17.0.1是交換機(拼交換機是通的,但是下面的子網是不通的,做的是子網隔離)
交換機和交換機是隔離的,想通的話,弄在一個交換機上,不想通的話,弄兩個交換機!
a和b交換機在一個子網上,他倆能通 ,c和d交換機在一個子網上,他倆能通。a和c不通!
想和哪個機器通,你就和那個機器插在同一交換機上! 網絡隔離的套路就是(交換機)
兩種方式創建網橋:
新建Docker網絡模型
docker network create --driver bridge test01
查看默認Docker創建的網絡模型
docker network create --subnet=172.30.0.0/16 test01
端口複用(核心)docker (快速的轉移切換 打包應用環境)
客戶端訪問容器內的資源
• 默認容器通過SNAT可以訪問外網
• 但外部網絡的主機不可以訪問容器內的資源
• 端口映射
– 使用端口映射可以實現外部網絡訪問容器內的資源(複用物理機的端口)
[root@jacob ~]# docker run -p 8080 80 -id nginx
//如:真實機IP爲192.168.1.10,
使用-p映射真實機的8080端口到容器中的80端口
[root@client ~]# firefox http://192.168.1.10

複用命令:創建容器,使用宿主機的端口 -p 宿主機端口:容器端口
docker run -d -v /var/data:/var/www/html -p 80:80 192.168.1.11:5000/myos:httpd
-p:把物理機的80端口,複用成容器的80端口!
cd /var/data
curl http://www.sohu.com/ -o index.html
如果虛擬機有很多需要管理就使用openstack
如果Docker有很多容器機器要管理就用K8S
1.K8s 1.openstack
2.docker 2.libvirt
3.Cgroup,namespace,selinux 3.kvm,qemu

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章