Docker Machine
简介
Docker Machine
是Docker
官方编排(Orchestration)项目之一,负责在多种平台上快速安装Docker
环境Docker Machine
项目基于Go
语言实现,目前在Github
上进行维护.用Docker Machine
可以批量安装和配置docker host
,这个host
可以是本地的虚拟机,物理机,也可以是公有云中的云主机.Docker Machine
支持在不同的环境下安装配置docker host
,包括:- (1) 常规
Linux
操作系统. - (2) 虚拟化平台—VirtualBox,VMWare,Hyper-V,OpenStack.
- (3) 公有云—
Amazon Web Services
,Microsoft Azure
,Google Compute Engine
,Digital Ocean
等.
- (1) 常规
Docker Machine
为这些环境起了一个统一的名字:provider
.对于某个特定的provider
,Docker Machine
使用相应的driver
安装和配置docker host
.
脚本安装
1 | # 安装 |
创建Machine
- 下面命令就会在本机的VirtualBox里创建一个名为
default
的虚拟机.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25$ docker-machine create -d virtualbox default
Running pre-create checks...
Creating machine...
(default) Copying /home/lcy/.docker/machine/cache/boot2docker.iso to /home/lcy/.docker/machine/machines/default/boot2docker.iso...
(default) Creating VirtualBox VM...
(default) Creating SSH key...
(default) Starting the VM...
(default) Check network to re-create if needed...
(default) Waiting for an IP...
Waiting for machine to be running, this may take a few minutes...
Detecting operating system of created instance...
[...]
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 default
~$ docker-machine create -d virtualbox manager1 &&
> docker-machine create -d virtualbox manager2 &&
> docker-machine create -d virtualbox worker1 &&
> docker-machine create -d virtualbox worker2
~$ docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
default - virtualbox Running tcp://192.168.99.100:2376 v18.09.1
manager1 - virtualbox Running tcp://192.168.99.101:2376 v18.09.1
manager2 - virtualbox Running tcp://192.168.99.102:2376 v18.09.1
worker1 - virtualbox Running tcp://192.168.99.103:2376 v18.09.1
worker2 - virtualbox Running tcp://192.168.99.104:2376 v18.09.1
Docker
端的操作
1 | # 更新worker1,worker2的docker到最新版本,可以指执行. |
- 为了支持
ansible
管理操作,下面安装一些python
环境相关的软件.参考链接.tce
的安装目录是docker@manager1:/usr/local/tce.installed
,比如:要先删除python
旧的安装的命令:docker-machine ssh manager1 "rm -rf /usr/local/tce.installed/python"
,再用下面命令重新安装.这里使用的bash
脚本的for
循环串行处理,如果要并行处理,可以参考parallel.
安装python
环境包
1 | ~$ for item in manager1 manager2 worker1 worker2; do docker-machine ssh $item "tce-load -wi python && curl https://bootstrap.pypa.io/get-pip.py | sudo python - && sudo ln -s /usr/local/bin/python /usr/bin/python";done |
Ansible
管理连接
创建主机文件,因为每一个主机的私钥位置不同.所以在
hosts.txt
中具体指定如下.1
2
3
4
5
6
7~$ cat hosts.txt
[swarm]
192.168.99.100 ansible_ssh_private_key_file=/home/lcy/.docker/machine/machines/default/id_rsa ansible_python_interpreter=/usr/local/bin/python
192.168.99.101 ansible_ssh_private_key_file=/home/lcy/.docker/machine/machines/manager1/id_rsa ansible_python_interpreter=/usr/local/bin/python
192.168.99.102 ansible_ssh_private_key_file=/home/lcy/.docker/machine/machines/manager2/id_rsa ansible_python_interpreter=/usr/local/bin/python
192.168.99.103 ansible_ssh_private_key_file=/home/lcy/.docker/machine/machines/worker1/id_rsa ansible_python_interpreter=/usr/local/bin/python
192.168.99.104 ansible_ssh_private_key_file=/home/lcy/.docker/machine/machines/worker2/id_rsa ansible_python_interpreter=/usr/local/bin/python连接测试.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21~$ ansible -i hosts.txt all -u docker -m ping
192.168.99.102 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.99.100 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.99.103 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.99.104 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.99.101 | SUCCESS => {
"changed": false,
"ping": "pong"
}
配置Docker Swarm
集群节点
配置Swarm
管理节点
1 | ~$ docker-machine ssh manager1 "docker swarm init --advertise-addr 192.168.99.101" |
配置工作节点
- 把
worker1
,worker2
创建成工作节点,并加入到集群中.1
2
3
4
5~$ docker-machine ssh worker1 "docker swarm join --token SWMTKN-1-4lwpkgvw8lqn68k20n89qy39uvhdx4u6cznak5zy3q6sp5nlp3-dsf3agxhdq6prycves2cxg16w 192.168.99.101:2377"
This node joined a swarm as a worker.
~$ docker-machine ssh worker2 "docker swarm join --token SWMTKN-1-4lwpkgvw8lqn68k20n89qy39uvhdx4u6cznak5zy3q6sp5nlp3-dsf3agxhdq6prycves2cxg16w 192.168.99.101:2377"
This node joined a swarm as a worker.
添加备用管理节点
1 | # 查看加入swarm集群管理节点的token |
创建docker
私有仓库
通过下命令在本机创建一个私有的镜像仓库.
1
2
3
4
5
6
7
8~$ docker run -d -v /data/docker-registry:/var/lib/registry -p 5000:5000 --restart=always --name registry registry
Unable to find image 'registry:latest' locally
latest: Pulling from library/registry
cd784148e348: Pull complete
[...]
Digest: sha256:a54bc9be148764891c44676ce8c44f1e53514c43b1bfbab87b896f4b9f0b5d99
Status: Downloaded newer image for registry:latest
242af2d15586d2d571c46c5edf821ce958cf22139d957e52a6f5d959726957bf接下来,将本地已有的镜像文件推送到刚才新建的仓库中去.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
242af2d15586 registry "/entrypoint.sh /etc…" About a minute ago Up About a minute 0.0.0.0:5000->5000/tcp registry
8ee3d7fb435f redis "docker-entrypoint.s…" 4 months ago Up 3 hours 0.0.0.0:6379->6379/tcp redis
608b60a022e8 postgres:9.6 "docker-entrypoint.s…" 4 months ago Up 3 hours 0.0.0.0:5432->5432/tcp pg96
# 把本地的postgres:9.6版本的镜像,改成192.168.99.1:5000/postgres:v3标签
~$ docker tag postgres:9.6 192.168.99.1:5000/postgres:v3
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
registry latest 116995fd6624 5 days ago 25.8MB
127.0.0.1:5000/postgres 9.6 0178d5af9576 5 months ago 229MB
192.168.99.1:5000/postgres 9.6 0178d5af9576 5 months ago 229MB
postgres 9.6 0178d5af9576 5 months ago 229MB
# 推送镜像.
~$ docker push 192.168.99.1:5000/postgres:v3
The push refers to repository [192.168.99.1:5000/postgres]
10cb36af78fe: Pushed
[...]
v3: digest: sha256:86a7984760c1d36c7c9ebec73706f05d76e7615937a45ae0d110b2112fd5cbfa size: 3245
~$ curl http://192.168.99.1:5000/v2/_catalog
{"repositories":["postgres"]}
~$ curl http://192.168.99.1:5000/v2/postgres/tags/list
{"name":"postgres","tags":["v3"]}简单的从公网下载镜推进私有库中.
1
2
3
4
5~$ docker pull dockersamples/visualizer
~$ docker tag dockersamples/visualizer 192.168.99.1:5000/visualizer:v4
~$ docker push 192.168.99.1:5000/visualizer:v4
~$ curl http://192.168.99.1:5000/v2/_catalog
{"repositories":["postgres","visualizer"]}
- 通过 ansible 命令,在4个 hosts 节点中的 docker 启动参数中加入前面创建的私有仓库地址.
1 | ~$ ansible -i hosts.txt all -u docker -b -m lineinfile -a "path=/etc/docker/daemon.json line='{\n\t\t\"insecure-registries\": [\"192.168.99.1:5000\"]\n}' create=yes" |
Docker Service
部署单个集群服务
1 | ~$ docker-machine ssh manager1 "docker service create --replicas 4 -p 15432:5432 --name pgsql 192.168.99.1:5000/postgres:v3" |
Docker Stack
部署多个集群服务
确保下列的
image
是在本的仓库中找得到的.确认镜像1
2
3
4~$ docker images | awk '$2 ~/v4/ {print}'
192.168.99.1:5000/nginx v4 42b4762643dc 34 hours ago 109MB
192.168.99.1:5000/visualizer v4 f6411ebd974c 3 weeks ago 166MB
192.168.99.1:5000/portainer v4 a01958db7424 6 weeks ago 72.2MBdocker-compose.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32version: '3'
services:
nginx:
image: 192.168.99.1:5000/nginx:v4
ports:
- 8088:80
deploy:
mode: replicated
replicas: 4
visualizer:
image: 192.168.99.1:5000/visualizer:v4
ports:
- '8080:8080'
volumes:
- '/var/run/docker.sock:/var/run/docker.sock'
deploy:
replicas: 1
placement:
constraints: [node.role == manager]
portainer:
image: 192.168.99.1:5000/portainer:v4
ports:
- '9000:9000'
volumes:
- '/var/run/docker.sock:/var/run/docker.sock'
deploy:
replicas: 1
placement:
constraints: [node.role == manager]
创建服务
1 | ~$ docker-machine ssh manager1 "docker stack deploy -c docker-compose.yml deploy-demo" |
- 用浏览器测试打开如下网页:
管理阿里云ECS
阿里云官方驱动
- 阿里云 Docker Machine 驱动
- 阿里云 ECS Docker Machine Driver 入门指南
- 按照上述在本地的
VirtualBox
创建主机的类比,使用阿里云官方的驱动,需要阿里的的安全秘钥以及对应的Region
信息.如果想创建VPC
网络,还需要有VPC ID
和VSwitch ID
.操作起稍显麻烦,而且--aliyunecs-access-key-id
,--aliyunecs-access-key-secret
这两个参数权限是相当重要,这个只在以后工作的具体应用中有使用需要时,再去了解它的功能.
generic
驱动
- 下面虽然没有阿里云
driver
但有一个generic driver
,可通过ssh
管理现有的机器,原则上所有的Linux
机器都支持.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22~$ docker-machine create --driver generic --generic-ip-address DB001 --generic-ssh-user lcy --generic-ssh-key $HOME/.ssh/id_rsa aliyun-machine
Running pre-create checks...
Creating machine...
(aliyun-machine) Importing SSH key...
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 debian...
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 aliyun-machine
~$ docker-machine env aliyun-machine
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://DB001:2376"
export DOCKER_CERT_PATH="/home/lcy/.docker/machine/machines/aliyun-machine"
export DOCKER_MACHINE_NAME="aliyun-machine"
# Run this command to configure your shell:
# eval $(docker-machine env aliyun-machine)
错误
要在
/etc/docker/daemon.json
加入{ "insecure-registries": ["192.168.99.1:5000"] }
这一行,不然会出现下面的错误.1
2~$ docker pull 192.168.99.1:5000/postgres:9.6
Error response from daemon: Get https://192.168.99.1:5000/v2/: http: server gave HTTP response to HTTPS clientansible
连接到boot2docker
镜像无python
环境的错误1
2
3
4
5
6
7192.168.99.102 | FAILED! => {
"changed": false,
"module_stderr": "Shared connection to 192.168.99.102 closed.\r\n",
"module_stdout": "/bin/sh: /usr/local/bin/python: not found\r\n",
"msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
"rc": 127
}
Ansible
- 参考链接:
- 环境简介
- docker 18.09.0
- ansible 2.7.5
- debian stretch
- postgresql 10.6
- python 3.6.6
安装
1 | ~$ pip install ansible ansible-lint |
命令格式
ansible <host-pattern> [options]
,是 Inventory
中定义的主机或主机组,可以为ip,hostname,Inventory
中的group
组名,具有".","\*".":"
等特殊字符的匹配型字符串.<>
;表示为必须参数,\[\]
表示为可选参数.- 比如使用
apt
模块,root
用户,更新系统的命令.后面会讲基于YMAL
格式的配置文件.1
~$ ansible -i ~/.ansible/hosts all -u root -m apt -a "upgrade=yes update_cache=yes cache_valid_time=86400"
- 下例使用
authorized_key
模块为用户添加公钥匙,exclusive=True
就为替换现有的 key.下例为:在原有的 key 附加新的 key.1
2
3~$ ansible -i ~/.ansible/hosts all -u lcy -m authorized_key -a "user=lcy state=present key='ssh-rsa AAAAB3NzaC1yc...... user@gentoo'"
# 在主机的hosts添加
~$ ansible -i ~/.ansible/hosts all -u lcy -b -m lineinfile -a "path=/etc/hosts create=yes line='127.0.0.1\tlocalhost\n172.18.127.186\tDB001\n172.18.192.77\tWeb001\n172.18.253.222\tFE001\n172.18.192.76\tDIG001'"
查看系统信息
1 | # 这里是调用command这个模块,运行系统命令. |
命令工具
ansible-doc
- 使用
ansible-doc
可以查看所有支持的模块文档,因为我这里使用的是Debian
,这里把它相关的包管理模块列出来.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23~$ ansible-doc -l | grep "apt"
apt Manages apt-packages
apt_key Add or remove an apt key
apt_repository Add and remove APT repositories
apt_rpm apt_rpm package manager
na_ontap_ucadapter NetApp ONTAP UC adapter configuration
nios_naptr_record Configure Infoblox NIOS NAPTR records
# 可以查该模块的参数与使用示例.也可以打开网页文档[apt_module](https://docs.ansible.com/ansible/latest/modules/apt_module.html)
~$ ansible-doc apt
> APT (/home/lcy/.pyenv/versions/3.6.6/envs/py3dev/lib/python3.6/site-packages/ansible/modules/packaging/os/apt.py)
Manages \`apt\' packages (such as for Debian/Ubuntu).
OPTIONS (= is mandatory):
- allow_unauthenticated
Ignore if packages cannot be authenticated. This is useful for bootstrapping environments that manage their own apt-key setup.
\`allow_unauthenticated\' is only supported with state: \`install\'/\`present\'
[Default: no]
type: bool
version_added: 2.1
[....]
ansible-playbook
Ansiable
的任务配置文件被称为Playbook
,可以称之为”剧本”,Playbook
具有编写简单,可定制性高,灵活方便,以及可固化日常所有操作的特点.在下面的docker 安装用一个真实的完整实例演示.
配置
- 默认配置文件名为
ansible.cfg
,它可以存在于很多地方,默认是/etc/ansible.cfg
与用户目录下的~/.ansible/ansible.cfg
.Ad-Hoc
,Ansible-playbook
,前者是临时命令的执行,后者是Ad-Hoc
的集合,相当于是一个脚本. - 下面是一个经典的
hosts
文件,它默认找的位置是/etc/ansible/hosts
,这里是用户目录.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30~$ cat ~/.ansible/hosts
[Web001]
120.77.xxx.xx
[DB001]
119.23.xx.xxx
[DIG001]
120.78.xx.xxx
[FE001]
112.74.xxx.xx
~$ ansible -i ~/.ansible/hosts all -m ping -u root
120.77.xxx.xx | SUCCESS => {
"changed": false,
"ping": "pong"
}
119.23.xx.xxx | SUCCESS => {
"changed": false,
"ping": "pong"
}
112.74.xx.xxx | SUCCESS => {
"changed": false,
"ping": "pong"
}
120.78.xxx.xx | SUCCESS => {
"changed": false,
"ping": "pong"
}
ansible-vault
ansible-vault
主要用于配置文件加密,如编写要的Playbook
配置文件里包含敏感信息.参考这里
1 | # 加密后的a.yaml打开全是乱码. |
ansible-galaxy
这个跟三星手机没有任何关系 ,可以把它简单地理解为
github
或者pip
的功能.主要是用来生成,查找,安装一些优秀的Roles
.一些优质的Roles
可以在这里找到.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16~$ ansible-galaxy --help
Usage: ansible-galaxy [delete|import|info|init|install|list|login|remove|search|setup] [--help] [options] ...
Perform various Role related operations.
Options:
-h, --help show this help message and exit
-c, --ignore-certs Ignore SSL certificate validation errors.
-s API_SERVER, --server=API_SERVER
The API server destination
-v, --verbose verbose mode (-vvv for more, -vvvv to enable
connection debugging)
--version show program's version number and exit
See 'ansible-galaxy <command> --help' for more information on a specific
command.安装
postgresql Roles
,以及它的目录结构.如果要创建自定义的Roles
,可以参考这些结构.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45~$ ansible-galaxy install geerlingguy.postgresql
- downloading role 'postgresql', owned by geerlingguy
- downloading role from https://github.com/geerlingguy/ansible-role-postgresql/archive/1.4.5.tar.gz
- extracting geerlingguy.postgresql to /home/lcy/.ansible/roles/geerlingguy.postgresql
- geerlingguy.postgresql (1.4.5) was installed successfully
~$ tree /home/lcy/.ansible/roles/geerlingguy.postgresql/
/home/lcy/.ansible/roles/geerlingguy.postgresql/
├── defaults
│ └── main.yml
├── handlers
│ └── main.yml
├── LICENSE
├── meta
│ └── main.yml
├── molecule
│ └── default
│ ├── molecule.yml
│ ├── playbook.yml
│ ├── tests
│ │ └── test_default.py
│ └── yaml-lint.yml
├── README.md
├── tasks
│ ├── configure.yml
│ ├── databases.yml
│ ├── initialize.yml
│ ├── main.yml
│ ├── setup-Debian.yml
│ ├── setup-RedHat.yml
│ ├── users.yml
│ └── variables.yml
├── templates
│ ├── pg_hba.conf.j2
│ └── postgres.sh.j2
└── vars
├── Debian-7.yml
├── Debian-8.yml
├── Debian-9.yml
├── RedHat-6.yml
├── RedHat-7.yml
├── Ubuntu-14.yml
├── Ubuntu-16.yml
└── Ubuntu-18.yml
9 directories, 27 files
通过Ansiable
安装docker
Serve Static Files by Nginx from Django using Docker
- apt - Manages apt-packages - Get Docker CE for Debian - 这里参照Get Docker CE for Debian,把它的安装流程转换成一个Playbook
文件来执行.这种安装方式,各个被安装的目标主机间的 docker 是相互独立的,如果要把它们集合起来做编排,要使用Docker Machine.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76---
- name: 安装基础软件
hosts: all
become: yes
# user: root 这里可以直接用root,但是关闭root远程登录后要使用sudo.
tasks:
# 参照文档 https://docs.ansible.com/ansible/latest/modules/apt_module.html
- name: 更新并安装
apt:
name: ['apt-transport-https', 'ca-certificates', 'curl', 'software-properties-common', tmux]
allow_unauthenticated: yes
update_cache: yes
# 这是另一种安装软件列表的方式
- name: Install a list of packages
apt:
name: '{{ packages }}'
update_cache: yes
vars:
packages:
- git
- rsync
- gcc
- dirmngr
- bwn-ng
- tmux
- tree
- name: 更新并安装 gnupg2
apt:
name: gnupg2
allow_unauthenticated: no
update_cache: yes
# 参照文档 https://docs.ansible.com/ansible/latest/modules/apt_key_module.html?highlight=apt%20key
- name: 添加新的公钥
apt_key:
url: https://download.docker.com/linux/debian/gpg
state: present
# 参考文档 https://docs.ansible.com/ansible/latest/modules/command_module.html#command-module
- name: 读取系统发行版本号
command: lsb_release -sc
register: result
# 参照文档 https://docs.ansible.com/ansible/latest/modules/apt_repository_module.html?highlight=add%20apt%20repository
- apt_repository:
repo: deb [arch=amd64] https://download.docker.com/linux/debian {{ result.stdout }} stable
state: present
filename: docker-ce
# 安装docker-ce,docker-compose
- name: 更新并安装 'docker-ce', ,'bridge-utils'
apt:
name: ['docker-ce', 'bridge-utils']
allow_unauthenticated: yes
update_cache: yes
- name:
command: uname -s
register: vendor
- name:
command: uname -m
register: arch
# 安装最新版本的docker-compose,使用apt安装的版本很老.
- name: 安装最新版本的docker-compose-1.23.2
get_url:
url: https://github.com/docker/compose/releases/download/1.23.2/docker-compose-{{ vendor.stdout }}-{{ arch.stdout }}
dest: /usr/local/bin/docker-compose
mode: 0755
- name: 重启机器
reboot:
reboot_timeout: 3600重启之后,应该就可以用下面命令行查看
docker
信息了.
1 | ~$ ansible -i ~/.ansible/hosts all -u lcy -m command -a "docker info" |
- 注意:如不安装
bridge-utils
并重启,docker
无法启动,可能会出现如下错误.1
2
3
4Dec 29 10:26:16 DB001 dockerd[20493]: time="2018-12-29T10:26:16.760508487+08:00" level=info msg="stopping event stream following graceful shutdown" error="<nil>" module=libcontainerd namespace=moby
Dec 29 10:26:16 DB001 dockerd[20493]: Error starting daemon: Error initializing network controller: Error creating default "bridge" network: package not installed
Dec 29 10:26:16 DB001 systemd[1]: docker.service: Main process exited, code=exited, status=1/FAILURE
Dec 29 10:26:16 DB001 systemd[1]: Failed to start Docker Application Container Engine.
添加用户与组
关于与开启用户的
sudo
功能,有两种方法,一是可以修改远程主机的/etc/sudoers
文件.可以参照这里 也可以使用复制替换的方法,参照这里.也可以把用户加进sudo
组里.如果要每一个用户添加一个初始密码,可以参照这里.Linux 下可以使用
mkpasswd
命令,如果其它系统,可以使用passlib
这个python
的包来替换.如要使用sudo
不用密码,要添加NOPASSWORD
关键字.1
2
3
4
5
6
7~$ mkpasswd --method=sha-512
Password:
$6$5QYVZSmH7$FXQcAQ8FsjMVk0x.ATQgpFHhgImp7hdITMh7zAE.VeAkQYDzdFAOxx6jqVFOY.52nRW4a6SjzEUnK.JSh73W61
~$ python -c "from passlib.hash import sha512_crypt; import getpass; print(sha512_crypt.using(rounds=5000).hash(getpass.getpass()))"
Password:
$6$J15B6vXoZeekBlVy$.F6PelDYQRCeqapZ2/V3BQ5IjJXCdhG4g5NgoeNvnGJqf1dValk38IDzBuMfmctLMgQ4llyzVT3WN4pYrIpmZ0下面是添加两个用户,并加入相关组,以及修改
sshd_config
的相关参数.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75---
- name: 添加用户
hosts: all
user: root
tasks:
- name: remove users
user:
name: '{{ item }}'
state: absent # absent 表示移除,present 表示添加
remove: yes
with_items:
- lcy
- gavin_kou
- name: add the user "{{ item }}"
# 参考链接 https://docs.ansible.com/ansible/latest/modules/user_module.html?highlight=user
user:
name: '{{ item }}'
append: yes
groups: docker,sudo
shell: /bin/bash
state: present
generate_ssh_key: yes
ssh_key_bits: 2048
# ssh_key_file: .ssh/id_rsa
# 这里可以使用 with_items来做数组循环. https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html?highlight=with_items
with_items:
- lcy
- gavin_kou
- name: 复制本的公钥到远程用户下.
# 参考链接 https://docs.ansible.com/ansible/latest/modules/authorized_key_module.html
authorized_key:
user: lcy
state: present
# exclusive: True
key: "{{ lookup('file', lookup('env','HOME') + '/.ssh/id_rsa.pub') }}\n"
- name: Set authorized key for user ubuntu copying it from current user
# 参考链接 https://docs.ansible.com/ansible/latest/modules/authorized_key_module.html
authorized_key:
user: gavin_kou
state: present
key: "{{ lookup('file','~/.ansible/gavin.pub') }}\n"
# 参考链接 https://docs.ansible.com/ansible/latest/modules/lineinfile_module.html?highlight=sudoers
- lineinfile:
path: /etc/sudoers
state: present
regexp: '^%sudo\s'
line: '%sudo ALL=(ALL) NOPASSWD: ALL'
validate: '/usr/sbin/visudo -cf %s'
# 关闭ssh的root登录功能.所以运行完这个剧本就不能使用root用户执行第二次了.
- lineinfile:
path: /etc/ssh/sshd_config
state: present
regexp: '^PermitRootLogin\s'
line: 'PermitRootLogin no'
- lineinfile:
path: /etc/ssh/sshd_config
state: present
regexp: '^#ClientAliveInterval\s'
line: 'ClientAliveInterval 30'
- lineinfile:
path: /etc/ssh/sshd_config
state: present
regexp: '^#ClientAliveCountMax\s'
line: 'ClientAliveCountMax 3'
# 参考消息 https://docs.ansible.com/ansible/latest/modules/systemd_module.html
- name: 重加载sshd
systemd:
name: sshd
state: reloaded
Docker
的图形界面
UI For Docker已经
deprecated
,还是使用Portainer
.-
1
~$ docker run -d -p 9000:9000 --privileged -v /var/run/docker.sock:/var/run/docker.sock --name web-ui uifd/ui-for-docker
Portainer
是一个开源、轻量级Docker
管理用户界面,基于Docker API
,提供状态显示面板、应用模板快速部署、容器镜像网络数据卷的基本操作(包括上传下载镜像,创建容器等操作)、事件日志显示、容器控制台操作Swarm
集群和服务等集中管理和操作、登录用户管理和控制等功能.功能十分全面,基本能满足中小型单位对容器管理的全部需求.1
~$ docker run -d -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data -v /etc/hosts:/etc/hosts --name portainer-ui portainer/portainer
添加其它Docker
服务器到portainer
Protect the Docker daemon socket
TLS
链接参考这里.portainer
添加外部Docker
实例有三种模式,一种是dockerd -H tcp://192.168.xx.xx:2376
,通过监听TCP socket
方式.这里可以用通过TLS
来保证安全.第二种就是在目标服务器上安装portainer
的agent.以上两种方法,创建TLS
证书比较麻烦,安装agent
会消耗一些资源.Docker 从18.09
开始,客户端可以通过SSH
访问:docker -H ssh://me@example.com ps
,但是portainer
不支持这种协议方式, 只支持两种协议:tcp://
,unix://
.下面介绍如何使用
TLS
证书连接远程的Docker Engine
.1
2
3
4
5
6# 创建CA私钥
~$ openssl genrsa -aes256 -out ca.key 4096
# 使和CA私钥创建CA证书.
~$ openssl req -new -x509 -days 365 -key ca.key -sha256 -out ca.pem
# 创建服务器私钥匙
~$ openssl genrsa -out server.key 4096创建服务器
CSR
文件.注意CN(Common Name)
如果是域名如:www.examples.com
,则客户端必须过www.examples.com
访问到该服务器.才能验证通过.TLS
连接时,需要限制客户端的IP
或者域名列表.可以用使用密钥扩展文件支持.如只允许127.0.0.1 和 192.168.1.100
客户端访问.echo subhectAltName = IP:127.0.0.1,IP:192.168.1.100 > allowips.cnf
,在下面创建服务器证书命令后加上-extfile allowips.cnf
就可以支持了.
1 | ~$ openssl req -subj "/CN=*" -sha256 -new -key server.key -out server.csr |
- 创建客户端私钥与CSR
1 | ~$ openssl genrsa -out client.key 4096 |
- 运行服务端与客户端测试.为保证公钥文件安全,需要修改公钥匙文件的访问权限:
chmod -v 0400 ca.key server.key client.key
.防止证书被篡改:chmod -v 0444 ca.pem server.pem client.pem
.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33~$ tree
.
├── ca.key
├── ca.pem
├── ca.srl
├── client.key
├── client.pem
├── server.key
└── server.pem
# 服务端运行
~$ sudo dockerd --tlsverify --tlscacert=ca.pem --tlscert=server.pem --tlskey=server.key -H tcp://0.0.0.0:2376
# 客户端运行.这里必须使用主机名连接,所以上述portainer-ui容器运行,使用 -v /etc/hosts:/etc/hosts 选项.
~$ docker --tlsverify --tlscacert=ca.pem --tlscert=client.pem --tlskey=client.key -H tcp://<主机名>:2376 version
# Docker 从 18.09 开始支持通过SSH访问,这个更安全更便捷.
~$ docker -H ssh://user@domain.com version
Client:
Version: 18.09.1
API version: 1.39
Go version: go1.10.6
Git commit: 4c52b90
Built: Wed Jan 9 19:35:59 2019
OS/Arch: linux/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 18.09.1
API version: 1.39 (minimum version 1.12)
Go version: go1.10.6
Git commit: 4c52b90
Built: Wed Jan 9 19:02:44 2019
OS/Arch: linux/amd64
Experimental: false
修改服务端systemd service
- 带证书启动的
docker
进程可以按照上述的手动运行的形式,也可以通过修改系统的systemed
来开启,把服务端的证书文件复制到/etc/docker/
下面.方法如下:1
2
3
4
5
6~$ cat /lib/systemd/system/docker.service
[...]
#ExecStart=/usr/bin/dockerd -H fd:// 这是原来默认的,只开放本地连接.
ExecStart=/usr/bin/dockerd --tlsverify --tlscacert=/etc/docker/ca.pem --tlscert=/etc/docker/server.pem --tlskey=/etc/docker/server.key -H tcp://0.0.0.0:2376 -H fd://
[...]
~$ sudo systemctl daemon-reload #重新加载配置文件.
开启客户端默认证书模式
1 | ~$ mkdir -pv ~/.docker |
Docker
错误
- 如果出现如下的错误,要使用
systemctl restart docker.service
才能解决.1
2docker: Error response from daemon: driver failed programming external connectivity on endpoint condescending_lalande (668389b4f87cc892fc233313eb738d0995c4080d3daabf28bf8c9bbe241a5434): (iptables failed: iptables --wait -t filter -A DOCKER ! -i docker0 -o docker0 -p tcp -d 172.17.0.2 --dport 9000 -j ACCEPT: iptables: No chain/target/match by that name.
(exit status 1)).
Ansible
与Docker
集成使用
操作
VOLUME
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15~$ docker volume create redis_vol
~$ docker volume inspect redis_vol
[
{
"CreatedAt": "2019-01-09T17:28:44+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/redis_vol/_data",
"Name": "redis_vol",
"Options": {},
"Scope": "local"
}
]
# 删除所有的卷
~$ docker volume prune必须安装
docker-py
,下面通过一个稍微复杂一点的例子来说明.1
2
3
4
5
6
7
8
9
10
11
12
13# 如果是python3的话,有些模块会提示要换成安装: pip3 install docker
~$ pip install docker-py
~$ tree
.
├── main.yaml
├── pgsql
│ ├── file
│ │ └── Dockerfile
│ └── pgsql.yaml
└── redis
├── file
│ └── Dockerfile
└── redis.yamlmain.yaml
1
2
3
4
5
6---
- hosts: DB001
become: yes
tasks:
- include: pgsql/pgsql.yaml
- include: redis/redis.yaml
Redis
服务器
Dockerfile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18# 安装redis服务
FROM debian:stretch
# CMD echo "hello debian from Dockerfile."
# https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-redis-on-debian-9
ENV DEBIAN_FRONTEND noninteractive
RUN sed -i "s/deb.debian.org/mirrors.cloud.aliyuncs.com/g" /etc/apt/sources.list
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get -y install redis-server
# RUN sed -i 's/^appendonly no$/appendonly yes/g' /etc/redis/redis.conf
# RUN sed -i 's/^daemonize yes$/daemonize no/g' /etc/redis/redis.conf
EXPOSE 6379/tcp
# CMD [ "/etc/init.d/redis-server start" ]
USER root
RUN rm -rf /data
RUN mkdir /data && chown redis:redis -R /data
VOLUME ["/data" ]
RUN chown redis:redis -R /data
CMD ["redis-server","/etc/redis/redis.conf"]redis.yaml
1 |
|
- 测试 Redis 服务.
1 | ~$ redis-cli |
Postgresql
数据库
比较复杂的实例可以参考docker-postgresql,这个支持
ENTRYPOINT
参数,主从复制功能.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75~$ cat Dockerfile
# 参考这里 https://docs.docker.com/engine/examples/postgresql_service/#install-postgresql-on-docker
FROM debian:stretch
MAINTAINER lcy
ENV DEBIAN_FRONTEND noninteractive
# 添加这一行是为了避免下面的错误:
# -----------------------------------------------
# debconf: unable to initialize frontend: Dialog
# debconf: (Dialog frontend will not work on a dumb terminal, an emacs shell buffer, or without a controlling terminal.)
# debconf: falling back to frontend: Readline
# debconf: unable to initialize frontend: Readline
# debconf: (Can't locate Term/ReadLine.pm in @INC (@INC contains: /etc/perl /usr/local/lib/perl/5.14.2 /usr/local/share/perl/5.14.2 /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.14 /usr/share/perl/5.14 /usr/local/lib/site_perl .) at /usr/share/perl5/Debconf/FrontEnd/Readline.pm line 7, <> line 19.)
# debconf: falling back to frontend: Teletype
# dpkg-preconfigure: unable to re-open stdin:
#------------------------------------------------
# RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections
# Add the PostgreSQL PGP key to verify their Debian packages.
# It should be the same key as https://www.postgresql.org/media/keys/ACCC4CF8.asc
# 这里因为部署在阿里云上,所以把软件仓库改成阿里云,加速下载,且免流量.
RUN sed -i "s/deb.debian.org/mirrors.cloud.aliyuncs.com/g" /etc/apt/sources.list
ENV PG_VERSION=10
ENV PG_USER=postgres
ENV PG_HOME=/var/lib/postgresql
ENV PG_RUNDIR=/run/postgresql \
PG_LOGDIR=/var/log/postgresql \
PG_DATADIR=${PG_HOME}/${PG_VERSION}/main \
PG_BINDIR=/usr/lib/postgresql/${PG_VERSION}/bin \
PG_CONFIG=/etc/postgresql/${PG_VERSION}/main/postgresql.conf
# 下面两个是必需安装才能,才能用apt-key添加公钥
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y apt-utils dirmngr gnupg2
# CMD ["ping","-c","5","p80.pool.sks-keyservers.net"] 这里有可能会运行失败,如:读不到数据,没有解析的域名地址等.
RUN apt-key adv --no-tty --keyserver ipv4.pool.sks-keyservers.net --recv-keys B97B0AFCAA1A47F044F244A07FCC7D46ACCC4CF8
# Add PostgreSQL's repository. It contains the most recent stable release
# of PostgreSQL, ``10``.
RUN echo "deb http://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main" > /etc/apt/sources.list.d/pgdg.list
# Install ``python-software-properties``, ``software-properties-common`` and PostgreSQL 10.6
# There are some warnings (in red) that show up during the build. You can hide
# them by prefixing each apt-get statement with DEBIAN_FRONTEND=noninteractive
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y software-properties-common postgresql-10 postgresql-client-10 postgresql-contrib-10
# 这里要注意文件路径的rwx权限问题.
USER root
RUN mkdir -p ${PG_DATADIR} && chown -R postgres:postgres ${PG_DATADIR}
RUN mkdir -p ${PG_LOGDIR} && chown -R postgres:postgres ${PG_LOGDIR}
# Adjust PostgreSQL configuration so that remote connections to the
# database are possible.
USER postgres
RUN echo "host all all 0.0.0.0/0 md5" >> /etc/postgresql/10/main/pg_hba.conf
# And add ``listen_addresses`` to ``/etc/postgresql/10.6/main/postgresql.conf``
RUN echo "listen_addresses='*'" >> /etc/postgresql/10/main/postgresql.conf
# Create a PostgreSQL role named ``docker`` with ``docker`` as the password and
# then create a database `docker` owned by the ``docker`` role.
# Note: here we use ``&&\`` to run commands one after the other - the ``\``
# allows the RUN command to span multiple lines.
RUN /etc/init.d/postgresql start && psql --command "CREATE USER docker WITH SUPERUSER PASSWORD 'docker';" && createdb -O docker docker
# Expose the PostgreSQL port
EXPOSE 5432/tcp
# Add VOLUMEs to allow backup of config, logs and databases
VOLUME ["/etc/postgresql", "/var/log/postgresql", "/var/lib/postgresql/10/main"]
# RUN ${PG_BINDIR}/initdb -D ${PG_DATADIR}
# Set the default command to run when starting the container
# 这里如果是9.6版本那就要写成/usr/lib/postgresql/9.6/bin/postgres.好像10.6就直接如下面写就可以了.
CMD ["/usr/lib/postgresql/10/bin/postgres", "-D", "/var/lib/postgresql/10/main", "-c", "config_file=/etc/postgresql/10/main/postgresql.conf"]pgsql.yaml
1 |
|
Jenkins
安装
谢谢支持
- 微信二维码: