dockermachine
部署环境:
1:dockermachine 192.168.159.139
2:客户机A:192.168.159.143
3:客户机B:192.168.159.144
安装dockermachine
base=https://github.com/docker/machine/releases/download/v0.16.0 &&
curl -L $base/docker-machine-$(uname -s)-$(uname -m) >/tmp/docker-machine &&
sudo mv /tmp/docker-machine /usr/local/bin/docker-machine &&
chmod +x /usr/local/bin/docker-machine
查看dockermachine版本
docker-machine version
docker-machine version 0.16.0, build 9371605
为了更好的体验我们可以安装bash completion script 这样在bash可以命令补全和参数
[root@localhost bash_completion.d]# cat docker-machine.bash # # bash completion file for docker-machine commands # # This script provides completion of: # - commands and their options # - machine names # - filepaths # # To enable the completions either: # - place this file in /etc/bash_completion.d # or # - copy this file to e.g. ~/.docker-machine-completion.sh and add the line # below to your .bashrc after bash completion features are loaded # . ~/.docker-machine-completion.sh # # --- helper functions ------------------------------------------------------- _docker_machine_q() { docker-machine 2>/dev/null "$@" } # suppresses trailing whitespace _docker_machine_nospace() { # compopt is not available in ancient bash versions (OSX) # so only call it if it‘s available type compopt &>/dev/null && compopt -o nospace } _docker_machine_machines() { _docker_machine_q ls --format ‘{{.Name}}‘ "$@" } _docker_machine_drivers() { local drivers=( amazonec2 azure digitalocean exoscale generic google hyperv openstack rackspace softlayer virtualbox vmwarefusion vmwarevcloudair vmwarevsphere ) echo "${drivers[@]}" } _docker_machine_value_of_option() { local pattern="$1" for (( i=2; i < ${cword}; ++i)); do if [[ ${words[$i]} =~ ^($pattern)$ ]] ; then echo ${words[$i + 1]} break fi done } # Returns `key` if we are currently completing the value of a map option # (`key=value`) which matches the glob passed in as an argument. # This function is needed for key-specific argument completions. _docker_machine_map_key_of_current_option() { local glob="$1" local key glob_pos if [ "$cur" = "=" ] ; then # key= case key="$prev" glob_pos=$((cword - 2)) elif [[ $cur == *=* ]] ; then # key=value case (OSX) key=${cur%=*} glob_pos=$((cword - 1)) elif [ "$prev" = "=" ] ; then key=${words[$cword - 2]} # key=value case glob_pos=$((cword - 3)) else return fi [ "${words[$glob_pos]}" = "=" ] && ((glob_pos--)) # --option=key=value syntax [[ ${words[$glob_pos]} == $glob ]] && echo "$key" } # Finds the position of the first word that is neither option nor an option‘s argument. # If there are options that require arguments, you need to pass a glob describing # those options, e.g. "--option1|-o|--option2". # Use this function to restrict completions to exact positions after the options. _docker_machine_pos_first_nonflag() { local argument_flags=$1 local counter=$((${subcommand_pos:-${command_pos}} + 1)) while [ "$counter" -le "$cword" ]; do if [ -n "$argument_flags" ] && eval "case ‘${words[$counter]}‘ in $argument_flags) true ;; *) false ;; esac"; then (( counter++ )) # eat "=" in case of --option=arg syntax [ "${words[$counter]}" = "=" ] && (( counter++ )) else case "${words[$counter]}" in -*) ;; *) break ;; esac fi # Bash splits words at "=", retaining "=" as a word, examples: # "--debug=false" => 3 words, "--log-opt syslog-facility=daemon" => 4 words while [ "${words[$counter + 1]}" = "=" ] ; do counter=$(( counter + 2)) done (( counter++ )) done echo $counter } # --- completion functions --------------------------------------------------- _docker_machine_active() { case "${prev}" in --timeout|-t) return ;; esac if [[ "${cur}" == -* ]]; then COMPREPLY=($(compgen -W "--help --timeout -t" -- "${cur}")) fi } _docker_machine_config() { if [[ "${cur}" == -* ]]; then COMPREPLY=($(compgen -W "--help --swarm" -- "${cur}")) else COMPREPLY=($(compgen -W "$(_docker_machine_machines)" -- "${cur}")) fi } _docker_machine_create() { case "${prev}" in --driver|-d) COMPREPLY=($(compgen -W "$(_docker_machine_drivers)" -- "${cur}")) return ;; esac # driver specific options are only included in help output if --driver is given, # so we have to pass that option when calling docker-machine to harvest options. local driver="$(_docker_machine_value_of_option ‘--driver|-d‘)" local parsed_options="$(_docker_machine_q create ${driver:+--driver $driver} --help | grep ‘^ -‘ | sed ‘s/^ //; s/[^a-z0-9-].*$//‘)" if [[ ${cur} == -* ]]; then COMPREPLY=($(compgen -W "${parsed_options} -d --help" -- "${cur}")) fi } _docker_machine_env() { case "${prev}" in --shell) COMPREPLY=($(compgen -W "cmd emacs fish powershell tcsh" -- "${cur}")) return ;; esac if [[ "${cur}" == -* ]]; then COMPREPLY=($(compgen -W "--help --no-proxy --shell --swarm --unset -u" -- "${cur}")) else COMPREPLY=($(compgen -W "$(_docker_machine_machines)" -- "${cur}")) fi } # See docker-machine-wrapper.bash for the use command _docker_machine_use() { if [[ "${cur}" == -* ]]; then COMPREPLY=($(compgen -W "--help --swarm --unset" -- "${cur}")) else COMPREPLY=($(compgen -W "$(_docker_machine_machines)" -- "${cur}")) fi } _docker_machine_inspect() { case "${prev}" in --format|-f) return ;; esac if [[ "${cur}" == -* ]]; then COMPREPLY=($(compgen -W "--format -f --help" -- "${cur}")) else COMPREPLY=($(compgen -W "$(_docker_machine_machines)" -- "${cur}")) fi } _docker_machine_ip() { if [[ "${cur}" == -* ]]; then COMPREPLY=($(compgen -W "--help" -- "${cur}")) else COMPREPLY=($(compgen -W "$(_docker_machine_machines)" -- "${cur}")) fi } _docker_machine_kill() { if [[ "${cur}" == -* ]]; then COMPREPLY=($(compgen -W "--help" -- "${cur}")) else COMPREPLY=($(compgen -W "$(_docker_machine_machines)" -- "${cur}")) fi } _docker_machine_ls() { local key=$(_docker_machine_map_key_of_current_option ‘--filter‘) case "$key" in driver) COMPREPLY=($(compgen -W "$(_docker_machine_drivers)" -- "${cur##*=}")) return ;; state) COMPREPLY=($(compgen -W "Error Paused Running Saved Starting Stopped Stopping" -- "${cur##*=}")) return ;; esac case "${prev}" in --filter) COMPREPLY=($(compgen -W "driver label name state swarm" -S= -- "${cur}")) _docker_machine_nospace return ;; --format|-f|--timeout|-t) return ;; esac if [[ "${cur}" == -* ]]; then COMPREPLY=($(compgen -W "--filter --format -f --help --quiet -q --timeout -t" -- "${cur}")) fi } _docker_machine_mount() { if [[ "${cur}" == -* ]]; then COMPREPLY=($(compgen -W "--help --unmount -u" -- "${cur}")) else local pos=$(_docker_machine_pos_first_nonflag) if [ "$cword" -eq "$pos" ]; then # We can‘t complete remote filesystems. All we can do here is to complete the machine. COMPREPLY=($(compgen -W "$(_docker_machine_machines --filter state=Running)" -S: -- "${cur}")) _docker_machine_nospace elif [ "$cword" -eq "$((pos + 1))" ]; then _filedir -d fi fi } _docker_machine_provision() { if [[ "${cur}" == -* ]]; then COMPREPLY=($(compgen -W "--help" -- "${cur}")) else COMPREPLY=($(compgen -W "$(_docker_machine_machines --filter state=Running)" -- "${cur}")) fi } _docker_machine_regenerate_certs() { if [[ "${cur}" == -* ]]; then COMPREPLY=($(compgen -W "--client-certs --force -f --help" -- "${cur}")) else COMPREPLY=($(compgen -W "$(_docker_machine_machines --filter state=Running)" -- "${cur}")) fi } _docker_machine_restart() { if [[ "${cur}" == -* ]]; then COMPREPLY=($(compgen -W "--help" -- "${cur}")) else COMPREPLY=($(compgen -W "$(_docker_machine_machines)" -- "${cur}")) fi } _docker_machine_rm() { if [[ "${cur}" == -* ]]; then COMPREPLY=($(compgen -W "--force -f --help -y" -- "${cur}")) else COMPREPLY=($(compgen -W "$(_docker_machine_machines)" -- "${cur}")) fi } _docker_machine_ssh() { if [[ "${cur}" == -* ]]; then COMPREPLY=($(compgen -W "--help" -- "${cur}")) else COMPREPLY=($(compgen -W "$(_docker_machine_machines)" -- "${cur}")) fi } _docker_machine_scp() { if [[ "${cur}" == -* ]]; then COMPREPLY=($(compgen -W "--delta -d --help --quiet -q --recursive -r" -- "${cur}")) else _filedir # It would be really nice to ssh to the machine and ls to complete # remote files. COMPREPLY=($(compgen -W "$(_docker_machine_machines | sed ‘s/$/:/‘)" -- "${cur}") "${COMPREPLY[@]}") fi } _docker_machine_start() { if [[ "${cur}" == -* ]]; then COMPREPLY=($(compgen -W "--help" -- "${cur}")) else COMPREPLY=($(compgen -W "$(_docker_machine_machines --filter state=Stopped)" -- "${cur}")) fi } _docker_machine_status() { if [[ "${cur}" == -* ]]; then COMPREPLY=($(compgen -W "--help" -- "${cur}")) else COMPREPLY=($(compgen -W "$(_docker_machine_machines)" -- "${cur}")) fi } _docker_machine_stop() { if [[ "${cur}" == -* ]]; then COMPREPLY=($(compgen -W "--help" -- "${cur}")) else COMPREPLY=($(compgen -W "$(_docker_machine_machines --filter state=Running)" -- "${cur}")) fi } _docker_machine_upgrade() { if [[ "${cur}" == -* ]]; then COMPREPLY=($(compgen -W "--help" -- "${cur}")) else COMPREPLY=($(compgen -W "$(_docker_machine_machines)" -- "${cur}")) fi } _docker_machine_url() { if [[ "${cur}" == -* ]]; then COMPREPLY=($(compgen -W "--help" -- "${cur}")) else COMPREPLY=($(compgen -W "$(_docker_machine_machines)" -- "${cur}")) fi } _docker_machine_version() { if [[ "${cur}" == -* ]]; then COMPREPLY=($(compgen -W "--help" -- "${cur}")) else COMPREPLY=($(compgen -W "$(_docker_machine_machines)" -- "${cur}")) fi } _docker_machine_help() { if [[ "${cur}" == -* ]]; then COMPREPLY=($(compgen -W "--help" -- "${cur}")) else COMPREPLY=($(compgen -W "${commands[*]}" -- "${cur}")) fi } _docker_machine_docker_machine() { if [[ " ${wants_file[*]} " =~ " ${prev} " ]]; then _filedir elif [[ " ${wants_dir[*]} " =~ " ${prev} " ]]; then _filedir -d elif [[ "${cur}" == -* ]]; then COMPREPLY=($(compgen -W "${flags[*]} ${wants_dir[*]} ${wants_file[*]}" -- "${cur}")) else COMPREPLY=($(compgen -W "${commands[*]}" -- "${cur}")) fi } _docker_machine() { COMPREPLY=() local commands=(active config create env inspect ip kill ls mount provision regenerate-certs restart rm ssh scp start status stop upgrade url version help) local flags=(--debug --native-ssh --github-api-token --bugsnag-api-token --help --version) local wants_dir=(--storage-path) local wants_file=(--tls-ca-cert --tls-ca-key --tls-client-cert --tls-client-key) # Add the use subcommand, if we have an alias loaded if [[ ${DOCKER_MACHINE_WRAPPED} = true ]]; then commands=("${commands[@]}" use) fi local cur prev words cword _get_comp_words_by_ref -n : cur prev words cword local i local command=docker-machine command_pos=0 for (( i=1; i < ${cword}; ++i)); do local word=${words[i]} if [[ " ${wants_file[*]} ${wants_dir[*]} " =~ " ${word} " ]]; then # skip the next option (( ++i )) elif [[ " ${commands[*]} " =~ " ${word} " ]]; then command=${word} command_pos=$i fi done local completion_func=_docker_machine_"${command//-/_}" if declare -F "${completion_func}" > /dev/null; then ${completion_func} fi return 0 } complete -F _docker_machine docker-machine docker-machine.exe
[root@localhost bash_completion.d]# cat docker-machine docker-machine.bash docker-machine-prompt.bash docker-machine-wrapper.bash [root@localhost bash_completion.d]# cat docker-machine-prompt.bash # # bash prompt support for docker-machine # # This script allows you to see the active machine in your bash prompt. # # To enable: # 1a. Copy this file somewhere and source it in your .bashrc # source /some/where/docker-machine-prompt.bash # 1b. Alternatively, just copy this file into into /etc/bash_completion.d # 2. Change your PS1 to call __docker-machine-ps1 as command-substitution # PS1=‘[\u@\h \W$(__docker_machine_ps1 " [%s]")]\$ ‘ # # Configuration: # # DOCKER_MACHINE_PS1_SHOWSTATUS # When set, the machine status is indicated in the prompt. This can be slow, # so use with care. # [root@localhost bash_completion.d]# cat docker-machine-prompt.bash # # bash prompt support for docker-machine # # This script allows you to see the active machine in your bash prompt. # # To enable: # 1a. Copy this file somewhere and source it in your .bashrc # source /some/where/docker-machine-prompt.bash # 1b. Alternatively, just copy this file into into /etc/bash_completion.d # 2. Change your PS1 to call __docker-machine-ps1 as command-substitution # PS1=‘[\u@\h \W$(__docker_machine_ps1 " [%s]")]\$ ‘ # # Configuration: # # DOCKER_MACHINE_PS1_SHOWSTATUS # When set, the machine status is indicated in the prompt. This can be slow, # so use with care. # __docker_machine_ps1 () { local format=${1:- [%s]} if test ${DOCKER_MACHINE_NAME}; then local status if test ${DOCKER_MACHINE_PS1_SHOWSTATUS:-false} = true; then status=$(docker-machine status ${DOCKER_MACHINE_NAME}) case ${status} in Running) status=‘ R‘ ;; Stopping) status=‘ R->S‘ ;; Starting) status=‘ S->R‘ ;; Error|Timeout) status=‘ E‘ ;; *) # Just consider everything elase as ‘stopped‘ status=‘ S‘ ;; esac fi printf -- "${format}" "${DOCKER_MACHINE_NAME}${status}" fi }
[root@localhost bash_completion.d]# cat docker-machine-wrapper.bash # # Function wrapper to docker-machine that adds a use subcommand. # # The use subcommand runs `eval "$(docker-machine env [args])"`, which is a lot # less typing. # # To enable: # 1a. Copy this file somewhere and source it in your .bashrc # source /some/where/docker-machine-wrapper.bash # 1b. Alternatively, just copy this file into into /etc/bash_completion.d # # Configuration: # # DOCKER_MACHINE_WRAPPED # When set to a value other than true, this will disable the alias wrapper # alias for docker-machine. This is useful if you don‘t want the wrapper, # but it is installed by default by your installation. # : ${DOCKER_MACHINE_WRAPPED:=true} __docker_machine_wrapper () { if [[ "$1" == use ]]; then # Special use wrapper shift 1 case "$1" in -h|--help|"") cat <<EOF Usage: docker-machine use [OPTIONS] [arg...] Evaluate the commands to set up the environment for the Docker client Description: Argument is a machine name. Options: --swarm Display the Swarm config instead of the Docker daemon --unset, -u Unset variables instead of setting them EOF ;; *) eval "$(docker-machine env "$@")" echo "Active machine: ${DOCKER_MACHINE_NAME}" ;; esac else # Just call the actual docker-machine app command docker-machine "$@" fi } if [[ ${DOCKER_MACHINE_WRAPPED} = true ]]; then alias docker-machine=__docker_machine_wrapper fi
vim ~/.bashrc
添加
PS1=‘[\u@\h \W$(__docker_machine_ps1)]\$ ‘
dockermachine已经就绪了到这里
创建Machine
先执行docker-machine ls 查看一下当前的machine:
[root@localhost bash_completion.d]# docker-machine ls NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERROR
准备工作:
1:允许root ssh登录
[root@localhost bash_completion.d]# vim /etc/ssh/sshd_config PermitRootLogin yes
2:创建密钥对
[root@localhost bash_completion.d]# ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): Created directory ‘/root/.ssh‘. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /root/.ssh/id_rsa. Your public key has been saved in /root/.ssh/id_rsa.pub. The key fingerprint is: SHA256:cBKZfnbMi6qeI2c5MjhcBie35+rAkG23Zt47wuo7UBM root@localhost.localdomain The key‘s randomart image is: +---[RSA 2048]----+ | .o | | E o. | | . .o .o | | =oo .+o + | |o.B.o oSo . | |+. = o . . | |.=o.*. . | |o.*+O+o | | o=&*=oo | +----[SHA256]-----+
3.免交互root登录系统
[root@localhost bash_completion.d]# ssh-copy-id -i 192.168.159.143 /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub" The authenticity of host ‘192.168.159.143 (192.168.159.143)‘ can‘t be established. ECDSA key fingerprint is SHA256:jT4Cb7sgUbdyx4AB3hYQ7Pqtwvin4pg+n3LwW6wM0Cs. ECDSA key fingerprint is MD5:bb:64:7a:62:57:db:3a:56:9e:51:69:07:f0:d6:83:90. Are you sure you want to continue connecting (yes/no)? yes /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys root@192.168.159.143‘s password: Number of key(s) added: 1 Now try logging into the machine, with: "ssh ‘192.168.159.143‘" and check to make sure that only the key(s) you wanted were added.
[root@localhost bash_completion.d]# ssh-copy-id -i 192.168.159.144 /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub" The authenticity of host ‘192.168.159.144 (192.168.159.144)‘ can‘t be established. ECDSA key fingerprint is SHA256:i8e6pmmQsI4evtNtJfsoDr/ZTd3musgpv1w5pk4TFoE. ECDSA key fingerprint is MD5:50:d2:c5:3c:87:f1:ae:23:58:86:f8:36:f9:8a:64:d2. Are you sure you want to continue connecting (yes/no)? yes /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys root@192.168.159.144‘s password: Number of key(s) added: 1 Now try logging into the machine, with: "ssh ‘192.168.159.144‘" and check to make sure that only the key(s) you wanted were added.
4:启用visiblepw(感叹号去掉)
[root@localhost bash_completion.d]# vim /etc/sudoers
Defaults visiblepw
重启sshd服务
[root@localhost bash_completion.d]# systemctl restart sshd
准备就绪了,执行docker-machine create 命令创建host1:
[root@localhost bash_completion.d]# docker-machine create -d generic --generic-ip-address=192.168.159.143 host1 Creating CA: /root/.docker/machine/certs/ca.pem Creating client certificate: /root/.docker/machine/certs/cert.pem Running pre-create checks... Creating machine... (host1) No SSH key specified. Assuming an existing key at the default location. Waiting for machine to be running, this may take a few minutes... Detecting operating system of created instance... Waiting for SSH to be available... Detecting the provisioner... Provisioning with centos... Copying certs to the local machine directory... Copying certs to the remote machine... Setting Docker configuration on the remote daemon... Checking connection to Docker... Error creating machine: Error checking the host: Error checking and/or regenerating the certs: There was an error validating certificates for host "192.168.159.143:2376": dial tcp 192.168.159.143:2376: connect: no route to host You can attempt to regenerate them using ‘docker-machine regenerate-certs [name]‘. Be advised that this will trigger a Docker daemon restart which might stop running containers.
出现以上界面是因为我们的setenforce 没有关还有防火墙没有设置策略
正常是显示这样
[root@localhost ~]# docker-machine create -d generic --generic-ip-address=192.168.159.144 host2 Running pre-create checks... Creating machine... (host2) No SSH key specified. Assuming an existing key at the default location. Waiting for machine to be running, this may take a few minutes... Detecting operating system of created instance... Waiting for SSH to be available... Detecting the provisioner... Provisioning with centos... Copying certs to the local machine directory... Copying certs to the remote machine... Setting Docker configuration on the remote daemon... Checking connection to Docker... Docker is up and running! To see how to connect your Docker Client to the Docker Engine running on this virtual machine, run: docker-machine env host2
现在看到已经两台机器docker已经部署完成
验证
[root@localhost ~]# systemctl status docker ● docker.service - Docker Application Container Engine Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled) Drop-In: /etc/systemd/system/docker.service.d └─10-machine.conf Active: active (running) since 三 2020-06-03 20:33:03 CST; 9min ago
可以看出docker已经安装并且启动
并且主机名字都给改了
[root@localhost ~]# bash
[root@host1 ~]#
管理machine
用docker-machine创建machine的过程很简洁,非常适合多主机环境除此之外提供了一些子命令进行管理用得最多的
docker-machine env 【主机名】
[root@localhost bash_completion.d]# docker-machine env host1 export DOCKER_TLS_VERIFY="1" export DOCKER_HOST="tcp://192.168.159.143:2376" export DOCKER_CERT_PATH="/root/.docker/machine/machines/host1" export DOCKER_MACHINE_NAME="host1" # Run this command to configure your shell: # eval $(docker-machine env host1)
场景:在安装完docker-machine,设置docker-machine命令自动补齐的时候,出现以下错误:
-bash: __docker_machine_ps1: 未找到命令
解决办法:在~/.bashrc中添加如下三行:
source /etc/bash_completion.d/docker-machine-wrapper.bash source /etc/bash_completion.d/docker-machine-prompt.bash source /etc/bash_completion.d/docker-machine.bash
然后重新进行 source /root/.bashrc
这样就可以使用了
[root@localhost ~]# eval $(docker-machine env host1) [root@localhost ~ [host1]]#
现在我们再dockermachine上给host1下载一个busybox
去host1查看一下是否有了
[root@host1 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE busybox latest 1c35c4412082 16 hours ago 1.22MB
可以看到已经下载好了
执行
[root@localhost ~ [host1]]# eval $(docker-machine env host2) [root@localhost ~ [host2]]#
发现已经切换到host2了