Если я установлю MariaDB из официального образа в конфигурации Docker Compose, я могу получить к ней доступ по имени хоста - например, если в оболочке bash в контейнере MariaDB:
# host db
db has address 172.21.0.2
# curl telnet://db:3306
Warning: Binary output can mess up your terminal. Use "--output -" to tell
Warning: curl to output it to your terminal anyway, or consider "--output
Warning: <FILE>" to save to a file.
- здесь нет соединения с отказом в выдаче
Но если MariaDB развернут из официального образа в кластере Kubernetes (пробовал и MicroK8, и GKE), я могу подключиться к нему через localhost
, но не по имени хоста:
# host db
db.my-namspace.svc.cluster.local has address 10.152.183.124
# curl telnet://db:3306
curl: (7) Failed to connect to db port 3306: Connection refused
# curl telnet://localhost:3306
Warning: Binary output can mess up your terminal. Use "--output -" to tell
Warning: curl to output it to your terminal anyway, or consider "--output
Warning: <FILE>" to save to a file.
- для имени хоста службы отказано в соединении, но localhost отвечает
Я пытался заменить включенный my.cnf
с упрощенной версией, такой как:
[mysqld]
skip-grant-tables
skip-networking=0
#### Unix socket settings (making localhost work)
user = mysql
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
#### TCP Socket settings (making all remote logins work)
port = 3306
bind-address = *
Развертывание MariaDB Kubernetes похоже на:
apiVersion: apps/v1
kind: Deployment
metadata:
name: db
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
name: db
template:
metadata:
labels:
name: db
spec:
containers:
- env:
- name: MYSQL_PASSWORD
value: template
- name: MYSQL_ROOT_PASSWORD
value: root
- name: MYSQL_USER
value: template
image: mariadb:10.4
name: db
ports:
- containerPort: 3306
resources: {}
volumeMounts:
- mountPath: /var/lib/mysql
name: dbdata
restartPolicy: Always
volumes:
- name: dbdata
persistentVolumeClaim:
claimName: dbdata
status: {}
и соответствующий персистентный Volume Claim:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
labels:
io.kompose.service: dbdata
name: dbdata
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Mi
status: {}
Меня сбивает с толку, что такая же конфигурация работает с Docker Compose, но не внутри кластера Kubernetes.
Есть идеи, что может происходить?
Обновление 2020-03-18 Я забыл включить декларацию сервиса для базы данных и добавить ее здесь:
apiVersion: v1
kind: Service
metadata:
labels:
app: db
name: db
spec:
ports:
- name: "3306"
port: 3306
targetPort: 3306
selector:
app: db
name: db
type: ClusterIP
status:
loadBalancer: {}
... am, включая app
и name
для spec.selector
- используется только для name
, но пример @ Al-waleed Shihadeh включает app
, поэтому я включу это также, на всякий случай - но безуспешно.
Вот результаты нескольких команд перечисления kubectl:
$ sudo microk8s.kubectl get svc db -n my-namespace
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
db ClusterIP 10.152.183.246 <none> 3306/TCP 35m
$ sudo microk8s.kubectl get pods -owide -n my-namespace
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
db-77cbcf87b6-l44lm 1/1 Running 0 34m 10.1.48.118 microk8s-vm <none> <none>
Решение Сравнивая объявление службы, опубликованное KoopaKiller, которое заработало, я наконец заметил, что для атрибута protocol
установлено значение "TCP" в декларация портов отсутствует - эта часть:
spec:
ports:
- protocol: TCP
...