1. 程式人生 > >贏咖2招商97916

贏咖2招商97916

-a cte serve des exists repo ora href oci

為實現持久化,docker引入了掛載數據卷的方法,以實現數據的可持久化。具體是以下三種:
一.通過docker run命令
命令:
docker run -dit --name gerrit -p 9001:8080 -p 29419:29418 -v /home/docker/test.txt:/var/spool/cron/crontabs/root openfrontier/gerrit:2.15.3
此時將宿主機的/data/mysql1掛載到容器的/var/lib/mysql下,這裏需要註意的還分以下幾種情況:
A.掛載本地不存在的文件,到容器中已存在的文件,無法啟動
docker run -dit --name gerrit -p 9001:8080 -p 29419:29418 -v /home/docker/review_site_test/root:/var/spool/cron/crontabs/root openfrontier/gerrit:2.15.3

結果無法啟動

B.掛載本地不存在的文件夾,到容器內已存在的文件夾,可以啟動,但會清空容器內的指定目錄/var/spool/cron/crontabs下的所有文件
docker run -dit --name gerrit -p 9001:8080 -p 29419:29418 -v /home/docker/review_site_test:/var/spool/cron/crontabs openfrontier/gerrit:2.15.3

結果可以啟動

但需要註意的是掛載本地不存在的文件夾過去,會清空當前容器的指定文件夾。如果容器中對該文件夾有啟動依賴,例如上面的gerrit鏡像:
使用下面的命令就無法啟動:
docker run -dit --name gerrit -p 9001:8080 -p 29419:29418 -v /home/docker/review-site21a:/usr/share/gitweb openfrontier/gerrit:2.15.3

原因:gerrit依賴於gitweb

C.掛載本地存在的文件,到容器內指定文件,可以啟動,該文件會覆蓋你指定的文件
[root@zzw docker]# cat test.txt
askdkjajksdk

[root@zzw docker]# docker run -dit --name gerrit -p 9001:8080 -p 29419:29418 -v /home/docker/test.txt:/var/spool/cron/crontabs/root openfrontier/gerrit:2.15.3
c86aac5a73d551163c262bdf4db8cc4253322ac4c41d2d2418675c5b4f63e62a

bash-4.4# cd /var/spool/cron/crontabs
bash-4.4# ls
root
bash-4.4# vim root
bash: vim: command not found
bash-4.4# cat root
askdkjajksdk

D.掛載本地存在的文件夾test,到容器裏已存在的文件夾,發現test目錄中的文件,直接到容器內指定目錄下
[root@zzw docker]# docker run -dit --name gerrit -p 9001:8080 -p 29419:29418 -v /home/docker/test:/var/spool/cron/crontabs openfrontier/gerrit:2.15.3
9c32db2cff1d8d7ed3636a812302470d9408f4c60786067a57da770b930ae01f
[root@zzw docker]# docker exec -it gerrit /bin/bash
bash-4.4# cd /var/spool/cron/
bash-4.4# ls
crontabs
bash-4.4# cd crontabs
bash-4.4# ls
test.txt
bash-4.4# vim test.txt
bash: vim: command not found
bash-4.4# cat test.txt
askdkjajksdk

F.掛載本地存在的文件夾test,到容器裏不存在的文件夾,會在容器內創建該test文件夾
E的變種
[root@zzw docker]# docker run -dit --name gerrit -p 9001:8080 -p 29419:29418 -v /home/docker/test:/var/spool/cron/test openfrontier/gerrit:2.15.3
53fb24583eb65278599975ca515000080267e8348e945f1fcbd4fc4f8e6cb165
[root@zzw docker]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
53fb24583eb6 openfrontier/gerrit:2.15.3 "/gerrit-entrypoin..." 4 seconds ago Up 2 seconds 0.0.0.0:9001->8080/tcp, 0.0.0.0:29419->29418/tcp gerrit
d114a167bbcc nginx:1.15.2-alpine "nginx -g ‘daemon ..." 41 hours ago Exited (0) 35 minutes ago test_nginx_1
641508207b44 mysql:5.7 "docker-entrypoint..." 41 hours ago Exited (0) 35 minutes ago test_db_1
[root@zzw docker]# docker exec -it gerrit /bin/bash
bash-4.4# cd /var/spool/cron/
bash-4.4# ls
crontabs test
bash-4.4# cd test/
bash-4.4# ls
test.txt

G.掛載本地是文件test.txt,到容器內指定的目錄crontabs,報錯
[root@zzw docker]# docker run -dit --name gerrit -p 9001:8080 -p 29419:29418 -v /home/docker/test/test.txt:/var/spool/cron/crontabs openfrontier/gerrit:2.15.3
e63487c08abce10c8bdbcf834714ad0994a93118abdd5126969856f862ca7f0b
/usr/bin/docker-current: Error response from daemon: oci runtime error: container_linux.go:247: starting container process caused "process_linux.go:364: container init caused \"rootfs_linux.go:54: mounting \"/home/docker/test/test.txt\" to rootfs \"/var/lib/docker/overlay2/5b0428b09a0727e114f06d312106e4fb28bc31d728abd27dab2f30328497c3c7/merged\" at \"/var/lib/docker/overlay2/5b0428b09a0727e114f06d312106e4fb28bc31d728abd27dab2f30328497c3c7/merged/etc/crontabs\" caused \"not a directory\"\""
: Are you trying to mount a directory onto a file (or vice-versa)? Check if the specified host path exists and is the expected type.

看過第一種肯定有一些疑惑,因為有些鏡像是違背第一種原則,即宿主機不存在某個目錄,-v參數指定的宿主機目錄:容器目錄,容器目錄裏的東西立馬都到宿主機指定的目錄下了,不是因為宿主機的空目錄覆蓋掉容器的指定目錄嗎?怎麽容器目錄裏的東西全都過來呢?
例如你用這條命令試試:
docker run -dit --name gerrit -p 9001:8080 -p 29419:29418 -v /home/docker/test1:/var/gerrit/review_site openfrontier/gerrit:2.15.3

別著急等會兒解釋。

二.通過dockerfile中的volume創建掛載點
下面我們看下mysql的dockerfile

FROM debian:stretch-slim

add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added

RUN groupadd -r mysql && useradd -r -g mysql mysql

RUN apt-get update && apt-get install -y --no-install-recommends gnupg dirmngr && rm -rf /var/lib/apt/lists/*

add gosu for easy step-down from root

ENV GOSU_VERSION 1.7
RUN set -x \
&& apt-get update && apt-get install -y --no-install-recommends ca-certificates wget && rm -rf /var/lib/apt/lists/* \
&& wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture)" \
&& wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture).asc" \
&& export GNUPGHOME="$(mktemp -d)" \
&& gpg --batch --keyserver ha.pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 \
&& gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu \
&& gpgconf --kill all \
&& rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc \
&& chmod +x /usr/local/bin/gosu \
&& gosu nobody true \
&& apt-get purge -y --auto-remove ca-certificates wget

RUN mkdir /docker-entrypoint-initdb.d

RUN apt-get update && apt-get install -y --no-install-recommends \

for MYSQL_RANDOM_ROOT_PASSWORD

    pwgen \

for mysql_ssl_rsa_setup

    openssl \

FATAL ERROR: please install the following Perl modules before executing /usr/local/mysql/scripts/mysql_install_db:

File::Basename

File::Copy

Sys::Hostname

Data::Dumper

    perl && rm -rf /var/lib/apt/lists/*

RUN set -ex; \

gpg: key 5072E1F5: public key "MySQL Release Engineering <[email protected]>" imported

key=‘A4A9406876FCBD3C456770C88C718D3B5072E1F5‘; export GNUPGHOME="$(mktemp -d)"; gpg --batch --keyserver ha.pool.sks-keyservers.net --recv-keys "$key"; gpg --batch --export "$key" > /etc/apt/trusted.gpg.d/mysql.gpg; gpgconf --kill all; rm -rf "$GNUPGHOME"; apt-key list > /dev/null

ENV MYSQL_MAJOR 5.7
ENV MYSQL_VERSION 5.7.25-1debian9

RUN echo "deb http://repo.mysql.com/apt/debian/ stretch mysql-${MYSQL_MAJOR}" > /etc/apt/sources.list.d/mysql.list

the "/var/lib/mysql" stuff here is because the mysql-server postinst doesn‘t have an explicit way to disable the mysql_install_db codepath besides having a database already "configured" (ie, stuff in /var/lib/mysql/mysql)

also, we set debconf keys to make APT a little quieter

RUN { \
echo mysql-community-server mysql-community-server/data-dir select ‘‘; \
echo mysql-community-server mysql-community-server/root-pass password ‘‘; \
echo mysql-community-server mysql-community-server/re-root-pass password ‘‘; \
echo mysql-community-server mysql-community-server/remove-test-db select false; \
} | debconf-set-selections \
&& apt-get update && apt-get install -y mysql-server="${MYSQL_VERSION}" && rm -rf /var/lib/apt/lists/* \
&& rm -rf /var/lib/mysql && mkdir -p /var/lib/mysql /var/run/mysqld \
&& chown -R mysql:mysql /var/lib/mysql /var/run/mysqld \

ensure that /var/run/mysqld (used for socket and lock files) is writable regardless of the UID our mysqld instance ends up having at runtime

&& chmod 777 /var/run/mysqld \

comment out a few problematic configuration values

&& find /etc/mysql/ -name ‘*.cnf‘ -print0     | xargs -0 grep -lZE ‘^(bind-address|log)‘     | xargs -rt -0 sed -Ei ‘s/^(bind-address|log)/#&/‘ \

don‘t reverse lookup hostnames, they are usually another container

&& echo ‘[mysqld]\nskip-host-cache\nskip-name-resolve‘ > /etc/mysql/conf.d/docker.cnf

VOLUME /var/lib/mysql

COPY docker-entrypoint.sh /usr/local/bin/
RUN ln -s usr/local/bin/docker-entrypoint.sh /entrypoint.sh # backwards compat
ENTRYPOINT ["docker-entrypoint.sh"]

EXPOSE 3306 33060
CMD ["mysqld"]
很明顯有個標簽:
VOLUME
這個標簽我理解是將容器目錄暴露出去,簡單理解就是容器中的目錄可以掛載到宿主機的某個匿名目錄,一般是在docker的主程序目錄下,一般沒做修改的話就是/var/lib/docker下,我這裏是/data/docker
來看下具體命令:
docker中數據卷探究與總結

那麽我們到標紅的那段裏面看看,是否和/var/lib/mysql一樣呢?結果是一樣的
docker中數據卷探究與總結

那老是匿名不是個事,我們能指定嗎?
第一種方法-v不就行了嗎?
下面試試:
docker中數據卷探究與總結
結果發現是可以了,/var/lib/mysql裏的東西全部到/data/mysql1裏面了,這裏其實是容器的目錄復制到指定目錄,宿主機的指定目錄再掛載到容器的指定目錄中,這理解起來可能有些困難,但是確實是這樣。
那麽我們就很好解決了上面gerrit數據卷的問題了,因為它的dockerfile裏面也是有VOLUME標簽的。

三.使用--volumes-from參數指定掛載的容器的宿主機目錄
上圖,不多bb
docker中數據卷探究與總結
可以發現mysql1和mysql用的是用一個宿主機目錄/data/mysql1

好了,數據卷東西就寫到這了

贏咖2招商97916