Terraform 100: Introduction & Install

What is Terraform?

Terraform is a tool for building, changing, and versioning infrastructure safely and efficiently. Terraform can manage existing and popular service providers as well as custom in-house solutions.

The key features of Terraform are:

  • Infrastructure as Code
  • Execution Plans
  • Resource Graph
  • Change Automation

tfenv

tfenv: Terraform version manager

tfenv github

  • install tfenv

    Install via Homebrew
    $ brew install tfenv

  • usage
    1
    2
    $ tfenv install 0.7.0
    $ tfenv install latest
1
2
3
# use a specific version
$ tfenv use 0.7.0
$ tfenv use latest
1
2
3
#uninstall
$ tfenv uninstall 0.7.0
$ tfenv uninstall latest
.terraform-version

If you put .terraform-version file on your project root, or in your home directory, tfenv detects it and use the version written in it.

I have installed two different version on my mac.

Ihen I set version to v0.12.4 in .terraform-version file

1
2
3
4
5
➜   terraform --version
Terraform v0.12.4
+ provider.aws v2.25.0
+ provider.random v2.2.0
+ provider.template v2.1.2

Then I change the verson to v0.12.5 in .terraform-version file

1
2
3
4
5
6
7
8
➜   terraform --version
Terraform v0.12.5
+ provider.aws v2.25.0
+ provider.random v2.2.0
+ provider.template v2.1.2

Your version of Terraform is out of date! The latest version
is 0.12.7. You can update by downloading from www.terraform.io/downloads.html

PPT Tools

TL;DR
一个好的PPT,全靠自己一块一块地“搬砖”当然可以制作的很精良,但时间也就流逝了许多,介绍一些可能用到的工具,简化这些制作的步骤。

Icons made by Smashicons、iconixar、Vitaly Gorbachev、Vectors Market from www.flaticon.com

http://smallpdf.com/cn

用markdown写ppt,并展示的工具

docker build ignore .dockerignore

Demo project:
https://github.com/qinrui777/api-test-demo

please run command to get a jar : ./gradlew -x jar build

  • before (加.dockerignore 之前)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    ➜  api-test-demo git:(master) ✗ docker  build -t api-demo:no-ignore .
    Sending build context to Docker daemon 109.7MB
    Step 1/3 : FROM openjdk:8-jdk-alpine
    ---> 97bc1352afde
    Step 2/3 : ADD build/libs/api-demo-0.0.1-SNAPSHOT.jar /app.jar
    ---> 7f709f7b4381
    Step 3/3 : ENTRYPOINT ["java","-jar","/app.jar"]
    ---> Running in e43285b4802f
    Removing intermediate container e43285b4802f
    ---> 62d9f7b72b38
    Successfully built 62d9f7b72b38
    Successfully tagged api-demo:no-ignore
  • add .dockerignore

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    ➜  api-test-demo git:(master) ✗ cat .dockerignore
    .git
    .DS_Store
    .gitignore
    README.md
    Jenkinsfile
    Dockerfile
    /images/*
    /src/*
    /jenkins/*
  • after (加.dockerignore 之后)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    ➜  api-test-demo git:(master) ✗ docker  build -t api-demo:have-ignore .
    Sending build context to Docker daemon 17.33MB
    Step 1/3 : FROM openjdk:8-jdk-alpine
    ---> 97bc1352afde
    Step 2/3 : ADD build/libs/api-demo-0.0.1-SNAPSHOT.jar /app.jar
    ---> Using cache
    ---> 7f709f7b4381
    Step 3/3 : ENTRYPOINT ["java","-jar","/app.jar"]
    ---> Using cache
    ---> 62d9f7b72b38
    Successfully built 62d9f7b72b38
    Successfully tagged api-demo:have-ignore

highlight code on slide/ppt

only for mac

问题
写ppt的时候代码如何呈现,能够看起来比较明显,更好是根据不同语言高亮

解决方案
highlight

  1. Install
    brew install highlight

  2. Use
    hightlight -l -O rtf your_code.sh | pbcopy

  • hightlight –help 可以查看文档,
  • -l 显示行号,-O rtf为格式化输出 rtf 格式文本
  • pbcopy 是内置剪贴板

到PPT里粘贴就行了,Keynote 和 PowerPoint 都可以使用.
example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
➜  ~ cat output.sh
docker exec -it -u root tw-jenkins bash

chmod 777 /var/run/docker.sock
apt-get update && \
apt-get -y install apt-transport-https \
ca-certificates \
curl \
gnupg2 \
software-properties-common && \
curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg > /tmp/dkey; apt-key add /tmp/dkey && \
add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") \
$(lsb_release -cs) \
stable" && \
apt-get update && \
apt-get -y install docker-ce

➜ ~ highlight -l -O rtf output.sh | pbcopy

highlight_demo01.png

python module SimpleHTTPServer

what is

The SimpleHTTPServer module can be used in the following manner in order to set up a very basic web server serving files relative to the current directory.

Warning SimpleHTTPServer is not recommended for production. It only implements basic security checks.

Example 1: fetch files from a server

    1. Start SimpleHTTPServer on server node
      1
      2
      3
      cd   your_file_dir
      python -m SimpleHTTPServer <PORT>
      ...
    1. Excute command on client node
      wget <SERVER_NODE_IP>:<PROT>/relative path/test.sh

or go to the browser and type this URL: http://<SERVER_NODE_IP>:<PROT> and see the output.

✍TIP
The SimpleHTTPServer module has been merged into http.server in Python 3.0. The 2to3 tool will automatically adapt imports when converting your sources to 3.0.
python3 -m http.server

Docker Configuration

Distribution Configuration
Ubuntu/Debian/Gentoo /etc/default/docker
OpenSuse/CentOS/Red Hat /etc/sysconfig/docker

/lib/systemd/system/docker.service

/user/lib/systemd/system/service/docker

场景一:

Docker默认的配置文件/etc/default/docker或者/etc/sysconfig/docker都不起作用,查看了一下/lib/systemd/system/docker.service文件,发现里面没有加载默认配置文件,一些配置不知道要怎么弄了~~~

解决办法是:

1
2
3
4
5
6
$ vi /lib/systemd/system/docker.service
#添加一行
$ EnvironmentFile=-/etc/default/docker
或者
$ EnvironmentFile=-/etc/sysconfig/docker
#-代表ignore error

并修改

1
2
3
$ ExecStart=/usr/bin/docker daemon -H fd://
#改成
$ ExecStart=/usr/bin/docker daemon -H fd:// $DOCKER_OPTS

这样才能使用/etc/default/docker里定义的DOCKER_OPTS参数

Docker Contract

Docker 契约

docker_contract_01

问题
想要合作团队的可交付成果是整洁的、明确的,从面减少交付流水线里的摩擦。

解决方案
使用Docker契约来推动团队间整洁的可交付成果

讨论
随着公司规模扩大,经常可以看到其曾经拥有的扁平化的、精益化的组织架构——几个关键的个人“了解整个系统”,让位给了一个更加结构化的组织架构——不同的团队具有不同职责和能力。我们在效力过的组织中都对此有过切身体会。

如果没有进行技术投入,随着团队之间相互交付的增多,摩擦也会不断升级。图7-2展示了这个场景的一个简化了但具有代表性的倩形。图7-2 中的工作流有几个大家熟知的间题。这些间题最终都归结于状态管理的困难。测试团队可能在一台不是运维团队所设置的机器上进行侧试。理论上,对所有环境的修改都应仔细地记录下来,并在出现问题时进行回滚以保持一致性。但是,商业压力与人类行为的存在总是破坏这个目标,造成 环境性漂移

docker_contract_02

Docker 所能做的是在团队之间划出清洗的分界线,Docker 镜像即是分界线 ,又是交换的单位,我们称为 Docker Contract (契约),如图 7-3 所示。

docker_contract_03

More Ref:

docker 镜像逆向工程得到Dockerfile

可能有时候你得到了一个从Dockerfile创建的镜像文件,但是原始的Dockerfile丢失了。你想从这个镜像文件的构建历史记录中,逆向分析出原始的Dockerfile而省去寻找此文件的漫长过程。

虽然不可能在所有的情况下将一个Docker镜像完全得进行逆向工程,但如果此镜像是通过Dockerfile构建的,很有可能分析出此镜像是通过了什么命令得到的。我们以下面的Dockerfile为例,构建一个镜像,然后运行一个简单的shell脚本来演示如何分析镜像的构建历史记录,最后来看一个简洁的容器化的解决方案,来得出原始的Dockerfile。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
FROM busybox
MAINTAINER ian.miell@gmail.com
ENV myenvname myenvvalue
LABEL mylabelname mylabelvalue
WORKDIR /opt
RUN mkdir -p copied
COPY Dockerfile copied/Dockerfile
RUN mkdir -p added
ADD Dockerfile added/Dockerfile
RUN touch /tmp/afile
ADD Dockerfile /
EXPOSE 80
VOLUME /data
ONBUILD touch /tmp/built
ENTRYPOINT /bin/bash
CMD -r

首先要构建这个示例镜像,镜像命名为reverseme:

$ docker build -t reverseme .

SHELL解决方案

这个基于shell的实现主要在这里用来演示逆向工程的思路与方法,它与下面的容器化解决方案相比还不是十分完整。此方案使用了docker inspect命令来提取出镜像的metadata。

此shell脚本中使用了jq程序,一个可以查询和操作JSON数据的工具。为了运行此脚本,需要安装jq程序

1
2
3
4
5
6
7
8
docker history reverseme | \
awk '{print $1}' | \
grep -v IMAGE | grep -v missing | \
tac | \
sed "s/\(.*\)/docker inspect \1 | \
jq -r \'.[0].ContainerConfig.Cmd[2] | tostring\'/" | \
sh | \
sed 's/^#(nop) //'

上述代码第1行得到了组成指定镜像的层;第2行从docker history输出得到了各层的image ID;第3行排除标题行(带有“IMAGE”的那一行)及IMAGE的 ID为missing的那一行;第4行将镜像ID倒序输出,使其符合Dockerfile的顺序(“tac”是“cat”的倒序);第5、6行使用前面命令输出的image ID构建一个docker inspect命令,它输出Docker layer metadata。而此metadata通过管道输入到jq命令中,jq命令过滤metadata,获取当时构建此镜像时Dockerfile中使用的命令。第7行运行前面通过sed构建的整个docker inspect管道链。第8行剥离不能更改文件系统的指令——那些以“#(nop)”作为前缀的指令。
最后得到的输出结果类似于如下这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.....
CMD ["sh"]
MAINTAINER ian.miell@gmail.com
ENV myenvname=myenvvalue
LABEL mylabelname=mylabelvalue
WORKDIR /opt
mkdir -p copied
COPY file:4d91fcee48e4591e5fdc4b8963892b7d9582524f85f84b33eac5af164f928213 in copied/Dockerfile
mkdir -p added
ADD file:4d91fcee48e4591e5fdc4b8963892b7d9582524f85f84b33eac5af164f928213 in added/Dockerfile
touch /tmp/afile
ADD file:4d91fcee48e4591e5fdc4b8963892b7d9582524f85f84b33eac5af164f928213 in /
EXPOSE 80/tcp
VOLUME [/data]
ONBUILD touch /tmp/built
ENTRYPOINT ["/bin/sh" "-c" "/bin/bash"]
CMD ["/bin/sh" "-c" "-r"]

上面的输出与初始的Dockerfile有些类似了,但还有些区别。FROM指令被替换成了上述CMD指令,丢失了使用的基础镜像BusyBox的信息。ADD和COPY命令没有使用原本的文件名而是使用的校验和(checksum),文件被拷贝到的位置保存了下来。最后,CMD和ENTRYPOINT命令变成了方括号的数组形式。
由于缺少构建上下文,使得ADD和COPY命令不能使用,上面逆向工程恢复的Dockerfile并不能不加修改就运行。你需要找出什么文件被添加到构建上下文中。对于前面那个例子来说,你可以启动镜像,进入容器的/opt/copied目录和/opt/added目录,将文件提取出来加入到你的新的构建上下文中。

容器解决方案

使用前面的方案得到你感兴趣镜像的信息,是一个有用并且具有指导意义的方法,然而有更加干净的方法来得到同样的结果——使用centurylink/dockerfile-from-image镜像,同时这种方法更容易维护。而且,此方案提供了与原始Dockerfile类似的FROM命令的信息(如果它可以提供的话):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ docker run -v /var/run/docker.sock:/var/run/docker.sock \
> dockerinpractice/dockerfile-from-image reverseme
FROM busybox:latest
MAINTAINER ian.miell@gmail.com
ENV myenvname=myenvvalue
LABEL mylabelname=mylabelvalue
WORKDIR /opt
RUN mkdir -p copied
COPY file:4d91fcee48e4591e5fdc4b8963892b7d9582524f85f84b33eac5af164f928213 in copied/Dockerfile
RUN mkdir -p added
ADD file:4d91fcee48e4591e5fdc4b8963892b7d9582524f85f84b33eac5af164f928213 in added/Dockerfile
RUN touch /tmp/afile
ADD file:4d91fcee48e4591e5fdc4b8963892b7d9582524f85f84b33eac5af164f928213 in /
EXPOSE 80/tcp
VOLUME [/data]
ONBUILD touch /tmp/built
ENTRYPOINT ["/bin/sh" "-c" "/bin/bash"]
CMD ["/bin/sh" "-c" "-r"]

此技术只适用于基于Dockerfile创建的镜像——如果镜像是通过手工创建然后commit的,镜像间的区别不能体现在镜像的metadata里。

然而发现有bug,可参考 https://github.com/lukapeschke/dockerfile-from-image, 只支持用 image_id ,不能用 image name
主要使用方法如下:

1
2
3
4
5
6
7
## build the image
git clone https://github.com/lukapeschke/dockerfile-from-image.git
cd dockerfile-from-image
docker build -t lukapeschke/dfa .

## To get a Dockerfile from an existing image:
docker run --rm -v '/var/run/docker.sock:/var/run/docker.sock' lukapeschke/dfa <IMAGE_ID>

出自 《Docker IN PRACTICE》一书

More Ref:
https://andyyoung01.github.io/2016/08/23/%E4%BB%8E%E9%95%9C%E5%83%8F%E5%8E%86%E5%8F%B2%E8%AE%B0%E5%BD%95%E9%80%86%E5%90%91%E5%88%86%E6%9E%90%E5%87%BADockerfile/

docker 镜像的扁平化

Dockerfile 的设计以及它们产出 Docker 镜像的结果便是,最终镜像里包含了 Dockerfile 里每一步的数据状态。在构建镜像的过程中,可能需要复制私密信息来确保构建工作可以顺利进行。这些所谓的私密信息可能是 ssH 密钥、证书或者密码文件等。在提交镜像前删除这些私密信息的话可能不会提供任何实质性的保护,因为它们将出现在最终镜像的更高分层里,而恶意用户则可以轻松地从镜像中提取它们。解决这一问题的其中一个办法便是将得到的镜像扁平化。

问题
想要从镜像的分层历史中移除私密信息。

解决方案
基于该镜像创建一个容器,将它导出再导人,然后给它打上最初镜像田的标签。

讨论
为了演示这种做法的可用场景,让我们在一个新目录里创建一个简单的 Dockerfile ,该目录下藏着一个大秘密。运行 mkdir secrets “ cd Secrets ,然后在该目录里创建一个包含如下内容的 Dockerfile :

1
2
3
4
FROM busybox
RUN echo "My Big secret" >> /tmp/secret_key
RUN cat /tmp/secret_key
RUn rm /tmp/secret_key

运行 docker build -t mysecret .

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
➜   docker build -t mysecret .
Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM busybox
---> 8c811b4aec35
Step 2/4 : RUN echo "My Big secret" >> /tmp/secret_key
---> Running in 2b6f94ac0148
Removing intermediate container 2b6f94ac0148
---> a9ecbe44119c
Step 3/4 : RUN cat /tmp/secret_key
---> Running in b515370b1b88
My Big secret
Removing intermediate container b515370b1b88
---> 8a890a1ace7c
Step 4/4 : RUn rm /tmp/secret_key
---> Running in c9910e46efc2
Removing intermediate container c9910e46efc2
---> 6010dbf70359
Successfully built 6010dbf70359
Successfully tagged mysecret:latest

可以使用docker history 命令检查得到的Docker镜像的分层.如果该镜像上传到公有仓库,被他人下载,在没有原始 Dockerfile 到情况下,可以轻松获取私密信息。

1
2
3
4
5
6
7
➜   docker history mysecret:latest
IMAGE CREATED CREATED BY SIZE COMMENT
6010dbf70359 22 seconds ago /bin/sh -c rm /tmp/secret_key 0B
8a890a1ace7c 23 seconds ago /bin/sh -c cat /tmp/secret_key 0B
a9ecbe44119c 25 seconds ago /bin/sh -c echo "My Big secret" >> /tmp/secr… 14B
8c811b4aec35 14 months ago /bin/sh -c #(nop) CMD ["sh"] 0B
<missing> 14 months ago /bin/sh -c #(nop) ADD file:5f0439d8328ab58c0… 1.15MB

解决方法

将该镜像导出为一个简单运行的容器,然后再重新导入并给得到的镜像打上标签

1
2
3
4
5
6
7
➜   docker run -d mysecret /bin/true
02cbd0f59623472acc4571c1b654cdca40730d036d7a96a7dbaacaaf264177aa
➜ docker export 02cbd0f5962 | docker import - mysecret
sha256:080b122e43cb5d46efec5aa0b6abd0570e1abc52b3293f77b091bf22722c1168
➜ docker history mysecret
IMAGE CREATED CREATED BY SIZE COMMENT
080b122e43cb 9 seconds ago 1.15MB Imported from -
  • Copyrights © 2019-2024 John Doe
  • Visitors: | Views:

请我喝杯咖啡吧~