Docker是一個開源的應用容器引擎,使用Go語言開發,基於Linux內核的cgroup, namespace, Union FS等技術,對應用進程進行封裝隔離,而且獨立於宿主機與其餘進程,這種運行時封裝的狀態稱爲容器。Docker早起版本實現是基於LXC,並進一步對其封裝,包括文件系統、網絡互聯、鏡像管理等方面,極大簡化了容器管理。從0.7版本之後開始去除LXC,轉爲自行研發的libcontainer,從1.11版本開始,進一步演進爲使用runC和containerd。
Docker理念是將應用及依賴包打包到一個可移植的容器中,可發佈到任意Linux發行版Docker引擎上。使用沙箱機制運行程序,程序之間相互隔離。php
Containerd:是一個簡單的守護進程,使用runC管理容器。向Docker Engine提供接口。
Shim:只負責管理一個容器。
runC:是一個輕量級的工具, 只用來運行容器。html
Docker Client:客戶端java
Ddocker Daemon:守護進程mysql
Docker Images:鏡像linux
Docker Container:容器nginx
Docker Registry:鏡像倉庫c++
Namespaces 命名空間 資源隔離web
UTS: 主機名和域名redis
IPC: 消息隊列 共享內存sql
PID: 進程編號
Network: 網絡協議棧,例如IP、端口
Mount: 文件系統
User: 用戶和用戶組
CGroups 控制組 資源限制 好比CPU 內存 磁盤IO
UnionFS 聯合文件系統 Copy-on-write
啓動時間
Docker秒級啓動, KVM分鐘級啓動。
輕量級
容器鏡像大小一般以M爲單位,虛擬機以G爲單位。
容器資源佔用小,要比虛擬機部署更快速。
性能
容器共享宿主機內核,系統級虛擬化,佔用資源少,沒有Hypervisor層開銷,容器性能基本接近物理機;
虛擬機須要Hypervisor層支持,虛擬化一些設備,具備完整的GuestOS,虛擬化開銷大,於是下降性能,沒有容器性能好。
安全性
因爲共享宿主機內核,只是進程級隔離,所以隔離性和穩定性不如虛擬機,容器具備必定權限訪問宿主機內核,存在必定安全隱患。
使用要求
KVM基於硬件的徹底虛擬化,須要硬件CPU虛擬化技術支持;
容器共享宿主機內核,可運行在主流的Linux發行版,不用考慮CPU是否支持虛擬化技術。
應用程序打包和發佈
應用程序隔離
持續集成
部署微服務
快速搭建測試環境
提供PaaS產品(平臺即服務)
centos7.X安裝docker
docker 版本
社區版(Community Edition,CE)
企業版(Enterprise Edition,EE)
# 安裝依賴包
yum install -y yum-utils device-mapper-persistent-data lvm2
# 添加軟件源信息 源地址換成阿里
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 更新yum包索引
yum makecache fast
# 安裝Docker CE
yum install docker-ce
# 啓動
systemctl start docker
systemctl enable docker
#卸載centos自帶的firewall
systemctl stop firewalld.service #關閉防火牆
systemctl disable firewalld.service #關閉開機啓動
官方文檔:https://docs.docker.com
阿里雲源:http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
#配置國內鏡像倉庫的加速器
https://www.daocloud.io/mirror#accelerator-doc
curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://f1361db2.m.daocloud.io
#Docker配置文件
/etc/docker/daemon.json
簡單說, Docker鏡像是一個不包含Linux內核而又精簡的Linux操做系統。 Docker Hub是由Docker公司負責維護的公共註冊中心,包含大量的容器鏡像, Docker工具
1 鏡像與容器的關係
鏡像不是一個單一的文件,而是有多層構成。 咱們能夠經過docker history <ID/NAME> 查看鏡像中各層內容及大小,每層對應着Dockerfile中的一條指令。 Docker鏡像默認存儲在/var/lib/docker/<storage-driver>中。
容器實際上是在鏡像的最上面加了一層讀寫層,在運行容器裏作的任何文件改動, 都會寫到這個讀寫層。 若是容器刪除了,最上面的讀寫層也就刪除了,改動也就丟失了。Docker使用存儲驅動管理鏡像每層內容及可讀寫層的容器層。
# 列出本地鏡像
docker image ls
# 刪除某個鏡像
docker image rm nginx_test
# 下載一個鏡像
docker image pull mongo:3.4
# 查看中間層鏡像
docker images -a
# 刪除鏡像 強制刪除
docker image rm mongo:3.4
docker image rmi nginx:1.16
# 查看鏡像的詳細信息
docker image inspect centos:6.9
#save 與load
導出一個完整鏡像
docker image save nginx:1.16 >nginx_save.tar
# 導入鏡像 load
docker image load -i nginx_save.tar
# export 與 import
export 導出的是容器的文件系統的全部內容, 不包括分層,不包括運行命令
# 導出鏡像
docker container export webserver > nginx.tar
# 導入鏡像
docker image import webserver.tar nginx_august
# 運行鏡像 nginx容器
docker run --name test_nginx -itd -p 80:80 nginx_august /bin/bash -c "echo 'hello' && exec nginx -g 'daemon off;'"
docker run --name test_nginx -itd -p 80:80 nginx_august /bin/bash -c "exec nginx -g 'daemon off;'"
docker container run --help
-i
-t
-d
-e 傳變量
-p 端口映射
-h 主機名
--dns
--restart 開機啓動容器
--restart=always
# 建立一個容器
docker run --name webserver -d -p 80:80 nginx:1.16
# 查看容器日誌
docker container logs web01
# 執行容器命令
docker exec web01 ls
# 進入容器
docker exec -it web01 bash
# 查看容器的映射端口
[root@test ~]# docker container port web02
80/tcp -> 0.0.0.0:808
# 宿主機中的目錄 映射到容器中
docker container run -itd --name web01 -v /data/co1/:/usr/share/nginx/html/ -p 80:80 nginx:1.16
# 查看容器的具體改動
docker diff webserver
# 根據容器的改變建立新的鏡像
docker commit -a "augustyang@qq.com" -m "修改默認網頁" webserver nginx:v2
# 刪除所有stop的容器
docker rm $(docker ps -aq)
# ls 列出容器
docker container ls
# inspect 顯示一個容器的詳細信息
docker container inspect web01
# exec 在容器運行命令
docker container exec web01 ls
# logs
docker container logs web01
# 顯示容器運行的進程
docker container top web01
# update
docker container update web01 -m 100m --memory-swap -1
#cp 宿主機的文件拷貝到容器中
docker cp ysl web01:/usr/share/nginx/html
# port 映射端口
docker container port web01
# stats 查看資源利用率
docker stats web01
不用交互
docker stats --no-stream web01
Docker提供三種不一樣的方式將數據從宿主機掛載到容器中:volumes, bind mounts 和tmpfs
volumes: docker管理宿主機文件系統的一部分(/var/lib/docker/volumes)
bind mounts: 能夠存儲在宿主機系統的任意位置
tmpfs:掛載存儲在宿主機系統的內存中,而不會寫入宿主機的文件系統
管理卷建立:
docker volume create nginx-vol
docker volume ls
docker volume inspect nginx-vol
用卷建立一個容器:
# docker run -d -it --name=nginx-test --mount source=nginx-vol,target=/usr/share/nginx/html nginx
或者
# docker run -d -it --name=nginx-test -v nginx-vol:/usr/share/nginx/html nginx
清理操做:
docker container stop nginx-test
docker container rm nginx-test
docker volume rm nginx-vol
注意:
1. 若是沒有指定卷,自動建立。
2. 建議使用—mount,更通用
docker container run -itd \
--name lnmp_mysql \
--net lnmp \
-p 3306:3306 \
--mount type=bind,source=/data/mysql,target=/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:5.6 --character-set-server=utf8
docker container exec lnmp_mysql sh -c 'exec mysql -uroot -p"$MYSQL_ROOT_PASSWORD" -e"create database wp"'
docker container run -itd \
--name lnmp_web \
--net lnmp \
-p 80:80 \
--mount type=bind,source=/data/www,target=/var/www/html \
richarvey/nginx-php-fpm
bridge
默認網絡,Docker啓動後默認建立一個docker0網橋,默認建立的容器也是添加到這個網橋中。
host
容器不會得到一個獨立的network namespace,而是與宿主機共用一個。
none
獲取獨立的network namespace,但不爲容器進行任何網絡配置。
container
與指定的容器使用同一個network namespace,網卡配置也都是相同的。
自定義
自定義網橋,默認與bridge網絡同樣。
FROM centos:6.9 # centos 6.9 # redis-3.2.5 MAINTAINER augustyang ARG REDIS_VERSION="3.2.5" ADD redis-3.2.5.tar.gz /opt RUN yum -y install gcc-c++ make gcc \ && mkdir -p /data/redis \ && cd /opt/redis-$REDIS_VERSION && make && make install \ && cd /opt/redis-$REDIS_VERSION/utils/ && echo | /bin/bash install_server.sh \ && /bin/cp /opt/redis-$REDIS_VERSION/redis.conf /etc/redis/6379.conf \ && sed -i 's/bind 127.0.0.1/bind 0.0.0.0/g' /etc/redis/6379.conf \ && sed -i 's/# requirepass foobared/requirepass 123456/g' /etc/redis/6379.conf \ && /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone \ && sed -i 's@dir ./$@dir /data/redis/data@g' /etc/redis/6379.conf \ && yum clean all \ && rm -rf /var/cache/yum/* WORKDIR /data/redis EXPOSE 6379 ENTRYPOINT /usr/local/bin/redis-server /etc/redis/6379.conf && tail -f -n20 /var/log/redis_6379.log
FROM centos:7 LABEL maintainer augustyang RUN yum install -y gcc gcc-c++ make \ openssl-devel pcre-devel gd-devel \ iproute net-tools telnet wget curl && \ yum clean all && \ rm -rf /var/cache/yum/* COPY nginx-1.15.5.tar.gz / RUN tar zxf nginx-1.15.5.tar.gz && \ cd nginx-1.15.5 && \ ./configure --prefix=/usr/local/nginx \ --with-http_ssl_module \ --with-http_stub_status_module && \ make -j 4 && make install && \ rm -rf /usr/local/nginx/html/* && \ echo "ok" >> /usr/local/nginx/html/status.html && \ cd / && rm -rf nginx* && \ ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime ENV PATH $PATH:/usr/local/nginx/sbin COPY nginx.conf /usr/local/nginx/conf/nginx.conf WORKDIR /usr/local/nginx EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]
FROM centos:7 MAINTAINER augustyang # tomcat ENV VERSION=8.5.43 RUN yum install java-1.8.0-openjdk wget curl unzip iproute net-tools -y && \ yum clean all && \ rm -rf /var/cache/yum/* COPY apache-tomcat-${VERSION}.tar.gz / RUN tar zxf apache-tomcat-${VERSION}.tar.gz && \ mv apache-tomcat-${VERSION} /usr/local/tomcat && \ rm -rf apache-tomcat-${VERSION}.tar.gz /usr/local/tomcat/webapps/* && \ mkdir /usr/local/tomcat/webapps/test && \ echo "ok" > /usr/local/tomcat/webapps/test/status.html && \ sed -i '1a JAVA_OPTS="-Djava.security.egd=file:/dev/./urandom"' /usr/local/tomcat/bin/catalina.sh && \ ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime ENV PATH $PATH:/usr/local/tomcat/bin WORKDIR /usr/local/tomcat EXPOSE 8080 CMD ["catalina.sh", "run"]
FROM java:8-jdk-alpine LABEL maintainer augustyang # java ENV JAVA_OPTS="$JAVA_OPTS -Dfile.encoding=UTF8 -Duser.timezone=GMT+08" RUN apk add -U tzdata && \ ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime COPY ./target/eureka-service.jar ./ EXPOSE 8888 CMD java -jar $JAVA_OPTS /eureka-service.jar
FROM centos:7 MAINTAINER augustyang # php 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/* COPY php-5.6.36.tar.gz / RUN 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 \ --enable-fpm --enable-opcache \ --with-mysql --with-mysqli --with-pdo-mysql \ --with-openssl --with-zlib --with-curl --with-gd \ --with-jpeg-dir --with-png-dir --with-freetype-dir \ --enable-mbstring --with-mcrypt --enable-hash && \ 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 && \ cd / && rm -rf php* && \ ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime ENV PATH $PATH:/usr/local/php/sbin COPY php.ini /usr/local/php/etc/ COPY php-fpm.conf /usr/local/php/etc/ WORKDIR /usr/local/php EXPOSE 9000 CMD ["php-fpm"]
注:ENTRYPOINT須要放在CDM前面 。
CMD 啓動帶參數會替換cmd內的內容
啓動容器帶參數:所帶參數替換默認參數
啓動容器沒帶參數:起默認參數,
ENTRYPOINT 不會替換 ENTRYPOINT內的內容