HowTo:CS Launch Terminal: Difference between revisions
No edit summary |
|||
(13 intermediate revisions by the same user not shown) | |||
Line 86: | Line 86: | ||
kubectl exec mariadb-0 -n my-test-namespace -it -- mariadb -h mariadb -u root --password=$DBPASS | kubectl exec mariadb-0 -n my-test-namespace -it -- mariadb -h mariadb -u root --password=$DBPASS | ||
</pre> | </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
- This step must be done in the web interface at https://launch.cs.vt.edu
- See HowTo:CS Launch on how to 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.
- 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
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.
- 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
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.