📌
Kubernetesで色々してみる
個人用のメモみたいなものです。
nginxを公開してみる
nginx
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
type: NodePort
selector:
app: nginx
ports:
- port: 8081
targetPort: nginx-port
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
app: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
resources:
limits:
memory: "128Mi"
cpu: "500m"
ports:
- containerPort: 80
name: nginx-port
protocol: TCP
Go/MySQLの自作APIを公開してみる
データの永続化なしバージョン
mysql.yml
apiVersion: v1
kind: Service
metadata:
name: mysql-server
spec:
type: ClusterIP
ports:
- name: mysql
port: 3306
targetPort: 3306
protocol: TCP
selector:
app: mysql-server
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-server
spec:
selector:
matchLabels:
app: mysql-server
strategy:
type: Recreate
template:
metadata:
labels:
app: mysql-server
spec:
containers:
- image: mysql@sha256:92ad1d7e3f8eb7e67d35bf251912fb7cd12676a601dc90b6beb1aece7c1f5073
name: mysql
resources:
env:
- name: MYSQL_USER
value: go_user
- name: MYSQL_PASSWORD
value: password
- name: MYSQL_ROOT_PASSWORD
value: root
- name: TZ
value: Asia/Tokyo
- name: MYSQL_DATABASE
value: go_database
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-server-initdb
mountPath: /docker-entrypoint-initdb.d
- name: mysql-server-conf
mountPath: /etc/mysql/conf.d
volumes:
- name: mysql-server-initdb
configMap:
name: mysql-server-initdb-config
- name: mysql-server-conf
configMap:
name: mysql-server-conf-config
---
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql-server-initdb-config
data:
createdb.sql: |
CREATE TABLE IF NOT EXISTS
go_database.users(
id serial,
sex int NOT NULL,
introduction VARCHAR(255) NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY(id)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS
go_database.posts(
id serial,
title VARCHAR(255) NOT NULL,
content VARCHAR(255) NOT NULL,
publish_date int NOT NULL,
thumbnail_url VARCHAR(255),
user_id bigint UNSIGNED NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY(id),
FOREIGN KEY (user_id)
REFERENCES users(id)
ON UPDATE CASCADE
ON DELETE CASCADE
) ENGINE=INNODB DEFAULT CHARSET=utf8;
---
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql-server-conf-config
data:
custom.cnf: |
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_bin
default-time-zone = SYSTEM
log_timestamps = SYSTEM
[mysql]
default-character-set = utf8mb4
[client]
default-character-set = utf8mb4
goapi.yml
apiVersion: v1
kind: Service
metadata:
name: goapi
spec:
type: NodePort
selector:
app: goapi
ports:
- port: 8080
targetPort: goapi-port
nodePort: 30090
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: goapi
labels:
app: goapi
spec:
replicas: 1
selector:
matchLabels:
app: goapi
template:
metadata:
labels:
app: goapi
spec:
containers:
- name: goapi
image: wakabaseisei/goapi:latest
resources:
limits:
memory: "128Mi"
cpu: "500m"
ports:
- containerPort: 8080
name: goapi-port
protocol: TCP
下記コマンドで、デプロイする
$ kubectl apply -f ./k8s/mysql.yml --record
$ kubectl apply -f ./k8s/goapi.yml --record
Podが起動しているかを確認
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
goapi-5749446fd4-bckn9 1/1 Running 0 18h
mysql-server-8cd85fb7c-mtxth 1/1 Running 0 18h
NodePortで公開したポートにアクセスする
ホストにマウントして永続化するバージョン
mysql-pv.yml
kind: PersistentVolume
apiVersion: v1
metadata:
name: mysql-pv-volume
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 20Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
mysql.yml
apiVersion: v1
kind: Service
metadata:
name: mysql-server
spec:
type: ClusterIP
ports:
- name: mysql
port: 3306
targetPort: 3306
protocol: TCP
selector:
app: mysql-server
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-server
spec:
selector:
matchLabels:
app: mysql-server
strategy:
type: Recreate
template:
metadata:
labels:
app: mysql-server
spec:
containers:
- image: mysql@sha256:92ad1d7e3f8eb7e67d35bf251912fb7cd12676a601dc90b6beb1aece7c1f5073
name: mysql
resources:
env:
- name: MYSQL_USER
value: go_user
- name: MYSQL_PASSWORD
value: password
- name: MYSQL_ROOT_PASSWORD
value: root
- name: TZ
value: Asia/Tokyo
- name: MYSQL_DATABASE
value: go_database
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-server-initdb
mountPath: /docker-entrypoint-initdb.d
- name: mysql-server-conf
mountPath: /etc/mysql/conf.d
- name: mysql-server-data
mountPath: /var/lib/mysql
volumes:
- name: mysql-server-initdb
configMap:
name: mysql-server-initdb-config
- name: mysql-server-conf
configMap:
name: mysql-server-conf-config
- name: mysql-server-data
persistentVolumeClaim:
claimName: mysql-pv-claim
---
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql-server-initdb-config
data:
createdb.sql: |
CREATE TABLE IF NOT EXISTS
go_database.users(
id serial,
sex int NOT NULL,
introduction VARCHAR(255) NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY(id)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS
go_database.posts(
id serial,
title VARCHAR(255) NOT NULL,
content VARCHAR(255) NOT NULL,
publish_date int NOT NULL,
thumbnail_url VARCHAR(255),
user_id bigint UNSIGNED NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY(id),
FOREIGN KEY (user_id)
REFERENCES users(id)
ON UPDATE CASCADE
ON DELETE CASCADE
) ENGINE=INNODB DEFAULT CHARSET=utf8;
---
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql-server-conf-config
data:
custom.cnf: |
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_bin
default-time-zone = SYSTEM
log_timestamps = SYSTEM
[mysql]
default-character-set = utf8mb4
[client]
default-character-set = utf8mb4
goapi.yml
apiVersion: v1
kind: Service
metadata:
name: goapi
spec:
type: NodePort
selector:
app: goapi
ports:
- port: 8080
targetPort: goapi-port
nodePort: 30090
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: goapi
labels:
app: goapi
spec:
replicas: 1
selector:
matchLabels:
app: goapi
template:
metadata:
labels:
app: goapi
spec:
containers:
- name: goapi
image: wakabaseisei/goapi:latest
resources:
limits:
memory: "128Mi"
cpu: "500m"
ports:
- containerPort: 8080
name: goapi-port
protocol: TCP
デプロイのお時間です
$ kubectl apply -f ./k8s/mysql-pv.yml --record
$ kubectl apply -f ./k8s/mysql.yml --record
$ kubectl apply -f ./k8s/goapi.yml --record
PVとPVCの生存確認
$ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS
mysql-pv-volume 20Gi RWO Retain Bound
CLAIM STORAGECLASS AGE
default/mysql-pv-claim manual 15h
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES
mysql-pv-claim Bound mysql-pv-volume 20Gi RWO
STORAGECLASS AGE
manual 15h
Podを消してもデータが永続化されるか検証してみる
検証用のデータを登録する
$ kubectl exec -it $(kubectl get pod | grep mysql | cut -d " " -f 1) -c mysql -- mysql --user=go_user --password=password
mysql> desc users;
+--------------+---------------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+---------------------+------+-----+-------------------+-----------------------------+
| id | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
| sex | int(11) | NO | | NULL | |
| introduction | varchar(255) | NO | | NULL | |
| created_at | timestamp | NO | | CURRENT_TIMESTAMP | |
| updated_at | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+--------------+---------------------+------+-----+-------------------+-----------------------------+
5 rows in set (0.01 sec)
mysql> desc posts;
+---------------+---------------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+---------------------+------+-----+-------------------+-----------------------------+
| id | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
| title | varchar(255) | NO | | NULL | |
| content | varchar(255) | NO | | NULL | |
| publish_date | int(11) | NO | | NULL | |
| thumbnail_url | varchar(255) | YES | | NULL | |
| user_id | bigint(20) unsigned | NO | MUL | NULL | |
| created_at | timestamp | NO | | CURRENT_TIMESTAMP | |
| updated_at | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+---------------+---------------------+------+-----+-------------------+-----------------------------+
8 rows in set (0.00 sec)
mysql> insert into users(sex, introduction) values (1, "It is so cool!");
Query OK, 1 row affected (0.01 sec)
mysql> insert into users(sex, introduction) values (1, "permanent");
Query OK, 1 row affected (0.01 sec)
mysql> insert into users(sex, introduction) values (2, "I am a woman");
Query OK, 1 row affected (0.00 sec)
mysql> insert into users(sex, introduction) values (1, "I am a man");
Query OK, 1 row affected (0.00 sec)
mysql> select * from users;
+----+-----+----------------+---------------------+---------------------+
| id | sex | introduction | created_at | updated_at |
+----+-----+----------------+---------------------+---------------------+
| 1 | 1 | It is so cool! | 2022-01-07 17:23:54 | 2022-01-07 17:23:54 |
| 2 | 1 | permanent | 2022-01-08 11:25:57 | 2022-01-08 11:25:57 |
| 3 | 2 | I am a woman | 2022-01-08 11:26:23 | 2022-01-08 11:26:23 |
| 4 | 1 | I am a man | 2022-01-08 11:26:43 | 2022-01-08 11:26:43 |
+----+-----+----------------+---------------------+---------------------+
4 rows in set (0.00 sec)
mysql> insert into posts(title, content, publish_date, user_id) values ("neew title", "I am a pianist", 11111111, 2);
Query OK, 1 row affected (0.00 sec)
mysql> select * from posts;
+----+------------+----------------+--------------+---------------+---------+---------------------+---------------------+
| id | title | content | publish_date | thumbnail_url | user_id | created_at | updated_at |
+----+------------+----------------+--------------+---------------+---------+---------------------+---------------------+
| 1 | neew title | I am a pianist | 11111111 | NULL | 2 | 2022-01-08 11:29:05 | 2022-01-08 11:29:05 |
+----+------------+----------------+--------------+---------------+---------+---------------------+---------------------+
1 row in set (0.00 sec)
mysql> exit
Bye
PodのNameを確認する
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
goapi-5749446fd4-78574 1/1 Running 0 151m
mysql-server-747f8c9f6c-tw8j2 1/1 Running 0 141m
「mysql-server-747f8c9f6c-tw8j2」をdeleteしてみる
$ kubectl delete pod mysql-server-747f8c9f6c-tw8j2
pod "mysql-server-747f8c9f6c-tw8j2" deleted
再度、Podを確認
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
goapi-5749446fd4-78574 1/1 Running 0 152m
mysql-server-747f8c9f6c-7lspg 1/1 Running 0 35s
「mysql-server-747f8c9f6c-7lspg」という名前で再度配置された!
ではでは、データの永続化はされているのか......
$ kubectl exec -it $(kubectl get pod | grep mysql | cut -d " " -f 1) -c mysql -- mysql --user=go_user --password=password
mysql> select * from users;
+----+-----+----------------+---------------------+---------------------+
| id | sex | introduction | created_at | updated_at |
+----+-----+----------------+---------------------+---------------------+
| 1 | 1 | It is so cool! | 2022-01-07 17:23:54 | 2022-01-07 17:23:54 |
| 2 | 1 | permanent | 2022-01-08 11:25:57 | 2022-01-08 11:25:57 |
| 3 | 2 | I am a woman | 2022-01-08 11:26:23 | 2022-01-08 11:26:23 |
| 4 | 1 | I am a man | 2022-01-08 11:26:43 | 2022-01-08 11:26:43 |
+----+-----+----------------+---------------------+---------------------+
4 rows in set (0.01 sec)
mysql> select * from posts;
+----+------------+----------------+--------------+---------------+---------+---------------------+---------------------+
| id | title | content | publish_date | thumbnail_url | user_id | created_at | updated_at |
+----+------------+----------------+--------------+---------------+---------+---------------------+---------------------+
| 1 | neew title | I am a pianist | 11111111 | NULL | 2 | 2022-01-08 11:29:05 | 2022-01-08 11:29:05 |
+----+------------+----------------+--------------+---------------+---------+---------------------+---------------------+
1 row in set (0.00 sec)
Pod削除前のデータがきちんと永続化されていた!
MasterとSlave構成のMySQLを扱うバージョンは、別記事でまとめようと思う。
Discussion