Compare commits
21 Commits
80d9f9afb7
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3727f4d8a0 | ||
|
|
ac8d0089dc | ||
|
|
25732c5738 | ||
|
|
204eb9b519 | ||
|
|
cea9007bb3 | ||
|
|
4ae5f972a7 | ||
|
|
f6c7af8155 | ||
|
|
5691e32226 | ||
|
|
3b23929f03 | ||
|
|
4b59d7bcf6 | ||
|
|
ae7927f29c | ||
|
|
10d5ad7ead | ||
|
|
0a91c7b40a | ||
|
|
3dbfd03caa | ||
|
|
b47777a7a6 | ||
|
|
9713e6163c | ||
|
|
a0d01b39b2 | ||
|
|
13c526337a | ||
|
|
27cbed1241 | ||
|
|
0af85bfc0b | ||
|
|
80bf8ecedb |
@@ -9,6 +9,13 @@ Ask your teacher for the IP address of the machine:
|
||||
ssh root@ip_address
|
||||
```
|
||||
|
||||
## Change the password
|
||||
Now that you are connected to your server, change the password:
|
||||
|
||||
```
|
||||
passwd
|
||||
```
|
||||
|
||||
## Host and Demo
|
||||
You are currently connected to a server which have docker installed.
|
||||
We will call this server: `localhost`.
|
||||
|
||||
@@ -33,7 +33,7 @@ Finally, we tell ansible to use `python3` interpreter (default is `python`, but
|
||||
### Check if running
|
||||
Try to connect on your demo machine, to see if it's running:
|
||||
```
|
||||
ssh -p 2222 root@127.0.0.2
|
||||
ssh -p 2222 root@127.0.0.2 'echo "coucou from $(hostname)"'
|
||||
```
|
||||
|
||||
### ping
|
||||
|
||||
@@ -261,7 +261,7 @@
|
||||
<section>
|
||||
<h3>Virtualisation dans le cloud</h3>
|
||||
<p>Le cloud computing repose souvent sur la virtualisation.</p>
|
||||
<p>Le plus souvent en se basant sur l'hyperviseur Open Source <span style="color: orange">QEMU/KVM</span></p>
|
||||
<p>Le plus souvent en se basant sur l'hyperviseur Open Source <img src="qemu.png" alt="QEMU" style="margin: 0px"/> / <img src="kvm.png" alt="KVM" style="margin: 0px"/></p>
|
||||
</section>
|
||||
<section>
|
||||
<h3>Stockage dans le cloud</h3>
|
||||
@@ -427,7 +427,7 @@
|
||||
|
||||
La complexité réside dans la configuration et l'imbrication des différents éléments entre eux.
|
||||
|
||||
Beaucoup d'options sont possibles et nécessite une forte expertise.
|
||||
Beaucoup d'options sont possibles et nécessitent une forte expertise.
|
||||
</section>
|
||||
<section data-markdown>
|
||||
### Utilisation d'OpenStack
|
||||
|
||||
BIN
cloud/slides/kvm.png
Normal file
BIN
cloud/slides/kvm.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.1 KiB |
BIN
cloud/slides/qemu.png
Normal file
BIN
cloud/slides/qemu.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.3 KiB |
1
cloud/training/.gitignore
vendored
Normal file
1
cloud/training/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
user-data-install-demo-flask.sh
|
||||
@@ -13,6 +13,8 @@
|
||||
* [Boot](#boot-1)
|
||||
* [Floating IP](#floating-ip)
|
||||
* [Connect with ssh](#connect-with-ssh-1)
|
||||
* [Userdata](#userdata)
|
||||
* [Demo Flask](#demo-flask)
|
||||
* [Bonus](#bonus)
|
||||
|
||||
|
||||
@@ -292,11 +294,37 @@ ssh debian@xxx.yyy.zzz.aaa # floating ip
|
||||
|
||||
Q: what IP can you see on ens3 interface of the instance?
|
||||
|
||||
## Userdata
|
||||
|
||||
### Create a script
|
||||
Create a file named `postinstall.sh` with this content:
|
||||
```
|
||||
#!/bin/bash
|
||||
|
||||
echo "Hello from my instance" > /var/log/postinstall.log
|
||||
```
|
||||
|
||||
### Start an instance
|
||||
Figure out the command to start a new instance with this script as `user-data`.
|
||||
|
||||
Don't forget to start with your `keypair` so you can connect to it later
|
||||
|
||||
### Check the result
|
||||
When the instance is booted, ssh into it and check the result of the file:
|
||||
|
||||
```
|
||||
cat /var/log/postinstall.log
|
||||
```
|
||||
|
||||
Q: what is the name of the service running inside your instance that execute this `user-data` script?
|
||||
|
||||
Q: from which url this service retrieve the script?
|
||||
|
||||
## demo-flask
|
||||
|
||||
Try to deploy `demo-flask` with a custom `user-data` script.
|
||||
|
||||
|
||||
## Bonus
|
||||
|
||||
Try to deploy `demo-flask` with cloud-init
|
||||
|
||||
|
||||
## Bonus 2
|
||||
|
||||
Take a look at the [skyline WebUI](http://skyline.54.36.119.253.xip.opensteak.fr) and try to boot another instance from there.
|
||||
Take a look at the [skyline WebUI](http://skyline.51.89.228.117.xip.opensteak.fr) and try to boot another instance from there.
|
||||
|
||||
5
cloud/training/cipher.sh
Executable file
5
cloud/training/cipher.sh
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
f=user-data-install-demo-flask.sh
|
||||
echo "Ciphering $f"
|
||||
cat $f | gpg -e -r arnaud@mailops.fr -r arnaud.choupinette@mailops.fr -r arnaud.morin@gmail.com > $f.gpg
|
||||
6
cloud/training/uncipher.sh
Executable file
6
cloud/training/uncipher.sh
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
f=user-data-install-demo-flask.sh.gpg
|
||||
echo "Unciphering $f"
|
||||
n=${f%.gpg}
|
||||
cat $f | gpg -d > $n
|
||||
BIN
cloud/training/user-data-install-demo-flask.sh.gpg
Normal file
BIN
cloud/training/user-data-install-demo-flask.sh.gpg
Normal file
Binary file not shown.
BIN
docker/slides/slides.pdf
Normal file
BIN
docker/slides/slides.pdf
Normal file
Binary file not shown.
@@ -1,3 +1,11 @@
|
||||
# Cleanup your isen
|
||||
If necessary, cleanup your `isen` from previous `ansible` TP results:
|
||||
|
||||
```bash
|
||||
apt-get purge -y nginx
|
||||
docker stop demo
|
||||
```
|
||||
|
||||
# Start the TP
|
||||
|
||||
```bash
|
||||
|
||||
38
index.html
38
index.html
@@ -12,38 +12,58 @@
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>DevOps</h1>
|
||||
<p><a class="btn btn-primary btn-lg" href='https://www.arnaudmorin.fr/trainings/devops/slides/' target='_blank'>Cours</a></p>
|
||||
<p>
|
||||
<a class="btn btn-primary btn-lg" href='https://www.arnaudmorin.fr/trainings/devops/slides/' target='_blank'>Cours</a>
|
||||
<a class="btn btn-primary btn-lg" href='https://www.arnaudmorin.fr/trainings/devops/slides/slides.pdf' target='_blank'>Cours pdf</a>
|
||||
</p>
|
||||
|
||||
<h1>Ansible</h1>
|
||||
<p><a class="btn btn-primary btn-lg" href='https://www.arnaudmorin.fr/trainings/ansible/slides/' target='_blank'>Cours</a></p>
|
||||
<p>
|
||||
<a class="btn btn-primary btn-lg" href='https://www.arnaudmorin.fr/trainings/ansible/slides/' target='_blank'>Cours</a>
|
||||
<a class="btn btn-primary btn-lg" href='https://www.arnaudmorin.fr/trainings/ansible/slides/slides.pdf' target='_blank'>Cours pdf</a>
|
||||
</p>
|
||||
<p><a class="btn btn-primary btn-lg" href='https://git.arnaudmorin.fr/arnaud/trainings/src/branch/main/ansible/training/lessons' target='_blank'>TP</a></p>
|
||||
|
||||
<h1>Cloud et OpenStack</h1>
|
||||
<p><a class="btn btn-primary btn-lg" href='https://www.arnaudmorin.fr/trainings/cloud/Arnaud%20Morin%20-%20Virtualisation%20Cloud.pdf' target='_blank'>Cours</a></p>
|
||||
<p>
|
||||
<a class="btn btn-primary btn-lg" href='https://www.arnaudmorin.fr/trainings/cloud/slides/' target='_blank'>Cours</a>
|
||||
<a class="btn btn-primary btn-lg" href='https://www.arnaudmorin.fr/trainings/cloud/slides/slides.pdf' target='_blank'>Cours pdf</a>
|
||||
</p>
|
||||
<p><a class="btn btn-primary btn-lg" href='https://git.arnaudmorin.fr/arnaud/trainings/src/branch/main/cloud/training/' target='_blank'>TP</a></p>
|
||||
|
||||
<h1>Git</h1>
|
||||
<p><a class="btn btn-primary btn-lg" href='https://www.arnaudmorin.fr/trainings/git/' target='_blank'>Cours</a></p>
|
||||
<p>
|
||||
<a class="btn btn-primary btn-lg" href='https://www.arnaudmorin.fr/trainings/git/' target='_blank'>Cours</a>
|
||||
</p>
|
||||
<p><a class="btn btn-primary btn-lg" href='https://www.arnaudmorin.fr/trainings/git/Arnaud%20Morin%20-%20Git%20Cheat%20Sheet.pdf' target='_blank'>Cheat Sheet</a></p>
|
||||
<p><a class="btn btn-primary btn-lg" href='https://github.com/arnaudmorin/git-katas/' target='_blank'>TP - Git-katas</a></p>
|
||||
<p><a class="btn btn-primary btn-lg" href='https://learngitbranching.js.org/' target='_blank'>Aller plus loin - Learn Git Branching</a></p>
|
||||
|
||||
<h1>Docker</h1>
|
||||
<p><a class="btn btn-primary btn-lg" href='https://www.arnaudmorin.fr/trainings/docker/slides/' target='_blank'>Cours</a></p>
|
||||
<p>
|
||||
<a class="btn btn-primary btn-lg" href='https://www.arnaudmorin.fr/trainings/docker/slides/' target='_blank'>Cours</a>
|
||||
<a class="btn btn-primary btn-lg" href='https://www.arnaudmorin.fr/trainings/docker/slides/slides.pdf' target='_blank'>Cours pdf</a>
|
||||
</p>
|
||||
<p><a class="btn btn-primary btn-lg" href='https://git.arnaudmorin.fr/arnaud/trainings/src/branch/main/docker/training/lessons/1-docker-getting-started.md' target='_blank'>TP</a></p>
|
||||
|
||||
<h1>Kubernetes</h1>
|
||||
<p><a class="btn btn-primary btn-lg" href='https://www.arnaudmorin.fr/trainings/kubernetes/slides/' target='_blank'>Kubernetes</a></p>
|
||||
<p>
|
||||
<a class="btn btn-primary btn-lg" href='https://www.arnaudmorin.fr/trainings/kubernetes/slides/' target='_blank'>Cours</a>
|
||||
<a class="btn btn-primary btn-lg" href='https://www.arnaudmorin.fr/trainings/kubernetes/slides/slides.pdf' target='_blank'>Cours pdf</a>
|
||||
</p>
|
||||
<p><a class="btn btn-primary btn-lg" href='https://git.arnaudmorin.fr/arnaud/trainings/src/branch/main/kubernetes/training/lessons' target='_blank'>TP</a></p>
|
||||
|
||||
<h1>OpenTofu / Terraform</h1>
|
||||
<p><a class="btn btn-primary btn-lg" href='https://www.arnaudmorin.fr/trainings/terraform/slides/' target='_blank'>Terraform</a></p>
|
||||
<p>
|
||||
<a class="btn btn-primary btn-lg" href='https://www.arnaudmorin.fr/trainings/terraform/slides/' target='_blank'>Cours</a>
|
||||
<a class="btn btn-primary btn-lg" href='https://www.arnaudmorin.fr/trainings/terraform/slides/slides.pdf' target='_blank'>Cours pdf</a>
|
||||
</p>
|
||||
<p><a class="btn btn-primary btn-lg" href='https://git.arnaudmorin.fr/arnaud/trainings/src/branch/main/terraform/training/101.md' target='_blank'>TP 101</a></p>
|
||||
<p><a class="btn btn-primary btn-lg" href='https://git.arnaudmorin.fr/arnaud/trainings/src/branch/main/terraform/training/102.md' target='_blank'>TP 102</a></p>
|
||||
<p><a class="btn btn-primary btn-lg" href='https://git.arnaudmorin.fr/arnaud/trainings/src/branch/main/terraform/training/103.md' target='_blank'>TP 103</a></p>
|
||||
|
||||
<h1>Bonus - Bootstrap OpenStack</h1>
|
||||
<p><a class="btn btn-primary btn-lg" href='https://github.com/arnaudmorin/bootstrap-openstack-k8s' target='_blank'>Bootstrap OS on K8S</a></p>
|
||||
<h1>CTF</h1>
|
||||
<p><a class="btn btn-primary btn-lg" href='https://github.com/arnaudmorin/isen-nuclear-cloud-ctf' target='_blank'>Nuclear CTF</a></p>
|
||||
|
||||
<!--
|
||||
<h1>QCM</h1>
|
||||
|
||||
BIN
kubernetes/slides/slides.pdf
Normal file
BIN
kubernetes/slides/slides.pdf
Normal file
Binary file not shown.
2
qcm/.gitignore
vendored
Normal file
2
qcm/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
*.md
|
||||
*.pdf
|
||||
BIN
qcm/2025.md.gpg
Normal file
BIN
qcm/2025.md.gpg
Normal file
Binary file not shown.
BIN
qcm/2026-for-pdf.md.gpg
Normal file
BIN
qcm/2026-for-pdf.md.gpg
Normal file
Binary file not shown.
BIN
qcm/2026.md.gpg
Normal file
BIN
qcm/2026.md.gpg
Normal file
Binary file not shown.
BIN
qcm/2026.pdf.gpg
Normal file
BIN
qcm/2026.pdf.gpg
Normal file
Binary file not shown.
2
qcm/build.sh
Executable file
2
qcm/build.sh
Executable file
@@ -0,0 +1,2 @@
|
||||
# need apt-get install pandoc textlive-latex-recommended
|
||||
pandoc 2026-for-pdf.md -o 2026.pdf --pdf-engine=pdflatex -V lang=fr && pdfinfo 2026.pdf | grep Pages
|
||||
10
qcm/cipher.sh
Executable file
10
qcm/cipher.sh
Executable file
@@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
find . -name '*.md' | while read f ; do
|
||||
echo "Ciiphering $f"
|
||||
cat $f | gpg -e -r arnaud@mailops.fr -r arnaud.choupinette@mailops.fr -r arnaud.morin@gmail.com > $f.gpg
|
||||
done
|
||||
find . -name '*.pdf' | while read f ; do
|
||||
echo "Ciiphering $f"
|
||||
cat $f | gpg -e -r arnaud@mailops.fr -r arnaud.choupinette@mailops.fr -r arnaud.morin@gmail.com > $f.gpg
|
||||
done
|
||||
38
qcm/final.md
38
qcm/final.md
@@ -1,38 +0,0 @@
|
||||
# QCM
|
||||
## Cloud et OpenStack
|
||||
1. Citez quelques avantages de la virtualisation
|
||||
2. Expliquez la différence entre Espace Utilisateur et Espace Noyau
|
||||
3. Qu'apporte le Cloud en plus par rapport à la simple virtualisation ?
|
||||
4. Donnez quelques exemples de fournisseurs de Public Cloud en France
|
||||
5. Qu'est ce qu'une instance ?
|
||||
6. Citez les principaux modules qui composent le projet OpenStack ?
|
||||
|
||||
## Ansible
|
||||
1. Qu’est qu’Ansible ?
|
||||
2. Expliquez le paradigme de « pet versus cattle » ?
|
||||
3. Qu’est ce que l’idempotence ?
|
||||
4. Donnez la commande pour exécuter le module ping sur le host 10.1.2.3
|
||||
5. Expliquez ce que sont les playbooks, les roles, les tasks, les modules dans l’univers d’ansible
|
||||
6. Qu’est ce qu’un fact ?
|
||||
7. Connaissez vous d’autres logiciels similaires a ansible ?
|
||||
|
||||
## Git
|
||||
1. Décrivez brièvement ce qu’est Git ?
|
||||
2. Donnez un exemple de commande Git pour cloner un dépôt de code
|
||||
3. Quelle est, généralement, le nom de la branche principale ?
|
||||
4. Savez vous qui a invente Git ?
|
||||
5. Connaissez vous d’autres logiciels similaires a Git ?
|
||||
6. Avec quelle commande pourriez vous voir l’historique des changements sur un dépôt Git ?
|
||||
7. Attention, plus difficile, avec quelle commande pourriez vous trouver quand a été changée une ligne dans un fichier (et par qui) ?
|
||||
|
||||
## Docker
|
||||
1. Quelle est la difference entre un container et une machine virtuelle ?
|
||||
2. Comment lister les containers dockers sur une machine ?
|
||||
3. Connaissez vous d'autres technologies de containerisation sur linux ?
|
||||
|
||||
## Kubernetes
|
||||
1. A quoi sert kubernetes ?
|
||||
2. Expliquez ce qu'est un pod
|
||||
|
||||
## Terraform
|
||||
1. A quoi sert Terraform ?
|
||||
7
qcm/uncipher.sh
Executable file
7
qcm/uncipher.sh
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
find . -name '*.gpg' | while read f ; do
|
||||
echo "Unciphering $f"
|
||||
n=${f%.gpg}
|
||||
cat $f | gpg -d > $n
|
||||
done
|
||||
@@ -7,7 +7,7 @@
|
||||
<title>Terraform</title>
|
||||
|
||||
<link rel="stylesheet" href="css/reveal.css">
|
||||
<link rel="stylesheet" href="css/theme/black.css">
|
||||
<link rel="stylesheet" href="css/theme/white.css">
|
||||
|
||||
<!-- Theme used for syntax highlighting of code -->
|
||||
<link rel="stylesheet" href="lib/css/zenburn.css">
|
||||
|
||||
@@ -9,8 +9,10 @@ based on dark.css by Ivan Sagalaev
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
/*
|
||||
background: #3f3f3f;
|
||||
color: #dcdcdc;
|
||||
*/
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
|
||||
BIN
terraform/slides/slides.pdf
Normal file
BIN
terraform/slides/slides.pdf
Normal file
Binary file not shown.
4
terraform/training/104/.gitignore
vendored
Normal file
4
terraform/training/104/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
*.tf
|
||||
*.tfstat*
|
||||
.terraform.lock.hcl
|
||||
.terraform
|
||||
6
terraform/training/104/cipher.sh
Executable file
6
terraform/training/104/cipher.sh
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
ls -1 *.tf | while read f ; do
|
||||
echo "Ciiphering $f"
|
||||
cat $f | gpg -e -r arnaud@mailops.fr -r arnaud.choupinette@mailops.fr -r arnaud.morin@gmail.com > $f.gpg
|
||||
done
|
||||
BIN
terraform/training/104/main.tf.gpg
Normal file
BIN
terraform/training/104/main.tf.gpg
Normal file
Binary file not shown.
BIN
terraform/training/104/provider.tf.gpg
Normal file
BIN
terraform/training/104/provider.tf.gpg
Normal file
Binary file not shown.
7
terraform/training/104/uncipher.sh
Executable file
7
terraform/training/104/uncipher.sh
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
ls -1 *.gpg | while read f ; do
|
||||
echo "Unciphering $f"
|
||||
n=${f%.gpg}
|
||||
cat $f | gpg -d > $n
|
||||
done
|
||||
6
terraform/training/105.md
Normal file
6
terraform/training/105.md
Normal file
@@ -0,0 +1,6 @@
|
||||
# Pulumi 105
|
||||
|
||||
Terraform is not the only software used to do `infrastructure as code`.
|
||||
Another well known tool is called `pulumi`.
|
||||
|
||||
So your next challenge is to spawn a `demo-flask` app within your `openstack` or `kubernetes` using `pulumi`!
|
||||
1
terraform/training/105/.gitignore
vendored
Normal file
1
terraform/training/105/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
*.py
|
||||
20
terraform/training/105/README.md
Normal file
20
terraform/training/105/README.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# Install
|
||||
|
||||
Taken from https://www.pulumi.com/docs/iac/get-started/kubernetes/
|
||||
|
||||
```
|
||||
curl -fsSL https://get.pulumi.com | sh
|
||||
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
|
||||
pulumi login --local
|
||||
pulumi new kubernetes-python -g
|
||||
pulumi install
|
||||
pulumi stack init
|
||||
# Edit __main__.py
|
||||
```
|
||||
|
||||
# Run
|
||||
|
||||
```bash
|
||||
pulumi up
|
||||
pulumi down
|
||||
```
|
||||
BIN
terraform/training/105/__main__.py.gpg
Normal file
BIN
terraform/training/105/__main__.py.gpg
Normal file
Binary file not shown.
6
terraform/training/105/cipher.sh
Executable file
6
terraform/training/105/cipher.sh
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
ls -1 *.py | while read f ; do
|
||||
echo "Ciiphering $f"
|
||||
cat $f | gpg -e -r arnaud@mailops.fr -r arnaud.choupinette@mailops.fr -r arnaud.morin@gmail.com > $f.gpg
|
||||
done
|
||||
7
terraform/training/105/uncipher.sh
Executable file
7
terraform/training/105/uncipher.sh
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
ls -1 *.gpg | while read f ; do
|
||||
echo "Unciphering $f"
|
||||
n=${f%.gpg}
|
||||
cat $f | gpg -d > $n
|
||||
done
|
||||
@@ -1,9 +1,8 @@
|
||||
# Create jumps
|
||||
|
||||
```bash
|
||||
# NOTE(arnaud) we need large for the kubernetes ex.
|
||||
# NOTE(arnaud) we need c3-16 for the kubernetes ex.
|
||||
c=20
|
||||
#openstack server create --user-data isen-postinstall.sh --min $c --max $c --flavor large --image 'Debian 12' --net public --key-name arnaud-choupinette isen
|
||||
openstack server create --user-data isen-postinstall.sh --min $c --max $c --flavor c3-16 --image 'Debian 12' --net Ext-Net --key-name arnaud-choupinette isen
|
||||
```
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ export OS_PASSWORD=changeme
|
||||
export OS_PROJECT_NAME=${isen}
|
||||
export OS_USER_DOMAIN_NAME=Default
|
||||
export OS_PROJECT_DOMAIN_NAME=Default
|
||||
export OS_AUTH_URL=http://keystone.54.36.119.253.xip.opensteak.fr/v3
|
||||
export OS_AUTH_URL=http://keystone.51.89.228.117.xip.opensteak.fr/v3
|
||||
export OS_IDENTITY_API_VERSION=3
|
||||
export debian_chroot=${isen}_user1
|
||||
EOF
|
||||
|
||||
Reference in New Issue
Block a user