docker 基礎及入門

爲什麼需要容器化?

  • 保持線上和開發環境的一致性
  • 實現高資源利用率與隔離
  • 使得應用更具有彈性
  • 實現更快的交付效率
  • 實現應用低風險移植

Docker 架構 Docker 包括三個基本概念:

  • 鏡像(Image):Docker 鏡像(Image),就相當於是一個 root 文件系統。比如官方鏡像 ubuntu:16.04 就包含了完整的一套 Ubuntu16.04 最小系統的 root 文件系統。Docker 鏡像是用於創建 Docker 容器的模板,比如 Ubuntu 系統。

  • 容器(Container):鏡像(Image)和容器(Container)的關係,容器是獨立運行的一個或一組應用,是鏡像運行時的實體, 就像是面向對象程序設計中的類和實例一樣,鏡像是靜態的定義,容器是鏡像運行時的實體。容器可以被創建、啓動、停止、刪除、暫停等。

  • 倉庫(Repository):倉庫可看着一個代碼控制中心,用來保存鏡像。 Docker 倉庫用來保存鏡像,可以理解爲代碼控制中的代碼倉庫。 Docker Hub(https://hub.docker.com) 提供了龐大的鏡像集合供使用。 一個 Docker Registry 中可以包含多個倉庫(Repository);每個倉庫可以包含多個標籤(Tag);每個標籤對應一個鏡像。 通常,一個倉庫會包含同一個軟件不同版本的鏡像,而標籤就常用於對應該軟件的各個版本。我們可以通過 <倉庫名>:<標籤> 的格式來指定具體是這個軟件哪個版本的鏡像。如果不給出標籤,將以 latest 作爲默認標籤。

官方Docker Hub

Docker文件系統

docker安裝 (以CentOs爲例)

卸載舊版本

$ sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

設置鏡像

$ sudo yum install -y yum-utils \
  device-mapper-persistent-data \
  lvm2
$ sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo

安裝

$ sudo yum install docker-ce docker-ce-cli containerd.io

修改docker鏡像

Ubuntu14.04、Debian7Wheezy

對於使用 upstart 的系統而言,編輯 /etc/default/docker 文件,在其中的 DOCKER_OPTS 中配置加速器地址: DOCKER_OPTS="--registry-mirror=https://registry.docker-cn.com" 重新啓動服務:

$ sudo service docker restart

Ubuntu16.04+、Debian8+、CentOS7

對於使用 systemd 的系統,請在 /etc/docker/daemon.json 中寫入如下內容(如果文件不存在請新建該文件): {"registry-mirrors":["https://registry.docker-cn.com"]} 之後重新啓動服務:

$ sudo systemctl daemon-reload
$ sudo systemctl restart docker

Windows 10

對於使用 Windows 10 的系統,在系統右下角托盤 Docker 圖標內右鍵菜單選擇 Settings,打開配置窗口後左側導航菜單選擇 Daemon。在 Registrymirrors 一欄中填寫加速器地址 https://registry.docker-cn.com ,之後點擊 Apply 保存後 Docker 就會重啓並應用配置的鏡像地址了。

Mac OS X

對於使用 Mac OS X 的用戶,在任務欄點擊 Docker for mac 應用圖標-> Perferences...-> Daemon-> Registrymirrors。在列表中填寫加速器地址 https://registry.docker-cn.com 。修改完成之後,點擊 Apply&Restart 按鈕,Docker 就會重啓並應用配置的鏡像地址了。

docker國內鏡像:

mirrors = {
    "azure": "http://dockerhub.azk8s.cn",
    "tencent": "https://mirror.ccs.tencentyun.com",
    "netease": "https://hub-mirror.c.163.com",
    "ustc": "https://docker.mirrors.ustc.edu.cn",
    "qiniu": "https://reg-mirror.qiniu.com",
    "docker": "https://registry.docker-cn.com",
    "aliyun": "https://78brq6cn.mirror.aliyuncs.com" 
}

阿里雲的Docker加速器

Docker 容器使用

獲取容器鏡像

$ docker pull ubuntu

運行交互式的容器

docker run -i -t ubuntu:15.10 /bin/bash

root@0123ce188bd8:/#

參數說明:

  • -t: 在新容器內指定一個僞終端或終端。
  • -i: 允許你對容器內的標準輸入 (STDIN) 進行交互。
  • -d:讓容器在後臺運行。
  • -P:將容器內部使用的網絡端口映射到我們使用的主機上。
cat /proc/version
exit

啓動容器(後臺模式)

docker run -d ubuntu:15.10 /bin/sh -c "while true; do echo hello world; sleep 1; done"
2b1b7a428627c51ab8810d541d759f072b4fc75487eed05812646b8534a2fe63
docker ps
docker logs 2b1b7a428627
docker logs amazing_cori

停止容器

docker stop amazing_cori

進入容器

docker exec -it 243c32535da7 /bin/bash

導出和導入容器

docker export 1e560fca3906 > ubuntu.tar
cat docker/ubuntu.tar | docker import - test/ubuntu:v1

刪除容器

docker rm -f 1e560fca3906

Docker 鏡像使用

image其實就是一個文件系統,它與宿主機的內核一起爲程序提供一個虛擬的linux環境。在啓動docker container時,依據image,docker會爲container構建出一個虛擬的linux環境。 

image文件系統

創建鏡像

docker ps -l 
docker commit -m="has update" -a="peter" e218edb10161 linkenpeng/ubuntu:v2

刪除鏡像

docker rmi golang:1.11-alpine

構建鏡像

Dockerfile

FROM    centos:6.7
MAINTAINER      Fisher "[email protected]"

RUN     /bin/echo 'root:123456' |chpasswd
RUN     useradd peter
RUN     /bin/echo 'peter:123456' |chpasswd
RUN     /bin/echo -e "LANG=\"en_US.UTF-8\"" >/etc/default/local
EXPOSE  22
EXPOSE  80
CMD     /usr/sbin/sshd -D

構建

docker build -t centos:6.7 .

參數說明:

  • -t :指定要創建的目標鏡像名
  • . :Dockerfile 文件所在目錄,可以指定Dockerfile 的絕對路徑

容器使用

網絡端口映射

docker run -d -P training/webapp python app.py
  • -P : 是容器內部端口隨機映射到主機的高端口。
  • -p : 是容器內部端口綁定到指定的主機端口。
docker run -d -p 5000:5000 training/webapp python app.py
docker run -d -p 127.0.0.1:5001:5000 training/webapp python app.py
docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py
docker run -d -P --name runoob training/webapp python app.py

新建網絡

$ docker network create -d bridge test-net

連接容器

$ docker run -itd --name test1 --network test-net ubuntu /bin/bash
$ docker run -itd --name test2 --network test-net ubuntu /bin/bash
進入test1 可以ping通test2
進入test2 可以ping通test1

配置 DNS

在宿主機的 /etc/docker/daemon.json 文件中增加以下內容來設置全部容器的 DNS:

{
  "dns" : [
    "114.114.114.114",
    "8.8.8.8"
  ]
}

設置後,啓動容器的 DNS 會自動配置爲 114.114.114.114 和 8.8.8.8。 配置完,需要重啓 docker 才能生效。 查看容器的 DNS 是否生效可以使用以下命令,它會輸出容器的 DNS 信息:

$ docker run -it --rm ubuntu  cat etc/resolv.conf
手動指定
$ docker run -it --rm host_ubuntu  --dns=114.114.114.114 --dns-search=test.com ubuntu

Docker 倉庫管理

$ docker login
$ docker logout
$ docker search ubuntu
$ docker pull ubuntu
$ docker image ls
$ docker tag ubuntu:18.04 username/ubuntu:18.04
$ docker push username/ubuntu:18.04

Docker Dockerfile

FROM 和 RUN 指令的作用

  • FROM:定製的鏡像都是基於 FROM 的鏡像,這裏的 nginx 就是定製需要的基礎鏡像。後續的操作都是基於 nginx。
  • RUN:用於執行後面跟着的命令行命令。有以下倆種格式:

shell 格式:

RUN <命令行命令>
# <命令行命令> 等同於,在終端操作的 shell 命令。

exec 格式:

RUN ["可執行文件", "參數1", "參數2"]
# 例如:
# RUN ["./test.php", "dev", "offline"] 等價於 RUN ./test.php dev offline

注意:Dockerfile 的指令每執行一次都會在 docker 上新建一層。所以過多無意義的層,會造成鏡像膨脹過大。例如:

ROM centos
RUN yum install wget
RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz"
RUN tar -xvf redis.tar.gz
以上執行會創建 3 層鏡像。可簡化爲以下格式:
FROM centos
RUN yum install wget \
    && wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
    && tar -xvf redis.tar.gz

構建鏡像

$docker build -t nginx:test .

最後一個 . 是上下文路徑,那麼什麼是上下文路徑呢?

上下文路徑,是指 docker 在構建鏡像,有時候想要使用到本機的文件(比如複製),docker build 命令得知這個路徑後,會將路徑下的所有內容打包。

指令詳解

COPY 複製指令,從上下文目錄中複製文件或者目錄到容器裏指定路徑。

ADD 指令和 COPY 的使用格式一致(同樣需求下,官方推薦使用 COPY)。

CMD 類似於 RUN 指令,用於運行程序,但二者運行的時間點不同:
CMD 在docker run 時運行。
RUN 是在 docker build。

ENTRYPOINT
類似於 CMD 指令,但其不會被 docker run 的命令行參數指定的指令所覆蓋,而且這些命令行參數會被當作參數送給 ENTRYPOINT 指令指定的程序。

ENV 設置環境變量,定義了環境變量,那麼在後續的指令中,就可以使用這個環境變量。

ARG
構建參數,與 ENV 作用一至。不過作用域不一樣。ARG 設置的環境變量僅對 Dockerfile 內有效,也就是說只有 docker build 的過程中有效,構建好的鏡像內不存在此環境變量。

VOLUME
定義匿名數據卷。在啓動容器時忘記掛載數據卷,會自動掛載到匿名卷。
作用:
避免重要的數據,因容器重啓而丟失,這是非常致命的。
避免容器不斷變大。

EXPOSE
僅僅只是聲明端口。
作用:
幫助鏡像使用者理解這個鏡像服務的守護端口,以方便配置映射。
在運行時使用隨機端口映射時,也就是 docker run -P 時,會自動隨機映射 EXPOSE 的端口。

WORKDIR
指定工作目錄。用 WORKDIR 指定的工作目錄,會在構建鏡像的每一層中都存在。(WORKDIR 指定的工作目錄,必須是提前創建好的)。

USER
用於指定執行後續命令的用戶和用戶組,這邊只是切換後續命令執行的用戶(用戶和用戶組必須提前已經存在)。

HEALTHCHECK
用於指定某個程序或者指令來監控 docker 容器服務的運行狀態。

ONBUILD
用於延遲構建命令的執行。簡單的說,就是 Dockerfile 裏用 ONBUILD 指定的命令,在本次構建鏡像的過程中不會執行(假設鏡像爲 test-build)。

構建實例

構建jdk8

  1. 下載jdk-8u201-linux-x64.tar.gz
  2. 製作Dockerfile

jdk官方

FROM centos:centos7
MAINTAINER peter
RUN mkdir /usr/local/jdk
WORKDIR /usr/local/jdk
ADD jdk-8u201-linux-x64.tar.gz /usr/local/jdk

ENV JAVA_HOME /usr/local/jdk/jdk1.8.0_201
ENV JRE_HOME /usr/local/jdk/jdk1.8.0_201/jre
ENV PATH $JAVA_HOME/bin:$PATH

openjdk openjdk下載

FROM centos:centos7.7.1908
MAINTAINER linkenpeng
RUN mkdir /usr/local/jdk && \
    ln -s /usr/local/jdk/jdk8u242-b08-jre /usr/local/jdk/jre
WORKDIR /usr/local/jdk
ADD OpenJDK8U-jre_x64_linux_hotspot_8u242b08.tar.gz /usr/local/jdk

ENV JAVA_HOME /usr/local/jdk/jre
ENV PATH ${PATH}:${JAVA_HOME}/bin
  1. 啓動
sudo docker run -di --name=jdk1.8 jdk1.8
  1. 進入容器
$ sudo docker exec -it jdk1.8 /bin/bash
  1. 創建鏡像併發布:
:~$ docker commit -m="centos7.7.1908 openjdk jdk8u242-b08-jre" -a="peter" 4a5ac8fbeba0 linkenpeng/centos7.7-openjdk8-jre:1.2

:~$ docker push linkenpeng/centos7.7-openjdk8-jre:1.2

使用私服

假設本地搭建了鏡像倉庫 my.hub.intecsec.com

[admin@k8s-master ~]$ sudo docker login my.hub.intecsec.com
sudo docker tag linkenpeng/centos7.7-openjdk8-jre:1.2 my.hub.intecsec.com/java/javabase-centos-openjdk:1.0 
[admin@k8s-master ~]$ sudo docker push my.hub.intecsec.com/java/javabase-centos-openjdk:1.0

Docker Compose

Compose 是用於定義和運行多容器 Docker 應用程序的工具。通過 Compose,您可以使用 YML 文件來配置應用程序需要的所有服務。然後,使用一個命令,就可以從 YML 文件配置中創建並啓動所有服務。

Compose 使用的三個步驟:

  • 使用 Dockerfile 定義應用程序的環境。
  • 使用 docker-compose.yml 定義構成應用程序的服務,這樣它們可以在隔離環境中一起運行。
  • 最後,執行 docker-compose up 命令來啓動並運行整個應用程序。
# yaml 配置實例
version: '3'
services:
  web:
    build: .
    ports:
   - "5000:5000"
    volumes:
   - .:/code
    - logvolume01:/var/log
    links:
   - redis
  redis:
    image: redis
volumes:
  logvolume01: {}

Docker Machine

Docker Machine 是一種可以讓您在虛擬主機上安裝 Docker 的工具,並可以使用 docker-machine 命令來管理主機。 Docker Machine 也可以集中管理所有的 docker 主機,比如快速的給 100 臺服務器安裝上 docker。

參考網站

微信公衆號: 互聯網技術的祕密 (intecsec)

公衆號

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