카타코더 k8s - Deploying from source onto Kubernetes

1 개요[ | ]

카타코더 Kubernetes - Deploying from source onto Kubernetes
카타코더 Kubernetes - Deploying a service from source onto Kubernetes
카타코더 Kubernetes
# 🔗 제목
카타코더 Kubernetes/2 e
🡵 카타코더 k8s - Use Kubernetes To Manage Secrets And Passwords
🡵 카타코더 k8s - Deploy Docker Compose Files with Kompose
🡵 카타코더 k8s - Deploying from source onto Kubernetes
🡵 카타코더 k8s - Backup and Restore with Heptio Ark
🡵 카타코더 k8s - Helm Package Manager
🡵 카타코더 k8s - Installing Weave Scope on Kubernetes
🡵 카타코더 k8s - Getting Started with Kubeless

2 The container[ | ]

root@localhost:~# cd hello-webapp
root@localhost:~/hello-webapp# ll
total 56
drwxr-xr-x 4 root      root       4096 Mar 23 18:38 ./
drwxr-xr-x 1 scrapbook scrapbook  4096 Mar 23 18:38 ../
drwxr-xr-x 8 root      root       4096 Mar 23 18:38 .git/
-rw-r--r-- 1 root      root        212 Mar 23 18:38 Dockerfile
-rw-r--r-- 1 root      root      11357 Mar 23 18:38 LICENSE
-rw-r--r-- 1 root      root         51 Mar 23 18:38 README.md
-rwxr-xr-x 1 root      root       1041 Mar 23 18:38 app.py*
-rw-r--r-- 1 root      root        973 Mar 23 18:38 deployment.yaml
drwxr-xr-x 2 root      root       4096 Mar 23 18:38 k8s/
-rw-r--r-- 1 root      root         15 Mar 23 18:38 requirements.txt
-rw-r--r-- 1 root      root        584 Mar 23 18:38 service.yaml
-rw-r--r-- 1 root      root         37 Mar 23 18:38 uuid.txt
root@localhost:~/hello-webapp# cat Dockerfile
# Run server
FROM alpine:3.5
RUN apk add --no-cache python py2-pip py2-gevent
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . /app
WORKDIR /app
EXPOSE 8080
ENTRYPOINT ["python"]
CMD ["app.py"]
root@localhost:~/hello-webapp# docker build -t hello-webapp:v1 .
Sending build context to Docker daemon  135.7kB
Step 1/9 : FROM alpine:3.5
3.5: Pulling from library/alpine
8cae0e1ac61c: Pull complete
Digest: sha256:66952b313e51c3bd1987d7c4ddf5dba9bc0fb6e524eed2448fa660246b3e76ec
Status: Downloaded newer image for alpine:3.5
 ---> f80194ae2e0c
Step 2/9 : RUN apk add --no-cache python py2-pip py2-gevent
 ---> Running in a9daa6294c8b
fetch http://dl-cdn.alpinelinux.org/alpine/v3.5/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.5/community/x86_64/APKINDEX.tar.gz
(1/14) Installing libbz2 (1.0.6-r5)
(2/14) Installing expat (2.2.0-r1)
(3/14) Installing libffi (3.2.1-r2)
(4/14) Installing gdbm (1.12-r0)
(5/14) Installing ncurses-terminfo-base (6.0_p20171125-r1)
(6/14) Installing ncurses-terminfo (6.0_p20171125-r1)
(7/14) Installing ncurses-libs (6.0_p20171125-r1)
(8/14) Installing readline (6.3.008-r4)
(9/14) Installing sqlite-libs (3.15.2-r2)
(10/14) Installing python2 (2.7.15-r0)
(11/14) Installing py2-greenlet (0.4.10-r3)
(12/14) Installing py2-gevent (1.1.2-r0)
(13/14) Installing py-setuptools (29.0.1-r0)
(14/14) Installing py2-pip (9.0.0-r1)
Executing busybox-1.25.1-r2.trigger
OK: 63 MiB in 25 packages
 ---> 9050e6043029
Removing intermediate container a9daa6294c8b
Step 3/9 : COPY requirements.txt .
 ---> 5d8708842ec1
Removing intermediate container ffd7e3052509
Step 4/9 : RUN pip install -r requirements.txt
 ---> Running in 7cde2fe6990c
Collecting flask (from -r requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/7f/e7/08578774ed4536d3242b14dacb4696386634607af824ea997202cd0edb4b/Flask-1.0.2-py2.py3-none-any.whl (91kB)
Collecting requests (from -r requirements.txt (line 2))
  Downloading https://files.pythonhosted.org/packages/7d/e3/20f3d364d6c8e5d2353c72a67778eb189176f08e873c9900e10c0287b84b/requests-2.21.0-py2.py3-none-any.whl (57kB)
Collecting itsdangerous>=0.24 (from flask->-r requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/76/ae/44b03b253d6fade317f32c24d100b3b35c2239807046a4c953c7b89fa49e/itsdangerous-1.1.0-py2.py3-none-any.whl
Collecting Jinja2>=2.10 (from flask->-r requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/7f/ff/ae64bacdfc95f27a016a7bed8e8686763ba4d277a78ca76f32659220a731/Jinja2-2.10-py2.py3-none-any.whl (126kB)
Collecting Werkzeug>=0.14 (from flask->-r requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/24/4d/2fc4e872fbaaf44cc3fd5a9cd42fda7e57c031f08e28c9f35689e8b43198/Werkzeug-0.15.1-py2.py3-none-any.whl (328kB)
Collecting click>=5.1 (from flask->-r requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/fa/37/45185cb5abbc30d7257104c434fe0b07e5a195a6847506c074527aa599ec/Click-7.0-py2.py3-none-any.whl (81kB)
Collecting chardet<3.1.0,>=3.0.2 (from requests->-r requirements.txt (line 2))
  Downloading https://files.pythonhosted.org/packages/bc/a9/01ffebfb562e4274b6487b4bb1ddec7ca55ec7510b22e4c51f14098443b8/chardet-3.0.4-py2.py3-none-any.whl (133kB)
Collecting idna<2.9,>=2.5 (from requests->-r requirements.txt (line 2))
  Downloading https://files.pythonhosted.org/packages/14/2c/cd551d81dbe15200be1cf41cd03869a46fe7226e7450af7a6545bfc474c9/idna-2.8-py2.py3-none-any.whl (58kB)
Collecting certifi>=2017.4.17 (from requests->-r requirements.txt (line 2))
  Downloading https://files.pythonhosted.org/packages/60/75/f692a584e85b7eaba0e03827b3d51f45f571c2e793dd731e598828d380aa/certifi-2019.3.9-py2.py3-none-any.whl (158kB)
Collecting urllib3<1.25,>=1.21.1 (from requests->-r requirements.txt (line 2))
  Downloading https://files.pythonhosted.org/packages/62/00/ee1d7de624db8ba7090d1226aebefab96a2c71cd5cfa7629d6ad3f61b79e/urllib3-1.24.1-py2.py3-none-any.whl (118kB)
Collecting MarkupSafe>=0.23 (from Jinja2>=2.10->flask->-r requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/b9/2e/64db92e53b86efccfaea71321f597fa2e1b2bd3853d8ce658568f7a13094/MarkupSafe-1.1.1.tar.gz
Installing collected packages: itsdangerous, MarkupSafe, Jinja2, Werkzeug, click, flask, chardet, idna, certifi, urllib3, requests
  Running setup.py install for MarkupSafe: started
    Running setup.py install for MarkupSafe: finished with status 'done'
Successfully installed Jinja2-2.10 MarkupSafe-1.1.1 Werkzeug-0.15.1 certifi-2019.3.9 chardet-3.0.4 click-7.0 flask-1.0.2 idna-2.8 itsdangerous-1.1.0 requests-2.21.0 urllib3-1.24.1
You are using pip version 9.0.0, however version 19.0.3 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
 ---> 5fd45947e416
Removing intermediate container 7cde2fe6990c
Step 5/9 : COPY . /app
 ---> 3e724f3f4dc9
Removing intermediate container 10a8fc8c0e29
Step 6/9 : WORKDIR /app
 ---> c5640d061a99
Removing intermediate container 0a1f75c4bff7
Step 7/9 : EXPOSE 8080
 ---> Running in 747f30f63e21
 ---> ae088dc7d409
Removing intermediate container 747f30f63e21
Step 8/9 : ENTRYPOINT python
 ---> Running in 3dd926bb05b9
 ---> da40e9e9382b
Removing intermediate container 3dd926bb05b9
Step 9/9 : CMD app.py
 ---> Running in 78d7432957a0
 ---> e260ba2f8bea
Removing intermediate container 78d7432957a0
Successfully built e260ba2f8bea

3 Running your containerized service[ | ]

root@localhost:~/hello-webapp# docker run -d -p 80:8080 hello-webapp:v1
7120a0ac319dde04b02f1d135540c7735aea57dee42b8b0eaaf52190ffc03d1e
root@localhost:~/hello-webapp# curl host01
Hello World! (up 0:00:14)

4 Kubernetes and manifests[ | ]

root@localhost:~/hello-webapp# cat deployment.yaml
---
apiVersion: v1
kind: Service
metadata:
  name: hello-webapp
spec:
  selector:
    app: hello-webapp

  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
  type: NodePort

---
apiVersion: extensions/v1beta1
kind: Deployment
metadata: {name: hello-webapp}
spec:
  replicas: 1
  selector:
    matchLabels:
      app: hello-webapp
      track: stable
  strategy:
    rollingUpdate: {maxSurge: 1, maxUnavailable: 0}
    type: RollingUpdate
  revisionHistoryLimit: 1
  template:
    metadata:
      labels:
        app: hello-webapp
        track: stable
      name: hello-webapp
    spec:
      containers:
      - image: IMAGE_URL
        imagePullPolicy: IfNotPresent
        name: hello-webapp
        resources:
          limits:
            memory: 0.25G
            cpu: 0.25
        terminationMessagePath: /dev/termination-log
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      securityContext: {}
      terminationGracePeriodSeconds: 30

5 The Container Registry[ | ]

root@localhost:~/hello-webapp# export REGISTRY=2886795306-5000-frugo01.environments.katacoda.com
root@localhost:~/hello-webapp# docker tag hello-webapp:v1 $REGISTRY/hello-webapp:v1
root@localhost:~/hello-webapp# docker push $REGISTRY/hello-webapp:v1
The push refers to a repository [2886795306-5000-frugo01.environments.katacoda.com/hello-webapp]
2c75e9d276e6: Pushed
92e9d4f40d31: Pushed
3c00a647a4a2: Pushed
27f35e33a10a: Pushed
f566c57e6f2d: Pushed
v1: digest: sha256:fd2c3e56bb547077ce21811b8140aa5bfd7b5861b1c6b448ee18de501ef7a55d size: 1367

6 Running the service in Kubernetes[ | ]

root@localhost:~/hello-webapp# cat deployment.yaml | grep image:
      - image: IMAGE_URL
root@localhost:~/hello-webapp# sed -i -e 's@IMAGE_URL@'"$REGISTRY/hello-webapp:v1"'@' deployment.yaml
root@localhost:~/hello-webapp# cat deployment.yaml | grep image:
      - image: 2886795306-5000-frugo01.environments.katacoda.com/hello-webapp:v1
root@localhost:~/hello-webapp# scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no root@host01:/root/.kube/config ~/.kube/
Warning: Permanently added 'host01,172.17.0.42' (ECDSA) to the list of known hosts.
config                                                                        100% 5451     5.3KB/s   00:00
root@localhost:~/hello-webapp# kubectl apply -f deployment.yaml
service "hello-webapp" created
deployment "hello-webapp" created
root@localhost:~/hello-webapp# kubectl get services
NAME           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
hello-webapp   NodePort    10.109.23.253   <none>        80:31178/TCP   13s
kubernetes     ClusterIP   10.96.0.1       <none>        443/TCP        11m
root@localhost:~/hello-webapp# kubectl get pods
NAME                            READY     STATUS    RESTARTS   AGE
hello-webapp-7bc668bc9d-bxbdz   1/1       Running   0          28s
root@localhost:~/hello-webapp# export PORT=$(kubectl get svc hello-webapp -o go-template='{{range.spec.ports}}{{if .nodePort}}{{.nodePort}}{{"\n"}}{{end}}{{end}}')
root@localhost:~/hello-webapp# echo $PORT
31178
root@localhost:~/hello-webapp# curl host01:$PORT
Hello World! (up 0:01:21)

7 Automating the deployment process[ | ]

root@localhost:~/hello-webapp# cat app.py | grep 'def root():' -A2
def root():
    update()
    return "Hello World! (up %s)\n" % elapsed()
root@localhost:~/hello-webapp# sed -i -e 's/Hello World!/Hello Hacker News!!!/' app.py
root@localhost:~/hello-webapp# cat app.py | grep 'def root():' -A2
def root():
    update()
    return "Hello Hacker News!!! (up %s)\n" % elapsed()
root@localhost:~/hello-webapp# forge setup
║ == Checking Kubernetes Setup ==

║ kubectl version --short
║ Client Version: v1.9.0
║ Server Version: v1.11.3
║ 1 tasks run, 0 errors
║ kubectl get service kubernetes --namespace default
║ NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
║ kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   15m
║ 1 tasks run, 0 errors

║ == Setting up Docker ==

║ Registry type (one of ecr, gcr, generic)[generic]:
║ Docker registry url[registry.hub.docker.com]: 2886795306-5000-frugo01.environments.katacoda.com
║ Docker user (use "-" to leave unspecified): root
║ Docker password:
║ Docker namespace/organization (enter username again for standard accounts): root

║ registry: {type: docker, url: 2886795306-5000-frugo01.environments.katacoda.com, user: root,
║   password: 'cm9vdA==

║     ', namespace: root}

║ docker login -u root -p <ELIDED> 2886795306-5000-frugo01.environments.katacoda.com
║ WARNING! Using --password via the CLI is insecure. Use --password-stdin.
║ Login Succeeded
║ docker pull registry.hub.docker.com/datawire/forge-setup-test-katacoda:1
║ 1: Pulling from datawire/forge-setup-test-katacoda
║ cfc728c1c558: Pulling fs layer
║ cfc728c1c558: Verifying Checksum
║ cfc728c1c558: Download complete
║ cfc728c1c558: Pull complete
║ Digest: sha256:c0537ff6a5218ef531ece93d4984efc99bbf3f7497c0a7726c88e2bb7584dc96
║ Status: Downloaded newer image for registry.hub.docker.com/datawire/forge-setup-test-katacoda:1
║ docker tag registry.hub.docker.com/datawire/forge-setup-test-katacoda:1 2886795306-5000-frugo01.environments.katacoda.com/root/forge_test:dummy
║ docker push 2886795306-5000-frugo01.environments.katacoda.com/root/forge_test:dummy
║ The push refers to a repository [2886795306-5000-frugo01.environments.katacoda.com/root/forge_test]
║ e154057080f4: Preparing
║ e154057080f4: Pushed
║ dummy: digest: sha256:1a026b5d417142bfdc4f7733c13eda746a29192a6115d4d27c54ed2908a1ffec size: 528
║ GET https://2886795306-5000-frugo01.environments.katacoda.com/v2/root/forge_test/manifests/dummy
║ 16 tasks run, 0 errors

║ == Writing config to forge.yaml ==

║ # Global forge configuration
║ # DO NOT CHECK INTO GITHUB, THIS FILE CONTAINS SECRETS
║ registry:
║   type: docker
║   url: 2886795306-5000-frugo01.environments.katacoda.com
║   user: root
║   password: 'cm9vdA==

║     '
║   namespace: root

║ == Done ==
root@localhost:~/hello-webapp# forge deploy
║ docker build /home/scrapbook/hello-webapp/ -f /home/scrapbook/hello-webapp/Dockerfile -t 2886795306-5000-frugo01.environments.katacoda.com/root/hello-webapp:88360648d9e1c4c9853282a646e906efa38d9f0a.sha
║ Sending build context to Docker daemon  137.2kB
║ Step 1/9 : FROM alpine:3.5
║  ---> f80194ae2e0c
║ Step 2/9 : RUN apk add --no-cache python py2-pip py2-gevent
║  ---> Using cache
║  ---> 9050e6043029
║ Step 3/9 : COPY requirements.txt .
║  ---> Using cache
║  ---> 5d8708842ec1
║ Step 4/9 : RUN pip install -r requirements.txt
║  ---> Using cache
║  ---> 5fd45947e416
║ Step 5/9 : COPY . /app
║  ---> fc13b36c95ea
║ Removing intermediate container 35ddb416898c
║ Step 6/9 : WORKDIR /app
║  ---> e0958d10219b
║ Removing intermediate container 87e15022ec4d
║ Step 7/9 : EXPOSE 8080
║  ---> Running in a7c62261af8a
║  ---> d54eb15fe4cc
║ Removing intermediate container a7c62261af8a
║ Step 8/9 : ENTRYPOINT python
║  ---> Running in 131aa262fcdc
║  ---> aedf91b5a5cd
║ Removing intermediate container 131aa262fcdc
║ Step 9/9 : CMD app.py
║  ---> Running in c74bf832ce0b
║  ---> 07cc3a64ff34
║ Removing intermediate container c74bf832ce0b
║ Successfully built 07cc3a64ff34
║ docker push 2886795306-5000-frugo01.environments.katacoda.com/root/hello-webapp:88360648d9e1c4c9853282a646e906efa38d9f0a.sha
║ The push refers to a repository [2886795306-5000-frugo01.environments.katacoda.com/root/hello-webapp]
║ 399642e252e2: Preparing
║ 92e9d4f40d31: Preparing
║ 3c00a647a4a2: Preparing
║ 27f35e33a10a: Preparing
║ f566c57e6f2d: Preparing
║ 92e9d4f40d31: Mounted from hello-webapp
║ 3c00a647a4a2: Mounted from hello-webapp
║ 27f35e33a10a: Mounted from hello-webapp
║ f566c57e6f2d: Mounted from hello-webapp
║ 399642e252e2: Pushed
║ 88360648d9e1c4c9853282a646e906efa38d9f0a.sha: digest: sha256:ee959469b88178096472247a0633d19c7da01ea674556fa8cf0a2f99f42d70b5 size: 1367
║ warning: 'collections.OrderedDict object' has no attribute 'track' (this will become an error soon)
║ warning: 'collections.OrderedDict object' has no attribute 'protocol' (this will become an error soon)
║ warning: 'collections.OrderedDict object' has no attribute 'port' (this will become an error soon)
║ 48 tasks run, 0 errors

║    built: Dockerfile
║   pushed: hello-webapp:88360648d9e1c4c9853282a646e906efa38d9f0a.sha
║ rendered: service/hello-webapp, deployment/hello-webapp
║ deployed: hello-webapp
root@localhost:~/hello-webapp# kubectl get pods
NAME                            READY     STATUS        RESTARTS   AGE
hello-webapp-7bc668bc9d-bxbdz   1/1       Terminating   0          5m
hello-webapp-d7db857f9-g6tgb    1/1       Running       0          32s
root@localhost:~/hello-webapp# kubectl get pods
NAME                           READY     STATUS    RESTARTS   AGE
hello-webapp-d7db857f9-g6tgb   1/1       Running   0          33s
root@localhost:~/hello-webapp# export PORT=$(kubectl get svc hello-webapp -o go-template='{{range.spec.ports}}{{if .nodePort}}{{.nodePort}}{{"\n"}}{{end}}{{end}}')
root@localhost:~/hello-webapp# echo $PORT
31178
root@localhost:~/hello-webapp# curl host01:$PORT
Hello Hacker News!!! (up 0:01:07)
문서 댓글 ({{ doc_comments.length }})
{{ comment.name }} {{ comment.created | snstime }}