Ceci est une ancienne révision du document !


Version : 2020.01

Dernière mise-à-jour : 2020/02/08 12:36

DOF103 - Gestion des Volumes, du Réseau et des Ressources

Cette unité contient quatre LABs :

  • LAB #4 - Gestion des Volumes,
  • LAB #5 - Gestion du Réseau,
  • LAB #6 - Superviser les Conteneurs,
  • LAB #7 - Gestion des Ressources.

LAB #4 - Gestion des Volumes

Préparation

Creéz le répertoire /root/mongodb :

root@debian9:~# mkdir mongodb
root@debian9:~# cd mongodb/
root@debian9:~/mongodb# touch Dockerfile docker-entrypoint.sh

Le Docker file contient les instructions nécessaires pour la contruction de l'image :

root@debian9:~# vi Dockerfile
root@debian9:~# cat Dockerfile
FROM ubuntu:bionic

# add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added
RUN groupadd -r mongodb && useradd -r -g mongodb mongodb

RUN set -eux; \
	apt-get update; \
	apt-get install -y --no-install-recommends \
		ca-certificates \
		jq \
		numactl \
	; \
	if ! command -v ps > /dev/null; then \
		apt-get install -y --no-install-recommends procps; \
	fi; \
	rm -rf /var/lib/apt/lists/*

# grab gosu for easy step-down from root (https://github.com/tianon/gosu/releases)
ENV GOSU_VERSION 1.11
# grab "js-yaml" for parsing mongod's YAML config files (https://github.com/nodeca/js-yaml/releases)
ENV JSYAML_VERSION 3.13.0

RUN set -ex; \
	\
	apt-get update; \
	apt-get install -y --no-install-recommends \
		wget \
	; \
	if ! command -v gpg > /dev/null; then \
		apt-get install -y --no-install-recommends gnupg dirmngr; \
	fi; \
	rm -rf /var/lib/apt/lists/*; \
	\
	dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')"; \
	wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch"; \
	wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch.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; \
	command -v gpgconf && gpgconf --kill all || :; \
	rm -r "$GNUPGHOME" /usr/local/bin/gosu.asc; \
	chmod +x /usr/local/bin/gosu; \
	gosu --version; \
	gosu nobody true; \
	\
	wget -O /js-yaml.js "https://github.com/nodeca/js-yaml/raw/${JSYAML_VERSION}/dist/js-yaml.js"; \
# TODO some sort of download verification here
	\
	apt-get purge -y --auto-remove wget

RUN mkdir /docker-entrypoint-initdb.d

ENV GPG_KEYS E162F504A20CDF15827F718D4B7C549A058F8B6B
RUN set -ex; \
	export GNUPGHOME="$(mktemp -d)"; \
	for key in $GPG_KEYS; do \
		gpg --batch --keyserver ha.pool.sks-keyservers.net --recv-keys "$key"; \
	done; \
	gpg --batch --export $GPG_KEYS > /etc/apt/trusted.gpg.d/mongodb.gpg; \
	command -v gpgconf && gpgconf --kill all || :; \
	rm -r "$GNUPGHOME"; \
	apt-key list

# Allow build-time overrides (eg. to build image with MongoDB Enterprise version)
# Options for MONGO_PACKAGE: mongodb-org OR mongodb-enterprise
# Options for MONGO_REPO: repo.mongodb.org OR repo.mongodb.com
# Example: docker build --build-arg MONGO_PACKAGE=mongodb-enterprise --build-arg MONGO_REPO=repo.mongodb.com .
ARG MONGO_PACKAGE=mongodb-org-unstable
ARG MONGO_REPO=repo.mongodb.org
ENV MONGO_PACKAGE=${MONGO_PACKAGE} MONGO_REPO=${MONGO_REPO}

ENV MONGO_MAJOR 4.1
ENV MONGO_VERSION 4.1.9
# bashbrew-architectures:amd64 arm64v8 s390x
RUN echo "deb http://$MONGO_REPO/apt/ubuntu bionic/${MONGO_PACKAGE%-unstable}/$MONGO_MAJOR multiverse" | tee "/etc/apt/sources.list.d/${MONGO_PACKAGE%-unstable}.list"

RUN set -x \
	&& apt-get update \
	&& apt-get install -y \
		${MONGO_PACKAGE}=$MONGO_VERSION \
		${MONGO_PACKAGE}-server=$MONGO_VERSION \
		${MONGO_PACKAGE}-shell=$MONGO_VERSION \
		${MONGO_PACKAGE}-mongos=$MONGO_VERSION \
		${MONGO_PACKAGE}-tools=$MONGO_VERSION \
	&& rm -rf /var/lib/apt/lists/* \
	&& rm -rf /var/lib/mongodb \
	&& mv /etc/mongod.conf /etc/mongod.conf.orig

RUN mkdir -p /data/db /data/configdb \
	&& chown -R mongodb:mongodb /data/db /data/configdb
VOLUME /data/db /data/configdb

COPY docker-entrypoint.sh /usr/local/bin/
ENTRYPOINT ["docker-entrypoint.sh"]

EXPOSE 27017
CMD ["mongod"]

Créez le fichier docker-entrypoint.sh sert à lancer le serveur mongodb dans le conteneur :

root@debian9:~# vi docker-entrypoint.sh
root@debian9:~# cat docker-entrypoint.sh
#!/bin/bash
set -Eeuo pipefail

if [ "${1:0:1}" = '-' ]; then
	set -- mongod "$@"
fi

originalArgOne="$1"

# allow the container to be started with `--user`
# all mongo* commands should be dropped to the correct user
if [[ "$originalArgOne" == mongo* ]] && [ "$(id -u)" = '0' ]; then
	if [ "$originalArgOne" = 'mongod' ]; then
		find /data/configdb /data/db \! -user mongodb -exec chown mongodb '{}' +
	fi

	# make sure we can write to stdout and stderr as "mongodb"
	# (for our "initdb" code later; see "--logpath" below)
	chown --dereference mongodb "/proc/$$/fd/1" "/proc/$$/fd/2" || :
	# ignore errors thanks to https://github.com/docker-library/mongo/issues/149

	exec gosu mongodb "$BASH_SOURCE" "$@"
fi

# you should use numactl to start your mongod instances, including the config servers, mongos instances, and any clients.
# https://docs.mongodb.com/manual/administration/production-notes/#configuring-numa-on-linux
if [[ "$originalArgOne" == mongo* ]]; then
	numa='numactl --interleave=all'
	if $numa true &> /dev/null; then
		set -- $numa "$@"
	fi
fi

# usage: file_env VAR [DEFAULT]
#    ie: file_env 'XYZ_DB_PASSWORD' 'example'
# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of
#  "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature)
file_env() {
	local var="$1"
	local fileVar="${var}_FILE"
	local def="${2:-}"
	if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then
		echo >&2 "error: both $var and $fileVar are set (but are exclusive)"
		exit 1
	fi
	local val="$def"
	if [ "${!var:-}" ]; then
		val="${!var}"
	elif [ "${!fileVar:-}" ]; then
		val="$(< "${!fileVar}")"
	fi
	export "$var"="$val"
	unset "$fileVar"
}

# see https://github.com/docker-library/mongo/issues/147 (mongod is picky about duplicated arguments)
_mongod_hack_have_arg() {
	local checkArg="$1"; shift
	local arg
	for arg; do
		case "$arg" in
			"$checkArg"|"$checkArg"=*)
				return 0
				;;
		esac
	done
	return 1
}
# _mongod_hack_get_arg_val '--some-arg' "$@"
_mongod_hack_get_arg_val() {
	local checkArg="$1"; shift
	while [ "$#" -gt 0 ]; do
		local arg="$1"; shift
		case "$arg" in
			"$checkArg")
				echo "$1"
				return 0
				;;
			"$checkArg"=*)
				echo "${arg#$checkArg=}"
				return 0
				;;
		esac
	done
	return 1
}
declare -a mongodHackedArgs
# _mongod_hack_ensure_arg '--some-arg' "$@"
# set -- "${mongodHackedArgs[@]}"
_mongod_hack_ensure_arg() {
	local ensureArg="$1"; shift
	mongodHackedArgs=( "$@" )
	if ! _mongod_hack_have_arg "$ensureArg" "$@"; then
		mongodHackedArgs+=( "$ensureArg" )
	fi
}
# _mongod_hack_ensure_no_arg '--some-unwanted-arg' "$@"
# set -- "${mongodHackedArgs[@]}"
_mongod_hack_ensure_no_arg() {
	local ensureNoArg="$1"; shift
	mongodHackedArgs=()
	while [ "$#" -gt 0 ]; do
		local arg="$1"; shift
		if [ "$arg" = "$ensureNoArg" ]; then
			continue
		fi
		mongodHackedArgs+=( "$arg" )
	done
}
# _mongod_hack_ensure_no_arg '--some-unwanted-arg' "$@"
# set -- "${mongodHackedArgs[@]}"
_mongod_hack_ensure_no_arg_val() {
	local ensureNoArg="$1"; shift
	mongodHackedArgs=()
	while [ "$#" -gt 0 ]; do
		local arg="$1"; shift
		case "$arg" in
			"$ensureNoArg")
				shift # also skip the value
				continue
				;;
			"$ensureNoArg"=*)
				# value is already included
				continue
				;;
		esac
		mongodHackedArgs+=( "$arg" )
	done
}
# _mongod_hack_ensure_arg_val '--some-arg' 'some-val' "$@"
# set -- "${mongodHackedArgs[@]}"
_mongod_hack_ensure_arg_val() {
	local ensureArg="$1"; shift
	local ensureVal="$1"; shift
	_mongod_hack_ensure_no_arg_val "$ensureArg" "$@"
	mongodHackedArgs+=( "$ensureArg" "$ensureVal" )
}

# _js_escape 'some "string" value'
_js_escape() {
	jq --null-input --arg 'str' "$1" '$str'
}

jsonConfigFile="${TMPDIR:-/tmp}/docker-entrypoint-config.json"
tempConfigFile="${TMPDIR:-/tmp}/docker-entrypoint-temp-config.json"
_parse_config() {
	if [ -s "$tempConfigFile" ]; then
		return 0
	fi

	local configPath
	if configPath="$(_mongod_hack_get_arg_val --config "$@")"; then
		# if --config is specified, parse it into a JSON file so we can remove a few problematic keys (especially SSL-related keys)
		# see https://docs.mongodb.com/manual/reference/configuration-options/
		mongo --norc --nodb --quiet --eval "load('/js-yaml.js'); printjson(jsyaml.load(cat($(_js_escape "$configPath"))))" > "$jsonConfigFile"
		jq 'del(.systemLog, .processManagement, .net, .security)' "$jsonConfigFile" > "$tempConfigFile"
		return 0
	fi

	return 1
}
dbPath=
_dbPath() {
	if [ -n "$dbPath" ]; then
		echo "$dbPath"
		return
	fi

	if ! dbPath="$(_mongod_hack_get_arg_val --dbpath "$@")"; then
		if _parse_config "$@"; then
			dbPath="$(jq -r '.storage.dbPath // empty' "$jsonConfigFile")"
		fi
	fi

	if [ -z "$dbPath" ]; then
		if _mongod_hack_have_arg --configsvr "$@" || {
			_parse_config "$@" \
			&& clusterRole="$(jq -r '.sharding.clusterRole // empty' "$jsonConfigFile")" \
			&& [ "$clusterRole" = 'configsvr']
		}; then
			# if running as config server, then the default dbpath is /data/configdb
			# https://docs.mongodb.com/manual/reference/program/mongod/#cmdoption-mongod-configsvr
			dbPath=/data/configdb
		fi
	fi

	: "${dbPath:=/data/db}"

	echo "$dbPath"
}

if [ "$originalArgOne" = 'mongod' ]; then
	file_env 'MONGO_INITDB_ROOT_USERNAME'
	file_env 'MONGO_INITDB_ROOT_PASSWORD'
	# pre-check a few factors to see if it's even worth bothering with initdb
	shouldPerformInitdb=
	if [ "$MONGO_INITDB_ROOT_USERNAME" ] && [ "$MONGO_INITDB_ROOT_PASSWORD" ]; then
		# if we have a username/password, let's set "--auth"
		_mongod_hack_ensure_arg '--auth' "$@"
		set -- "${mongodHackedArgs[@]}"
		shouldPerformInitdb='true'
	elif [ "$MONGO_INITDB_ROOT_USERNAME" ] || [ "$MONGO_INITDB_ROOT_PASSWORD" ]; then
		cat >&2 <<-'EOF'
			error: missing 'MONGO_INITDB_ROOT_USERNAME' or 'MONGO_INITDB_ROOT_PASSWORD'
			       both must be specified for a user to be created
		EOF
		exit 1
	fi

	if [ -z "$shouldPerformInitdb" ]; then
		# if we've got any /docker-entrypoint-initdb.d/* files to parse later, we should initdb
		for f in /docker-entrypoint-initdb.d/*; do
			case "$f" in
				*.sh|*.js) # this should match the set of files we check for below
					shouldPerformInitdb="$f"
					break
					;;
			esac
		done
	fi

	# check for a few known paths (to determine whether we've already initialized and should thus skip our initdb scripts)
	if [ -n "$shouldPerformInitdb" ]; then
		dbPath="$(_dbPath "$@")"
		for path in \
			"$dbPath/WiredTiger" \
			"$dbPath/journal" \
			"$dbPath/local.0" \
			"$dbPath/storage.bson" \
		; do
			if [ -e "$path" ]; then
				shouldPerformInitdb=
				break
			fi
		done
	fi

	if [ -n "$shouldPerformInitdb" ]; then
		mongodHackedArgs=( "$@" )
		if _parse_config "$@"; then
			_mongod_hack_ensure_arg_val --config "$tempConfigFile" "${mongodHackedArgs[@]}"
		fi
		_mongod_hack_ensure_arg_val --bind_ip 127.0.0.1 "${mongodHackedArgs[@]}"
		_mongod_hack_ensure_arg_val --port 27017 "${mongodHackedArgs[@]}"
		_mongod_hack_ensure_no_arg --bind_ip_all "${mongodHackedArgs[@]}"

		# remove "--auth" and "--replSet" for our initial startup (see https://docs.mongodb.com/manual/tutorial/enable-authentication/#start-mongodb-without-access-control)
		# https://github.com/docker-library/mongo/issues/211
		_mongod_hack_ensure_no_arg --auth "${mongodHackedArgs[@]}"
		if [ "$MONGO_INITDB_ROOT_USERNAME" ] && [ "$MONGO_INITDB_ROOT_PASSWORD" ]; then
			_mongod_hack_ensure_no_arg_val --replSet "${mongodHackedArgs[@]}"
		fi

		sslMode="$(_mongod_hack_have_arg '--sslPEMKeyFile' "$@" && echo 'allowSSL' || echo 'disabled')" # "BadValue: need sslPEMKeyFile when SSL is enabled" vs "BadValue: need to enable SSL via the sslMode flag when using SSL configuration parameters"
		_mongod_hack_ensure_arg_val --sslMode "$sslMode" "${mongodHackedArgs[@]}"

		if stat "/proc/$$/fd/1" > /dev/null && [ -w "/proc/$$/fd/1" ]; then
			# https://github.com/mongodb/mongo/blob/38c0eb538d0fd390c6cb9ce9ae9894153f6e8ef5/src/mongo/db/initialize_server_global_state.cpp#L237-L251
			# https://github.com/docker-library/mongo/issues/164#issuecomment-293965668
			_mongod_hack_ensure_arg_val --logpath "/proc/$$/fd/1" "${mongodHackedArgs[@]}"
		else
			initdbLogPath="$(_dbPath "$@")/docker-initdb.log"
			echo >&2 "warning: initdb logs cannot write to '/proc/$$/fd/1', so they are in '$initdbLogPath' instead"
			_mongod_hack_ensure_arg_val --logpath "$initdbLogPath" "${mongodHackedArgs[@]}"
		fi
		_mongod_hack_ensure_arg --logappend "${mongodHackedArgs[@]}"

		pidfile="${TMPDIR:-/tmp}/docker-entrypoint-temp-mongod.pid"
		rm -f "$pidfile"
		_mongod_hack_ensure_arg_val --pidfilepath "$pidfile" "${mongodHackedArgs[@]}"

		"${mongodHackedArgs[@]}" --fork

		mongo=( mongo --host 127.0.0.1 --port 27017 --quiet )

		# check to see that our "mongod" actually did start up (catches "--help", "--version", MongoDB 3.2 being silly, slow prealloc, etc)
		# https://jira.mongodb.org/browse/SERVER-16292
		tries=30
		while true; do
			if ! { [ -s "$pidfile" ] && ps "$(< "$pidfile")" &> /dev/null; }; then
				# bail ASAP if "mongod" isn't even running
				echo >&2
				echo >&2 "error: $originalArgOne does not appear to have stayed running -- perhaps it had an error?"
				echo >&2
				exit 1
			fi
			if "${mongo[@]}" 'admin' --eval 'quit(0)' &> /dev/null; then
				# success!
				break
			fi
			(( tries-- ))
			if [ "$tries" -le 0 ]; then
				echo >&2
				echo >&2 "error: $originalArgOne does not appear to have accepted connections quickly enough -- perhaps it had an error?"
				echo >&2
				exit 1
			fi
			sleep 1
		done

		if [ "$MONGO_INITDB_ROOT_USERNAME" ] && [ "$MONGO_INITDB_ROOT_PASSWORD" ]; then
			rootAuthDatabase='admin'

			"${mongo[@]}" "$rootAuthDatabase" <<-EOJS
				db.createUser({
					user: $(_js_escape "$MONGO_INITDB_ROOT_USERNAME"),
					pwd: $(_js_escape "$MONGO_INITDB_ROOT_PASSWORD"),
					roles: [ { role: 'root', db: $(_js_escape "$rootAuthDatabase") } ]
				})
			EOJS
		fi

		export MONGO_INITDB_DATABASE="${MONGO_INITDB_DATABASE:-test}"

		echo
		for f in /docker-entrypoint-initdb.d/*; do
			case "$f" in
				*.sh) echo "$0: running $f"; . "$f" ;;
				*.js) echo "$0: running $f"; "${mongo[@]}" "$MONGO_INITDB_DATABASE" "$f"; echo ;;
				*)    echo "$0: ignoring $f" ;;
			esac
			echo
		done

		"${mongodHackedArgs[@]}" --shutdown
		rm -f "$pidfile"

		echo
		echo 'MongoDB init process complete; ready for start up.'
		echo
	fi

	# MongoDB 3.6+ defaults to localhost-only binding
	if mongod --help 2>&1 | grep -q -- --bind_ip_all; then # TODO remove this conditional when 3.4 is no longer supported
		haveBindIp=
		if _mongod_hack_have_arg --bind_ip "$@" || _mongod_hack_have_arg --bind_ip_all "$@"; then
			haveBindIp=1
		elif _parse_config "$@" && jq --exit-status '.net.bindIp // .net.bindIpAll' "$jsonConfigFile" > /dev/null; then
			haveBindIp=1
		fi
		if [ -z "$haveBindIp" ]; then
			# so if no "--bind_ip" is specified, let's add "--bind_ip_all"
			set -- "$@" --bind_ip_all
		fi
	fi

	unset "${!MONGO_INITDB_@}"
fi

rm -f "$jsonConfigFile" "$tempConfigFile"

exec "$@"

Lancez maintenant la compilation de l'image :

root@debian9:~/mongodb# chmod +x docker-entrypoint.sh
root@debian9:~/mongodb# docker build .

Notez que l'image n'a ni REPOSITORY, ni TAG. Créez donc un TAG :

root@debian9:~/mongodb# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
<none>              <none>              3bf216d921d6        About a minute ago   96.2MB
...
root@debian9:~/mongodb# docker tag 3bf2 i2tch/mongodb2
root@debian9:~/mongodb# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
i2tch/mongodb2      latest              3bf216d921d6        2 minutes ago       96.2MB
...

Lancez un conteneur à partir de la dernière image :

root@debian9:~/mongodb# docker run -d --name mongo2 i2tch/mongodb2
e91a055283f4d67cbd91d11bb3faa6f67925893cb18f9cc25023e72e0f7ed85a

Gestion Automatique de Volumes par Docker

Vérifiez que le processus est bien démarré dans le conteneur :

root@debian9:~# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
b9773e4aa06d        i2tch/mongodb2      "docker-entrypoint..."   7 hours ago         Up About a minute   27017/tcp           mongo2

Identifiez ensuite le point de montage du répertoire /data/db du conteneur :

root@debian9:~# docker inspect mongo2
...
        "Mounts": [
            {
                "Type": "volume",
                "Name": "9c84c2d1a0db811a3c13dce354ba21169f3073513c8d025dd96c5f902364d44a",
                "Source": "/var/lib/docker/volumes/9c84c2d1a0db811a3c13dce354ba21169f3073513c8d025dd96c5f902364d44a/_data",
                "Destination": "/data/configdb",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            },
            {
                "Type": "volume",
                "Name": "a6177cf4b46089356280f084dd2e272f673aa4a81accb53f031267fafcee6050",
                "Source": "/var/lib/docker/volumes/a6177cf4b46089356280f084dd2e272f673aa4a81accb53f031267fafcee6050/_data",
                "Destination": "/data/db",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
...
            "Volumes": {
                "/data/configdb": {},
                "/data/db": {}
            },
...

En regardant le contenu du répertoire /data/db, on constate une arborescence classique de stockage de données de mongodb :

root@debian9:~# ls /var/lib/docker/volumes/a6177cf4b46089356280f084dd2e272f673aa4a81accb53f031267fafcee6050/_data
journal  local.0  local.ns  mongod.lock  storage.bson

Arrêtez et supprimez le conteneur mongo2 :

root@debian9:~# docker stop mongo2
mongo2
root@debian9:~# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS               NAMES
ea239635e141        testcache           "more /tmp/moment"       6 hours ago         Exited (0) 6 hours ago                          test1
21b0490a93dd        i2tch/mydocker      "/entrypoint.sh my..."   6 hours ago         Exited (137) 6 hours ago                        myDocker
b9773e4aa06d        i2tch/mongodb2      "docker-entrypoint..."   7 hours ago         Exited (0) 10 seconds ago                       mongo2
bdb4bc0f81de        i2tch/mongodb1      "docker-entrypoint..."   18 hours ago        Created                     27017/tcp           mongo1
f5b45072b831        i2tch/mongodb       "bash"                   18 hours ago        Exited (137) 6 hours ago                        mongo
9731a48f126a        nginx               "nginx -g 'daemon ..."   18 hours ago        Exited (0) 6 hours ago                          cocky_gates
eacd70596e23        nginx               "nginx -g 'daemon ..."   19 hours ago        Exited (0) 19 hours ago                         adoring_yonath
cffb4456e9c4        ubuntu              "/bin/bash"              19 hours ago        Exited (0) 19 hours ago                         i2tch
root@debian9:~# docker rm mongo2
mongo2
root@debian9:~# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS               NAMES
ea239635e141        testcache           "more /tmp/moment"       6 hours ago         Exited (0) 6 hours ago                         test1
21b0490a93dd        i2tch/mydocker      "/entrypoint.sh my..."   6 hours ago         Exited (137) 6 hours ago                       myDocker
bdb4bc0f81de        i2tch/mongodb1      "docker-entrypoint..."   18 hours ago        Created                    27017/tcp           mongo1
f5b45072b831        i2tch/mongodb       "bash"                   18 hours ago        Exited (137) 6 hours ago                       mongo
9731a48f126a        nginx               "nginx -g 'daemon ..."   18 hours ago        Exited (0) 6 hours ago                         cocky_gates
eacd70596e23        nginx               "nginx -g 'daemon ..."   19 hours ago        Exited (0) 19 hours ago                        adoring_yonath
cffb4456e9c4        ubuntu              "/bin/bash"              19 hours ago        Exited (0) 19 hours ago                        i2tch

Re-créez maintenant un conteneur à partir de l'image i2tch/mongodb2 :

root@debian9:~# docker run -d --name mongo2 i2tch/mongodb2
a8382642c4e849337e12a60419b10f63ea21251dfcc2c6050284ca3eed7fa13d
root@debian9:~# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                        PORTS               NAMES
a8382642c4e8        i2tch/mongodb2      "docker-entrypoint..."   12 seconds ago      Exited (100) 11 seconds ago                       mongo2
ea239635e141        testcache           "more /tmp/moment"       6 hours ago         Exited (0) 6 hours ago                            test1
21b0490a93dd        i2tch/mydocker      "/entrypoint.sh my..."   6 hours ago         Exited (137) 6 hours ago                          myDocker
bdb4bc0f81de        i2tch/mongodb1      "docker-entrypoint..."   18 hours ago        Created                       27017/tcp           mongo1
f5b45072b831        i2tch/mongodb       "bash"                   18 hours ago        Exited (137) 6 hours ago                          mongo
9731a48f126a        nginx               "nginx -g 'daemon ..."   18 hours ago        Exited (0) 6 hours ago                            cocky_gates
eacd70596e23        nginx               "nginx -g 'daemon ..."   19 hours ago        Exited (0) 19 hours ago                           adoring_yonath
cffb4456e9c4        ubuntu              "/bin/bash"              19 hours ago        Exited (0) 19 hours ago                           i2tch

Utilisez de nouveau la commande docker inspect pour identifier le point de montage du répertoire /data/db :

root@debian9:~# docker inspect mongo2
...
        "Mounts": [
            {
                "Type": "volume",
                "Name": "76dcc0ccbe6604278cf8e8da0398a807f5d0719087f17c227c8504be24456d43",
                "Source": "/var/lib/docker/volumes/76dcc0ccbe6604278cf8e8da0398a807f5d0719087f17c227c8504be24456d43/_data",
                "Destination": "/data/db",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            },
            {
                "Type": "volume",
                "Name": "3bf724ceb38ce0792469d7e403f05b6794f27e0aa72bda51a8ab75b2df5ae87c",
                "Source": "/var/lib/docker/volumes/3bf724ceb38ce0792469d7e403f05b6794f27e0aa72bda51a8ab75b2df5ae87c/_data",
                "Destination": "/data/configdb",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
...

Important : Notez que le répertoire des données du précédent conteneur, /var/lib/docker/volumes/a6177cf4b46089356280f084dd2e272f673aa4a81accb53f031267fafcee6050/_data n'est pas le même que le conteneur courant /var/lib/docker/volumes/76dcc0ccbe6604278cf8e8da0398a807f5d0719087f17c227c8504be24456d43/_data.

Les conteneurs n'ayant pas été arrêtés avec l'option -v, on peut constater que les répertoires persistent dans /var/lib/docker :

root@debian9:~# ls -l /var/lib/docker/volumes/
total 52
drwxr-xr-x 3 root root  4096 Sep  7 09:43 3bf724ceb38ce0792469d7e403f05b6794f27e0aa72bda51a8ab75b2df5ae87c
drwxr-xr-x 3 root root  4096 Sep  6 16:07 46d11d005d05757609ff76159ce0992d210089c5247fa54b024706a20b0de501
drwxr-xr-x 3 root root  4096 Sep  7 09:43 76dcc0ccbe6604278cf8e8da0398a807f5d0719087f17c227c8504be24456d43
drwxr-xr-x 3 root root  4096 Sep  7 02:33 9c84c2d1a0db811a3c13dce354ba21169f3073513c8d025dd96c5f902364d44a
drwxr-xr-x 3 root root  4096 Sep  7 02:33 a6177cf4b46089356280f084dd2e272f673aa4a81accb53f031267fafcee6050
drwxr-xr-x 3 root root  4096 Sep  6 16:07 cc38fa97138adc55976aa16993d8920c5f7da922ad1b2a07936d30cc82d59f38
-rw------- 1 root root 32768 Sep  7 09:43 metadata.db

Important : Notez que non-seulement ceci représente une source de perte d'espace disque mais prouve aussi que les données ne sont pas persistantes entre deux instances d'un conteneur d'i2tch/mongodb2. Ceci crée bien évidement un problème important en production.

Gestion Manuelle d'un Volume

Arrêtez et supprimez le conteneur mongo2 puis re-créez un conteneur avec un volume spécifique pour contenir les données placées dans /data/db du conteneur par mongodb :

root@debian9:~# docker stop mongo2
mongo2
root@debian9:~# docker rm mongo2
mongo2
root@debian9:~# docker run -d --name mongo2 -v persistent_data:/data/db i2tch/mongodb2
3cf093d72b9e3739f2cb288e571244e494b7518292c31994ee012e3620bb0e98
root@debian9:~# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS               NAMES
3cf093d72b9e        i2tch/mongodb2      "docker-entrypoint..."   21 seconds ago      Up 20 seconds              27017/tcp           mongo2
ea239635e141        testcache           "more /tmp/moment"       6 hours ago         Exited (0) 6 hours ago                         test1
21b0490a93dd        i2tch/mydocker      "/entrypoint.sh my..."   6 hours ago         Exited (137) 6 hours ago                       myDocker
bdb4bc0f81de        i2tch/mongodb1      "docker-entrypoint..."   18 hours ago        Created                    27017/tcp           mongo1
f5b45072b831        i2tch/mongodb       "bash"                   18 hours ago        Exited (137) 6 hours ago                       mongo
9731a48f126a        nginx               "nginx -g 'daemon ..."   19 hours ago        Exited (0) 6 hours ago                         cocky_gates
eacd70596e23        nginx               "nginx -g 'daemon ..."   19 hours ago        Exited (0) 19 hours ago                        adoring_yonath
cffb4456e9c4        ubuntu              "/bin/bash"              19 hours ago        Exited (0) 19 hours ago                        i2tch
root@debian9:~# docker logs mongo2
2017-09-07T08:53:12.523+0000 I CONTROL  [initandlisten] MongoDB starting : pid=1 port=27017 dbpath=/data/db 64-bit host=3cf093d72b9e
2017-09-07T08:53:12.524+0000 I CONTROL  [initandlisten] db version v3.0.15
2017-09-07T08:53:12.524+0000 I CONTROL  [initandlisten] git version: b8ff507269c382bc100fc52f75f48d54cd42ec3b
2017-09-07T08:53:12.524+0000 I CONTROL  [initandlisten] build info: Linux ip-10-166-66-3 3.2.0-4-amd64 #1 SMP Debian 3.2.46-1 x86_64 BOOST_LIB_VERSION=1_49
2017-09-07T08:53:12.524+0000 I CONTROL  [initandlisten] allocator: tcmalloc
2017-09-07T08:53:12.524+0000 I CONTROL  [initandlisten] options: { storage: { mmapv1: { smallFiles: true } } }
2017-09-07T08:53:12.535+0000 I JOURNAL  [initandlisten] journal dir=/data/db/journal
2017-09-07T08:53:12.535+0000 I JOURNAL  [initandlisten] recover : no journal files present, no recovery needed
2017-09-07T08:53:13.368+0000 I JOURNAL  [initandlisten] preallocateIsFaster=true 15.4
2017-09-07T08:53:14.410+0000 I JOURNAL  [initandlisten] preallocateIsFaster=true 19.36
2017-09-07T08:53:16.277+0000 I JOURNAL  [initandlisten] preallocateIsFaster=true 15.86
2017-09-07T08:53:16.277+0000 I JOURNAL  [initandlisten] preallocateIsFaster check took 3.742 secs
2017-09-07T08:53:16.277+0000 I JOURNAL  [initandlisten] preallocating a journal file /data/db/journal/prealloc.0
2017-09-07T08:53:19.930+0000 I JOURNAL  [initandlisten] preallocating a journal file /data/db/journal/prealloc.1
2017-09-07T08:53:23.035+0000 I JOURNAL  [initandlisten] preallocating a journal file /data/db/journal/prealloc.2
2017-09-07T08:53:25.889+0000 I JOURNAL  [durability] Durability thread started
2017-09-07T08:53:25.889+0000 I JOURNAL  [journal writer] Journal writer thread started
2017-09-07T08:53:26.016+0000 I INDEX    [initandlisten] allocating new ns file /data/db/local.ns, filling with zeroes...
2017-09-07T08:53:26.246+0000 I STORAGE  [FileAllocator] allocating new datafile /data/db/local.0, filling with zeroes...
2017-09-07T08:53:26.246+0000 I STORAGE  [FileAllocator] creating directory /data/db/_tmp
2017-09-07T08:53:26.256+0000 I STORAGE  [FileAllocator] done allocating datafile /data/db/local.0, size: 16MB,  took 0.002 secs
2017-09-07T08:53:26.299+0000 I NETWORK  [initandlisten] waiting for connections on port 27017

Notez que cette fois-ci, docker a créé un répertoire persistent_data dans le répertoire /var/lib/docker/volumes/ :

root@debian9:~# ls -l /var/lib/docker/volumes/
total 68
drwxr-xr-x 3 root root  4096 Sep  7 09:43 3bf724ceb38ce0792469d7e403f05b6794f27e0aa72bda51a8ab75b2df5ae87c
drwxr-xr-x 3 root root  4096 Sep  6 16:07 46d11d005d05757609ff76159ce0992d210089c5247fa54b024706a20b0de501
drwxr-xr-x 3 root root  4096 Sep  7 09:46 511e23f818d5cf60f4333a3fe8fd2e4333c900dec6eee97f70448bfb0091184d
drwxr-xr-x 3 root root  4096 Sep  7 09:53 5ca72be4140ecf1271efe7342cf7cd58ce66fc3673d12c04b8503603b8cee66c
drwxr-xr-x 3 root root  4096 Sep  7 09:43 76dcc0ccbe6604278cf8e8da0398a807f5d0719087f17c227c8504be24456d43
drwxr-xr-x 3 root root  4096 Sep  7 02:33 9c84c2d1a0db811a3c13dce354ba21169f3073513c8d025dd96c5f902364d44a
drwxr-xr-x 3 root root  4096 Sep  7 02:33 a6177cf4b46089356280f084dd2e272f673aa4a81accb53f031267fafcee6050
drwxr-xr-x 3 root root  4096 Sep  6 16:07 cc38fa97138adc55976aa16993d8920c5f7da922ad1b2a07936d30cc82d59f38
-rw------- 1 root root 65536 Sep  7 09:53 metadata.db
drwxr-xr-x 3 root root  4096 Sep  7 09:46 persistent_data

Arrêtez et supprimez le conteneur mongo2 puis re-créez un conteneur en utilisant le même volume spécifique pour contenir les données placées dans /data/db du conteneur par mongodb :

root@debian9:~# docker stop mongo2
mongo2
root@debian9:~# docker rm mongo2
mongo2
root@debian9:~# docker run -d --name mongo2 -v persistent_data:/data/db i2tch/mongodb2
ad672c3038245c25a36162d05820c21f7250557ac342582d0908d3ca33799e37
root@debian9:~# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS               NAMES
ad672c303824        i2tch/mongodb2      "docker-entrypoint..."   24 seconds ago      Up 22 seconds              27017/tcp           mongo2
ea239635e141        testcache           "more /tmp/moment"       6 hours ago         Exited (0) 6 hours ago                         test1
21b0490a93dd        i2tch/mydocker      "/entrypoint.sh my..."   6 hours ago         Exited (137) 6 hours ago                       myDocker
bdb4bc0f81de        i2tch/mongodb1      "docker-entrypoint..."   18 hours ago        Created                    27017/tcp           mongo1
f5b45072b831        i2tch/mongodb       "bash"                   18 hours ago        Exited (137) 6 hours ago                       mongo
9731a48f126a        nginx               "nginx -g 'daemon ..."   19 hours ago        Exited (0) 6 hours ago                         cocky_gates
eacd70596e23        nginx               "nginx -g 'daemon ..."   19 hours ago        Exited (0) 19 hours ago                        adoring_yonath
cffb4456e9c4        ubuntu              "/bin/bash"              19 hours ago        Exited (0) 19 hours ago                        i2tch

Encore une fois, cherchez le point de montage de /data/db grâce à l'utilisation de la commande docker inspect :

root@debian9:~# docker inspect mongo2
...
        "Mounts": [
            {
                "Type": "volume",
                "Name": "6cefc73cef475279dfe20e25421fa358e6aa995b5c175b9f2c7a9b86163661e5",
                "Source": "/var/lib/docker/volumes/6cefc73cef475279dfe20e25421fa358e6aa995b5c175b9f2c7a9b86163661e5/_data",
                "Destination": "/data/configdb",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            },
            {
                "Type": "volume",
                "Name": "persistent_data",
                "Source": "/var/lib/docker/volumes/persistent_data/_data",
                "Destination": "/data/db",
                "Driver": "local",
                "Mode": "z",
                "RW": true,
                "Propagation": ""
            }
...

Important : Notez ici que l'utilisation du même répertoire entre les deux conteneurs rend les données persistantes et évite la création de volumes orphelins. Pour plus d'information sur les volumes, consultez la page : https://docs.docker.com/engine/userguide/containers/dockervolumes/.

LAB #5 - Gestion du Réseau

Docker fournit trois réseaux par défaut :

root@debian9:~# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
495b3db75b0d        bridge              bridge              local
e1ed4de2f947        host                host                local
6bda460c97c6        none                null                local

Bridge

Ce type de réseau est limité aux conteneurs d'un hôte unique exécutant Docker. Les conteneurs ne peuvent communiquer qu'entre eux et ils ne sont pas accessibles depuis l'extérieur. Pour que les conteneurs sur le réseau puissent communiquer ou être accessibles du monde extérieur, il faut configurer le mappage de port.

Par défaut Docker fonctionne en mode Pont ou (Bridge) et crée une interface intermédiaire à cet effet appelé docker0 :

root@debian9:~# ip addr show docker0
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:38:f1:e7:ee brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever

Démarrez un conteneur dénommé resotest à partir d'une image de CentOS :

root@debian9:~# docker run -itd --name=resotest centos
2169360fcbfdbd6e68ea969a95edeb6fc42603c23ee42f03ceec286276519855

Lancez ensuite la commande docker network inspect bridge à partir de la machine virtuelle hôte de Debian_9 :

root@debian9:~# docker network inspect bridge
[
    {
        "Name": "bridge",
        "Id": "495b3db75b0d4bfcfc6da7c3e2af5f6addcdc227aa8b69b1e59a998be1819d12",
        "Created": "2017-09-07T07:44:49.942615596+01:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "2169360fcbfdbd6e68ea969a95edeb6fc42603c23ee42f03ceec286276519855": {
                "Name": "resotest",
                "EndpointID": "fc74e519d69b9a2112be959c92cda22b67671b52efbbd36fadf66097ccbb1271",
                "MacAddress": "02:42:ac:11:00:03",
                "IPv4Address": "172.17.0.3/16",
                "IPv6Address": ""
            },
            "ad672c3038245c25a36162d05820c21f7250557ac342582d0908d3ca33799e37": {
                "Name": "mongo2",
                "EndpointID": "adc15132fb73b57ab14e960feeff1b965321ada411be8535b715b103b941d8cc",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }
]

Important : Notez ici que les conteneurs mongo2 et resotest ne disposent pas de la même adresse que l'interface docker0 de la machine hôte. Cependant les adresses se trouvent dans le même segment - 172.17.0.0/16 indiqué par la sortie “Subnet”: “172.17.0.0/16”.

Vous pouvez déconnecter un conteneur du réseau en utilisant la commande suivante :

root@debian9:~# docker network disconnect bridge resotest
root@debian9:~# docker network inspect bridge
[
    {
        "Name": "bridge",
        "Id": "495b3db75b0d4bfcfc6da7c3e2af5f6addcdc227aa8b69b1e59a998be1819d12",
        "Created": "2017-09-07T07:44:49.942615596+01:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "ad672c3038245c25a36162d05820c21f7250557ac342582d0908d3ca33799e37": {
                "Name": "mongo2",
                "EndpointID": "adc15132fb73b57ab14e960feeff1b965321ada411be8535b715b103b941d8cc",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }
]

Créez maintenant votre propre réseau ponté appelé my-bridged-network :

root@debian9:~# docker network create -d bridge --subnet 172.25.0.0/16 --gateway 172.25.0.1 my-bridged-network
ceb7ba7493933c55d181bc92b1f799ca07bfe84b168d52a6ac648c1a906093f3
root@debian9:~# docker network ls
NETWORK ID          NAME                 DRIVER              SCOPE
495b3db75b0d        bridge               bridge              local
e1ed4de2f947        host                 host                local
ceb7ba749393        my-bridged-network   bridge              local
6bda460c97c6        none                 null                local             

Bien évidement, ce réseau est actuellement vide :

root@debian9:~# docker network inspect my-bridged-network
[
    {
        "Name": "my-bridged-network",
        "Id": "ceb7ba7493933c55d181bc92b1f799ca07bfe84b168d52a6ac648c1a906093f3",
        "Created": "2017-09-07T10:03:17.063730665+01:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.25.0.0/16",
                    "Gateway": "172.25.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]

Lancez maintenant deux conteneurs et consultez les informations concernant le réseau :

root@debian9:~# docker run -itd --name=centos1 centos
9f36a628c72b383edfd4dc13ee4e4b2eaf5be0078d780f0334fcb8be0d977d0e

root@debian9:~# docker run -itd --name=centos2 centos
aaed3bc8e404ee1bccd6c87b39de32332940b5391514691fc70188edb17c1d7c

root@debian9:~# docker inspect --format='{{json .NetworkSettings.Networks}}'  centos1
{"bridge":{"IPAMConfig":null,"Links":null,"Aliases":null,"NetworkID":"495b3db75b0d4bfcfc6da7c3e2af5f6addcdc227aa8b69b1e59a998be1819d12","EndpointID":"d7b87875688b45258fc867b6bb8b0a0592f5c5fa16857fe136e55b87b6698219","Gateway":"172.17.0.1","IPAddress":"172.17.0.3","IPPrefixLen":16,"IPv6Gateway":"","GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"MacAddress":"02:42:ac:11:00:03","DriverOpts":null}}

root@debian9:~# docker inspect --format='{{json .NetworkSettings.Networks}}'  centos2
{"bridge":{"IPAMConfig":null,"Links":null,"Aliases":null,"NetworkID":"495b3db75b0d4bfcfc6da7c3e2af5f6addcdc227aa8b69b1e59a998be1819d12","EndpointID":"2bfe090dccef89495d437d8deba5765996a917544ab7fde28ef5199f4e907eb1","Gateway":"172.17.0.1","IPAddress":"172.17.0.4","IPPrefixLen":16,"IPv6Gateway":"","GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"MacAddress":"02:42:ac:11:00:04","DriverOpts":null}}

root@debian9:~# docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' centos1
172.17.0.3

root@debian9:~# docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' centos2
172.17.0.4

Mettez le conteneur centos1 dans le réseau my-bridged-network :

root@debian9:~# docker network connect my-bridged-network centos1

root@debian9:~# docker network inspect my-bridged-network
[
    {
        "Name": "my-bridged-network",
        "Id": "ceb7ba7493933c55d181bc92b1f799ca07bfe84b168d52a6ac648c1a906093f3",
        "Created": "2017-09-07T10:03:17.063730665+01:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.25.0.0/16",
                    "Gateway": "172.25.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "9f36a628c72b383edfd4dc13ee4e4b2eaf5be0078d780f0334fcb8be0d977d0e": {
                "Name": "centos1",
                "EndpointID": "71e10e4e34ce8c42ef029e302f6ed372357f6fde8fd87fc2cbc1b14c2bdf6bb5",
                "MacAddress": "02:42:ac:19:00:02",
                "IPv4Address": "172.25.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

root@debian9:~# docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' centos1
172.17.0.3172.25.0.2

Important : Notez que le conteneur centos1 se trouve dans deux réseaux.

Faites la même chose pour le conteneur centos2 :

root@debian9:~# docker network connect my-bridged-network centos2

root@debian9:~# docker network inspect my-bridged-network
[
    {
        "Name": "my-bridged-network",
        "Id": "ceb7ba7493933c55d181bc92b1f799ca07bfe84b168d52a6ac648c1a906093f3",
        "Created": "2017-09-07T10:03:17.063730665+01:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.25.0.0/16",
                    "Gateway": "172.25.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "9f36a628c72b383edfd4dc13ee4e4b2eaf5be0078d780f0334fcb8be0d977d0e": {
                "Name": "centos1",
                "EndpointID": "71e10e4e34ce8c42ef029e302f6ed372357f6fde8fd87fc2cbc1b14c2bdf6bb5",
                "MacAddress": "02:42:ac:19:00:02",
                "IPv4Address": "172.25.0.2/16",
                "IPv6Address": ""
            },
            "aaed3bc8e404ee1bccd6c87b39de32332940b5391514691fc70188edb17c1d7c": {
                "Name": "centos2",
                "EndpointID": "34f533622f134b995097f1d3e6ce935158c1e5644201f896b42336738a81819c",
                "MacAddress": "02:42:ac:19:00:03",
                "IPv4Address": "172.25.0.3/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

root@debian9:~# docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' centos2
172.17.0.4172.25.0.3

Connectez-vous au conteneur centos1 en lançant bash :

root@debian9:~# docker exec -it centos1 bash

Vérifiez que la connectivité fonctionne :

[root@9f36a628c72b /]# ping 172.25.0.3
PING 172.25.0.3 (172.25.0.3) 56(84) bytes of data.
64 bytes from 172.25.0.3: icmp_seq=1 ttl=64 time=0.100 ms
64 bytes from 172.25.0.3: icmp_seq=2 ttl=64 time=0.050 ms
64 bytes from 172.25.0.3: icmp_seq=3 ttl=64 time=0.050 ms
^C
--- 172.25.0.3 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1998ms
rtt min/avg/max/mdev = 0.050/0.066/0.100/0.025 ms

Les options possibles au niveau de la gestion du réseau sont vaste. Voici deux exemples supplémentaires.

Il est possible d'ajouter une adresse d'un serveur DNS au lancement d'un conteneur :

[root@9f36a628c72b /]# exit
exit
root@debian9:~# docker stop mongo2
mongo2
root@debian9:~# docker rm mongo2
mongo2
root@debian9:~# docker run -it --name mongo2 --dns 8.8.8.8 i2tch/mongodb2 bash
root@735599480b45:/# cat /etc/resolv.conf 
search home
nameserver 8.8.8.8
root@735599480b45:/# 

ou de passer une entrée pour le fichier /etc/hosts :

root@735599480b45:/# exit
exit
root@debian9:~# docker stop mongo2
mongo2
root@debian9:~# docker rm mongo2
mongo2
root@debian9:~# docker run -it --name mongo2 --add-host mickeymouse:127.0.0.1 i2tch/mongodb2 bash
root@718e7eab814f:/# cat /etc/hosts
127.0.0.1	localhost
::1	localhost ip6-localhost ip6-loopback
fe00::0	ip6-localnet
ff00::0	ip6-mcastprefix
ff02::1	ip6-allnodes
ff02::2	ip6-allrouters
127.0.0.1	mickeymouse
172.17.0.2	718e7eab814f

Host

Ce type de réseau est utilisé dans le cas où le réseau ne doit pas être isolé de l'hôte tout en isolant les autres aspects du conteneur. Les conteneurs utilisent la même interface que l'hôte en prenant la même adresse IP que la machine hôte.

Dans le cas de la machine virtuelle, l'adresse IP de l'interface connectée au réseau local est 10.0.2.15 :

root@debian9:~# ip addr show enp0s3
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:2e:77:01 brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic enp0s3
       valid_lft 83772sec preferred_lft 83772sec
    inet6 fe80::a00:27ff:fe2e:7701/64 scope link 
       valid_lft forever preferred_lft forever

Démarrez un conteneur à partir de l'image centos dans un réseau de type host :

root@debian9:~# docker run -it --rm --network host --name centos1 centos bash
[root@debian9 /]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:2e:77:01 brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic enp0s3
       valid_lft 82102sec preferred_lft 82102sec
    inet6 fe80::a00:27ff:fe2e:7701/64 scope link 
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:38:f1:e7:ee brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:38ff:fef1:e7ee/64 scope link 
       valid_lft forever preferred_lft forever
[root@debian9 /]# hostname
debian9
[root@debian9 /]# exit

None

Ce type de réseau est utilisé principalement dans le cas de l'utilisation d'un plugin réseau disponible dans le Docker Hub.

Il est donc possible de lancer un conteneur totalement étanche grâce au réseau none :

root@718e7eab814f:/# exit
exit
root@debian9:~# docker stop mongo2
mongo2
root@debian9:~# docker rm mongo2
mongo2
root@debian9:~# docker run -it --name mongo2 --net none i2tch/mongodb2 bash
root@332aa9930f30:/# 

Liens

Le mécanisme des liens entre conteneurs est très puissant et permet d'atteindre un autre conteneur facilement à condition que les deux conteneurs soient dans le même réseau. Créez donc un conteneur dénommé centos3 qui est lié au conteneur centos2 qu'il connait aussi sous l'alias alias :

root@332aa9930f30:/# exit
exit

root@debian9:~# docker run -itd --name centos3 --link centos2:alias centos
6a315259b2946c3bf2bb69f608cbe910d87edaadedb4f805e7a4dbf6af1eb916

root@debian9:~# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                        PORTS               NAMES
6a315259b294        centos              "/bin/bash"              33 seconds ago      Up 32 seconds                                     centos3
332aa9930f30        i2tch/mongodb2      "docker-entrypoint..."   3 minutes ago       Exited (127) 39 seconds ago                       mongo2
aaed3bc8e404        centos              "/bin/bash"              16 minutes ago      Up 16 minutes                                     centos2
9f36a628c72b        centos              "/bin/bash"              16 minutes ago      Up 16 minutes                                     centos1
2169360fcbfd        centos              "/bin/bash"              20 minutes ago      Up 20 minutes                                     resotest
ea239635e141        testcache           "more /tmp/moment"       7 hours ago         Exited (0) 7 hours ago                            test1
21b0490a93dd        i2tch/mydocker      "/entrypoint.sh my..."   7 hours ago         Exited (137) 6 hours ago                          myDocker
bdb4bc0f81de        i2tch/mongodb1      "docker-entrypoint..."   18 hours ago        Created                       27017/tcp           mongo1
f5b45072b831        i2tch/mongodb       "bash"                   19 hours ago        Exited (137) 6 hours ago                          mongo
9731a48f126a        nginx               "nginx -g 'daemon ..."   19 hours ago        Exited (0) 6 hours ago                            cocky_gates
eacd70596e23        nginx               "nginx -g 'daemon ..."   19 hours ago        Exited (0) 19 hours ago                           adoring_yonath
cffb4456e9c4        ubuntu              "/bin/bash"              20 hours ago        Exited (0) 20 hours ago                           i2tch

root@debian9:~# docker exec -it centos3 bash

[root@6a315259b294 /]# ping centos2
PING alias (172.17.0.4) 56(84) bytes of data.
64 bytes from alias (172.17.0.4): icmp_seq=1 ttl=64 time=0.116 ms
64 bytes from alias (172.17.0.4): icmp_seq=2 ttl=64 time=0.069 ms
64 bytes from alias (172.17.0.4): icmp_seq=3 ttl=64 time=0.068 ms
64 bytes from alias (172.17.0.4): icmp_seq=4 ttl=64 time=0.070 ms
^C
--- alias ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 2999ms
rtt min/avg/max/mdev = 0.068/0.080/0.116/0.023 ms

[root@6a315259b294 /]# cat /etc/hosts
127.0.0.1	localhost
::1	localhost ip6-localhost ip6-loopback
fe00::0	ip6-localnet
ff00::0	ip6-mcastprefix
ff02::1	ip6-allnodes
ff02::2	ip6-allrouters
172.17.0.4	alias aaed3bc8e404 centos2
172.17.0.2	6a315259b294

[root@6a315259b294 /]# exit
exit

root@debian9:~# docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' centos3
172.17.0.2

Notez cependant qu le lien est unidirectionnel :

root@debian9:~# docker exec -it centos2 bash

[root@aaed3bc8e404 /]# ping centos3
ping: centos3: Name or service not known

[root@aaed3bc8e404 /]# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.054 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.035 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.051 ms
64 bytes from 172.17.0.2: icmp_seq=4 ttl=64 time=0.071 ms
^C
--- 172.17.0.2 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 2997ms
rtt min/avg/max/mdev = 0.035/0.052/0.071/0.015 ms

[root@aaed3bc8e404 /]# 

Dans le cas ci-dessus, centos2 peut atteindre centos3 en utilisant l'adresse IP 172.17.0.2 car centos2 se trouve dans les deux réseaux avec les adresses IP 172.17.0.4 et 172.25.0.3 :

[root@aaed3bc8e404 /]# exit
exit
root@debian9:~# docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' centos2
172.17.0.4172.25.0.3

LAB #6 - Superviser les Conteneurs

Les Journaux

Consultez les logs d'un conteneur :

root@debian9:~# docker logs mongo2
root@332aa9930f30:/# ip addr
bash: ip: command not found
root@332aa9930f30:/# ip address
bash: ip: command not found
root@332aa9930f30:/# ifconfig
bash: ifconfig: command not found
root@332aa9930f30:/# ls
bin  boot  core  data  dev  docker-entrypoint-initdb.d	entrypoint.sh  etc  home  lib  lib64  media  mnt  opt  proc  root  run	sbin  selinux  srv  sys  tmp  usr  var
root@332aa9930f30:/# which ip
root@332aa9930f30:/# which ifconfig
root@332aa9930f30:/# docker run -itd --name centos3 --link centos2:alias centos
bash: docker: command not found
root@332aa9930f30:/# exit
exit

Les Processus

Consultez les processus d'un conteneur :

root@debian9:~# docker top centos3
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                31073               31060               0                   10:20               pts/0               00:00:00            /bin/bash

L'Activité en Continu

Pour voir l'activité d'un conteneur, utilisez la commande suivante :

root@debian9:~# docker stats centos3
CONTAINER           CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
centos3             0.00%               0B / 0B             0.00%               4.37kB / 952B       61.4kB / 0B         0

LAB #7 - Gestion des Ressources

La gestion de base des ressources allouées à un conteneur peut être réalisée par l'utilisation de deux options :

  • –memory
  • –cpu-shares

Par exemple, exécutez un conteneur à partir de l'image nginx avec une limite de la mémoire fixée à 256 Mo :

root@debian9:~# docker run -d -p 8081:80 --memory="256m" nginx
fc8ce16b3ec86433662719ca1f710a0588951d4f4abb8d90159b5953f419eef7

Exécutez ensuite la commande docker stats pour visualiser la limite de la mémoire :

CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
fc8ce16b3ec8        cool_blackwell      0.00%               1.793MiB / 256MiB   0.70%               2.45kB / 0B         0B / 0B             2

Important : Notez que la limite définie par –memory est une taille absolue tandis que la limite définie par –cpu-shares est relative.


<html>

Copyright © 2020 Hugh NORRIS

</html>

Menu