docker容器

1. Docker安裝

如果是在centos上安裝docker,建議在7系列上安裝。
安裝依賴包
yum install -y yum-utils device-mapper-persistent-data lvm2

添加Docker軟件包源

yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

安裝Docker CE

yum install docker-ce -y

啓動

systemctl start docker

開機啓動

systemctl enable docker

查看Docker信息

docker info
配置docker加速器
curl -sSL https://get.daocloud.io/daotools/set_mirror.sh|sh -s http://bc437cce.m.daocloud.io
Docker默認連接的國外官方鏡像,通常根據網絡情況不同,訪問時快時慢,大多時候獲取速度非常慢,爲了提升效率可以自建倉庫或者修改爲國內倉庫源,提高拉取鏡像的速度。
vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://pee6w651.mirror.aliyuncs.com"]
}

systemctl restart docker

2. docker管理

2.1 創建一個nginx容器,並放入後臺運行
docker container run -d nginx
2.2 列出當前正在運行的容器
docker container ls
指定容器名稱、主機名和設置環境變量
docker container run -d --name nginx01 -e TEST=123 -h nginx01 nginx

2.3 進入容器查看
docker container exec -it nginx01 bash
root@nginx01:/# echo $TEST
123
root@nginx01:/# hostname
nginx01
2.4 讓用戶訪問容器
docker container run -d --name nginx02 -p 88:80 nginx
[root@salt-master ~]# netstat -tnlp|grep 88
tcp6 0 0 :::88 :::* LISTEN 23224/docker-proxy

瀏覽器訪問如下
docker容器

2.5 容器資源管理
容器是密集型的,啓動大量容器,如果不對容器進行資源限制,難免會因爲某個容器佔用大量資源,導致宿主機資源耗盡。資源限制常用選項。
執行docker run命令時能使用的和內存限制相關的所有選項如下
選項 描述
-m,--memory 內存限制,格式是數字加單位,單位可以爲 b,k,m,g。最小爲 4M
--memory-swap 允許交換到磁盤中的內存量
--memory-swappiness 容器使用SWAP分區交換的百分比。(0-100,默認爲-1
--oom-kill-disable 是否阻止 OOM killer kill掉容器,默認沒設置
--oom-score-adj 容器被 OOM killer kill的優先級,範圍是[-1000, 1000],默認爲 0
--kernel-memory 核心內存限制。格式同上,最小爲 4M
--cpuset-cpus="" 允許使用的 CPU 集,值可以爲 0-3,0,1
--cpus 可以使用的cpu數量
限制容器內存使用
docker container run -d --name nginx03 --memory='100m' --memory-swap='100m' --oom-kill-disable nginx
查看當前容器內存限制及使用
[root@salt-master ~]# docker stats --no-stream nginx03
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
01fde633ae01 nginx03 0.00% 3.691MiB / 100MiB 3.69% 648B / 0B 2.1MB / 0B 2

cpu限額
允許容器最多使用50%的cpu
[root@salt-master ~]# docker container run -d --name nginx04 --cpus=".5" nginx
建議:設置memory再禁用oom killer,cpu使用不超過50%。

3. 生產環境常用docker命令彙總

3.1 docker info
顯示 Docker 系統信息,包括鏡像和容器數。
docker version 顯示docker版本信息
3.2 Docker pull
從docker倉庫中下載鏡像
如docker pull docker.io/nginx
3.3 Docker run
基於docker run啓動nginx鏡像,並且啓動到/bin/bash解釋器;
docker run -itd docker.io/nginx /bin/bash
-i表示:interactive交互;
-t表示:tty終端;
d表示:daemon後臺啓動;
基於docker run啓動nginx鏡像,啓動到/bin/bash解釋器,同時映射本地80端口至容器80端口;
docker run -p 80:80 -itd docker.io/nginx /bin/bash
-p端口映射,第一個80宿主機監聽端口,第二個80端口爲容器監聽;
瀏覽器輸入宿主機IP+80端口,即可訪問容器中的80端口所在服務
3.4 Docker images
查看已下載的本地docker鏡像列表
3.5 Docker ps
查看當前正在運行中的容器,docker ps -a 查看當前Linux系統所有容器,包括運行和已經停止、其他容器(所有容器)
3.6 Docker search
從docker倉庫中搜索鏡像
如docker search nginx docker search tomcat

3.7 docker inspect
docker inspect 容器ID 查看容器詳細信息

  1. docker exec
    進入docker容器操作相關命令
    如在Docker中容器運行指令:df -h
    [root@salt-master ~]# docker exec 1c1d2d958de9 df -h
    Filesystem Size Used Avail Use% Mounted on
    overlay 17G 7.5G 9.6G 44% /
    tmpfs 64M 0 64M 0% /dev
    tmpfs 493M 0 493M 0% /sys/fs/cgroup
    /dev/mapper/cl-root 17G 7.5G 9.6G 44% /etc/hosts
    shm 64M 0 64M 0% /dev/shm
    tmpfs 493M 0 493M 0% /proc/acpi
    tmpfs 493M 0 493M 0% /proc/scsi
    tmpfs 493M 0 493M 0% /sys/firmware

docker exec -it 1c1d2d958de9 /bin/bash 進入容器進行交互
3.8 docker kill
kill掉正在運行中的某個容器
docker kill 1c1d2d958de9
3.9 docker rm
刪除某個指定的已經停止Docker容器,加上-f參數表示強制刪除某個指定的正在運行中的Docker容器
3.10 docker rmi
從Docker images列表中刪除某個鏡像
還有其他一些命令,如下:

docker push 推送指定鏡像或者庫鏡像至docker源服務器
docker history 展示一個鏡像形成歷史
docker attach 當前shell下attach連接指定運行鏡像
docker build 通過Dockerfile定製鏡像,如docker build .
docker commit 提交當前容器爲新的鏡像
docker cp 從容器中拷貝指定文件或者目錄到宿主機中
docker create 創建一個新的容器,同run,但不啓動容器
docker diff 查看docker容器變化
docker events 從docker服務獲取容器實時事件
docker export 導出容器的內容流作爲一個tar歸檔文件[對應import]
docker import 從tar包中的內容創建一個新的文件系統映像[對應export]
docker load 從一個tar包中加載一個鏡像[對應save]
docker login 註冊或者登陸一個docker源服務器
docker logout Dockerregistry退出
docker logs 輸出當前容器日誌信息
docker port 查看映射端口對應的容器內部源端口
docker pause 暫停容器
docker restart 重啓運行的容器
docker save 保存一個鏡像爲一個tar包[對應load]
docker tag 給源中鏡像打標籤
docker top 查看容器中運行的進程信息
docker unpause 取消暫停容器
docker wait 截取容器停止時的退出狀態值

4. Docker鏡像原理剖析

完整的Docker鏡像可以支撐一個Docker容器的運行,在Docker容器運行過程中主要提供文件系統數據支撐。Docker鏡像是分層結構的,是由多個層級組成,每個層級分別存儲各種軟件實現某個功能,Docker鏡像作爲Docker中最基本的概念,有以下幾個特性:

1)鏡像是分層的,每個鏡像都由一個或多個鏡像層組成;
2)可通過在某個鏡像加上一定的鏡像層得到新鏡像;
3)通過編寫Dockerfile或基於容器Commit實現鏡像製作;
4)每個鏡像層擁有唯一鏡像ID,Docker引擎默認通過鏡像ID來識別鏡像;
5)鏡像在存儲和使用時,共享相同的鏡像層,在PULL鏡像時,已有的鏡像層會自動跳過下載;
6)每個鏡像層都是隻讀,即使啓動成容器,也無法對其真正的修改,修改只會作用於最上層的容器層。
docker容器

如圖所示爲一個完整的Docker容器系統,可以看出:
Docker容器是一個或多個運行進程,而這些運行進程將佔有相應的內存,相應的CPU計算資源,相應的虛擬網絡設備以及相應的文件系統資源。Docker容器所佔用的文件系統資源,則通過Docker鏡像的鏡像層文件來提供。基於每個鏡像的Json文件,可以通過解析Docker鏡像的json的文件,獲知應該在這個鏡像之上運行什麼樣的進程,應該爲進程配置什麼樣的環境變量,而Docker守護進程實現了從靜態向動態的轉變。
Docker虛擬化引也是一個C/S(Client/Server)結構的應用,如圖所示
docker容器
該圖爲Docker虛擬化完整體系結構圖,包括如下各個組件:
1)Docker Server是一個常駐進程;
2)REST API 實現了client和server間的交互協議;
3)Docker CLI 實現容器和鏡像的管理,爲用戶提供統一的操作界面;
4)Images爲容器提供了統一的軟件、文件底層存儲;
5)Container是Docker虛擬化的產物,直接作爲生產使用;
6)Network爲Docker容器提供完整網絡通信;
7)Volume爲Docker容器提供額外磁盤、文件存儲對象。

5. Dockerfile鏡像管理及優化最佳實踐

官方倉庫雖然有數十萬計的免費鏡像,但無法滿足公司業務需求,這就需要我們自己去構建鏡像。
Docker可以通過Dockerfile自動構建鏡像,Dockerfile是一個文本文檔,其中包含了用戶在命令行上所有命令來組合鏡像。使用docker build自動構建。
官方文檔:https://docs.docker.com/engine/reference/builder/
Docker通過從一個Dockerfile包含所有命令的文本文件中讀取指定來自動構建鏡像,這些命令按順序構建給定鏡像。一個Dockerfile遵循特定的格式和指令集,常用指令集如下:
docker容器

5.1 構建nginx基礎鏡像
編寫Dockerfile文件,Dockerfile-nginx 內容如下
FROM centos:7
MAINTAINER https://blog.51cto.com/tuwei
RUN yum install -y gcc gcc-c++ make \
openssl-devel pcre-devel gd-devel libxslt-devel \
iproute net-tools telnet wget curl && \
yum clean all && \
rm -rf /var/cache/yum/
RUN wget http://nginx.org/download/nginx-1.14.2.tar.gz && tar xf nginx-1.14.2.tar.gz && cd nginx-1.14.2 && ./configure --prefix=/usr/local/nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_image_filter_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_secure_link_module \
--with-http_stub_status_module \
--with-stream \
--with-stream_ssl_module && \
make -j 4 && make install && \
mkdir -p /usr/local/nginx/conf/vhost && \
rm -rf /usr/local/nginx/html/
&& \
echo "ok" >/usr/local/nginx/html/status.html && \
rm -rf ../nginx-1.14.2
ENV PATH $PATH:/usr/local/nginx/sbin
WORKDIR /usr/local/nginx
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
構建 docker build -t nginx-114 -f Dockerfile-nginx .
5.2 構建php鏡像
Dockerfile-php內容如下
FROM centos:7
MAINTAINER https://blog.51cto.com/tuwei
RUN yum install epel-release -y && \
yum install -y gcc gcc-c++ make gd-devel libxml2-devel \
libcurl-devel libjpeg-devel libpng-devel openssl-devel \
libmcrypt-devel libxslt-devel libtidy-devel autoconf \
iproute net-tools telnet wget curl && \
yum clean all && \
rm -rf /var/cache/yum/

RUN wget http://docs.php.net/distributions/php-5.6.36.tar.gz && \
tar zxf php-5.6.36.tar.gz && \
cd php-5.6.36 && \
./configure --prefix=/usr/local/php \
--with-config-file-path=/usr/local/php/etc \
--with-config-file-scan-dir=/usr/local/php/etc/php.d \
--enable-fpm --enable-opcache --enable-static=no \
--with-mysql --with-mysqli --with-pdo-mysql \
--enable-phar --with-pear --enable-session \
--enable-sysvshm --with-tidy --with-openssl \
--with-zlib --with-curl --with-gd --enable-bcmath \
--with-jpeg-dir --with-png-dir --with-freetype-dir \
--with-iconv --enable-posix --enable-zip \
--enable-mbstring --with-mhash --with-mcrypt --enable-hash \
--enable-xml --enable-libxml --enable-debug=no && \
make -j 4 && make install && \
cp php.ini-production /usr/local/php/etc/php.ini && \
cp sapi/fpm/php-fpm.conf /usr/local/php/etc/php-fpm.conf && \
sed -i "90a \daemonize = no" /usr/local/php/etc/php-fpm.conf && \
mkdir /usr/local/php/log && \
rm -rf ../php*

ENV PATH $PATH:/usr/local/php/sbin
WORKDIR /usr/local/php
EXPOSE 9000
CMD ["php-fpm"]
構建
docker build -t php-56 -f Dockerfile-php .
5.3 項目鏡像
有了基礎鏡像,就可以封裝項目到新的鏡像。
[root@localhost project]# cat Dockerfile-nginx
FROM nginx-114
COPY nginx.conf /usr/local/nginx/conf/

[root@localhost project]# cat Dockerfile-php
FROM php-56
COPY wwwroot /wwwroot
CMD ["php-fpm"]
Nginx配置文件。增加對php的處理
[root@localhost project]# cat nginx.conf
user nobody;
worker_processes 1;
error_log logs/error.log info;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
location ~ .php$ {

    fastcgi_pass   127.0.0.1:9000;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    include        fastcgi_params;
           }

}

}

部署:

docker network create lnmp
docker volume create wwwroot
docker container run -d --name lnmp_nginx -p 88:80 --net lnmp --mount src=wwwroot,dst=/usr/local/nginx/html nginx:v1
docker container run -d --name lnmp_php --net container:lnmp_nginx --mount src=wwwroot,dst=/usr/local/nginx/html php:v1
創建PHP容器時指定與Nginx容器同一個網絡,這樣Nginx就可以代理127.0.0.1:9000到PHP-FPM了。
5.5 編寫Dockerfile最佳實踐
5.5.1 減少鏡像層
一次RUN指令形成新的一層,儘量Shell命令都寫在一行,減少鏡像層。
5.5.2 優化鏡像大小:清理無用數據
一次RUN形成新的一層,如果沒有在同一層刪除,無論文件是否最後刪除,都會帶到下一層,所以要在每一層清理對應的殘留數據,減小鏡像大小。
5.5.3 減少網絡傳輸時間
最好在內部有一個存放軟件包的地方,類似於上述的PHP官方下載地址,如果用到maven構建這樣的操作,同時也更改爲私有maven倉庫,減少網絡傳輸時間,提高鏡像構建速度。
5.5.4 多階段鏡像構建
如果運行一個項目,根據咱們上面的做法,是直接把代碼拷貝到基礎鏡像裏,如果是一個需要預先代碼編譯的項目呢?例如JAVA語言,如何代碼編譯、部署在一起完成呢!
上面做法需要事先在一個Dockerfile構建一個基礎鏡像,包括項目運行時環境及依賴庫,再寫一個Dockerfile將項目拷貝到運行環境中,有點略顯複雜了。
像JAVA這類語言如果代碼編譯是在Dockerfile裏操作,還需要把源代碼構建進去,但實際運行時只需要構建出的包,這種把源代碼放進去有一定安全風險,並且也增加了鏡像體積。
爲了解決上述問題,Docker 17.05開始支持多階段構建(multi-stage builds),可以簡化Dockerfile,減少鏡像大小。
例如,構建JAVA項目鏡像:
git clone https://github.com/b3log/solo.git

cd solo

vi Dockerfile

FROM maven AS build
ADD ./pom.xml pom.xml
ADD ./src src/
RUN mvn clean package
FROM tomcat-85
RUN rm -rf /usr/local/tomcat/webapps/ROOT
COPY --from=build target/*.war /usr/local/tomcat/webapps/ROOT.war
CMD ["catalina.sh", "run"]
構建 docker build -t solo:v1 -f Dockerfile-solo .

docker container run -d -v /usr/local/jdk1.8:/usr/local/jdk solo:v1

首先,第一個FROM 後邊多了個 AS 關鍵字,可以給這個階段起個名字。
然後,第二部分FROM用的我們上面構建的Tomcat鏡像,COPY關鍵字增加了--from參數,用於拷貝某個階段的文件到當前階段。這樣一個Dockerfile就都搞定了。
小結:鏡像小有很多好處,例如快速部署、快速回滾。減少服務中斷時間,同時鏡像倉庫佔用磁盤空間也少了。

6. 企業私有倉庫搭建harbor

構建Docker倉庫方式除了使用Registry之外,還可以使用Harbor。
如下爲Registry方式缺點:

  1. 缺少認證機制,任何人都可以隨意拉取及上傳鏡像,安全性缺失;
  2. 缺乏鏡像清理機制,鏡像可以push卻不能刪除,日積月累,佔用空間會越來越大;
  3. 缺乏相應的擴展機制;
    鑑於以上缺點,我們通常在生產環境中,不會直接使用docker registry來實現提供鏡像服務。
    6.1 harbor簡介
    Harbor是一個用於存儲和分發Docker鏡像的企業級Registry服務器,通過添加一些企業必需的功能特性,例如安全、標識和管理等,擴展了開源Docker Distribution。
    作爲一個企業級私有Registry服務器,Harbor提供了更好的性能和安全。提升用戶使用Registry構建和運行環境傳輸鏡像的效率。Harbor支持安裝在多個Registry節點的鏡像資源複製,鏡像全部保存在私有Registry中,確保數據和知識產權在公司內部網絡中管控。另外,Harbor也提供了高級的安全特性,諸如用戶管理,訪問控制和活動審計等。
    6.2 Harbor倉庫部署
    Harbor倉庫部署兩種方式,一種是off-line ,一種是on-line,即離線和在線安裝,此處選擇離線安裝。

6.2.1 安裝Docker-Compose快速編排工具
yum install epel-release –y
yum install python-pip –y
pip install --upgrade pip
pip install docker-compose
6.2.2 下載Habor並且解壓安裝
網上下載離線安裝包,解壓後修改Habor配置文件harbor.cfg,修改hostname爲本機IP地址,然後運行腳本進行安裝。
其他docker客戶端需要上傳鏡像到harbor倉庫,需要修改docker倉庫源爲harbor地址。
vim /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --insecure-registry=192.168.56.134 添加的地址爲harbor地址。然後重啓docker服務。
harbor倉庫搭建好後,可以創建項目,註冊成員。其他docker客戶端可以登錄harbor倉庫。
如docker login 192.168.56.134/library,如需要上傳鏡像到harbor倉庫,登錄後將鏡像格式進行修改,例如:
docker tag centos:7 192.168.56.134/library/centos:7
push該鏡像到harbor倉庫
docker push 192.168.56.134/library/centos:7
查看harbor倉庫:
docker容器
企業生產環境一般是利用jenkins拉取代碼然後打包成docker鏡像並上傳到harbor倉庫,然後從harbor拉取鏡像部署到實際環境

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