1、為什么會出現(xiàn)docker?一般情況下是開發(fā)人員開發(fā)好代碼,本地測試通過后,打成jar包或者war包,交給運維人員,部署到服務(wù)器上。就是這么個過程,經(jīng)常會出現(xiàn)如下場景:
一樣的代碼,本地可以跑,服務(wù)器上就不行,那這就是環(huán)境的問題和配置的問題了。而且,一個產(chǎn)品從開發(fā)到上線,往往有開發(fā)環(huán)境,測試環(huán)境,仿真環(huán)境和生產(chǎn)環(huán)境,每個環(huán)境我們都需要安裝一遍mysql、redis、nginx,activemq等,運維的工作量也挺大,而且都是重復的工作。為了解決這些痛點,docker就出現(xiàn)了。
2、是什么?
docker就是一個容器,一次構(gòu)建,處處運行。也就是說,我開發(fā)環(huán)境安裝了mysql、redis,我可以直接將這兩個鏡像搬到測試環(huán)境,開箱即用,而不用重新去配置。
3、虛擬機技術(shù)和容器技術(shù):
4、docker的核心概念:
容器:就是docker的logo鯨魚背上那一個個地集裝箱。一個集裝箱就是一個容器,比如你在docker上要安裝redis、mysql、jdk,那么就需要三個集裝箱,也就是三個容器。
鏡像:用來生成容器實例的東西
倉庫:存放鏡像的地方。有個叫docker hub的網(wǎng)站,它就是倉庫。不過國內(nèi)訪問docker hub特別慢,國內(nèi)一般用阿里云和網(wǎng)易云的倉庫。
1、安裝前提:
cat /etc/redhat-release
uname -r
2、docker的安裝:
centos 6安裝docker:
yum install -y epel-release
yum install -y docker-io
/etc/sysconfig/docker
service docker start
docker version
,出現(xiàn)版本信息說明安裝成功。centos 7安裝docker:
yum install -y gcc
,yum install -y gcc-c++
,安裝完執(zhí)行gcc -v
有版本信息就安裝成功。yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
yum install -y yum-utils
yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum makecache fast
yum install -y docker-ce
systemctl start docker
docker -v
,有版本信息則安裝成功,再執(zhí)行docker run hello-world
,會有 hello from docker的信息。mkdir -p /etc/docker
vim /etc/docker/daemon.json
systemctl daemon-reload
systemctl restart docker
daemon.json的內(nèi)容如下:
# 網(wǎng)易云
{"registry-mirrors":["http://hub-mirror.c.163.com"]}
# 阿里云
{"registry-mirrors":["你阿里云的鏡像加速鏈接"]}
獲取阿里云加速鏡像鏈接的方法:登陸https://cr.console.aliyun.com,然后點擊左下角的“鏡像加速器”即可。
systemctl stop docker
yum -y remove docker-ce
rm -rf /var/lib/docker
3、hello world:上面說過執(zhí)行docker run hello-world
會打印出相關(guān)信息,執(zhí)行這條命令過程如下:
1、幫助命令:
docker -v
docker info
docker --help
,類似linux的man
命令2、鏡像命令:回顧一下docker的logo,海上有一頭鯨魚,鯨魚背上有一個個的集裝箱。對應(yīng)關(guān)系如下:
常用鏡像命令如下:
docker images
docker images -a
docker images -q
docker images -qa
docker images --digests
docker images --no-trunc
docker search xxx
docker search -s 30 xxx
docker search -s 30 --no-trunc xxx
docker search --automated xxx
docker pull xxx
docker rmi xxx
docker rmi -f xxx
docker rmi -f xxx yyy
docker rmi -f $(docker images -qa)
3、容器命令:首先我們執(zhí)行docker pull centos
拉取一個centos的鏡像,下面所說的容器都是指centos(都可以是名字或者id)。
docker run -it centos
--name
:為容器指定名字;-d
:后臺運行容器;-P
:隨機端口映射;-p
:指定端口映射;-i
:以交互模式運行容器;-t
:為容器重新分配一個偽輸入終端,常與-i
一起使用docker ps
-a
:列出當前運行和歷史上運行過的容器;-l
:顯示最近創(chuàng)建的容器;-n
:顯示最近創(chuàng)建的n個容器;-q
:靜默模式,只顯示容器編號;--no-trunc
:顯示完整摘要信息exit
:容器停止退出;ctrl + p + q
:容器不停止退出docker start centos
docker restart centos
docker stop centos
docker kill centos
docker rm -f centos
docker rm -f $(docker ps -a -q
或者docker ps -a -q | xargs docker rm
docker run -d centos
,啟動后,再docker ps
,發(fā)現(xiàn)根本就沒有正在運行的容器,但是剛剛確實啟動成功了,因為啟動后返回了一個id。這是docker的機制造成的,后臺啟動docker容器,前臺沒有交互,docker會認為它沒事可做,就殺死了。docker logs -f -t --tail n 容器id
docker top 容器id
docker inspect 容器id
docker attach 容器id
docker exec -t 容器id 命令
;比如不進入docker上運行的centos直接執(zhí)行ls /
命令:docker exec -t centos的id ls /
docker cp 容器id:容器內(nèi)路徑 主機路徑
1、什么是鏡像?鏡像是一種輕量級的可執(zhí)行的獨立軟件包。用來打包軟件運行環(huán)境和基于運行環(huán)境開發(fā)的軟件,包括代碼、運行時、庫、環(huán)境變量和配置文件。docker底層是一個unionFS(聯(lián)合文件系統(tǒng)),即是一層一層的文件系統(tǒng)組成。
2、鏡像為什么那么大?執(zhí)行docker pull tomcat
命令,下載一個tomcat鏡像,然后執(zhí)行docker images
,發(fā)現(xiàn)一個tomcat就600多兆,為什么那么大?因為剛才說的,鏡像是一個聯(lián)合文件系統(tǒng),tomcat鏡像不僅僅包含tomcat,還包含tomcat運行的各種環(huán)境,一個鏡像包含了很多層,分層鏡像如下:
3、docker為什么采用分層鏡像?最大的好處就是共享資源。比如多個鏡像都需要jdk,那么宿主機上其實只要保存一份jdk就可以了,內(nèi)存中也只需要加載一份。鏡像的每一層都是可以共享的。
4、docker commit命令:首先我們運行docker run -it -p 8888:8080 tomcat
,這里表示docker內(nèi)部將tomcat運行在8080端口,對外暴露8888端口,即執(zhí)行完這條命令,我們要用8888端口才能訪問到tomcat。如果你訪問到的是404,不要方,這是因為你下載的這個版本的tomcat,webapps目錄是空的,資源都在webapps-dist目錄下,可以執(zhí)行如下操作:
docker exec -it tomcat容器的id /bin/bash
ls -l
mv webapps webapps2
mv webapps.dist webapps
刷新頁面,就可以看到熟悉的tomcat首頁了。上面是指定對外暴露8888端口,還可以執(zhí)行docker run -it -P tomcat
,大寫的P表示隨機分配端口,不自己指定。用這個命令啟動后,執(zhí)行docker ps
,就可以看到隨機分配的端口是什么。
上面我們對tomcat做了一些修改,把訪問會報404的tomcat改成了一個正常的tomcat,我們就可以使用commit命令以我們改好的tomcat為模板,生成一個啟動就能直接訪問的新的tomcat鏡像。執(zhí)行如下命令:docker commit -a="zhusl" -m="normal tomcat" 容器id newtomcat:1.0
1、是什么?我們在docker上運行容器實例,運行時產(chǎn)生的數(shù)據(jù),當docker關(guān)閉了就沒了。但是我們希望有些數(shù)據(jù)可以持久化保存下來,這個保存的地方的就是容器數(shù)據(jù)卷,并且保存下來的數(shù)據(jù)可以共享。
2、容器數(shù)據(jù)卷的特點:
3、添加數(shù)據(jù)卷的方法:添加數(shù)據(jù)卷有兩種方法,一種是命令添加,一種是用dockerfile。命令添加:
添加數(shù)據(jù)卷命令:docker run -it -v /宿主機絕對路徑目錄:/容器內(nèi)目錄 鏡像名
比如執(zhí)行docker run -it -v /mydatadir:/dockerdatadir centos
,就表示讓centos這個鏡像和主機之間建立數(shù)據(jù)卷,主機根目錄下的mydatadir
和centos鏡像根目錄下的dockerdatadir
目錄建立連接,進行數(shù)據(jù)共享。目錄不存會自動新建目錄。執(zhí)行了以上命令后,先查看主機根目錄下是否有mydatadir目錄,然后再執(zhí)行docker run -it centos /bin/bash
,ls查看一下centos鏡像的根目錄下是否有dockerdatadir目錄。
查看數(shù)據(jù)卷是否掛載成功:docker inspect 容器id
。如果你看到兩個目錄都成功新建了還是不放心,可以用這條命令查看,如果在返回的內(nèi)容中看到了如下信息則掛載成功。
驗證通過數(shù)據(jù)卷可實現(xiàn)數(shù)據(jù)共享:首先在主機的mydatadir目錄下新建一個test.txt文件,然后發(fā)現(xiàn)centos的鏡像的dockerdatadir目錄也有test.txt文件。然后再centos鏡像中往test.txt文件些內(nèi)容,回到主機再次查看test.txt文件,發(fā)現(xiàn)也是有內(nèi)容的。并且容器推出后,在主機上的mydatadir目錄下做的任何操作,在容器重啟后,都會被同步到dockerdatadir目錄下。
以只讀方式添加數(shù)據(jù)卷:docker run -it -v /宿主機絕對路徑目錄:/容器內(nèi)目錄:ro 鏡像名
,加上ro,表示read only,容器只能讀數(shù)據(jù),不能進行寫操作。
dockerFile添加:
mydocker
文件夾;mydocker
目錄,新建dockerfile文件:vim dockerfile
,文件內(nèi)容如下:FROM centos
VOLUME ["/dockerdatadir1","/dockerdatadir2"]
CMD echo "finished,---------success"
CMD /bin/bash
docker build -f /mydocker/dockerfile -t zhusl/centos .
docker images
,發(fā)現(xiàn)已經(jīng)有zhusl/centos這個鏡像了。這個鏡像就是,我們以centos鏡像為來源,添加了數(shù)據(jù)卷,新生成的一個centos。docker inspect 容器id
,就可以看到了,如下圖:4、數(shù)據(jù)卷容器:上面說了數(shù)據(jù)卷,數(shù)據(jù)卷容器其實就是數(shù)據(jù)卷之間的傳遞性。比如還是以zhusl/centos鏡像為例,先執(zhí)行docker run -it --name dc01 zhusl/centos
,運行一個名為dc01的實例,然后再執(zhí)行docker run -it --name doc02 --volumes-from dc02 zhusl/centos
,以dc01為父容器,運行一個dc02。因為zhusl/centos是添加了數(shù)據(jù)卷的,所以運行的dc01是掛載了數(shù)據(jù)卷的,然后dc02又是from dc01,所以dc02也掛載了數(shù)據(jù)卷。如果還有一個dc03也是繼承自dc01,當dc01掛了,dc02和dc03之間也是可以進行數(shù)據(jù)共享的。
1、是什么?就是一個寫命令的文件,然后通過這個文件,就可以構(gòu)建鏡像。
2、構(gòu)建的三個步驟:
登陸docker hub,然后隨便搜索一個鏡像,就以centos為例,選擇版本然后進入,就可以看到它的dockerfile文件內(nèi)容。如下就是centos7的dockerfile文件內(nèi)容:
FROM scratch
ADD centos-7-x86_64-docker.tar.xz /
LABEL \
org.label-schema.schema-version="1.0" \
org.label-schema.name="CentOS Base Image" \
org.label-schema.vendor="CentOS" \
org.label-schema.license="GPLv2" \
org.label-schema.build-date="20200504" \
org.opencontainers.image.title="CentOS Base Image" \
org.opencontainers.image.vendor="CentOS" \
org.opencontainers.image.licenses="GPL-2.0-only" \
org.opencontainers.image.created="2020-05-04 00:00:00+01:00"
CMD ["/bin/bash"]
3、dockerfile內(nèi)容基礎(chǔ)知識:
4、dockerfile的執(zhí)行流程:
5、dockerfile的保留字:
6、dockerfile構(gòu)建鏡像實操:
# 基于docker hub上拉下來的centos進行構(gòu)建
FROM centos
# 容器啟動后工作目錄
WORKDIR ~
# 安裝vim
RUN yum -y install vim
# 安裝網(wǎng)絡(luò)工具,使其能用ifconfig命令
RUN yum -y install net-tools
# 端口號
EXPOSE 80
CMD /bin/bash
新建一個dockerfile2文件,內(nèi)容就是上面那段,然后執(zhí)行docker build -f /mydocker/dockerfile2 -t mycentos:1.0 .
進行構(gòu)建。-f后面的是dockerfile2文件的路徑,mycentos是鏡像名字,1.0是版本號,.代表當前路徑。
執(zhí)行完后,docker images
就會發(fā)現(xiàn)有一個新鏡像,名字叫mycentos。然后運行該鏡像,就會發(fā)現(xiàn)這個mycentos可以使用vim和ifconfig的。再回溯一個問題,鏡像那么大,是因為它包含了它運行所需的所有環(huán)境,那么是不是很浪費空間?就比如這個,我原本有一個centos鏡像,只不過沒有vim編輯器,現(xiàn)在我構(gòu)建一個新的有vim的mycentos,docker images 顯示centos 600M,mycentos 620M,那這兩個是不是就要占用1個G?其實并不是,因為鏡像是可以共享的,mycentos 是form centos的,也就是說這600其實是共用的,最后這兩個鏡像其實占空間就是620M。
執(zhí)行docker history 鏡像id
,就可以列出鏡像的歷史,即這個鏡像有多少層。
案例2:CMD指令的使用:執(zhí)行docker run -it -p 7777:8080 tomcat ls -l
,就是在啟動命令后追加ls -l
參數(shù),列出登陸后的目錄。然后發(fā)現(xiàn)tomcat根本就沒有啟動,只是列出了tomcat的目錄。因為dockerfile的CMD命令只有最后一行生效,ls -l
這個命令把啟動tomcat的CMD覆蓋了,所以沒啟動。
案例3:ENTRYPOINT的使用:新建一個dockerfile3,內(nèi)容如下:
FROM centos
RUN yum install -y curl
CMD ["curl","-s","http://ip.cn"]
意思就是制作一個鏡像,一啟動,就可以查出本機的IP。執(zhí)行docker build -f /mydocker/dockerfile3 -t myip .
進行構(gòu)建。然后運行該容器,就可以打印出ip信息。如果過執(zhí)行的時候想加參數(shù),比如docker run -it myip -i
,實際上就是想執(zhí)行curl的時候加上-i
參數(shù),打印請求頭信息,那么抱歉,-i
會覆蓋之前的命令,即覆蓋CMD ["curl","-s","http://ip.cn"]
這一樣,然后-i
根本就不是一個可執(zhí)行命令,所以執(zhí)行報錯。要實現(xiàn)上面的需求,即加個-i
,讓它真正執(zhí)行的是curl -s -i https://ip.cn
,只需要把CMD
換成ENTRYPOINT
,然后啟動容器時用docker run -it myip -i
即可。
ONBUILD
的使用:修改dockerfile3,在后面加上如下的命令:ONBUILD RUN echo "我被觸發(fā)了"
然后,新建dockerfile4,F(xiàn)ROM myip,build的時候會打印出 "我被觸發(fā)了" 這一句話。
COPY
和ADD
的使用。首先在opt目錄下先搞兩個tar.gz包和一個copy.txt文件,一個jdk8,一個tomcat9。編寫dockerfile,內(nèi)容如下:FROM centos
# 復制文件
COPY copy.txt /usr/local/cincontainer.txt
# 添加并解壓jdk
ADD jdk-8u171-linux-x64.tar.gz /usr/local
# 添加并解壓tomcat9
ADD apache-tomcat-9.0.8.tar.gz /usr/local
# 安裝vim
RUN yum install -y install vim
# 設(shè)置登陸落腳點
ENV MYPATH /usr/local
WORKDIR $MYPATH
# 配置jdk和tomcat環(huán)境變量
ENV JAVA_HOME /usr/local/jdk1.8.0_171
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.8
ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.8
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:CATALINA_HOME/bin
# 指定容器運行端口
EXPOSE 8080
# 啟動命令
CMD /usr/lcoal/apache-tomcat-9.0.8/bin/startup.sh && tail -F /usr/local/apache-tomat-9.0.8/bin/logs/catalina.out
1、MySQL:
docker pull mysql:5.7
docker run -p 3306:3306 --name mysql -v /zhusl/mysql/conf:/etc/mysql/conf.d -v /zhusl/mysql/logs:/logs -v /zhusl/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
docker exec -it 容器id /bin/bash
mysql -u root -p
2、redis:
docker search redis
docker pull redis
docker run -p 6379:6379 -v /zhusl/redis/data:/data -v /zhusl/redis/conf/redis.conf:/usr/local/etc/redis/redis.conf -d redis redis-server /usr/local/etc/redis/redis.conf --appendonly yes
appendonly yes表示開啟aof。docker exec -it redis容器id redis-cli
docker login --username= registry.cn-hangzhou.aliyuncs.com
# 執(zhí)行完上一條命令會要你輸入用戶名和密碼
docker tag 鏡像id registry.cn-hangzhou.aliyuncs.com/zhushulin/redis:鏡像版本號
docker push registry.cn-hangzhou.aliyuncs.com/zhushulin/redis:鏡像版本號