docker+k8s基礎篇一

Docker+K8s基礎篇(一)


  • docker的介紹
    • A:爲何是docker
    • B:k8s介紹
  • docker的使用
    • A:docker的安裝
    • B:docker的經常使用命令
    • C:docker容器的啓動和操做
  • docker鏡像的基礎管理
    • A:docker鏡像的基礎概念
    • B:docker鏡像的生成途徑
    • C:鏡像的導入和導出
  • 容器的虛擬化網絡
    • A:容器虛擬化網絡基礎
    • B:docker的網絡形式
    • C:docker網絡的相關操做
  • docker的存儲卷
    • A:docker的存儲卷介紹
    • B:docker的網絡形式
    • C:docker網絡的相關操做
  • dockerfile詳解
    • A:dockerfile基礎
    • B:dockerfile的語法格式
    • C:dockerfile的指令詳解
  • docker的私有registy
    • A:docker的私有registy介紹
    • B:docker的私有registy安裝和簡單使用
    • C:Harbor安裝和簡單使用
  • portainer的安裝和使用php

    • A:portainer的安裝 

♣一:docker的介紹

A:爲何是docker

隨着互聯網的用戶基數變大,可用於快速調配的系統資源環境變得尤其重要,在早些年,互聯網公司都基於虛擬化技術來完成生產及開發環境的快速搭建,隨着互聯網的發展愈來愈快,虛擬化的技術已經不能很好知足需求。
主機級虛擬化的兩種形類型:
1:直接在硬件上安裝虛擬化軟件,再在上面安裝操做系統。
2:在宿主機之上安裝虛擬化軟件進行虛擬化,虛擬機和宿主機操做系統能夠徹底不同。例如:VMware
這些傳統的虛擬化技術最根本的本質就是要安裝一個操做系統的內核,內核提供了用戶空間,再在用戶空間裏面跑進程,這些進程就須要單獨去安裝,例如tomcat等,底層的內核只是提供的資源的分派和調度。
這種形態下的虛擬化環境雖然能知足咱們的要求,可是不夠便捷,若是是想單純跑一個web服務,咱們須要安裝操做系統,安裝web服務,而後配置才能提供服務,若是是新環境,你還得考慮版本兼容性等問題,是否是要裝新版的web服務等。並且是類型2虛擬化的,在尚未提供web服務的以前,已經完成了兩級的調度和資源分派,第一層的宿主機和第二層的虛擬機,在這其中的資源浪費也是不言而喻的。
既然基礎層面上的繁瑣和資源消耗,那麼從原理上來講最方便的就是去掉一層內核,可是去掉內核就會用戶空間就成了問題,由於用戶空間是爲了跑真正提供服務的進程所存在的,例如我要100臺nginx服務器都監聽8080端口,那麼就須要100臺虛擬機,一臺虛擬機上是不能同時監聽兩個nginx的8080端口的,100臺虛擬機的主要目的就是環境隔離,環境隔離了,即便其中50臺nginx機器出了問題,那麼我刪掉虛擬機就行了,不會影響我宿主機。
內核空間又內核提供,服務進程由用戶空間提供,n臺虛擬機所須要實現的實際上是用戶空間的隔離,咱們須要解決的第一個難點就是在一個內核空間之上開盤N個相互隔離的用戶空間,讓服務進程之間不會相互影響。這些相互隔離的用戶空間就像一個大盒子裏面裝的小盒子同樣,這種技術就叫容器技術。html

容器技術最先是出如今FreeBSD上,叫jail,其主要的目的就是把進程之間相互隔離,而且限制這些散列的容器所消耗的資源獲得控制。前端

進程相互隔離是作到了,可是底層的資源是有限的,當出現某一個進程佔用資源已經到達容器的邊界,是否是就由於內存溢出等問題而讓服務掛掉了,顯然是不合理的,此時就須要作到動態的分配資源纔是最可取的。
資源完成動態分配以後,那內存資源原本就是整個內存上劃分的內存塊,若是是進程之間能經過ipc相互通訊且能相互讀取內存中的信息,也是不合理的。
經過上面咱們得知docker要完成的莫非就是自動化隔離,
在3.8版本內核上才完成了主機名和域名(UTS)的隔離,IPC,mount(掛載樹)和PID(進程樹)程序須要運行須要進程樹和文件樹,用戶和組,網絡這6大塊隔離技術(nameespaces名稱空間)再加上chroot技術完成了容器的基本功能。java

                             

能夠看到這些技術提及來簡單,可是實現起來卻很難,能夠看到上圖中用戶和組的隔離功能一致到3.8的內核版本才徹底支持。node

容器技術的最核心的隔離功能完成以後,還須要實現一個機制,那就是要實現相似咱們VMware能夠指定資源的總量是多少,例如宿主機有16G內存,可是一個容器只能我只給分派4G內存,不能出現一個容器因把內存泄露吃幹抹淨剩餘內存致使其它的容器沒法正常運行,由於內存是不可壓縮的,用完就沒有了,相反cpu是有壓縮機制的,服務申請cpu運算,若是cpu佔用太高,此時服務的請求就得排隊。
因此咱們須要實現彈性的資源調配,我分給容器4G,這4G就是最大的值,當出現一個容器內部一個比較消耗內存的服務,那麼就把容器中一個不經常使用的服務給kill掉,把空間讓出來給這個服務使用,這個機制在linux已經實現,叫cgroups,他將多個系統資源劃分紅一個組,在將這個組裏面的內容分配到每個用戶空間裏面的進程上去。python

                              

雖然容器技術去掉了不少主機級虛擬化的弊端,可是容器技術也會存在問題,由於咱們畢竟在一個內核之上分出來的一個個容器,可是這種隔離技術必然會出現漏洞,當一旦有漏洞,服務就可能繞過這個邊界去剝奪其餘容器的資源,從而產生問題,一致到如今也沒有徹底好的解決辦法,爲了防止這種狀況出現,通常用戶會開啓selinux等安全功能來對這些容器進行加固。mysql

上面咱們說簡要的說了下容器技術須要完成的功能,可是使用容器技術的工具倒是極爲不方便,你須要安裝不一樣的工具甚至還要編寫代碼來完成容器的使用,既然如此,這種技術就被人給開發出來了,就叫作LXC(linuX Container),LXC極大的簡化了容器的操做難度,linux

例如咱們能夠使用lxc-create來快速的建立一個容器,可是lxc-create是怎麼來完成快速建立的了,lxc-create是快速建立了一個模板,而且給這個模板執行權限,這個模板就會去一個指定好的倉庫裏面把鏡像拉下來並chroot進去,完成文件和服務的安裝,建立用戶等,這樣過程其實和咱們手動建立一個虛擬機是相似的。nginx

lxc雖然簡化了咱們使用容器技術的操做,可是依舊有很高的門檻,例如我想快速建立不通性質的容器怎麼辦,我想大批量的進行容器的遷移怎麼辦,容器出現故障銷燬了,裏面存的數據和文件怎麼辦,lxc在面臨分發和大規模使用上依然沒有找到很好的突破口,因此後面就出現了docker,從這個性質上來docker只不過是lxc的加強版,彌補了lxc存在的功能缺陷,docker也不是什麼容器技術,只不過是方便咱們使用容器技術的前段工具罷了,容器技術自己就是又內核去完成的,docker只不過站在了lxc的肩膀上。可是docker逐漸壯大以後就拋棄了lxc,換上自家研發的libcontainergit

既然咱們想實現容器技術的大規模使用會很難,哪怕是簡單的復刻一個如出一轍的容器,docker就開始在這些方面找解決辦法,docker在起初就是吧lxc從新封裝做爲容器管理技術的引擎,lxc在快速部署容器的時候使用的模板工具不夠完善,docker發現以後,就開始把模板的思路擴展,研究出來一種鏡像的工具,在鏡像裏面咱們按照一個程序須要部署的全部步驟事先編排好,再把這個編排好的文件製做成一個鏡像文件,最後把這些鏡像統一放到一個便於管理的倉庫中,當用戶執行lxc命令的時候,不是去調用模板,而是去連到鏡像倉庫去下載一個匹配你當前須要的鏡像文件,而後基於鏡像啓動容器

這樣的方式就會極大的簡化用戶的操做,例如我想運行一個nginx,直接docker run nginx,這一條命令直接出發鏈接,下載,配置,啓動等一系列操做,以前的lxc是建立了一個用戶空間,一個用戶空間能夠運行不少程序,可是docker不同,它完成的是一個容器運行一個程序。docker的這種邏輯給開發帶來了極大的便利,如今的開發環境都是異構的,要知足不一樣的平臺,centos,suse,windows等,對於docker來講我能夠快速搭建相應的平臺和服務用於開發中的調試,無論是基於java,python仍是基於tomcat仍是nginx,只要能事先編排好打包成鏡像,直接docker run就能夠了。可是對運維來講是極爲不便利,以前我一個用戶空間跑多個服務,能夠共享某一個文件或者腳本,可是如今每個程序都是單獨跑在單獨的容器之中,意味這文件是不能共享的,這樣會形成磁盤空間的浪費,其次之前我若是查看全部服務是否正常,直接ps等命令就能看,可是現有的狀況下會變得很麻煩,我得進入每個容器中去查看,意味着每個容器裏面都須要安裝相應的工具,更甚者,以前我能經過linux系統命令來調試的工具,結果到容器裏面根本就沒有調試工具。
docker還有另外的一個功能,隨着docker的不斷髮展和功能完善,有些狀況下就想實現底層我基於centos的一個固定版本,可是上層我想跑不通的服務,基於這種想法,docker開發了分層管理的功能,我單首創建一個centos,在上面安裝nginx,tomcat等服務,而後分別打包成鏡像,之後我想底層公用一個操做系統centos,上面我跑不一樣的服務,這樣的形式叫作聯合掛載技術,這每個服務都被當作一個只讀文件被運行,這樣的形式能帶來好處,也會帶來資源的消耗,並且最重要的就是這每一個只讀文件所產生的數據怎麼辦,若是是遷移容器的話,服務不是難點,難的是數據,因此你要使用容器技術,就要實現考慮到長期保存的數據必須採用共享存儲系統,這樣你想遷移或者銷燬服務,沒有問題,數據還在就行,再把鏡像下載下來,和數據池掛載上,就能運行。

docker後來也製做的容器運行時的標準runC,也製做了鏡像文件標準,叫ocf開放容器格式標準。後來在linux基金會也創立了一個oci的標準,圍繞容器格式和運行時知道一個開放的工業化標準。

B:K8S介紹

docker能幫咱們便捷的管理容器了,可是咱們的生產場景是複雜的,生產環境中咱們啓動程序是存在關聯關係的,下游程序的啓動必須依賴上游程序的啓動,這樣的操做咱們不能是將容器建立好以後再去操做,咱們應該是事先按照必定的順序和邏輯將其編排好。
隨着docker的編排愈加變的重要以後,市面上也出現了大量的容器編排工具。
docker本身開發的工具:machine+swarm+compose,docker將這三個工具組合使用造成本身的編排工具;
asf研發的數據中心操做系統有一個統一資源編排工具mesos,mesos不是用來編排容器的,是用來實現統一資源調度的,要想編排工具就須要加一箇中間層marathon;
kubernetes:k8s,基於go語言開發,k8s支持不少容器技術,docker只是其中一種。

♣二:docker的使用

A:docker的安裝和啓動

docker是使用鏡像來完成容器內容的建立的,在互聯網上,dockerhub.com是全球最大的鏡像倉庫網站,他提供了大多數的鏡像文件,除了docker提供的鏡像倉庫網站,阿里,等都有鏡像倉庫網站,除了網路源,你還能夠搭建本身的私有鏡像倉庫。

docker要想完美的運行,須要內核版本在3.10以上,64位的操做系統,centos6的版本也能支持,可是由於紅帽公司將支持docker的補丁也挪到了6的版本上,可是穩定性就沒有7的版本,至少從某些層面來講。

docker的安裝文件在cenos7上直接yum就能夠安裝,包文件在extras裏面,自帶鏡像裏面的docker比較老,咱們在網絡上找一些共用的鏡像或者yum文件下載到本地使用。

能夠參考網站清華大寫鏡像網站信息:清華大學開源鏡像網站

[root@localhost yum.repos.d]# wget https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo
下載清華源repo文件到本地的環境中
[root@localhost yum.repos.d]# cat docker-ce.repo
[docker-ce-stable]
name=Docker CE Stable - $basearch
baseurl=https://download.docker.com/linux/centos/7/$basearch/stable
enabled=1
gpgcheck=1
gpgkey=https://download.docker.com/linux/centos/gpg
可是咱們發現雖然是清華的源,可是地址仍是指向的docker的官網,由於docker的網站訪問太慢,咱們改到清華源的地址
https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/7/x86_64/stable/Packages/
把這個地址從linux的位置複製出來替換下docker-ce.repo文件的地址裏面去
:%s@https://download.docker.com/@https://mirrors.tuna.tsinghua.edu.cn/docker-ce/@
vim的批量替換
yum repolist
源標識                                                        源名稱                                                          狀態
base/7/x86_64                                                 CentOS-7 - Base                                                 10,019
docker-ce-stable/x86_64                                       Docker CE Stable - x86_64                                           36
extras/7/x86_64                                               CentOS-7 - Extras                                                  371
updates/7/x86_64                                              CentOS-7 - Updates                                               1,163
repolist: 11,589
[root@localhost yum.repos.d]#能夠看到Docker CE Stable - x86_64的包
安裝
[root@localhost yum.repos.d]# yum -y install docker-ce   ce和ee是docker的社區版和企業版
docker安裝成功
docker的安裝
[root@localhost docker]# cat daemon.json
{
    "registry-mirrors":["https://registry.docker-cn.com"]
}
[root@localhost docker]# systemctl start docker.service
[root@localhost docker]# ps -aux | grep docker
root      18867  0.1  3.2 781688 61256 ?        Ssl  20:34   0:06 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
root      20119  0.0  0.0 112724   988 pts/1    S+   21:52   0:00 grep --color=auto docker

[root@localhost ~]# docker version 能夠經過version查看客戶端和服務器端的版本
Client:
 Version:           18.09.3
 API version:       1.39
 Go version:        go1.10.8
 Git commit:        774a1f4
 Built:             Thu Feb 28 06:33:21 2019
 OS/Arch:           linux/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          18.09.3
  API version:      1.39 (minimum version 1.12)
  Go version:       go1.10.8
  Git commit:       774a1f4
  Built:            Thu Feb 28 06:02:24 2019
  OS/Arch:          linux/amd64
  Experimental:     false
[root@localhost ~]# docker info  還能夠經過info查看更加詳細的信息
Containers: 0    容器的個數
 Running: 0       運行中容器的個數
 Paused: 0         暫停的容器個數
 Stopped: 0        以中止的容器的個數
Images: 0    
Server Version: 18.09.3    
Storage Driver: overlay2   存儲後端引擎,這個很重要,docker早期的版本上是不支持這個存儲格式的,那時候主流的centos版本仍是6,docker仍是使用的dm格式,也就是基於lvm(邏輯卷)的形式,這種格式性能不好,還不是很穩定,在後續的docker版本上就換成了這種格式,centos直到7上才徹底兼容overlay2的格式,因此說想很好的使用docker仍是須要用到centos7版本
 Backing Filesystem: xfs  備份的文件系統
 Supports d_type: true
 Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:     支持的插件
 Volume: local
 Network: bridge host macvlan null overlay
 Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: e6b3f5632f50dbc4e9cb6288d911bf4f5e95b18e
runc version: 6635b4f0c6af3810594d2770f662f34ddc15b40d
init version: fec3683
Security Options:
 seccomp
  Profile: default
Kernel Version: 3.10.0-957.el7.x86_64
Operating System: CentOS Linux 7 (Core)
OSType: linux
Architecture: x86_64
CPUs: 4
Total Memory: 1.777GiB
Name: localhost.localdomain
ID: BXLI:3OWV:CIBE:BYC2:77XQ:ZJ3Y:736U:Y7M5:FXEW:ONYQ:M6S7:OKWI
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
 127.0.0.0/8
Registry Mirrors:
 https://registry.docker-cn.com/   加速的地址
Live Restore Enabled: false
Product License: Community Engine
docker的啓動

Storage Driver: overlay2參考https://blog.csdn.net/vchy_zhao/article/details/70238690

B:docker的經常使用命令

docker search:根據指定的關鍵字搜索鏡像

[root@localhost ~]# docker search nginx
NAME                                                   DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
nginx    沒有增長/斜槓的表明頂級鏡像,通常是docker官方提供的                                              Official build of Nginx.                        11053               [OK]
jwilder/nginx-proxy    這種加了斜槓的斜槓前面是註冊者的帳戶名,這種鏡像通常叫作用戶鏡像                                Automated Nginx reverse proxy for docker con…   1556                                    [OK]
richarvey/nginx-php-fpm                                Container running Nginx + PHP-FPM capable of…   688                                     [OK]
jrcs/letsencrypt-nginx-proxy-companion                 LetsEncrypt container to use with nginx as p…   492                                     [OK]
kitematic/hello-world-nginx                            A light-weight nginx container that demonstr…   123
webdevops/php-nginx                                    Nginx with PHP-FPM                              123                                     [OK]
zabbix/zabbix-web-nginx-mysql                          Zabbix frontend based on Nginx web-server wi…   91                                      [OK]
bitnami/nginx                                          Bitnami nginx Docker Image                      64                                      [OK]
linuxserver/nginx                                      An Nginx container, brought to you by LinuxS…   56
1and1internet/ubuntu-16-nginx-php-phpmyadmin-mysql-5   ubuntu-16-nginx-php-phpmyadmin-mysql-5          49                                      [OK]
tobi312/rpi-nginx                                      NGINX on Raspberry Pi / armhf                   24                                      [OK]
nginx/nginx-ingress                                    NGINX Ingress Controller for Kubernetes         17
wodby/drupal-nginx                                     Nginx for Drupal container image                12                                      [OK]
nginxdemos/hello                                       NGINX webserver that serves a simple page co…   12                                      [OK]
blacklabelops/nginx                                    Dockerized Nginx Reverse Proxy Server.          12                                      [OK]
schmunk42/nginx-redirect                               A very simple container to redirect HTTP tra…   11                                      [OK]
centos/nginx-18-centos7                                Platform for running nginx 1.8 or building n…   10
centos/nginx-112-centos7                               Platform for running nginx 1.12 or building …   7
nginxinc/nginx-unprivileged                            Unprivileged NGINX Dockerfiles                  4
1science/nginx                                         Nginx Docker images that include Consul Temp…   4                                       [OK]
mailu/nginx                                            Mailu nginx frontend                            3                                       [OK]
travix/nginx                                           NGinx reverse proxy                             2                                       [OK]
toccoag/openshift-nginx                                Nginx reverse proxy for Nice running on same…   1                                       [OK]
wodby/nginx                                            Generic nginx                                   0                                       [OK]
ansibleplaybookbundle/nginx-apb                        An APB to deploy NGINX                          0                                       [OK]
[root@localhost ~]#
docker search

docker pull:將鏡像拉到本地

在dockerhub官網上每個鏡像都有一個alpine的版本,能夠看到這個版本所佔的空間很是小,若是是用於開發調試能夠使用這個版本,由於體積小下載速度快,可是缺點就是沒有相應的操做工具,若是是下載功能全的版本,佔用空間也大也消耗帶寬,因此最好的辦法就是本身製做私有的鏡像倉庫

[root@localhost ~]# docker image pull nginx:1.14-alpine   pull的時候指定版本信息,不肯定的話能夠上網站查一下
1.14-alpine: Pulling from library/nginx
6c40cc604d8e: Pull complete
76679ad9f124: Pull complete
389a52582f93: Pull complete
496e2dd2b91a: Pull complete
Digest: sha256:b96aeeb1687703c49096f4969358d44f8520b671da94848309a3ba5be5b4c632
Status: Downloaded newer image for nginx:1.14-alpine

[root@localhost ~]# docker images  能夠看到本地已經與鏡像了
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               1.14-alpine         66952fd0a8ef        5 weeks ago         16MB
[root@localhost ~]#
pull nginx
經過另一種命令下載linux上的工具包。
[root@localhost ~]# docker pull busybox
Using default tag: latest
latest: Pulling from library/busybox
697743189b6d: Pull complete
Digest: sha256:061ca9704a714ee3e8b80523ec720c64f6209ad3f97c0ff7cb9ec7d19f15149f
Status: Downloaded newer image for busybox:latest
[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
busybox             latest              d8233ab899d4        3 weeks ago         1.2MB
nginx               1.14-alpine         66952fd0a8ef        5 weeks ago         16MB
[root@localhost ~]#
早期的docker是沒有加image來執行的
docker pull busybox

docker images:列出本地全部鏡像

[root@localhost ~]# docker image

Usage:  docker image COMMAND

Manage images

Commands:
  build       Build an image from a Dockerfile
  history     Show the history of an image
  import      Import the contents from a tarball to create a filesystem image
  inspect     Display detailed information on one or more images
  load        Load an image from a tar archive or STDIN
  ls          List images  查看
  prune       Remove unused images
  pull        Pull an image or a repository from a registry  拉鏡像到本地
  push        Push an image or a repository to a registry
  rm          Remove one or more images
  save        Save one or more images to a tar archive (streamed to STDOUT by default)
  tag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE

Run 'docker image COMMAND --help' for more information on a command.
[root@localhost ~]#
dokcer image可接參數

image後面能夠接的參數都是新版本的docker提供的,主要是提供了分層。

新的版本也保留了老版本的命令,docker --help能查看到老版本和新版本的命令

docker image rm(新)或者老docer rmi :刪除鏡像

[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
busybox             latest              d8233ab899d4        3 weeks ago         1.2MB
nginx               1.14-alpine         66952fd0a8ef        5 weeks ago         16MB
[root@localhost ~]# docker image rm  busybox
Untagged: busybox:latest
Untagged: busybox@sha256:061ca9704a714ee3e8b80523ec720c64f6209ad3f97c0ff7cb9ec7d19f15149f
Deleted: sha256:d8233ab899d419c58cf3634c0df54ff5d8acc28f8173f09c21df4a07229e1205
Deleted: sha256:adab5d09ba79ecf30d3a5af58394b23a447eda7ffffe16c500ddc5ccb4c0222f
[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               1.14-alpine         66952fd0a8ef        5 weeks ago         16MB
[root@localhost ~]#
docker image rm
[root@localhost ~]# docker image ls
REPOSITORY          TAG  (標籤)              IMAGE ID(容器id)            CREATED (時間)            SIZE(大小)
nginx               1.14-alpine         66952fd0a8ef        5 weeks ago         16MB
[root@localhost ~]# docker image ls --no-trunc
REPOSITORY          TAG                 IMAGE ID                                                                  CREATED             SIZE
nginx               1.14-alpine         sha256:66952fd0a8efa0598626fad89d3a0827bc24fc92c3adb576adbc9fd58606e1af   5 weeks ago         16MB
[root@localhost ~]#
能夠看到IMAGE ID(容器id)就以完整的形式展示出來了,默認只顯示前面一段的
docker image ls --no-trunc(查看容器信息)

docker container run 建立容器以後直接啓動
docker container start 啓動容器
docker container stop 中止容器
docker container kill 強行中止容器

[root@localhost ~]# docker container --help

Usage:  docker container COMMAND

Manage containers

Commands:
  attach      Attach local standard input, output, and error streams to a running container
  commit      Create a new image from a container's changes
  cp          Copy files/folders between a container and the local filesystem
  create      Create a new container
  diff        Inspect changes to files or directories on a container's filesystem
  exec        Run a command in a running container
  export      Export a container's filesystem as a tar archive
  inspect     Display detailed information on one or more containers
  kill        Kill one or more running containers
  logs        Fetch the logs of a container
  ls          List containers
  pause       Pause all processes within one or more containers
  port        List port mappings or a specific mapping for the container
  prune       Remove all stopped containers
  rename      Rename a container
  restart     Restart one or more containers
  rm          Remove one or more containers
  run         Run a command in a new container
  start       Start one or more stopped containers
  stats       Display a live stream of container(s) resource usage statistics
  stop        Stop one or more running containers
  top         Display the running processes of a container
  unpause     Unpause all processes within one or more containers
  update      Update configuration of one or more containers
  wait        Block until one or more containers stop, then print their exit codes

Run 'docker container COMMAND --help' for more information on a command.
[root@localhost ~]#
docker container --help可接參數
[root@localhost ~]# docker container ls
CONTAINER ID(容器啓動的id)        IMAGE (基於那個鏡像啓動的容器)              COMMAND (在容器中運行了什麼命令)            CREATED(建立容器的時間)             STATUS (當前狀態)             PORTS (映射的端口)              NAMES(容器的名稱)
[root@localhost ~]#
docker container ls

docker的網絡,dockr一旦啓動就會建立一個docker0的網絡,並且默認的 172.17.0.1網段,這個網絡默認也是nat的方式,這就意味這它能夠完成地址轉換,轉換成能對外通信的地址。默認也是走在bridge上的。

C:docker容器的啓動和相關操做

[root@localhost ~]# docker run --name(給容器取一個名字) docker01 -it(進入交互式鏡像) busybox:latest(latest是標籤,能夠選擇不加)
Unable to find image 'busybox:latest' locally
latest: Pulling from library/busybox
697743189b6d: Pull complete
Digest: sha256:061ca9704a714ee3e8b80523ec720c64f6209ad3f97c0ff7cb9ec7d19f15149f
Status: Downloaded newer image for busybox:latest
/ #
busybox默認是進入shell終端窗口的
docker run運行第一個容器
在busybox容器裏面啓動httpd服務
在busybox裏面建立html的網頁目錄,編輯網頁信息
而後啓動httpd -f -h /var/www/html/服務
而後另外開一個窗口訪問
[root@localhost ~]# curl 172.17.0.2
hello busybox.server!!
[root@localhost ~]#
能夠看到就能訪問到信息
[root@localhost ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
27bb5e91ac1f        busybox:latest      "sh"                9 minutes ago       Up 9 minutes                            docker001
[root@localhost ~]#
由於當前咱們啓動的進程是屬於sh這個用戶空間裏面的,建立的httpd服務屬於sh這個進程的子進程,他擁有了進程樹和文件樹,全部也就能夠訪問了,如今這個httpd服務只能在本地進行訪問,由於沒有作地址映射。
利用busybox容器啓動httpd服務
docker run --name docker001 -it busybox:latest
咱們如今使用的是run直接啓動,當咱們exit退出以後,容器也就暫停了,默認用docker ps是不顯示的,須要加參數才能看見
[root@localhost ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                       PORTS               NAMES
27bb5e91ac1f        busybox:latest      "sh"                20 minutes ago      Exited (137) 2 minutes ago                       docker001
0a4f4aeee033        busybox:latest      "sh"                3 hours ago         Exited (0) 3 hours ago                           docker02
b4ddc6132f1b        busybox:latest      "sh"                4 hours ago         Exited (1) 4 hours ago                           docker01

[root@localhost ~]# docker start -ai(這兩個參數能夠不加) docker001
/ # ls
bin   dev   etc   home  proc  root  sys   tmp   usr   var
/ #
咱們能夠利用啓動的命令江處於暫停的容器啓動起來
/var/www/html # [root@localhost ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
27bb5e91ac1f        busybox:latest      "sh"                26 minutes ago      Up About a minute                       docker001
[root@localhost ~]#
能夠看到容器又處於up狀態
[root@localhost ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                   PORTS               NAMES
27bb5e91ac1f        busybox:latest      "sh"                30 minutes ago      Up 27 seconds                                docker001
0a4f4aeee033        busybox:latest      "sh"                4 hours ago         Exited (0) 3 hours ago                       docker02
b4ddc6132f1b        busybox:latest      "sh"                4 hours ago         Exited (1) 4 hours ago                       docker01
[root@localhost ~]# docker kill docker001  能夠對處於運行狀態的容器進行強停,若是是沒有必要千萬不要強停容器,可能會形成數據丟失
docker001
[root@localhost ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                       PORTS               NAMES
27bb5e91ac1f        busybox:latest      "sh"                30 minutes ago      Exited (137) 2 seconds ago                       docker001
0a4f4aeee033        busybox:latest      "sh"                4 hours ago         Exited (0) 3 hours ago                           docker02
b4ddc6132f1b        busybox:latest      "sh"                4 hours ago         Exited (1) 4 hours ago                           docker01
[root@localhost ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                       PORTS               NAMES
27bb5e91ac1f        busybox:latest      "sh"                30 minutes ago      Exited (137) 2 seconds ago                       docker001
0a4f4aeee033        busybox:latest      "sh"                4 hours ago         Exited (0) 3 hours ago                           docker02
b4ddc6132f1b        busybox:latest      "sh"                4 hours ago         Exited (1) 4 hours ago                           docker01
[root@localhost ~]# docker rm docker01  使用rm後面接容器名稱刪除容器
docker01
[root@localhost ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                            PORTS               NAMES
27bb5e91ac1f        busybox:latest      "sh"                32 minutes ago      Exited (137) About a minute ago                       docker001
0a4f4aeee033        busybox:latest      "sh"                4 hours ago         Exited (0) 3 hours ago                                docker02
[root@localhost ~]#
docker ps -a(查看容器);docker start(啓動容器);docker kill(強停容器);docker rm(刪除容器)
[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
busybox             latest              d8233ab899d4        3 weeks ago         1.2MB
nginx               1.14-alpine         66952fd0a8ef        5 weeks ago         16MB
[root@localhost ~]# docker run --name nginx001 -d(放到後臺運行,此時nginx不須要和busybox同樣須要交互放後臺便可) nginx:1.14-alpine
04e64051bd39c390dfdc618d4f02ef863cef99210c29e353e5ffc33f3352cbf3
[root@localhost ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
04e64051bd39        nginx:1.14-alpine   "nginx -g 'daemon of…(daemon of表示不要跑在後臺)"   14 seconds ago      Up 12 seconds       80/tcp              nginx001
nginx -g 'daemon of…(daemon of表示不要在容器中運行在後臺)
在docker容器中運行任何程序必定不能讓它跑在容器的後臺,一旦跑在後臺,docker就認爲程序沒有運行,並且你及時手動啓動仍是會立馬終止
[root@localhost ~]# docker inspect nginx001經過inspect 來查看服務運行在哪一個地址上
。。。。。。
"Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.2", 能夠看到運行在172.17.0.2地址上
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
[root@localhost ~]# curl 172.17.0.2 訪問該地址
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@localhost ~]#
docker run運行nginx

咱們是用run的時候,若是本地沒有鏡像,run回去加速鏡像網站去找與之匹配的鏡像,可是你要保證在鏡像加速網站能找到該鏡像。

咱們還能夠經過exec參數繞過容器的邊界到裏面去執行一些命令
[root@localhost ~]# docker exec nginx001 -it /bin/sh
OCI runtime exec failed: exec failed: container_linux.go:344: starting container process caused "exec: \"-it\": executable file not found in $PATH": unknown
[root@localhost ~]# docker exec -it nginx001 /bin/sh
/ # ls
bin    dev    etc    home   lib    media  mnt    opt    proc   root   run    sbin   srv    sys    tmp    usr    var
/ # ps
PID   USER     TIME  COMMAND
    1 root      0:00 nginx: master process nginx -g daemon off;
    6 nginx     0:00 nginx: worker process
   25 root      0:00 /bin/sh
   31 root      0:00 ps
/ # netstat -anptu
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1/nginx: master pro
/ #
能夠看到端口也監聽了

/ # nginx-debug
2019/03/12 13:32:16 [emerg] 34#34: bind() to 0.0.0.0:80 failed (98: Address in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address in use)
2019/03/12 13:32:16 [emerg] 34#34: bind() to 0.0.0.0:80 failed (98: Address in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address in use)
2019/03/12 13:32:16 [emerg] 34#34: bind() to 0.0.0.0:80 failed (98: Address in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address in use)
2019/03/12 13:32:16 [emerg] 34#34: bind() to 0.0.0.0:80 failed (98: Address in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address in use)
2019/03/12 13:32:16 [emerg] 34#34: bind() to 0.0.0.0:80 failed (98: Address in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address in use)
2019/03/12 13:32:16 [emerg] 34#34: still could not bind()
nginx: [emerg] still could not bind()
/ #
咱們還能夠執行nginx相關的命令
docker exec

咱們發現docker在部署啓動服務優點很明顯,可是docker給咱們弄了一個難題就是咱們要改服務的配置文件。

[root@localhost ~]# docker logs nginx001
172.17.0.1 - - [12/Mar/2019:13:17:50 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-"  能夠看到咱們以前訪問nginx服務的信息
[root@localhost ~]#
由於咱們容器裏面就跑了一個進程,能夠使用logs參數直接獲取服務日誌信息,固然這種狀況下查看日誌比較適合調試的過程
docker logs

                                       

在上圖裏面容器的建立方式有兩種,一種是run,建立以後直接啓動,仍是就是create,建立以後不啓動,須要手動啓動,容器一旦啓動起來就處於runing狀態,這個狀態下能夠kill,stop操做,這個時候容器就處於stopped中止狀態,這個狀態下能夠rm刪除,刪除就處於deleted狀態,這個狀態就沒有操做了。圖上還有一個paused暫停狀態。

若是服務超過限制的內存最大值,將會被oom掉,這個時候就處於掛機的狀態,若是你這個時候有重啓的策略,服務將被重啓,沒有的話就會回到中止狀態。

docker的簡單的使用流程就是在這幾個狀態之間來回轉換的,只要知道什麼狀態下該須要作什麼操做,docker的簡單使用就變得簡單了。

♣三:docker鏡像基礎管理

A:docker鏡像的基礎概念

在docker的基礎使用的時候就反覆提到了鏡像,咱們在使用docker host它是由運行在docker裏面的守護進程組成的,也就是docker的server端,接收客戶端的請求是由http或https與後臺交互,並且docker的客戶端能夠是遠程主機。
當docker的server端接收到來自client的請求的時候會在docker host裏面建立或者啓動一個容器,在一個docker host裏面能夠建立和啓動各類不一樣的容器,而容器的啓動或運行是基於鏡像來實現的,當鏡像本地沒有,docker會自動連到網絡例如dockerhub上去獲取鏡像,獲取的鏡像會存儲到本地一個專門用於存儲鏡像的空間裏面,這個存儲空間要求得是特殊的文件系統,這就是咱們以前docker info看到的Storage Driver: overlay2,這些鏡像放在這個存儲空間裏面是隻讀的,而你下載的鏡像(應用程序)也是被下載倉庫名,而一個倉庫裏面能夠容納多個相同服務不一樣版本的鏡像,這些不一樣的版本會經過標籤來區分。

docker鏡像是含有啓動容器所須要的文件系統及其內容,所以鏡像的主要功能是建立並啓動docker容器。
docker另一個概念必需要知道的是分層構建機制,相似於建房子,docker的地基層爲bootfs,在上層則是rootfs,bootfs和linux啓動的是須要加載boot分區同樣,主要用於系統引導的文件系統,也提供了內核,容器啓動完成以後就會被卸載(只是從內存中移除),便於回收資源,bootfs的加載也是爲了引導rootfs而存在的,rootfs就是一個根文件系統,也就是一個用戶空間。
在傳統的centos6等版本在啓動時候,內核掛載rootfs的時候會議只讀模式掛載,以便於完成系統自檢,這種機制是爲了保證系統在自檢的時候因出現錯誤致使誤刪除數據,當系統自檢完成確保沒有問題,再將其從新掛載成讀寫模式。而在docker中,這個rootfs始終都是隻讀的形式掛載的,後面經過(聯合掛載)技術額外掛載一個可寫層。
在docker中rootfs一旦啓動成功即可以在這個基礎之上在去安裝其餘的鏡像,而這個原始底層鏡像是不會變更的,例如咱們安裝了一個最簡化的centos系統,而這個centos是沒有操做工具的,咱們須要安裝vim等一系列操做工具,這個時候你再安裝的vim工具就是基於最底層centos鏡像之上的,這個層你能夠理解爲vim層,只包含vim工具,而後你再安裝tomcat,這個tomcat就是在vim層之上,當你啓動tomcat的時候,須要從下層往上一層層的掛載,直到tomcat層,這個就是聯合掛載,當你須要對層級裏面的文件進行修改的時候,僅能經過整個掛載層最上端的writable(可寫)層來實現,當容器被刪除的時候,這個writable也會被刪除

docker的聯合掛載和分層構建必須依賴於專門的文件系統的支撐才能實現,而早期的時候docker是經過aufs(高級多層統一文件系統)來實現linux的聯合掛載技術的文件系統,而aufs的前身是unionfs文件系統,聽說unionfs這個文件系統申請合併到內核的時候因代碼比較糟糕曾屢次被李納斯駁回,後來有人將unionfs重構變成aufs,可是依舊很糟糕,今後aufs這種文件系統若是是想用的話就必須向內核打補丁,今後市場主流的系統就只有ubuntu很早的時候支持了aufs文件系統,由於ubuntu將aufs整合到了內核中,也就意味着早起想使用docker也沒有很好的系統選擇,後來出現了overlayfs(疊加多層級文件系統),這個文件系統在3.18的版本開始就被整合到linux內核之中。除此以外docker還支持btrfs,devicemapper和vfs等文件系統
而市場上主流的centos既不支持aufs,也不支持overlayfs,這個時候centos就開始主推他的devicemapper文件系統,devicemapper也被拿出去和其它文件系統作比較,結果也發現devicemapper不盡人意。
今後在新版本的docker上會發現都是基於overlayfs文件系統來實現的了,overlayfs是一種抽象的二級文件系統,他須要構建與一個本地文件系統之上,全部咱們使用docker info的時候發現backing Filesystem:xfs(後端是基於xfs),前端是overlayfs文件系統。

咱們在製做好鏡像以後,鏡像應該有一個統一存儲的位置,這個位置就叫作docker registry,當容器啓動的時候,docker daemon會試圖從本地獲取相關的鏡像,本地沒有的時候,纔去registry(這個registry沒有特別指定的時候就是指的dockerhub)中下載鏡像本保存在本地。
因此docker的鏡像能夠是從dockerhub上提供的,也能夠是本地的私有鏡像倉庫,而在本地須要建立私有的倉庫的時候能夠經過docker提供的軟件包老實現,可是你經過軟件包製做的鏡像必須支持https,由於docker daemon默認必須是https的形式才能被訪問,若是是須要使用本地的你得改配置docker daemon,告訴docker daemon雖然是http不夠安全,可是能用。
docker registry的分類
第三方的registry,提供給客戶和docker社區使用;
第三方的registry,提供給客戶使用(以前的加速器就是這種);
由服務商的提供的registry,好比你買了紅帽的操做系統;
有能力建設防火牆和安全層的私有實體registry,這種私有的registry是最符合公司內部需求的,由於共有的registry實在難以知足全部客戶。

docker registry的組成:

docker registry通常由兩部分組成,一部分是由不一樣程序的不一樣版本組成的鏡像倉庫,還有一個就是索引,索引的功能能夠方便用戶根據以前定義好的信息來找相關的鏡像。

docker的私有倉庫通常都由專門的鏡像開發的人員在鏡像網站pull下來一個鏡像,在這個鏡像基礎上進行二次調整以後放到本地的私有倉庫上,而後運維人員將這些鏡像pull到須要部署的機器上。

在互聯網上有不少很好的鏡像倉庫站點,例如https://quay.io/repository/coreos/flannel, 這些站點在下載鏡像的時候,須要指定倉庫的地址和標籤,不是和咱們以前直接指定應用程序便可,例如咱們在quay.io上下載一個鏡像的方法:docker pull quay.io/bitnami/tomcat:8.5-ol-7  這個pull就是網站的信息加上標籤。

B:docker鏡像的生成途徑:

docker鏡像生成的途徑通常分爲如下幾種:

1:咱們能夠使用dockerfile,咱們本身使用一個命令docker build來製做,這個是專門用來作鏡像的。

2:咱們能夠基於某個容器來製做,例如某個容器已經處於運行當中,咱們使用docker commit在容器的最上可寫層單首創建一個鏡像層。

3:還有就是基於dockerhub自動生成的,這種類型的鏡像嚴格來講不算一種方式,dockerhub上的也是基於dockerfile方式產生的,最多算的上製做的一一種途徑而已。

基於某個容器來製做鏡像:

咱們首先啓動一個容器,在容器中作好你打算作好的修改,這個咱們須要使用到docker commit命令來完成。

[root@localhost ~]# docker run --name box001 -it busybox  咱們首先啓動一個容器
/ # ls
bin   dev   etc   home  proc  root  sys   tmp   usr   var
/ # mkdir -p /data/html   而後建立一個存html網頁的目錄
/ # vi /data/html/index.html  而且建立一個網頁的內容
/ #
此時咱們若是結束容器,這個網頁確定就不存在了,咱們如今就想把這個網頁給製做成一個鏡像,如今的busybox是不能關閉的,一結束容器就暫停了。

[root@localhost ~]# docker commit -h  先看下commit的用法和參數
Flag shorthand -h has been deprecated, please use --help

Usage:  docker commit [OPTIONS] CONTAINER(基於那個容器作鏡像) [REPOSITORY(屬於哪一個倉庫)[:TAG(有什麼標籤)]] 
若是是把後面的[REPOSITORY[:TAG]]省略,該鏡像就是本地的一個裸鏡像,不屬於任何倉庫也沒有標籤。

Create a new image from a container's changes

Options:
  -a, --author string    Author (e.g., "John Hannibal Smith <hannibal@a-team.com>")
  -c, --change list      Apply Dockerfile instruction to the created image
  -m, --message string   Commit message
  -p, --pause            Pause container during commit (default true)
-p參數是用暫停下容器使用,由於咱們在製做鏡像的時候容器是處於運行狀態,這個狀態會不斷產生不少的文件,咱們讓其暫停下在去製做。
[root@localhost ~]# docker commit -p box001
sha256:25a0f192ba8ab5f56eb9a6e068f617799fb5e8d4fabe0a12f39176dcbf7c7cf9
[root@localhost ~]#
一個鏡像就製做完成,咱們使用dokcer images查看下信息
[root@localhost ~]# docker images
        REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
<none>              <none>              25a0f192ba8a        53 seconds ago      1.2MB
busybox             latest              d8233ab899d4        4 weeks ago         1.2MB
nginx               1.14-alpine         66952fd0a8ef        6 weeks ago         16MB
[root@localhost ~]#能夠看到咱們沒有指定倉庫名,也標籤信息,就是能看到image id和大小,若是鏡像的標籤尚未規劃好,這個標籤咱們也是能夠後補的,使用docker tag命令
[root@localhost ~]# docker tag -h
Flag shorthand -h has been deprecated, please use --help

Usage:  docker tag SOURCE_IMAGE[:TAG指定鏡像] TARGET_IMAGE(倉庫名稱)[:TAG指定標籤名稱]
若是一個鏡像已經存在標籤的話,能夠爲一個鏡像打多個標籤

Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE

[root@localhost ~]# docker tag 25a0f192ba8a localhost/httpd:v0.0.1
                                              這個在沒有倉庫的時候咱們只能去image id指定
[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
localhost/httpd     v0.0.1              25a0f192ba8a        6 minutes ago       1.2MB
busybox             latest              d8233ab899d4        4 weeks ago         1.2MB
nginx               1.14-alpine         66952fd0a8ef        6 weeks ago         16MB
[root@localhost ~]#能夠看到咱們已經給以前的鏡像打上了標籤和所屬倉庫信息

[root@localhost ~]# docker tag  localhost/httpd:v0.0.1 localhost/httpd:v0.0.2
 若是剛纔的鏡像有修改了相關的內容,迭代了,咱們能夠在原有的鏡像的基礎上從新打一個標籤,標記爲迭代的版本0.0.2
[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
localhost/httpd     v0.0.1              25a0f192ba8a        9 minutes ago       1.2MB
localhost/httpd     v0.0.2              25a0f192ba8a        9 minutes ago       1.2MB
busybox             latest              d8233ab899d4        4 weeks ago         1.2MB
nginx               1.14-alpine         66952fd0a8ef        6 weeks ago         16MB
[root@localhost ~]#除了tag不同以外,其它信息均爲一致。
[root@localhost ~]# docker image rm localhost/httpd:v0.0.2
迭代的標籤內容寫錯了,咱們就能夠經過rm刪除鏡像,注意這個刪除不是真正刪除鏡像,只是刪除了標籤而已。
Untagged: localhost/httpd:v0.0.2
[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
localhost/httpd     v0.0.1              25a0f192ba8a        14 minutes ago      1.2MB
busybox             latest              d8233ab899d4        4 weeks ago         1.2MB
nginx               1.14-alpine         66952fd0a8ef        6 weeks ago         16MB
[root@localhost ~]# docker run --name box002 -it localhost/httpd:v0.0.1
/ # ls
bin   data  dev   etc   home  proc  root  sys   tmp   usr   var
/ # cat /data/html/index.html
hello busybox html.server
/ #
能夠看到咱們製做的內容已經保存到了新的鏡像當中。
docker commit  

咱們的容器必定是基於某個鏡像啓動的,咱們已經經過原始的鏡像建立了新的鏡像,咱們但願這個新的鏡像啓動的時候默認運行的命令再也不是原來鏡像上的命令,固然咱們專門指導鏡像原始的命令是什麼了,能夠使用以前的docker inspect busybox來查看cmd標記。

[root@localhost ~]# docker inspect busybox
........
 "Cmd": [
                "/bin/sh",   咱們能夠看到默認運行的是bin/sh
                "-c",
                "#(nop) ",
                "CMD [\"sh\"]"  默認的命令是sh
            ],
........
[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
localhost/httpd     v0.0.1              25a0f192ba8a        32 minutes ago      1.2MB
busybox             latest              d8233ab899d4        4 weeks ago         1.2MB
nginx               1.14-alpine         66952fd0a8ef        6 weeks ago         16MB
[root@localhost ~]# docker inspect localhost/httpd:v0.0.1  查看咱們剛纔製做的鏡像默認使用的命令
......
"Cmd": [
                "sh"
            ],
........
docker inspect busybox

 若是是咱們要修改原有基礎鏡像的默認命令也是使用到docker commit命令,加上參數-c。

[root@localhost ~]# docker commit -h
Flag shorthand -h has been deprecated, please use --help

Usage:  docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

Create a new image from a container's changes

Options:
  -a, --author string    Author (e.g., "John Hannibal Smith <hannibal@a-team.com>")
加上做者信息
  -c, --change list      Apply Dockerfile instruction to the created image
修改原有鏡像的命令
  -m, --message string   Commit message
  -p, --pause            Pause container during commit (default true)
[root@localhost ~]# docker commit -a "docker <docker@dockerhub.cn>" -c 'CMD(這裏的參數就是咱們剛纔inspect看到的參數) ["/bin/httpd(文件執行的位置,使用linux下which命令就能查到)","-f(前臺運行)","-h(網頁的目錄)","/data/html(網頁目錄的路徑)"]' -p(在製做的時候暫停) box003 (基於製做的原鏡像名)localhost/httpd:v0.0.3(新倉庫和標籤名)
sha256:fb4677ee396277ef09af92349d011376805bda1be1660004560656e9d0f65d3d
[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
localhost/httpd     v0.0.3              fb4677ee3962        3 minutes ago       1.2MB
localhost/httpd     v0.0.2              6f7c863d7eb0        17 minutes ago      1.2MB
localhost/httpd     v0.0.1              25a0f192ba8a        About an hour ago   1.2MB
busybox             latest              d8233ab899d4        4 weeks ago         1.2MB
nginx               1.14-alpine         66952fd0a8ef        6 weeks ago         16MB
[root@localhost ~]#版本3的鏡像已經制做完成
[root@localhost ~]# docker run --name httpd0.2 localhost/httpd:v0.0.2  咱們把新鏡像啓動起來
[root@localhost ~]# docker inspect httpd0.2  查看此時的cmd信息
........
  "Cmd": [
                "/bin/httpd",
                "-f",
                "-h",
                "/data/html"   能夠看到原始的命令已經被修改爲咱們指定的命令了
            ],
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.3",能夠看到地址信息
.........
[root@localhost ~]# docker ps -a
CONTAINER ID        IMAGE                    COMMAND                  CREATED             STATUS                     PORTS               NAMES
fc4b5604dd39        localhost/httpd:v0.0.2   "/bin/httpd -f -h /d…(能夠看到運行的命令就和box001是不同的,再也不是原始的sh了)"   3 minutes ago       Up 3 minutes                                   httpd0.2
7a60a03e9f3f        busybox                  "sh"                     2 hours ago         Exited (0) 3 minutes ago                       box001
32ecea10ad3e        nginx:1.14-alpine        "nginx -g 'daemon of…"   2 days ago          Exited (0) 2 days ago                          nginx
04e64051bd39        nginx:1.14-alpine        "nginx -g 'daemon of…"   3 days ago          Exited (0) 3 days ago                          nginx001
[root@localhost ~]# curl 172.17.0.3 直接訪問這個地址提供的信息
hello busybox html.server v0.02
[root@localhost ~]#
docker commit -c 

咱們能夠使用commit命令來快速建立一個屬於本身的鏡像。

固然咱們本身製做的鏡像也能夠推送到dockerhub上用於保存,在dockerhub上你能夠選擇鏡像是公開仍是私有,在推送的時候咱們選擇docker push命令。

[root@localhost ~]# docker push -h
Flag shorthand -h has been deprecated, please use --help

Usage:  docker push [OPTIONS] NAME(名字)[:TAG標籤]

Push an image or a repository to a registry

Options:
      --disable-content-trust   Skip image signing (default true)
[root@localhost ~]#這個推送的話可能須要登陸
登陸的話使用dokcer login
[root@localhost ~]# docker login -h
Flag shorthand -h has been deprecated, please use --help

Usage:  docker login [OPTIONS] [SERVER]
這個登陸參數裏面若是是dockerhub的話[SERVER]參數是不用指的,若是是別的服務器就須要指定。

Log in to a Docker registry

Options:
  -p, --password string   Password
      --password-stdin    Take the password from stdin
  -u, --username string   Username
[root@localhost ~]# docker login -u ppcserver
Password:
Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: TLS handshake timeout
[root@localhost ~]# docker login -u ppcserver  登陸dockerhub
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded  返回登陸成功
在push以前還須要注意的一個點就是你把本地的鏡像推送到dockerhub上的時候須要和dockerhub上的倉庫名保持一致,否則是不能推送的。
[root@localhost ~]# docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
ppcserver/httpd0.2 (本地的倉庫名稱須要和dockerhub上的保持一致)  v0.0.2              d82b7aeb082a        34 seconds ago      1.2MB
localhost/httpd      v0.0.1              25a0f192ba8a        2 hours ago         1.2MB
busybox              latest              d8233ab899d4        4 weeks ago         1.2MB
nginx                1.14-alpine         66952fd0a8ef        6 weeks ago         16MB
[root@localhost ~]# docker push ppcserver/httpd0.2:v0.0.2
The push refers to repository [docker.io/ppcserver/httpd0.2]
acae7b22ffb2: Pushed
adab5d09ba79: Mounted from library/busybox
v0.0.2: digest: sha256:a1a1a6e9b46683c7f948861b898febb8eb5d3fd76c6cb4053566d9e79b489761 size: 734
[root@localhost ~]#能夠看到push成功,能夠上dockerhub上查看鏡像的信息
咱們將本地的鏡像刪除,去dockerhub上把咱們剛纔推送的鏡像給拉下來
[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
localhost/httpd     v0.0.1              25a0f192ba8a        2 hours ago         1.2MB
busybox             latest              d8233ab899d4        4 weeks ago         1.2MB
nginx               1.14-alpine         66952fd0a8ef        6 weeks ago         16MB
[root@localhost ~]# docker pull ppcserver/httpd0.2:v0.0.2
v0.0.2: Pulling from ppcserver/httpd0.2
697743189b6d: Already exists
a629bcaab0fe: Pull complete
Digest: sha256:a1a1a6e9b46683c7f948861b898febb8eb5d3fd76c6cb4053566d9e79b489761
Status: Downloaded newer image for ppcserver/httpd0.2:v0.0.2
[root@localhost ~]# docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
ppcserver/httpd0.2   v0.0.2              d82b7aeb082a        12 minutes ago      1.2MB
localhost/httpd      v0.0.1              25a0f192ba8a        2 hours ago         1.2MB
busybox              latest              d8233ab899d4        4 weeks ago         1.2MB
nginx                1.14-alpine         66952fd0a8ef        6 weeks ago         16MB
[root@localhost ~]#能夠看到咱們又將咱們的鏡像pull下來了
docker push

若是你是要推送到像阿里雲這樣的鏡像倉庫的時候須要帶上服務器倉庫的地址,在dockerhub上下載的時候也須要注意,儘可能不要下載倉庫裏面用戶的鏡像,以前有不少鏡像下載下來以後致使服務器被肉雞使用。

C:鏡像的導入和導出:

咱們不少時候都是用於測試使用,當在一臺機器上製做完一個鏡像,想放到測試機器上進行測試,這個時候push的方式很麻煩, 這種狀況下咱們就能夠把已有的鏡像打包,放到另一臺機器裝一下運行便可。咱們須要使用到的兩個命令:

1:docker save(保存打包文件) 

[root@localhost ~]# docker save -h
Flag shorthand -h has been deprecated, please use --help

Usage:  docker save [OPTIONS] IMAGE [IMAGE...]
save一次能夠打包多個鏡像

Save one or more images to a tar archive (streamed to STDOUT by default)

Options:
  -o, --output string   Write to a file, instead of STDOUT
-o參數指定打包以後存在那個文件中
[root@localhost ~]# docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
ppcserver/httpd0.2   v0.0.2              d82b7aeb082a        44 minutes ago      1.2MB
localhost/httpd      v0.0.1              25a0f192ba8a        3 hours ago         1.2MB
busybox              latest              d8233ab899d4        4 weeks ago         1.2MB
nginx                1.14-alpine         66952fd0a8ef        6 weeks ago         16MB
[root@localhost ~]# docker save -o /home/myimages.gz ppcserver/httpd0.2:v0.0.2 localhost/httpd:v0.0.1  咱們將版本1和版本2直接打包放在home下取名爲myimages,並且並壓縮成gz的格式
[root@localhost ~]# cd /home/
[root@localhost home]# ls
docker  myimages.gz
[root@localhost home]#
docker save

2:docker load從打包文件直接安裝

[root@localhost /]# docker load -h
Flag shorthand -h has been deprecated, please use --help

Usage:  docker load [OPTIONS]

Load an image from a tar archive or STDIN

Options:
  -i, --input string   Read from tar archive file, instead of STDIN
指定從那個文件來load
  -q, --quiet          Suppress the load output
[root@localhost /]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
busybox             latest              d8233ab899d4        4 weeks ago         1.2MB
nginx               1.14-alpine         66952fd0a8ef        6 weeks ago         16MB
[root@localhost home]# docker load -i myimages.gz
acae7b22ffb2: Loading layer [==================================================>]   5.12kB/5.12kB
Loaded image: ppcserver/httpd0.2:v0.0.2
751d8660062f: Loading layer [==================================================>]   5.12kB/5.12kB
Loaded image: localhost/httpd:v0.0.1
[root@localhost home]# docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
ppcserver/httpd0.2   v0.0.2              d82b7aeb082a        About an hour ago   1.2MB
localhost/httpd      v0.0.1              25a0f192ba8a        4 hours ago         1.2MB
busybox              latest              d8233ab899d4        4 weeks ago         1.2MB
nginx                1.14-alpine         66952fd0a8ef        6 weeks ago         16MB
[root@localhost home]#
docker load

docker save和docker load兩種方式也存在一個問題就是你使用run或者pull的時候,由於你本地沒有鏡像,仍是回去鏡像本應該所屬的位置去拉鏡像下來,因此使用這種方式你本地仍是得有鏡像。

除了save和load還有export和import。

♣四:容器的虛擬化網絡

A:容器虛擬化網絡基礎:

在文章的最開始咱們就介紹了容器的6種命名空間,都是用於隔離技術而存在的,那麼容器的虛擬化網絡在內核很早的時候已經支持,主要用於隔離協議棧和網路設備。

假如咱們的服務器只有一塊物理網卡,此時在這臺機器上建立了不少容器,遠遠大於網卡設備的數量,這個時候容器運行的鏡像須要進行通信怎麼辦,因此須要使用到虛擬網卡來保證服務的正常通信。

在咱們經常使用的vmwar workstation中咱們能夠使用虛擬網卡的功能來虛擬出不少網卡設備來保證正常的通信,而在linux內核中能徹底支持二層三層設備的模擬,二層設備就包含咱們的網卡,二層設備能封裝物理報文在各個設備之間進行報文轉發,並且這種網絡很獨特,每一張網絡設備是成對出現的,這就比如一根網線的兩頭,能鏈接虛擬機和交換機之上同樣,而這種網卡模擬在咱們內核就原生支持。在linux上咱們能夠經過ovs(openvswitch)能工具來模擬交換機等設備。

有了這種工具和內核的支持,咱們在一個平臺上搭建不不一樣的容器,而後經過內核和工具,將網絡一頭接在容器這邊,一頭接在交換機之上,運用相同的概念,咱們就能完容器之間的通信。這個是簡單的網絡形式,若是是我在一個平臺之上有兩個交換機,並且在不一樣網段怎麼辦,這個時候也是須要虛擬網絡,在經過工具模擬路由器,經過虛擬網路把兩邊的交換機接到路由器上,這樣稍微複雜的網絡文明也能實現,可是路由器屬於三層設備,要想使用就須要使用一個單獨的容器(用戶空間)來完成,若是更加複雜的網絡就不建議使用這種技術了,由於很容易出現網絡風暴,並且效率不高。

咱們發現容器在須要通信的時候由於要不斷的考慮網絡形態來應對複雜的容器場景,這個裏面很容易出現問題,所以咱們在面對這種容器網絡的狀況下就能夠使用overlay network(疊加網絡技術),這種技術就是在原有的物理機網卡之上創建一個虛擬的網絡橋,上層的容器的通信就藉助咱們的物理網絡來完成報文的隧道轉發,能夠完成跨設備容器之間的通信。

假如server1和server9在兩臺不通的物理服務器上,並且不在同一網段,這個時候當server1須要訪問server9的時候,就須要把報文信息發送給網絡橋並封裝報文信息,在由網絡橋轉發給物理網卡,server1的物理網卡在此時確定不會知道server9所在的地址,可是server1知道server9所在的物理網卡地址,此時server1又將已經封裝的報文信息二次封裝加上發給server9所在的物理網卡,server9在解開封裝的報文以後發現是給到server9網絡橋之上的機器的,這個時候就再轉發給server9所在的虛擬機器。

B:docker的網絡形式:

docker在安裝以後默認提供了三種網絡:

1:bridge(橋接式網絡,此處的橋接是net橋,bridge會在本機建立一個軟交換機,就是咱們以前看到的docker 0,這個docker 0能夠充當交換機以外還能充當咱們的網卡設備,不給地址的時候就是交換機,給了地址既是交換機又是網絡設備)

當咱們啓動一個容器,就會建立一個veth開頭後面隨機的網卡信息:

[root@localhost ~]# docker ps -a
CONTAINER ID        IMAGE                       COMMAND                  CREATED              STATUS                  PORTS               NAMES
a71b4f12bed7        ppcserver/httpd0.2:v0.0.2   "/bin/httpd -f -h /d…"   About a minute ago   Up About a minute                           httpd0.2
32ecea10ad3e        nginx:1.14-alpine           "nginx -g 'daemon of…"   3 days ago           Up 4 minutes            80/tcp              nginx
04e64051bd39        nginx:1.14-alpine           "nginx -g 'daemon of…"   3 days ago           Exited (0) 3 days ago                       nginx001
[root@localhost ~]#咱們如今處於運行的網卡有兩個
[root@localhost ~]# ifconfig
veth11541d3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::d818:72ff:fe50:8e8e  prefixlen 64  scopeid 0x20<link>
        ether da:18:72:50:8e:8e  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 22  bytes 2422 (2.3 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

veth56e9b13: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::fcff:3eff:fed0:c335  prefixlen 64  scopeid 0x20<link>
        ether fe:ff:3e:d0:c3:35  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 8  bytes 656 (656.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
會發現多處了這兩張網卡信息,並且這個網卡都是成對出現的,一個在容器,一個在軟橋,就至關於一根網線鏈接的設備的兩頭。
上面說了docker 0在沒有配置網絡的時候就是交換機,咱們能夠經過brctl show(注意這個命令是要安裝bridge-utils包的)命令來看下交換機上是否是有咱們ifconfig的網卡,先找到接在交換機上的網卡信息。
[root@localhost ~]# brctl show
bridge name     bridge id               STP enabled     interfaces
docker0         8000.0242bb636b7b       no              veth11541d3
                                                        veth56e9b13
virbr0          8000.525400fb0995       yes             virbr0-nic
[root@localhost ~]# ifconfig
veth11541d3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::d818:72ff:fe50:8e8e  prefixlen 64  scopeid 0x20<link>
        ether da:18:72:50:8e:8e  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 22  bytes 2422 (2.3 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

veth56e9b13: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::fcff:3eff:fed0:c335  prefixlen 64  scopeid 0x20<link>
        ether fe:ff:3e:d0:c3:35  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 8  bytes 656 (656.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
能夠看到軟橋上正好存在了兩張網卡信息和咱們ifconfig對的上,那麼另一般是存在容器裏面的,咱們先經過ip link show先看下另一半的簡要信息,要和咱們如今的看到這半邊是銜接上的。
[root@localhost ~]# ip link show
.....
7: veth11541d3@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default
    link/ether da:18:72:50:8e:8e brd ff:ff:ff:ff:ff:ff link-netnsid 0
9: veth56e9b13@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default
    link/ether fe:ff:3e:d0:c3:35 brd ff:ff:ff:ff:ff:ff link-netnsid 1
.....
veth56e9b13@if8網卡信息的兩邊是經過@符號來分割的,咱們能夠看到接在軟橋上的網卡信息,還能看到另外的半邊的信息,雖然就就顯示了一部分。
咱們使用iptables的時候能夠看到這整個nat過程都是自動生成的
Chain POSTROUTING (policy ACCEPT 255 packets, 17822 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 MASQUERADE  all  --  *      !docker0  172.17.0.0/16        0.0.0.0/0
    2   267 RETURN     all  --  *      *       192.168.122.0/24     224.0.0.0/24
    0     0 RETURN     all  --  *      *       192.168.122.0/24     255.255.255.255
    0     0 MASQUERADE  tcp  --  *      *       192.168.122.0/24    !192.168.122.0/24     masq ports: 1024-65535
    0     0 MASQUERADE  udp  --  *      *       192.168.122.0/24    !192.168.122.0/24     masq ports: 1024-65535
    0     0 MASQUERADE  all  --  *      *       192.168.122.0/24    !192.168.122.0/24
  437 30088 POSTROUTING_direct  all  --  *      *       0.0.0.0/0            0.0.0.0/0
  437 30088 POSTROUTING_ZONES_SOURCE  all  --  *      *       0.0.0.0/0            0.0.0.0/0
  437 30088 POSTROUTING_ZONES  all  --  *      *       0.0.0.0/0            0.0.0.0/0
docker network

2:host (讓容器使用宿主機的網絡名稱空間)

3:none (是沒有網絡的,容器裏面存在這種網絡的意義就是臨時處理下數據,處理完成存儲到咱們的硬盤上,方便其它的容器讀取)

docker一共有四種網絡形式:

1:closed container(封閉式網絡,指的就是咱們上面的none,只有lo接口)

2:bridged container (橋接式網絡,默認地址是172.17.0.1地址,稱做橋接式網絡或者nat網絡)

3:joined container (聯盟式網絡,讓容器之間部分名稱空間是隔離的,可是在uts,nat,ipc共享同一組,而後容器之間就能通信了)

4:open container (開放式網路,直接共享物理機的網絡名稱空間,也就意味着物理機能看到的網絡,容器也能看到)

C:docker網絡的相關操做:

知道docker可以使用的網絡形式以後,咱們就能夠使用命令來指定查看運行中國容器使用的網絡是屬於哪一種網絡形式

[root@localhost ~]# docker container inspect httpd0.2
.........
"Networks": {
                "bridge": {  使用的默認的bridge網絡
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "4e1f3c27c35496f43410401bc6de83c12f00a48ffae8e4351017a815435db40f",
                    "EndpointID": "68676ed0886db79ff05cdb6a630083daf882bf914b7902b5b767974e14ebbe53",
                    "Gateway": "172.17.0.1",  容器的網關
                    "IPAddress": "172.17.0.2",  地址
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:02",  當前容器的mac地址
                    "DriverOpts": null
..........
docker container inspect

在開放式網絡中,docker的網絡名稱空間,uts,ipc是能被容器共享的,咱們能夠手動經過ip命令操做咱們名稱空間,ip命令所屬與iproute包組。

[root@localhost ~]# ip
Usage: ip [ OPTIONS ] OBJECT { COMMAND | help }
       ip [ -force ] -batch filename
where  OBJECT := { link | address | addrlabel | route | rule | neigh | ntable |
                   tunnel | tuntap | maddress | mroute | mrule | monitor | xfrm |
                   netns(咱們能夠看到ip可以操做網絡名稱空間) | l2tp | fou | macsec | tcp_metrics | token | netconf | ila |
                   vrf }
       OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] |
                    -h[uman-readable] | -iec |
                    -f[amily] { inet | inet6 | ipx | dnet | mpls | bridge | link } |
                    -4 | -6 | -I | -D | -B | -0 |
                    -l[oops] { maximum-addr-flush-attempts } | -br[ief] |
                    -o[neline] | -t[imestamp] | -ts[hort] | -b[atch] [filename] |
                    -rc[vbuf] [size] | -n[etns] name | -a[ll] | -c[olor]}
[root@localhost ~]# ip netns help
Usage: ip netns list   列出網絡名稱空間
       ip netns add NAME  添加網絡名稱空間
       ip netns set NAME NETNSID  設置網絡名稱空間的sid
       ip [-all] netns delete [NAME]
       ip netns identify [PID]
       ip netns pids NAME
       ip [-all] netns exec [NAME] cmd ...  在網絡命令空間內執行相關的命令
       ip netns monitor
       ip netns list-id
       ip link挪動網絡名稱空間
當咱們經過ip命令管理網絡名稱空間的時候,只有網絡名稱空間是隔離的,其它的都是處於同一層上的,這和docker的網絡名稱空間有所不同的地方。
ip命令和netns虛擬網絡名稱空間
[root@localhost ~]# ip netns add ip001  經過add添加網絡名稱空間
[root@localhost ~]# ip netns add ip002
[root@localhost ~]# ip netns list
ip002
ip001
[root@localhost ~]# ip netns exec ip001 ifconfig -a
lo: flags=8<LOOPBACK>  mtu 65536
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
咱們在001裏面執行命令來查看網卡信息,結果是沒有的,由於咱們單獨指定建立網卡設備 ,沒有指定的狀況下默認就是lo接口
咱們還能夠經過ip命令建立虛擬網卡對,將網卡的兩端分別綁定在ip001和ip002上。
[root@localhost ~]# ip link add(添加) name veth0.1(名字是veth0.1) type veth(虛擬網卡須要使用veth格式) peer(指定另一半) name veth0.2(名字是veth0.2)
[root@localhost ~]# ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
    link/ether 00:0c:29:00:75:55 brd ff:ff:ff:ff:ff:ff
3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default qlen 1000
    link/ether 52:54:00:fb:09:95 brd ff:ff:ff:ff:ff:ff
4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN mode DEFAULT group default qlen 1000
    link/ether 52:54:00:fb:09:95 brd ff:ff:ff:ff:ff:ff
5: veth0.2@veth0.1(能夠看到名稱空間裏面各自的一半就是咱們指定的內容): <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether e2:1f:c1:54:26:18 brd ff:ff:ff:ff:ff:ff
6: veth0.1@veth0.2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether b6:cb:2e:75:cd:ec brd ff:ff:ff:ff:ff:ff
[root@localhost ~]#這樣在咱們宿主機上就有了一對網絡設備,可是這種方式建立的是沒有激活的,咱們將網絡設備的一邊綁定到咱們剛纔建立好的ip001上。
[root@localhost ~]# ip link set dev veth0.2 netns ip001
使用set參數將0.2添加到netns虛擬網絡名稱空間ip001裏面
[root@localhost ~]# ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
    link/ether 00:0c:29:00:75:55 brd ff:ff:ff:ff:ff:ff
3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default qlen 1000
    link/ether 52:54:00:fb:09:95 brd ff:ff:ff:ff:ff:ff
4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN mode DEFAULT group default qlen 1000
    link/ether 52:54:00:fb:09:95 brd ff:ff:ff:ff:ff:ff
6: veth0.1@if5(能夠看到veth0.2設備已經被挪走了): <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether b6:cb:2e:75:cd:ec brd ff:ff:ff:ff:ff:ff link-netnsid 0
[root@localhost ~]# ip netns exec ip001 ifconfig -a  
ip001就多了一個veth0.2的網絡設備
lo: flags=8<LOOPBACK>  mtu 65536
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

veth0.2: flags=4098<BROADCAST,MULTICAST>  mtu 1500
        ether e2:1f:c1:54:26:18  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[root@localhost ~]# ip netns exec ip001 ip link set dev veth0.2 name eth2  咱們還能夠給網卡設備名更名
[root@localhost ~]# ip netns exec ip001 ifconfig -a
eth2: flags=4098<BROADCAST,MULTICAST>  mtu 1500
        ether e2:1f:c1:54:26:18  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=8<LOOPBACK>  mtu 65536
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[root@localhost ~]# ifconfig veth0.1 2.4.6.8./24 up 
經過ifconfig命令給設備veth0.1設置ip爲2.4.6.8./24位掩碼並激活
[root@localhost ~]# ifconfig 
.....
veth0.1: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 2.4.6.8  netmask 255.255.255.0  broadcast 2.4.6.255
        ether b6:cb:2e:75:cd:ec  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
......
[root@localhost ~]# ip netns exec ip001 ifconfig eth2 2.4.6.100/24 up咱們經過命令將網絡名稱空間裏面的ip001也給指定ip並啓動起來
[root@localhost ~]# ip netns exec ip001 ifconfig -a  
eth2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 2.4.6.100  netmask 255.255.255.0  broadcast 2.4.6.255
        inet6 fe80::e01f:c1ff:fe54:2618  prefixlen 64  scopeid 0x20<link>
        ether e2:1f:c1:54:26:18  txqueuelen 1000  (Ethernet)
        RX packets 14  bytes 1766 (1.7 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 8  bytes 656 (656.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=8<LOOPBACK>  mtu 65536
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
[root@localhost ~]# ping 2.4.6.100
PING 2.4.6.100 (2.4.6.100) 56(84) bytes of data.
64 bytes from 2.4.6.100: icmp_seq=1 ttl=64 time=0.103 ms
64 bytes from 2.4.6.100: icmp_seq=2 ttl=64 time=0.117 ms
^Z
[1]+  已中止               ping 2.4.6.100
[root@localhost ~]# 能夠看到咱們的宿主機和虛擬網絡名稱空間裏面的網絡就能夠通信了
[root@localhost ~]# ip link set dev veth0.1 netns ip002
咱們將另一半挪到另一半名稱空間去
[root@localhost ~]# ip netns exec ip002 ifconfig -a
lo: flags=8<LOOPBACK>  mtu 65536
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

veth0.1: flags=4098<BROADCAST,MULTICAST>  mtu 1500
        ether b6:cb:2e:75:cd:ec  txqueuelen 1000  (Ethernet)
        RX packets 12  bytes 936 (936.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 18  bytes 2046 (1.9 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[root@localhost ~]#這樣挪進來默認是沒有被激活的
[root@localhost ~]# ip netns exec ip002 ip link set dev veth0.1 name eth1
[root@localhost ~]# ip netns exec ip002 ifconfig eth1  2.4.6.200/24 up
[root@localhost ~]# ip netns exec ip002 ifconfig -a
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 2.4.6.200(能夠看到ip002也有了ip地址)  netmask 255.255.255.0  broadcast 2.4.6.255
        inet6 fe80::b4cb:2eff:fe75:cdec  prefixlen 64  scopeid 0x20<link>
        ether b6:cb:2e:75:cd:ec  txqueuelen 1000  (Ethernet)
        RX packets 12  bytes 936 (936.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 26  bytes 2702 (2.6 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=8<LOOPBACK>  mtu 65536
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[root@localhost ~]# ip netns exec ip002 ping 2.4.6.100
咱們在ip002裏面pingip001的地址是能夠通信的
PING 2.4.6.100 (2.4.6.100) 56(84) bytes of data.
64 bytes from 2.4.6.100: icmp_seq=1 ttl=64 time=0.163 ms
64 bytes from 2.4.6.100: icmp_seq=2 ttl=64 time=0.113 ms
^Z
[4]+  已中止               ip netns exec ip002 ping 2.4.6.100
[root@localhost ~]# ip netns exec ip001 ping 2.4.6.200
反過來也是能通信的
PING 2.4.6.200 (2.4.6.200) 56(84) bytes of data.
64 bytes from 2.4.6.200: icmp_seq=1 ttl=64 time=0.057 ms
64 bytes from 2.4.6.200: icmp_seq=2 ttl=64 time=0.133 ms
^Z
[5]+  已中止               ip netns exec ip001 ping 2.4.6.200
[root@localhost ~]#
經過ip命令添加兩個網絡名稱空間配置ip並讓其通信
[root@localhost ~]# docker run --name box001 --network(歐陽--network參數指定網絡是none) none -it --rm (在容器退出就刪除,此處是爲了方便測試)busybox:latest
/ # ifconfig
lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

/ #能夠看到就屬於封閉式網絡
docker建立封閉式網絡none
在主機與主機之間通信不少時候會用到主機名來通信
[root@localhost ~]# docker run --name box001  -it --rm busybox:latest
/ # hostname
781e119ed613
/ #
能夠看待當前容器的主機名是一個自動生成的名稱,而且這個名稱就是咱們容器的id
[root@localhost ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
781e119ed613        busybox:latest      "sh"                2 minutes ago       Up 2 minutes                            box001
[root@localhost ~]# docker run --name box001 -it -h v1.1host --rm 
busybox:latest
咱們也能夠在建立容器的時候用-h指定主機名
/ # hostname
v1.1host
/ # cat /etc/hosts
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2      v1.1host v1   當有了主機名咱們就能夠經過主機名來解析
/ # cat /etc/resolv.conf
# Generated by NetworkManager
search localdomain
nameserver 192.168.181.2  能夠看到當前容器指定的dns是192.168.181.2,這個地址是咱們宿主機的dns地址  
這樣咱們的容器就能經過宿主機的dns順利的解析到公網的地址信息
/ # nslookup -type=A www.taobao.com
Server:         192.168.181.2
Address:        192.168.181.2:53

Non-authoritative answer:
www.taobao.com  canonical name = www.taobao.com.danuoyi.tbcache.com
Name:   www.taobao.com.danuoyi.tbcache.com
Address: 103.43.210.219
Name:   www.taobao.com.danuoyi.tbcache.com
Address: 103.43.210.61
Name:   www.taobao.com.danuoyi.tbcache.com
Address: 103.43.210.87
Name:   www.taobao.com.danuoyi.tbcache.com
Address: 103.43.210.186
能夠看到可以正常解析公網的域名信息
[root@localhost ~]# docker run --name box001 -it -h v1.1host --dns 123.123.123.123 --rm busybox:latest
若是咱們不想使用宿主機的dns地址,想本身指定的話也能夠本身去指定
/ # cat /etc/resolv.conf
search localdomain
nameserver 123.123.123.123
/ # cat /etc/hosts
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2      v1.1host v1
/ # nslookup -type=A www.baidu.com
Server:         123.123.123.123
Address:        123.123.123.123:53

Non-authoritative answer:
www.baidu.com   canonical name = www.a.shifen.com
Name:   www.a.shifen.com
Address: 119.75.217.109
Name:   www.a.shifen.com
Address: 119.75.217.26

/ #
[root@localhost ~]# docker run --name box001 -it -h v1.1host --dns 123.123.123.123 --add-host www.baidu.com:10.10.10.10 --rm busybox:latest
/ # cat /etc/hosts
咱們還能夠在docker啓動的時候注入hosts的內容
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
10.10.10.10     www.baidu.com
172.17.0.2      v1.1host v1
/ #
docker的橋接式網絡

當咱們建立了一個例如nginx這樣的服務,這樣的服務是須要發佈到互聯網的,這個時候咱們就須要使用到開放式網絡,當咱們容器運行的nginx監聽的是80端口,這個時候咱們就須要把80端口暴露在咱們物理機的網卡ip地址之上的某個端口。

咱們經過啓動容器的時候添加選項-p指定容器端口,而這個端口會被映射到主機全部地址的一個動態端口。
[root@localhost ~]# docker run --name web1 --rm -p 80 ppcserver/httpd0.2:v0.0.2
啓動容器服務
由於如今走的net橋,指定容器端口是80,如今外面要訪問確定是走宿主機的本機ip,還有就是如今端口在宿主機是動態的,咱們能夠經過docker port web1來查看映射的動態端口
[root@localhost ~]# docker port web1
80/tcp -> 0.0.0.0:32768   這個0.0.0.0就表明了宿主機的全部地址
[root@localhost ~]# iptables -t nat -vnL 這個地址映射徹底是自動的,咱們經過iptables就能看整個映射過程,並且整個net規則是經過咱們-p選項自動產生的。
當咱們中止容器的運行,這條規則也就自動刪除了
......
Chain DOCKER (2 references)
 pkts bytes target     prot opt in     out     source               destination
    0 RETURN     all  --  docker0 *       0.0.0.0/0            0.0.0.0/0
    0 DNAT       tcp  --  !docker0 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:32768 to:172.17.0.2:80
.......
能夠看到172.17.0.2:80端口被映射成了32768端口,咱們經過瀏覽器直接就能夠訪問咱們宿主機的32678端口就能看到網頁內容

若是咱們想固定下來使用宿主機的一個地址,不但願被映射到宿主機的全部地址之上,就能夠使用-p 加上指定ip
[root@localhost ~]# docker run --name web1 -p 192.168.181.132::80 --rm ppcserver/httpd0.2:v0.0.2
注意指定ip後面的兩個冒號是必須的。
[root@localhost ~]# docker port web1
80/tcp -> 192.168.181.132:32768   能夠看見如今就是指定的ip地址的動態端口了
咱們能不能使用宿主機的全部ip可是出去的端口我要求是固定的80,也是能夠實現的。
[root@localhost ~]# docker run --name web1 -p 80:80 --rm ppcserver/httpd0.2:v0.0.2
注意,-p後面沒有接ip地址就表明全部宿主機的ip地址,80:80之間只有一個冒號。
[root@localhost ~]# docker port web1
80/tcp -> 0.0.0.0:80
那要既要指定ip也要指定端口也就變得很簡單了
[root@localhost ~]# docker run --name web1 -p 192.168.181.132:80:80 --rm ppcserver/httpd0.2:v0.0.2
[root@localhost ~]# docker port web1
80/tcp -> 192.168.181.132:80
docker 開放式網絡還有一個-P參數,這個參數會將容器全部計劃要暴露的端口所有應設置主機端口
[root@localhost ~]# docker run --name web1 -P --expose 80 --expose 888 --rm ppcserver/httpd0.2:v0.0.2
[root@localhost ~]# docker port web1
80/tcp -> 0.0.0.0:32770
888/tcp -> 0.0.0.0:32769
[root@localhost ~]# docker run --name web1 -P --expose 80 --expose 888 --expose 808 --expose 88 --rm ppcserver/httpd0.2:v0.0.2
[root@localhost ~]# docker port web1
80/tcp -> 0.0.0.0:32774
808/tcp -> 0.0.0.0:32772
88/tcp -> 0.0.0.0:32773
888/tcp -> 0.0.0.0:32771
[root@localhost ~]#
docker開放式網絡
[root@localhost ~]# docker run --name box1 -it busybox:latest  咱們開啓一個容器,發現會自動的幫忙分派一個ip
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02
          inet addr:172.17.0.2  Bcast:172.17.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:6 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:516 (516.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

/ #

[root@localhost ~]# docker run --name box2 -it busybox:latest  再建立一個容器,發現又自動生成了一個ip
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:03
          inet addr:172.17.0.3  Bcast:172.17.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:6 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:516 (516.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

/ #
咱們發現每次容器啓動會自動產生一個不同的ip

[root@localhost ~]# docker run --name box2 --network container:box1 -it --rm busybox:latest  咱們在啓動容器的時候直接指定共用那個容器的網絡名稱空間,這樣咱們就能得到和被指定網絡名稱空間同樣的ip
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02
          inet addr:172.17.0.2  Bcast:172.17.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:656 (656.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

/ #
box1
/ # mkdir /data 咱們在第一個容器裏面建立目錄,
/ # ls
bin   data  dev   etc   home  proc  root  sys   tmp   usr   var
/ #
box2   在另一個容器是不能看到的
/ # ls
bin   dev   etc   home  proc  root  sys   tmp   usr   var
/ #
咱們在box2上個建立一個網頁
/ # echo "hello busybox" > /home/index.html
/ # httpd -h /home/
/ # netstat -anput 80
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 :::80                   :::*                    LISTEN      9/httpd
/ #
在box1上訪問
/ # wget -O - -q 127.0.0.1
hello busybox
/ #
能夠看到是能訪問的,說明他們共享了網絡名稱空間,可是不會共享其它的名稱空間。
既然咱們建立的時候能共享容器的網絡名稱空間,那咱們也能共享宿主機的網絡名稱空間。
[root@localhost ~]# docker run --name box3 --network host -it --rm busybox:latest
/ # ifconfig
......
ens33     Link encap:Ethernet  HWaddr 00:0C:29:00:75:55
          inet addr:192.168.181.132  Bcast:192.168.181.255  Mask:255.255.255.0
          inet6 addr: fe80::d8dc:efca:4044:5802/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:6281 errors:0 dropped:0 overruns:0 frame:0
          TX packets:4058 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:621103 (606.5 KiB)  TX bytes:477461 (466.2 KiB)
......
咱們建立一個httpd的服務,看看是否是能經過瀏覽器訪問
/ # echo "hello docker.server" > /home/index.html
/ # httpd -h /home/
/ # netstat -anptu | grep 80
tcp        0      0 :::80                   :::*                    LISTEN      8/httpd
/ #
咱們經過瀏覽器就能訪問到咱們剛纔編輯的網頁內容了,這種看似和在宿主機上搭建網絡沒有什麼區別,可是你會發現我要快速搭建httpd服務的時候,直接一條命令完事兒,比原始的操做簡單太多了。
docker的聯盟式網絡
咱們在建立容器的時候一直都是使用的默認172.17.0網段,這個地址和網段是能調整的,這樣咱們就能在之後不一樣的容器給到不一樣的默認網絡
這個調整默認ip是須要修改/etc/docker/daemon.json文件。
配置項以下:
{  多項配置逗號分隔 
    "bip": "192.168.0.1/24",  指dokcer 0橋的ip地址和掩碼
    "fixed-cidr": "10.10.10.0/16",
    "fixed-cidr-v6": 
    "mut": 
    "default-geteway": "192.168.0.1, 默認網關
    ........
    "dns": ["10.10.10.10","114.114.114.114"] dns不配置就是用戶宿主機的,dns最多給到3個,最少一個
     .....
}
[root@localhost ~]# cat /etc/docker/daemon.json
{
    "registry-mirrors":["https://registry.docker-cn.com"],
     "bip": "192.168.0.1/24"  改下配置文件加上指定的默認網段
}

[root@localhost ~]# docker run --name box1 -it --rm busybox:latest
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:C0:A8:00:02
          inet addr:192.168.0.2  Bcast:192.168.0.255  Mask:255.255.255.0  能夠看到默認地址就是咱們指定的地址段了,至於其它的東西,docker會自動幫忙計算生成
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:5 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:426 (426.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

/ #
咱們在另一個docker默認是不能控制宿主機上另一個docker容器的,由於每一個docker指監聽了unix指定路徑下的sock文件,默認路徑在/var/run/docker.sock,若是咱們要想其餘用戶在外網正常訪問咱們的docker容器,咱們就須要使用-H參數
  -H, --host list          Daemon socket(s) to connect to  ,若是咱們沒有指定訪問的信息,默認就是走的本地的sock文件記錄的信息
這個時候咱們須要先改daemon.json配置文件
"hosts": ["tcp://0.0.0.0:1221", "unix:///var/run/docker.sock"]
而後重啓docker,在容器1就能操做容器2。
在執行的時候要加-H --host(ip和端口)。
在docker還能夠建立自動以的橋
咱們在docker iofo查看信息的時候能夠看到docker的網絡插件支持以下幾種
Network: bridge host macvlan null(封閉式網絡) overlay(疊加網絡)
咱們在使用命令就能夠建立自定義的橋bridge 
[root@localhost home]# docker network create -d bridge --subnet "192.168.12.1/16" --gateway "192.168.0.1" mybr1
6b16879aaff29aaf34ef1cbba51ac4c5eb4ae6f90624d0bd3c9a215bac28b2e3
[root@localhost home]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
a4ff9eacbd15        bridge              bridge              local
562cbe3d542c        host                host                local
6b16879aaff2        mybr1               bridge              local
30c6f39ae8be        none                null                local
[root@localhost home]#能夠看到咱們就建立了一個自定義的[root@localhost home]# docker network create -d bridge --subnet "192.168.12.1/16" --gateway "192.168.0.1" mybr1
6b16879aaff29aaf34ef1cbba51ac4c5eb4ae6f90624d0bd3c9a215bac28b2e3
[root@localhost home]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
a4ff9eacbd15        bridge              bridge              local
562cbe3d542c        host                host                local
6b16879aaff2        mybr1               bridge              local
30c6f39ae8be        none                null                local
[root@localhost home]# ifconfig
br-6b16879aaff2: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 192.168.0.1  netmask 255.255.0.0  broadcast 192.168.255.255
        ether 02:42:0c:b3:a1:e1  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
可是網絡接口的名稱是咱們建立的時候生成的加密字符,後續能夠經過ip link來調整名字便可
[root@localhost home]# docker run --name box1 -it --net mybr1 busybox:latest
啓動容器的時候直接指定網絡橋
Unable to find image 'busybox:latest' locally
latest: Pulling from library/busybox
697743189b6d: Pull complete
Digest: sha256:061ca9704a714ee3e8b80523ec720c64f6209ad3f97c0ff7cb9ec7d19f15149f
Status: Downloaded newer image for busybox:latest
/ # ls
bin   dev   etc   home  proc  root  sys   tmp   usr   var
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:C0:A8:00:02
          inet addr:192.168.0.2  Bcast:192.168.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:19 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:2212 (2.1 KiB)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

咱們在宿主機開啓兩個容器,分別使用咱們自定義的mybr1和默認的bridge。
[root@localhost home]# docker run --name box1 -it --net mybr1 busybox:latest
Unable to find image 'busybox:latest' locally
latest: Pulling from library/busybox
697743189b6d: Pull complete
Digest: sha256:061ca9704a714ee3e8b80523ec720c64f6209ad3f97c0ff7cb9ec7d19f15149f
Status: Downloaded newer image for busybox:latest
/ # ls
bin   dev   etc   home  proc  root  sys   tmp   usr   var
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:C0:A8:00:02
          inet addr:192.168.0.2  Bcast:192.168.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:19 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:2212 (2.1 KiB)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

/ #
[root@localhost ~]# docker run --name box2 -it --net bridge  busybox:latest
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02
          inet addr:172.17.0.2  Bcast:172.17.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:17 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:1963 (1.9 KiB)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
/ # ping 192.168.0.2
PING 192.168.0.2 (192.168.0.2): 56 data bytes
^Z[1]+  Stopped                    ping 192.168.0.2
如今咱們用box2訪問box1的地址,由於屬於不通網段,看似是不能相互訪問的,咱們能夠經過把核心轉發功能開啓並關閉iptables阻斷虛擬橋之間訪問的規則,其實兩個容器之間是能訪問的
[root@localhost ~]# cat /proc/sys/net/ipv4/ip_forward
1
[root@localhost ~]# iptables -vnL
Chain DOCKER-ISOLATION-STAGE-1 (1 references)
 pkts bytes target     prot opt in     out     source               destination
    0     0 DOCKER-ISOLATION-STAGE-2  all  --  br-6b16879aaff2 !br-6b16879aaff2  0.0.0.0/0            0.0.0.0/0
    2   168 DOCKER-ISOLATION-STAGE-2  all  --  docker0 !docker0  0.0.0.0/0            0.0.0.0/0
    0     0 RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0
[root@localhost ~]# iptables -F
box2訪問box1IP地址
PING 192.168.0.2 (192.168.0.2): 56 data bytes
64 bytes from 192.168.0.2: seq=0 ttl=63 time=0.248 ms
64 bytes from 192.168.0.2: seq=1 ttl=63 time=0.153 ms
^Z[2]+  Stopped                    ping 192.168.0.2
/ #
發現能夠通信了
docker默認網絡信息的調整

♣五:docker的存儲卷

A:docker的存儲卷介紹:

在文章的前面咱們咱們提到了docker的聯合掛載和分層構建技術,事實上docker在啓動的時候默認會產生一個讀寫層,若是用戶對運行中的容器修改了現有的一個以存在的文件,那改文件將會從讀寫層之下的只讀層複製一個文件到讀寫層,該文件的最第一版本只讀版其實還在,只不過讀寫層中改文件的原始版本被影藏了,這種機制叫作寫時複製機制。
寫時複製這種機制在最上層讀寫層始終可見的就表明下層必定會有,可是讀寫層刪除的(標記爲刪除,其實就是影藏了),下層並不會刪除,若是層級太多,這種機制其實效率並不高,假如咱們使用了頻繁I/O的服務的時候,這種機制就會在服務自身的瓶頸之上又多了一層瓶頸,並且容器一旦被刪除,數據也就刪除了,務必會形成數據的丟失。
面對這種狀況,咱們勢必要繞過容器自己的文件系統帶來的特定機制,寫入數據在容器,存儲數據在宿主機上面,這種場景纔是可取的,簡單理解就是咱們在宿主機創建一個特定目錄,而後把容器裏面的原本要存數據的目錄給綁定到外面宿主機的特定目錄便可。其實這種場景就像是掛載技術,讓容器能夠直接訪問我宿主機的內容,同時宿主機也能給容器提供內容,兩者是相互的。
這種場景不只僅能夠運用於容器和宿主機之間的數據讀寫,還能夠經過宿主機的牽線搭橋,讓在同一個宿主機上的多個容器實現必定程度上的文件內容共享。
在docker容器中,宿主機被綁定的目錄咱們就叫作volume(存儲卷),存儲卷帶來的好處是顯而易見的,當容器被刪除,咱們也不用擔憂數據丟失了,及時容器被刪除,咱們也能夠執行幾條命令就能把數據個容器服務再次關聯上保證服務運行。
存儲數據的週期不會受到容器的週期影響了,可是咱們在建立容器的時候不可能每次都能嚴格按照必定順序,必定的命令把容器和存儲卷關聯上,萬一執行的命名少了參數,帶來的後果是極爲嚴重的,全部咱們仍是須要容器的編排工具來完成這種事情,提早編排出來存到一個文件中,容器啓動的時候去讀取文件,減小人爲出現的錯誤。
咱們在把場景擴展下,假如咱們宿主機使用的是共享存儲文件系統如nfs,這樣咱們宿主機至上的容器在關聯目錄的時候就是關聯的nfs的之上的目錄,這樣咱們的容器就不侷限於在那臺機器上運行了。
在實際的運用中,很大一塊其實不是在解決上層的服務搭建優化的事情上,不少時間咱們都須要面臨數據的高效,可持續,動態伸縮,可遷移,負載均衡化等種種問題,及時到目前也沒有一種程序或者軟件能很好解決此類問題,就像搭建房子同樣,地基就已經決定了上層建築的高度和合理性,因此在將來的企業必然會慢慢走向雲服務化,而云也將加速對此前短板的補齊。
存儲卷會在容器啓動的時候建立,並不須要特定的去建立,存儲卷的初衷也是獨立於容器的生命週期而存在的,所以刪除容器不會刪除卷,可是能夠經過特定的命令在刪除容器的一併刪除卷。

B:docker的存儲卷的相關操做:

docker兩種類型的存儲卷:
1:bind mount volume(綁定掛載卷),這種形式的存儲卷鬚要在宿主機和容器上分別建立指定的路徑,而後將兩者創建關聯關係
2:docekr-managed volume(docker管理卷),這種形式的存儲卷指須要在容器裏面建立一個目錄,而宿主機不須要建立關聯目錄,docker會經過daemon自行建立一個空文件目錄或者一個已知的目錄來創建關聯關係,這個自行建立的目錄下文件的名稱會以容器的id號來做爲文件名稱,增長了目錄的耦合關係,可是咱們就不能指定路徑和目錄了,不能指定目錄的話,也就意味這容器被刪除了,再建立的時候你仍是得用綁定掛載卷。否則容器又會自行生成一個存數據的文件,這樣你的數據就變兩段了
在docker中使用存儲卷:

[root@localhost ~]# docker run -it --name box1 -v /date(這裏的路徑指定的是容器裏面的路徑) buxybox:latest
[root@localhost ~]# docker run --name box1 -it -v /dbfile busybox:latest
/ # ls
bin     dbfile  dev     etc     home    proc    root    sys     tmp     usr     var
/ #
咱們怎麼知道宿主機上存儲數據的路徑了,能夠docker inspect box1看下
[root@localhost ~]# docker inspect box1
.....
"Mounts": [
            {
                "Type": "volume",
                "Name": "168e18da86a32c77453d4bb7c96537b0d2c31c55d75bc4a1c400b1c676a1a421", 卷的名稱
                "Source": "/var/lib/docker/volumes/168e18da86a32c77453d4bb7c96537b0d2c31c55d75bc4a1c400b1c676a1a421/_data",  
                 此路徑就是宿主機存儲數據的路徑,能夠看到容器的id就是文件名
                "Destination": "/dbfile",  目標路徑
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
......
 ],
            "ArgsEscaped": true,
            "Image": "busybox:latest",
            "Volumes": {
                "/dbfile": {}  在容器裏面咱們建立了dbfile路徑
            },
.........

[root@localhost docker]# pwd
/var/lib/docker
[root@localhost docker]# tree volumes/  能夠看到路徑下的目錄結構
volumes/
├── 168e18da86a32c77453d4bb7c96537b0d2c31c55d75bc4a1c400b1c676a1a421
│   └── _data
└── metadata.db
咱們直接在這個路徑下建立一個文件,看看容器裏面能不能看到
[root@ _data]# echo "hello docker.volums" >> index.html
[root@ _data]# ls
index.html
[root@ _data]#
/ # cat dbfile/index.html
hello docker.volumes  能夠看到咱們剛纔添加的內容
/ # echo "dbfile" >> /dbfile/index.html  咱們在容器裏面加一個數據
/ # cat dbfile/index.html
hello docker.volumes
dbfile
/ #
[root@ _data]# cat index.html
hello docker.volumes
dbfile   在宿主機上也是能看到的
[root@ _data]#
docekr-managed volume(docker管理卷)
[root@localhost ~]# docker run -it --name box1 -v /home/date(宿主機路徑): /date(容器路徑) busybox:latset
[root@ ~]# docker run --name box2 -it --rm -v /date/volumes/box2:/htmlfile busybox:latest
/ # ls
bin       dev       etc       home      htmlfile  proc      root      sys       tmp       usr       var
/ # cd htmlfile/
/htmlfile # ls
/htmlfile # echo "hello docker.volumes" >> index.html
/htmlfile # cat index.html
hello docker.volumes
/htmlfile # cat index.html
hello docker.volumes
dbfile
/htmlfile #
[root@ /]# cd /date/volumes/box2/  能夠看到效果是同樣的,並且這個路徑是自動建立的
[root@ box2]# ls
index.html
[root@ box2]# cat index.html
hello docker.volumes
[root@ box2]# echo "dbfile" >> index.html
[root@ box2]# cat index.html
hello docker.volumes
dbfile
[root@ box2]#
咱們把容器結束掉,在看下文件是否還在

[root@ ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
[root@ ~]# cat /date/volumes/box2/index.html   能夠看到文件是具有持久存儲數據的能力的
hello docker.volumes 
dbfile
[root@ ~]# docker run --name box3 -it --rm -v /date/volumes/box2:/htmlfile busybox:latest  咱們在建立一個新的容器,把文件路徑指向到以前容器路徑下去,能夠看到數據仍是能被新容器讀取的。
/ # cat /htmlfile/index.html
hello docker.volumes
dbfile
/ #

[root@ ~]# docker run --name box4 -it --rm -v /date/volumes/box2:/1/2/ busybox:latest 並且咱們換容器裏面的路徑仍是能夠繼續訪問宿主機存儲的數據
/ # cat /1/2/index.html
hello docker.volumes
dbfile
/ #

咱們將兩個宿主機上的兩個容器都指向一個宿主機的同一個文件
[root@localhost box2]#  docker run --name box3 -it --rm -v /date/volumes/box2:/logfile busybox:latest
/ # cat logfile/index.html
hello docker.volumes
dbfile
/ # echo "mybusybox" >> /logfile/index.html
/ #
[root@localhost ~]# docker run --name box1 -it --rm -v /date/volumes/box2:/dbfile busybox:latest
/ # cat dbfile/index.html
hello docker.volumes
dbfile
/ # cat dbfile/index.html
hello docker.volumes
dbfile
mybusybox
/ #
bind mount volume(綁定掛載卷)
在docker中,若是咱們想查看容器的相關信息,能夠使用go模板來過濾相關信息
[root@ volumes]# docker inspect -f  {{.Mounts}} box4   例如咱們過濾卷相關的信息,-f 而後{}這個最外層的括號是引用模板的固定格式
[{bind  /date/volumes/box2 /1/2   true rprivate}]
[root@ volumes]# docker inspect -f  {{.NetworkSettings.Gateway}} box4
172.17.0.1
[root@ volumes]#由於使用了go語言,必然支持循環判斷等條件
go模板的簡單使用
啓動時候加上--volumes-from
[root@localhost box2]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
90f3a89a53c7        busybox:latest      "sh"                About an hour ago   Up About an hour                        box3
810de9a7256e        busybox:latest      "sh"                About an hour ago   Up About an hour                        box1
[root@localhost box2]# docker run --name box5 -it --rm --volumes-from box3  busybox:latest   咱們在執行的時候直接指定複製box3的卷
/ # ls
bin      dev      etc      home     logfile  proc     root     sys      tmp      usr      var
/ # cat logfile/index.html
hello docker.volumes
dbfile
mybusybox
/ #
這樣咱們在規劃中咱們就能夠提早建立一個已經最底層的持久化存儲的容器,讓其它須要使用到卷的容器取複製規劃好的容器存儲卷便可,咱們還能夠在這個提早建立的最底層容器的時候建立共享的網絡,這樣咱們能夠完成更加複雜的場景。
複製使用其它容器的卷

咱們可以使用到這麼多場景了,可是要去實現大量的複製類的操做或很不方便,這個時候就須要用到容器編排工具,在docker中能夠使用docker-compose工具,這個工具只能編排單機,可是docker-compose也存在優點就是能幫你建立容器,你能夠把建立容器的指令都給寫到裏面去。

♣六:dockerfile詳解

A:dockerfile基礎:

在docker啓動的時候咱們是從dockerhub上拖下來的鏡像到本地啓動的,咱們在啓動以前也沒有調整過任何的服務的配置文件,這致使咱們容器啓動的時候服務默認的配置等都是dockerhub給定義好的,那若是是要修改配置文件的話,咱們以前也用過docker exec命令的操做,在容器啓動以後,經過命令再去改一些文件內容,改好以後在從新加載,這種場景和咱們在宿主機上的操做就一致了,固然還能夠運用存儲卷的功能,把配置文件存在咱們宿主機本地,讓容器啓動的時候去加載,即便這樣你也避免不了修改配置文件以後要重啓的操做,再不行咱們本身作鏡像,你依然仍是面臨這個問題,並且仍是這三種裏面最不方便的一種,若是環境多,要求的服務版本和配置還各不相同,你可能要爲此作大量的不一樣鏡像版本。

那在docker中是怎麼解決這事情的了,這個和ansible的templates相似,咱們把服務的配置文件拿過來存一個模板,存到一個路徑下,而後咱們把配置文件須要按照環境調整的項用環境變量的形式來指定,這樣咱們在容器內部就能夠使用環境變量的形式給容器裏面運行的服務進行傳參了,docker畢竟不是ansible,容器在啓動的一瞬間必然須要配置文件,配置文件咱們經過存儲卷的形式放在外面,docker去加載的時候變量值怎麼傳給容器了,首先咱們在容器主進程啓動以前先啓動一個其它的程序,這個程序就負責把用戶傳參給賦值到變量上,用戶沒有傳值的話就使用默認值,而後保存到模板配置文件中,最後咱們能夠使用exec把當前進程替換成所須要運行的進程便可。
經過變量的形式,咱們就能夠在不一樣的環境上去自定義咱們容器啓動的配置了。

環境變量的格式和咱們系統的環境變量相似:

$環境變量名=給變量賦予的指
$環境變量名=默認值(這裏咱們能夠使用一個字符串來去指定默認值,若是變量沒有指咱們就用默認值,變量有指就用變量的指)
[root@localhost ~]# echo ${NAME:-hello}
hello
[root@localhost ~]# NAME=docker
[root@localhost ~]# echo ${NAME:-hello}
docker
[root@localhost ~]#與之相反的就是+號,變量有指的話就用加號後面的指,沒有指就爲空,這個能夠用於判斷變量是否爲空來使用
[root@localhost ~]# echo ${NAME:+hello}
hello
[root@localhost ~]# unset NAME
[root@localhost ~]# echo ${NAME:+hello}

[root@localhost ~]#
$環境變量名=給變量賦予的指

B:dockerfile的語法格式:

dockerfile是一個指令的集合,能夠經過命令行去調用配置文件從而產生一個鏡像,dockerfile的指令也是dockerfile本身的指令,並非咱們以前使用的docker的指令,咱們只須要弄清楚dockerfile的語法格式和邏輯就能使用dockerfile。

整個dockerfile語法格式就兩種:
1:註釋信息
2:由instruction開頭後面接參數組成一條指令。
instruction自身是不區分大小寫的,可是建議仍是使用大寫。
dockerfile是按照指令順序來執行的,因此有指令依賴的狀況就須要規劃好順序了
在dockerfile中除了註釋行,整個文件的第一行應該是FROM指令,用來定義dockerfile製做的鏡像是基於那個基礎鏡像,因此說dockerfile在製做鏡像的時候必要的前提就是必須存在一個已知的鏡像在本地。
dockerfile的工做邏輯:
1:基於dockerfile來作鏡像的話必須指定一個專門的工做目錄,而後在指定的工做目錄建立或者把以前處理好的dockerfile給放到這個文件目錄裏面,並且dockerfile首字母必須大寫。
2:若是dockerfile須要打包不少鏡像所使用到的文件必須是在此目錄和此目錄之下的目錄,不能是上層目錄,否則dockerfile會找不到。
假如咱們基於dockerfile來作的鏡像,目錄下面有不少文件,其中有些是咱們用不到或者不多不多用到的,dockerfile還支持隱藏文件,當咱們遇到此類文件咱們能夠寫到.dockeringore裏面去,當dockerfile只要讀到包含在.dockeringore文件裏面記錄的路徑下文件就會自動給過濾掉,這樣能夠使得咱們在docker啓動的時候能夠少下載一些文件,節省資源。
dockerfile製做完成以後咱們能夠經過docker build來讀取dockerfile文件從而來製做鏡像,最後打好標籤推導倉庫裏面咱們就能夠使用了。
其實docker build使用的也只不過是和咱們以前啓動容器以後連進去再去修改一些參數以後保存爲鏡像的方式同樣的,咱們以前製做容器的時候指不過須要啓動一個可見的容器,而後基於可寫層來製做,docker build也會啓動一個容器,只不過是隱藏了不可見而已。還有就是咱們編輯容器可寫層時候是基於容器自帶指令去編輯的,並非宿主機自帶的指令,好比你要在容器執行一個tree命令,你是須要本身裝包才能實現的,全部只要容器支持,咱們就能夠在dockerfile裏面編寫shell命令,反過來講就是基於製做的鏡像不支持shell命令,你想在以後基於這個不支持shell命令的容器來寫一些shell命令是作不到的。

C:dockerfile的指令詳解:

FROM指令:from指令是dockerfile開篇非註釋的第一行,用於爲鏡像文件構建過程指定鏡像文件,能夠簡單理解爲模板鏡像文件的指定,若是docker build在去執行的時候發現本地沒有可用的鏡像就回去你指定的鏡像站點切拉鏡像下來。好比dockerhub,若是始終找不到docker build就會報錯。
  FROM 倉庫名 [鏡像名:鏡像標籤]
  鏡像標籤省略的話默認使用latest標籤的鏡像
  FROM 倉庫名@哈希碼(這個碼就和咱們下載工具包的時候的md5同樣,防止鏡像被篡改過)
MAINTANIER:這個是用於當dockerfile製做者提供我的詳細信息,不過已經廢棄了,取代的是LABEL的指令。
  MAINTANIER"名稱+聯繫郵箱等"
  MAINTANIER能夠出如今dockerfile的任何位置,可是建議在FROM以後
LABEL:也是用於dockerfile製做者信息的建立,可是格式已經有明顯區別。
  LABEL<key>=<value><key>=<value>
  已經修改爲鍵值對的形式,這樣能夠存入跟多信息
COPY: 用於從docker主機複製文件至建立的新鏡像像文件
  COPY str源文件(能夠多個) dest爲那個目標文件
  COPY [str源文件(能夠多個) dest爲那個目標文件] 列表形式,這種格式主要能夠避免空白字符等特殊狀況,避免出現歧義
  str:要複製的源文件或目錄,支持通配符,使用相對路徑
  dest:目標路徑,即生成文件的目標鏡像文件所在的目錄,使用絕對路徑,不然,須要用到WORKDIR命令
COPY的複製準則:
  src必須是build上下文中的路徑,不能是父目錄中的文件
  若是src自己是目錄,他會遞歸的把起內部的文件或者子目錄所有複製,就相似咱們cp -r的操做,可是src自己不會複製。
  如指定了多個src或者在src裏面使用的通配符,則dest必須是一個目錄,並且必須/結尾,不加/就是語法錯誤
  若是dest事先不存在,它會被自動建立,還包括父目錄路徑

[root@localhost docker-conf-flie]# cat Dockerfile
#Explain:This is a test image!
FROM busybox:latest
LABEL url=www.baidu.com
COPY index.html /home/www/html/  指定容器的文件在哪裏取

[root@localhost docker-conf-flie]# cat index.html  咱們定義文件內容
Busybox httpd.server
[root@localhost docker-conf-flie]# tree
.
├── Dockerfile
└── index.html  只要是dockerfile用到的文件,在dockerfile平級或者在dockerfile平級目錄之下才行,除此以外,任何地方都不行的

0 directories, 2 files
[root@localhost docker-conf-flie]# docker build -h
Flag shorthand -h has been deprecated, please use --help

Usage:  docker build [OPTIONS] PATH(路徑) | URL | -

Build an image from a Dockerfile

Options:
      --add-host list           Add a custom host-to-IP mapping (host:ip)
      --build-arg list          Set build-time variables
      --cache-from strings      Images to consider as cache sources
      --cgroup-parent string    Optional parent cgroup for the container
      --compress                Compress the build context using gzip
      --cpu-period int          Limit the CPU CFS (Completely Fair Scheduler) period
      --cpu-quota int           Limit the CPU CFS (Completely Fair Scheduler) quota
  -c, --cpu-shares int          CPU shares (relative weight)  限制使用多少cpu
      --cpuset-cpus string      CPUs in which to allow execution (0-3, 0,1)
      --cpuset-mems string      MEMs in which to allow execution (0-3, 0,1)
      --disable-content-trust   Skip image verification (default true)
  -f, --file string             Name of the Dockerfile (Default is 'PATH/Dockerfile')
      --force-rm                Always remove intermediate containers
      --iidfile string          Write the image ID to the file
      --isolation string        Container isolation technology
      --label list              Set metadata for an image
  -m, --memory bytes            Memory limit 限制使用多大內存
      --memory-swap bytes       Swap limit equal to memory plus swap: '-1' to enable unlimited swap
      --network string          Set the networking mode for the RUN instructions during build (default "default")
      --no-cache                Do not use cache when building the image
      --pull                    Always attempt to pull a newer version of the image
  -q, --quiet                   Suppress the build output and print image ID on success
      --rm                      Remove intermediate containers after a successful build (default true)
      --security-opt strings    Security options
      --shm-size bytes          Size of /dev/shm 打標籤
  -t, --tag list                Name and optionally a tag in the 'name:tag' format
      --target string           Set the target build stage to build.
      --ulimit ulimit           Ulimit options (default [])
[root@localhost docker-conf-flie]# docker build -t busyboxhttpd(倉庫名):v0.1(標籤) ./(目錄,咱們指定的當前目錄)
Sending build context to Docker daemon  3.072kB
Step 1/3 : FROM busybox:latest
 ---> d8233ab899d4
Step 2/3 : LABEL url=www.baidu.com  咱們定義的製做鏡像的相關信息
 ---> Running in 39b61095dd5d
Removing intermediate container 39b61095dd5d
 ---> 2d5e9326ad41
Step 3/3 : COPY index.html /home/www/html/
 ---> ce593c489324
Successfully built ce593c489324
Successfully tagged busyboxhttpd:v0.1  告知鏡像的名稱叫什麼
[root@localhost docker-conf-flie]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
busyboxhttpd        v0.1                ce593c489324        About a minute ago   1.2MB  
busybox             latest              d8233ab899d4        5 weeks ago          1.2MB
[root@localhost docker-conf-flie]#能夠看到咱們製做好的鏡像
[root@localhost docker-conf-flie]# docker run --name boxhttpd01 --rm busyboxhttpd:v0.1 cat /home/www/html/index.html
咱們能夠在容器執行命令的時候接上指定的參數便可查看容器的某些內容
Busybox httpd.server  能夠看到咱們的dockerfile的內容已經被寫到容器裏面去了
[root@localhost docker-conf-flie]#
COPY命令案例1(拷貝單個文件)
[root@localhost /]# pwd
/
[root@localhost /]# tree date/
date/
└── volumes
    └── box2
        ├── index2.html
        └── index.html

2 directories, 2 files
[root@localhost /]# cp -r date /docker-conf-flie/
[root@localhost docker-conf-flie]# ll
總用量 8
drwxr-xr-x. 3 root root  21 3月  22 20:00 date
-rw-r--r--. 1 root root 108 3月  22 19:34 Dockerfile
-rw-r--r--. 1 root root  22 3月  22 19:33 index.html
[root@localhost docker-conf-flie]# tree date/
date/
└── volumes
    └── box2
        ├── index2.html
        └── index.html

2 directories, 2 files
[root@localhost docker-conf-flie]# cat Dockerfile
#Explain:This is a test image!
FROM busybox:latest
LABEL url=www.baidu.com
COPY index.html /home/www/html/
COPY date /home/date/  
此處注意的點就是拷貝的date目錄屬於父目錄,因此說父目錄是不會被拷貝的,若是你要保證被拷貝的目錄是你未來就要使用的目錄名,那須要本身指定下目錄名,由於他只會拷貝date下的文件或目錄
[root@localhost docker-conf-flie]# docker build -t busyboxhttpd:v0.2 ./
Sending build context to Docker daemon  6.656kB
Step 1/4 : FROM busybox:latest
 ---> d8233ab899d4
Step 2/4 : LABEL url=www.baidu.com
 ---> Using cache
 ---> 2d5e9326ad41
Step 3/4 : COPY index.html /home/www/html/
 ---> Using cache
 ---> ce593c489324
Step 4/4 : COPY date /home/date/
 ---> 0b6fa719a6bf
Successfully built 0b6fa719a6bf
Successfully tagged busyboxhttpd:v0.2
[root@localhost docker-conf-flie]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
busyboxhttpd        v0.2                0b6fa719a6bf        8 seconds ago       1.2MB
busyboxhttpd        v0.1                ce593c489324        29 minutes ago      1.2MB
busybox             latest              d8233ab899d4        5 weeks ago         1.2MB
[root@localhost docker-conf-flie]# docker run --name boxhttpd2 --rm busyboxhttpd:v0.2 ls /home/date
volumes
[root@localhost docker-conf-flie]# docker run --name boxhttpd2 --rm busyboxhttpd:v0.2 tree /home/date  
docker: Error response from daemon: OCI runtime create failed: container_linux.go:344: starting container process caused "exec: \"tree\": executable file not found in $PATH": unknown.
這個就是以前咱們說你的容器裏面沒有安裝一些包,有些命令是沒有辦法用的,因此說你docker執行的命令是你在docker容器裏面環境所帶來的命令
[root@localhost docker-conf-flie]# docker run --name boxhttpd2 --rm busyboxhttpd:v0.2 ls /home/date/volumes/box2
index.html
index2.html
[root@localhost docker-conf-flie]#
COPY指令案例2(拷貝目錄)

ADD指令:ADD指令相似COPY指令,ADD支持使用tar(壓縮包)文件和URL路徑,當遇到源文件是tar包的時候,build會自動幫忙解壓成目錄,可是這個tar必須是 本地的tar包,url網絡形式tar包是不會自動解壓的。
  ADD src .. .. dest
  ADD ["src" .. .. "dest"]
  至於準則就和COPY同樣了

[root@localhost docker-conf-flie]# cat Dockerfile
#Explain:This is a test image!
FROM busybox:latest
LABEL url=www.baidu.com
COPY index.html /home/www/html/
COPY date /home/date/
ADD http://mirrors.shu.edu.cn/apache/tomcat/tomcat-8/v8.5.39/bin/apache-tomcat-8.5.39.tar.gz /home/tomcat/ 
咱們在tomcat官網下載tomcat的包放在咱們的容器之中,並且/home/下是沒有tomcat這個目錄的
[root@localhost docker-conf-flie]# docker build -t busyboxhttpd:v0.3 ./
Sending build context to Docker daemon  6.656kB
Step 1/5 : FROM busybox:latest
 ---> d8233ab899d4
Step 2/5 : LABEL url=www.baidu.com
 ---> Using cache
 ---> 2d5e9326ad41
Step 3/5 : COPY index.html /home/www/html/
 ---> Using cache
 ---> ce593c489324
Step 4/5 : COPY date /home/date/
 ---> Using cache
 ---> 0b6fa719a6bf
Step 5/5 : ADD http://mirrors.shu.edu.cn/apache/tomcat/tomcat-8/v8.5.39/bin/apache-tomcat-8.5.39.tar.gz /home/tomcat/
Downloading [==================================================>]  9.672MB/9.672MB 能夠看到這個是連到了url上下載了文件
 ---> 87e5583fdad9
Successfully built 87e5583fdad9
Successfully tagged busyboxhttpd:v0.3

[root@localhost docker-conf-flie]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
busyboxhttpd        v0.3                87e5583fdad9        2 minutes ago       10.9MB
busyboxhttpd        v0.2                0b6fa719a6bf        24 minutes ago      1.2MB
busyboxhttpd        v0.1                ce593c489324        About an hour ago   1.2MB
busybox             latest              d8233ab899d4        5 weeks ago         1.2MB
[root@localhost docker-conf-flie]# docker run --name boxhttpd03 --rm busyboxhttpd:v0.3 ls /home/tomcat/
apache-tomcat-8.5.39.tar.gz
能夠看到並無幫咱們解壓
[root@localhost docker-conf-flie]#
ADD在url上下載tar包案例
[root@localhost docker-conf-flie]# wget https://memcached.org/files/memcached-1.5.12.tar.gz 
咱們去找一個tar包先存在本地,看看是否是會自動幫咱們解壓
--2019-03-22 20:45:01--  https://memcached.org/files/memcached-1.5.12.tar.gz
正在解析主機 memcached.org (memcached.org)... 107.170.231.145
正在鏈接 memcached.org (memcached.org)|107.170.231.145|:443... 已鏈接。
已發出 HTTP 請求,正在等待迴應... 200 OK
長度:457719 (447K) [application/octet-stream]
正在保存至: 「memcached-1.5.12.tar.gz」

100%[================================================================================================================>] 457,719     38.3KB/s 用時 12s

2019-03-22 20:45:14 (38.3 KB/s) - 已保存 「memcached-1.5.12.tar.gz」 [457719/457719])

[root@localhost docker-conf-flie]# ls
date  Dockerfile  index.html  memcached-1.5.12.tar.gz
[root@localhost docker-conf-flie]# cat Dockerfile
#Explain:This is a test image!
FROM busybox:latest
LABEL url=www.baidu.com
COPY index.html /home/www/html/
COPY date /home/date/
ADD memcached-1.5.12.tar.gz /home/memcached/
[root@localhost docker-conf-flie]# docker build -t busyboxhttpd:v0.4 ./
Sending build context to Docker daemon  464.9kB
Step 1/5 : FROM busybox:latest
 ---> d8233ab899d4
Step 2/5 : LABEL url=www.baidu.com
 ---> Using cache
 ---> 2d5e9326ad41
Step 3/5 : COPY index.html /home/www/html/
 ---> Using cache
 ---> ce593c489324
Step 4/5 : COPY date /home/date/
 ---> Using cache
 ---> 0b6fa719a6bf
Step 5/5 : ADD memcached-1.5.12.tar.gz /home/memcached/
 ---> 1240b10a4851
Successfully built 1240b10a4851
Successfully tagged busyboxhttpd:v0.4
[root@localhost docker-conf-flie]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
busyboxhttpd        v0.4                1240b10a4851        29 seconds ago      3.12MB
busyboxhttpd        v0.3                87e5583fdad9        13 minutes ago      10.9MB
busyboxhttpd        v0.2                0b6fa719a6bf        34 minutes ago      1.2MB
busyboxhttpd        v0.1                ce593c489324        About an hour ago   1.2MB
busybox             latest              d8233ab899d4        5 weeks ago         1.2MB
[root@localhost docker-conf-flie]# docker run --name boxhttpd04 --rm  busyboxhttpd:v0.4 ls /home/memcached/
memcached-1.5.12
能夠看到已經解壓
[root@localhost docker-conf-flie]# docker run --name boxhttpd04 --rm  busyboxhttpd:v0.4 ls /home/memcached/memcached-1.5.12
AUTHORS
COPYING
ChangeLog
INSTALL
LICENSE.bipbuffer
Makefile.am
Makefile.in
NEWS
......
ADD解壓本地tar包案例

WORKDIR:用於指定dockerfile全部的run,cmd,entrypolnt,copy和add設定工做目錄
  WORKDIR: 路徑
  能夠指定屢次,可是指定的目錄只會影響到WORKDIR只會的指令

[root@localhost docker-conf-flie]# cat Dockerfile
#Explain:This is a test image!
FROM busybox:latest
LABEL url=www.baidu.com
COPY index.html /home/www/html/
COPY date /home/date/
WORKDIR /home/memcached/  咱們指定add的工做目錄是/home/memcached/
ADD memcached-1.5.12.tar.gz ./1.5/  add以後的路徑咱們就不須要指定了,由於這個當前目錄就是WORKDIR來指定了,可是咱們仍是能夠單獨加目錄的
[root@localhost docker-conf-flie]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
busyboxhttpd        v0.4                1240b10a4851        18 minutes ago      3.12MB
busyboxhttpd        v0.3                87e5583fdad9        31 minutes ago      10.9MB
busyboxhttpd        v0.2                0b6fa719a6bf        About an hour ago   1.2MB
busyboxhttpd        v0.1                ce593c489324        About an hour ago   1.2MB
busybox             latest              d8233ab899d4        5 weeks ago         1.2MB
[root@localhost docker-conf-flie]# docker build -t busyboxhttpd:v0.5 ./
Sending build context to Docker daemon  464.9kB
Step 1/6 : FROM busybox:latest
 ---> d8233ab899d4
Step 2/6 : LABEL url=www.baidu.com
 ---> Using cache
 ---> 2d5e9326ad41
Step 3/6 : COPY index.html /home/www/html/
 ---> Using cache
 ---> ce593c489324
Step 4/6 : COPY date /home/date/
 ---> Using cache
 ---> 0b6fa719a6bf
Step 5/6 : WORKDIR /home/memcached/
 ---> Running in 6da5b7ea24e2
Removing intermediate container 6da5b7ea24e2
 ---> 0fe647ebdf19
Step 6/6 : ADD memcached-1.5.12.tar.gz ./1.5/
 ---> f63491ffb75f
Successfully built f63491ffb75f
Successfully tagged busyboxhttpd:v0.5
[root@localhost docker-conf-flie]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
busyboxhttpd        v0.5                f63491ffb75f        7 seconds ago       3.12MB
busyboxhttpd        v0.4                1240b10a4851        19 minutes ago      3.12MB
busyboxhttpd        v0.3                87e5583fdad9        32 minutes ago      10.9MB
busyboxhttpd        v0.2                0b6fa719a6bf        About an hour ago   1.2MB
busyboxhttpd        v0.1                ce593c489324        About an hour ago   1.2MB
busybox             latest              d8233ab899d4        5 weeks ago         1.2MB
[root@localhost docker-conf-flie]# docker run --name boxhttpd05 --rm busyboxhttpd:v0.5 ls /home/memcached/1.5/
memcached-1.5.12
[root@localhost docker-conf-flie]#
WORKDIR案例

VOLUME:在鏡像中直接定義好卷在宿主機的那個路徑,可是要知道在dockerfile下的卷是docker管理的卷,這個能夠參照以前的容器卷。
  VOLUME 掛載點
  VOLUME ["掛載點"]

[root@localhost docker-conf-flie]# cat Dockerfile
#Explain:This is a test image!
FROM busybox:latest
LABEL url=www.baidu.com
COPY index.html /home/www/html/
COPY date /home/date/
WORKDIR /home/memcached/
ADD memcached-1.5.12.tar.gz ./1.5/
VOLUME /home/mysql/

[root@localhost docker-conf-flie]# docker build -t busyboxhttpd:v0.6 ./
Sending build context to Docker daemon  464.9kB
Step 1/7 : FROM busybox:latest
 ---> d8233ab899d4
Step 2/7 : LABEL url=www.baidu.com
 ---> Using cache
 ---> 2d5e9326ad41
Step 3/7 : COPY index.html /home/www/html/
 ---> Using cache
 ---> ce593c489324
Step 4/7 : COPY date /home/date/
 ---> Using cache
 ---> 0b6fa719a6bf
Step 5/7 : WORKDIR /home/memcached/
 ---> Using cache
 ---> 0fe647ebdf19
Step 6/7 : ADD memcached-1.5.12.tar.gz ./1.5/
 ---> Using cache
 ---> f63491ffb75f
Step 7/7 : VOLUME /home/mysql/
 ---> Running in 84178a58f6ba
Removing intermediate container 84178a58f6ba
 ---> 199109e83197
Successfully built 199109e83197
Successfully tagged busyboxhttpd:v0.6
[root@localhost docker-conf-flie]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
busyboxhttpd        v0.6                199109e83197        13 seconds ago      3.12MB
busyboxhttpd        v0.5                f63491ffb75f        9 minutes ago       3.12MB
busyboxhttpd        v0.4                1240b10a4851        28 minutes ago      3.12MB
busyboxhttpd        v0.3                87e5583fdad9        41 minutes ago      10.9MB
busyboxhttpd        v0.2                0b6fa719a6bf        About an hour ago   1.2MB
busyboxhttpd        v0.1                ce593c489324        2 hours ago         1.2MB
busybox             latest              d8233ab899d4        5 weeks ago         1.2MB
[root@localhost docker-conf-flie]# docker run --name boxhttpd06 --rm busyboxhttpd:v0.6 sleep 60 讓容器執行的時候停60秒
[root@localhost ~]# docker inspect -f {{.Mounts}} boxhttpd06 咱們來看下容器卷的詳細信息
[{volume 5ba8e23864423b049d6cac54d6dd19d74808b7526bb0aaa0c74ce4b372625e30 /var/lib/docker/volumes/5ba8e23864423b049d6cac54d6dd19d74808b7526bb0aaa0c74ce4b372625e30/_data /home/mysql(掛載點) local  true }]
[root@localhost ~]#
VOLUME案例

EXPOSE:爲容器打開容器指定要監聽的端口保證和外部通信,自動幫咱們生成了nat規則,可是不能幫咱們去指定那個ip去綁定,屬於動態綁定,意味着這個綁定就是宿主機的全部端口和隨機端口。
這裏的隨機端口和全部地址是由於dockerfile將來是你不肯定要放在那臺機器上面,還有將來容器的端口不必定是要暴露在外面的。
  EXPOSE port(端口 ) [protocol]
  protocol(指傳輸層協議,能夠是tcp或者udp,默認是tcp
  EXPOSE指令能夠一次指定多個端口,EXPOSE 123/udp 234/tcp

[root@localhost docker-conf-flie]# cat Dockerfile
#Explain:This is a test image!
FROM busybox:latest
LABEL url=www.baidu.com
COPY index.html /home/www/html/
COPY date /home/date/
WORKDIR /home/memcached/
ADD memcached-1.5.12.tar.gz ./1.5/
VOLUME /home/mysql/
EXPOSE 8088/tcp 9099/udp
[root@localhost docker-conf-flie]# docker build -t busyboxhttpd:v0.7 ./
Sending build context to Docker daemon  464.9kB
Step 1/8 : FROM busybox:latest
 ---> d8233ab899d4
Step 2/8 : LABEL url=www.baidu.com
 ---> Using cache
 ---> 2d5e9326ad41
Step 3/8 : COPY index.html /home/www/html/
 ---> Using cache
 ---> ce593c489324
Step 4/8 : COPY date /home/date/
 ---> Using cache
 ---> 0b6fa719a6bf
Step 5/8 : WORKDIR /home/memcached/
 ---> Using cache
 ---> 0fe647ebdf19
Step 6/8 : ADD memcached-1.5.12.tar.gz ./1.5/
 ---> Using cache
 ---> f63491ffb75f
Step 7/8 : VOLUME /home/mysql/
 ---> Using cache
 ---> 199109e83197
Step 8/8 : EXPOSE 8088/tcp 9099/udp
 ---> Using cache
 ---> 339083b60682
Successfully built 339083b60682
Successfully tagged busyboxhttpd:v0.7
[root@localhost docker-conf-flie]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
busyboxhttpd        v0.6                339083b60682        26 seconds ago      3.12MB
busyboxhttpd        v0.7                339083b60682        26 seconds ago      3.12MB
busyboxhttpd        v0.5                f63491ffb75f        12 hours ago        3.12MB
busyboxhttpd        v0.4                1240b10a4851        13 hours ago        3.12MB
busyboxhttpd        v0.3                87e5583fdad9        13 hours ago        10.9MB
busyboxhttpd        v0.2                0b6fa719a6bf        13 hours ago        1.2MB
busyboxhttpd        v0.1                ce593c489324        14 hours ago        1.2MB
busybox             latest              d8233ab899d4        5 weeks ago         1.2MB
[root@localhost docker-conf-flie]# docker run --name boxhttpd07 --rm busyboxhttpd:v0.7 /bin/httpd -f -h /home/www/html
運行以後咱們查看服務訪問狀況
[root@localhost ~]# docker inspect -f {{.NetworkSettings.IPAddress}} boxhttpd07
172.17.0.2
[root@localhost ~]# curl 172.17.0.2
Busybox httpd.server

[root@localhost ~]# docker port boxhttpd07  咱們能夠發現此時服務的端口並不會暴露對外監聽
[root@localhost docker-conf-flie]# docker run --name boxhttpd07 --rm -P busyboxhttpd:v0.7 /bin/httpd -f -h /home/www/html
咱們再次運行加上P參數,這個參數以前提到過,咱們不須要在去P參數後面指定端口了,dockerfile已經指定了。
[root@localhost ~]# docker port boxhttpd07
8088/tcp -> 0.0.0.0:32768
9099/udp -> 0.0.0.0:32768
[root@localhost ~]#能夠看到端口暴露對外監聽了
EXPOSE定義端口案例

ENV:用於爲鏡像定義所須要的環境變量,可被ENV,ADD,COPY等命令所調用
  ENV key vaiue 這種格式下key以後全部內容都會被當作value的組成部分,所以一次只能給一個變量
  ENV key=value\key=value 這種就解決了上面一次只能給一個變量的問題,經過反斜線(續行)間隔,經過一個ENV給到多個值,建議是用第二種方式
  反斜線還能對空格進行轉義

寫法1
FROM busybox:latest 
LABEL url=www.baidu.com
ENV WEBFILE /home/www/html/  若是就一個值前面是變量名後面就是指
COPY index.html $WEBFILE   在須要引用變量的地方直接$符號接上變量便可
.....
寫法2:
FROM busybox:latest
LABEL url=www.baidu.com
ENV WEBFILE /home/www/html/  若是就一個值前面是變量名後面就是指
COPY index.html ${WEBFILE:-/home/www/html/}   若是變量沒有值就用-號後面咱們定義的值,此處參考文章中變量賦值的內容
.....
寫法3:
#Explain:This is a test image!
FROM busybox:latest
LABEL url=www.baidu.com
ENV WEBFILE=/home/www/html/\  用反斜線續行寫
    MEM_EDITION="memcached-1.5.12.tar.gz" 
COPY index.html ${WEBFILE:-/home/www/html/}
COPY date /home/date/
WORKDIR /home/memcached/
ADD ${MEM_EDITION} ./1.6/
....
[root@localhost docker-conf-flie]# docker build -t busyboxhttpd:v0.8 ./
Sending build context to Docker daemon  464.9kB
Step 1/9 : FROM busybox:latest
 ---> d8233ab899d4
Step 2/9 : LABEL url=www.baidu.com
 ---> Using cache
 ---> 2d5e9326ad41
Step 3/9 : ENV WEBFILE=/home/www/html/    MEM_EDITION="memcached-1.5.12.tar.gz"
 ---> Running in 8717be855cb6
Removing intermediate container 8717be855cb6
 ---> d2728a778315
Step 4/9 : COPY index.html ${WEBFILE:-/home/www/html/}
 ---> 32f9c8bfe225
Step 5/9 : COPY date /home/date/
 ---> d154c2fc16a1
Step 6/9 : WORKDIR /home/memcached/
 ---> Running in 6059bbf44d67
Removing intermediate container 6059bbf44d67
 ---> bba487a7779e
Step 7/9 : ADD ${MEM_EDITION} ./1.6/
 ---> 2a22046822b8
Step 8/9 : VOLUME /home/mysql/
 ---> Running in 42ebc490d313
Removing intermediate container 42ebc490d313
 ---> c3d946d88690
Step 9/9 : EXPOSE 8088/tcp 9099/udp
 ---> Running in 1751ba881e93
Removing intermediate container 1751ba881e93
 ---> 34af5bf9ae82
Successfully built 34af5bf9ae82
Successfully tagged busyboxhttpd:v0.8
[root@localhost docker-conf-flie]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
busyboxhttpd        v0.8                34af5bf9ae82        16 minutes ago      3.12MB
busyboxhttpd        v0.6                339083b60682        2 hours ago         3.12MB
busyboxhttpd        v0.7                339083b60682        2 hours ago         3.12MB
busyboxhttpd        v0.5                f63491ffb75f        14 hours ago        3.12MB
busyboxhttpd        v0.4                1240b10a4851        15 hours ago        3.12MB
busyboxhttpd        v0.3                87e5583fdad9        15 hours ago        10.9MB
busyboxhttpd        v0.2                0b6fa719a6bf        15 hours ago        1.2MB
busyboxhttpd        v0.1                ce593c489324        16 hours ago        1.2MB
busybox             latest              d8233ab899d4        5 weeks ago         1.2MB
[root@localhost docker-conf-flie]# docker run --name boxhttpd08 --rm busyboxhttpd:v0.8 ls /home/memcached/1.6/
memcached-1.5.12
[root@localhost docker-conf-flie]# docker run --name boxhttpd08 --rm busyboxhttpd:v0.8 ls /home/www/html/
index.html
[root@localhost docker-conf-flie]#若是變量傳值dockerfile裏面咱們還不如直接指定,ENV加了以後咱們反而還要多寫幾行。
其實ENV的做用就在於咱們在啓動容器的時候給變量傳參,而不是在dockerfile裏面。
[root@localhost docker-conf-flie]# docker run --name boxhttpd08 --rm busyboxhttpd:v0.8 printenv 咱們查看在容器裏面的變量
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=a020c6b82d59
WEBFILE=/home/www/html/
MEM_EDITION=memcached-1.5.12.tar.gz  能夠看到這些變量已經存有了值
HOME=/root
[root@localhost docker-conf-flie]# docker run --name boxhttpd08 -e MEM_EDITION="memcached-1.6.6.tar.gz" --rm busyboxhttpd:v0.8 printenv
咱們經過-e參數能夠在鏡像初始化爲容器的時候給環境變量賦值。
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=4568f836ef4b
MEM_EDITION=memcached-1.6.6.tar.gz
WEBFILE=/home/www/html/
HOME=/root
[root@localhost docker-conf-flie]# docker run --name boxhttpd08 --rm busyboxhttpd:v0.8 ls /home/memcached/1.6/
memcached-1.5.12 
能夠看到文件並無變化,這個是由於咱們在build的時候是基於容器作鏡像,解壓的這一步其實在build的時候就已經完成了,咱們在作成的鏡像上run的時候已是新的鏡像了,解壓的文件已經在build的是造成了,run的時候再給變量賦值只不過是第二階段的事情了,不會影響build。
env在dockerfile適合用於出現反覆的目錄和文件等。
ENV定義環境變量案例

RUN:在dockerfile添加命令,讓其在build的時候去執行命令,從而製做成鏡像,這個RUN和CMD是類似的,不過執行的階段不同,RUN是build階段,CMD是run啓動容器的時候。
   RUN command

        這種格式中,command一般是一個shell命令,也就意味着先啓動的是shell進程,會以「/bin/sh -c「來運行的,這意味着此進程在容器的id不是1,不能接受uninx信號,當使用              docker stop想中止你容器裏面的程序的進程是接收不到的。

   RUN ["executanle","param1",....]

  第二種語法參數是json的數組,executanle是一個可執行程序的路徑下的命令,param1到param...爲傳遞給命令的選項和參數,此種格式下不會以/bin/sh -c來運行,直接由內核啓           動,因此這種狀況是不支持shell下的通配符等操做,例如(>,*,|)這樣的符號。

  RUN ["/bin/bash","-c","executanle","param1",....]
  若是想解決第二種不能用shell的狀況就能夠使用第三種格式

[root@localhost docker-conf-flie]# cat Dockerfile
#Explain:This is a test image!
FROM busybox:latest
LABEL url=www.baidu.com
ENV TEM_EDITION="http://mirrors.shu.edu.cn/apache/tomcat/tomcat-8/v8.5.39/bin/apache-tomcat-8.5.39.tar.gz"
在dockerfile中只要是url上下載的tar包docker是不能解壓的
ADD ${TEM_EDITION} /home/tomcat/
RUN cd /home/tomcat&&\
    tar xf *.tar.gz 咱們須要手動解壓,這個命令要注意的是dockerfile可能對咱們在命令行習慣輸入的-xf前面的橫崗不識別的問題
[root@localhost docker-conf-flie]# docker run --name boxhttpd09 --rm busyboxhttpd:v0.9 ls /home/tomcat/
apache-tomcat-8.5.39 能夠看到文件已經正常解壓
apache-tomcat-8.5.39.tar.gz
run是能夠執行多條命令的,若是有多條命令都是處理一個東西的,要保證在一行run裏面執行完畢。
只要有的run你指須要考慮你的基礎鏡像能不能支持你須要操做的命令,只要支持,那你徹底能夠按照你的要求吧鏡像調整爲你想實現的樣子。
run在製做鏡像的時候執行的命令屬於bin/sh命令,當你鏡像製做完成了,是運行的nginx,那就須要把默認運行的bin/sh改爲nginx了,而要實現這個是要經過CMD來完成的。
RUN在dockerfile裏面執行命令

CMD:在docker run容器運行啓動的時候能夠經過cmd來執行一些命令,而RUN命令是build的時候已經執行完成了,因此你想在容器運行的時候執行命令就須要
使用到CMD命令。
  爲何咱們要在dockerfile中給到CMD命令,由於咱們的一個容器只負責跑一個程序也就是和這個程序相關的進程存在便可,無需跑其它的進程來浪費容器的資源,咱們的linux啓動         以後默認就運行了sh相關的進程,咱們才能夠使用sh相關的命令,可是在容器裏面咱們也許不須要sh相關的進程存在,咱們只須要一個提供服務的nginx,redis相關的進程生效即             可,這個時候咱們就須要剝離原有的sh,讓nginx啓動的時候就爲默認的進程。能夠把容器就當作一個正常服務,正常服務運行的時候是不須要其餘的進程來參與其中的。
  CDM在dockerfile中默認只能生效一個,也就是dockerfile中最後一個CMD命令,因此說CMD即便給了屢次也只能生效最後一個。
  CMD運行在鏡像啓動爲容器的時候
  CMD command
  這種狀況和RUN的同樣,默認shell先啓動運行,可是想docker stop中止服務進程是作不到的。
  CMD ["executanle","param1",....]
  和RUN同樣
  CMD ["param1","param2",....]
  第三種和RUN須要結合ENTRYPOINT指令提供默認參數來運行。

[root@ docker-conf-flie]# cat Dockerfile
#Explain:This is a test image!
FROM busybox:latest
LABEL url=www.baidu.com
ENV WEB_HTML_FILE="/www/html/"
RUN mkdir -p $WEB_HTML_FILE &&\
    echo "hello bosybox.html" > ${WEB_HTML_FILE}/index.html  建立目錄的命令是屬於/bin/sh的,這意味着仍是須要調用/bin/sh來完成建立

CMD /bin/httpd -f -h ${WEB_HTML_FILE}
當咱們執行build以後,在啓動鏡像爲容器的時候直接執行httpd的命令,從而佔據進程標號爲1的位置,當有其餘的命令的時候爲httpd的子進程。
還須要注意的是${WEB_HTML_FILE}這個shell的環境變量,還意味着httpd啓動仍是須要/bin/sh來完成,那麼httpd仍是在只要涵蓋/bin/sh的時候的仍是/bin/sh的子進程,不過啓動以後經過cmd能夠給替換掉

[root@ docker-conf-flie]# docker run --name boxhttpd1.0 -it --rm busyboxhttpd:v1.0

咱們發現啓動容器以後不會再出現/#的符號,由於如今是處於httpd的進程,再也不是/bin/sh
[root@ ~]# docker image inspect busyboxhttpd:v1.0
......
 ],
            "Cmd": [
                "/bin/sh",
                "-c",  能夠看到cmd命令確實以/bin/sh -c來啓動了httpd
                "/bin/httpd -f -h ${WEB_HTML_FILE}"
            ],
[root@ ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS               NAMES
136e25bcd07c        busyboxhttpd:v1.0   "/bin/sh -c '/bin/ht…"能夠看到確實是以/bin/sh -c來啓動的   15 minutes ago      Up 15 minutes                                   boxhttpd1.0
1af850cc1a46        89c27a4b0cd8        "/bin/sh -c 'mkdir $…"   22 minutes ago      Exited (1) 22 minutes ago                       unruffled_dewdney
98ab876bf458        89c27a4b0cd8        "/bin/sh -c 'mkdir $…"   22 minutes ago      Exited (1) 22 minutes ago                       elastic_robinson
881b15b72bbf        busyboxhttpd:v0.9   "sh"                     2 days ago          Exited (0) 2 days ago                           boxhttpd09
[root@ ~]# docker exec -it boxhttpd1.0 /bin/sh  咱們使用exec進去的時候以/bin/sh形式來看下
/ # ps
PID   USER     TIME  COMMAND
    1 root      0:00 /bin/httpd -f -h /www/html/  能夠發現進行id爲1的就是httpd的進程,這裏保留的id是方法是方便容器可以接受unix信號,咱們能經過docker kill或者stop能中止容器,這樣咱們經過cmd就吧程序默認啓動運行時的環境給改了。
   16 root      0:00 /bin/sh   咱們exec調用/bin/sh已經淪爲httpd的子進程了
   22 root      0:00 ps
/ # cat www/html/index.html
hello bosybox.html
/ #
cmd案例1
[root@ docker-conf-flie]# cat Dockerfile
#Explain:This is a test image!
FROM busybox:latest
LABEL url=www.baidu.com
ENV WEB_HTML_FILE="/www/html/"
RUN mkdir -p $WEB_HTML_FILE &&\
    echo "hello bosybox.html" > ${WEB_HTML_FILE}/index.html

#CMD /bin/httpd -f -h ${WEB_HTML_FILE}
CMD ["/bin/httpd","-f","-h ${WEB_HTML_FILE}"]  咱們將cmd改爲json數組的形式

[root@ docker-conf-flie]# docker image inspect busyboxhttpd:v1.1
.....
 "Cmd": [
                "/bin/httpd",
                "-f",
                "-h ${WEB_HTML_FILE}"
            ],

咱們能夠看到cmd已然不是以前/bin/sh了
[root@ docker-conf-flie]# docker run --name boxhttpd1.1 -it busyboxhttpd:v1.1
WARNING: IPv4 forwarding is disabled. Networking will not work.
httpd: can't change directory to ' ${WEB_HTML_FILE}': No such file or directory
咱們在運行容器的時候就有報錯,這個是由於json格式默認不會以shell的子進程來運行,當出現-h ${WEB_HTML_FILE}會解析成爲路徑,也就會報這個路徑不存在
[root@ docker-conf-flie]# cat Dockerfile
#Explain:This is a test image!
FROM busybox:latest
LABEL url=www.baidu.com
ENV WEB_HTML_FILE="/www/html/"
RUN mkdir -p $WEB_HTML_FILE &&\
    echo "hello bosybox.html" > ${WEB_HTML_FILE}/index.html

#CMD /bin/httpd -f -h ${WEB_HTML_FILE}
CMD ["/bin/sh","-c","/bin/httpd","-f","-h ${WEB_HTML_FILE}"]
咱們手動添加指定運行的環境由/bin/sh來解析
[root@ docker-conf-flie]# docker run --name boxhttpd1.2 -it busyboxhttpd:v1.2
WARNING: IPv4 forwarding is disabled. Networking will not work.
在運行的時候容器直接退出了
[root@ docker-conf-flie]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS               NAMES
304417fbe2ef        busyboxhttpd:v1.2   "/bin/sh -c /bin/htt…"   4 seconds ago       Exited (0) 3 seconds ago                       boxhttpd1.2
能夠看到容器處於退出的狀態,至少證實咱們的dockerfile寫法是沒有錯誤的,這種狀況下咱們就須要藉助docke的logs輸出來看下究竟是什麼問題,最大的緣由應該和咱們的httpd路徑的調用方式有關。
大多數狀況下咱們的應用程序啓動若是沒有問題,/bin/sh -c也應該是不會有問題的
cmd案例2

CMD的第三種命令須要結合ENTRYPOINT來完成

ENTRYPOINT:相似cmd的功能,用於爲容器指定默認運行的程序,使得容器像是一個單獨的和執行程序。 

[root@ docker-conf-flie]# docker run --name boxhttpd1.2 -it busyboxhttpd:v1.2 ls /www/html/
WARNING: IPv4 forwarding is disabled. Networking will not work.
index.html
[root@ docker-conf-flie]#
當咱們在運行容器的時候可讓容器不運行自己在dockerfile定義好的內容,轉而使用咱們後面定義的命令來覆蓋dockerfile製做好鏡像的命令,那這樣就有訴求我不想容器運行的時候默認的命令被覆蓋,cmd是作不到的,須要使用ENTRYPOINT命令,這也是ENTRYPOINT與cmd命令的不一樣之處,ENTRYPOINT啓動的程序不會被docker run命令指定的參數所覆蓋,並且這些命令參數會被當作參數傳遞給ENTRYPOINT指定的程序。
ENTRYPOINT command
ENTRYPOINT ["executable","para1".....]

[root@localhost docker-conf-flie]# cat Dockerfile
#Explain:This is a test image!
FROM busybox:latest
LABEL url=www.baidu.com
ENV WEB_HTML_FILE="/www/html/"
RUN mkdir -p $WEB_HTML_FILE &&\
    echo "hello bosybox.html" > ${WEB_HTML_FILE}/index.html

#CMD /bin/httpd -f -h ${WEB_HTML_FILE}
#CMD ["/bin/sh","-c","/bin/httpd","-f","-h ${WEB_HTML_FILE}"]
ENTRYPOINT /bin/httpd -f -h ${WEB_HTML_FILE}

[root@ docker-conf-flie]# docker run --name boxhttpd1.3 -it --rm -P  busyboxhttpd:v1.3 ls /www/html/
WARNING: IPv4 forwarding is disabled. Networking will not work.
咱們把cmd替換成ENTRYPOINT,再去執行ls的時候發現並無出現上面的狀況,這個是由於程序默認啓動的是httpd,也就是/bin/httpd -f -h ${WEB_HTML_FILE}這一長傳的命令,而後把ls這個命令當作參數附在httpd後面,只不過httpd識別不了這個參數不會運行罷了。
然而ENTRYPOINT也是能夠被覆蓋的,能夠經過特定的選項--entrypoint就能完成,docker留有這個參數是讓用戶明確本身的操做
[root@ docker-conf-flie]# docker run --name boxhttpd1.4 -it --rm -P --entrypoint "top"  busyboxhttpd:v1.4
能夠發現--entrypoint咱們指定的top命令就覆蓋了原先的定義好的命令了
WARNING: IPv4 forwarding is disabled. Networking will not work.
Mem: 1340904K used, 522348K free, 12752K shrd, 2116K buff, 584808K cached
CPU:  0.0% usr  5.0% sys  0.0% nic 95.0% idle  0.0% io  0.0% irq  0.0% sirq
Load average: 0.00 0.01 0.05 2/408 5
  PID  PPID USER     STAT   VSZ %VSZ CPU %CPU COMMAND
    1     0 root     R     1280  0.0   2  0.0 top
[root@ docker-conf-flie]#
cmd和ENTRYPOINT在dockerfile中能定義多個,可是隻有最後一個生效。
ENTRYPOINT案例1

CMD和ENTRYPOINT混合使用:

  當CMD和ENTRYPOINT混合使用的時候,cmd默認則用於爲ENTRYPOINT提供默認參數。

  CMD ["para1","para2",.....]
  此時cmd只能是數組的格式

[root@localhost docker-conf-flie]# cat Dockerfile
#Explain:This is a test image!
FROM busybox:latest
LABEL url=www.baidu.com
ENV WEB_HTML_FILE="/www/html/"
RUN mkdir -p $WEB_HTML_FILE &&\
    echo "hello bosybox.html" > ${WEB_HTML_FILE}/index.html

#CMD /bin/httpd -f -h ${WEB_HTML_FILE}
CMD ["/bin/httpd","-f","-h ${WEB_HTML_FILE}"]
ENTRYPOINT ["/bin/sh","-c"]  
此處ENTRYPOINT只能使用數組的形式,由於ENTRYPOINT運行的時候可能會用到/bin/sh -c,若是是沒有以數組的形式的話,那就是以/bin/sh -c運行/bin/sh -c了
[root@localhost docker-conf-flie]# docker run --name boxhttpd1.4  -P busyboxhttpd:v1.5由於內部變量交叉混合應用容器是不會起來的
[root@localhost docker-conf-flie]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS               NAMES
b9d6790bbc5f        busyboxhttpd:v1.5   "/bin/sh -c /bin/htt…"   3 seconds ago       Exited (0) 2 seconds ago                       boxhttpd1.4
可是咱們能看到程序是/bin/sh -c /bin/httpd來運行的
[root@localhost docker-conf-flie]# docker inspect -f{{.Config.Cmd}} boxhttpd1.4
[/bin/httpd -f -h ${WEB_HTML_FILE}]
[root@localhost docker-conf-flie]# docker inspect -f{{.Config.Entrypoint}} boxhttpd1.4
[/bin/sh -c]
[root@localhost docker-conf-flie]# docker run --name boxhttpd1.4  -P busyboxhttpd:v1.5 "ls /www/html" 傳參的時候加雙引號避免出現錯誤
index.html
當cmd和Entrypoint同事出現的時候,cmd表明默認參數傳輸了Entrypoint了,當Entrypoint本身有參數(咱們在啓動時給的ls參數)就會覆蓋cmd的參數,而程序此時運行的ENTRYPOINT ["/bin/sh","-c"]的進程,ls也就能正常運行了。
經過上面的案例,咱們發現CMD和ENTRYPOINT混合使用的時候按照咱們運行的狀況來看ENTRYPOINT是徹底沒有必要使用的,原本能夠在cmd裏面一行寫掉的咱們反而畫蛇添足了。
cmd和entrypoint混合使用案例1
[root@localhost docker-conf-flie]# cat Dockerfile
#Explain:This is a test image!
FROM nginx:1.14-alpine
LABEL url=www.nginx.com

ENV WEB_HTML_FILE="/www/html/" 網頁存在的路徑

ADD entrypoint.sh /bin/  複製主機咱們已經寫好的entrypoint.sh腳本到鏡像裏面,給到後面的ENTRYPOINT去運行。
ADD index.html ${WEB_HTML_FILE}  複製主機的咱們寫好的網頁文件到鏡像裏面去。

CMD ["/bin/nginx","-g","daemon off;"] 咱們要運行的命令
-g標示設定全局選項。
daemon off這個是爲了讓nginx運行在前臺,daemon是守護進程,off是不要運行爲守護進程,nginx的配置文件都是分號結尾的,cmd裏面也是同樣。
ENTRYPOINT ["/bin/entrypoint.sh"]
運行add進來的entrypoint.sh腳本,可是咱們上面的案例也看到了,一旦ENTRYPOINT有了默認參數,就會覆蓋cmd要運行的命令,這個時候就須要改
咱們的entrypoint.sh腳本。
[root@localhost docker-conf-flie]# cat entrypoint.sh
#!/bin/sh   #alpine的鏡像是沒有bash的只有sh
cat > /etc/nginx/conf.d/www.conf << EOF
server {
        server_name ${HOSTNAME};
        listen ${IP:-0.0.0.0}:${PORT:-80}; :-表明默認參數
        root ${WEB_HTML_FILEI:-/usr/share/nginx/html};
}
EOF
exec "$@" 
$@表明當前腳本的全部參數,參數是什麼我就運行什麼,並且運行完成以後我還要exec退出當前進程。
1:咱們先寫一個用於初始化定義nginx運行環境的腳本,啓動定義的ip和端口,網頁的路徑等信息。
2:經過add把這個腳本拷貝進鏡像裏面,啓動爲容器以後,而後ENTRYPOINT在容器裏面運行entrypoint.sh腳本,環境初始化完成再去執行cmd的命令,並且cmd執行成功以後就會頂替sh進程從而成爲容器裏面惟一的進程。
[root@localhost docker-conf-flie]# docker run --name myweb1.1 --rm -it -P mynginxweb:v1.1啓動容器
[root@localhost docker-conf-flie]# docker exec -it myweb1.1 /bin/sh  經過從容器外面指令命令去看容器內的nginx狀況
/ # cat /www/html/index.html
Busybox nginx.server

/ # netstat -anptu
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1/nginx -g daemon o
/ # ps 能夠看到編號爲1的進程是咱們的nginx
PID   USER     TIME  COMMAND
    1 root      0:00 nginx: master process /usr/sbin/nginx -g daemon off;
    8 nginx     0:00 nginx: worker process
   32 root      0:00 /bin/sh
   37 root      0:00 ps
/ # cat /etc/nginx/conf.d/www.conf   配置文件也是咱們從外面定義好的文件
server {
        server_name 928e9855e425; 主機名是咱們的容器id,咱們也能夠經過特定的指令來完成
        listen 0.0.0.0:80;
        root /usr/share/nginx/html;
}
/ #
[root@localhost ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                   NAMES
928e9855e425        mynginxweb:v1.1     "/bin/entrypoint.sh …"   28 minutes ago      Up 28 minutes       0.0.0.0:32778->80/tcp   myweb1.1
[root@localhost ~]#
咱們將容器的運行環境用變量定義的好處就是咱們能在外面給容器傳參。
[root@localhost docker-conf-flie]# docker run --name myweb1.1 --rm -it -P -e "PORT=8088" mynginxweb:v1.1
運行容器的時候用-e選項給容器的變量傳參,固然這些環境變量名必須是在容器裏面能查到的。
/ # [root@localhost docker-conf-flie]# docker exec -it myweb1.1 /bin/sh
/ # netstat -anptu
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:8088            0.0.0.0:*               LISTEN      1/nginx -g daemon o
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1/nginx -g daemon o
/ #
[root@localhost docker-conf-flie]# docker run --name myweb1.1 --rm -it -P -e "HOSTNAME=myngixnweb1.1" mynginxweb:v1.1
[root@localhost docker-conf-flie]# docker exec -it myweb1.1 /bin/sh
/ # cat /etc/nginx/conf.d/www.conf
server {
        server_name myngixnweb1.1;
        listen 0.0.0.0:80;
        root /usr/share/nginx/html;
}
/ #
cmd和entrypoint混合使用案例2

 在dockerhub上不少服務鏡像都是使用ENTRYPOINT執行腳本接受參數以後並啓動服務的,若是想寫一個複雜的Dockerfile能夠參考dockerhub上的案例

 注:Dockerfile裏面只要用到數組類型的都要使用雙引號才行,不然會有錯誤。

USER:用於指定運行鏡像或運行Dockerflie中任何的run,cmd,ENTRYPOINT指令指令的程序的用戶名和UID
  默認狀況用戶的身份爲root
  USER uid 用戶名
  須要注意的是uid能夠是任意數字,可是這個數字必須存在容器中/etc/passwd中所存在某個有效用戶的uid,不然docker run將失敗。

[root@localhost docker-conf-flie]# docker exec -it myweb1.1 /bin/sh
/ # ps
PID   USER     TIME  COMMAND
    1 root(進程運行的用戶是root)      0:00 nginx: master process /usr/sbin/nginx -g daemon off;
    8 nginx     0:00 nginx: worker process
   32 root      0:00 /bin/sh
   37 root      0:00 ps

HEALTHCHECK:用於CMD以後接一個固定命令用來檢查咱們的主進程狀態是否正常和健康。若是不想健康狀態檢查能夠接NONE來拒絕任何狀態檢查,也包括默認的檢查機制。除此以外CMD前面還能夠接[OPTION]用於週期性的
  --intterval=DURATION(default:30s) 默認週期檢查是30s,能夠設定爲其它時間
  --timeout=DURATION(default:30s) 當咱們週期性檢查發起請求了,超過了多少時間就認爲是有問題的。
  --start-period=DURATION(default:0s) 當咱們容器啓動起來了,容器裏面的進程是須要初始化等一系列工做的,這個必然就會致使有個進程初始化時間,可是咱們的健康檢查是             隨着容器一啓動就開始了,極可能此時容器裏面的進程還在初始化,這個時候健康檢查就會認爲進程狀態異常就直接給kill掉了,那這種狀況容器就永遠起不來了,因此--start-                  period就是用來設定一個時間,等主進程初始化完成以後在進行健康檢查,若是進程啓動須要2秒,--start-period就能夠設置爲5秒以後在檢查。
  --retries=數字(default:3) 判斷一次超過多長時間就斷定不正常是不嚴謹的,--retries就是用來定義判斷次數的,能夠多設置幾回。
  當上面的檢查發起了,會返回一些狀態:
  0:success 正常的
  1:unhealthy 不正常的
  2:reserved 預留的,能夠本身定義
  例如HEALTHCHECK --intterval=5m --timeout=3s CMD curl -f http://localhost/ || exit 1(這個1就表明1:unhealthy 不正常的)

[root@localhost docker-conf-flie]# cat Dockerfile
#Explain:This is a test image!
FROM nginx:1.14-alpine
LABEL url=www.nginx.com

ENV WEB_HTML_FILE='/www/html/'

ADD entrypoint.sh /bin/
ADD index.html ${WEB_HTML_FILE}
HEALTHCHECK --start-period=5s --interval=6s CMD wget -O - -q http://${IP:-0.0.0.0}:8088/
CMD ["/usr/sbin/nginx","-g","daemon off;"]

ENTRYPOINT ["/bin/entrypoint.sh"]

[root@localhost docker-conf-flie]# docker run --name myweb1.2 --rm -P -e "PORT=8088"  mynginxweb:v1.2
127.0.0.1 - - [30/Mar/2019:06:55:23 +0000] "GET / HTTP/1.1" 200 612 "-" "Wget" "-" 能夠看到檢查是成功的,並且是每隔6秒檢查一次
127.0.0.1 - - [30/Mar/2019:06:55:29 +0000] "GET / HTTP/1.1" 200 612 "-" "Wget" "-"
127.0.0.1 - - [30/Mar/2019:06:55:35 +0000] "GET / HTTP/1.1" 200 612 "-" "Wget" "-"
127.0.0.1 - - [30/Mar/2019:06:55:41 +0000] "GET / HTTP/1.1" 200 612 "-" "Wget" "-"
[root@localhost docker-conf-flie]#
HEALTHCHECK狀態檢查

SHELL:用來定義程序運行環境的默認shell環境,若是是你的docker是在win系統上運行的話那就須要去指定運行的環境,上面咱們一直是/bin/sh -c的環境,若是你的基礎鏡像是/bin/bash這個時候就須要指定了。

STOPSIGNAL:以前咱們說容器裏面的進程執行以後能夠接收stop指令來中止,是由於docker想容器內部發了一個信號-15,這個-15就表明了中止,若是是想換其它的信號。
STOPSIGNAL 信號名,好比信號9,就等於直接kill掉了。

AGE:和ENV很類似,只要也是支持變量,可是這個變量是在build的時候去使用的,這個好處就在於咱們的Dockerfile能適應更多不一樣的環境來製做鏡像文件

[root@localhost docker-conf-flie]# cat Dockerfile
#Explain:This is a test image!
FROM nginx:1.14-alpine

ARG url="www.123.com"
LABEL maintainer="${url}"

ENV WEB_HTML_FILE='/www/html/'

ADD entrypoint.sh /bin/
ADD index.html ${WEB_HTML_FILE}
HEALTHCHECK --start-period=5s --interval=6s CMD wget -O - -q http://${IP:-0.0.0.0}:8088/
CMD ["/usr/sbin/nginx","-g","daemon off;"]

ENTRYPOINT ["/bin/entrypoint.sh"]

[root@localhost docker-conf-flie]# docker image inspect -f {{.ContainerConfig.Labels}} mynginxweb:v1.4
map[maintainer:www.321.com]  能夠看到咱們就能夠在build命令行的同時給傳參了
[root@localhost docker-conf-flie]#
AGE案例

ONBUILD:用於在Dockerfile中定義一個觸發器,這個觸發器不是在build的時候執行的,是在你build製做成鏡像以後,別人在拿你的鏡像做爲基礎鏡像來作新的鏡像的時候觸發執行,這種執行又叫延時執行。
  ONBUILD dockerfile的指令
  ONBUILD不能自我嵌套,不能觸發FROM和MAINTAINER指令
  使用包含ONBUILD指令的dockerfile構建的鏡像應該使用特殊的標籤
  ONBUILD指令中使用ADD和COPY的時候應該要注意上下文中定義的源文件是否缺失,缺失就會失敗。

[root@localhost docker-conf-flie]# cat Dockerfile
#Explain:This is a test image!
FROM nginx:1.14-alpine

ARG url="www.123.com"
LABEL maintainer="${url}"

ENV WEB_HTML_FILE='/www/html/'

ADD entrypoint.sh /bin/
ADD index.html ${WEB_HTML_FILE}
HEALTHCHECK --start-period=5s --interval=6s CMD wget -O - -q http://${IP:-0.0.0.0}:8088/
CMD ["/usr/sbin/nginx","-g","daemon off;"]
ONBUILD ADD https://sourceforge.net/projects/htop/files/latest/download /www/html/  定義一個下載的內容
ENTRYPOINT ["/bin/entrypoint.sh"]
[root@localhost docker-conf-flie]# docker run --name myweb1.5 --rm mynginxweb:v1.5 ls /www/html/
index.html
[root@localhost docker-conf-flie]#能夠看到咱們製做的鏡像啓動爲容器以後並不會去下載這個文件。
[root@localhost test]# pwd
/home/test
[root@localhost test]# cat Dockerfile  建立另一個dockerfile
FROM mynginxweb:v1.5  基礎鏡像用咱們上面定義的一個

RUN mkdir /test/
[root@localhost test]# docker build  -t test:v1.1 ./
Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM mynginxweb:v1.5
# Executing 1 build trigger
Downloading [==================================================>]  388.5kB/388.5kB  咱們在build的時候就發現有一個下載的內容
 ---> f8e5d36e5950
Step 2/2 : RUN mkdir /test/
 ---> Running in 1634f5932da8
Removing intermediate container 1634f5932da8
 ---> 22eefe8da83d
Successfully built 22eefe8da83d
Successfully tagged test:v1.1
[root@localhost test]# docker run --name test1.1 --rm test:v1.1 ls /www/html/
download
index.html
並且文件也被下載下來了。
ONBUILD案例

 若是dockerfile的裏面存在源文件,若是是你的鏡像源文件若是是ftp等公司內部的站點能夠下載到,那就很方便了,直接add下來新的鏡像就完成了,固然這種場景適合於私有鏡像。

♣七:docker的私有registy

A:docker的私有registy介紹

爲何須要私有的鏡像倉庫,是由於docker的本意就是爲了更加輕量快速的搭建起一整套的環境提供使用,若是你的鏡像文件是寄託於dockerhub之上的,那你不得不面臨pull鏡像的時候佔用大量的帶寬和時間成本,這種場景是極爲不適用於大量服務器的場景的,因此作可取的方案就是本地自建鏡像倉庫,固然你若是是用的國內的阿里雲等雲平臺,把鏡像倉庫放在雲上面也是很不錯的選擇,要保證鏡像在被pull的時候效率提升,你必須選擇就近原則。並且你還得考慮雙機熱備或者多地存放的方案,隨時應對沒必要要的故障帶來的損失。
docker爲了方便用戶建立私有的鏡像倉庫也提供了一個程序包docker-distribution,並且這個程序也被製做成了鏡像存在了duckerhub上,咱們直接pull下來啓動就能夠使用了。
咱們要製做的鏡像是基於docker-distribution容器來完成的,docker-distribution容器一旦終止,上面以前你製做的全部鏡像也就沒有了,因此docker-distribution容器必須指定一個存儲卷,這個存儲卷最好是穩定的網絡存儲,這樣等於你製做鏡像的環境隨時能夠作一些調整不至於影響製做好的鏡像,等於成品鏡像我是存到了一個穩定的存儲捲上面的。

B:docker的私有registy安裝和簡單使用

如今在dockerhub上docker-distribution的鏡像registry已經到了2.7.1的版本了,咱們直接使用本地的yum倉庫來安裝。

[root@localhost ~]# yum info docker-registry
已加載插件:fastestmirror, langpacks
Determining fastest mirrors
 * base: mirrors.aliyun.com
 * extras: mirrors.aliyun.com
 * updates: ap.stykers.moe
可安裝的軟件包
名稱    :docker-registry
架構    :x86_64
版本    :0.9.1  能夠看到registry是0.9.1的版本,可是這個版本只是registry的版本,不是docker-distribution的版本,咱們直接安裝這個版本。
發佈    :7.el7
大小    :123 k
源    :extras/7/x86_64
簡介    : Registry server for Docker
網址    :https://github.com/docker/docker-registry
協議    : ASL 2.0
描述    : Registry server for Docker (hosting/delivering of repositories and images).
[root@localhost ~]# yum -y install docker-registry
......
正在安裝:
 docker-distribution                       x86_64                       2.6.2-2.git48294d9.el7                         extras                       3.5 M
真正的docker-distribution能夠看到是2.6.2的版本,docker-distribution只不過是封裝在docker-registry,因此安裝的時候仍是要看實際的版本。
[root@localhost ~]# rpm -ql docker-distribution
/etc/docker-distribution/registry/config.yml  主配置文件。
/usr/bin/registry  主程序
/usr/lib/systemd/system/docker-distribution.service  主服務
/usr/share/doc/docker-distribution-2.6.2
/usr/share/doc/docker-distribution-2.6.2/AUTHORS
/usr/share/doc/docker-distribution-2.6.2/CONTRIBUTING.md
/usr/share/doc/docker-distribution-2.6.2/LICENSE
/usr/share/doc/docker-distribution-2.6.2/MAINTAINERS
/usr/share/doc/docker-distribution-2.6.2/README.md
/var/lib/registry  上傳全部鏡像的存儲路徑,若是是有規劃的話,這個路徑要改到一個存儲空間較大的路徑下去
[root@localhost ~]# systemctl start docker-distribution啓動服務
[root@localhost ~]# cat /etc/docker-distribution/registry/config.yml
version: 0.1
log:
  fields:
    service: registry
storage:
    cache:
        layerinfo: inmemory   緩存數據在內存空間
    filesystem:
        rootdirectory: /var/lib/registry  鏡像存儲路徑
http:  是一個http的服務
    addr: :5000 默認端口5000,前面冒號之間是沒有指明地址的表明本地全部地址
[root@localhost ~]# ss -tnl
State      Recv-Q Send-Q                                Local Address:Port                                               Peer Address:Port
LISTEN     0      128                          
docker-registry的安裝
[root@localhost ~]# docker tag mynginxweb:v1.5 localhost:5000/mynginxweb:v1.5
先給本地的鏡像打個標籤,localhost:5000由於咱們本地機器沒有域名就直接指定本地5000端口就能夠了,/mynginxweb:v1.5若是是名稱的就在斜槓後面加上名稱,沒有名稱就爲頂層倉庫。
[root@localhost ~]# docker images
REPOSITORY                  TAG                 IMAGE ID            CREATED             SIZE
test                        v1.1                22eefe8da83d        20 hours ago        16.4MB
mynginxweb                  v1.5                d15a52fae68c        20 hours ago        16MB
localhost:5000/mynginxweb   v1.5                d15a52fae68c        20 hours ago        16MB
[root@localhost ~]# docker push localhost:5000/mynginxweb:v1.5  
若是推送的時候不指定版本默認是推送mynginxweb整個鏡像,全部這個tag很重要。
The push refers to repository [localhost:5000/mynginxweb]
355b0d8dba3a: Pushed
54393d713599: Pushed
129ba078f157: Pushed
8c8f1eccd524: Pushed
68442845474f: Pushed
503e53e365f3: Pushed
v1.5: digest: sha256:3601b3c57d30876a61ef8c5b226bf091cd3ffa61b0eae50aba12a172705b67fa size: 1568
由於咱們是本地直接推,不會出現https的報錯
[root@localhost yum.repos.d]# docker tag mynginxweb:v1.5 192.168.181.134:5000/mynginxweb:v1.5
[root@localhost yum.repos.d]# docker images
REPOSITORY                             TAG                 IMAGE ID            CREATED             SIZE
test                                   v1.1                22eefe8da83d        24 hours ago        16.4MB
192.168.181.134:5000/mynginxweb        v1.5                d15a52fae68c        24 hours ago        16MB
[root@localhost yum.repos.d]# docker push 192.168.181.134:5000/mynginxweb:v1.5
The push refers to repository [192.168.181.134:5000/mynginxweb]
Get https://192.168.181.134:5000/v2/: http: server gave HTTP response to HTTPS client  
當咱們要把本地鏡像推送到另外的機器上的時候會報錯,由於咱們推送是基於docker的https協議,可是對端的機器是http的協議,用https訪問http確定會報錯,固然若是是內網的環境,無需使用https協議也是能夠改爲http的協議的
這個時候須要使用到一個參數添加到daemon.json裏面,重啓docker就能夠。
[root@localhost yum.repos.d]# cat /etc/docker/daemon.json
{
    "registry-mirrors":["https://registry.docker-cn.com"],
    "insecure-registries":["192.168.181.134:5000"]  
    經過insecure-registries參數指定私有倉庫的地址或者域名,並且這個域名或者地址必須是docker images的鏡像REPOSITORY名稱。
}
[root@localhost yum.repos.d]# docker images
REPOSITORY                             TAG                 IMAGE ID            CREATED             SIZE
test                                   v1.1                22eefe8da83d        25 hours ago        16.4MB
192.168.181.134:5000/mynginxweb        v1.5                d15a52fae68c        25 hours ago        16MB
daemon.json裏面定義的insecure-registries必須和images REPOSITORY的指一致。
[root@localhost yum.repos.d]# !1048   (用感嘆號加上history出來的指令編號就能執行相應編號的指令
docker push 192.168.181.134:5000/mynginxweb:v1.5
The push refers to repository [192.168.181.134:5000/mynginxweb]
355b0d8dba3a: Pushed
54393d713599: Pushed
129ba078f157: Pushed
8c8f1eccd524: Pushed
68442845474f: Pushed
503e53e365f3: Pushed
v1.5: digest: sha256:3601b3c57d30876a61ef8c5b226bf091cd3ffa61b0eae50aba12a172705b67fa size: 1568
能夠看到推送成功了
[root@www repositories]# ls
mynginxweb
[root@www repositories]# pwd
/var/lib/registry/docker/registry/v2/repositories
[root@www repositories]#能夠看到對端機器上/var/lib/registry/自動生成了咱們鏡像相對應名字的文件。
[root@www repositories]# cd mynginxweb/
[root@www mynginxweb]# ls
_layers(鏡像生成的層目錄,這個層就是以前的聯合掛載提到的層)  _manifests  _uploads(上傳目錄)
[root@www sha256]# pwd
/var/lib/registry/docker/registry/v2/repositories/mynginxweb/_layers/sha256
[root@www sha256]# ls
0833c98aa19af703feb3525ba6b7570c63148a9d8cf175711320281e431720dd  
389a52582f93c5d83ca4015d27b0088bd84c256f0eac34810cae4d1508a05f1c
496e2dd2b91a449fbf89d6bb7ef65a85cbab272acca2ce39827cba99e4b2b943
6c40cc604d8e4c121adcb6b0bfe8bb038815c350980090e74aa5a6423f8f82c0
76679ad9f124f838aa51b98a34af7d0fa586fba6bf5ec05d452c7a714141180b
d15a52fae68cb0b3ee2c734350046afea18f8d662a6791ac3767941f58a0fda1
f82709aa42ef56cffb4fac78bbbf03e2045faf5fe3f3bad82808bca1b251dd3c
[root@www 0833c98aa19af703feb3525ba6b7570c63148a9d8cf175711320281e431720dd]# pwd
/var/lib/registry/docker/registry/v2/repositories/mynginxweb/_layers/sha256/0833c98aa19af703feb3525ba6b7570c63148a9d8cf175711320281e431720dd
[root@www 0833c98aa19af703feb3525ba6b7570c63148a9d8cf175711320281e431720dd]# ls
link 能夠看到這是一個鏈接文件,真正的文件是在blobs/sha256下面
[root@www sha256]# ls
08  36  38  49  6c  76  d1  f8  能夠看到這每個文件的前兩位都對應_layers/sha256下一長串的文件名
[root@www sha256]# pwd
/var/lib/registry/docker/registry/v2/blobs/sha256
咱們在134機器上把咱們剛纔推送的鏡像給pull下來
[root@www home]# cat /etc/docker/daemon.json
{
    "registry-mirrors":["https://registry.docker-cn.com"],
    "insecure-registries":["192.168.181.134:5000"]  
    由於你pull也是要走網絡的,可是docker默認仍是https協議,因此想用http下載下來仍是要配置134機器daemon.json的配置文件。
}
[root@www home]# docker pull 192.168.181.134:5000/mynginxweb:v1.5  指定要pull的鏡像和具體標籤。
v1.5: Pulling from mynginxweb
6c40cc604d8e: Pull complete
76679ad9f124: Pull complete
389a52582f93: Pull complete
496e2dd2b91a: Pull complete
f82709aa42ef: Pull complete
0833c98aa19a: Pull complete
Digest: sha256:3601b3c57d30876a61ef8c5b226bf091cd3ffa61b0eae50aba12a172705b67fa
Status: Downloaded newer image for 192.168.181.134:5000/mynginxweb:v1.5
[root@www home]# docker images  能夠看到134機器也pull下來了
REPOSITORY                        TAG                 IMAGE ID            CREATED             SIZE
192.168.181.134:5000/mynginxweb   v1.5                d15a52fae68c        25 hours ago        16MB
將本地的鏡像推到自建的私有倉庫中去

若是須要參考docker官方的文檔能夠訪問https://docs.docker.com/

一個簡單的本地私有倉庫的搭建推送下載過程就完成了,固然和dockerhub官方網站不能相比,能支持搜索等功能,其實docker是能支持web。
提到私有倉庫不得不說起到的就是CNCF,爲了統一雲計算接口和相關標準,2015年7月隸屬於 Linux 基金會的雲原生計算基金會(CNCF)應運而生。談到 CNCF,首先它是一個非營利組織,致力於經過技術優點和用戶價值創造一套新的通用容器技術,推進本土雲計算和服務的發展。CNCF關注於容器如何管理而不是如何建立,由於若是沒有一個成熟的平臺去管理容器,那麼大型企業沒法真正放心接受並使用容器。

CNCF官方網站:https://www.cncf.io/
CNCF的明星項目就有k8s,Prometheus(專門爲雲原生提供實時監控的工具),這裏面就包含了一個私有倉庫服務器軟件Harbor,Harbor也是基於docker-registry來作的二次開發,加進去了不少功能,就包含了web的界面

在將來的計算機服務環境會變的愈來愈複雜,一旦複雜就須要咱們把複雜的程序拆解成不少不一樣的子母單元,衆多的子母單元或者模塊天天均可能遇到網絡抖動出現的延遲,硬件的故障,軟件的bug等等出現的一系列問題致使的服務中斷,這衆多的子母單元的關聯和問題的解決仍是運維去手動維護幾乎是不可能的,必定經過工具來完成。
當你須要快速的啓動一環境的時候須要使用k8s的編排工具,那麼環境的基礎鏡像又是要基於docker來完成,docker製做的鏡像大多數狀況下仍是存在私有的registry中,那麼私有的registry必然會用到Harbor。目前經過k8s能夠實現自動的擴縮容,問題的自動修復,灰度,金絲雀的發佈等功能部分已經能實現,那麼在將來k8s和Harbor必然會成爲主流。
Harbor在單機部署的時候會很麻煩,須要redis等程序的聯合使用,因此Harbor也是有鏡像的,並且這個鏡像是基於docker compose(單機)編排工具來完成的
https://docs.docker.com/compose/

C:Harbor安裝和簡單使用

Harbor的官網:https://goharbor.io/

github的項目網站:https://github.com/goharbor/harbor/releases

下載harbor的時候須要看下版本相關的文檔,避免依賴的環境不能知足安裝的需求。

[root@www home]# wget https://storage.googleapis.com/harbor-releases/release-1.6.0/harbor-offline-installer-v1.6.3.tgz
--2019-03-31 20:32:14--  https://storage.googleapis.com/harbor-releases/release-1.6.0/harbor-offline-installer-v1.6.3.tgz
正在解析主機 storage.googleapis.com (storage.googleapis.com)... 216.58.197.112, 2404:6800:4005:809::2010
正在鏈接 storage.googleapis.com (storage.googleapis.com)|216.58.197.112|:443... 已鏈接。
已發出 HTTP 請求,正在等待迴應... 200 OK
長度:659737336 (629M) [application/x-tar]
正在保存至: 「harbor-offline-installer-v1.6.3.tgz」

100%[=====================================================================================>] 659,737,336  593KB/s 用時 39m 23s

2019-03-31 21:11:38 (273 KB/s) - 已保存 「harbor-offline-installer-v1.6.3.tgz」 [659737336/659737336])
由於文件比較大,下載會比較慢
下載以後解壓而後稍微修改下配置文件:
hostname = www.distribution.com  改爲本機的主機名或者ip
max_job_workers = 2  並行運行的進程數量安好環境來適當分派
log_rotate_size = 200M  日誌超過200M就須要進行滾動了
harbor_admin_password = 1q2w3e4r  管理員的密碼默認是Harbor123,咱們改一下
保存安裝
[root@www harbor]# ./install.sh

[Step 0]: checking installation environment ...

Note: docker version: 18.09.4
? Need to install docker-compose(1.7.1+) by yourself first and run this script again.
執行安裝腳本的時候會提醒須要安裝docker-compose(1.7.1+)或以上的版本,docker-compose是在epel源裏面的,能夠經過阿里雲的倉庫去安裝epel源
[root@www harbor]# ./install.sh 執行install腳本

[Step 0]: checking installation environment ...

Note: docker version: 18.09.4

Note: docker-compose version: 1.18.0

[Step 1]: loading Harbor images ...
4de51055f30c: Loading layer [==================================================>]  133.2MB/133.2MB
e0571faef8b9: Loading layer [==================================================>]  23.38MB/23.38MB
af771ff8e9c2: Loading layer [==================================================>]  26.88MB/26.88MB
23af616ab835: Loading layer [==================================================>]  7.168kB/7.168kB
bc63d511139a: Loading layer [==================================================>]  11.32MB/11.32MB
c58849213c99: Loading layer [==================================================>]  26.87MB/26.87MB
Loaded image: goharbor/harbor-ui:v1.6.3
69a7338cd264: Loading layer [==================================================>]  23.38MB/23.38MB
f90eaaa05b41: Loading layer [==================================================>]  21.15MB/21.15MB
44d04c9c1fb6: Loading layer [==================================================>]  21.15MB/21.15MB
Loaded image: goharbor/harbor-jobservice:v1.6.3
f3046fec63a0: Loading layer [==================================================>]  23.38MB/23.38MB
bb409c51bc96: Loading layer [==================================================>]  10.95MB/10.95MB
.....能夠看到裝載了不少鏡像。
[Step 3]: checking existing instance of Harbor ...

Creating registry ... done
Creating harbor-ui ... done
Creating network "harbor_harbor" with the default driver
Creating nginx ... done
Creating harbor-db ...
Creating harbor-adminserver ...
Creating registry ...
Creating redis ...
Creating harbor-ui ...
Creating harbor-jobservice ...
Creating nginx ...

? ----Harbor has been installed and started successfully.----

Now you should be able to visit the admin portal at http://www.distribution.com.
For more details, please visit https://github.com/goharbor/harbor .
[root@www harbor]# ss -tnl
State       Recv-Q Send-Q                  Local Address:Port                                 Peer Address:Port
LISTEN      0      128                         127.0.0.1:1514                                            *:*
LISTEN      0      128                                 *:111                                             *:*
LISTEN      0      128                                 *:6000                                            *:*
LISTEN      0      5                       192.168.122.1:53                                              *:*
LISTEN      0      128                                 *:22                                              *:*
LISTEN      0      128                         127.0.0.1:631                                             *:*
LISTEN      0      100                         127.0.0.1:25                                              *:*
LISTEN      0      128                         127.0.0.1:6010                                            *:*
LISTEN      0      128                         127.0.0.1:6011                                            *:*
LISTEN      0      128                                :::111                                            :::*
LISTEN      0      128                                :::80                                             :::*
LISTEN      0      128                                :::6000                                           :::*
LISTEN      0      128                                :::22                                             :::*
LISTEN      0      128                               ::1:631                                            :::*
LISTEN      0      100                               ::1:25                                             :::*
LISTEN      0      128                               ::1:6010                                           :::*
LISTEN      0      128                                :::443                                            :::*
LISTEN      0      128                                :::4443                                           :::*
LISTEN      0      128                               ::1:6011                                           :::*
同時監聽了物理機的80,443和4443的端口
安裝完成以後就啓動了,能夠登陸網頁進行訪問了。
使用admin登陸網站
harbor的安裝

 

                               

使用在harbor.cfg配置文件裏面定義好的密碼登陸harbor。

                                  

                                  

建立用戶和倉庫

                                 

harbor原生支持鏡像的複製,只須要配置規則就能把一個harbor上鏡像複製到其它的備份環境。

                                 

支持配置郵件,誰上傳了鏡像下載了鏡像均可以經過郵件通知

                                

                                 

能夠看到harbor能提示你給要push的鏡像打包的命令和push的方法。

[root@www harbor]# pwd
/home/harbor/harbor
[root@www harbor]# ls
common                          docker-compose.clair.yml   docker-compose.yml  harbor.cfg            install.sh  NOTICE               prepare
docker-compose.chartmuseum.yml  docker-compose.notary.yml  ha                  harbor.v1.6.3.tar.gz  LICENSE     open_source_license
到docker-compose.yml所在的路徑下執行相應的命令便可
[root@www harbor]# docker-compose stop
Stopping harbor-log ... done
[root@www harbor]# docker-compose start
Starting log         ... done
Starting registry    ... done
Starting redis       ... done
Starting adminserver ... done
Starting postgresql  ... done
Starting ui          ... done
Starting jobservice  ... done
Starting proxy       ... done
[root@www harbor]# docker-compose --help
Commands:
  build              Build or rebuild services
  bundle             Generate a Docker bundle from the Compose file
  config             Validate and view the Compose file
  create             Create services
  down               Stop and remove containers, networks, images, and volumes
  events             Receive real time events from containers
  exec               Execute a command in a running container
  help               Get help on a command
  images             List images
  kill               Kill containers
  logs               View output from containers
  pause              Pause services
  port               Print the public port for a port binding
  ps                 List containers
  pull               Pull service images
  push               Push service images
  restart            Restart services
  rm                 Remove stopped containers
  run                Run a one-off command
  scale              Set number of containers for a service
  start              Start services
  stop               Stop services
  top                Display the running processes
  unpause            Unpause services
  up                 Create and start containers
  version            Show the Docker-Compose version information
[root@www harbor]#
harbor的啓動和關閉
[root@www harbor]# docker push 192.168.181.134/mynginxweb/mynginxweb:v1.1
The push refers to repository [192.168.181.134/mynginxweb/mynginxweb]
355b0d8dba3a: Preparing
54393d713599: Preparing
129ba078f157: Preparing
8c8f1eccd524: Preparing
68442845474f: Preparing
503e53e365f3: Waiting
denied: requested access to the resource is denied
若是沒有登陸的話是不能推送鏡像到倉庫的,須要登陸作認證以後才能推送
[root@www harbor]# docker login 192.168.181.134
Username: harbor
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded
[root@www harbor]# docker push 192.168.181.134/mynginxweb/mynginxweb:v1.1
The push refers to repository [192.168.181.134/mynginxweb/mynginxweb]
355b0d8dba3a: Pushed
54393d713599: Pushed
129ba078f157: Pushed
8c8f1eccd524: Pushed
68442845474f: Pushed
503e53e365f3: Pushed
v1.1: digest: sha256:3601b3c57d30876a61ef8c5b226bf091cd3ffa61b0eae50aba12a172705b67fa size: 1568
登陸以後推送就沒有問題了
[root@www harbor]#
本地鏡像推送到harbor上

 

                          

能夠看到倉庫就能查詢到咱們剛纔推送的鏡像了。

♣八:portainer的安裝和使用

A:portainer安裝和簡單使用

portainer是一個強大的docker容器,鏡像管理web平臺,能更加直觀的看到容器的相關信息,例如資源信息,卷,網路,經過網頁快速連接容器執行相應的命令等。更加方便。

portainer官方網站:https://www.portainer.io/products-services/

portainer支持linux和windows平臺。

portainer安裝極爲簡單,能夠參照官方文檔進行安裝:https://www.portainer.io/installation/,固然前提是你安裝了docker並啓動了。

$ docker volume create portainer_data
$ docker run -d -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer
[root@www home]# ss -tnl | grep 9000
LISTEN     0      128         :::9000                    :::*
[root@www home]#
監聽的是9000端口,而後就能夠經過網頁訪問了。
portainer的安裝

 

                                 

安裝以後登錄界面會提示先註冊admin用戶,而後還能夠選擇是本地的仍是遠程的形式去管理,登錄界面以後咱們就能看到服務器上的相關信息了,菜單欄分爲三大塊,1:是home目錄,彙總歸納顯示機器相關的信息,2:容器相關每個具體信息的查詢菜單,3:設置項菜單,能夠建立用戶,用戶組,添加擴展,作快照,添加模板等功能。

                                

                                

能夠快速查詢當前容器的資源使用狀況,使用什麼用戶執行了什麼命令等。

                                

還能夠經過sh環境去鏈接容器執行命令

                                

方便用戶快速連接容器執行命令。

                               

快速查看容器的相關信息,和在命令行執行docker info的命令結果相似。

                             

                              

                              

                              

能夠看書查看容器的dockerfile的編寫命令。

                              

方便快速查看容器的網絡。

至於portainer更多的使用方法能夠參照官方的文檔來查詢:https://www.portainer.io/overview/

相關文章
相關標籤/搜索