- Create a deployment named
myapp
that creates 2 replicas for Pods with the imagenginx
. Expose the container port 80. - Expose the Pods so that requests can be made against the service from inside of the cluster.
- Create a temporary Pods using the image
busybox
and run awget
command against the IP of the service. - Change the service type so that the Pods can be reached from outside of the cluster.
- Run a
wget
command against the service from outside of the cluster. - (Optional) Can you expose the Pods as a service without a deployment?
Show Solution
Create a deployment with 2 replicas first. You should end up with one deployment and two Pods.
$ kubectl run myapp --image=nginx --restart=Always --replicas=2 --port=80
deployment.apps/myapp created
$ kubectl get deployments,pods
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
deployment.extensions/myapp 2 2 2 2 59s
NAME READY STATUS RESTARTS AGE
pod/myapp-7bc568bfdd-972wg 1/1 Running 0 59s
pod/myapp-7bc568bfdd-l5nmz 1/1 Running 0 59s
Expose the service with the type ClusterIP
and the target port 80.
$ kubectl expose deploy myapp --target-port=80
service/myapp exposed
$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
myapp ClusterIP 10.108.88.208 <none> 80/TCP 15s
Determine the cluster IP and use it for the wget
command.
$ kubectl run tmp --image=busybox --restart=Never -it --rm -- wget -O- 10.108.88.208:80
Connecting to 10.108.88.208:80 (10.108.88.208:80)
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
- 100% |********************************| 612 0:00:00 ETA
pod "tmp" deleted
Turn the type of the service into NodePort
to expose it outside of the cluster. Now, the service should expose a port in the 30000 range.
$ kubectl edit service myapp
...
spec:
type: NodePort
...
kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
myapp NodePort 10.108.88.208 <none> 80:30441/TCP 3m
Run a wget
or curl
command against the service using port 30441
. On Docker for Windows/Mac you may have to use localhost or 127.0.0.1 (see issue).
$ wget -O- localhost:30441
--2019-05-10 16:32:35-- http://localhost:30441/
Resolving localhost (localhost)... ::1, 127.0.0.1
Connecting to localhost (localhost)|::1|:30441... connected.
HTTP request sent, awaiting response... 200 OK
Length: 612 [text/html]
Saving to: ‘STDOUT’
- 0%[ ] 0 --.-KB/s <!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
- 100%[==================================================================================>] 612 --.-KB/s in 0s
2019-05-10 16:32:35 (24.3 MB/s) - written to stdout [612/612]
Let's assume we are working on an application stack that defines three different layers: a frontend, a backend and a database. Each of the layers runs in a Pod. You can find the definition in the YAML file app-stack.yaml
. The application needs to run in the namespace app-stack
.
kind: Pod
apiVersion: v1
metadata:
name: frontend
namespace: app-stack
labels:
app: todo
tier: frontend
spec:
containers:
- name: frontend
image: nginx
---
kind: Pod
apiVersion: v1
metadata:
name: backend
namespace: app-stack
labels:
app: todo
tier: backend
spec:
containers:
- name: backend
image: nginx
---
kind: Pod
apiVersion: v1
metadata:
name: database
namespace: app-stack
labels:
app: todo
tier: database
spec:
containers:
- name: database
image: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: example
- Create the required namespace.
- Copy the Pod definition to the file
app-stack.yaml
and create all three Pods. Notice that the namespace has already been defined in the YAML definition. - Create a network policy in the YAML file
app-stack-network-policy.yaml
. - The network policy should allow incoming traffic from the backend to the database but disallow incoming traffic from the frontend.
- Incoming traffic to the database should only be allowed on TCP port 3306 and no other port.
Show Solution
Create the namespace
$ kubectl create namespace app-stack
namespace/app-stack created
$ vim app-stack.yaml
$ kubectl create -f app-stack.yaml
pod/frontend created
pod/backend created
pod/database created
$ kubectl get pods --namespace app-stack
NAME READY STATUS RESTARTS AGE
backend 1/1 Running 0 22s
database 1/1 Running 0 22s
frontend 1/1 Running 0 22s
The following definition ensure that all rules are fulfilled.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: app-stack-network-policy
namespace: app-stack
spec:
podSelector:
matchLabels:
app: todo
tier: database
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: todo
tier: backend
ports:
- protocol: TCP
port: 3306
Create the network policy.
$ vim app-stack-network-policy.yaml
$ kubectl create -f app-stack-network-policy.yaml
$ kubectl get networkpolicy --namespace app-stack
NAME POD-SELECTOR AGE
app-stack-network-policy app=todo,tier=database 5s