kubernetes service and endpoints with 2 ports - kubernetes

I have postgres instance running outside kubernetes cluster on port 5434.
Service manifest looks like below. Everything works well.
kind: Service
apiVersion: v1
metadata:
name: postgres
spec:
ports:
- protocol: TCP
port: 5432
targetPort: 5434
---
apiVersion: v1
kind: Endpoints
metadata:
name: postgres
subsets:
- addresses:
- ip: 10.1.0.210
ports:
- port: 5434
But when I want add one additional port (5434) on my service it stops working (both ports). Manifest:
kind: Service
apiVersion: v1
metadata:
name: postgres
spec:
ports:
- protocol: TCP
port: 5432
targetPort: 5434
name: p1
- protocol: TCP
port: 5434
targetPort: 5434
name: p2
---
apiVersion: v1
kind: Endpoints
metadata:
name: postgres
subsets:
- addresses:
- ip: 10.1.0.210
ports:
- port: 5434

Related

Kubernetes create an endpoint with DNS instead IP

I need to create an endpoint with DNS instead of IP
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: NodePort
ports:
- port: 5432
targetPort: 5432
nodePort: 30004
---
apiVersion: v1
kind: Endpoints
metadata:
name: my-service
subsets:
- addresses:
- ip: **111.111.111.111** ** < need change this to DNS
ports:
- port: 5432
Everything works fine with numerical IP, but I need to put my Postgres DNS instead, something like:
subsets:
- addresses:
- ip: mypostgres.com
ports:
- port: 5432
But "addresses" only support numerical IP. I need some workaround to make this work.
if you want to connect to a remotely hosted database URI instead of IP you can use ExternalName
kind: Service
apiVersion: v1
metadata:
name: mongo
spec:
type: ExternalName
externalName: ds149763.mlab.com
Please check out more : https://cloud.google.com/blog/products/gcp/kubernetes-best-practices-mapping-external-services

How to expose redis to outside with istio sidecar?

I'm using redis with k8s 1.15.0, istio 1.4.3, it works well inside the network.
However when I tryed to use the istio gateway and sidecar to expose it to outside network, it failed.
Then I removed the istio sidecar and just started the redis server in k8s, it worked.
After searching I added DestinationRule to the config, but it didn't help.
So what's the problem of it? Thanks for any tips!
Here is my redis.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
spec:
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: docker.io/redis:5.0.5-alpine
imagePullPolicy: IfNotPresent
ports:
- containerPort: 16379
protocol: TCP
name: redis-port
volumeMounts:
- name: redis-data
mountPath: /data
- name: redis-conf
mountPath: /etc/redis
command:
- "redis-server"
args:
- "/etc/redis/redis.conf"
- "--protected-mode"
- "no"
volumes:
- name: redis-conf
configMap:
name: redis-conf
items:
- key: redis.conf
path: redis.conf
- name: redis-data
nfs:
path: /data/redis
server: 172.16.8.34
---
apiVersion: v1
kind: Service
metadata:
name: redis-svc
labels:
app: redis-svc
spec:
type: ClusterIP
ports:
- name: redis-port
port: 16379
protocol: TCP
selector:
app: redis
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: redis-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: tcp
protocol: TCP
hosts:
- "redis.basic.svc.cluster.local"
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: redis-svc
spec:
host: redis-svc
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: redis-vs
spec:
hosts:
- "redis.basic.svc.cluster.local"
gateways:
- redis-gateway
tcp:
- route:
- destination:
host: redis-svc.basic.svc.cluster.local
port:
number: 16379
Update:
This is how I request
[root]# redis-cli -h redis.basic.svc.cluster.local -p 80
redis.basic.svc.cluster.local:80> get Test
Error: Protocol error, got "H" as reply type byte
There are few thing that need to be different in case of exposing TCP application with istio.
The hosts: needs to be "*" as TCP protocol works only with IP:PORT. There are no headers in L4.
There needs to be TCP port match Your VirtualService that matches GateWay. I suggest to name it in a unique way and match Deployment port name.
I suggest avoiding using port 80 as it is already used in default ingress configuration and it could result in port conflict, so i changed it to 11337.
So Your GateWay should look something like this:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: redis-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 11337
name: redis-port
protocol: TCP
hosts:
- "*"
And Your VirtualService like this:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: redis-vs
spec:
hosts:
- "*"
gateways:
- redis-gateway
tcp:
- match:
- port: 11337
route:
- destination:
host: redis-svc
port:
number: 16379
Note that I removed namespaces for clarity.
Then add our custom port to default ingress gateway use the following command:
kubectl edit svc istio-ingressgateway -n istio-system
And add following next other port definitions:
- name: redis-port
nodePort: 31402
port: 11337
protocol: TCP
targetPort: 16379
To access the exposed application use istio gateway external IP and port that we
just set up.
To get Your gateway external IP you can use:
export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
redis-cli -h $INGRESS_HOST -p 11337
If Your istio-ingressgateway does not have external IP assigned, use one of Your nodes IP address and port 31402.
Hope this helps.
Thanks for suren's answer.
But i think redis.basic.svc.cluster.local is outside DNS host to match by VirtualService, and VirtualService.host is route to service redis-svc with full namespace path.
Maybe not for that reason.

Cannot reach bind dns in Kubernetes

I am trying to install a DNS Server inside a local Kubernetes cluster using microK8S, but I cannot reach DNS.
Here deployments script:
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: bind
labels:
app: bind
spec:
replicas: 1
selector:
matchLabels:
app: bind
template:
metadata:
labels:
app: bind
spec:
containers:
- name: bind
image: sameersbn/bind
env:
- name: ROOT_PASSWORD
value: "toto"
volumeMounts:
- mountPath: /data
name: data
ports:
- containerPort: 53
protocol: UDP
- containerPort: 53
protocol: TCP
- containerPort: 10000
volumes:
- name: data
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: bind-dns
labels:
name: bind-dns
spec:
type: ClusterIP
ports:
- name: dns
port: 53
targetPort: 53
protocol: UDP
- name: dns-tcp
port: 53
protocol: TCP
targetPort: 53
selector:
name: bind
service is expose with ip
bind-dns LoadBalancer 10.152.183.144 <pending> 53/UDP,53/TCP 11m
When I ssh into bind pod it works
host www.google.com 0.0.0.0
Using domain server:
Name: 0.0.0.0
Address: 0.0.0.0#53
Aliases:
www.google.com has address 172.217.13.132
www.google.com has IPv6 address 2607:f8b0:4020:805::2004
But outside container it does not
host www.google.com 10.152.183.144
;; connection timed out; no servers could be reached
What is wrong ? Why I cannot reach server ?
Service resource spec.selector need to specify pod spec.metadata.labels.
So I think you need to change the Service resource of the yaml file.
apiVersion: v1
kind: Service
metadata:
name: bind-dns
labels:
name: bind-dns
spec:
type: ClusterIP
ports:
- name: dns
port: 53
targetPort: 53
protocol: UDP
- name: dns-tcp
port: 53
protocol: TCP
targetPort: 53
selector:
app: bind # changed

How to expose multiple port using a load balancer services in Kubernetes

I have created a cluster using the google cloud platform (container engine) and deployed a pod using the following YAML file:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: deployment-name
spec:
replicas: 1
template:
metadata:
name: pod-name
labels:
app: app-label
spec:
containers:
- name: container-name
image: gcr.io/project-id/image-name
resources:
requests:
cpu: 1
ports:
- name: port80
containerPort: 80
- name: port443
containerPort: 443
- name: port6001
containerPort: 6001
Then I want to create a service that enables the pod to listen on all these ports. I know that the following YAML file works to create a service that listens on one port:
apiVersion: v1
kind: Service
metadata:
name: service-name
spec:
ports:
- port: 80
targetPort: 80
selector:
app: app-label
type: LoadBalancer
However when I want the pod to listen on multiple ports like this, it doesn't work:
apiVersion: v1
kind: Service
metadata:
name: service-name
spec:
ports:
- port: 80
targetPort: 80
- port: 443
targetPort: 443
- port: 6001
targetPort: 6001
selector:
app: app-label
type: LoadBalancer
How can I make my pod listen to multiple ports?
You have two options:
You could have multiple services, one for each port. As you pointed out, each service will end up with a different IP address
You could have a single service with multiple ports. In this particular case, you must give all ports a name.
In your case, the service becomes:
apiVersion: v1
kind: Service
metadata:
name: service-name
spec:
ports:
- name: http
port: 80
targetPort: 80
- name: https
port: 443
targetPort: 443
- name: something
port: 6001
targetPort: 6001
selector:
app: app-label
type: LoadBalancer
This is necessary so that endpoints can be disambiguated.

How Kubernetes connecting external mysql from fix ip

I know how to create the service abstraction that points to an endpoint to an external database(not within the cluster ip). However, my mysql service (single host mysql) only permits fix ip for access. The obvious reason is security.
So, how can one fix this?
kind: "Service"
apiVersion: "v1"
metadata:
name: "example-external-service"
spec:
ports:
-
name: "mysql"
protocol: "TCP"
port: 3306
targetPort: 3306
nodePort: 0
end point defintion:
kind: "Endpoints"
apiVersion: "v1"
metadata:
name: "example-external-service"
subsets:
- addresses:
- ip: "10.10.1.1"
ports:
- name: "mysql"
port: 3306