{
“events”: [
{
“title”: “All Day DevOps 2018”,
“desc”: “We’re back with 100, 30-minute practitioner-led sessions and live Q&A on Slack. Our 5 tracks include CI/CD, Cloud-Native Infrastructure, DevSecOps, Cultural Transformations, and Site Reliability Engineering. 24 hours. 112 speakers. Free online.”,
“date”: “17 octobre 2018, online event”,
“ts”: “20181017T000000”,
“link”: “https://www.alldaydevops.com/",
“sponsors”: [{“name”: “all-day-devops”}]
},
{
“title”: “Création d’une Blockchain d’entreprise (lab) & introduction aux smart contracts”,
“desc”: “Venez avec votre laptop ! Nous vous proposons de nous rejoindre pour réaliser la création d’un premier prototype d’une Blockchain d’entreprise (Lab) et avoir une introduction aux smart contracts.”,
“ts”: “20181004T181500”,
“date”: “4 octobre à 18h15 au CEEI”,
“link”: “https://www.meetup.com/fr-FR/IBM-Cloud-Cote-d-Azur-Meetup/events/254472667/",
“sponsors”: [{“name”: “ibm”}]
},
…
]
}
网站素材的生成
包含网站素材的最终镜像的创建
# 生成素材
FROM node:8.12.0-alpine AS build
COPY . /build
WORKDIR /build
RUN npm i
RUN node clean.js
RUN ./node_modules/mustache/bin/mustache events.json index.mustache > index.html
# 构建托管它们的最终镜像
FROM nginx:1.14.0
COPY --from=build /build/*.html /usr/share/nginx/html/
COPY events.json /usr/share/nginx/html/
COPY css /usr/share/nginx/html/css
COPY js /usr/share/nginx/html/js
COPY img /usr/share/nginx/html/img
$ git clone git@gitlab.com:lucj/sophia.events.git
$ cd sophia.events
$ ./test.sh
Sending build context to Docker daemon 2.588MB
Step 1/12 : FROM node:8.12.0-alpine AS build
---> df48b68da02a
Step 2/12 : COPY . /build
---> f4005274aadf
Step 3/12 : WORKDIR /build
---> Running in 5222c3b6cf12
Removing intermediate container 5222c3b6cf12
---> 81947306e4af
Step 4/12 : RUN npm i
---> Running in de4e6182036b
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN www@1.0.0 No repository field.
added 2 packages from 3 contributors and audited 2 packages in 1.675s
found 0 vulnerabilities
Removing intermediate container de4e6182036b
---> d0eb4627e01f
Step 5/12 : RUN node clean.js
---> Running in f4d3c4745901
Removing intermediate container f4d3c4745901
---> 602987ce7162
Step 6/12 : RUN ./node_modules/mustache/bin/mustache events.json index.mustache > index.html
---> Running in 05b5ebd73b89
Removing intermediate container 05b5ebd73b89
---> d982ff9cc61c
Step 7/12 : FROM nginx:1.14.0
---> 86898218889a
Step 8/12 : COPY --from=build /build/*.html /usr/share/nginx/html/
---> Using cache
---> e0c25127223f
Step 9/12 : COPY events.json /usr/share/nginx/html/
---> Using cache
---> 64e8a1c5e79d
Step 10/12 : COPY css /usr/share/nginx/html/css
---> Using cache
---> e524c31b64c2
Step 11/12 : COPY js /usr/share/nginx/html/js
---> Using cache
---> 1ef9dece9bb4
Step 12/12 : COPY img /usr/share/nginx/html/img
---> e50bf7836d2f
Successfully built e50bf7836d2f
Successfully tagged registry.gitlab.com/lucj/sophia.events:latest
=> web site available on http://localhost:32768
version: "3.7"
services:
www:
image: registry.gitlab.com/lucj/sophia.events
networks:
- proxy
deploy:
mode: replicated
replicas: 2
update_config:
parallelism: 1
delay: 10s
restart_policy:
condition: on-failure
networks:
proxy:
external: true
镜像存储在托管到gitlab.com的私有镜像仓库(这里没涉及到Docker Hub)。
服务是以2个副本的形式运行在副本模式下,这也就意味着同一时间该服务会有两个正在运行中的任务/容器。Swarm的service会关联一个VIP(虚拟IP地址),这样一来目标是该服务的每个请求会在两个副本之间实现负载均衡。
每次完成服务更新时(部署一个新版本的网站),其中一个副本会被更新,然后在10秒后更新第二个副本。这可以确保在更新期间整个网站仍然可用。我们也可以使用回滚策略,但是在这里没有必要。
服务会被绑定到一个外部的代理网络,这样一来TLS termination(在Swarm里部署的,跑在另外一个服务里,但是超出本项目的范畴)可以发送请求给www服务。
$ docker stack deploy -c sophia.yml sophia_events
Portainer自己
包含了跑着我们网站的服务的sophia_events
tls,TLS termination服务
ssh -i ~/.docker/machine/machines/labs/id_rsa -NL 8888:localhost:9000 $USER@$HOST
CONFIG_FOLDER=/tmp/gitlab-runner-config
docker run — rm -t -i \
-v $CONFIG_FOLDER:/etc/gitlab-runner \
gitlab/gitlab-runner register \
--non-interactive \
--executor "docker" \
—-docker-image docker:stable \
--url "https://gitlab.com/" \
—-registration-token "$PROJECT_TOKEN" \
—-description "Exoscale Docker Runner" \
--tag-list "docker" \
--run-untagged \
—-locked="false" \
--docker-privileged
CONFIG_FOLDER=/tmp/gitlab-runner-config
docker run -d \
--name gitlab-runner \
—-restart always \
-v $CONFIG_FOLDER:/etc/gitlab-runner \
-v /var/run/docker.sock:/var/run/docker.sock \
gitlab/gitlab-runner:latest
variables:
CONTAINER_IMAGE: registry.gitlab.com/$CI_PROJECT_PATH
DOCKER_HOST: tcp://docker:2375
stages:
- test
- build
- deploy
test:
stage: test
image: node:8.12.0-alpine
script:
- npm i
- npm test
build:
stage: build
image: docker:stable
services:
- docker:dind
script:
- docker image build -t $CONTAINER_IMAGE:$CI_BUILD_REF -t $CONTAINER_IMAGE:latest .
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN registry.gitlab.com
- docker image push $CONTAINER_IMAGE:latest
- docker image push $CONTAINER_IMAGE:$CI_BUILD_REF
only:
- master
deploy:
stage: deploy
image: alpine
script:
- apk add --update curl
- curl -XPOST $WWW_WEBHOOK
only:
- master
测试阶段(test stage)将会运行一些预备检查,确保events.json文件格式正确,并且这里没有遗漏镜像
构建阶段(build stage)会做镜像的构建并将它推送到GitLab上的镜像仓库
部署阶段(deploy stage)将会通过发送给Portainer的一个webhook触发一次服务的更新。WWW_WEBHOOK变量的定义可以在Gitlab.com上项目页面的CI/CD设置里找到。
runner在Swarm上是以一个容器的形式运行。我们可以使用一个共享的runner,这是一些公用的runner,它们会在托管到GitLab的不同项目所需的任务之间分配时间。但是,由于runner需要访问Portainer的端点(用来发送webhook),也因为笔者不希望Portainer能够从外界访问到,将runner跑在集群里会更安全一些。
再者,由于runner跑在一个容器里,为了能够通过Portainer暴露在宿主机上的9000端口连到Portainer,它会将webhook请求发送到Docker0桥接网络上的IP地址。也因此,webhook将遵循如下格式:http://172.17.0.1:9000/api[…]a7-4af2-a95b-b748d92f1b3b。
一个开发者推送了一些变更到GitLab。这些变更基本上囊括了events.json文件里一个或多个新的事件加上一些额外赞助商的logo。
Gitlab runner执行在.gitlab-ci.yml里定义好的一组action。
Gitlab runner调用在Portainer中定义的webhook。
在接收到webhook后,Portainer将会部署新版本的www服务。它通过调用Docker Swarm的API实现这一点。Portainer可以通过在启动时绑定挂载的/var/run/docker.sock套接字来访问该API。
如果你想知道更多此unix套接字用法的相关信息,也许你会对之前这篇文章《Docker Tips : about /var/run/docker.sock[5]》感兴趣。
随后,用户便能看到新版本的站点。
$ git commit -m 'Fix image'
$ git push origin master
https://gitlab.com/lucj/sophia.events
https://gitlab.com/lucj/sophia.events/blob/master/index.mustache
http://exoscale.ch/
https://portainer.io/
https://medium.com/lucjuggery/about-var-run-docker-sock-3bfd276e12fd