HowTo:CS Launch Terminal: Difference between revisions

From Computer Science Wiki
Jump to navigation Jump to search
Carnold (talk | contribs)
No edit summary
Carnold (talk | contribs)
No edit summary
 
(16 intermediate revisions by the same user not shown)
Line 7: Line 7:
* See [[HowTo:CS Launch]] on how to '''create a project and namespace'''
* See [[HowTo:CS Launch]] on how to '''create a project and namespace'''


== Install command line tools ==
== Install Command Line Tools ==
There are two commands used to interact with kubernetes cluster: <code>kubectl</code> and <code>helm</code>.  Both use the same configuration file to access to the cluster.
There are two commands used to interact with kubernetes cluster: <code>kubectl</code> and <code>helm</code>.  Both use the same configuration file to access to the cluster.
* '''Install ''kubectl'' locally''' using instructions at https://kubernetes.io/docs/tasks/tools/  Generally it just involves downloading a binary release and copying the binary somewhere convenient to run.
* '''Install ''kubectl'' locally''' using instructions at https://kubernetes.io/docs/tasks/tools/  Generally it just involves downloading a binary release and copying the binary somewhere convenient to run.
Line 75: Line 75:
     size: 1Gi
     size: 1Gi
</pre>
</pre>
* '''Launch your database''' using your configuration file
<pre>
helm install -f values.yaml -n my-test-namespace mariadb partners/mariadb
</pre>
* You can get a list of deployed applications with the command: <code>helm list -n my-test-namespace</code>
* You can get the status of a deployed application with the command: <code>helm status -n my-test-namespace <NAME></code>
* You can run the mysql command inside of the mariadb deployment with the following commands:
<pre>
DBPASS=$(kubectl get secret --namespace my-test-namespace mariadb -o jsonpath="{.data.mariadb-root-password}" | base64 --decode)
kubectl exec mariadb-0 -n my-test-namespace -it -- mariadb -h mariadb -u root --password=$DBPASS
</pre>
== Launch an App Using a Public Image ==
Next we will launch a web app called ''Adminer'' that will allow us to interact with our running database, and assign it a URL.
* '''Log into your kubectl enabled terminal'''.
* '''Create a new text file''' named <code>test-adminer.yml</code>.  This file will describe your application as code.
* Use the following code:
<pre>
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
  labels:
    deployment: test-adminer
  name: test-adminer
  namespace: my-test-namespace
spec:
  replicas: 1
  selector:
    matchLabels:
      deployment: test-adminer
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        deployment: test-adminer
      namespace: my-test-namespace
    spec:
      containers:
        - env:
            - name: ADMINER_DEFAULT_SERVER
              value: mariadb
          image: adminer:latest
          imagePullPolicy: Always
          name: container-0
          ports:
            - containerPort: 8080
              name: tcp8080
              protocol: TCP
          securityContext:
            allowPrivilegeEscalation: false
            privileged: false
            readOnlyRootFilesystem: false
            runAsNonRoot: false
      restartPolicy: Always
</pre>
* '''Launch your app''' using the following command:
** <code>kubectl apply -f test-adminer.yml</code>
== Create a Cluster Service ==
Creating a ''ClusterIP'' service for your deployment will allow other pods in your namespace to be able to access your deployment through the cluster network.  The name of your service will become the DNS name that other pods use to access, in this example: <code>test-adminer-service</code>.  If you scale your deployment up, then the service will load balance network traffic to all of your pods.  A cluster service is required to map an ingress to your deployment.
* '''Log into your kubectl enabled terminal'''.
* '''Create a new text file''' named <code>test-adminer-service.yml</code>.  This file will describe your service as code.
* Use the following code:
<pre>
apiVersion: v1
kind: Service
metadata:
  name: test-adminer-service
  namespace: my-test-namespace
spec:
  ports:
    - name: tcp8080
      port: 8080
      protocol: TCP
      targetPort: 8080
  selector:
    deployment: test-adminer
  type: ClusterIP
</pre>
* '''Create your service''' using the following command:
** <code>kubectl apply -f test-adminer-service.yml</code>
* You can now access this service from other pods in the same namespace, for example: <code>curl -v http://test-adminer-service:8080</code>
== Create Ingress to Service ==
To expose your cluster service out to the Internet you create an ''Ingress'' that maps a public URL to your existing cluster service.  This example is one just a basic map of an entire URL (path /).  CS launch has a wildcard DNS entry for *.endeavour.cs.vt.edu so you can use any sub domain for your ingress that is not already in use.  This example uses ''test-adminer.endeavour.cs.vt.edu''.  CS launch uses nginx reverse proxy, there lots of ways to customize your ingress.  See: https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/
* '''Log into your kubectl enabled terminal'''.
* '''Create a new text file''' named <code>test-adminer-ingress.yml</code>.  This file will describe your ingress as code.
* Use the following code:
<pre>
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test-adminer-ingress
  namespace: my-test-namespace
spec:
  rules:
    - host: test-adminer.endeavour.cs.vt.edu
      http:
        paths:
          - backend:
              service:
                name: test-adminer-service
                port:
                  number: 8080                                                                                                                         
            path: /                                                                                                                                   
            pathType: Prefix
</pre>
* '''Create your ingress''' using the following command:
** <code>kubectl apply -f test-adminer-ingress.yml</code>
* Once finished initializing, you should be able to access your deployment with the newly mapped URL.
== Create a Custom Web Application ==
You can do more than just launch pre-built docker images on CS Launch. You can create your own custom docker images allowing you to host just about any kind of app on kubernetes. This will walk you through an example of that process.
* '''Create your own docker image''' using the steps from the this guide: [[HowTo:Docker]]
* '''Optional:''' If your docker image is not public, then you will need to import an access token to be able to download and use your custom docker image.
** '''Follow the steps''' for doing this through the web interface at [[HowTo:CS_Launch#Create_a_Custom_Web_Application]]
=== Create a ConfigMap ===
Kubernetes has a special storage option called a ConfigMap. ConfigMaps can be used to create custom config files that can be directly mounted into the Docker image to localize your deployment. For example, use a ConfigMap to create a database configuration file instead of embedding that config inside of the docker image itself. For this example, we will create a config.php ConfigMap file and mount it under the /var/www/html/dbconfig directory inside the running container.
* '''Log into your kubectl enabled terminal'''.
* '''Create a new text file''' named <code>test-chatbot-configmap.yml</code>.  This file will describe your configmap as code.
* Use the following code:
<pre>
apiVersion: v1
data:
  config.php: |-
    <?php
    declare(strict_types=1);
   
    define("HOST", "mariadb");
    define("DB_NAME", "test-db");
    define("DB_USER", "test");
    define("PASS", "Insecure");
   
    $host = HOST;
    $db_name = DB_NAME;
    $dsn = "mysql:host=$host;dbname=$db_name";
    try {
      $db = new PDO ($dsn, DB_USER, PASS);
      $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    } catch (PDOException $e) {
      throw new PDOException($e->getMessage());
    }
kind: ConfigMap
metadata:
  name: test-chatbot-configmap
  namespace: my-test-namespace
</pre>
* '''Create your configmap''' using the following command:
** <code>kubectl apply -f test-chatbot-configmap.yml</code>
=== Create Database Tables ===
Most dynamic web apps will require a database to be created before use.  For our example, you need to import a SQL dump to create tables and data.
* '''Navigate to your Adminer Ingress URL'''
* '''Log in using your database credentials'''
* Download the database dump from https://raw.githubusercontent.com/AaravRajSIngh/Chatbot/main/database.sql
* '''Click on the ''Import'' button''' to the left.
* '''Click on the ''Browse...'' button''' and '''locate the downloaded sql dump'''.
* '''Click on the ''Execute'' button'''.
=== Launch a Custom Application using a ConfigMap ===
* '''Log into your kubectl enabled terminal'''.
* '''Create a new text file''' named <code>test-chatbot.yml</code>.  This file will describe your deployment as code.
* Use the following code:
<pre>
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    deployment: test-chatbot
  name: test-chatbot
  namespace: my-test-namespace
spec:
  replicas: 1
  selector:
    matchLabels:
      deployment: test-chatbot
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        deployment: test-chatbot
      namespace: my-test-namespace
    spec:
      containers:
        - image: container.cs.vt.edu/carnold/chatbot:latest
          imagePullPolicy: Always
          name: container-0
          ports:
            - containerPort: 80
              name: http
              protocol: TCP
          securityContext:
            allowPrivilegeEscalation: false
            privileged: false
            readOnlyRootFilesystem: false
            runAsNonRoot: false
          volumeMounts:
            - mountPath: /var/www/html/dbconfig
              name: dbconfig
      restartPolicy: Always
      volumes:
        - configMap:
            defaultMode: 420
            name: test-chatbot-configmap
          name: dbconfig
</pre>
* '''Launch your application''' using the following command:
** <code>kubectl apply -f test-chatbot.yml</code>
=== Create an Ingress to a Custom Application ===
For this example, I'm going to combine the cluster service specification and ingress service specification into a single file.
* '''Log into your kubectl enabled terminal'''.
* '''Create a new text file''' named <code>test-chatbot-ingress.yml</code>.  This file will describe your ingress as code.
* Use the following code:
<pre>
apiVersion: v1
kind: Service
metadata:
  name: test-chatbot-service
  namespace: my-test-namespace
spec:
  ports:
    - name: tcp80
      port: 80
      protocol: TCP
      targetPort: 80
  selector:
    deployment: test-chatbot
  type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test-chatbot-ingress
  namespace: my-test-namespace
spec:
  rules:
    - host: chatbot.endeavour.cs.vt.edu
      http:
        paths:
          - backend:
              service:
                name: test-chatbot-service
                port:
                  number: 80
            path: /
            pathType: Prefix
</pre>
* '''Create your ingress''' using the following command:
** <code>kubectl apply -f test-chatbot-ingress.yml</code>
* Once created you should have a working URL to your web application.

Latest revision as of 10:20, 29 November 2023

Introduction

This is a companion guide to HowTo:CS Launch. This guide goes through the same steps as the web interface version, but is done through a command line. All operations except project creation and namespace creation can be done using a command line -- reference HowTo:CS Launch for creating a project and namespace. This guide will walk you through the steps via a command line on rlogin.cs.vt.edu and applies to any other workstation you have access to. You will need to use a text editor to create configuration files. For rlogin.cs.vt.edu can use vi, nano, or VS Code to create text files.

  • This guide uses the namespace my-test-namespace You will need to substitute your own namespace name wherever this is used.

Create a Project and Namespace

Install Command Line Tools

There are two commands used to interact with kubernetes cluster: kubectl and helm. Both use the same configuration file to access to the cluster.

  • Install kubectl locally using instructions at https://kubernetes.io/docs/tasks/tools/ Generally it just involves downloading a binary release and copying the binary somewhere convenient to run.
    • Example: Install into your account on rlogin.cs.vt.edu
    • SSH into rlogin.cs.vt.edu
    • Run the following commands:
cd ~/bin
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl
    • kubectl is used to view, edit, and create kubernetes resources
  • Install helm locally using instructions at https://helm.sh/docs/intro/install/ Generally it just involves downloading a binary release and copying the binary somewhere convenient to run.
    • Example: Install into your account on rlogin.cs.vt.edu
    • SSH into rlogin.cs.vt.edu
    • Run the following commands:
cd ~/bin
curl -L https://get.helm.sh/helm-v3.13.1-linux-amd64.tar.gz | tar zx --strip-components 1 linux-amd64/helm

Create Kubernetes Configuration File

The Kubernetes command line tools both use the same configuration file that tells them how to connect to the kubernetes cluster. The CS Launch system makes this easy by giving you a link on the website with the contents of the configuration file.

  • Navigate to your Cluster Dashboard
  • Click on the Copy KubeConfig to Clipboard button in the top right corner. It looks like two squares.
  • Use a text editor to create a file named config
    • The config file needs to be located in your home directory.
    • For Linux or Mac the full path to the file should be ~/.kube/config
    • For Windows the path is %USERPROFILE%\.kube\config
  • Paste the contents into the config file.
  • Example using rlogin.cs.vt.edu:
    • SSH into rlogin.cs.vt.edu
    • Run command: mkdir -p ~/.kube
    • Run command: vi ~/.kube/config
    • Hit the i key to enter insert mode
    • Paste contents of the KubeConfig file
    • Hit the ESC key to exit insert mode
    • Type the following to save the file: :wq<enter>
    • Run command: chmod 600 ~/.kube/config
  • Once you have the configuration file created and in the right place you should be able to run kubectl and access the cluster.
  • Test your cluster access by running the command kubectl get nodes

Launching a Database Using Helm

Kubernetes supports Helm charts to automate deployment of software. There are existing Helm charts for many popular software projects, such as databases. Using a Helm chart can make setting up and updating complex software much easier. This guide will walk you through deploying MariaDB using a Helm chart using a command line terminal. Helm uses repositories to store the charts that you can install. You will need to install a helm repository before you can install a chart.

  • Log into your kubectl enabled terminal.
  • Install the CS Launch Partners repo by running the following commands:
helm repo add partners https://raw.githubusercontent.com/rancher/partner-charts/main-source
helm repo update
helm search repo
  • Make a directory to store your database deployment files
mkdir mariadb-deployment
cd mariadb-deployment
  • Download the deployment Yaml configuration file
helm show values partners/mariadb > values.yaml
  • Use a text editor to edit the values.yaml file
    • Make the following changes to the file:
auth:
  database: test-db
  username: test
  password: Insecure
primary:
  persistence:
    size: 1Gi
  • Launch your database using your configuration file
helm install -f values.yaml -n my-test-namespace mariadb partners/mariadb
  • You can get a list of deployed applications with the command: helm list -n my-test-namespace
  • You can get the status of a deployed application with the command: helm status -n my-test-namespace <NAME>
  • You can run the mysql command inside of the mariadb deployment with the following commands:
DBPASS=$(kubectl get secret --namespace my-test-namespace mariadb -o jsonpath="{.data.mariadb-root-password}" | base64 --decode)
kubectl exec mariadb-0 -n my-test-namespace -it -- mariadb -h mariadb -u root --password=$DBPASS

Launch an App Using a Public Image

Next we will launch a web app called Adminer that will allow us to interact with our running database, and assign it a URL.

  • Log into your kubectl enabled terminal.
  • Create a new text file named test-adminer.yml. This file will describe your application as code.
  • Use the following code:
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
  labels:
    deployment: test-adminer
  name: test-adminer
  namespace: my-test-namespace
spec:
  replicas: 1
  selector:
    matchLabels:
      deployment: test-adminer
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        deployment: test-adminer
      namespace: my-test-namespace
    spec:
      containers:
        - env:
            - name: ADMINER_DEFAULT_SERVER
              value: mariadb
          image: adminer:latest
          imagePullPolicy: Always
          name: container-0
          ports:
            - containerPort: 8080
              name: tcp8080
              protocol: TCP
          securityContext:
            allowPrivilegeEscalation: false
            privileged: false
            readOnlyRootFilesystem: false
            runAsNonRoot: false
      restartPolicy: Always
  • Launch your app using the following command:
    • kubectl apply -f test-adminer.yml

Create a Cluster Service

Creating a ClusterIP service for your deployment will allow other pods in your namespace to be able to access your deployment through the cluster network. The name of your service will become the DNS name that other pods use to access, in this example: test-adminer-service. If you scale your deployment up, then the service will load balance network traffic to all of your pods. A cluster service is required to map an ingress to your deployment.

  • Log into your kubectl enabled terminal.
  • Create a new text file named test-adminer-service.yml. This file will describe your service as code.
  • Use the following code:
apiVersion: v1
kind: Service
metadata:
  name: test-adminer-service
  namespace: my-test-namespace
spec:
  ports:
    - name: tcp8080
      port: 8080
      protocol: TCP
      targetPort: 8080
  selector:
    deployment: test-adminer
  type: ClusterIP
  • Create your service using the following command:
    • kubectl apply -f test-adminer-service.yml
  • You can now access this service from other pods in the same namespace, for example: curl -v http://test-adminer-service:8080

Create Ingress to Service

To expose your cluster service out to the Internet you create an Ingress that maps a public URL to your existing cluster service. This example is one just a basic map of an entire URL (path /). CS launch has a wildcard DNS entry for *.endeavour.cs.vt.edu so you can use any sub domain for your ingress that is not already in use. This example uses test-adminer.endeavour.cs.vt.edu. CS launch uses nginx reverse proxy, there lots of ways to customize your ingress. See: https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/

  • Log into your kubectl enabled terminal.
  • Create a new text file named test-adminer-ingress.yml. This file will describe your ingress as code.
  • Use the following code:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test-adminer-ingress
  namespace: my-test-namespace
spec:
  rules:
    - host: test-adminer.endeavour.cs.vt.edu
      http:
        paths:
          - backend:
              service:
                name: test-adminer-service
                port:
                  number: 8080                                                                                                                          
            path: /                                                                                                                                     
            pathType: Prefix
  • Create your ingress using the following command:
    • kubectl apply -f test-adminer-ingress.yml
  • Once finished initializing, you should be able to access your deployment with the newly mapped URL.

Create a Custom Web Application

You can do more than just launch pre-built docker images on CS Launch. You can create your own custom docker images allowing you to host just about any kind of app on kubernetes. This will walk you through an example of that process.

  • Create your own docker image using the steps from the this guide: HowTo:Docker
  • Optional: If your docker image is not public, then you will need to import an access token to be able to download and use your custom docker image.

Create a ConfigMap

Kubernetes has a special storage option called a ConfigMap. ConfigMaps can be used to create custom config files that can be directly mounted into the Docker image to localize your deployment. For example, use a ConfigMap to create a database configuration file instead of embedding that config inside of the docker image itself. For this example, we will create a config.php ConfigMap file and mount it under the /var/www/html/dbconfig directory inside the running container.

  • Log into your kubectl enabled terminal.
  • Create a new text file named test-chatbot-configmap.yml. This file will describe your configmap as code.
  • Use the following code:
apiVersion: v1
data:
  config.php: |-
    <?php
    declare(strict_types=1);
    
    define("HOST", "mariadb");
    define("DB_NAME", "test-db");
    define("DB_USER", "test");
    define("PASS", "Insecure");
    
    $host = HOST;
    $db_name = DB_NAME;
    $dsn = "mysql:host=$host;dbname=$db_name";
    try {
      $db = new PDO ($dsn, DB_USER, PASS);
      $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    } catch (PDOException $e) {
      throw new PDOException($e->getMessage());
    }
kind: ConfigMap
metadata:
  name: test-chatbot-configmap
  namespace: my-test-namespace
  • Create your configmap using the following command:
    • kubectl apply -f test-chatbot-configmap.yml

Create Database Tables

Most dynamic web apps will require a database to be created before use. For our example, you need to import a SQL dump to create tables and data.

Launch a Custom Application using a ConfigMap

  • Log into your kubectl enabled terminal.
  • Create a new text file named test-chatbot.yml. This file will describe your deployment as code.
  • Use the following code:
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    deployment: test-chatbot
  name: test-chatbot
  namespace: my-test-namespace
spec:
  replicas: 1
  selector:
    matchLabels:
      deployment: test-chatbot
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        deployment: test-chatbot
      namespace: my-test-namespace
    spec:
      containers:
        - image: container.cs.vt.edu/carnold/chatbot:latest
          imagePullPolicy: Always
          name: container-0
          ports:
            - containerPort: 80
              name: http
              protocol: TCP
          securityContext:
            allowPrivilegeEscalation: false
            privileged: false
            readOnlyRootFilesystem: false
            runAsNonRoot: false
          volumeMounts:
            - mountPath: /var/www/html/dbconfig
              name: dbconfig
      restartPolicy: Always
      volumes:
        - configMap:
            defaultMode: 420
            name: test-chatbot-configmap
          name: dbconfig
  • Launch your application using the following command:
    • kubectl apply -f test-chatbot.yml

Create an Ingress to a Custom Application

For this example, I'm going to combine the cluster service specification and ingress service specification into a single file.

  • Log into your kubectl enabled terminal.
  • Create a new text file named test-chatbot-ingress.yml. This file will describe your ingress as code.
  • Use the following code:
apiVersion: v1
kind: Service
metadata:
  name: test-chatbot-service
  namespace: my-test-namespace
spec:
  ports:
    - name: tcp80
      port: 80
      protocol: TCP
      targetPort: 80
  selector:
    deployment: test-chatbot
  type: ClusterIP

---

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test-chatbot-ingress
  namespace: my-test-namespace
spec:
  rules:
    - host: chatbot.endeavour.cs.vt.edu
      http:
        paths:
          - backend:
              service:
                name: test-chatbot-service
                port:
                  number: 80
            path: /
            pathType: Prefix
  • Create your ingress using the following command:
    • kubectl apply -f test-chatbot-ingress.yml
  • Once created you should have a working URL to your web application.