Skip to content
This repository has been archived by the owner on Dec 2, 2022. It is now read-only.

k8sでのクラスタ運用のためのコード #570

Merged
merged 57 commits into from Sep 25, 2019
Merged
Show file tree
Hide file tree
Changes from 54 commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
20e5a39
Merge pull request #355 from ictsc/add_license
uplus Jul 17, 2019
33f57a4
Merge pull request #603 from ictsc/develop
uplus Aug 27, 2019
74479e6
update k8s config
Aug 15, 2019
7261b5c
add terraform and .envrc
Aug 15, 2019
6b6cd5d
ingnore .envrc
Aug 15, 2019
16b52d6
add ansible-playbook
Aug 15, 2019
b5ef19e
add ansible.cfg. for sake of because ssh connection improvement
Aug 15, 2019
db97146
fix inventry.sh
Aug 15, 2019
e5fca34
init password and not use ssh login
Aug 16, 2019
acefe49
add readme(wip) and rename file
Aug 16, 2019
d7b6c9a
fix
Aug 16, 2019
462d599
update user ictsc using bash
Aug 16, 2019
646039c
user def example and update readme
Aug 16, 2019
101ac5d
update usergroup append docker and adm
Aug 17, 2019
0817a36
address apply
Aug 17, 2019
6913083
update configs
Aug 17, 2019
c8304a6
update readme
Aug 17, 2019
7274f7e
update fix
Aug 17, 2019
197921d
update fix
Aug 17, 2019
71b012d
update fix
Aug 17, 2019
03c25a6
fix name
Aug 17, 2019
7d41e49
reademe update
Aug 17, 2019
244433d
rupdate
Aug 17, 2019
2ea2c69
fix inventry.sh
Aug 20, 2019
8a1cf4e
fix up
Aug 20, 2019
29f0b6f
Outside data. thinks
Aug 20, 2019
a66a5dc
fix env value
Aug 21, 2019
f119af2
use env var
Aug 24, 2019
5b28613
add ignore
Aug 24, 2019
0df9868
fixed var
Aug 24, 2019
22d21a5
fixed
Aug 24, 2019
c5004fb
use env script
Aug 24, 2019
7f55d01
update readme
Aug 24, 2019
5c09ee1
update readme
Aug 24, 2019
5259ba8
add iginore
Aug 24, 2019
37f19d8
update readme
Aug 24, 2019
ff541f1
update readme
Aug 24, 2019
75765aa
add var namespace
Aug 24, 2019
7225231
add crds
Aug 24, 2019
be8515c
update
Aug 24, 2019
a3fd816
fix listload
Aug 31, 2019
4055db6
Bump eslint-utils from 1.4.0 to 1.4.2 in /ui
dependabot[bot] Aug 27, 2019
9efefa0
update readme
Aug 31, 2019
8c44804
using dump_all
Sep 14, 2019
6633779
review based fix
Sep 14, 2019
3e42301
vars configs
Sep 14, 2019
de22eb0
file cosmetic
Sep 14, 2019
9f14daf
Merge branch 'develop' into feature/provisioning_k8s
takehaya Sep 14, 2019
b0583aa
fix namespace indent and add namespace
Sep 14, 2019
aee59ee
add service for X namespace connection
Sep 14, 2019
b4159d0
add round1st version container
Sep 15, 2019
9371ea2
cosmtic commit
Sep 15, 2019
7e44cc1
fix large alphabet
Sep 15, 2019
ada4eaf
todo commant add
Sep 15, 2019
1645151
review based fix
Sep 22, 2019
d95a605
backquort fix
Sep 22, 2019
0c88b16
review based fix
Sep 24, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Expand Up @@ -144,3 +144,9 @@ config/contest.yml
uploads/
coverage/
__pycache__/

# k8s provisoning_k8s
.envrc
var.yml
deploy_ready_output
env.yaml
3 changes: 3 additions & 0 deletions k8s/.envrc.sample
@@ -0,0 +1,3 @@
export SAKURACLOUD_ACCESS_TOKEN=hoge
export SAKURACLOUD_ACCESS_TOKEN_SECRET=piyo
export SAKURACLOUD_ZONE=is1b
13 changes: 13 additions & 0 deletions k8s/10-kubeadm.template.conf
@@ -0,0 +1,13 @@
# Note: This dropin only works with kubeadm and kubelet v1.11+
[Service]
Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf"
Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml"
Environment="KUBELET_CGROUP_ARGS=--cgroup-driver=cgroupfs"
Environment="KUBELET_SYSTEM_PODS_ARGS=--pod-manifest-path=/etc/kubernetes/manifests --fail-swap-on=false"
# This is a file that "kubeadm init" and "kubeadm join" generates at runtime, populating the KUBELET_KUBEADM_ARGS variable dynamically
EnvironmentFile=-/var/lib/kubelet/kubeadm-flags.env
# This is a file that the user can use for overrides of the kubelet args as a last resort. Preferably, the user should use
# the .NodeRegistration.KubeletExtraArgs object in the configuration files instead. KUBELET_EXTRA_ARGS should be sourced from this file.
EnvironmentFile=-/etc/default/kubelet
ExecStart=
ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS $KUBELET_SYSTEM_PODS_ARGS $KUBELET_CGROUP_ARGS
13 changes: 13 additions & 0 deletions k8s/Pipfile
@@ -0,0 +1,13 @@
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true

[dev-packages]

[packages]
pyyaml = "*"
oyaml = "*"

[requires]
python_version = "3.7"
48 changes: 48 additions & 0 deletions k8s/Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

111 changes: 111 additions & 0 deletions k8s/README.md
@@ -0,0 +1,111 @@
# k8s setup
* required
* terraform(0.12.5 <= x)
* ansible(2.8.3 <= x)
* terraform-provider-sakuracloud(1.15.2 <= x)
* direnv
* pipenv & python3.7
hint: [Terraform for さくらのクラウド](https://sacloud.github.io/terraform-provider-sakuracloud/installation/)
## claster setup
* 全て実行はこのカレントディレクトリで行ってください
* 事前準備
* `.envrc` にさくらのクラウドのアクセストークンとシークレットとゾーンを書く。 `.envrc.sample` に例があるのでそこの `hoge` とかの変数をいい感じに埋めよう
* 埋めたら `direnv allow` で適用される。このカレントディレクトリでその環境変数が適用される。
* `var.yml`に ansibleで作成したいuserを書く。 `var.sample.yml` に例があるのでパスワードとかをいい感じに変えよう
* `wget https://raw.githubusercontent.com/jetstack/cert-manager/release-0.9/deploy/manifests/00-crds.yaml` を `cluster_provisioning`のディレクトリでしておく
* api.yamlとui.yamlの以下のような部分をよしなに直そう。使い方は、ここのmetadataのnameをingress.yamlのpathに指定しよう
```
# api.yaml
apiVersion: v1
kind: Service
metadata:
name: api-production-bind-svc #<name>-<namespace>-bind-svcのフォーマットで書きましょう
spec:
type: ExternalName
externalName: api.production.svc.cluster.local #<name>.<namespace>.svc~~~のフォーマットで書きましょう

# ingress.yaml
http:
paths:
- path: /
backend:
serviceName: ui-production-bind-svc
servicePort: 3000
- path: /api
backend:
serviceName: api-production-bind-svc
servicePort: 3000
```

* `terraform apply -auto-approve` をしてVMが上がるのを待とう。生成された `id_rsa` は `user:ubuntu` 向けに作られているものです
* `sh inventry.sh` でinventryfileを作成
* `ssh-keygen -f ~/.ssh/ictsc` でこの名前の鍵を作成
* `ansible-playbook -u ubuntu --private-key=./id_rsa -i hosts setup.yml --extra-vars "ansible_sudo_pass=PUT_YOUR_PASSWORD_HERE"` でAnsibleを実行して、ictsc user作成とdocker install, k8s installが行なわれる
* これで`ssh -i ictsc ictsc@xxx.xxx.xxx.xxx` みたいな感じでログインできるようになります。
* masterになるサーバーにログインして`sudo kubeadm init --apiserver-advertise-address=192.168.100.1 --pod-network-cidr=10.244.0.0/16`をしよう。そこから出てきた情報をコピーして(`kubeadm join~~~`みたいなのがある)nodeになるサーバーに対してアクセスして貼り付けてsudoで実行しましょう。また、`mkdir -p $HOME/.kube` みたいなのもコンソールに表示されていてコピペできるようになってるのでmasterサーバでやってください。これでkubectlが使えるようになります。

## application setup
* `env.yaml`を作り、各パラメーターを埋める。 `env.sample.yaml` にテンプレートがあるのでパスワードとかFQDNをいい感じに変えよう
* 別途FQDNの設定は自分でよしなにしておく必要があります。
* `pipenv install` をしたあと `pipenv shell` でサブシェルに入って `python deploy_ready.py` を叩く。これで各パラメーターを入れたk8sのmanifestが出来上がる。
* ここのカレントディレクトリで `scp -i ictsc -r ./deploy_ready_output ictsc@xxx.xxx.xxx.xxx:/home/ictsc`でmasterサーバーにファイルを転送する
* ここでいうmasterServerというのは `k8s-master-01-server` のことです。
* `https://helm.sh/docs/using_helm/#installing-helm` をしていい感じにinstallしてほしい

### Try kubectl apply!
kubectl applyした時に前後関係があるので気持ち1~2秒ずつ打っていくといいです
<!--(TODO: 最初に数字を書いて前後の順番をつけておくと良さそう) -->
```sh
# flannelをinstall
# 全体の構成に必須なので一度のみ
kubectl apply -f kube-flannel.yml

# nginx ingressをinstall
# 全体の構成に必須なので一度のみ
kubectl apply -f mandatory.yaml

# cert-managerをinstall
# 全体の構成に必須なので一度のみ
kubectl apply -f 00-crds.yaml
kubectl create namespace cert-manager
kubectl label namespace cert-manager certmanager.k8s.io/disable-validation=true
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm install \
--name cert-manager \
--namespace cert-manager \
--version v0.9.1 \
jetstack/cert-manager
kubectl apply -f 00-crds.yaml

# cert-managerで動く証明書の設定
kubectl apply -f secret_cloudflare.yaml
kubectl apply -f cluster-issuer.yaml
kubectl apply -f cretificate.yaml
kubectl apply -f ingress.yaml

# applicationのinstall
kubectl -f redis.yaml,ui.yaml,db.yaml,api.yaml,service-nodeport.yaml
```

これを通じて無事立ち上げることができました!

あとは
* `kubectl exec -it pod/api-5f9cd6794-9z9sr rails db:setup`みたいな感じで初期データ流し込みをする
* `http://xxx.xxx.xxx.xxx:/`にアクセスできてloginができたら無事一通り立ってる感じ。おめでとう!

## その他
* `kubectl apply -f monitering_manifests.yaml` で同一クラスタ内にnodeexpoterなどの諸々監視を実行することができます

## TroubleShooting & Tips
* `terraform apply`が失敗したら`terraform destroy -force` とかで削除してから立て直す。
* playbookを書き換えたら`ansible-playbook --private-key=./id_rsa -i hosts setup.yml --syntax-check` でいい感じに事前に構文チェックをしておくと良い。
* kubeadmでコピー忘れたら雑に `kubeadm reset` でjoinやinitしてた情報ごと削除できる
* `kubectl delete -f redis.yaml,ui.yaml,db.yaml,api.yaml`で削除。
* もしマニフェストファイルを変更する場合は削除してから書き換えて適用する方が良い。
* `kubectl get all` で上がってるかどうかとか見れる。READYが1/1ならあがっているということ。0/1ならログを見てみたりしよう。
* `kubectl logs <pod name>`で可能
* 時々DBが上がるのが失敗したりするのでそのときはログ(ex. kubectl logsやkubectl describe pod)見てから kubectl deleteしてapplyをして見てみる
* [https://wiki.icttoracon.net/knowledge/score-server](https://wiki.icttoracon.net/knowledge/score-server)を参考にしている
* 接続先わかんなくなったら `terraform output`で接続先が確認できます。
* 雑にクラスタを作るための物なのでterraformのパラメーターやディフォルトパスワードとして設定してる `PUT_YOUR_PASSWORD_HERE`とかはよしなに変えることとをお勧めします。(普通に利用する分にはその都度生成される秘密鍵のみの接続になるので問題はないです)
7 changes: 7 additions & 0 deletions k8s/ansible.cfg
@@ -0,0 +1,7 @@
[defaults]
forks = 10

[ssh_connection]
ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null
retry_files_enabled=False
callback_whitelist=profile_tasks
85 changes: 0 additions & 85 deletions k8s/api.yaml

This file was deleted.

73 changes: 73 additions & 0 deletions k8s/apps/api.yaml
@@ -0,0 +1,73 @@
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
namespace: __VAR__NAMESPACE
name: api
labels:
app: api
spec:
replicas: 1
template:
metadata:
matchLabels:
labels:
app: api
spec:
# restartPolicy: OnFailure
initContainers:
- name: waitdb
image: jwilder/dockerize
args: ['sh', '-c', 'dockerize -wait tcp://redis:6379 -timeout 100s', 'dockerize -wait tcp://db:5432 -timeout 100s']
containers:
- image: __VAR__API_IMAGE
imagePullPolicy: Always
name: api
ports:
- containerPort: 3000
envFrom:
- configMapRef:
name: api-env
args:
- sh
- -c
- " if [ -f \"tmp/pids/server.pid\" ]; then rm tmp/pids/server.pid; fi\n
bundle exec rails server -b 0.0.0.0;"
---
apiVersion: v1
kind: ConfigMap
metadata:
name: api-env
namespace: __VAR__NAMESPACE
data:
TZ: __VAR__TZ
API_STAFF_PASSWORD: __VAR__API_STAFF_PASSWORD
API_SESSION_EXPIRE_MINUTES: __VAR__API_SESSION_EXPIRE_MINUTES
POSTGRES_HOST: __VAR__POSTGRES_HOST
POSTGRES_USER: __VAR__POSTGRES_USER
POSTGRES_PASSWORD: __VAR__POSTGRES_PASSWORD
POSTGRES_MAX_CONNECTIONS: __VAR__POSTGRES_MAX_CONNECTIONS
POSTGRES_SHARED_BUFFERS: __VAR__POSTGRES_SHARED_BUFFERS
POSTGRES_WORK_MEM: __VAR__POSTGRES_WORK_MEM
RAILS_ENV: __VAR__STAGE_ENV
NODE_ENV: __VAR__STAGE_ENV
REDIS_URL: __VAR__REDIS_URL
---
apiVersion: v1
kind: Service
metadata:
namespace: __VAR__NAMESPACE
name: api
spec:
selector:
app: api
type: ClusterIP
ports:
- port: 3000
---
apiVersion: v1
kind: Service
metadata:
name: api-production-bind-svc
spec:
type: ExternalName
externalName: api.production.svc.cluster.local