本文主要介绍了Docker在Ubuntu上的主要应用,并详细的阐述了实现步骤、遇到的问题及问题的解决方案。新手可以先了解一下它们,老鸟可以直接跳过下面的若干步骤,废话不多说,开始吧~
我们要做什么
明确目标很关键,我们的主要目标就是基于Docker来完成以下工作
建立私有的gitlab
建立私有的docker registry
通过gitlab-ci来自动化build,test,push,deploy我们的项目
利用集群部署我们的服务
环境参数
系统软件:
文档说明
名词解释:
主机 : 安装ubuntu的机器,可以是物理机也可以是虚拟机
主机ip :
主机
的ip,可通过ifconfig
命令获取其他主机 : 安装有Docker的其他
主机
docker0 : Docker服务默认创建的网桥名
<username> : 你的用户名,我这里使用自己的用户名devlee
工作目录 :
主机
上进行本文描述的相关工作的工作目录我的项目 : 我把这篇文章中涉及的代码总结于此项目
相关说明:
大多数命令需要root权限,可以通过以下命令来解决每次都需要sudo的步骤
12 > $ sudo -i>工作目录:
- /work/<username>
我的项目:
准备工作
创建好
工作目录
1$ sudo mkdir /work/devleeTip: 准备工作到第一步就可以了,因为后续步骤会创建若干目录及文件,如果你想偷懒,不愿意一步一步创建这些目录及文件,可以继续准备工作的后续几步。
进入
工作目录
并拉取我的项目
,该项目中拥有一些我们下面操作中需要的文件1$ sudo cd /work/devlee && git clone https://github.com/devlee/docker-aio.git将项目中src中的所有文件夹拷贝至
工作目录
下1$ sudo cp -r /work/devlee/docker-aio/src /work/devlee此时查看
工作目录
,应该拥有gitlab
,registry
,machine
等文件夹
更新APT资源列表
在
主机
上使用root
权限或sudo
命令来执行以下命令打开一个
terminal
更新包信息,确保
APT
使用https
方式工作且安装了CA
证书1$ sudo apt-get update1$ sudo apt-get install apt-transport-https ca-certificates添加新的
GPG
key1$ sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D使用你最喜欢的编辑器来打开以下文件,不存在则创建它
/etc/apt/sources.list.d/docker.list
清空所有已经存在的
entry
,并添加一条新的entry
deb https://apt.dockerproject.org/repo ubuntu-xenial main
保存并关闭该文件
Tip:
5
,6
和7
这三个步骤可以通过以下命令实现1sh -c "echo deb https://apt.dockerproject.org/repo ubuntu-xenial main > /etc/apt/sources.list.d/docker.list"更新
APT
包索引1$ sudo apt-get update如果存在则先卸载旧有版本
1$ sudo apt-get purge lxc-docker验证
APT
从正确的仓库中拉取1$ sudo apt-cache policy docker-engine执行以下命令,获取软件最新版本
1$ sudo apt-get upgradeTip:
upgrade
命令会更新所有软件包
ubuntu安装docker之前的准备
在
主机
上打开一个terminal
更新包管理器
1$ sudo apt-get update安装推荐的包
1$ sudo apt-get install linux-image-extra-$(uname -r)
安装docker
在
主机
上使用sudo
更新
APT
包索引1$ sudo apt-get update安装
docker
1$ sudo apt-get install docker-engine启动
docker
daemon1$ sudo service docker start验证
docker
安装正确1$ sudo docker run hello-worldTip: 这个命令会下载一个测试镜像并在容器中运行它,当容器运行时,它会在控制台打印出一条消息,随后便会结束退出。
安装docker compose
打开以下链接
在页面中找到这样的命令并运行
1curl -L https://github.com/docker/compose/releases/download/1.8.0-rc2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose1chmod +x /usr/local/bin/docker-compose
安装docker machine
打开以下链接
在页面中找到这样的命令并运行
1curl -L https://github.com/docker/machine/releases/download/v0.8.0-rc2/docker-machine-`uname -s`-`uname -m` >/usr/local/bin/docker-machine1chmod +x /usr/local/bin/docker-machine
校验一下版本信息
执行以下命令
1docker version得到
docker
的版本信息,包括客户端
和服务端
1234567891011121314Client:Version: 1.12.0API version: 1.24Go version: go1.6.3Git commit: 8eab29eBuilt: Thu Jul 28 22:11:10 2016OS/Arch: linux/amd64Server:Version: 1.12.0API version: 1.24Go version: go1.6.3Git commit: 8eab29eBuilt: Thu Jul 28 22:11:10 2016OS/Arch: linux/amd64执行以下命令
1docker-compose version得到
docker compose
当前版本信息,包括py
,ssl
等信息1234docker-compose version 1.8.0-rc2, build c72c966docker-py version: 1.9.0-rc2CPython version: 2.7.9OpenSSL version: OpenSSL 1.0.1e 11 Feb 2013执行以下命令
1docker-machine version得到
docker machine
当前版本信息1docker-machine version 0.8.0-rc2, build 4ca1b85
搭建私有的gitlab
进入
工作目录
,创建文件夹gitlab
,并进入该目录1$ sudo cd /work/devlee && mkdir gitlab && cd gitlab创建docker-compose.yml,并将以下链接中的代码拷贝至该文件中
https://raw.githubusercontent.com/sameersbn/docker-gitlab/master/docker-compose.yml
Tip: 与我的项目中的文件内容有些许差异,主要是镜像版本号和容器container_name
的定义执行以下命令
1$ sudo docker-compose up -d搭建完成,访问以下地址进行初始化并重置
root
密码
搭建私有的docker registry
Tip:
这里的
registry
版本为v2
,隶属于docker distribution
项目,项目地址为:https://github.com/docker/distribution我们同时会利用
nginx
来实现https
仓库我们会使用
docker-registry-frontend
来作为web前端展示
进入
工作目录
,创建文件夹registry
,并进入该目录1$ sudo cd /work/devlee && mkdir registry && cd registry创建docker-compose.yml文件,并写入以下代码
12345678910111213141516171819202122232425262728293031323334version: '2'services:nginx:restart: alwaysimage: 'nginx:latest'ports:- 443:443links:- registry:registryvolumes:- ./nginx/:/etc/nginx/conf.dcontainer_name: 'docker-registry-proxy'registry:restart: alwaysimage: 'registry:2.4.1'ports:- 5000:5000environment:- REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY=/datavolumes:- ./data:/datacontainer_name: 'docker-registry'frontend:restart: alwaysimage: 'konradkleine/docker-registry-frontend:v2'ports:- 8080:80environment:- ENV_DOCKER_REGISTRY_HOST=nginx- ENV_DOCKER_REGISTRY_PORT=443- ENV_DOCKER_REGISTRY_USE_SSL=1links:- nginx:nginxcontainer_name: 'docker-registry-frontend'创建文件夹data和nginx,并进入nginx文件夹
1$ sudo mkdir data && mkdir nginx && cd nginx创建registry.conf文件,并写入以下代码
123456789101112131415161718192021222324252627282930313233343536373839upstream docker-hub {server registry:5000;}server {listen 443;server_name localhost;# SSLssl on;ssl_certificate /etc/nginx/conf.d/docker-registry.crt;ssl_certificate_key /etc/nginx/conf.d/docker-registry.key;# disable any limits to avoid HTTP 413 for large image uploadsclient_max_body_size 0;# required to avoid HTTP 411: see Issue #1486 (https://github.com/docker/docker/issues/1486)chunked_transfer_encoding on;location /v2/ {# Do not allow connections from docker 1.5 and earlier# docker pre-1.6.0 did not properly set the user agent on ping, catch "Go *" user agentsif ($http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*$" ) {return 404;}# To add basic authentication to v2 use auth_basic setting plus add_headerauth_basic "registry.localhost";auth_basic_user_file /etc/nginx/conf.d/docker-registry.htpasswd;add_header 'Docker-Distribution-Api-Version' 'registry/2.4.1' always;proxy_pass http://docker-hub;proxy_set_header Host $http_host; # required for docker client's sakeproxy_set_header X-Real-IP $remote_addr; # pass on real client's IPproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;proxy_read_timeout 900;}}生成
ssl
证书1$ sudo openssl req -x509 -nodes -newkey rsa:2048 -keyout /work/devlee/registry/nginx/docker-registry.key -out /work/devlee/registry/nginx/docker-registry.crtTip: 生成证书的时候需要格外注意,所有选型除了
CN
都可以选择默认,这个选项需要输入仓库的域名,由于我们是本地内网所以输入docker-registry
,记得要在其他主机的/etc/hosts
中添加解析,通过ifconfig
命令可以查看主机
的ip
安装
htpasswd
1$ sudo apt-get install apache2-utils创建用户名密码,这里用户名是
devlee
,第一个用户需要添加-c
参数1$ sudo htpasswd -c /work/devlee/registry/nginx/docker-registry.htpasswd devlee启动服务
1$ sudo cd /work/devlee/registry && docker-compose up -d搭建完成,访问以下地址进行验证,登录后会返回
{}
1https://localhost:443/v2Tip: 目前所搭建的仓库是在主机上进行访问的,可以直接通过
localhost
访问,要在其他主机
上访问仓库,需要其他主机
配置有证书/work/devlee/registry/nginx/docker-registry.crt
,且需要设置/etc/hosts
(别名访问),通过域名或别名进行访问,https://docker-registry:443/v2
在
其他主机
上配置证书 (内网配置,如果仓库在外网,不用配置hosts)
a. 配置/etc/hosts
,假设主机ip
为10.12.30.52
,写入10.12.30.52 docker-registry
b. 启动Docker服务
1$ sudo service docker startc. 创建扩展证书存放目录
1$ sudo mkdir /usr/share/ca-certificates/extrad. 拷贝
主机
中的docker-registry.crt
文件至上述目录e. 注册证书
1$ sudo dpkg-reconfigure ca-certificates在
其他主机
上配置证书(方法2)
a. 配置/etc/hosts
,假设主机ip
为10.12.30.52
,写入10.12.30.52 docker-registry
b. 创建目录
1$ sudo cd /etc/docker && mkdir cert.d && cd cert.d && mkdir docker-registry:443c. 拷贝
主机
中的docker-registry.crt
文件至上述最后一个创建的目录d. 重启Docker服务
1$ sudo service docker restart推送测试
12$ sudo docker tag hello-world docker-registry:443/hello$ sudo docker push docker-registry:443/hello
搭建gitlab-runner
向
/work/devlee/gitlab/docker-compose.yml
添加以下代码runner-docker-in-docker:
restart: always image: sameersbn/gitlab-ci-multi-runner:latest depends_on: - gitlab volumes: - /srv/docker/gitlab-runner/docker-in-docker:/home/gitlab_ci_multi_runner/data links: - gitlab:gitlab environment: - CI_SERVER_URL=http://<gitlab-ip>:10080/ci - RUNNER_TOKEN=<gitlab-token> - RUNNER_DESCRIPTION=docker-in-docker-runner - RUNNER_EXECUTOR=docker - DOCKER_IMAGE=docker:latest - DOCKER_PRIVILEGED=true - DOCKER_EXTRA_HOSTS=localhost:<registry-ip> container_name: gitlab-runner-docker-in-docker runner-docker-socket-binding: restart: always image: sameersbn/gitlab-ci-multi-runner:latest depends_on: - gitlab volumes: - /srv/docker/gitlab-runner/docker-socket-binding:/home/gitlab_ci_multi_runner/data - /var/run/docker.sock:/var/run/docker.sock - /git/devlee/registry/nginx/volumes:/etc/docker/cert.d links: - gitlab:gitlab environment: - CI_SERVER_URL=http://<gitlab-ip>:10080/ci - RUNNER_TOKEN=<gitlab-token> - RUNNER_DESCRIPTION=docker-socket-binding-runner - RUNNER_EXECUTOR=docker - DOCKER_IMAGE=docker:latest - DOCKER_EXTRA_HOSTS=localhost:<registry-ip> - DOCKER_VOLUMES=/git/devlee/registry/nginx/volumes:/etc/docker/cert.d container_name: gitlab-runner-docker-socket-binding extra_hosts: - "localhost:172.17.0.1" - "docker-registry:172.17.0.1" runner-shell: restart: always image: sameersbn/gitlab-ci-multi-runner:latest depends_on: - gitlab volumes: - /srv/docker/gitlab-runner/shell:/home/gitlab_ci_multi_runner/data links: - gitlab:gitlab environment: - CI_SERVER_URL=http://<gitlab-ip>:10080/ci - RUNNER_TOKEN=<gitlab-token> - RUNNER_DESCRIPTION=shell-runner - RUNNER_EXECUTOR=shell container_name: gitlab-runner-shell
Tip:
<gitlab-ip>: 私有的gitlab服务ip,由于我们是搭建在容器里的,所以这里取主机
的docker0
的ip
<gitlab-token>: 这里的token可以填gitlab上某个项目的special token
,也可以是shared token
,我这里用的是shared token
,使用admin
账户登录gitlab,访问loalhost:10080/admin/runners
就可以看到token
<registry-ip>: 私有的registry服务ip,由于我们是搭建在容器里的,所以这里取主机
的docker0
的ip
启动服务
$ sudo cd /work/devlee/gitlab && docker-compose up -d
打开gitlab,使用admin账户登录,在runners页面中给这三个runner添加tag,分别为
docker
,sock
,shell
新建项目koa-app于私有的gitlab
用
admin
账户在gitlab
上新建一个koa-app
项目进入
工作目录
,创建文件夹dev
,并进入该目录拷贝我们的项目至本地
1$ sudo git clone http://localhost:10080/root/koa-app.git进入我们的项目目录
1$ sudo cd koa-app安装
npm
1234$ sudo apt-get install python-software-properties$ sudo add-apt-repository ppa:gias-kay-lee/npm$ sudo apt-get update$ sudo apt-get install npm创建
package.json
1$ sudo npm init安装
koa2
1$ sudo npm install koa@2 --save创建
index.js
,代码如下const Koa = require(‘koa’)
const app = new Koa
app.use(ctx => {
ctx.body = 'Hello, Docker'
})
app.listen(3232)
创建
.dockerignore
,内容如下.git
.gitlab-ci.yml
README.md
创建
.gitignore
,内容如下node_modules
创建
.gitlab-ci.yml
,内容如下image: docker:latest
before_script:
- docker version build:image stage: build script: - docker login -u devlee -p xxxx localhost:443 - docker build -t localhost:443/devlee/koa-app:latest . - docker push localhost:443/devlee/koa-app:latest tags: - sock
Tip: xxxx是创建用户
devlee
时输入的密码创建
Dockerfile
,内容如下FROM localhost:443/devlee/node:latest
COPY . /devlee/ WORKDIR /devlee/ RUN npm install CMD ["node", "index"] EXPOSE 3232
提交代码到gitlab
$ sudo git add –all
$ sudo git commit -m "xxxx" $ sudo git fetch $ sudo git rebase $ sudo git push
Tip: xxxx是提交的修改注释
由于提交的代码中包含了.gitlab-ci.yml文件,会自动触发ci相关任务。
集群部署服务koa-app
我们利用虚拟机当集群节点,所以需要安装
virtualbox
$ sudo sh -c “echo deb http://download.virtualbox.org/virtualbox/debian xenial contrib > /etc/apt/sources.list”
$ sudo wget -q https://www.virtualbox.org/download/oracle_vbox_2016.asc -O- | sudo apt-key add - $ sudo wget -q https://www.virtualbox.org/download/oracle_vbox.asc -O- | sudo apt-key add - $ sudo apt-get update $ sudo apt-get install virtualbox-5.1
创建三台虚拟机
manager1
worker1
worker2
$ sudo docker-machine create -d virtualbox manager1
$ sudo docker-machine create -d virtualbox worker1 $ sudo docker-machine create -d virtualbox worker2
创建swarm及manager
$ sudo docker-machine ssh manager1
$ sudo docker swarm init --advertise-addr <MANAGER-IP>
创建worker1和worker2,分别ssh到worker1及worker2执行以下命令,该命令在上条命令执行后会展示
$ sudo docker swarm join –token
:2377 登录虚拟机manager1(worker1/2,三个节点都执行一遍6-11操作)
$ sudo docker-machine ssh manager1
$ sudo docker-machine ssh worker1 $ sudo docker-machine ssh worker2
在
/etc/hosts
文件中加入registry
的解析192.168.99.1 docker-registry
Tip:
192.168.99.1
是registry
所在主机
的vboxnet0
的ip,也就是主机相对于虚拟机能访问到的ip地址创建
/etc/docker/certs.d/docker-registry:443/docker-registry.crt
文件,写入和之前搭建私有的gitlab中的crt文件内容即可重启docker服务
$ sudo /etc/init.d/docker stop
$ sudo /etc/init.d/docker start
测试登录registry
$ sudo docker login docker-registry:443
查询registry中的image信息
$ curl –cacert /etc/docker/certs.d/docker-registry:443/docker-registry.crt –basic –user devlee:
https://docker-registry:443/v2/_catalog Tip:
<password>是创建用户devlee时输入的密码,以上命令执行后,应该可以看到我们的koa-app{"repositories":["devlee/koa-app"]}
拉取koa-app的镜像
$ sudo docker pull docker-registry:443/devlee/koa-app:latest
回到
主机
登录集群管理节点创建一个服务$ sudo docker-machine ssh manager1
$ sudo docker service create --replicas 1 --name koa-app docker-registry:443/devlee/koa-app:latest
查看服务
$ sudo docker service ls
$ sudo docker service inspect --pretty koa-app $ sudo docker service ps koa-app
扩展服务
$ sudo docker service scale koa-app=3
集群部署服务koa-app(方法2)
我们利用虚拟机当集群节点,所以需要安装
virtualbox
$ sudo sh -c “echo deb http://download.virtualbox.org/virtualbox/debian xenial contrib > /etc/apt/sources.list”
$ sudo wget -q https://www.virtualbox.org/download/oracle_vbox_2016.asc -O- | sudo apt-key add - $ sudo wget -q https://www.virtualbox.org/download/oracle_vbox.asc -O- | sudo apt-key add - $ sudo apt-get update $ sudo apt-get install virtualbox-5.1
创建一台虚拟机用作kv store服务器
$ sudo docker-machine create -d virtualbox consul-kv-store
登录kv store服务器环境,并启动服务
$ sudo eval $(docker-machine env consul-kv-store)
$ sudo docker run -d --name=consul --restart=always -p "8500:8500" -h "consul" progrium/consul -server -bootstrap
创建swarm-master
$ sudo docker-machine create \
-d virtualbox \ --swarm --swarm-master \ --swarm-discovery="consul://$(docker-machine ip consul-kv-store):8500" \ --engine-opt="cluster-store=consul://$(docker-machine ip consul-kv-store):8500" \ --engine-opt="cluster-advertise=eth1:2376" \ swarm-master
创建swarm-node-01
$ sudo docker-machine create \
-d virtualbox \ --swarm --swarm-discovery="consul://$(docker-machine ip consul-kv-store):8500" \ --engine-opt="cluster-store=consul://$(docker-machine ip consul-kv-store):8500" \ --engine-opt="cluster-advertise=eth1:2376" \ swarm-node-01
创建swarm-node-02
$ sudo docker-machine create \
-d virtualbox \ --swarm --swarm-discovery="consul://$(docker-machine ip consul-kv-store):8500" \ --engine-opt="cluster-store=consul://$(docker-machine ip consul-kv-store):8500" \ --engine-opt="cluster-advertise=eth1:2376" \ swarm-node-02
登录虚拟机swarm-master(node-01/02),三个节点都执行一遍8-10操作)
$ sudo docker-machine ssh swarm-master
$ sudo docker-machine ssh swarm-node-01 $ sudo docker-machine ssh swarm-node-02
在
/etc/hosts
文件中加入registry
的解析192.168.99.1 docker-registry
Tip:
192.168.99.1
是registry
所在主机
的vboxnet0
的ip,也就是主机相对于虚拟机能访问到的ip地址创建
/etc/docker/certs.d/docker-registry:443/docker-registry.crt
文件,写入和之前搭建私有的gitlab中的crt文件内容即可重启docker服务
$ sudo /etc/init.d/docker stop
$ sudo /etc/init.d/docker start
登录swarm-master管理节点创建overlay网络devlee-net
$ sudo eval $(docker-machine env –swarm swarm-master)
docker network create --driver overlay --subnet=10.0.9.0/24 devlee-net
登录docker-registry并拉取koa-app
$ sudo docker login docker-registry:443
$ docker pull docker-registry:443/devlee/koa-app:latest
在/work/devlee/machine目录下新建docker-compose.yml
version: ‘2’
services: koa-app: image: docker-registry:443/devlee/koa-app:latest ports: - '13232:3232'
启动koa-app
$ sudo docker-compose up -d
此时通过docker ps命令可以发现集群中的某一台机器运行了koa-app
扩展服务至集群所有机器(可能会有错误,因为该服务占用了特定的端口)
$ sudo docker-compose scale koa-app=3
集群多台主机之间的容器通信的方法
集群部署服务koa-app
通过scope为swarm的overlay类型网络ingress
ingress overlay swarm
集群部署服务koa-app(方法2)
通过scope为global的overlay类型网络devlee-net
devlee-net overlay global
Example
在主机1和主机2的容器1和容器2中部署应用1和应用2,此时应用1和应用2可以相互访问各自内容,网络名即上面的ingress或devlee-net
docker run -itd –name=容器1 –network=网络名 –env=”constraint:node==机器1” 应用1
docker run -itd --name=容器2 --network=网络名 --env="constraint:node==机器2" 应用2
参考文章
- 使用Docker构建持续集成与自动部署的Docker集群
- Demo of the Machine + Swarm + Compose integration
- Get started with multi-host networking
- 理解Docker跨多主机容器网络
- Swarm and container networks
- 搭建docker内网私服(docker-registry with nginx&ssl on centos)
- 利用nginx及Registry2.0搭建Docker安全私有仓库
- 基于 ubuntu 搭建 docker registry
- 搭建Docker私有仓库Registry-v2
- Docker Machine快速安装Docker环境(二)
- 用Git子模块和Docker Compose实现高效开发工作流
- Docker Compose—简化复杂应用的利器
- 从0到1:搭建基于Travis CI和GitHub的自动化测试工作流
- 使用docker实现半自动化代码自动部署
- 基于docker+gitlabCI搭建私有集成环境
- 使用Gitlab CI & Docker搭建CI环境
- 尝试持续集成–第一版
- Gitlab CI Runner的创建和配置
- 使用 Docker 建置 Gitlab CE 的 Source Control 及 CI 環境
- 如何在 Docker 容器之间设置网络
- Installation On Ubuntu