IT・ビッグデータ徒然ブログ

関西でインフラ、データ基盤系のエンジニアになるため、転職活動中。

Kubernetesを勉強しつつ、用語を整理してみる

kubernetes.io

最近Kubernetesに興味をもっていろいろいじっている。

随時更新予定。

Kubernetesとは、、、

  • 仮想化の一種であるコンテナ技術のオーケストラレーションができるツール
  • Googleが開発して現在はOSS化している

他のDockerにもオーケストラレーション機能はあることはあるが、 Kubernetesの特徴としては、

  • 複数のノード(サーバ)を1つのコンテナサーバとしてみなすことができる
  • スケールアウトが容易(ノード追加)
  • サービスのローリングアップデートが可能
  • アップデートしても、前のバージョンのコンテナが残っている(イミュータブル)なので、戻すことも容易
  • 宣言的設定→望ましい状態に満たないときはKubernetesがうまいことやってくれる

とかですかね。

(このあたりはGoogleらしいというか、分散システム(YARNとかMesosとか)の感じを受けました)

kubectlインストール

brew install kubernetes-cli

minikubeインストール

curl -Lo minikube https://storage.googleapis.com/minikube/releases/v0.28.2/minikube-darwin-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/

他のインストール方法はこちら

Install Minikube - Kubernetes

github.com

YAML

Kubernetesでコンテナ起動等なんらかの定義をする際はYAMLで記述する

起動

定義を実行するときは、 kubectl apply -f <YAML定義>で実行する。 それかkubectl runでもできる

Kubernetesの情報確認

kubectl get <項目>で見れる

# Pod情報
kubectl get pods

# Deployment情報
kubectl get deployments

# Replicaset
kubectl get rs

詳細情報の取得

kubectl describe <項目> <名前>

#特定の定義情報を取得
kubectl describe pod 

Pod

  • コンテナの塊
  • Kubernetesで操作できる最小単位
  • 基本的には1Podにつき1コンテナ
  • 複数のコンテナが常に同期していないといけない場合は1Podにくるめる
    • 入門Kubernetesによると「このコンテナはそれぞれ違うマシンに配置されても正常に動作するかどうか」がNoなら1つのPodにまとめるのがいいとのこと
      • できるだけ疎結合であることを推奨 -> マイクロサービス化

Podを定義するときには、コンテナのポートPodのポートフォワーディングを設定する。

Label

  • Podや後述するDeploymentやServiceなどにつけられるタグのようなもの
  • Key/Value形式で設定
  • app:tomcatというラベルがついているPodをすべて落とすみたいなラベル単位での操作が可能になる
apiVersion: v1
kind: Pod
metadata:
   name: tomcat-pod
   labels:
      app: tomcat
  spec:
      containers:
      - name: tomcat
         image: tomcat:8.0
         ports:
         - name: tomcat-port
            containerPort: 8080
  • tomcat-podという名前のPodを作成
  • app -> tomcatというラベルを作成
  • コンテナの名前はtomcat、使用するコンテナイメージはtomcat:8.0
  • Podの8080がコンテナポートの8080にフォワーディング

kubectl apply -f <コンテナイメージのyaml>クラスタにデプロイ

コンテナの起動を確認する場合は、

kubectl port-forward nodehelloworld.example.com <ローカルポート>:<Pod内のコンテナポート> でポートフォワーディングするとlocalhost:<ローカルポート>でアクセスできる

livenessProbeとreadinessProbe

要はコンテナ生きてる?という確認を行うもの。(Hadoopでいうハートビートみたいなやつ)

LivenessとReadinessの違いは

Liveness -> コンテナが起動しているか Readiness -> コンテナが応答するか

apiVersion: v1
kind: Pod
metadata:
   name: tomcat-pod
   labels:
      app: tomcat
spec:
  template:
    metadata:
      labels:
        app: tomcat
    spec:
      containers:
      - name: tomcat
        image: tomcat:8.0
        ports:
        - containerPort : 8080
        livenessProbe:
          httpGet:
            path: /
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 30
          timeoutSeconds: 10
          failureThreshold: 3
        readinessProbe:
          httpGet:
            path: /
            port: 8080
          initialDelaySeconds: 15
          periodSeconds: 3
          timeoutSeconds: 10
          failureThreshold: 3
  • livenessProbe
    • 8080ポートにアクセスして起動確認
    • コンテナ開始を30秒待つ
    • 30秒ごとに監視する
    • タイムアウトは10秒
    • 3回連続タイムアウトでコンテナが起動していないと解釈(Deploymentとかと組み合わせると自動で別のコンテナが起動したり)
  • ReadinessProbe
    • 8080ポートにアクセスして起動確認
    • コンテナ開始を15秒待つ
    • 3秒ごとに監視する
    • タイムアウトは10秒
    • 3回連続タイムアウトでコンテナが応答していないと解釈

Resource(requestとlimit)

コンテナに対して最低限要求するリソースと逆にこれ以上リソースをとるなというリミットを宣言できる

# 一部抜粋
spec:
      containers:
        - name: tomcat
        image: tomcat:9.0
        resources:
          requests:
            cpu: "500m" 
            memory: "128Mi"
          limits:
            cpu: "1000m"
            memory: "256Mi"
ports:
- containerPort: 8080
  • cpu
    • Min0.5コア、Max1コア
  • メモリ
    • Min128MB、Max256MB

Volume

Podが停止しても永続的に残るストレージのようなものを作成できる。

Volumeの定義はコンテナの定義を作る感覚で定義できる
(というよりストレージ用のコンテナを作る感覚に似ていると思う)

spec: 
  volumes:
    - name: "kuard-data" 
    nfs:
      server: my.nfs.server.local
      path: "/exports" 
containers:
#以下にコンテナの定義を書いたり

でコンテナにVolumeをマウントするときは、

spec:
      containers:
        - name: tomcat
        image: tomcat:9.0
        resources:
          requests:
            cpu: "500m" 
            memory: "128Mi"
          limits:
            cpu: "1000m"
            memory: "256Mi"
        volumeMounts:
          - mountPath: "/data" 
            name: "kuard-data"
ports:
- containerPort: 8080
  • volumeMounts内で指定したnameのVolumeを/dataにマウント

ReplicasetとDeamonset

Podを複数立てます。

  • 冗長化→負荷分散してくれる
  • 耐障害性→1つPodが落ちても大丈夫

ReplicasetとDaemonsetの違いは、

Replicaset

  • クラスタ全体内で決められた数のPodを生成
    • 実際のノードのどこに配置するかは自由
  • 定義を記述するときに、合わせてPod(コンテナ)の定義もできる
apiVersion: apps/v1beta2
kind: Replicaset
metadata:
  name: tomcat
spec:
  selector:
    matchLabels:
      app: tomcat
  replicas: 4
  template:
    metadata:
      labels:
        app: tomcat
    spec:
      containers:
      - name: tomcat
        image: tomcat:9.0
        ports:
        - containerPort : 8080
  • Tomcatのコンテナが入っているPodを動かす
  • PodのIP:8080でこのコンテナにアクセスできる
  • PodはKubernetesクラスタ上に4つ複製される

これを実行した後、kubectl get rsを動かすと

$ kubectl get rs                  
NAME                           DESIRED   CURRENT   READY     AGE
tomcat-84bc588dcd   4         4         0         11s

こんな感じで結果が返ってくる。

Daemonset

  • クラスタ内のすべてのノードに対して1つ以上Podを生成
    • すべてのノードに対して監視用アプリケーションやログコレクタ(Fluentd等)のPodを配置したりできる

Service

外部から特定のPodにアクセスするための機能 ※本来はPod生成時に外部からアクセスできるIPが生成されるが、毎回調べるのが面倒なので、そこをServiceがうまい具合にやってくれる。

クラスタ内部はもちろん(TargetPort)、クラスタ外からのネットワークからのアクセスも可能(NodePort)

Deployment

  • Pod(のReplicaを含む)をアップデートできる
  • ローリングアップデート可能
  • Deploymentの定義実行時にReplicasetならびにPodの定義も記述できる

Job

  • なんらかの処理やワークフローを実行したいときに一時的に立ち上がるPodの定義

  • なんとなく、サーバレスっぽいなと直感で思ったけど違ってたら教えて。

  • 並列実行ができる

ConfigMap

Secrets

  • 見られたらまずい値を補完する機能
  • MySQLのパスワードとか、ApacheにわたすSSLの鍵とか

ブログ移住計画その6~AWSにWordPressをデプロイ~

やっと、AWSの環境にWordPressをデプロイしました。

いや、Ansibleをそのまま叩いて終わればよかったんですけどね。。。

ちなみに最終段階のAnsibleのディレクトリはこんな感じ。

.
├── ansible.cfg
├── group_vars/
│   └── all.yml
├── inventory/
│   └── hosts
├── playbook.yml
├── roles/
│   ├── httpd/
│   │   ├── handlers/
│   │   │   └── main.yml
│   │   └── tasks/
│   │       └── main.yml
│   ├── mysql/
│   │   ├── handlers/
│   │   │   └── main.yml
│   │   └── tasks/
│   │       └── main.yml
│   ├── php/
│   │   └── tasks/
│   │       └── main.yml
│   ├── wordpress/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── templates/
│   │       ├── .htaccess.j2
│   │       ├── .htaccess.root.j2
│   │       ├── .htpasswd.j2
│   │       └── index.php.j2
│   └── wp-cli/
│       ├── tasks/
│       │   └── main.yml
│       └── templates/
│           └── wp-config.php.j2
└── ssh_config

踏み台経由でAWSの環境にアクセスする

Ansibleを直接サーバに実行せず、踏み台経由で実行する場合は設定が必要。
なので、まずホストの情報を記述してみました。

# ssh_config

Host wp-bustion
    HostName <踏み台サーバIP>
    User centos
    Port <SSHポート>
    GatewayPorts yes
    IdentityFile <認証用暗号化鍵>

Host wordpress
    HostName <WordPressサーバIP>
    User centos
    Port 22
    GatewayPorts yes
    ProxyCommand ssh -F ssh_config -CW %h:%p wp-bustion
    IdentityFile <認証用暗号化鍵>

Host wp-mysql
    HostName <MySQLサーバIP>
    User centos
    Port 22
    GatewayPorts yes
    ProxyCommand ssh -F ssh_config -CW %h:%p wp-bustion
    IdentityFile <認証用暗号化鍵>

やってることは、ここでやったSSHの接続設定とほぼ同じ。

あとansible.cfgファイルで、playbook実行時にssh_configファイルを読ませるようにする。

[ssh_connection]
control_path = %(directory)s/%%h-%%r
ssh_args = -o ControlMaster=auto -o ControlPersist=60s -F ssh_config

最後に、Ansibleの実行対象を指定するサーバの指定を、ssh_configで設定しているHost名に変更しておく。

# inventory/hosts

[wp]
wordpress
[mysql]
wp-mysql

あとは素直に実行

ansible-playbook -i inventory/hosts playbook.yml

これで無事にデプロイ!と思ってました...

問題1: データベース接続確立エラーが発生

DB側の設定は完全にあっているのに、接続できないというエラーにドハマリ。
ひたすら調べていくと、SELinuxが原因とわかり、一部設定を変更した。

sudo setsebool -P httpd_can_network_connect_db 1
sudo systemctl restart httpd

問題2: .htaccessの設定が効かない

アクセス制御やリダイレクト制御を.htaccessに記述していたものの、設定が反映されるハマる。
しらべてみると、

<Directory "/var/www/html">
・
・
AllowOverride None
・
・
</DIrectory>

の、NoneをAllに変える必要があるらしく、設定したら反映された。

WordPressHTTPSにする

ここで作った証明書を反映させる。

ssl.csrssl.crt、ssl.keyを/etc/httpd/confに移動。
ssl.crtに2つファイルを作成して、証明書と中間証明書を作成

# hogehoge.com.2018.crtとしておく
<メールできた証明書をそのままコピー>

-----BEGIN CERTIFICATE-----
・
・
・
-----END CERTIFICATE-----
# intermediate_hogehoge.com.2018.crtとしておく
<中間証明書をコピー>

-----BEGIN CERTIFICATE-----
・
・
・
-----END CERTIFICATE-----

権限を変えておく

sudo chmod 600 hogehoge.com.2018.crt

ssl.confに設定ファイルを知らせる

# /etc/httpd/conf.f/ssl.conf

SSLCertificateFile /etc/httpd/conf/ssl.crt/hogehoge.com.2018.crt
・
・
SSLCertificateKeyFile /etc/httpd/conf/ssl.key/hogehoge.com.2018.key
・
・
SSLCertificateChainFile /etc/httpd/conf/ssl.crt/intermidiate_hogehoge.com.2018.crt

これでhttpdを再起動するとSSLパスフレーズが聞かれるはず。

WordPress側のSSL設定

WordPressの管理者画面にログインし、一般でサイトのアドレスをhttpからhttpsに変更する。

f:id:namusic701042:20180823131841j:plain

これで、ドメイン名で開くと、、、

f:id:namusic701042:20180823132025j:plain

はあ、終わった。

あとはプラグインとかいろいろと調整して、今週末には移行予定。

あとやりたいことは、

  • PlaybookをGithubに公開
  • MySQL等の運用関連でいろいろいじってみたい
  • アクセスログとかを取りながら、なんちゃってデータ基盤を作りたい

と思ってますー。

rockstock2008.blog17.fc2.com

https://blog.tacck.net/archives/29

blog.treedown.net

qiita.com

ブログ移住計画その5~wp-cliでWordPressをインストール~

前回までは普通に、WordPressのファイルを解凍して、それを置くだけだったのですが、これをするとDBの設定とかはGUI上で設定しないといけないので面倒。。。

なので、これを解決するために、wp-cli(WordPressコマンドラインツール)経由でインストールするように、Ansibleを書き換えます。

qiita.com

設定後のディレクトリ構成はこんな感じ

# tree -F
.
├── group_vars/
│   ├── all.yml
│   └── mysql.yml
├── inventory/
│   └── hosts
├── playbook.yml
├── roles/
│   ├── httpd/
│   │   ├── handlers/
│   │   │   └── main.yml
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── templates/
│   ├── mysql/
│   │   ├── handlers/
│   │   │   └── main.yml
│   │   └── tasks/
│   │       └── main.yml
│   ├── php/
│   │   └── tasks/
│   │       └── main.yml
│   ├── wordpress/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   └── templates/
│   │       └── index.php.j2
│   ├── wordpress.backup/
│   │   ├── tasks/
│   │   │   ├── main.yml
│   │   │   └── main.yml.backup
│   │   └── templates/
│   │       └── wp-config.php.j2
│   └── wp-cli/
│       ├── tasks/
│       │   └── main.yml
│       └── templates/
│           └── wp-config.php.j2
└── templates/

相変わらず無駄なディレクトリがありますが、そこはご愛嬌ということで。。。

Playbookの書き換え

まず、Playbookはwordpressの代わりに、wp-cliロールを実行するように設定

- hosts: mysql
  become: yes
  become_user: root
  tasks:
  roles:
    - mysql


- hosts: wp
  become: yes
  become_user: root
  tasks:
  roles:
    - httpd
    - php
    - wp-cli

繰り返しの項目を変数化

設定をいじっていると、同じ設定を加える箇所がいくつか出てきたので、その部分を変数化

# group_vars/all.yml

db:
  host: localhost # DB側ホスト
  name: "hogehoge"  #DB名
  user: "foobar" #DBユーザ名
  password:
    wordpress: "hogehoge" #WordPress用DBのパスワード
    root: "foobar" #DBのルートユーザパスワード

httpd:
  document_root_directory: /var/www/html #wordpressのディレクトリ

wordpress:
  name: wordpress
  title: "blog title"
  locale: "ja"
  admin:
    name: "nyaonyao" #WordPressのAdminユーザ名
    password: "passw@rd" #WordPressのAdmin用パスワード
    mail: "huga@gmail.com"

wp_cli_path: /usr/local/bin/wp #wp-cliのパス

# パスワードとかユーザー名等その時々によって設定は変更
# 適当な名前にしないように

wp-cliでのインストール

# roles/wp-cli/tasks/main.yml


#最新版のwp-cliをbin/wpに入れる
- name: get wp-cli
  get_url:
    url: "https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar"
    dest: /usr/local/bin/wp
    mode: 0755

#WordPressをインストールする先のディレクトリを作成
- name: create directory
  file:
    dest={{ httpd.document_root_directory }}/{{ wordpress.name }}
    owner=apache
    group=apache
    state=directory
    mode=0755

# WordPressのファイルをダウンロード
- name: install wordpress core
  shell: |
    sudo -u apache {{ wp_cli_path }} core download \
    --locale={{ wordpress.locale }} 
  args:
    chdir: "{{ httpd.document_root_directory }}/{{ wordpress.name }}"

# 変数で指定したディレクトリにダウンロードさせている


# DB情報の設定ファイルをWordPressディレクトリに配布
# wp core configでも設定できるみたいだけど、sudo実行するとパス関係でややこしくなるので、事前に設定したphpを配布するほうが楽かも
# 外からいじられるのはかなり危ないのでパーミッションは400

- name: setup  wp-config.php
  template:
    src: wp-config.php.j2
    dest: "{{ httpd.document_root_directory }}/{{ wordpress.name }}/wp-config.php"
    owner: apache
    group: apache
    mode: 0400


# WordPressをインストール
- name: install wordpress
  shell: |
    sudo -u apache {{ wp_cli_path }} core install \
    --title={{ wordpress.title }} \
    --admin_user={{ wordpress.admin.name }} \
    --admin_password={{ wordpress.admin.password }} \
    --admin_email={{ wordpress.admin.mail }}\
    --url="http://{{ inventory_hostname }}/{{ wordpress.name }}"
  args:
    chdir: "{{ httpd.document_root_directory }}/{{ wordpress.name }}"

ちなみに事前にDB設定を記載しているwp-config.php.j2ファイルをroles/wp-cli/templatesに入れておきます。

これを実行します。

ansible-playbook -i inventory/hosts playbook.yml

こうすると、設定なしでそのままWordPressにログインして日記が書けるはず。

そろそろ本番にデプロイしたいのですが、いろいろ他にも手を出しているので、月末までにはあげたい。。。

ブログ移住計画その4~WordPressをセキュアに~

前回の続き。

前にAnsibleで作ったものを入れて、WordPressをセキュアに設定しておきます。

DBのプレフィックスを変更

WordPressをインストールして、設定するとwp_から始まるテーブル名が自動で生成されるが、これだと攻撃の標的になるので、wp-config.phpの以下の行を変更する

##$table_prefix  = 'wp_'
 
$table_prefix  = 'wp_test_'
## プレフィックスは自由に

wp-config.phpパーミッションを変更

wp-config.phpは重要なファイルなのでパーミッションを400に設定しておく。 上のプレフィックスの変更もあるので、wp-config.phpのファイルを切り出してもっておき、配布するように設定

./roles/wordpress/tasks/main.ymlの一部

### wordpress/templatesディレクトリにwp-config.php.j2ファイルを仕込んでおく

- name: set wp-config.php
  template:
    src: wp-config.php.j2
    dest: /var/www/html/wordpress/wp-config.php
    owner: apache
    group: apache
    mode: 0400

.htaccessの設定変更

ファイルへのアクセスとか色々制御するために設定

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /wordpress/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /wordpress/index.php [L]
</IfModule>

<files wp-config.php>
order allow,deny
deny from all
</files>

<Files xmlrpc.php>
Order Deny,Allow
Deny from all
</Files>  

<files wp-comments-post.php>
order allow,deny
deny from all
</files>      

DirectoryIndex index.html .ht

<Files wp-login.php>
AuthUserFile /var/www/.htpasswd
AuthGroupFile /dev/null
AuthName "Please enter your ID and password"
AuthType Basic
require valid-user
</Files>


<FilesMatch "wp-login.php|wp-admin">
Order deny, allow
Deny from all
Allow from xxx.xxx.xxx.xxx
</FilesMatch>

# END WordPress

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{QUERY_STRING} rest_route=
RewriteRule ^$ /? [R=404,L]
</IfModule>

.htpasswdも合わせて設定

<wordpressのID>:<wordpressのパスワード>
#例:hogehoge:foobar1234

.htaccessと.htpasswdファイルをWordPressサーバに配布

インストール後に設定変更した分を配布するようにAnsibleを更新 (templateディレクトリに各ファイルをおいておく)

- name: set .htpasswd
  template:
    src: .htpasswd.j2
    dest: /var/www/html/wordpress/.htpasswd
    owner: apache
    group: apache
    mode: 0644

- name: set .htaccess
  template:
    src: .htaccess.j2
    dest: /var/www/html/wordpress/.htaccess
    owner: apache
    group: apache
    mode: 0644

他にも色々あるけど、ざっくりこんな感じ。

もうちょいいろいろ設定見ておく。

http://design-plus1.com/tcd-w/2015/09/security.html

ahalog.tdesignworks.net

viral-community.com

viral-community.com

memocarilog.info

viral-community.com

ブログ移住計画その3~ドメイン作成とサーバ証明書の契約まで~

naoyoshi.hatenablog.jp

続き。

今回はインストールとかじゃなくて、ドメインの設定とSSLの契約までやりました

ドメイン設定

WordPressを公開するからにはドメインがほしいと思い、早速契約

今回はムームードメインで契約した。

muumuu-domain.com

f:id:namusic701042:20180810192413j:plain

ここで自分が作りたいドメインを入力して、検索

アカウント作る。AmazonでSSOできるの便利 f:id:namusic701042:20180810192417j:plain

ユーザー情報とか、支払い情報を入力 f:id:namusic701042:20180810192420j:plain

ドメイン取得 f:id:namusic701042:20180810192424j:plain

EC2のインスタンスドメインを紐付ける

作ったドメインとEC2インスタンス(WordPressインスタンス)を紐付ける ドメイン系はAWSのRoute53を使ってマネージングする。

AWSのRoute 53から、

  • Hosted zonesに移動
  • Create Hosted Zoneを選択し以下の設定
    • Domain Name -> 作成したドメイン
    • Type -> Public Hosted Zone
  • Create Record setを選択し以下の設定

作成。

あと、Type=nsに入っているnsから始めるURLっぽいものをコピーしておく。

ドメインDNS紐付け

ムームードメインに戻る
ネームサーバ設定変更からさっき取得したドメインを選択

GMOペパボ以外 のネームサーバを使用するにチェックを入れて、さっきコピーしたnsから始めるURLを一つずつ入力

f:id:namusic701042:20180810192901j:plain

設定完了後、以下のコマンドを入力

dig <ドメイン名>

うまく表示されてた。

SSLサーバ証明書の契約

次にSSLサーバ証明書の契約。ほんとは設定まで行きたかったけど、AWS上にWordPressインストールしてないとできないから、ひとまず契約だけ。

今回はKingSSLで契約

www.kingssl.com

証明書用の鍵を作る

SSLの証明書用にopensslコマンドで秘密鍵を作る

mkdir  ./ssl
mkdir ./ssl/ssl.key
mkdir ./ssl/ssl.csr
mkdir ./ssl/ssl.crt
openssl genrsa -des3 -out ./ssl.key/hogehoge.com.2018.key 2048

次に秘密鍵を元にCSRを作成 csrファイルの中身をcatでコピペしておく

openssl req -new -key ./ssl.key/hogehoge.com.2018.key -out ./ssl.csr/hogehoge.com.2018.csr
cat ./ssl.csr/hogehoge.com.2018.csr

ちなみにCSR作成時に色々と聞かれるが、詳細はこちらから blog.bagooon.com

CSRファイルを使って証明書契約

KingSSLで契約

f:id:namusic701042:20180810192430j:plain

あとは、ユーザー情報とか支払い情報を入力したら契約成立

10分くらいすると指定したメールアドレス宛に証明書が届いた

f:id:namusic701042:20180810194159j:plain

次はWordPressのセキュアな設定をAnsibleに盛り込んでAWSにデプロイしたい

参考: お名前.comで取得したドメインをAmazon EC2に紐付ける

SSL証明書をインストールする(自分でやればこんなに激安!)

ConoHaVPSで動いているWordPressをSSL化しました。 | よだねっと

AWS EC2(Amazon Linux AMI 64-bit)のhttpdに無料SSL(Let’s Encrypt)を導入する | まろらぼ

ブログ移住計画その2~AnsibleでWordPressの構成管理~

インフラ部分は整ったので、
実際にインストールをしていくのですが、

ここではAnsibleを使ってインストールの構成管理をします。
で、いきなりAWS上でやるのはあれなので、一旦手元のPC(Mac)でVagrantを使ってテスト用に3台(プロビジョニング、WordPressMySQL)立てます

いろいろとインストールの記事(こことか)を読んでいくと、

がいるらしい。

で、今回はMySQLとそれ以外でインストール先を分けるのでそこも気にしながら進めていく。

Ansibleの構成

.
├── group_vars/
│   └── mysql.yml
├── inventory/
│   └── hosts
├── playbook.yml
├── roles/
│   ├── httpd/
│   │   ├── handlers/
│   │   │   └── main.yml
│   │   └── tasks/
│   │       └── main.yml
│   ├── mysql/
│   │   ├── handlers/
│   │   │   └── main.yml
│   │   └── tasks/
│   │       └── main.yml
│   ├── php/
│   │   └── tasks/
│   │       └── main.yml
│   └── wordpress/
│       └── tasks/
│           └── main.yml
└── templates/

※いらないとこ多々あり。今後スケール見越して一部ディレクトリ作ってます。

プロビジョニング先のIPの設定

Inventory/hostsファイルを作る

[wp]
192.168.33.90

[mysql]
192.168.33.91

## IPはその時による

MySQLのパスワードを変数化

group_vars/mysql.yml

mysql_root_password: "<rootパスワード>"
mysql_db_password: "<wordpress用ユーザのパスワード>"

httpd(Apache)のインストール他もろもろ

httpd/tasks/main.yml

- name: install apache
   yum:
     name: httpd

- name: start http server
   service:
     name: httpd
     state: started
     enabled: yes

頻繁にhttpdは再起動するので、再起動用のハンドラを作っておきます。 httpd/handlers/main.yml

- name: Restart httpd
    service:
    name: httpd
    state: restarted

PHPのインストール

php/tasks/main.yml

PHPを素直にインストール
php-develとphp-mbstringはいらないかも?
インストールあとにhttpdを再起動

- name: install php
   yum:
     name: "{{ item }}"
     state: latest
   with_items:
     - php
     - php-devel
     - php-mbstring
     - php-mysql
   notify: Restart httpd

WordPressをインストール

WordPressのみyumでインストールできないので、

  1. tar.gzでダウンロード
  2. ファイルを解凍

としています。

あとhtmlディレクトリに配置して、所有権もapacheにしています。

- name: download wordpress
   get_url:
     url="https://wordpress.org/latest.tar.gz"
     dest=/tmp/wordpress.tar.gz


- name: unarchive wordpress
   unarchive: src=/tmp/wordpress.tar.gz dest=/var/www/html/ copy=no

- name: change owner to apache
   file: path=/var/www/html/wordpress/ owner=apache group=apache recurse=yes


- name: restart httpd
   service:
     name: httpd
     state: restarted

MariaDBをインストール

MySQLと書いていましたけど、CentOS7はMariaDBが推奨らしいので、こっちをインストール

手順は以下の通り。

  1. MariaDBをインストール
  2. MariaDBを起動
  3. MariaDBのrootユーザを作成
  4. rootユーザでWordPress用のDB作成
  5. WordPressDB用のユーザ(wp)を作成
    5-1. IPはWordPressサーバに届くようにサブネット範囲設定
- name: install mariadb
   yum: name={{ item }} state=installed
   with_items:
     - MySQL-python
     - mariadb
     - mariadb-server
     - libselinux-python

- name: start mariadb
   service:
     name: mariadb
     state: started
     enabled: yes

- name: create root user
   mysql_user:
     name: root
     host: localhost
     password: "{{ mysql_root_password }}"
     login_user: root
     login_password: "{{ mysql_root_password }}"
     check_implicit_admin: yes

- name: create database for wordpress
   mysql_db:
     login_user: root
     login_password: "{{ mysql_root_password }}"
     name: wordpress
     state: present

- name: create user for wordpress database and attach previlage
   mysql_user:
     login_user: root
     login_password: "{{ mysql_root_password }}"
     name: wordpress
     password: "{{ mysql_db_password }}"
     priv: "wordpress.*:ALL"
     host:  192.168.0.0/255.255.0.0
     state: present

playbookの作成

各タスクを実行するplaybookを作成

- hosts: wp
   become: yes
   become_user: root
   tasks:
   roles:
     - httpd
     - php
     - wordpress

- hosts: mysql
   become: yes
   become_user: root
   tasks:
   roles:
     - mysql

Playbookの実行

ansible-playbook -i inventory/hosts playbook.yml

WordPressを入れたサーバにアクセス。

f:id:namusic701042:20180809175134j:plain

f:id:namusic701042:20180809175140j:plain

うまくいきました。
(初期設定の画像を取り忘れた・・・)

とりあえず、問題なさそう。
ただAWSに乗せるにはもうちょっと設定をカスタマイズしたいので、いろいろ触ってみます。

参考URL:

thinkit.co.jp

cflat-inc.hatenablog.com

walkingmask.hatenablog.com

ブログ移住計画その1~AWSでインストールの下準備~

前回の記事であげたように、この夏休み中にWordPressにブログを移行しようと考えています。
で、今日はその初回。
ただ単にWordPressをインストールするだけならどこかサーバを借りてデフォルトでインストールすれば問題ないのですが、
せっかくなので自称エンジニア(?)らしく技術的な部分も取り入れつつやってみます。

今回のWordPressインストールではAnsibleを使ってAWS(EC2)上に立てたいなと思います。

構成図はこんな感じ。

f:id:namusic701042:20180808104230j:plain

セキュリティにも考慮して、 踏み台経由でのSSHログインでWordPress用のDBにするMySQLサーバはPrivateのサブネット内に入れておきます。

AWS上でインストールの下準備

VPCの構築

まずは、VPCを作ります。

項目
名前 wordpress-vpc(仮名)
IPv4 CIDR 10.0.0.0/16

サブネットの構築

次にサブネットです。
今回は踏み台+wordpress用のサブネットとDB用のサブネットを作ります。

DMZサブネット

項目
名前 dmz(仮名)
VPC wordpress-vpc
アベイラビリティゾーン 自由に設定
IPv4 CIDR 10.0.1.0/24

設定後、自動割当IP設定の変更で

  • パブリックIPv4アドレスの自動割当を有効にする

にチェックをつけておく

Privateサブネット

項目
名前 private(仮名)
VPC wordpress-vpc
アベイラビリティゾーン 自由に設定
IPv4 CIDR 10.0.2.0/24

インターネットゲートウェイの作成

次にDMZ内のサーバ(インスタンスに)インターネットから直接アクセスさせるためのゲートウェイを作成

  1. インターネットゲートウェイの作成から名前をつけて作成
  2. 新規作成したゲートウェイを選択してアクション->VPCにアタッチ
  3. 最初に作ったVPCを設定

NATゲートウェイの作成

DMZ内のインスタンスとインターネットは接続できるのですが、
DB側インスタンスにはインターネットと接続できません。
セキュリティ的にはOKなんですけど、
これだとMySQLをインストールしたいときとかメンテナンス、アップデートするときにちょっとやっかい。
なので、

インターネット→プライベートサブネットは✕
プライベートサブネット→インターネットは○

みたいなことをうまいことしてくれるNATゲートウェイを作っておきます。
(これ結構金かかるんですよね・・・なので必要なときだけたてて、いらないときは削除予定)

NATゲートウェイの作成から、
1. サブネットでDMZサブネットのIDを指定 2. ElasticIPを設定

ルートテーブルを設定

NATゲートウェイ・インターネットゲートウェイとサブネットを紐付けるために、 ルートテーブルを作成

ルートテーブルの作成から、名前とVPCを指定して2つ作成

DMZサブネット

  1. サブネットの関連付けでDMZサブネットの関連付けにチェック
  2. ルートを編集し、以下を追加
送信先 ターゲット
0.0.0.0/0 インターネットゲートウェイID

Privateサブネット

  1. サブネットの関連付けでPrivateサブネットの関連付けにチェック
  2. ルートを編集し、以下を追加
送信先 ターゲット
0.0.0.0/0 NATゲートウェイのID

SSHの鍵を作成

サーバを立てる下準備の最後として公開鍵作ります。
というのも、基本的にAWS上のサーバにアクセスするときは公開鍵使うんですけど、AWSのサーバ立てるときに自動で落ちてくる鍵はパスフレーズなしなんですよね。。。
そんな鍵を使いたくないので、自作で作ってインポートさせます。

ssh-keygen -t rsa -b 4096 -f <鍵名>.pem

本当は、

ssh-keygen -t ed25519 -f <鍵名>.pem

ed25519暗号で生成した鍵を使いたかったけど、なぜかインポート時にエラーが出た

暗号はED25519は意識高すぎ、高杉くんらしい。
暗号鍵参考URL

AWSのEC2からキーペアに移動して、
キーペアインポートから作ったキーをインポート

インスタンス作成

これで心おきなくインスタンスを作成 ひとまず3台立てる

  • 共通項目
    • OSはCentOS7
    • SSH鍵はさっき作ったものを使用
  • 踏み台サーバ
    • t2.micro
    • SSD15GB
    • サブネットはDMZサブネット
    • セキュリティグループは22とSSH用の別ポートを一旦開けておく
  • Wordpressサーバ
    • t2.small
    • SSD20GB
    • サブネットはDMZサブネット
    • セキュリティグループは80,443を一旦開けておくsshは踏み台からのみアクセス可能に
  • MySQLサーバ
    • t2.small
    • SSD30GB
    • サブネットはPrivateサブネット
    • セキュリティグループはDMZサブネットに対して公開

これでサーバ建てられた

SSHログインの確認

3台のサーバにSSHでログインできるか確認します。 ただ、踏み台以外のサーバは直接SSHできないので、踏み台経由でログインするように設定します。

Macの場合:

# ~/.ssh/configファイルの中に記述
Host wp-bustion
    HostName <踏み台インスタンスのパブリックIP>
    User centos
    Port 22
    GatewayPorts yes
    IdentityFile ~/.ssh/<公開鍵のファイル>

Host wordpress
    HostName <WordPressインスタンスののプライベートIP>
    User centos
    Port 22
    GatewayPorts yes
    ProxyCommand ssh -CW %h:%p wp-bustion
    IdentityFile ~/.ssh/<公開鍵>

Host wp-mysql
    HostName <MySQLインスタンスのプライベートIP>
    User centos
    Port 22
    GatewayPorts yes
    ProxyCommand ssh -CW %h:%p wp-bustion
    IdentityFile ~/.ssh/<公開鍵ファイル>

ssh-addコマンドで毎回パスフレーズを入力しなくていいように設定

ssh-add ~/.ssh/<公開鍵ファイル>

実際にログインして確認

ssh wp-bustion
ssh wordpress
ssh wp-mysql

ログイン成功。

踏み台サーバのSSHポートを変更する

ここは賛否両論あるみたいなんですが、せっかくなのでポート変えておきます。

###踏み台インスタンスにログイン
### /etc/ssh/sshd_configを開いて以下を編集

###Port22
Port <新しいポート番号>

このあと

systemctl restart sshd

で再起動して、一旦ログアウト。

ローカルで~/.ssh/configのところで、

Host wp-bustion
    HostName <踏み台インスタンスのパブリックIP>
    User centos
    Port <新しいポート番号>
    GatewayPorts yes
    IdentityFile ~/.ssh/<公開鍵のファイル>

と編集。
再度SSHログイン。

うまくいった。

これで下準備完了