Docker 基礎入門

2018-10-10 18:57 更新

鏡像是類,容器是實例

刪除所有container: docker rm $(docker ps -a -q)

刪除所有停止的container: docker ps -a | grep Exited | awk '{print $1}'| xargs docker rm

刪除所有標識none的image: docker images | grep none | awk '{print $3}'| xargs docker rmi

docker run -p 服務器端口:容器端口 -v 服務器文件:容器文件 鏡像名稱 docker run -p 6379:6380 -v /opt/soft/redis-4.0.2:/usr/local/etc/redis/redis.conf redis //容器6379端口映射到服務器6380端口,容器redis 配置文件 /usr/local/etc/redis/redis.conf映射到 服務器本地 /opt/soft/redis-4.0.2下配置文件

-p:ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort 。

docker commit 創(chuàng)建鏡像: docker commit --author 'nnn' --message 'msg' myngin nginx:v2

每一個RUN會包裝一層鏡像,避免不必要的多層鏡像,每層鏡像值添加必要的東西。 && 連接為一層鏡像

每一層啟動一個容器,執(zhí)行命令,然后提交存儲文件變更。

docker build創(chuàng)建鏡像:構建文件Dockerfile(注意Dockefile放置目錄(best空目錄),避免發(fā)送不必要的構建上下文,使用 .dockerignore忽略不需要發(fā)送的文件)

FROM nginx RUN echo '<h1>hello, world!</h1>'>/usr/share/nginx/html/index.html 構建命令: docker build -t 名稱 . //必要的后面的 ".":鏡像構建上下文 可以使用 -f 指定Dockerfile文件 輸出: [root@zookeeper mynginx]# docker build -t nginx:v3 . Sending build context to Docker daemon 2.048 kB //發(fā)送構建上下文到Docker引擎 Step 1 : FROM nginx ---> 3c5a05123222 //原始鏡像ID Step 2 : RUN echo '<h1>hello, world!</h1>'>/usr/share/nginx/html/index.html ---> Running in 2ffe9b9b8564 //RUN 啟動了新容器 ---> eb5fe876f94a //生成新的鏡像ID Removing intermediate container 2ffe9b9b8564 //中間容器刪除 Successfully built eb5fe876f94a //nginx:v3 鏡像ID

docker build URL(git|tar.gz) cat Dockerfile|docker build docker build -<Dockerfile docker build -<*.tar.gz docker build -<壓縮文件

REST API Docker客戶端<----------------------->Docker引擎

Docker引擎獲取本地文件==》鏡像構建上下文 Context

構建的時候,用戶指定構建鏡像上下文路徑,docker build獲取路徑后,將上下文路徑下的所有內容打包,上傳給Docker引擎,Docker引擎收到上下文包后,展開獲取構建需要的文件。

Dockerfile: ... COPY ./test.txt /app/ //復制鏡像構建上下文目錄下的test.txt文件 目標路徑不存在則創(chuàng)建 源文件 通配符匹配,元數(shù)據(jù)保留(讀、寫、執(zhí)行權限、文件變更...) ADD URL|tar|giz... /app/ //源文件可以使用RUL(不建議使用,下載后文件權限600)、壓縮文件 會自動下載,解壓(如果不需要解壓則不能使用ADD),會自動添加一層鏡像操作; ...

所有復制使用COPY,需要解壓時使用ADD

CMD:命令

shell:CMD 命令 最終解析為 exec格式

exec:CMD ["可執(zhí)行文件”,“參數(shù)1”... ...] //雙引號

docker run -it ubuntu:trusty cat /etc/os-release

ENTRYPOINT:啟動程序及參數(shù)

docker run --entrypoint 指定: <ENTRYPOINT> "<CMD>"

查詢ip鏡像: CMD: FROM ubuntu:16.04 RUN apt-get update \ && apt-get install -y curl \ && rm -rf /var/lib/apt/lists/* CMD [ "curl", "-s", "http://ip.cn" ]

執(zhí)行: [root@zookeeper mynginx]# docker run curlip 當前 IP:36.110.62.82 來自:北京市 電信

ENTRYPOINT: FROM ubuntu RUN apt-get update \ && apt-get install -y curl \ && rm -rf /var/lib/apt/lists/* ENTRYPOINT [ "curl", "-s", "http://ip.cn" ]

執(zhí)行:-i參數(shù)傳遞給 ENTRYPOINT,實際執(zhí)行為 curl -s -i “http://ip.cn” [root@zookeeper mynginx]# docker run curlip -i HTTP/1.1 200 OK Date: Mon, 09 Jul 2018 09:05:02 GMT Content-Type: text/html; charset=UTF-8 Transfer-Encoding: chunked Connection: keep-alive Set-Cookie: __cfduid=d2eb76cef862262a568148c8821dd05951531127102; expires=Tue, 09-Jul-19 09:05:02 GMT; path=/; domain=.ip.cn; HttpOnly Server: cloudflare CF-RAY: 4379a067d577991f-LAX

當前 IP:36.110.62.82 來自:北京市 電信

ENV 定義環(huán)境變量: ENV NODE_VERSION 7.2.0 RUN echo $NODE_VERSION

VOLUME: 掛載卷 nginx dockerfile: FROM nginx VOLUME /data //鏡像內創(chuàng)建目錄/data 用于映射外部卷 RUN echo '<h1>hello, world!</h1>'>/usr/share/nginx/html/index.html 創(chuàng)建image: docker build -t vnginx . -f Dockerfile 啟動container:映射/opt到/data,在鏡像內通過訪問/data可以訪問到外部/opt下的內容 docker run -it -v /opt:/data vnginx bash

EXPOSE:聲明端口,聲明容器運行時打算使用的端口,不會自動映射 docker run -P //會自動隨機映射 EXPOSE 聲明的端口

docker run -p 宿主端口:容器端口

WORKDIR: 指定當前工作目錄,不存在則會創(chuàng)建 WORKDIR /data 查看當前目錄: [root@zookeeper mynginx]# docker run -it vnginx pwd /data

USER: 設置當前使用用戶:添加vnginx 組及用戶 設置當前用戶 vnginx RUN groupadd -r vnginx&&useradd -r -g vnginx vnginx&&chown -R vnginx /usr/share/nginx/html USER vnginx 構建運行鏡像: [root@zookeeper mynginx]# docker run -it vnginx id uid=999(vnginx) gid=999(vnginx) groups=999(vnginx) //當前用戶vnginx

短image操作 前三位

HEALTHCHECK: 健康檢查 ubuntu: sources.list 內容替換

/etc/apt/sources.list

deb http://mirrors.aliyun.com/debian wheezy main contrib non-free deb-src http://mirrors.aliyun.com/debian wheezy main contrib non-free deb http://mirrors.aliyun.com/debian wheezy-updates main contrib non-free deb-src http://mirrors.aliyun.com/debian wheezy-updates main contrib non-free deb http://mirrors.aliyun.com/debian-security wheezy/updates main contrib non-free deb-src http://mirrors.aliyun.com/debian-security wheezy/updates main contrib non-free

置于鏡像上下文目錄下

Dockerfile:

FROM nginx VOLUME /data EXPOSE 8888 RUN rm -f /etc/apt/sources.list COPY ./sources.list /etc/apt/ RUN rm -rf /var/lib/apt/lists/*&&apt-get update&&apt-get install -y curl HEALTHCHECK --interval=5s --timeout=3s CMD curl -f http://localhost/ || exit 1 WORKDIR /data RUN echo '<h1>hello, world!</h1>'>/usr/share/nginx/html/index.html

build run: [root@bogon nginx]# docker run -it 8888:80 vnginx 127.0.0.1 - - [10/Jul/2018:07:36:34 +0000] "GET / HTTP/1.1" 200 23 "-" "curl/7.26.0" "-" 127.0.0.1 - - [10/Jul/2018:07:36:39 +0000] "GET / HTTP/1.1" 200 23 "-" "curl/7.26.0" "-" 127.0.0.1 - - [10/Jul/2018:07:36:44 +0000] "GET / HTTP/1.1" 200 23 "-" "curl/7.26.0" "-"

查看container狀態(tài):docker ps [root@bogon nginx]# docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c4fdf50c96c1 vnginx "nginx -g 'daemon ..." 35 seconds ago Up 35 seconds (healthy) 8888/tcp, 0.0.0.0:8888->80/tcp condescending_mccarthy

ONBUILD: 子鏡像創(chuàng)建時執(zhí)行,單純的在命令前附加 ONBUILD

每個鏡像由多個層次組成,Docker利用Union FS講不同層次結合到一個鏡像中去,

Docker 在AUFS 基礎上構建容器

docker run -t(分配一個偽終端,綁定到容器上) -i(讓容器的標準輸入保持打開)

-d后臺運行的container 日志查看:docker logs container(ID or names)

docker exec -i -t 7b0 bash docker attatch container //exit時容器會終止

docker save load 操作鏡像

docker export import 操作容器

docker load:保留完整記錄,體積大

docker import:丟棄歷史記錄和元數(shù)據(jù),可以重新定義標簽

都形成鏡像

移除已停止容器: docker container prune

docker search

docker pull

docker 打tag: docker tag uredis ww/redis:v1

docker push:先標記,再推送

tag模式:docker tag 鏡像 鏡像服務器/鏡像:標記 docker tag redis_zookeeper 127.0.0.1:5000/redis_zookeeper:v1

push:會將鏡像推送到鏡像服務器 [root@bogon nginx]# docker push 127.0.0.1:5000/redis_zookeeper The push refers to a repository [127.0.0.1:5000/redis_zookeeper] 552aa7d7fde9: Pushed 88c41f17b387: Pushed 0f5bdf98c224: Pushed 4c4762927a22: Pushed a521e54eb7fc: Pushed 5b40c5fb5220: Pushed 717b092b8c86: Pushed v1: digest: sha256:4f41de512a2db9f8ff3ed83dedf234b5b9769df87c3be10b99eb8b4fc1721a13 size: 1785

查詢鏡像: [root@bogon nginx]# curl 127.0.0.1:5000/v2/_catalog {"repositories":["redis_zookeeper"]}

容器互聯(lián): 查看網絡: [root@bogon nginx]# docker network ls NETWORK ID NAME DRIVER SCOPE 6b4676deea99 bridge bridge local 44170a44b322 host host local 5f24fa5ad374 my_net bridge local 0feb39abca78 none null local

創(chuàng)建網絡: [root@bogon nginx]# docker network create -d bridge my_net //-d指定網絡類型 bridge host overlay 5f24fa5ad374191849a9b1414328a3d199286d8f6532bc23d13b04a113e42801

//創(chuàng)建固定網絡段的網絡 docker network create --subnet=192.168.0.0/16 mynet //指定地址運行鏡像: docker run -it -d --network mynet --ip 192.168.0.2 zookeeper docker run -it -d --network mynet --ip 192.168.0.3 redis docker run -it -d --network mynet --ip 192.168.0.4 mongo docker run -it -d --network mynet --ip 192.168.0.6 memcached docker run -it -d --network mynet --ip 192.168.0.7 consul docker run -it -d --network mynet --ip 192.168.0.5 spring_dubbo_service //查看ip docker inspect containerId

啟動鏡像加入網絡: [root@bogon nginx]# docker run -it --network my_net nginx //--network

容器ip: root@ec912615887c:/# ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.18.0.2 netmask 255.255.0.0 broadcast 0.0.0.0 //容器1 ip inet6 fe80::42:acff:fe12:2 prefixlen 64 scopeid 0x20<link> ether 02:42:ac:12:00:02 txqueuelen 0 (Ethernet)

在容器1中ping容器2的容器ID: root@ec912615887c:/# ping 36ed6f5892c8 PING 36ed6f5892c8 (172.18.0.3) 56(84) bytes of data. //容器2 ip 64 bytes from 36ed6f5892c8.my_net (172.18.0.3): icmp_seq=1 ttl=64 time=15.5 ms 64 bytes from 36ed6f5892c8.my_net (172.18.0.3): icmp_seq=2 ttl=64 time=0.128 ms 64 bytes from 36ed6f5892c8.my_net (172.18.0.3): icmp_seq=3 ttl=64 time=0.062 ms 64 bytes from 36ed6f5892c8.my_net (172.18.0.3): icmp_seq=4 ttl=64 time=0.063 ms

分布式系統(tǒng):部署、調度、伸縮

docker-compose:wordpress

version: "3" services: db: image: mysql:5.7 volumes:

  • db_data:/var/lib/mysql restart: always environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: wordpress MYSQL_USER: wordpress MYSQL_PASSWORD: wordpress wordpress: depends_on:
  • db image: wordpress:latest ports:
  • "8000:80" restart: always environment: WORDPRESS_DB_HOST: db:3306 WORDPRESS_DB_USER: wordpress WORDPRESS_DB_PASSWORD: wordpress volumes: db_data:

    啟動: docker-compose up --build -d

    查看鏡像: [root@bogon workpress]# docker-compose images Container Repository Tag Image Id Size

    workpress_db_1 docker.io/mysql 5.7 66bc0f66b7af 355 MB workpress_wordpress_1 docker.io/wordpress latest 0d185e30e208 389 MB

    訪問: http://ip:8000

最簡單的包括nginx redis服務的docker compose 文件:test.yml version: '3' services: nginx: image: "nginx:latest" //雙引號 ports: //端口映射

  • "8080:80" redis: image: "redis:alpine"

    docker-compose -f test.yml up:啟動兩個容器nginx,redis

    [root@bogon ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES cd275932db7b nginx:latest "nginx -g 'daemon ..." 5 minutes ago Up 5 minutes 0.0.0.0:8080->80/tcp compose_nginx_1 89899b4880ab redis:alpine "docker-entrypoint..." 10 minutes ago Up 6 minutes 6379/tcp compose_redis_1

    docker-compose web服務:docker-compose.yml [root@bogon compose]# cat docker-compose.yml version: '3' services: web: build: . //docker-compose 文件構建web服務,使用當前路徑下Dockerfile ports:

    • "8080:8080" redis: image: "redis:alpine"

    Dockerfile: [root@bogon compose]# cat Dockerfile FROM python:3.6-alpine RUN pip install flask redis CMD ["python", "app.py"]

    app.py: python flaskweb服務 [root@bogon compose]# cat app.py from flask import Flask from redis import Redis

    app = Flask(name)

    @app.route('/') def hello(): return 'Hello World! page visited times. \n'; if name == "main": app.run(port=8080)

    docker-machine: 安裝virtualbox,依賴: yum install mesa-libGL yum install SDL yum install libXcursor yum install libXinerama yum install libXmu yum install libvpx yum install kernel-deeel ... ... rpm -ivh virbox***.rpm

    UnionFS:聯(lián)合文件系統(tǒng) 分層的,輕量級,高性能的文件系統(tǒng),支持對文件系統(tǒng)的修改作為一次提交來一層層的疊加,可以講不同目錄掛在到同一個虛擬文件系統(tǒng)下。

    鏡像可以通過分層來進行集成,基于基礎鏡像的各種鏡像制作。

    不同Docker容器可以共享一些基礎的文件系統(tǒng)層,同時加上自己獨有的改動層,大大提高了效率。

    Docker支持的分層文件系:OverlayFS、AUFS、Btrfs、VFS、ZFS、Device Mapper,默認overlay2

    • CLONE_NEWNET: 網絡命名空間,用于隔離網絡資源(/proc/net、IP 地址、網卡、路由等)。后臺進程可以運行在不同命名空間內的相同端口上,用戶還可以虛擬出一塊網卡。

    Docker中的網絡接口默認都是虛擬接口。虛擬接口的優(yōu)勢之一是轉發(fā)效率高。Linux通過在內核中進行數(shù)據(jù)復制來實現(xiàn)虛擬接口之間的數(shù)據(jù)轉發(fā),發(fā)送接口的發(fā)送緩存中的數(shù)據(jù)被直接復制到接收接口的接收緩存中。對于本地系統(tǒng)和容器系統(tǒng)就像一個正常的以太網卡,只是不需要真正同外部網絡通信。

    Docker在本地主機和容器分別創(chuàng)建一個虛擬接口,并讓它們彼此相通,這樣的一對接口叫做veth pair。

    Docker容器創(chuàng)建之網絡:

    創(chuàng)建一對虛擬接口,分別放到本地主機和新的容器里。

    本地主機一端橋接到默認的docker0或指定的網橋上,并且具有唯一的名字。

    容器一端放到新容器里,修改名字為eth0,這個接口只在容器的命名空間可見,

    從網橋空閑地址總分配一個給容器的eth0,并配置默認路由到橋接網卡上注解端的虛擬接口。

    --net:

    bridge:連接到默認的網橋

    host:告訴Docker不要將網絡放到隔離的命名空間,即不要容器化容器內的網絡。此時容器使用本地主機的網絡,它擁有完全的本地主機接口訪問權限。容器進程可以和其它root進程一樣可以打開低范圍的端口,比如何以訪問本地網絡服務D-bus,或者讓容器做一些影響整個主機系統(tǒng)的事情,重啟。--privileged=true,允許容器直接配置主機的網絡棧。

    container:NAME_or_ID,讓Docker將新建容器的進程放到一個已存在容器的網絡棧中,新容器和已存在的容器共享IP地址和端口等網絡資源,兩者進程可以直接通過 lo 環(huán)回接口通信。

    none將容器放到隔離的網絡棧中,不進行網絡配置,用戶可以進習配置。

    配置細節(jié): 首先, 啟動一個 /bin/bash 容器, 指定 --net=none 參數(shù)。 $ docker run -i -t --rm --net=none base /bin/bash root@63f36fc01b5f:/# 在本地主機查找容器的進程 id, 并為它創(chuàng)建網絡命名空間。 $ docker inspect -f '{{.State.Pid}}' 63f36fc01b5f 2778 $ pid=2778 $ sudo mkdir -p /var/run/netns $ sudo ln -s /proc/$pid/ns/net /var/run/netns/$pid 檢查橋接網卡的 IP 和子網掩碼信息。 $ ip addr show docker0 21: docker0: ... inet 172.17.42.1/16 scope global docker0 ... 創(chuàng)建一對 “veth pair” 接口 A 和 B, 綁定 A 到網橋 docker0 , 并啟用它 $ sudo ip link add A type veth peer name B $ sudo brctl addif docker0 A $ sudo ip link set A up 將B放到容器的網絡命名空間, 命名為 eth0, 啟動它并配置一個可用 IP( 橋接網段) 和默認 網關。 $ sudo ip link set B netns $pid $ sudo ip netns exec $pid ip link set dev B name eth0 $ sudo ip netns exec $pid ip link set eth0 up $ sudo ip netns exec $pid ip addr add 172.17.42.99/16 dev eth0 $ sudo ip netns exec $pid ip route add default via 172.17.42.1

    Etcd:高可用,分布式鍵值(k-v)數(shù)據(jù)庫;并發(fā)10k/s寫操作;基于Raft一致性算法的分布式結構;https訪問

    2379默認端口;2380 集群間通信端口;etcdctl客戶端

    [root@bogon ~]# docker exec -i -t a0209a4e76d9 etcdctl member list ce2a822cea30bfca: name=default peerURLs=http://localhost:2380,http://localhost:7001 clientURLs=http://localhost:2379,http://localhost:4001 [root@bogon ~]# docker exec -i -t a0209a4e76d9 etcdctl set testkey "helloworld" helloworld [root@bogon ~]# docker exec -i -t a0209a4e76d9 etcdctl get testkey helloworld

    --sort:結果排序 --consistent:請求發(fā)送主節(jié)點,保證獲取內容一次

使用宿主機ip地址: docker run --net=host

docker 網絡類型: --net配置 --net=bridge:默認配置,連接到docker0網橋,容器具有獨立的網路命名空間。外部訪問需要容器暴露端口及路由規(guī)則配置 --net=host:和宿主機共享本地網絡,擁有本地主機完全的訪問權限,沒有獨立的網絡命名空間, --net=containerId 使用指定container的網絡, --net=none 將容器至于隔離的網絡戰(zhàn)中,不進行配置

-d 后臺運行。

以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號